diff --git a/data/sql/updates/db_world/2025_03_15_00.sql b/data/sql/updates/db_world/2025_03_15_00.sql new file mode 100644 index 000000000..a4e98ef9a --- /dev/null +++ b/data/sql/updates/db_world/2025_03_15_00.sql @@ -0,0 +1,5 @@ +-- DB update 2025_03_13_00 -> 2025_03_15_00 +-- +-- SPELL_ATTR0_CU_ONLY_ONE_AREA_AURA 45402 Demonic Vapor +DELETE FROM `spell_custom_attr` WHERE `spell_id` = 45402; +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES(45402, 536870912); diff --git a/data/sql/updates/db_world/2025_03_16_00.sql b/data/sql/updates/db_world/2025_03_16_00.sql new file mode 100644 index 000000000..0f8179757 --- /dev/null +++ b/data/sql/updates/db_world/2025_03_16_00.sql @@ -0,0 +1,4 @@ +-- DB update 2025_03_15_00 -> 2025_03_16_00 +-- Fixes Zangarmarsh Quest "A Job Undone" invalid prerequisite quest +-- closes https://github.com/azerothcore/azerothcore-wotlk/issues/21708 +UPDATE `quest_template_addon` SET `PrevQuestID` = 9773 WHERE (`ID` = 9899); diff --git a/data/sql/updates/db_world/2025_03_16_01.sql b/data/sql/updates/db_world/2025_03_16_01.sql new file mode 100644 index 000000000..e2bc3b9be --- /dev/null +++ b/data/sql/updates/db_world/2025_03_16_01.sql @@ -0,0 +1,14 @@ +-- DB update 2025_03_16_00 -> 2025_03_16_01 +-- Add Relic of Ulduar to loot tables +DELETE FROM `creature_loot_template` WHERE `Entry` IN (27960, 27961, 27962, 27963, 27964, 27965, 27969, 27970, 27971, 27972) AND `Item` = 42780; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(27960, 42780, 0, 35, 0, 1, 0, 1, 3, 'Dark Rune Warrior - Relic of Ulduar'), +(27961, 42780, 0, 36, 0, 1, 0, 1, 3, 'Dark Rune Worker - Relic of Ulduar'), +(27962, 42780, 0, 36, 0, 1, 0, 1, 3, 'Dark Rune Elementalist - Relic of Ulduar'), +(27963, 42780, 0, 36, 0, 1, 0, 1, 3, 'Dark Rune Theurgist - Relic of Ulduar'), +(27964, 42780, 0, 36, 0, 1, 0, 1, 3, 'Dark Rune Scholar - Relic of Ulduar'), +(27965, 42780, 0, 38, 0, 1, 0, 1, 3, 'Dark Rune Shaper - Relic of Ulduar'), +(27969, 42780, 0, 30, 0, 1, 0, 1, 3, 'Dark Rune Giant - Relic of Ulduar'), +(27970, 42780, 0, 18, 0, 1, 0, 1, 3, 'Raging Construct - Relic of Ulduar'), +(27971, 42780, 0, 22, 0, 1, 0, 1, 3, 'Unrelenting Construct - Relic of Ulduar'), +(27972, 42780, 0, 19, 0, 1, 0, 1, 3, 'Lightning Construct - Relic of Ulduar'); diff --git a/data/sql/updates/db_world/2025_03_16_02.sql b/data/sql/updates/db_world/2025_03_16_02.sql new file mode 100644 index 000000000..a88bfe363 --- /dev/null +++ b/data/sql/updates/db_world/2025_03_16_02.sql @@ -0,0 +1,20 @@ +-- DB update 2025_03_16_01 -> 2025_03_16_02 +-- Add Relic of Ulduar to loot tables Halls of Lightning +DELETE FROM `creature_loot_template` WHERE `Entry` IN (28547, 28578, 28579, 28580, 28581, 28582, 28583, 28584, 28826, 28835, 28836, 28837, 28838, 28920, 28961, 28965) AND `Item` = 42780; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(28547, 42780, 0, 23, 0, 1, 0, 1, 3, 'Storming Vortex - Relic of Ulduar'), +(28578, 42780, 0, 29, 0, 1, 0, 1, 3, 'Hardened Steel Reaver - Relic of Ulduar'), +(28579, 42780, 0, 28, 0, 1, 0, 1, 3, 'Hardened Steel Berserker - Relic of Ulduar'), +(28580, 42780, 0, 27, 0, 1, 0, 1, 3, 'Hardened Steel Skycaller - Relic of Ulduar'), +(28581, 42780, 0, 30, 0, 1, 0, 1, 3, 'Stormforged Tactician - Relic of Ulduar'), +(28582, 42780, 0, 30, 0, 1, 0, 1, 3, 'Stormforged Mender - Relic of Ulduar'), +(28583, 42780, 0, 23, 0, 1, 0, 1, 3, 'Blistering Steamrager - Relic of Ulduar'), +(28584, 42780, 0, 20, 0, 1, 0, 1, 3, 'Unbound Firestorm - Relic of Ulduar'), +(28826, 42780, 0, 21, 0, 1, 0, 1, 3, 'Stormfury Revenant - Relic of Ulduar'), +(28835, 42780, 0, 20, 0, 1, 0, 1, 3, 'Stormforged Construct - Relic of Ulduar'), +(28836, 42780, 0, 34, 0, 1, 0, 1, 3, 'Stormforged Runeshaper - Relic of Ulduar'), +(28837, 42780, 0, 31, 0, 1, 0, 1, 3, 'Stormforged Sentinel - Relic of Ulduar'), +(28838, 42780, 0, 34, 0, 1, 0, 1, 3, 'Titanium Vanguard - Relic of Ulduar'), +(28920, 42780, 0, 33, 0, 1, 0, 1, 3, 'Stormforged Giant - Relic of Ulduar'), +(28961, 42780, 0, 34, 0, 1, 0, 1, 3, 'Titanium Siegebreaker - Relic of Ulduar'), +(28965, 42780, 0, 31, 0, 1, 0, 1, 3, 'Titanium Thunderer - Relic of Ulduar'); diff --git a/data/sql/updates/db_world/2025_03_16_03.sql b/data/sql/updates/db_world/2025_03_16_03.sql new file mode 100644 index 000000000..d231ced36 --- /dev/null +++ b/data/sql/updates/db_world/2025_03_16_03.sql @@ -0,0 +1,12 @@ +-- DB update 2025_03_16_02 -> 2025_03_16_03 +-- Remove SmartAI sql for NPC Jenny (25969) +DELETE FROM `smart_scripts` +WHERE `entryorguid` = 25969; + +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_jenny' WHERE (`entry` = 25969); + +-- spell 46340 Crates Carried +-- add custom attribute SPELL_ATTR0_CU_IGNORE_EVADE +DELETE FROM `spell_custom_attr` WHERE `spell_id` = 46340; +INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES +(46340, 2048); diff --git a/data/sql/updates/db_world/2025_03_16_04.sql b/data/sql/updates/db_world/2025_03_16_04.sql new file mode 100644 index 000000000..86aad65a1 --- /dev/null +++ b/data/sql/updates/db_world/2025_03_16_04.sql @@ -0,0 +1,4 @@ +-- DB update 2025_03_16_03 -> 2025_03_16_04 +-- fixes quest "Pushed Too Far" not having a prerequisite +-- https://github.com/azerothcore/azerothcore-wotlk/issues/21553 +UPDATE `quest_template_addon` SET `PrevQuestID` = 12867 WHERE (`ID` = 12869); diff --git a/data/sql/updates/db_world/2025_03_17_00.sql b/data/sql/updates/db_world/2025_03_17_00.sql new file mode 100644 index 000000000..4a9c2caa4 --- /dev/null +++ b/data/sql/updates/db_world/2025_03_17_00.sql @@ -0,0 +1,8 @@ +-- DB update 2025_03_16_04 -> 2025_03_17_00 +-- +DELETE FROM `spell_script_names` WHERE `spell_id` IN (29707, 30324, 47449, 47450) AND `ScriptName` = 'spell_warr_heroic_strike'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(29707, 'spell_warr_heroic_strike'), +(30324, 'spell_warr_heroic_strike'), +(47449, 'spell_warr_heroic_strike'), +(47450, 'spell_warr_heroic_strike'); diff --git a/data/sql/updates/db_world/2025_03_17_01.sql b/data/sql/updates/db_world/2025_03_17_01.sql new file mode 100644 index 000000000..6dfe65950 --- /dev/null +++ b/data/sql/updates/db_world/2025_03_17_01.sql @@ -0,0 +1,35 @@ +-- DB update 2025_03_17_00 -> 2025_03_17_01 +-- Declare variables for item IDs +SET @item_severed_arm = 45323; +SET @item_bloated_slippery_eel = 45328; +SET @quest_disarmed = 13836; + +-- Delete Severed Arm from fish loot +DELETE FROM `fishing_loot_template` +WHERE `entry` = 4567 AND `item` = @item_severed_arm; + +-- Delete Bloated Slippery Eel from fish loot (water outside of Dalaran, where Quest Item was before patch 3.3.3) +DELETE FROM `fishing_loot_template` +WHERE `entry` = 3979 AND `item` = @item_bloated_slippery_eel; + +-- Delete Bloated Slippery Eel from gameobject loot (fishing holes outside of Dalaran, where Quest Item was before patch 3.3.3) +DELETE FROM `gameobject_loot_template` +WHERE `entry` = 25671 AND `item` = @item_bloated_slippery_eel; + +-- Update Bloated Slippery Eel entry in reference loot (the quest fish already exists in loot table but is in "wrong" water; move it to outside of the prison) +UPDATE `reference_loot_template` +SET `entry` = 11024 +WHERE `entry` = 11026 AND `item` = @item_bloated_slippery_eel; + +-- Update conditions according to the changed entry in `reference_loot_template` +UPDATE `conditions` +SET `sourceGroup` = 11024 +WHERE `sourceGroup` = 11026 AND `sourceEntry` = @item_bloated_slippery_eel AND `conditionValue1` = @quest_disarmed; + +-- Delete outdated condition +DELETE FROM `conditions` +WHERE `sourceGroup` = 25671 AND `sourceEntry` = @item_bloated_slippery_eel AND `conditionValue1` = @quest_disarmed; + +-- Delete duplicated Corroded Jewelry from fish loot +DELETE FROM `fishing_loot_template` +WHERE `entry` = 4560 AND `item` = 45903; diff --git a/data/sql/updates/db_world/2025_03_17_02.sql b/data/sql/updates/db_world/2025_03_17_02.sql new file mode 100644 index 000000000..ee584b6e8 --- /dev/null +++ b/data/sql/updates/db_world/2025_03_17_02.sql @@ -0,0 +1,68 @@ +-- DB update 2025_03_17_01 -> 2025_03_17_02 +-- Fix double cast of Scourge Disguise +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 28669); +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 +(28669, 0, 0, 1, 54, 0, 100, 512, 0, 0, 0, 0, 0, 0, 28, 51966, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Flying Fiend - On Just Summoned - Remove \'Scourge Disguise[51966]\''), +(28669, 0, 1, 2, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 11, 52191, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Flying Fiend - On Just Summoned - Cast \'Scourge Disguise[52191]\''), +(28669, 0, 2, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 80, 2866900, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Flying Fiend - On Just Summoned - Run Script'), +(28669, 0, 3, 0, 40, 0, 100, 512, 62, 28669, 0, 0, 0, 0, 11, 52220, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Flying Fiend - On Waypoint 62 Reached - Cast \'Kill Credit\''), +(28669, 0, 4, 5, 40, 0, 100, 512, 63, 28669, 0, 0, 0, 0, 28, 52191, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Flying Fiend - On Waypoint 63 Reached - Remove \'Scourge Disguise[52191]\''), +(28669, 0, 5, 6, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 75, 52192, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Flying Fiend - On Waypoint 63 Reached - Cast \'Scourge Disguise[52192]\''), +(28669, 0, 6, 7, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 75, 51971, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Flying Fiend - On Waypoint 63 Reached - Cast \'Scourge Disguise Instability[51971]\''), +(28669, 0, 7, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 11, 50630, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Flying Fiend - On Waypoint 63 Reached - Cast \'Eject All Passengers\''); + +-- Add or Remove linked to Scourge Disguise spells +DELETE FROM `spell_linked_spell` WHERE (`spell_trigger` IN ( -52010, -52192, -51966, 51966, 52192)); +INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES +(-52010, -52192, 0, 'Remove Scourge Disguise [52192]'), +(-52010, -51966, 0, 'Remove Scourge Disguise [51966]'), +(-51966, -51971, 0, 'Remove Scourge Disguise Instability [51971]'), +(-52192, -51971, 0, 'Remove Scourge Disguise Instability [51971]'), +(51966, -52192, 0, 'Remove Scourge Disguise [52192]'), +(52192, -51966, 0, 'Remove Scourge Disguise [51966]'), +(51966, 51971, 0, 'Add Scourge Disguise Instability [51971]'), +(52192, 51971, 0, 'Add Scourge Disguise Instability [51971]'); + +-- Attach script to Scourge Disguise Instability +DELETE FROM `spell_script_names` WHERE `spell_id` = 51971; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(51971, 'spell_scourge_disguise_instability'); + +-- Update Blightguard AI +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=28603; + +-- Update Blightguard scripts: cast invisibility, remove aura from target, cast Shadowstrike +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 28603); +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 +(28603, 0, 0, 0, 25, 0, 100, 0, 0, 0, 0, 0, 0, 0, 75, 52060, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blightguard - On Reset - Cast \'Invisibility\''), +(28603, 0, 1, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 28, 52060, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blightguard - On Aggro - Remove Aura \'Invisibility\''), +(28603, 0, 2, 0, 0, 0, 100, 0, 6000, 6000, 10000, 10000, 0, 0, 11, 33914, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Blightguard - In Combat - Cast \'Shadowstrike\''), +(28603, 0, 3, 0, 24, 0, 100, 0, 51966, 0, 100, 100, 0, 0, 28, 51966, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Blightguard - On Target Has \'Scourge Disguise\' Aura - Remove \'Scourge Disguise\'[51966]'), +(28603, 0, 4, 0, 24, 0, 100, 0, 52192, 0, 100, 100, 0, 0, 28, 52192, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Blightguard - On Target Has \'Scourge Disguise\' Aura - Remove \'Scourge Disguise\'[52192]'); + +-- Original commit: https://github.com/TrinityCore/TrinityCore/commit/d96482b2d49c61fe26533def461276a8038db4ab +-- Update Blightguard spawn location (thanks to @Killyana) +DELETE FROM `creature` WHERE (`id1` = 28603 AND `guid` IN (113672, 52812, 52813, 52814, 52815, 52816, 52817, 52818, 52819, 52820, 52821, 52822, 52823, 52824, 52825, 52826, 52827, 52828, 52829, 52830, 52831, 52832, 52833) ); +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`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES +(52812, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6022.67, -2049.14, 238.189, 1.46482, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52813, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6042.88, -2119.83, 239.522, 5.55282, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52814, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6101.08, -2157.18, 239.578, 5.52926, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52815, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6176.72, -2208.48, 241.65, 0.110007, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52816, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6227.74, -2193.69, 236.211, 0.66371, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52817, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6270.34, -2053.92, 238.548, 1.23705, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52818, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6069.51, -1913.87, 236.212, 2.78429, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52819, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6017.94, -1903.71, 239.384, 3.56183, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52820, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 5981.49, -1963.15, 237.669, 4.15088, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52821, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6017.39, -2106.46, 243.382, 5.40752, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52822, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 5275.12, -1678.04, 236.349, 1.1703, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52823, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 5224.69, -1751.98, 235.717, 3.17306, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52824, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 5154.48, -1745.88, 238.291, 3.26731, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52825, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 5082.87, -1725.64, 235.624, 3.55791, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52826, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 5034.49, -1655.17, 240.16, 1.8693, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52827, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 5069.11, -1540.09, 240.561, 6.1183, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52828, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 5099.29, -1559.64, 238.941, 0.624444, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52829, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6183.62, -2102.73, 235.653, 3.42675, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52830, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6113.59, -2105.41, 234.909, 0.441447, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52831, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6091.98, -2019.44, 235.639, 1.6706, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52832, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6199.66, -1957.45, 234.049, 1.20721, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL), +(52833, 28603, 0, 0, 571, 0, 0, 1, 1, 0, 6242.41, -2003.27, 234.282, 4.15089, 600, 10, 0, 0, 0, 1, 0, 0, 0, '', 0, 0, NULL); diff --git a/data/sql/updates/db_world/2025_03_17_03.sql b/data/sql/updates/db_world/2025_03_17_03.sql new file mode 100644 index 000000000..4a101c6e9 --- /dev/null +++ b/data/sql/updates/db_world/2025_03_17_03.sql @@ -0,0 +1,3 @@ +-- DB update 2025_03_17_02 -> 2025_03_17_03 +UPDATE `quest_poi` SET `WorldMapAreaId` = 1421, `VerifiedBuild` = 51831 WHERE (`QuestID` = 8948) AND (`id` = 0); +UPDATE `quest_poi_points` SET `VerifiedBuild` = 51831 WHERE (`QuestID` = 8948) AND (`Idx1` = 0) AND (`Idx2` = 0); diff --git a/data/sql/updates/db_world/2025_03_19_00.sql b/data/sql/updates/db_world/2025_03_19_00.sql new file mode 100644 index 000000000..d4e782ef2 --- /dev/null +++ b/data/sql/updates/db_world/2025_03_19_00.sql @@ -0,0 +1,10 @@ +-- DB update 2025_03_17_03 -> 2025_03_19_00 +-- +DELETE FROM `spell_script_names` WHERE `spell_id` = 45034; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES(45034, 'spell_kalecgos_curse_of_boundless_agony_aura'); +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` IN (45032, 45034)) AND (`SourceId` = 0) AND (`ConditionValue1` IN (45032, 45034)); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 45032, 0, 0, 1, 0, 45032, 0, 0, 1, 0, 0, '', 'Player does not have Curse of Boundless Agony'), +(13, 1, 45032, 0, 0, 1, 0, 45034, 0, 0, 1, 0, 0, '', 'Player does not have Curse of Boundless Agony'), +(13, 1, 45034, 0, 0, 1, 0, 45032, 0, 0, 1, 0, 0, '', 'Player does not have Curse of Boundless Agony'), +(13, 1, 45034, 0, 0, 1, 0, 45034, 0, 0, 1, 0, 0, '', 'Player does not have Curse of Boundless Agony'); diff --git a/data/sql/updates/db_world/2025_03_19_01.sql b/data/sql/updates/db_world/2025_03_19_01.sql new file mode 100644 index 000000000..6c6383241 --- /dev/null +++ b/data/sql/updates/db_world/2025_03_19_01.sql @@ -0,0 +1,11 @@ +-- DB update 2025_03_19_00 -> 2025_03_19_01 + +-- Add creature formation for the last pack before Kalecgos +DELETE FROM `creature_formations` WHERE `leaderGUID` = 54834; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(54834, 54834, 0, 0, 3, 0, 0), +(54834, 43654, 0, 0, 3, 0, 0), +(54834, 42573, 0, 0, 3, 0, 0), +(54834, 42574, 0, 0, 3, 0, 0), +(54834, 54817, 0, 0, 3, 0, 0), +(54834, 42656, 0, 0, 3, 0, 0); diff --git a/data/sql/updates/db_world/2025_03_21_00.sql b/data/sql/updates/db_world/2025_03_21_00.sql new file mode 100644 index 000000000..5b3c7c17c --- /dev/null +++ b/data/sql/updates/db_world/2025_03_21_00.sql @@ -0,0 +1,76 @@ +-- DB update 2025_03_19_01 -> 2025_03_21_00 +-- Update gameobject 'SWP / MGT' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (188116, 188115, 188114, 187869, 188523, 188075, 188081, 188165, 188166, 188173, 187979, 187990, 187764, 187765, 187766, 187770, 188064, 188065, 187578, 188118, 187896)) AND (`guid` IN (268109, 268110, 268111, 268112, 50437, 50442, 50452, 99798, 99799, 99800, 99802, 99803, 99804, 99805, 99806, 99807, 99808, 99809, 99810, 99811, 99812, 99813)); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES +-- Orb of the Blue Flight +-- was 187869 before +(268109, 188116, 580, 0, 0, 1, 1, 1696.15478515625, 674.96759033203125, 28.05020904541015625, 4.817109584808349609, 0, 0, -0.66913032531738281, 0.74314504861831665, 7200, 255, 1, "", 50664, NULL), +-- was 188114 before +(268110, 188115, 580, 0, 0, 1, 1, 1651.9205322265625, 635.35009765625, 28.12865447998046875, 6.195919513702392578, 0, 0, -0.04361915588378906, 0.999048233032226562, 7200, 255, 1, "", 50664, NULL), +-- was 188115 before +(268111, 188114, 580, 0, 0, 1, 1, 1704.3033447265625, 582.68109130859375, 28.16482734680175781, 1.605701684951782226, 0, 0, 0.719339370727539062, 0.694658815860748291, 7200, 255, 1, "", 50664, NULL), +-- was 188116 before +(268112, 187869, 580, 0, 0, 1, 1, 1746.5653076171875, 621.91339111328125, 28.05021095275878906, 2.984498262405395507, 0, 0, 0.996916770935058593, 0.078466430306434631, 7200, 255, 1, "", 50664, NULL), +-- Doodad_Sunwell_BossCollision01 +(50437, 188523, 580, 0, 0, 1, 1, 1704.8704833984375, 927.79095458984375, 40.58108901977539062, 1.553341388702392578, 0, 0, 0.700908660888671875, 0.713251054286956787, 7200, 255, 0, "", 50664, NULL), +-- Doodad_Sunwell_Fire_Barrier_ext01 +(50442, 188075, 580, 0, 0, 1, 1, 1499.90625, 558.431884765625, 39.33041763305664062, 4.084071159362792968, 0, 0, -0.8910064697265625, 0.453990638256072998, 7200, 255, 1, "", 50664, NULL), +-- Sanctum Planetarium +(50452, 188081, 530, 0, 0, 1, 1, 12780.5546875, -6887.462890625, 19.20861244201660156, 1.239183306694030761, 0, 0, 0.580702781677246093, 0.814115643501281738, 120, 255, 0, "", 45942, NULL), +-- Doodad_Kael_Explode_FX_Left01 +(99798, 188165, 585, 0, 0, 3, 1, 138.3532257080078125, 190.1392364501953125, -16.8305530548095703, 4.27606058120727539, 0, 0, -0.84339046478271484, 0.537301182746887207, 7200, 255, 1, "", 49345, NULL), +-- Doodad_Kael_Explode_FX_Right01 +(99799, 188166, 585, 0, 0, 3, 1, 158.750701904296875, 190.509857177734375, -16.8794155120849609, 4.97418975830078125, 0, 0, -0.60876083374023437, 0.793353796005249023, 7200, 255, 1, "", 49345, NULL), +-- Escape to the Isle of Quel'Danas +(99800, 188173, 585, 0, 0, 3, 1, 148.4007110595703125, 203.44293212890625, -11.957921028137207, 1.012289404869079589, 0, 0, 0.484808921813964843, 0.87462007999420166, 7200, 255, 1, "", 49345, NULL), +-- Doodad_SunwellRaid_Gate_02 +(99802, 187979, 585, 0, 0, 3, 1, 254.4499053955078125, -29.3622722625732421, 5.577684879302978515, 4.712389945983886718, 0, 0, -0.70710659027099609, 0.707106947898864746, 7200, 255, 1, "", 50664, NULL), +-- Doodad_SunwellRaid_Gate_07 +(99803, 187990, 585, 0, 0, 3, 1, 3.43621826171875, -448.19219970703125, -5.711883544921875, 4.00553131103515625, 0, 0, -0.9081430435180664, 0.418660014867782592, 7200, 255, 0, "", 49345, NULL), +-- Rohendor, The Second Gate +(99804, 187764, 585, 0, 0, 3, 1, -15.906280517578125, -421.996246337890625, -47.174774169921875, 3.045581579208374023, 0, 0, 0.99884796142578125, 0.047987140715122222, 7200, 255, 1, "", 49345, NULL), +-- Archonisus, The Third Gate +(99805, 187765, 585, 0, 0, 3, 1, -108.729034423828125, -598.2764892578125, -6.37282562255859375, 1.387535810470581054, 0, 0, 0.639438629150390625, 0.768842101097106933, 7200, 255, 1, "", 49345, NULL), +-- Agamath, The First Gate +(99806, 187766, 585, 0, 0, 3, 1, 72.422332763671875, -587.3228759765625, 1.59500885009765625, 2.696528911590576171, 0, 0, 0.975341796875, 0.220699742436408996, 7200, 255, 1, "", 49345, NULL), +-- Doodad_SunwellRaid_Gate_04 +(99807, 187770, 585, 0, 0, 3, 1, 127.100799560546875, 61.36127090454101562, -15.1793174743652343, 4.712389945983886718, 0, 0, -0.70710659027099609, 0.707106947898864746, 7200, 255, 1, "", 49345, NULL), +-- Asylum Door +(99808, 188064, 585, 0, 0, 3, 1, 149.9267120361328125, 125.6940383911132812, -7.26305294036865234, 1.570795774459838867, 0, 0, 0.707106590270996093, 0.707106947898864746, 7200, 255, 0, "", 49345, NULL), +-- Assembly Chamber Door +(99809, 188065, 585, 0, 0, 3, 1, 215.1305694580078125, 0.396176815032958984, 9.411577224731445312, 0, 0, 0, 0, 1, 7200, 255, 0, "", 49345, NULL), +-- Sanctum Planetarium +(99810, 188081, 585, 0, 0, 3, 1, -214.19488525390625, -251.215927124023437, -72.2626113891601562, 2.635444164276123046, 0, 0, 0.96814727783203125, 0.250381410121917724, 7200, 255, 0, "", 50664, NULL), +-- Scrying Orb +(99811, 187578, 585, 0, 0, 3, 1, 231.2144927978515625, -274.873016357421875, -7.39517498016357421, 1.658061861991882324, 0, 0, 0.737277030944824218, 0.67559051513671875, 7200, 255, 1, "", 49345, NULL), +-- Doodad_SunwellRaid_Gate_08 +(99812, 188118, 585, 0, 0, 3, 1, -71.202423095703125, -523.017578125, 0.144580841064453125, 3.132858037948608398, 0, 0, 0.999990463256835937, 0.004367320332676172, 7200, 255, 0, "", 50664, NULL), +-- Doodad_SunwellRaid_Gate_05 +(99813, 187896, 585, 0, 0, 3, 1, 231.232269287109375, -236.829681396484375, 0.579834997653961181, 4.712389945983886718, 0, 0, -0.70710659027099609, 0.707106947898864746, 7200, 255, 1, "", 49345, NULL); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (188075, 188119, 188421, 188523, 188524)) AND (`guid` IN (468, 469, 470, 471, 472)); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`, `Comment`) VALUES +-- Doodad_Sunwell_Fire_Barrier_ext01 +(468, 188075, 585, 0, 0, 3, 1, 45.91571044921875, -797.59228515625, -52.4864501953125, 5.663594245910644531, 0, 0, -0.30486392974853515, 0.952395915985107421, 7200, 255, 1, "", 49345, NULL), +-- Doodad_Sunwell_Ice_Barrier01 +(469, 188119, 585, 0, 0, 3, 1, -384.951171875, -659.806640625, -51.23577880859375, 3.132858037948608398, 0, 0, 0.999990463256835937, 0.004367320332676172, 7200, 255, 0, "", 49345, NULL), +-- Doodad_Sunwell_BossForceField01 +(470, 188421, 585, 0, 0, 3, 1, -324.042999267578125, -595.18365478515625, -59.2552947998046875, 3.132858037948608398, 0, 0, 0.999990463256835937, 0.004367320332676172, 7200, 255, 0, "", 49345, NULL), +-- Doodad_Sunwell_BossCollision01 +(471, 188523, 585, 0, 0, 3, 1, -325.217803955078125, -595.8587646484375, -51.23577880859375, 3.132858037948608398, 0, 0, 0.999990463256835937, 0.004367320332676172, 7200, 255, 0, "", 50664, NULL), +-- Doodad_Sunwell_BossCollision02 +(472, 188524, 585, 0, 0, 3, 1, -326.933685302734375, -595.60992431640625, -51.23577880859375, 3.132858037948608398, 0, 0, 0.999990463256835937, 0.004367320332676172, 7200, 255, 0, "", 49345, NULL); + +-- remaining spawns (no sniffed values available) +-- (all in map 580) +-- 50439 - 187764 -- Rohendor, The Second Gate +-- 50440 - 187765 -- Archonisus, The Third Gate +-- 50441 - 187766 -- Agamath, The First Gate +-- 50110 - 187990 -- Doodad_SunwellRaid_Gate_07 +-- 50443 - 188081 -- Sanctum Planetarium +-- 50444 - 188118 -- Doodad_SunwellRaid_Gate_08 +-- 50445 - 188119 -- Doodad_Sunwell_Ice_Barrier01 +-- 50447 - 188421 -- Doodad_Sunwell_BossForceField01 +-- 50438 - 188524 -- Doodad_Sunwell_BossCollision02 diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp index e74591af1..19191a654 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp @@ -264,7 +264,7 @@ void FollowerAI::MovementInform(uint32 motionType, uint32 pointId) } } -void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, const Quest* quest) +void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, const Quest* quest, bool inheritWalkState, bool inheritSpeed) { if (me->GetVictim()) { @@ -297,7 +297,7 @@ void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, const Qu AddFollowState(STATE_FOLLOW_INPROGRESS); - me->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + me->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE, MOTION_SLOT_ACTIVE, inheritWalkState, inheritSpeed); LOG_DEBUG("scripts.ai", "FollowerAI start follow {} ({})", player->GetName(), m_uiLeaderGUID.ToString()); } diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h index d3eef03ad..f827f7e36 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h @@ -55,7 +55,7 @@ public: void UpdateAI(uint32) override; //the "internal" update, calls UpdateFollowerAI() virtual void UpdateFollowerAI(uint32); //used when it's needed to add code in update (abilities, scripted events, etc) - void StartFollow(Player* player, uint32 factionForFollower = 0, const Quest* quest = nullptr); + void StartFollow(Player* player, uint32 factionForFollower = 0, const Quest* quest = nullptr, bool inheritWalkState = true, bool inheritSpeed = true); void SetFollowPaused(bool bPaused); //if special event require follow mode to hold/resume during the follow void SetFollowComplete(bool bWithEndEvent = false); diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 78b7fa822..ddb2317ec 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -277,7 +277,7 @@ void MotionMaster::MoveTargetedHome(bool walk /*= false*/) if (target) { LOG_DEBUG("movement.motionmaster", "Following {} ({})", target->IsPlayer() ? "player" : "creature", target->GetGUID().ToString()); - Mutate(new FollowMovementGenerator(target, PET_FOLLOW_DIST, _owner->GetFollowAngle(),true), MOTION_SLOT_ACTIVE); + Mutate(new FollowMovementGenerator(target, PET_FOLLOW_DIST, _owner->GetFollowAngle(), true, true), MOTION_SLOT_ACTIVE); } } else @@ -406,7 +406,7 @@ void MotionMaster::MoveCircleTarget(Unit* target) /** * @brief The unit will follow this target. Doesn't work with UNIT_FLAG_DISABLE_MOVE */ -void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slot, bool inheritWalkState) +void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slot, bool inheritWalkState, bool inheritSpeed) { // ignore movement request if target not exist if (!target || target == _owner || _owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE)) @@ -419,13 +419,13 @@ void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlo { LOG_DEBUG("movement.motionmaster", "Player ({}) follow to {} ({})", _owner->GetGUID().ToString(), target->IsPlayer() ? "player" : "creature", target->GetGUID().ToString()); - Mutate(new FollowMovementGenerator(target, dist, angle, inheritWalkState), slot); + Mutate(new FollowMovementGenerator(target, dist, angle, inheritWalkState, inheritSpeed), slot); } else { LOG_DEBUG("movement.motionmaster", "Creature ({}) follow to {} ({})", _owner->GetGUID().ToString(), target->IsPlayer() ? "player" : "creature", target->GetGUID().ToString()); - Mutate(new FollowMovementGenerator(target, dist, angle, inheritWalkState), slot); + Mutate(new FollowMovementGenerator(target, dist, angle, inheritWalkState, inheritSpeed), slot); } } diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index 9287dcacb..735314dbc 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -201,7 +201,7 @@ public: void MoveIdle(); void MoveTargetedHome(bool walk = false); void MoveRandom(float wanderDistance = 0.0f); - void MoveFollow(Unit* target, float dist, float angle, MovementSlot slot = MOTION_SLOT_ACTIVE, bool inheritWalkState = true); + void MoveFollow(Unit* target, float dist, float angle, MovementSlot slot = MOTION_SLOT_ACTIVE, bool inheritWalkState = true, bool inheritSpeed = true); void MoveChase(Unit* target, std::optional dist = {}, std::optional angle = {}); void MoveChase(Unit* target, float dist, float angle) { MoveChase(target, ChaseRange(dist), ChaseAngle(angle)); } void MoveChase(Unit* target, float dist) { MoveChase(target, ChaseRange(dist)); } diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index e6bb5dd4b..96ac2f1f5 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -539,8 +539,9 @@ bool FollowMovementGenerator::DoUpdate(T* owner, uint32 time_diff) if (_inheritWalkState) init.SetWalk(target->IsWalking() || target->movespline->isWalking()); - if (Optional velocity = GetVelocity(owner, target, i_path->GetActualEndPosition(), owner->IsGuardian())) - init.SetVelocity(*velocity); + if (_inheritSpeed) + if (Optional velocity = GetVelocity(owner, target, i_path->GetActualEndPosition(), owner->IsGuardian())) + init.SetVelocity(*velocity); init.Launch(); } diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 003e967d4..82ba2df47 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -75,8 +75,8 @@ template class FollowMovementGenerator : public MovementGeneratorMedium>, public TargetedMovementGeneratorBase { public: - FollowMovementGenerator(Unit* target, float range, ChaseAngle angle, bool inheritWalkState) - : TargetedMovementGeneratorBase(target), i_path(nullptr), i_recheckPredictedDistanceTimer(0), i_recheckPredictedDistance(false), _range(range), _angle(angle),_inheritWalkState(inheritWalkState) {} + FollowMovementGenerator(Unit* target, float range, ChaseAngle angle, bool inheritWalkState, bool inheritSpeed) + : TargetedMovementGeneratorBase(target), i_path(nullptr), i_recheckPredictedDistanceTimer(0), i_recheckPredictedDistance(false), _range(range), _angle(angle),_inheritWalkState(inheritWalkState), _inheritSpeed(inheritSpeed) {} ~FollowMovementGenerator() { } MovementGeneratorType GetMovementGeneratorType() { return FOLLOW_MOTION_TYPE; } @@ -108,6 +108,7 @@ private: float _range; ChaseAngle _angle; bool _inheritWalkState; + bool _inheritSpeed; }; #endif diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index e20def2cb..11ca29a07 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1431,7 +1431,16 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation()); float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation()); - float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); + // Added GROUND_HEIGHT_TOLERANCE to account for cases where, during a jump, + // the Z position may be slightly below the vmap ground level. + // Without this tolerance, a ray trace might incorrectly attempt to find ground + // beneath the actual surface. + // + // Example: + // actual vmap ground: -56.342392 + // Z position: -56.347195 + float searchGroundZPos = pos.GetPositionZ()+GROUND_HEIGHT_TOLERANCE; + float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), searchGroundZPos); bool isCasterInWater = m_caster->IsInWater(); if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance)) diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp index b7e6e1fac..00e91d584 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp @@ -106,20 +106,29 @@ const Position LandingPos = { 1476.77f, 665.094f, 20.6423f }; class CorruptTriggers : public BasicEvent { public: - CorruptTriggers(Unit* caster) : _caster(caster) { } + CorruptTriggers(Unit* caster, uint8 currentLane) : _caster(caster), _currentLane(currentLane) { } bool Execute(uint64 /*execTime*/, uint32 /*diff*/) override { std::list creatureList; _caster->GetCreaturesWithEntryInRange(creatureList, 70.0f, NPC_FOG_TRIGGER); for (auto const& creature : creatureList) + { if (_caster->GetExactDist2d(creature) <= 11.0f) + { creature->CastSpell(creature, SPELL_FOG_OF_CORRUPTION, true); + continue; + } + + if (!_currentLane && creature->GetPositionX() > 1510.0f) + creature->CastSpell(creature, SPELL_FOG_OF_CORRUPTION, true); + } return true; } private: Unit* _caster; + uint8 _currentLane; }; struct boss_felmyst : public BossAI @@ -283,20 +292,20 @@ struct boss_felmyst : public BossAI me->GetMotionMaster()->MovePoint(POINT_LANE, RightSideLanes[_currentLane], false); else me->GetMotionMaster()->MovePoint(POINT_LANE, LeftSideLanes[_currentLane], false); - }, 2s); + }, 5s); break; case POINT_LANE: Talk(EMOTE_BREATH); me->m_Events.AddEventAtOffset([&] { - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(0)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(500)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1000)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(1500)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2000)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(2500)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3000)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(3500)); - me->m_Events.AddEvent(new CorruptTriggers(me), me->m_Events.CalculateTime(4000)); + me->m_Events.AddEvent(new CorruptTriggers(me, _currentLane), me->m_Events.CalculateTime(0)); + me->m_Events.AddEvent(new CorruptTriggers(me, _currentLane), me->m_Events.CalculateTime(500)); + me->m_Events.AddEvent(new CorruptTriggers(me, _currentLane), me->m_Events.CalculateTime(1000)); + me->m_Events.AddEvent(new CorruptTriggers(me, _currentLane), me->m_Events.CalculateTime(1500)); + me->m_Events.AddEvent(new CorruptTriggers(me, _currentLane), me->m_Events.CalculateTime(2000)); + me->m_Events.AddEvent(new CorruptTriggers(me, _currentLane), me->m_Events.CalculateTime(2500)); + me->m_Events.AddEvent(new CorruptTriggers(me, _currentLane), me->m_Events.CalculateTime(3000)); + me->m_Events.AddEvent(new CorruptTriggers(me, _currentLane), me->m_Events.CalculateTime(3500)); + me->m_Events.AddEvent(new CorruptTriggers(me, _currentLane), me->m_Events.CalculateTime(4000)); }, 5s); me->m_Events.AddEventAtOffset([&] { @@ -360,57 +369,63 @@ struct boss_felmyst : public BossAI struct npc_demonic_vapor : public NullCreatureAI { - npc_demonic_vapor(Creature* creature) : NullCreatureAI(creature) { } + npc_demonic_vapor(Creature* creature) : NullCreatureAI(creature), _timer{1} { } void Reset() override { me->CastSpell(me, SPELL_DEMONIC_VAPOR_SPAWN_TRIGGER, true); - me->CastSpell(me, SPELL_DEMONIC_VAPOR_PERIODIC, true); } - void UpdateAI(uint32 /*diff*/) override + void IsSummonedBy(WorldObject* summoner) override { - if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) == NULL_MOTION_TYPE) + if (!summoner || !summoner->ToUnit()) + return; + + me->m_Events.AddEventAtOffset([this, summoner] { + me->GetMotionMaster()->MoveFollow(summoner->ToUnit(), 0.0f, 0.0f, MOTION_SLOT_CONTROLLED); + }, 2s); + } + + void UpdateAI(uint32 diff) override + { + if (_timer) { - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (me->GetDistance2d(itr->GetSource()) < 20.0f && itr->GetSource()->IsAlive()) - { - me->GetMotionMaster()->MoveFollow(itr->GetSource(), 0.0f, 0.0f, MOTION_SLOT_CONTROLLED); - break; - } + _timer += diff; + if (_timer >= 2000) + { + me->CastSpell(me, SPELL_DEMONIC_VAPOR_PERIODIC, true); + _timer = 0; + } } } +private: + uint32 _timer; }; struct npc_demonic_vapor_trail : public NullCreatureAI { - npc_demonic_vapor_trail(Creature* creature) : NullCreatureAI(creature) - { - timer = 1; - } + npc_demonic_vapor_trail(Creature* creature) : NullCreatureAI(creature), _timer{1} { } - uint32 timer; void Reset() override { me->CastSpell(me, SPELL_DEMONIC_VAPOR_TRAIL_PERIODIC, true); me->DespawnOrUnsummon(20000); } - void SpellHitTarget(Unit*, SpellInfo const* spellInfo) override + void SpellHitTarget(Unit* /*unit*/, SpellInfo const* spellInfo) override { - if (spellInfo->Id == SPELL_DEMONIC_VAPOR) - me->CastSpell(me, SPELL_SUMMON_BLAZING_DEAD, true); + if (spellInfo->Id == SPELL_DEMONIC_VAPOR && !_timer) + _timer = 1; } void UpdateAI(uint32 diff) override { - if (timer) + if (_timer) { - timer += diff; - if (timer >= 6000) + _timer += diff; + if (_timer >= 5000) { - timer = 0; + _timer = 0; me->CastSpell(me, SPELL_SUMMON_BLAZING_DEAD, true); } } @@ -421,6 +436,8 @@ struct npc_demonic_vapor_trail : public NullCreatureAI summon->SetInCombatWithZone(); summon->AI()->AttackStart(summon->AI()->SelectTarget(SelectTargetMethod::Random, 0, 100.0f)); } +private: + uint32 _timer; }; class spell_felmyst_fog_of_corruption : public SpellScript diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp index ac23eb718..300a39dea 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp @@ -47,32 +47,36 @@ enum Yells enum Spells { - SPELL_SPECTRAL_EXHAUSTION = 44867, - SPELL_SPECTRAL_BLAST = 44869, - SPELL_SPECTRAL_BLAST_PORTAL = 44866, - SPELL_SPECTRAL_BLAST_AA = 46648, - SPELL_TELEPORT_SPECTRAL = 46019, + SPELL_SPECTRAL_EXHAUSTION = 44867, + SPELL_SPECTRAL_BLAST = 44869, + SPELL_SPECTRAL_BLAST_PORTAL = 44866, + SPELL_SPECTRAL_BLAST_AA = 46648, + SPELL_TELEPORT_SPECTRAL = 46019, - SPELL_TELEPORT_NORMAL_REALM = 46020, - SPELL_SPECTRAL_REALM = 46021, - SPELL_SPECTRAL_INVISIBILITY = 44801, - SPELL_DEMONIC_VISUAL = 44800, + SPELL_TELEPORT_NORMAL_REALM = 46020, + SPELL_SPECTRAL_REALM = 46021, + SPELL_SPECTRAL_INVISIBILITY = 44801, + SPELL_DEMONIC_VISUAL = 44800, - SPELL_ARCANE_BUFFET = 45018, - SPELL_FROST_BREATH = 44799, - SPELL_TAIL_LASH = 45122, + SPELL_ARCANE_BUFFET = 45018, + SPELL_FROST_BREATH = 44799, + SPELL_TAIL_LASH = 45122, - SPELL_BANISH = 44836, - SPELL_TRANSFORM_KALEC = 44670, - SPELL_CRAZED_RAGE = 44807, + SPELL_BANISH = 44836, + SPELL_TRANSFORM_KALEC = 44670, + SPELL_CRAZED_RAGE = 44807, - SPELL_CORRUPTION_STRIKE = 45029, - SPELL_CURSE_OF_BOUNDLESS_AGONY = 45032, - SPELL_CURSE_OF_BOUNDLESS_AGONY_PLR = 45034, - SPELL_SHADOW_BOLT = 45031, + SPELL_CORRUPTION_STRIKE = 45029, + SPELL_CURSE_OF_BOUNDLESS_AGONY = 45032, + SPELL_CURSE_OF_BOUNDLESS_AGONY_PLR = 45034, + SPELL_CURSE_OF_BOUNDLESS_AGONY_REMOVE = 45050, + SPELL_CURSE_OF_BOUNDLESS_AGONY_DUMMY_1 = 45083, + SPELL_CURSE_OF_BOUNDLESS_AGONY_DUMMY_2 = 45085, + SPELL_CURSE_OF_BOUNDLESS_AGONY_DUMMY_3 = 45084, + SPELL_SHADOW_BOLT = 45031, - SPELL_HEROIC_STRIKE = 45026, - SPELL_REVITALIZE = 45027 + SPELL_HEROIC_STRIKE = 45026, + SPELL_REVITALIZE = 45027 }; enum SWPActions @@ -244,7 +248,7 @@ struct boss_kalecgos : public BossAI DoCastAOE(SPELL_SPECTRAL_BLAST); }, 20s, 30s); - scheduler.Schedule(16s, [this](TaskContext) + scheduler.Schedule(9s, [this](TaskContext) { if (Creature* kalec = me->SummonCreature(NPC_KALEC, 1702.21f, 931.7f, -74.56f, 5.07f, TEMPSUMMON_MANUAL_DESPAWN)) kalec->CastSpell(kalec, SPELL_SPECTRAL_INVISIBILITY, true); @@ -388,6 +392,7 @@ struct boss_sathrovarr : public ScriptedAI void JustDied(Unit* /*killer*/) override { + DoCastSelf(SPELL_CURSE_OF_BOUNDLESS_AGONY_REMOVE, true); Talk(SAY_SATH_DEATH); } @@ -464,10 +469,10 @@ class spell_kalecgos_curse_of_boundless_agony_aura : public AuraScript bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo({ SPELL_CURSE_OF_BOUNDLESS_AGONY_PLR }); + return ValidateSpellInfo({ SPELL_CURSE_OF_BOUNDLESS_AGONY_PLR, SPELL_CURSE_OF_BOUNDLESS_AGONY_DUMMY_1, SPELL_CURSE_OF_BOUNDLESS_AGONY_DUMMY_2, SPELL_CURSE_OF_BOUNDLESS_AGONY_DUMMY_3 }); } - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (InstanceScript* instance = GetUnitOwner()->GetInstanceScript()) if (instance->IsEncounterInProgress()) @@ -476,8 +481,18 @@ class spell_kalecgos_curse_of_boundless_agony_aura : public AuraScript void OnPeriodic(AuraEffect const* aurEff) { - if (aurEff->GetTickNumber() > 1 && aurEff->GetTickNumber() % 5 == 1) + uint32 tickNumber = aurEff->GetTickNumber(); + if (tickNumber > 1 && tickNumber % 5 == 1) GetAura()->GetEffect(aurEff->GetEffIndex())->SetAmount(aurEff->GetAmount() * 2); + + uint32 spellId = 0; + if (tickNumber <= 10) + spellId = SPELL_CURSE_OF_BOUNDLESS_AGONY_DUMMY_1; + else if (tickNumber <= 20) + spellId = SPELL_CURSE_OF_BOUNDLESS_AGONY_DUMMY_2; + else + spellId = SPELL_CURSE_OF_BOUNDLESS_AGONY_DUMMY_3; + GetTarget()->CastSpell(GetTarget(), spellId, true); } void Register() override diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp index b0d51b814..1f9fa5a87 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp @@ -184,7 +184,10 @@ struct npc_sunblade_scout : public ScriptedAI protectors.remove_if([](Creature* trigger) {return !trigger->HasAura(SPELL_COSMETIC_STUN_IMMUNE_PERMANENT);}); protectors.sort(Acore::ObjectDistanceOrderPred(me)); if (protectors.empty()) + { ScheduleCombat(); + return; + } Creature* closestProtector = protectors.front(); me->GetMotionMaster()->MoveFollow(closestProtector, 0.0f, 0.0f); _protectorGUID = closestProtector->GetGUID(); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp index 9edac602a..55e4f8039 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp @@ -757,7 +757,10 @@ struct npc_amanishi_scout : public ScriptedAI triggers.remove_if([](Creature* trigger) {return !IsDrum(trigger);}); triggers.sort(Acore::ObjectDistanceOrderPred(me)); if (triggers.empty()) + { ScheduleCombat(); + return; + } Creature* closestDrum = triggers.front(); me->GetMotionMaster()->MoveFollow(closestDrum, 0.0f, 0.0f); _drumGUID = closestDrum->GetGUID(); diff --git a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_herald_volazj.cpp b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_herald_volazj.cpp index f386515dc..fa1a998b0 100644 --- a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_herald_volazj.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_herald_volazj.cpp @@ -33,7 +33,6 @@ enum Spells // INSANITY SPELL_INSANITY = 57496, //Dummy INSANITY_VISUAL = 57561, - SPELL_INSANITY_TARGET = 57508, SPELL_CLONE_PLAYER = 57507, //casted on player during insanity SPELL_INSANITY_PHASING_1 = 57508, SPELL_INSANITY_PHASING_2 = 57509, @@ -362,15 +361,13 @@ class spell_herald_volzaj_insanity : public SpellScript { targets.remove_if([this](WorldObject* targetObj) -> bool { - return !targetObj || !targetObj->IsPlayer() || !targetObj->ToPlayer()->IsInCombatWith(GetCaster()) || + return !targetObj || !targetObj->IsPlayer() || !GetCaster()->IsInCombatWith(targetObj->ToPlayer()) || targetObj->GetDistance(GetCaster()) >= (MAX_VISIBILITY_DISTANCE * 2); }); } if (targets.empty()) - { return; - } // Start channel visual and set self as unnattackable caster->ToCreature()->AI()->Talk(SAY_INSANITY); @@ -387,16 +384,12 @@ class spell_herald_volzaj_insanity : public SpellScript { WorldObject* targetObj = *itr; if (!targetObj) - { continue; - } Player* plrTarget = targetObj->ToPlayer(); // This should never happen, spell has attribute SPELL_ATTR3_ONLY_TARGET_PLAYERS if (!plrTarget) - { continue; - } // phase mask plrTarget->CastSpell(plrTarget, InsanitySpells.at(insanityCounter), true); @@ -405,19 +398,17 @@ class spell_herald_volzaj_insanity : public SpellScript for (std::list::const_iterator itr2 = targets.begin(); itr2 != targets.end(); ++itr2) { // Should not make clone of current player target - Player const* plrClone = *itr2 ? (*itr2)->ToPlayer() : nullptr; - if (!plrClone || plrClone == plrTarget) - { + Player* plrClone = *itr2 ? (*itr2)->ToPlayer() : nullptr; + if (!plrClone || plrClone == plrTarget || !plrClone->IsAlive()) continue; - } if (Unit* summon = caster->SummonCreature(NPC_TWISTED_VISAGE, plrClone->GetPosition(), TEMPSUMMON_CORPSE_DESPAWN, 0)) { + plrClone->CastSpell(summon, SPELL_CLONE_PLAYER, true); + summon->AddThreat(plrTarget, 0.0f); summon->SetInCombatWith(plrTarget); plrTarget->SetInCombatWith(summon); - - plrTarget->CastSpell(summon, SPELL_CLONE_PLAYER, true); summon->SetPhaseMask(1 | (1 << (4 + insanityCounter)), true); summon->SetUInt32Value(UNIT_FIELD_MINDAMAGE, plrClone->GetUInt32Value(UNIT_FIELD_MINDAMAGE)); summon->SetUInt32Value(UNIT_FIELD_MAXDAMAGE, plrClone->GetUInt32Value(UNIT_FIELD_MAXDAMAGE)); diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp index e0c82fd6e..90781cfbc 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp @@ -94,6 +94,8 @@ struct boss_magus_telestra : public BossAI if (IsHeroic() && sGameEventMgr->IsActiveEvent(GAME_EVENT_WINTER_VEIL) && !me->HasAura(SPELL_WEAR_CHRISTMAS_HAT)) me->AddAura(SPELL_WEAR_CHRISTMAS_HAT, me); + + SetInvincibility(false); } uint32 GetData(uint32 data) const override @@ -184,6 +186,7 @@ struct boss_magus_telestra : public BossAI case EVENT_MAGUS_HEALTH2: if (me->HealthBelowPct(11)) { + SetInvincibility(true); me->CastSpell(me, SPELL_START_SUMMON_CLONES, false); events.ScheduleEvent(EVENT_MAGUS_RELOCATE, 3500ms); Talk(SAY_SPLIT); @@ -214,6 +217,7 @@ struct boss_magus_telestra : public BossAI me->CastSpell(me, SPELL_TELESTRA_BACK, true); me->RemoveAllAuras(); Talk(SAY_MERGE); + SetInvincibility(false); break; } diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index dcc760e74..4885663ff 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -474,6 +474,92 @@ public: } }; +/*###### +## Quest 11881: Load'er Up +######*/ + +// NPC 25969: Jenny +enum Jenny +{ + EVENT_JENNY_START_FOLLOW = 1, + EVENT_JENNY_MOVE_TO_FEZZIX = 2, + EVENT_JENNY_DESPAWN = 3, + SPELL_CRATES_CARRIED = 46340, + SPELL_DROP_CRATE = 46342, + SPELL_GIVE_JENNY_CREDIT = 46358, + NPC_FEZZIX_GEARTWIST = 25849 +}; + +struct npc_jenny : public FollowerAI +{ + npc_jenny(Creature* creature) : FollowerAI(creature) + { + Initialize(); + } + + void Initialize() + { + me->SetReactState(REACT_PASSIVE); + me->CastSpell(me, SPELL_CRATES_CARRIED); + + // can't update follow here, call later + _events.ScheduleEvent(EVENT_JENNY_START_FOLLOW, 1s); + } + + void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*type*/, SpellSchoolMask /*school*/) override + { + if (me->HasAura(SPELL_CRATES_CARRIED)) + me->CastSpell(me, SPELL_DROP_CRATE); + else + me->DespawnOrUnsummon(); + } + + void UpdateFollowerAI(uint32 diff) override + { + _events.Update(diff); + + if (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_JENNY_START_FOLLOW: + // This NPC only moves at its fixed speed_run rate in the db + // and does not inherit the speed of the target + if (TempSummon* summon = me->ToTempSummon()) + if (Unit* summonerUnit = summon->GetSummonerUnit()) + if (Player* summoner = summonerUnit->ToPlayer()) + StartFollow(summoner, 0, nullptr, true, false); + break; + case EVENT_JENNY_MOVE_TO_FEZZIX: + me->SetWalk(true); + me->GetMotionMaster()->MovePoint(0, _fezzix); + _events.ScheduleEvent(EVENT_JENNY_DESPAWN, 7s); + break; + case EVENT_JENNY_DESPAWN: + me->DespawnOrUnsummon(); + break; + } + } + } + + void MoveInLineOfSight(Unit* who) override + { + if (who->GetEntry() == NPC_FEZZIX_GEARTWIST && me->IsWithinDistInMap(who, 15.0f)) + { + if (TempSummon* s = me->ToTempSummon()) + if (Unit* u = s->GetSummonerUnit()) + if (Player* p = u->ToPlayer()) + me->CastSpell(p, SPELL_GIVE_JENNY_CREDIT); + SetFollowComplete(true); + _fezzix = who->GetPosition(); + _events.ScheduleEvent(EVENT_JENNY_MOVE_TO_FEZZIX, 1s); + } + } +private: + EventMap _events; + Position _fezzix; +}; + /*###### ## Quest 11590: Abduction ######*/ @@ -2059,4 +2145,5 @@ void AddSC_borean_tundra() new npc_hidden_cultist(); RegisterSpellScript(spell_q11719_bloodspore_ruination_45997); new npc_bloodmage_laurith(); + RegisterCreatureAI(npc_jenny); } diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp index 3493ce2fa..1764f9561 100644 --- a/src/server/scripts/Northrend/zone_zuldrak.cpp +++ b/src/server/scripts/Northrend/zone_zuldrak.cpp @@ -23,6 +23,8 @@ #include "ScriptedGossip.h" #include "SpellAuras.h" #include "SpellInfo.h" +#include "SpellScript.h" +#include "SpellScriptLoader.h" #include "Vehicle.h" // Ours @@ -240,6 +242,7 @@ enum overlordDrakuru 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, @@ -866,6 +869,51 @@ public: } }; +enum ScourgeDisguiseInstability +{ + SCOURGE_DISGUISE_FAILING_MESSAGE_1 = 28552, // Scourge Disguise Failing! Find a safe place! + SCOURGE_DISGUISE_FAILING_MESSAGE_2 = 28758, // Scourge Disguise Failing! Run for cover! + SCOURGE_DISGUISE_FAILING_MESSAGE_3 = 28759, // Scourge Disguise Failing! Hide quickly! +}; +std::vector const scourgeDisguiseTextIDs = { SCOURGE_DISGUISE_FAILING_MESSAGE_1, SCOURGE_DISGUISE_FAILING_MESSAGE_2, SCOURGE_DISGUISE_FAILING_MESSAGE_3 }; + +class spell_scourge_disguise_instability : public AuraScript +{ + PrepareAuraScript(spell_scourge_disguise_instability); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SCOURGE_DISGUISE_EXPIRING }); + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + SetDuration(urand(3 * MINUTE * IN_MILLISECONDS, 5 * MINUTE * IN_MILLISECONDS)); + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + { + if (Player* player = caster->ToPlayer()) + { + if (player->HasAnyAuras(SPELL_SCOURGE_DISGUISE, SPELL_SCOURGE_DISGUISE_INSTANT_CAST)) + { + uint32 textId = Acore::Containers::SelectRandomContainerElement(scourgeDisguiseTextIDs); + player->Unit::Whisper(textId, player, true); + player->CastSpell(player, SPELL_SCOURGE_DISGUISE_EXPIRING, true); + } + } + } + } + + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_scourge_disguise_instability::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectRemove += AuraEffectRemoveFn(spell_scourge_disguise_instability::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + void AddSC_zuldrak() { // Ours @@ -880,4 +928,6 @@ void AddSC_zuldrak() new npc_crusade_recruit(); new go_scourge_enclosure(); new npc_storm_cloud(); + + RegisterSpellScript(spell_scourge_disguise_instability); } diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index 44b35a35c..3298acc92 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -899,6 +899,74 @@ class spell_warr_retaliation : public AuraScript } }; +// 29707 - Heroic Strike (Rank 10) +// 30324 - Heroic Strike (Rank 11) +// 47449 - Heroic Strike (Rank 12) +// 47450 - Heroic Strike (Rank 13) +enum DazeSpells +{ + ICON_GENERIC_DAZE = 15, + SPELL_GENERIC_AFTERMATH = 18118, +}; + +class spell_warr_heroic_strike : public SpellScript +{ + PrepareSpellScript(spell_warr_heroic_strike); + + void HandleOnHit() + { + Unit* target = GetHitUnit(); + if (!target) + return; + std::list AuraEffectList = target->GetAuraEffectsByType(SPELL_AURA_MOD_DECREASE_SPEED); + bool bonusDamage = false; + for (AuraEffect* eff : AuraEffectList) + { + const SpellInfo* spellInfo = eff->GetSpellInfo(); + if (!spellInfo) + continue; + + // Warrior Spells: Piercing Howl or Dazed (29703) + if (spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && (spellInfo->SpellFamilyFlags[1] & (0x20 | 0x200000))) + { + bonusDamage = true; + break; + } + + // Generic Daze: icon 15 with mechanic daze or snare + if ((spellInfo->SpellIconID == ICON_GENERIC_DAZE) + && ((spellInfo->Mechanic == MECHANIC_DAZE || spellInfo->HasEffectMechanic(MECHANIC_DAZE)) + || (spellInfo->Mechanic == MECHANIC_SNARE || spellInfo->HasEffectMechanic(MECHANIC_SNARE)) + ) + ) + { + bonusDamage = true; + break; + } + + if ((spellInfo->Id == SPELL_GENERIC_AFTERMATH) + || (spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfo->SpellFamilyFlags[1] & 0x40)) // Blast Wave + || (spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && (spellInfo->SpellFamilyFlags[2] & 0x4000)) // Avenger's Shield + ) + { + bonusDamage = true; + break; + } + } + if (bonusDamage) + { + int32 damage = GetHitDamage(); + AddPct(damage, 35); // "Causes ${0.35*$m1} additional damage against Dazed targets." + SetHitDamage(damage); + } + } + + void Register() override + { + OnHit += SpellHitFn(spell_warr_heroic_strike::HandleOnHit); + } +}; + void AddSC_warrior_spell_scripts() { RegisterSpellScript(spell_warr_mocking_blow); @@ -925,4 +993,5 @@ void AddSC_warrior_spell_scripts() RegisterSpellScript(spell_warr_vigilance); RegisterSpellScript(spell_warr_vigilance_trigger); RegisterSpellScript(spell_warr_t3_prot_8p_bonus); + RegisterSpellScript(spell_warr_heroic_strike); }