diff --git a/.github/README.md b/.github/README.md index 8953b4ca0..995688155 100644 --- a/.github/README.md +++ b/.github/README.md @@ -4,6 +4,7 @@ [![CodeFactor](https://www.codefactor.io/repository/github/azerothcore/azerothcore-wotlk/badge)](https://www.codefactor.io/repository/github/azerothcore/azerothcore-wotlk) [![StackOverflow](http://img.shields.io/badge/stackoverflow-azerothcore-blue.svg?logo=stackoverflow)](https://stackoverflow.com/questions/tagged/azerothcore?sort=newest "Ask / browse questions here") [![Discord](https://img.shields.io/discord/217589275766685707?logo=discord&logoColor=white)](https://discord.gg/gkt4y2x "Our community hub on Discord") +[![Bounties on BountyHub](https://img.shields.io/badge/Bounties-on%20BountyHub-yellow)](https://www.bountyhub.dev/bounties?repo=azerothcore) ## Build Status diff --git a/data/sql/updates/db_world/2025_11_17_04.sql b/data/sql/updates/db_world/2025_11_17_04.sql new file mode 100644 index 000000000..7cc968b76 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_17_04.sql @@ -0,0 +1,10 @@ +-- DB update 2025_11_17_03 -> 2025_11_17_04 +-- +DELETE FROM `acore_string` WHERE `entry` IN (5088, 5089); +INSERT INTO `acore_string` (`entry`, `content_default`) VALUES +(5088, 'Quest: {} ({}) \nStatus: {}'), +(5089, 'Quest can\'t be taken!'); + +DELETE FROM `command` WHERE `name` = 'quest status'; +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('quest status', 2, 'Syntax: .quest status $id [$name]. Displays the selected player\'s status for the specified quest.'); diff --git a/data/sql/updates/db_world/2025_11_18_00.sql b/data/sql/updates/db_world/2025_11_18_00.sql new file mode 100644 index 000000000..1954dd901 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_18_00.sql @@ -0,0 +1,45 @@ +-- DB update 2025_11_17_04 -> 2025_11_18_00 +-- +DELETE FROM `smart_scripts` WHERE (`source_type` = 0) AND (`entryorguid` IN (28732, 28733, 28734)); +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 +(28732, 0, 0, 0, 0, 0, 100, 0, 2000, 5000, 6000, 8000, 0, 0, 11, 52532, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Warrior - In Combat - Cast \'Strike\''), +(28732, 0, 1, 0, 0, 0, 100, 0, 2000, 10000, 15000, 15000, 0, 0, 11, 49806, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Warrior - In Combat - Cast \'Cleave\''), +(28733, 0, 0, 0, 0, 0, 100, 0, 0, 0, 2000, 2500, 0, 0, 11, 52534, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Shadowcaster - In Combat - Cast \'Shadow Bolt\''), +(28733, 0, 1, 0, 0, 0, 100, 0, 6000, 12000, 12000, 20000, 0, 0, 11, 52535, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Shadowcaster - In Combat - Cast \'Shadow Nova\''), +(28734, 0, 0, 0, 67, 0, 100, 0, 7000, 7000, 7000, 7000, 0, 5, 11, 52540, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Skirmisher - On Behind Target - Cast \'Backstab\''), +(28734, 0, 1, 0, 0, 0, 100, 0, 5000, 10000, 15000, 15000, 0, 0, 11, 52536, 0, 0, 0, 0, 0, 5, 40, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Skirmisher - In Combat - Cast \'Fixate Trigger\''); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28729) AND (`source_type` = 0) AND (`id` IN (6)); +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28730) AND (`source_type` = 0) AND (`id` IN (5)); +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28731) AND (`source_type` = 0) AND (`id` IN (6)); + +SET @CGUID := 12758; + +DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+8; +INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`,`dynamicflags`, `VerifiedBuild`) VALUES +(@CGUID+0, 28731, 601, 4277, 4405, 3, 1, 0, 543.82611083984375, 665.12335205078125, 776.24530029296875, 1.553343057632446289, 7200, 0, 0, 11210, 0, 0, 0, 0, 0, 64395), -- 28731 (Area: 4405 - Difficulty: 1) CreateObject1 -- silthik +(@CGUID+1, 28730, 601, 4277, 4405, 3, 1, 0, 526.66357421875, 663.6053466796875, 775.80523681640625, 1.239183783531188964, 7200, 0, 0, 11210, 0, 0, 0, 0, 0, 64395), -- 28730 (Area: 4405 - Difficulty: 1) CreateObject1 gashra +(@CGUID+2, 28729, 601, 4277, 4405, 3, 1, 0, 511.809722900390625, 666.493408203125, 776.27813720703125, 0.977384388446807861, 7200, 0, 0, 11210, 0, 0, 0, 0, 0, 64395), -- 28729 (Area: 4405 - Difficulty: 1) CreateObject1 -- narjil +(@CGUID+3, 28733, 601, 4277, 4405, 3, 1, 0, 549.69268798828125, 662.0069580078125, 776.99273681640625, 1.640609502792358398,7200, 0, 0, 5028, 6525, 0, 0, 0, 0, 64395), +(@CGUID+4, 28734, 601, 4277, 4405, 3, 1, 0, 550.046142578125, 668.1309814453125, 776.2789306640625, 1.65806281566619873, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 64395), +(@CGUID+5, 28732, 601, 4277, 4405, 3, 1, 0, 531.03082275390625, 658.173095703125, 776.2396240234375, 1.343903541564941406, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 64395), +(@CGUID+6, 28734, 601, 4277, 4405, 3, 1, 0, 521.81475830078125, 659.4708251953125, 776.3131103515625, 1.186823844909667968, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 64395), +(@CGUID+7, 28733, 601, 4277, 4405, 3, 1, 0, 506.17828369140625, 669.9266357421875, 776.3056640625, 0.855211317539215087, 7200, 0, 0, 5028, 6525, 0, 0, 0, 0, 64395), +(@CGUID+8, 28732, 601, 4277, 4405, 3, 1, 0, 506.515625, 664.38018798828125, 776.97589111328125, 0.92502450942993164, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 64395); + +-- Prevent combat assist +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|33554432 WHERE `entry` IN (28732, 28733, 28734, 28731, 28730, 28729, 28684, 31612, 31616, 31615, 31617, 31608, 31605, 31606); + +DELETE FROM `creature_formations` WHERE `leaderGUID` IN (12758, 12759, 12760); +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `groupAI`) VALUES +(12758, 12758, 11), +(12758, 12762, 11), +(12758, 12761, 11), + +(12759, 12759, 11), +(12759, 12763, 11), +(12759, 12764, 11), + +(12760, 12760, 11), +(12760, 12765, 11), +(12760, 12766, 11); diff --git a/data/sql/updates/db_world/2025_11_18_01.sql b/data/sql/updates/db_world/2025_11_18_01.sql new file mode 100644 index 000000000..c9c429617 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_18_01.sql @@ -0,0 +1,3 @@ +-- DB update 2025_11_18_00 -> 2025_11_18_01 +-- despawn on evade +UPDATE `creature_template` SET `flags_extra` = `flags_extra`|0x80000000 WHERE `entry` IN (26631, 31350); diff --git a/data/sql/updates/db_world/2025_11_18_02.sql b/data/sql/updates/db_world/2025_11_18_02.sql new file mode 100644 index 000000000..15aac3ed2 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_18_02.sql @@ -0,0 +1,5 @@ +-- DB update 2025_11_18_01 -> 2025_11_18_02 +-- +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 17) AND (`SourceGroup` = 0) AND (`SourceEntry` = 43997) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 31) AND (`ConditionTarget` = 1) AND (`ConditionValue1` = 3) AND (`ConditionValue2` = 24533) AND (`ConditionValue3` = 0); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(17, 0, 43997, 0, 0, 31, 1, 3, 24533, 0, 0, 0, 0, '', 'target must be \'Dragonflayer Defender\''); diff --git a/data/sql/updates/db_world/2025_11_20_00.sql b/data/sql/updates/db_world/2025_11_20_00.sql new file mode 100644 index 000000000..9e5bfd987 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_20_00.sql @@ -0,0 +1,14 @@ +-- DB update 2025_11_18_02 -> 2025_11_20_00 +-- +DELETE FROM `creature_summon_groups` WHERE `summonerId` = 29310 AND `summonerType` = 0 AND `groupId` = 2; +INSERT INTO `creature_summon_groups`(`summonerId`, `summonerType`, `groupId`, `entry`, `position_x`, `position_y`, `position_z`, `orientation`, `summonType`, `summonTime`, `Comment`) VALUES +(29310, 0, 2, 30111, 434.00433349609375, -702.8974609375, -17.9579715728759765, 3.124139308929443359, 8, 0, 'Jedoga Shadowseeker - Twilight Worshipper'), +(29310, 0, 2, 30111, 429.734161376953125, -712.18231201171875, -17.9568767547607421, 2.862339973449707031, 8, 0, 'Jedoga Shadowseeker - Twilight Worshipper'), +(29310, 0, 2, 30111, 388.307830810546875, -766.78399658203125, -17.9607582092285156, 2.094395160675048828, 8, 0, 'Jedoga Shadowseeker - Twilight Worshipper'), +(29310, 0, 2, 30111, 392.577484130859375, -765.63641357421875, -17.9589138031005859, 2.251474618911743164, 8, 0, 'Jedoga Shadowseeker - Twilight Worshipper'), +(29310, 0, 2, 30111, 381.83843994140625, -773.3897705078125, -17.9530143737792968, 1.762782573699951171, 8, 0, 'Jedoga Shadowseeker - Twilight Worshipper'), +(29310, 0, 2, 30111, 439.982635498046875, -699.070068359375, -17.9527797698974609, 3.193952560424804687, 8, 0, 'Jedoga Shadowseeker - Twilight Worshipper'), +(29310, 0, 2, 30111, 394.354156494140625, -760.810791015625, -17.9546241760253906, 2.443460941314697265, 8, 0, 'Jedoga Shadowseeker - Twilight Worshipper'), +(29310, 0, 2, 30111, 434.4365234375, -709.4752197265625, -17.961435317993164, 2.94960641860961914, 8, 0, 'Jedoga Shadowseeker - Twilight Worshipper'), +(29310, 0, 2, 30111, 387.0694580078125, -770.94964599609375, -17.957611083984375, 1.972222089767456054, 8, 0, 'Jedoga Shadowseeker - Twilight Worshipper'), +(29310, 0, 2, 30111, 427.302093505859375, -717.3992919921875, -17.9517745971679687, 2.705260276794433593, 8, 0, 'Jedoga Shadowseeker - Twilight Worshipper'); diff --git a/data/sql/updates/db_world/2025_11_20_01.sql b/data/sql/updates/db_world/2025_11_20_01.sql new file mode 100644 index 000000000..ad17c2b25 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_20_01.sql @@ -0,0 +1,4 @@ +-- DB update 2025_11_20_00 -> 2025_11_20_01 +-- +UPDATE `creature_addon` SET `bytes2` = 1, `auras` = '31261' WHERE `guid` IN (114372, 114373, 114381); +UPDATE `creature` SET `unit_flags` = `unit_flags`|256|512|536870912, `VerifiedBuild` = 64502 WHERE `guid` IN (114372, 114373, 114381) AND `id1` = 30148; diff --git a/data/sql/updates/db_world/2025_11_20_02.sql b/data/sql/updates/db_world/2025_11_20_02.sql new file mode 100644 index 000000000..b8b12eb91 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_20_02.sql @@ -0,0 +1,5 @@ +-- DB update 2025_11_20_01 -> 2025_11_20_02 +-- +UPDATE `creature_template` SET `speed_run` = 1.142857 WHERE `entry` = 31356; +UPDATE `creature_template` SET `speed_run` = 0.428571 WHERE `entry` = 31873; +UPDATE `creature_template` SET `speed_run` = 0.714285 WHERE `entry` = 31348; diff --git a/data/sql/updates/db_world/2025_11_20_03.sql b/data/sql/updates/db_world/2025_11_20_03.sql new file mode 100644 index 000000000..5d252067d --- /dev/null +++ b/data/sql/updates/db_world/2025_11_20_03.sql @@ -0,0 +1,10 @@ +-- DB update 2025_11_20_02 -> 2025_11_20_03 +-- +UPDATE `creature_template` SET `AIName` = '', `npcflag` = 16777216 WHERE `entry` = 26809; +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 26809) AND (`source_type` = 0); + +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` = 26809; +INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `cast_flags`, `user_type`) VALUES +(26809, 47416, 2, 1); + +UPDATE `spell_dbc` SET `Effect_1` = 24, `EffectBasePoints_1` = 1, `ImplicitTargetA_1` = 25, `EffectItemType_1` = 36765 WHERE `id` = 47416; diff --git a/data/sql/updates/db_world/2025_11_20_04.sql b/data/sql/updates/db_world/2025_11_20_04.sql new file mode 100644 index 000000000..3eafbca14 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_20_04.sql @@ -0,0 +1,11 @@ +-- DB update 2025_11_20_03 -> 2025_11_20_04 +-- +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 17) AND (`SourceGroup` = 0) AND (`SourceEntry` = 47431) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 29) AND (`ConditionTarget` = 1) AND (`ConditionValue1` = 26359) 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 +(17, 0, 47431, 0, 0, 29, 1, 26359, 0, 0, 0, 0, 0, '', 'Capture Jormungar Spawn require Ice Heart Jormungar Spawn'); + +UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE `entry` = 190510; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 190510) 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 +(190510, 1, 0, 0, 63, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 1000, 0, 0, 0, 0, 0, 19, 26359, 5, 0, 0, 0, 0, 0, 0, 'Captured Jormungar Spawn - On Just Created - Despawn In 1000 ms'); diff --git a/data/sql/updates/db_world/2025_11_21_00.sql b/data/sql/updates/db_world/2025_11_21_00.sql new file mode 100644 index 000000000..df1eaf216 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_21_00.sql @@ -0,0 +1,15 @@ +-- DB update 2025_11_20_04 -> 2025_11_21_00 +-- +SET @GUID := 1161; +DELETE FROM `gameobject` WHERE `id` = 193997 AND `guid` BETWEEN @GUID AND @GUID+9; +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`) VALUES +(@GUID+0, 193997, 571, 0, 0, 1, 1, 7330.44, -2212.68, 800.483, 4.25861, 0, 0, 0.848046, -0.529922, 120, 255, 1, '', 0), +(@GUID+1, 193997, 571, 0, 0, 1, 1, 7211.5, -2373.86, 781.449, 4.38078, 0, 0, 0.814114, -0.580705, 120, 255, 1, '', 0), +(@GUID+2, 193997, 571, 0, 0, 1, 1, 6973.8, -2096.83, 777.638, 3.26377, 0, 0, 0.998135, -0.0610507, 120, 255, 1, '', 0), +(@GUID+3, 193997, 571, 0, 0, 1, 1, 7310.71, -2812.07, 798.081, 1.5708, 0, 0, 0.707108, 0.707106, 120, 255, 1, '', 0), +(@GUID+4, 193997, 571, 0, 0, 1, 1, 7301.01, -2746.12, 749.508, 0.157079, 0, 0, 0.0784588, 0.996917, 120, 255, 1, '', 0), +(@GUID+5, 193997, 571, 0, 0, 1, 1, 7550.37, -3154.98, 840.146, 4.41568, 0, 0, 0.803858, -0.594822, 120, 255, 1, '', 0), +(@GUID+6, 193997, 571, 0, 0, 1, 1, 7177.29, -3071.11, 862.298, 0.680677, 0, 0, 0.333806, 0.942642, 120, 255, 1, '', 0), +(@GUID+7, 193997, 571, 0, 0, 1, 1, 7694.28, -3154.72, 869.769, 3.76991, 0, 0, 0.951057, -0.309016, 120, 255, 1, '', 0), +(@GUID+8, 193997, 571, 0, 0, 1, 1, 7155.12, -2096.03, 764.428, 2.53072, 0, 0, 0.953716, 0.300709, 300, 100, 1, '', 0), +(@GUID+9, 193997, 571, 0, 0, 1, 1, 7218.2, -2139.83, 863.085, -1.09956, 0, 0, -0.5225, 0.852639, 300, 100, 1, '', 0); diff --git a/data/sql/updates/db_world/2025_11_21_01.sql b/data/sql/updates/db_world/2025_11_21_01.sql new file mode 100644 index 000000000..b779b8100 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_21_01.sql @@ -0,0 +1,3 @@ +-- DB update 2025_11_21_00 -> 2025_11_21_01 +-- +UPDATE `gameobject_loot_template` SET `QuestRequired` = 0 WHERE `Item` = 44724; diff --git a/data/sql/updates/db_world/2025_11_21_02.sql b/data/sql/updates/db_world/2025_11_21_02.sql new file mode 100644 index 000000000..355d90f53 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_21_02.sql @@ -0,0 +1,10 @@ +-- DB update 2025_11_21_01 -> 2025_11_21_02 +-- +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` = 54581; +DELETE FROM `spell_script_names` WHERE `spell_id` = 54581; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(54581, 'spell_mammoth_explosion'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 29402) AND (`source_type` = 0) AND (`id` IN (2)); +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 +(29402, 0, 2, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 41, 3000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ironwool Mammoth - On Spellhit \'Throw U.D.E.D.\' - Despawn In 3000 ms'); diff --git a/data/sql/updates/db_world/2025_11_21_03.sql b/data/sql/updates/db_world/2025_11_21_03.sql new file mode 100644 index 000000000..a53a7c4e5 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_21_03.sql @@ -0,0 +1,75 @@ +-- DB update 2025_11_21_02 -> 2025_11_21_03 +-- Update gameobject 'Everfrost Chip' with sniffed values +-- updated spawns +DELETE FROM `gameobject` WHERE (`id` IN (193997)) AND (`guid` IN (1161, 1162, 1163, 1164, 1165, 1167, 1168, 1169, 1170, 221001, 221003)); +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 +(1161, 193997, 571, 0, 0, 1, 1, 7330.43603515625, -2212.681884765625, 800.4833984375, 4.258606910705566406, 0, 0, -0.84804725646972656, 0.529920578002929687, 120, 255, 1, "", 47720, NULL), +(1162, 193997, 571, 0, 0, 1, 1, 7211.49853515625, -2373.85595703125, 781.44903564453125, 4.380776405334472656, 0, 0, -0.81411552429199218, 0.580702960491180419, 120, 255, 1, "", 46779, NULL), +(1163, 193997, 571, 0, 0, 1, 1, 6973.80322265625, -2096.8271484375, 777.637451171875, 3.263772249221801757, 0, 0, -0.99813461303710937, 0.061051756143569946, 120, 255, 1, "", 47720, NULL), +(1164, 193997, 571, 0, 0, 1, 1, 7310.7119140625, -2812.06591796875, 798.08099365234375, 1.570795774459838867, 0, 0, 0.707106590270996093, 0.707106947898864746, 120, 255, 1, "", 47720, NULL), +(1165, 193997, 571, 0, 0, 1, 1, 7301.00634765625, -2746.119873046875, 749.50848388671875, 0.15707901120185852, 0, 0, 0.078458786010742187, 0.996917366981506347, 120, 255, 1, "", 46368, NULL), +(1167, 193997, 571, 0, 0, 1, 1, 7177.28662109375, -3071.111083984375, 862.29815673828125, 0.680676698684692382, 0, 0, 0.333806037902832031, 0.942641794681549072, 120, 255, 1, "", 50664, NULL), +(1168, 193997, 571, 0, 0, 1, 1, 7694.28369140625, -3154.7197265625, 869.7685546875, 3.769911527633666992, 0, 0, -0.95105648040771484, 0.309017121791839599, 120, 255, 1, "", 52237, NULL), +(1169, 193997, 571, 0, 0, 1, 1, 7155.11767578125, -2096.0322265625, 764.4278564453125, 2.530723094940185546, 0, 0, 0.953716278076171875, 0.300707906484603881, 120, 255, 1, "", 48632, NULL), +(1170, 193997, 571, 0, 0, 1, 1, 7218.19775390625, -2139.83154296875, 863.0850830078125, 5.183629035949707031, 0, 0, -0.52249813079833984, 0.852640450000762939, 120, 255, 1, "", 47720, NULL), +(221001, 193997, 571, 0, 0, 1, 1, 7558.2021484375, -3285.407470703125, 879.133544921875, 2.635444164276123046, 0, 0, 0.96814727783203125, 0.250381410121917724, 120, 255, 1, "", 52237, NULL), +(221003, 193997, 571, 0, 0, 1, 1, 7912.7431640625, -3406.700439453125, 865.29608154296875, 1.343901276588439941, 0, 0, 0.622513771057128906, 0.78260880708694458, 120, 255, 1, "", 46779, NULL); + +-- new spawns +DELETE FROM `gameobject` WHERE (`id` IN (193997)) AND (`guid` IN (3721, 3722, 3723, 3724, 3725, 3726, 3727, 3728, 3729, 3730, 3731, 3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739, 3740, 3741, 3742, 3743, 3744, 3745, 3746, 3747, 3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755, 3756, 3757, 3758, 3759, 3760, 3761)); +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 +(3721, 193997, 571, 0, 0, 1, 1, 6966.74658203125, -1889.3590087890625, 895.60174560546875, 1.099556446075439453, 0, 0, 0.522498130798339843, 0.852640450000762939, 120, 255, 1, "", 48632, NULL), +(3722, 193997, 571, 0, 0, 1, 1, 6981.6015625, -2300.420654296875, 796.2930908203125, 2.426007747650146484, 0, 0, 0.936672210693359375, 0.350207358598709106, 120, 255, 1, "", 53788, NULL), +(3723, 193997, 571, 0, 0, 1, 1, 6991.40185546875, -1943.47314453125, 855.679931640625, 0.174532130360603332, 0, 0, 0.087155342102050781, 0.996194720268249511, 120, 255, 1, "", 50664, NULL), +(3724, 193997, 571, 0, 0, 1, 1, 6994.66064453125, -2035.5594482421875, 864.358642578125, 4.293513298034667968, 0, 0, -0.8386697769165039, 0.544640243053436279, 120, 255, 1, "", 48632, NULL), +(3725, 193997, 571, 0, 0, 1, 1, 6996.35595703125, -2136.819580078125, 739.002197265625, 3.141592741012573242, 0, 0, -1, 0, 120, 255, 1, "", 46779, NULL), +(3726, 193997, 571, 0, 0, 1, 1, 7051.85888671875, -2172.247314453125, 768.96563720703125, 4.939284324645996093, 0, 0, -0.6225137710571289, 0.78260880708694458, 120, 255, 1, "", 48632, NULL), +(3727, 193997, 571, 0, 0, 1, 1, 7065.01416015625, -2197.10009765625, 765.82073974609375, 0.226892471313476562, 0, 0, 0.113203048706054687, 0.993571877479553222, 120, 255, 1, "", 48019, NULL), +(3728, 193997, 571, 0, 0, 1, 1, 7087.513671875, -2469.864990234375, 1020.7822265625, 0.453785061836242675, 0, 0, 0.224950790405273437, 0.974370121955871582, 120, 255, 1, "", 46779, NULL), +(3729, 193997, 571, 0, 0, 1, 1, 7091.23681640625, -2341.15966796875, 846.66546630859375, 1.448621988296508789, 0, 0, 0.662619590759277343, 0.748956084251403808, 120, 255, 1, "", 50664, NULL), +(3730, 193997, 571, 0, 0, 1, 1, 7099.56982421875, -1978.443603515625, 769.72406005859375, 0.174532130360603332, 0, 0, 0.087155342102050781, 0.996194720268249511, 120, 255, 1, "", 47720, NULL), +(3731, 193997, 571, 0, 0, 1, 1, 7128.27685546875, -2301.65625, 794.41070556640625, 3.78736734390258789, 0, 0, -0.94832324981689453, 0.317305892705917358, 120, 255, 1, "", 48019, NULL), +(3732, 193997, 571, 0, 0, 1, 1, 7131.44287109375, -1925.8997802734375, 861.8017578125, 4.869470596313476562, 0, 0, -0.64944744110107421, 0.760406434535980224, 120, 255, 1, "", 48632, NULL), +(3733, 193997, 571, 0, 0, 1, 1, 7136.599609375, -3013.7421875, 925.5281982421875, 0.523597896099090576, 0, 0, 0.258818626403808593, 0.965925931930541992, 120, 255, 1, "", 52237, NULL), +(3734, 193997, 571, 0, 0, 1, 1, 7165.87353515625, -2420.04345703125, 893.84649658203125, 2.251473426818847656, 0, 0, 0.902585029602050781, 0.430511653423309326, 120, 255, 1, "", 46368, NULL), +(3735, 193997, 571, 0, 0, 1, 1, 7169.20556640625, -3040.478759765625, 877.94464111328125, 3.176533222198486328, 0, 0, -0.999847412109375, 0.017469281330704689, 120, 255, 1, "", 50664, NULL), +(3736, 193997, 571, 0, 0, 1, 1, 7181.78857421875, -2185.91015625, 761.67608642578125, 5.969027042388916015, 0, 0, -0.1564340591430664, 0.987688362598419189, 120, 255, 1, "", 48632, NULL), +(3737, 193997, 571, 0, 0, 1, 1, 7187.119140625, -2160, 772.549560546875, 0.226892471313476562, 0, 0, 0.113203048706054687, 0.993571877479553222, 120, 255, 1, "", 50664, NULL), +(3738, 193997, 571, 0, 0, 1, 1, 7188.72509765625, -2656.859375, 812.5784912109375, 3.211419343948364257, 0, 0, -0.9993906021118164, 0.034906134009361267, 120, 255, 1, "", 50375, NULL), +(3739, 193997, 571, 0, 0, 1, 1, 7204.47900390625, -3115.85888671875, 839.8372802734375, 1.099556446075439453, 0, 0, 0.522498130798339843, 0.852640450000762939, 120, 255, 1, "", 50664, NULL), +(3740, 193997, 571, 0, 0, 1, 1, 7218.46337890625, -2811.569580078125, 821.97149658203125, 3.001946926116943359, 0, 0, 0.997563362121582031, 0.069766148924827575, 120, 255, 1, "", 52237, NULL), +(3741, 193997, 571, 0, 0, 1, 1, 7234.15869140625, -2995.100830078125, 845.96881103515625, 2.617989301681518554, 0, 0, 0.965925216674804687, 0.258821308612823486, 120, 255, 1, "", 47720, NULL), +(3742, 193997, 571, 0, 0, 1, 1, 7255.27197265625, -2932.182373046875, 913.513671875, 0.645771682262420654, 0, 0, 0.317304611206054687, 0.948323667049407958, 120, 255, 1, "", 50375, NULL), +(3743, 193997, 571, 0, 0, 1, 1, 7294.00244140625, -2323.291748046875, 750.2393798828125, 1.012289404869079589, 0, 0, 0.484808921813964843, 0.87462007999420166, 120, 255, 1, "", 52237, NULL), +(3744, 193997, 571, 0, 0, 1, 1, 7323.62353515625, -3240.092041015625, 843.68536376953125, 4.223697185516357421, 0, 0, -0.85716724395751953, 0.515038192272186279, 120, 255, 1, "", 52237, NULL), +(3745, 193997, 571, 0, 0, 1, 1, 7369.80322265625, -3274.489990234375, 855.65020751953125, 5.410521507263183593, 0, 0, -0.42261791229248046, 0.906307935714721679, 120, 255, 1, "", 52237, NULL), +(3746, 193997, 571, 0, 0, 1, 1, 7372.5302734375, -2198.384033203125, 846.09051513671875, 1.692969322204589843, 0, 0, 0.748955726623535156, 0.662620067596435546, 120, 255, 1, "", 51666, NULL), +(3747, 193997, 571, 0, 0, 1, 1, 7418.05126953125, -2554.40576171875, 749.71136474609375, 3.752462387084960937, 0, 0, -0.95371627807617187, 0.300707906484603881, 120, 255, 1, "", 53788, NULL), +(3748, 193997, 571, 0, 0, 1, 1, 7440.8046875, -2885.421875, 822.1888427734375, 3.822272777557373046, 0, 0, -0.94264125823974609, 0.333807557821273803, 120, 255, 1, "", 51739, NULL), +(3749, 193997, 571, 0, 0, 1, 1, 7453.85693359375, -2422.166015625, 757.46722412109375, 2.862335443496704101, 0, 0, 0.990267753601074218, 0.139175355434417724, 120, 255, 1, "", 50664, NULL), +(3750, 193997, 571, 0, 0, 1, 1, 7457.181640625, -2679.326416015625, 807.17596435546875, 0.069811686873435974, 0, 0, 0.034898757934570312, 0.999390840530395507, 120, 255, 1, "", 46368, NULL), +(3751, 193997, 571, 0, 0, 1, 1, 7459.62353515625, -3428.14892578125, 1016.05328369140625, 4.817109584808349609, 0, 0, -0.66913032531738281, 0.74314504861831665, 120, 255, 1, "", 52237, NULL), +(3752, 193997, 571, 0, 0, 1, 1, 7462.48876953125, -2339.7900390625, 801.07098388671875, 1.32644820213317871, 0, 0, 0.615660667419433593, 0.788011372089385986, 120, 255, 1, "", 50375, NULL), +(3753, 193997, 571, 0, 0, 1, 1, 7463.67822265625, -3317.8291015625, 897.6239013671875, 1.32644820213317871, 0, 0, 0.615660667419433593, 0.788011372089385986, 120, 255, 1, "", 51739, NULL), +(3754, 193997, 571, 0, 0, 1, 1, 7474.890625, -2936.453125, 911.251220703125, 3.019413232803344726, 0, 0, 0.998134613037109375, 0.061051756143569946, 120, 255, 1, "", 52237, NULL), +(3755, 193997, 571, 0, 0, 1, 1, 7499.189453125, -2326.282958984375, 873.71429443359375, 3.822272777557373046, 0, 0, -0.94264125823974609, 0.333807557821273803, 120, 255, 1, "", 50664, NULL), +(3756, 193997, 571, 0, 0, 1, 1, 7527.39404296875, -2460.450439453125, 794.4395751953125, 5.166176319122314453, 0, 0, -0.52991867065429687, 0.84804844856262207, 120, 255, 1, "", 46368, NULL), +(3757, 193997, 571, 0, 0, 1, 1, 7543.634765625, -3157.632080078125, 838.59716796875, 2.181660413742065429, 0, 0, 0.887010574340820312, 0.461749136447906494, 120, 255, 1, "", 52237, NULL), +(3758, 193997, 571, 0, 0, 1, 1, 7547.81689453125, -3288.013427734375, 885.25384521484375, 2.042035102844238281, 0, 0, 0.852640151977539062, 0.522498607635498046, 120, 255, 1, "", 50664, NULL), +(3759, 193997, 571, 0, 0, 1, 1, 7558.64404296875, -3311.80029296875, 941.5128173828125, 0.331610709428787231, 0, 0, 0.16504669189453125, 0.986285746097564697, 120, 255, 1, "", 50664, NULL), +(3760, 193997, 571, 0, 0, 1, 1, 7620.017578125, -3140.361083984375, 856.6376953125, 5.567600727081298828, 0, 0, -0.35020732879638671, 0.936672210693359375, 120, 255, 1, "", 52237, NULL), +(3761, 193997, 571, 0, 0, 1, 1, 7638.5, -2502.473876953125, 943.86505126953125, 2.478367090225219726, 0, 0, 0.94551849365234375, 0.325568377971649169, 120, 255, 1, "", 52237, NULL); + +-- remove duplicate spawns +DELETE FROM `gameobject` WHERE (`id` IN (193997)) AND (`guid` IN (221003, 221004)); +DELETE FROM `gameobject_addon` WHERE (`guid` IN (221003, 221004)); + +-- remaining spawns (no sniffed values available) +-- (`guid` IN (221000, 221002, 1166)) + +-- update phasemask of remaining spawns +UPDATE `gameobject` SET `phaseMask` = 1 WHERE (`id` IN (193997)) AND (`guid` IN (221000, 221002, 1166)); + +-- clear existing pool (pooling probably needs to be set up from scratch for all the new spawns instead if necessary) +DELETE FROM `pool_gameobject` WHERE `pool_entry` = 383 AND (`guid` IN (221000, 221001, 221002, 221003, 221004)); +DELETE FROM `pool_template` WHERE `entry` = 383; diff --git a/data/sql/updates/db_world/2025_11_21_04.sql b/data/sql/updates/db_world/2025_11_21_04.sql new file mode 100644 index 000000000..e4a2c2e92 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_21_04.sql @@ -0,0 +1,23 @@ +-- DB update 2025_11_21_03 -> 2025_11_21_04 + +-- Clean Script Name & add SmartAI (Beryl Sorcerer, Captured Beryl Sorcerer) +UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE (`entry` IN (25316, 25474)); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 0) AND (`entryorguid` IN (25316, 25474)); +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 +(25316, 0, 0, 0, 8, 0, 100, 0, 45611, 0, 0, 0, 0, 0, 80, 2531600, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Beryl Sorcerer - On Spellhit \'Arcane Chains\' - Run Script'), +(25316, 0, 1, 0, 0, 0, 100, 0, 3000, 4000, 4000, 8000, 0, 0, 11, 9672, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Beryl Sorcerer - In Combat - Cast \'Frostbolt\''), +(25316, 0, 2, 0, 2, 0, 100, 0, 35, 50, 8000, 12000, 0, 0, 11, 50648, 64, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Beryl Sorcerer - Between 35-50% Health - Cast \'Blink\''), +(25474, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 80, 2547400, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Beryl Sorcerer - On Just Summoned - Run Script'), +(25474, 0, 1, 0, 65, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Beryl Sorcerer - On Follow Complete - Despawn Instant'); + +-- Set Action Lists (Beryl Sorcerer, Captured Beryl Sorcerer) +DELETE FROM `smart_scripts` WHERE (`source_type` = 9) AND (`entryorguid` IN (2531600, 2547400)); +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 +(2531600, 9, 0, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 0, 0, 11, 45625, 0, 524023, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Beryl Sorcerer - Actionlist - Cast \'Arcane Chains: Character Force Cast\''), +(2531600, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 33, 25474, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Beryl Sorcerer - Actionlist - Quest Credit \'null\''), +(2531600, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Beryl Sorcerer - Actionlist - Despawn Instant'), +(2547400, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 18, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Beryl Sorcerer - Actionlist - Set Flags Not Attackable & Player Controlled'), +(2547400, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Beryl Sorcerer - Actionlist - Set Reactstate Passive'), +(2547400, 9, 2, 0, 0, 0, 100, 0, 200, 200, 0, 0, 0, 0, 11, 45632, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Beryl Sorcerer - Actionlist - Cast \'Enslaved Arcane Chains: Character Force Cast\''), +(2547400, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 29, 2, 180, 25262, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Beryl Sorcerer - Actionlist - Start Follow Owner Or Summoner'); diff --git a/data/sql/updates/db_world/2025_11_21_05.sql b/data/sql/updates/db_world/2025_11_21_05.sql new file mode 100644 index 000000000..fdb2a63f9 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_21_05.sql @@ -0,0 +1,10 @@ +-- DB update 2025_11_21_04 -> 2025_11_21_05 +-- +-- Megalith +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 24371; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 24371) AND (`source_type` = 0); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(24371, 0, 0, 0, 0, 0, 100, 0, 3000, 5000, 15000, 20000, 0, 0, 11, 50084, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Megalith - In Combat - Cast \'Hulking Uppercut\''), +(24371, 0, 1, 0, 0, 0, 100, 0, 0, 1000, 5000, 5000, 0, 0, 11, 50086, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Megalith - In Combat - Cast \'Boulder\''), +(24371, 0, 2, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Megalith - On Just Died - Say Line 0'); diff --git a/data/sql/updates/db_world/2025_11_21_06.sql b/data/sql/updates/db_world/2025_11_21_06.sql new file mode 100644 index 000000000..d2f421d5b --- /dev/null +++ b/data/sql/updates/db_world/2025_11_21_06.sql @@ -0,0 +1,11 @@ +-- DB update 2025_11_21_05 -> 2025_11_21_06 +-- +-- Warbear Matriarch +-- Disable AA +UPDATE `creature_template` SET `AIName` = 'VehicleAI' WHERE (`entry` = 29918); +-- Spells from 1,2,3 to 4,5,6 +DELETE FROM `creature_template_spell` WHERE (`CreatureID` = 29918); +INSERT INTO `creature_template_spell` (`CreatureID`, `Index`, `Spell`, `VerifiedBuild`) VALUES +(29918, 3, 54459, 12340), +(29918, 4, 54458, 12340), +(29918, 5, 54460, 12340); diff --git a/data/sql/updates/db_world/2025_11_21_07.sql b/data/sql/updates/db_world/2025_11_21_07.sql new file mode 100644 index 000000000..39bd7a49b --- /dev/null +++ b/data/sql/updates/db_world/2025_11_21_07.sql @@ -0,0 +1,4 @@ +-- DB update 2025_11_21_06 -> 2025_11_21_07 +-- +-- replace woman with $gman:woman; +UPDATE `quest_offer_reward` SET `RewardText` = 'Wintergarde is saved because of you, $N. To think that one $gman:woman; could so swiftly turn the tides of battle is hard for most to comprehend; yet here we are - victorious! You have managed to restore the faith of these people and earned the respect of your commanding officers.$B$B$B$BLord Fordragon has returned to Angrathar to prepare our forces for the destruction of the Wrathgate and has requested that you join him! I couldn\'t recommend a better soldier for the job, $N.' WHERE (`ID` = 12473); diff --git a/data/sql/updates/db_world/2025_11_23_00.sql b/data/sql/updates/db_world/2025_11_23_00.sql new file mode 100644 index 000000000..a883f44c8 --- /dev/null +++ b/data/sql/updates/db_world/2025_11_23_00.sql @@ -0,0 +1,3 @@ +-- DB update 2025_11_21_07 -> 2025_11_23_00 +-- +UPDATE `gameobject` SET `spawntimesecs` = 1800 WHERE `id` = 193997 AND `guid` IN (1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,3721,3722,3723,3724,3725,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,3736,3737,3738,3739,3740,3741,3742,3743,3744,3745,3746,3747,3748,3749,3750,3751,3752,3753,3754,3755,3756,3757,3758,3759,3760,3761,221001); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index e646dd2e1..ec93785c0 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -583,8 +583,8 @@ void BattlegroundEY::FillInitialWorldStates(WorldPackets::WorldState::InitWorldS packet.Worldstates.emplace_back(WORLD_STATE_BATTLEGROUND_EY_DRAENEI_RUINS_HORDE_CONTROL, _capturePointInfo[POINT_DRAENEI_RUINS].IsUnderControl(TEAM_HORDE)); packet.Worldstates.emplace_back(WORLD_STATE_BATTLEGROUND_EY_DRAENEI_RUINS_ALLIANCE_CONTROL, _capturePointInfo[POINT_DRAENEI_RUINS].IsUnderControl(TEAM_ALLIANCE)); packet.Worldstates.emplace_back(WORLD_STATE_BATTLEGROUND_EY_DRAENEI_RUINS_UNCONTROL, _capturePointInfo[POINT_DRAENEI_RUINS].IsUncontrolled()); - packet.Worldstates.emplace_back(WORLD_STATE_BATTLEGROUND_EY_MAGE_TOWER_ALLIANCE_CONTROL, _capturePointInfo[POINT_MAGE_TOWER].IsUnderControl(TEAM_HORDE)); - packet.Worldstates.emplace_back(WORLD_STATE_BATTLEGROUND_EY_MAGE_TOWER_HORDE_CONTROL, _capturePointInfo[POINT_MAGE_TOWER].IsUnderControl(TEAM_ALLIANCE)); + packet.Worldstates.emplace_back(WORLD_STATE_BATTLEGROUND_EY_MAGE_TOWER_ALLIANCE_CONTROL, _capturePointInfo[POINT_MAGE_TOWER].IsUnderControl(TEAM_ALLIANCE)); + packet.Worldstates.emplace_back(WORLD_STATE_BATTLEGROUND_EY_MAGE_TOWER_HORDE_CONTROL, _capturePointInfo[POINT_MAGE_TOWER].IsUnderControl(TEAM_HORDE)); packet.Worldstates.emplace_back(WORLD_STATE_BATTLEGROUND_EY_MAGE_TOWER_UNCONTROL, _capturePointInfo[POINT_MAGE_TOWER].IsUncontrolled()); packet.Worldstates.emplace_back(WORLD_STATE_BATTLEGROUND_EY_FEL_REAVER_HORDE_CONTROL, _capturePointInfo[POINT_FEL_REAVER].IsUnderControl(TEAM_HORDE)); packet.Worldstates.emplace_back(WORLD_STATE_BATTLEGROUND_EY_FEL_REAVER_ALLIANCE_CONTROL, _capturePointInfo[POINT_FEL_REAVER].IsUnderControl(TEAM_ALLIANCE)); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 242d2325b..a21ec121c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -420,6 +420,8 @@ Player::Player(WorldSession* session): Unit(), m_mover(this) sScriptMgr->OnConstructPlayer(this); _expectingChangeTransport = false; + _pendingFlightChangeCounter = 0; + _mapChangeOrderCounter = 0; } Player::~Player() diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index a1c09fb47..5afbaadab 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -656,7 +656,8 @@ void WorldSession::HandleReclaimCorpseOpcode(WorldPacket& recv_data) if (time_t(corpse->GetGhostTime() + _player->GetCorpseReclaimDelay(corpse->GetType() == CORPSE_RESURRECTABLE_PVP)) > time_t(GameTime::GetGameTime().count())) return; - if (!corpse->IsWithinDistInMap(_player, CORPSE_RECLAIM_RADIUS, true)) + // skip phase check + if (!corpse->IsInMap(_player) || !corpse->IsWithinDist(_player, CORPSE_RECLAIM_RADIUS, true)) return; // resurrect diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 1be5903bf..dc08173ee 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -415,33 +415,31 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo, Unit* mover if (mover->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) { - // if we boarded a transport, add us to it - if (Player* plrMover = mover->ToPlayer()) + // if we boarded a transport, add us to it (generalized for both players and creatures) + if (!mover->GetTransport()) { - if (!plrMover->GetTransport()) + if (Transport* transport = mover->GetMap()->GetTransport(movementInfo.transport.guid)) { - if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid)) - { - plrMover->m_transport = transport; - transport->AddPassenger(plrMover); - } + mover->SetTransport(transport); + transport->AddPassenger(mover); } - else if (plrMover->GetTransport()->GetGUID() != movementInfo.transport.guid) + } + else if (mover->GetTransport()->GetGUID() != movementInfo.transport.guid) + { + // Switching transports + bool foundNewTransport = false; + mover->GetTransport()->RemovePassenger(mover); + if (Transport* transport = mover->GetMap()->GetTransport(movementInfo.transport.guid)) { - bool foundNewTransport = false; - plrMover->m_transport->RemovePassenger(plrMover); - if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid)) - { - foundNewTransport = true; - plrMover->m_transport = transport; - transport->AddPassenger(plrMover); - } + foundNewTransport = true; + mover->SetTransport(transport); + transport->AddPassenger(mover); + } - if (!foundNewTransport) - { - plrMover->m_transport = nullptr; - movementInfo.transport.Reset(); - } + if (!foundNewTransport) + { + mover->SetTransport(nullptr); + movementInfo.transport.Reset(); } } @@ -449,23 +447,20 @@ void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo, Unit* mover { GameObject* go = mover->GetMap()->GetGameObject(movementInfo.transport.guid); if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT) - { movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT); - } } } - else if (mover->IsPlayer()) + else { - if (Player* plrMover = mover->ToPlayer()) + // if we were on a transport, leave (handles both players and creatures) + if (Transport* transport = mover->GetTransport()) { - if (plrMover->GetTransport()) // if we were on a transport, leave - { - sScriptMgr->AnticheatSetUnderACKmount(plrMover); // just for safe + if (mover->IsPlayer()) + sScriptMgr->AnticheatSetUnderACKmount(mover->ToPlayer()); // just for safe - plrMover->m_transport->RemovePassenger(plrMover); - plrMover->m_transport = nullptr; - movementInfo.transport.Reset(); - } + transport->RemovePassenger(mover); + mover->SetTransport(nullptr); + movementInfo.transport.Reset(); } } diff --git a/src/server/game/Handlers/VehicleHandler.cpp b/src/server/game/Handlers/VehicleHandler.cpp index 180cb6c29..fffdc0063 100644 --- a/src/server/game/Handlers/VehicleHandler.cpp +++ b/src/server/game/Handlers/VehicleHandler.cpp @@ -50,7 +50,10 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket& recvData) mi.guid = guid; ReadMovementInfo(recvData, &mi); - _player->m_mover->m_movementInfo = mi; + if (_player->m_mover->IsRooted()) // for some reason client sends it without it even if rooted + mi.AddMovementFlag(MOVEMENTFLAG_ROOT); + + ProcessMovementInfo(mi, _player->m_mover, _player->m_mover->ToPlayer(), recvData); _player->ExitVehicle(); } diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 5061f873c..b8c3cb918 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1157,7 +1157,10 @@ enum AcoreStrings LANG_CMD_NO_DOOR_FOUND = 5086, LANG_CMD_DOOR_OPENED = 5087, - // Room for more strings 5088-9999 + LANG_CMD_QUEST_STATUS = 5088, + LANG_CMD_QUEST_UNAVAILABLE = 5089, + + // Room for more strings 5090-9999 // Level requirement notifications LANG_SAY_REQ = 6604, diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 5c7407633..8733c6910 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -643,6 +643,8 @@ Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, gameObjTarget = nullptr; destTarget = nullptr; damage = 0; + m_reflectionTarget = nullptr; + m_reflectionTargetGuid.Clear(); effectHandleMode = SPELL_EFFECT_HANDLE_LAUNCH; m_diminishLevel = DIMINISHING_LEVEL_1; m_diminishGroup = DIMINISHING_NONE; @@ -2591,6 +2593,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) //Spells with this flag cannot trigger if effect is casted on self bool canEffectTrigger = !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPPRESS_CASTER_PROCS) && unitTarget->CanProc() && (CanExecuteTriggersOnHit(mask) || missInfo == SPELL_MISS_IMMUNE2); bool reflectedSpell = missInfo == SPELL_MISS_REFLECT; + Unit* reflectionSource = nullptr; Unit* spellHitTarget = nullptr; if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target @@ -2602,6 +2605,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) { spellHitTarget = m_caster; unitTarget = m_caster; + reflectionSource = effectUnit; if (m_caster->IsCreature()) m_caster->ToCreature()->LowerPlayerDamageReq(target->damage); } @@ -2609,7 +2613,24 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) if (spellHitTarget) { + if (reflectionSource) + { + m_reflectionTarget = reflectionSource; + m_reflectionTargetGuid = reflectionSource->GetGUID(); + m_reflectionTargetPosition.Relocate(reflectionSource); + } + else + { + m_reflectionTarget = nullptr; + m_reflectionTargetGuid.Clear(); + m_reflectionTargetPosition = Position(); + } + SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura); + + m_reflectionTarget = nullptr; + m_reflectionTargetGuid.Clear(); + m_reflectionTargetPosition = Position(); if (missInfo2 != SPELL_MISS_NONE) { if (missInfo2 != SPELL_MISS_MISS) diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 3025e803e..639eb9629 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -666,6 +666,9 @@ public: WorldLocation* destTarget; int32 damage; SpellEffectHandleMode effectHandleMode; + Unit* m_reflectionTarget; + ObjectGuid m_reflectionTargetGuid; + Position m_reflectionTargetPosition; // used in effects handlers Aura* m_spellAura; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 7e4405490..bf50edfb3 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5013,7 +5013,24 @@ void Spell::EffectKnockBack(SpellEffIndex effIndex) return; float x, y; - if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST) + Unit* reflectionSource = m_reflectionTarget; + + if (!reflectionSource && !m_reflectionTargetGuid.IsEmpty()) + { + if (Unit* resolvedSource = ObjectAccessor::GetUnit(*m_caster, m_reflectionTargetGuid)) + reflectionSource = resolvedSource; + } + + if (reflectionSource) + { + reflectionSource->GetPosition(x, y); + } + else if (!m_reflectionTargetGuid.IsEmpty()) + { + x = m_reflectionTargetPosition.GetPositionX(); + y = m_reflectionTargetPosition.GetPositionY(); + } + else if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST) { if (m_targets.HasDst()) destTarget->GetPosition(x, y); diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index 1ebdd97ee..64ccd48df 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -5131,6 +5131,13 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->ChannelInterruptFlags &= ~AURA_INTERRUPT_FLAG_TURNING; }); + // Summon Scourged Captive + ApplySpellFix({ 51597 }, [](SpellInfo* spellInfo) + { + spellInfo->Effects[EFFECT_0].BasePoints = 1; + spellInfo->Effects[EFFECT_0].DieSides = 0; + }); + // The Green Tower ApplySpellFix({ 18097 }, [](SpellInfo* spellInfo) { diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp index 401c4c059..a049852e4 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -37,6 +37,7 @@ public: { "complete", HandleQuestComplete, SEC_GAMEMASTER, Console::Yes }, { "remove", HandleQuestRemove, SEC_GAMEMASTER, Console::Yes }, { "reward", HandleQuestReward, SEC_GAMEMASTER, Console::Yes }, + { "status", HandleQuestStatus, SEC_GAMEMASTER, Console::Yes }, }; static ChatCommandTable commandTable = { @@ -724,6 +725,53 @@ public: handler->SetSentErrorMessage(false); return true; } + + static bool HandleQuestStatus(ChatHandler* handler, Quest const* quest, Optional playerTarget) + { + if (!playerTarget) + playerTarget = PlayerIdentifier::FromTargetOrSelf(handler); + + if (!playerTarget) + { + handler->SendErrorMessage(LANG_PLAYER_NOT_FOUND); + return false; + } + + uint32 entry = quest->GetQuestId(); + std::string status; + if (Player* player = playerTarget->GetConnectedPlayer()) + { + QuestStatus qs = player->GetQuestStatus(entry); + switch (qs) + { + case QUEST_STATUS_NONE: + status = "Not Taken"; + break; + case QUEST_STATUS_COMPLETE: + status = "Complete"; + break; + case QUEST_STATUS_INCOMPLETE: + status = "Incomplete"; + break; + case QUEST_STATUS_FAILED: + status = "Failed"; + break; + case QUEST_STATUS_REWARDED: + status = "Rewarded"; + break; + default: + status = "Unknown"; + break; + } + + handler->PSendSysMessage(LANG_CMD_QUEST_STATUS, quest->GetTitle(), entry, status); + + if (!player->CanTakeQuest(quest, true)) + handler->PSendSysMessage(LANG_CMD_QUEST_UNAVAILABLE, entry, status); + } + + return true; + } }; void AddSC_quest_commandscript() diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp index 84bd98bc6..01df35c96 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp @@ -218,29 +218,22 @@ public: switch (m_uiEventId) { case EVENT_OZ: - if (OzDialogue[count].textid) - text = OzDialogue[count].textid; - if (OzDialogue[count].timer) - TalkTimer = OzDialogue[count].timer; + text = OzDialogue[count].textid; + TalkTimer = OzDialogue[count].timer; break; - case EVENT_HOOD: - if (HoodDialogue[count].textid) - text = HoodDialogue[count].textid; - if (HoodDialogue[count].timer) - TalkTimer = HoodDialogue[count].timer; + text = HoodDialogue[count].textid; + TalkTimer = HoodDialogue[count].timer; break; - case EVENT_RAJ: - if (RAJDialogue[count].textid) - text = RAJDialogue[count].textid; - if (RAJDialogue[count].timer) - TalkTimer = RAJDialogue[count].timer; + text = RAJDialogue[count].textid; + TalkTimer = RAJDialogue[count].timer; break; + default: + return; } - if (text) - CreatureAI::Talk(text); + CreatureAI::Talk(text); } void PrepareEncounter() diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h index 90222743e..fa7d50231 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h @@ -29,7 +29,11 @@ enum ANData DATA_KRIKTHIR = 0, DATA_HADRONOX = 1, DATA_ANUBARAK = 2, - MAX_ENCOUNTERS = 3 + MAX_ENCOUNTERS = 3, + + DATA_GASHRA = 4, + DATA_NARJIL = 5, + DATA_SILTHIK = 6 }; enum ANIds diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp index f840eb534..3661dc064 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp @@ -80,10 +80,10 @@ enum CreatureIds NPC_ANUBAR_VENOMANCER = 29217, }; -enum Phases : uint8 +enum Groups : uint8 { - PHASE_EMERGED = 1, - PHASE_SUBMERGED + GROUP_EMERGED = 1, + GROUP_SUBMERGED }; enum SubPhase : uint8 @@ -117,7 +117,7 @@ struct boss_anub_arak : public BossAI _submergePhase = SUBMERGE_NONE; ScheduleHealthCheckEvent({ 75, 50, 25 }, [&]{ - events.Reset(); + events.CancelEventGroup(GROUP_EMERGED); Talk(SAY_SUBMERGE); DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS, true); DoCastSelf(SPELL_SUBMERGE, false); @@ -133,75 +133,74 @@ struct boss_anub_arak : public BossAI DoCastSelf(SPELL_IMPALE_PERIODIC, true); ++_submergePhase; - events.Reset(); ScheduleSubmerged(); } } void ScheduleEmerged() { - events.SetPhase(PHASE_EMERGED); - events.ScheduleEvent(EVENT_CARRION_BEETLES, 6500ms, 0, PHASE_EMERGED); - events.ScheduleEvent(EVENT_LEECHING_SWARM, 20s, 0, PHASE_EMERGED); - events.ScheduleEvent(EVENT_POUND, 15s, 0, PHASE_EMERGED); + events.CancelEventGroup(GROUP_SUBMERGED); + events.ScheduleEvent(EVENT_CARRION_BEETLES, 6500ms, GROUP_EMERGED); + events.ScheduleEvent(EVENT_LEECHING_SWARM, 20s, GROUP_EMERGED); + events.ScheduleEvent(EVENT_POUND, 15s, GROUP_EMERGED); }; void ScheduleSubmerged() { - events.SetPhase(PHASE_SUBMERGED); - events.ScheduleEvent(EVENT_EMERGE, 60s, 0, PHASE_SUBMERGED); + events.CancelEventGroup(GROUP_EMERGED); + events.ScheduleEvent(EVENT_EMERGE, 60s, GROUP_SUBMERGED); switch (_submergePhase) { case SUBMERGE_75: - events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 4s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 4s, GROUP_SUBMERGED); if (IsHeroic()) - events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 7s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 7s, GROUP_SUBMERGED); _remainingLargeSummonsBeforeEmerge = IsHeroic() ? 2 : 1; - events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 4s, 0, PHASE_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 24s, 0, PHASE_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 44s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 4s, GROUP_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 24s, GROUP_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 44s, GROUP_SUBMERGED); break; case SUBMERGE_50: - events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 4s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 4s, GROUP_SUBMERGED); if (IsHeroic()) - events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 7s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 7s, GROUP_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_VENOMANCER, 24s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_VENOMANCER, 24s, GROUP_SUBMERGED); if (IsHeroic()) - events.ScheduleEvent(EVENT_SUMMON_VENOMANCER, 29s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_VENOMANCER, 29s, GROUP_SUBMERGED); _remainingLargeSummonsBeforeEmerge = IsHeroic() ? 4 : 2; - events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 4s, 0, PHASE_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 24s, 0, PHASE_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 44s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 4s, GROUP_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 24s, GROUP_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 44s, GROUP_SUBMERGED); break; case SUBMERGE_25: - events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 4s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 4s, GROUP_SUBMERGED); if (IsHeroic()) - events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 7s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_GUARDIAN, 7s, GROUP_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_VENOMANCER, 24s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_VENOMANCER, 24s, GROUP_SUBMERGED); if (IsHeroic()) - events.ScheduleEvent(EVENT_SUMMON_VENOMANCER, 29s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_VENOMANCER, 29s, GROUP_SUBMERGED); _remainingLargeSummonsBeforeEmerge = IsHeroic() ? 4 : 2; - events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 4s, 0, PHASE_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_DARTER, 4s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 4s, GROUP_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_DARTER, 4s, GROUP_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_DARTER, 12s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_DARTER, 12s, GROUP_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 24s, 0, PHASE_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_DARTER, 26s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 24s, GROUP_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_DARTER, 26s, GROUP_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_DARTER, 32s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_DARTER, 32s, GROUP_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 44s, 0, PHASE_SUBMERGED); - events.ScheduleEvent(EVENT_SUMMON_DARTER, 45s, 0, PHASE_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_ASSASSINS, 44s, GROUP_SUBMERGED); + events.ScheduleEvent(EVENT_SUMMON_DARTER, 45s, GROUP_SUBMERGED); break; default: break; @@ -213,9 +212,8 @@ struct boss_anub_arak : public BossAI Talk(SAY_AGGRO); instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT); - events.SetPhase(PHASE_EMERGED); - events.ScheduleEvent(EVENT_CLOSE_DOORS, 5s, 0, PHASE_EMERGED); ScheduleEmerged(); + events.ScheduleEvent(EVENT_CLOSE_DOORS, 5s); // set up world triggers std::list summoned; @@ -285,9 +283,8 @@ struct boss_anub_arak : public BossAI --_remainingLargeSummonsBeforeEmerge; if (_remainingLargeSummonsBeforeEmerge == 0) { - events.Reset(); - events.SetPhase(PHASE_SUBMERGED); - events.ScheduleEvent(EVENT_EMERGE, 5s, 0, PHASE_SUBMERGED); + me->RemoveAurasDueToSpell(SPELL_IMPALE_PERIODIC); + events.RescheduleEvent(EVENT_EMERGE, 5s, GROUP_SUBMERGED); } break; } @@ -319,12 +316,12 @@ struct boss_anub_arak : public BossAI break; case EVENT_CARRION_BEETLES: DoCastSelf(SPELL_CARRION_BEETLES); - events.ScheduleEvent(EVENT_CARRION_BEETLES, 25s, 0, PHASE_EMERGED); + events.ScheduleEvent(EVENT_CARRION_BEETLES, 25s, GROUP_EMERGED); break; case EVENT_LEECHING_SWARM: Talk(SAY_LOCUST); DoCastSelf(SPELL_LEECHING_SWARM); - events.ScheduleEvent(EVENT_LEECHING_SWARM, 20s, 0, PHASE_EMERGED); + events.ScheduleEvent(EVENT_LEECHING_SWARM, 20s, GROUP_EMERGED); break; case EVENT_POUND: if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 10.0f)) @@ -332,10 +329,10 @@ struct boss_anub_arak : public BossAI DoCastSelf(SPELL_SELF_ROOT, true); me->DisableRotate(true); me->SendMovementFlagUpdate(); - events.ScheduleEvent(EVENT_ENABLE_ROTATE, 3300ms, 0, PHASE_EMERGED); + events.ScheduleEvent(EVENT_ENABLE_ROTATE, 3300ms, GROUP_EMERGED); DoCast(target, SPELL_POUND); } - events.ScheduleEvent(EVENT_POUND, 18s, 0, PHASE_EMERGED); + events.ScheduleEvent(EVENT_POUND, 18s, GROUP_EMERGED); break; case EVENT_ENABLE_ROTATE: me->RemoveAurasDueToSpell(SPELL_SELF_ROOT); @@ -376,10 +373,10 @@ struct boss_anub_arak : public BossAI void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask) override { + BossAI::DamageTaken(attacker, damage, damagetype, damageSchoolMask); + if (me->HasAura(SPELL_SUBMERGE) && damage >= me->GetHealth()) damage = me->GetHealth() - 1; - - BossAI::DamageTaken(attacker, damage, damagetype, damageSchoolMask); } private: diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp index 36fd31ff1..46e7e5cb2 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp @@ -16,6 +16,7 @@ */ #include "AchievementCriteriaScript.h" +#include "CreatureGroups.h" #include "CreatureScript.h" #include "ScriptedCreature.h" #include "azjol_nerub.h" @@ -75,16 +76,6 @@ public: { BossAI::Reset(); - me->SummonCreature(NPC_WATCHER_NARJIL, 511.8f, 666.493f, 776.278f, 0.977f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - me->SummonCreature(NPC_SHADOWCASTER, 511.63f, 672.44f, 775.71f, 0.90f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - me->SummonCreature(NPC_WARRIOR, 506.75f, 670.7f, 776.24f, 0.92f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - me->SummonCreature(NPC_WATCHER_GASHRA, 526.66f, 663.605f, 775.805f, 1.23f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - me->SummonCreature(NPC_SKIRMISHER, 522.91f, 660.18f, 776.19f, 1.28f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - me->SummonCreature(NPC_WARRIOR, 528.14f, 659.72f, 776.14f, 1.37f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - me->SummonCreature(NPC_WATCHER_SILTHIK, 543.826f, 665.123f, 776.245f, 1.55f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - me->SummonCreature(NPC_SKIRMISHER, 547.5f, 669.96f, 776.1f, 2.3f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - me->SummonCreature(NPC_SHADOWCASTER, 548.64f, 664.27f, 776.74f, 1.77f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); - ScheduleHealthCheckEvent(25, [&] { DoCastSelf(SPELL_FRENZY, true); @@ -100,6 +91,16 @@ public: _canTalk = true; _minionInCombat = false; + + Creature* narjil = instance->GetCreature(DATA_NARJIL); + Creature* gashra = instance->GetCreature(DATA_GASHRA); + Creature* silthik = instance->GetCreature(DATA_SILTHIK); + + for (Creature* watcher : { narjil, gashra, silthik }) + { + if (watcher && watcher->GetFormation()) + watcher->GetFormation()->RespawnFormation(true); + } } void MoveInLineOfSight(Unit* who) override @@ -120,24 +121,39 @@ public: { _minionInCombat = true; - for (Seconds const& timer : { 10s, 40s, 70s }) + Talk(SAY_SEND_GROUP, 10s); + + for (Seconds const& timer : { 60s, 120s }) { me->m_Events.AddEventAtOffset([this] { - me->CastCustomSpell(SPELL_SUBBOSS_AGGRO_TRIGGER, SPELLVALUE_MAX_TARGETS, 1, me, true); Talk(SAY_SEND_GROUP); + + me->m_Events.AddEventAtOffset([this] { + me->CastCustomSpell(SPELL_SUBBOSS_AGGRO_TRIGGER, SPELLVALUE_MAX_TARGETS, 1, me, true); + }, 5s); }, timer); } me->m_Events.AddEventAtOffset([this] { me->SetInCombatWithZone(); - }, 100s); + }, IsHeroic() ? 200s : 180s); } } uint32 GetData(uint32 data) const override { if (data == me->GetEntry()) - return summons.HasEntry(NPC_WATCHER_NARJIL) && summons.HasEntry(NPC_WATCHER_GASHRA) && summons.HasEntry(NPC_WATCHER_SILTHIK); + { + Creature* narjil = instance->GetCreature(DATA_NARJIL); + Creature* gashra = instance->GetCreature(DATA_GASHRA); + Creature* silthik = instance->GetCreature(DATA_SILTHIK); + + if (!narjil || !gashra || !silthik) + return false; + + return narjil->IsAlive() && gashra->IsAlive() && silthik->IsAlive(); + } + return 0; } @@ -187,12 +203,6 @@ public: } } - void JustSummoned(Creature* summon) override - { - summon->SetNoCallAssistance(true); - summons.Summon(summon); - } - void SummonedCreatureDies(Creature* summon, Unit*) override { summons.Despawn(summon); diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp index ef6372c78..7fd7af40f 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp @@ -37,6 +37,9 @@ ObjectData const creatureData[] = { NPC_KRIKTHIR_THE_GATEWATCHER, DATA_KRIKTHIR }, { NPC_HADRONOX, DATA_HADRONOX }, { NPC_ANUBARAK, DATA_ANUBARAK }, + { NPC_WATCHER_GASHRA, DATA_GASHRA }, + { NPC_WATCHER_NARJIL, DATA_NARJIL }, + { NPC_WATCHER_SILTHIK, DATA_SILTHIK }, { 0, 0 } }; diff --git a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/ahnkahet.h b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/ahnkahet.h index b6b691be6..9b205b1c6 100644 --- a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/ahnkahet.h +++ b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/ahnkahet.h @@ -44,6 +44,7 @@ enum AhnKahetCreatures NPC_AMANITAR = 30258, // Teldaram and Jedoga encounter related NPC_JEDOGA_CONTROLLER = 30181, + NPC_TWILIGHT_WORSHIPPER = 30111 }; enum AhnkahetSpells diff --git a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_jedoga_shadowseeker.cpp b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_jedoga_shadowseeker.cpp index e5444781d..59e0a320a 100644 --- a/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_jedoga_shadowseeker.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/ahnkahet/boss_jedoga_shadowseeker.cpp @@ -90,6 +90,7 @@ enum SummonGroups { SUMMON_GROUP_OOC = 0, SUMMON_GROUP_OOC_TRIGGERS = 1, + SUMMON_GROUP_IC_WORSHIPPERS = 2 }; enum Points @@ -217,7 +218,7 @@ struct boss_jedoga_shadowseeker : public BossAI void JustSummoned(Creature* summon) override { - if (summon->GetEntry() == NPC_JEDOGA_CONTROLLER) + if (summon->EntryEquals(NPC_JEDOGA_CONTROLLER, NPC_TWILIGHT_WORSHIPPER)) { summons.Summon(summon); } @@ -326,6 +327,17 @@ struct boss_jedoga_shadowseeker : public BossAI _JustEngagedWith(); Talk(SAY_AGGRO); ReschedulleCombatEvents(); + + std::list tempSummons; + me->SummonCreatureGroup(SUMMON_GROUP_IC_WORSHIPPERS, &tempSummons); + if (!tempSummons.empty()) + { + for (TempSummon* summon : tempSummons) + { + if (summon) + summon->SetStandState(UNIT_STAND_STATE_KNEEL); + } + } } void KilledUnit(Unit* who) override diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp index a1e01ee32..27b3254b8 100644 --- a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp +++ b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp @@ -47,7 +47,7 @@ enum Spells SPELL_COPY_OF_SUMMON_MINIONS = 59933, SPELL_BLIZZARD = 49034, SPELL_FROSTBOLT = 49037, - SPELL_TOUCH_OF_MISERY = 50090 + SPELL_WRATH_OF_MISERY = 50089 }; enum Misc @@ -56,14 +56,7 @@ enum Misc NPC_CRYSTAL_HANDLER = 26627, NPC_SUMMON_CRYSTAL_HANDLER_TARGET = 27583, - EVENT_SUMMON_FETID_TROLL = 1, - EVENT_SUMMON_SHADOWCASTER = 2, - EVENT_SUMMON_HULKING_CORPSE = 3, - EVENT_SUMMON_CRYSTAL_HANDLER = 4, - EVENT_CAST_OFFENSIVE_SPELL = 5, - EVENT_KILL_TALK = 6, - EVENT_CHECK_PHASE = 7, - EVENT_SPELL_SUMMON_MINIONS = 8, + EVENT_KILL_TALK = 1, ROOM_RIGHT = 0, ROOM_LEFT = 1, @@ -79,8 +72,7 @@ std::unordered_map> const npcSummon = class boss_novos : public CreatureScript { -public: - boss_novos() : CreatureScript("boss_novos") { } + boss_novos(Creature* creature) : BossAI(creature, DATA_NOVOS) { } struct boss_novosAI : public BossAI { @@ -118,40 +110,96 @@ public: _achievement = false; } - void MoveInLineOfSight(Unit* /*who*/) override { } + void JustEngagedWith(Unit* who) override + { + Talk(SAY_AGGRO); + BossAI::JustEngagedWith(who); + scheduler.ClearValidator(); - void JustEngagedWith(Unit* who) override - { - Talk(SAY_AGGRO); - BossAI::JustEngagedWith(who); + ScheduleTimedEvent(3s, [&] { + if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET)) + trigger->CastSpell(trigger, SPELL_SUMMON_FETID_TROLL_CORPSE, true, nullptr, nullptr, me->GetGUID()); + }, 3s); - events.ScheduleEvent(EVENT_SUMMON_FETID_TROLL, 3s); - events.ScheduleEvent(EVENT_SUMMON_SHADOWCASTER, 9s); - events.ScheduleEvent(EVENT_SUMMON_HULKING_CORPSE, 30s); - events.ScheduleEvent(EVENT_SUMMON_CRYSTAL_HANDLER, 20s); - events.ScheduleEvent(EVENT_CHECK_PHASE, 80s); + ScheduleTimedEvent(9s, [&] { + if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET)) + trigger->CastSpell(trigger, SPELL_SUMMON_RISEN_SHADOWCASTER, true, nullptr, nullptr, me->GetGUID()); + }, 10s); - me->CastSpell(me, SPELL_ARCANE_BLAST, true); - me->CastSpell(me, SPELL_ARCANE_FIELD, true); - me->CastSpell(me, SPELL_DESPAWN_CRYSTAL_HANDLER, true); + ScheduleTimedEvent(30s, [&] { + if (Creature* trigger = summons.GetCreatureWithEntry(NPC_CRYSTAL_CHANNEL_TARGET)) + trigger->CastSpell(trigger, SPELL_SUMMON_HULKING_CORPSE, true, nullptr, nullptr, me->GetGUID()); + }, 30s); - for (auto& itr : npcSummon) + scheduler.Schedule(70s, [this](TaskContext context) { + if (me->HasAura(SPELL_BEAM_CHANNEL)) { - uint32 summonEntry; - Position summonPos; - std::tie(summonEntry, summonPos) = itr.second; - if (Creature* creature = me->SummonCreature(summonEntry, summonPos)) - switch (itr.first) - { - case ROOM_LEFT: - _summonTargetLeftGUID = creature->GetGUID(); - break; - case ROOM_RIGHT: - _summonTargetRightGUID = creature->GetGUID(); - break; - } + context.Repeat(2s); + return; } + scheduler.CancelAll(); + + me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); + me->InterruptNonMeleeSpells(false); + + scheduler.SetValidator([this] { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + + ScheduleTimedEvent(5s, 10s, [&] { + DoCastRandomTarget(SPELL_BLIZZARD); + }, 12s, 25s); + + ScheduleTimedEvent(5s, 10s, [&] { + DoCastRandomTarget(SPELL_WRATH_OF_MISERY); + }, 8s, 16s); + + if (IsHeroic()) + { + ScheduleTimedEvent(10s, [&] { + DoCastAOE(SPELL_SUMMON_MINIONS); + }, 37s, 55s); + } + }); + + for (Seconds timer : { 16s, 32s, 48s, 64s }) + { + me->m_Events.AddEventAtOffset([&] { + Talk(SAY_SUMMONING_ADDS); + Talk(EMOTE_SUMMONING_ADDS); + if (Creature* target = ObjectAccessor::GetCreature(*me, _stage ? _summonTargetLeftGUID : _summonTargetRightGUID)) + target->CastSpell(target, SPELL_SUMMON_CRYSTAL_HANDLER, true, nullptr, nullptr, me->GetGUID()); + _stage = _stage ? 0 : 1; + }, timer); + } + + me->SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty); + me->RemoveAllAuras(); + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + + DoCastSelf(SPELL_ARCANE_BLAST, true); + DoCastSelf(SPELL_ARCANE_FIELD, true); + DoCastSelf(SPELL_DESPAWN_CRYSTAL_HANDLER, true); + + for (auto& itr : npcSummon) + { + uint32 summonEntry; + Position summonPos; + std::tie(summonEntry, summonPos) = itr.second; + if (Creature* creature = me->SummonCreature(summonEntry, summonPos)) + switch (itr.first) + { + case ROOM_LEFT: + _summonTargetLeftGUID = creature->GetGUID(); + break; + case ROOM_RIGHT: + _summonTargetRightGUID = creature->GetGUID(); + break; + } + } + } + me->SetGuidValue(UNIT_FIELD_TARGET, ObjectGuid::Empty); me->RemoveAllAuras(); me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); @@ -179,7 +227,11 @@ public: summons.Summon(summon); if (me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && summon->GetEntry() != NPC_CRYSTAL_CHANNEL_TARGET && summon->GetEntry() != NPC_CRYSTAL_HANDLER) summon->SetReactState(REACT_DEFENSIVE); - else if (summon->GetEntry() != NPC_CRYSTAL_CHANNEL_TARGET) + + if (summon->GetEntry() == NPC_FETID_TROLL_CORPSE) + summon->GetMotionMaster()->MovePoint(1, -373.56f, -770.86f, 28.59f); + + if (summon->EntryEquals(NPC_CRYSTAL_HANDLER)) summon->SetInCombatWithZone(); } @@ -249,10 +301,12 @@ public: } } - bool CheckEvadeIfOutOfCombatArea() const override - { - return !SelectTargetFromPlayerList(80.0f); - } + scheduler.Update(diff); + events.Update(diff); + + if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) + DoSpellAttackIfReady(SPELL_FROSTBOLT); + } private: uint8 _crystalCounter; diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp index b36e991d5..7e37bb805 100644 --- a/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp +++ b/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp @@ -59,7 +59,6 @@ enum Misc EVENT_SPELL_EYE_BEAM = 4, EVENT_SPELL_LIGHTNING_BREATH = 5, EVENT_SPELL_POISON_CLOUD = 6, - EVENT_SPELL_TURN_FLESH = 7, EVENT_TURN_FLESH_REAL = 9, EVENT_TURN_BONES_REAL = 10, EVENT_KILL_TALK = 11 @@ -77,9 +76,7 @@ public: struct boss_tharon_jaAI : public BossAI { - boss_tharon_jaAI(Creature* creature) : BossAI(creature, DATA_THARON_JA) - { - } + boss_tharon_jaAI(Creature* creature) : BossAI(creature, DATA_THARON_JA) { } void Reset() override { @@ -88,15 +85,23 @@ public: me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true); me->SetDisplayId(me->GetNativeDisplayId()); me->CastSpell(me, SPELL_CLEAR_GIFT, true); + + ScheduleHealthCheckEvent(55, [&] { + Talk(SAY_FLESH); + me->GetThreatMgr().ResetAllThreat(); + me->CastSpell((Unit*)nullptr, SPELL_TURN_FLESH, false); + + events.Reset(); + events.ScheduleEvent(EVENT_TURN_FLESH_REAL, 3s); + }, false); } void JustEngagedWith(Unit* who) override { Talk(SAY_AGGRO); BossAI::JustEngagedWith(who); - events.ScheduleEvent(EVENT_SPELL_CURSE_OF_LIFE, 5s); - events.ScheduleEvent(EVENT_SPELL_SHADOW_VOLLEY, 8s, 10s); - events.ScheduleEvent(EVENT_SPELL_TURN_FLESH, 1s); + events.ScheduleEvent(EVENT_SPELL_CURSE_OF_LIFE, 13s, 24s); + events.ScheduleEvent(EVENT_SPELL_SHADOW_VOLLEY, 6s, 29s); } void KilledUnit(Unit* /*victim*/) override @@ -144,24 +149,11 @@ public: { case EVENT_SPELL_CURSE_OF_LIFE: DoCastRandomTarget(SPELL_CURSE_OF_LIFE, 0, 30.0f, false); - events.ScheduleEvent(EVENT_SPELL_CURSE_OF_LIFE, 13s); + events.ScheduleEvent(EVENT_SPELL_CURSE_OF_LIFE, 11s, 28s); break; case EVENT_SPELL_SHADOW_VOLLEY: DoCastAOE(SPELL_SHADOW_VOLLEY); - events.ScheduleEvent(EVENT_SPELL_SHADOW_VOLLEY, 9s); - break; - case EVENT_SPELL_TURN_FLESH: - if (me->HealthBelowPct(50)) - { - Talk(SAY_FLESH); - me->GetThreatMgr().ResetAllThreat(); - me->CastSpell((Unit*)nullptr, SPELL_TURN_FLESH, false); - - events.Reset(); - events.ScheduleEvent(EVENT_TURN_FLESH_REAL, 3s); - return; - } - events.ScheduleEvent(EVENT_SPELL_TURN_FLESH, 1s); + events.ScheduleEvent(EVENT_SPELL_SHADOW_VOLLEY, 6s, 29s); break; case EVENT_TURN_FLESH_REAL: DoCastSelf(SPELL_DUMMY, true); diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp index 78defb706..ff76ad283 100644 --- a/src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp +++ b/src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp @@ -130,6 +130,12 @@ public: if (!UpdateVictim()) return; + if (!CheckInRoom()) + { + EnterEvadeMode(EVADE_REASON_BOUNDARY); + return; + } + events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; @@ -159,9 +165,9 @@ public: DoMeleeAttackIfReady(); } - bool CheckEvadeIfOutOfCombatArea() const override + bool CheckInRoom() override { - return me->GetHomePosition().GetExactDist2d(me) > 60.0f; + return (me->GetPositionY() >= -700.0f && me->GetPositionY() <= -628.0f); } private: diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index db638f0a0..bf939932d 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -1950,14 +1950,14 @@ public: currentStopPoint = 0; events.Reset(); } - void DoAction(int32 actionId) override + void DoAction(int32 actionId) override { switch (actionId) { case ACTION_START_INTRO: events.ScheduleEvent(EVENT_LK_SAY_AGGRO, 0ms); - events.ScheduleEvent(EVENT_LK_BATTLE_1, 2s +500ms); + events.ScheduleEvent(EVENT_LK_BATTLE_1, 2s + 500ms); events.ScheduleEvent(EVENT_LK_BATTLE_2, 3s); events.ScheduleEvent(me->GetEntry() == NPC_JAINA_PART2 ? EVENT_JAINA_IMMOBILIZE_LK : EVENT_SYLVANAS_IMMOBILIZE_JUMP, 9s); break; @@ -1989,7 +1989,7 @@ public: path.push_back(G3D::Vector3(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ())); for (uint8 i = WP_STOP[currentStopPoint - 1] + (currentStopPoint == 1 ? 0 : 1); i <= WP_STOP[currentStopPoint]; ++i) path.push_back(G3D::Vector3(PathWaypoints[i].GetPositionX(), PathWaypoints[i].GetPositionY(), PathWaypoints[i].GetPositionZ())); - me->GetMotionMaster()->MoveSplinePath(&path); + me->GetMotionMaster()->MoveSplinePath(&path, FORCED_MOVEMENT_RUN); } void MovementInform(uint32 type, uint32 /*id*/) override diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp index f5ceede61..b7fe5f2b6 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_sjonnir.cpp @@ -28,6 +28,7 @@ enum Spells SPELL_LIGHTNING_SHIELD = 50831, SPELL_STATIC_CHARGE = 50834, SPELL_LIGHTNING_RING = 50840, + SPELL_LIGHTNING_RING_5S = 51849, // IRON SLUDGE SPELL_TOXIC_VOLLEY = 50838, @@ -41,7 +42,6 @@ enum Spells enum Npc { - NPC_IRON_SLUDGE = 28165, // if 2 ooze then spawn 1 iron_sludge NPC_DWARFES_FRIENDLY = 27980, //after fix the machine by Brann NPC_OOZE = 27981, //spawn after killing dwarf NPC_FORGED_IRON_DWARF = 27982, @@ -57,15 +57,6 @@ enum Yells enum Events { - // SJONNIR - EVENT_SHIELD = 1, - EVENT_CHAIN_LIGHTNING = 2, - EVENT_STATIC_CHARGE = 3, - EVENT_LIGHTNING_RING = 4, - EVENT_CHECK_HEALTH = 5, - EVENT_SUMMON = 6, - EVENT_SUMMON_SPEACH = 7, - // TRASH EVENT_MALFORMED_OOZE_CHECK = 10, EVENT_TOXIC_VOLLEY = 11, @@ -73,8 +64,11 @@ enum Events EVENT_FORGED_LIGHTNING_TETHER = 13, }; -enum Misc +enum SjonnirMisc { + GROUP_SUMMONS = 1, + GROUP_LIGHTNING_RING = 2, + POS_GEN_RIGHT = 0, POS_GEN_LEFT = 1, POS_ROOM_CENTER = 2, @@ -83,13 +77,6 @@ enum Misc ACTION_SLUG_KILLED = 1, }; -enum SummonPhases -{ - PHASE_SUMMON_UNFRIENDLY_DWARFES = 0, - PHASE_SUMMON_OOZE = 1, - PHASE_SUMMON_FRIENDLY_DWARFES = 2, -}; - static Position RoomPosition[] = { {1293.0f, 610.0f, 199.3f, 0.0f}, @@ -107,75 +94,135 @@ public: return GetHallsOfStoneAI(pCreature); } - struct boss_sjonnirAI : public ScriptedAI + struct boss_sjonnirAI : public BossAI { - boss_sjonnirAI(Creature* c) : ScriptedAI(c), summons(me) - { - pInstance = c->GetInstanceScript(); - } + boss_sjonnirAI(Creature* c) : BossAI(c, BOSS_SJONNIR) { } - InstanceScript* pInstance; - EventMap events; - SummonList summons; - - uint8 SummonPhase; uint8 SlugeCount; void Reset() override { - events.Reset(); - summons.DespawnAll(); - + _Reset(); + scheduler.ClearValidator(); SlugeCount = 0; - SummonPhase = PHASE_SUMMON_UNFRIENDLY_DWARFES; + instance->SetData(DATA_SJONNIR_ACHIEVEMENT, false); - if (pInstance) + if (instance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE) { - pInstance->SetData(BOSS_SJONNIR, NOT_STARTED); - pInstance->SetData(DATA_SJONNIR_ACHIEVEMENT, false); + if (GameObject* console = me->GetMap()->GetGameObject(instance->GetGuidData(GO_SJONNIR_CONSOLE))) + console->SetGoState(GO_STATE_READY); - me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - if (pInstance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE) + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRANN))) { - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - - if (GameObject* console = me->GetMap()->GetGameObject( pInstance->GetGuidData(GO_SJONNIR_CONSOLE))) - console->SetGoState(GO_STATE_READY); - - if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN))) - { - brann->setDeathState(DeathState::JustDied); - brann->Respawn(); - brann->AI()->DoAction(ACTION_SJONNIR_WIPE_START); - } + brann->setDeathState(DeathState::JustDied); + brann->Respawn(); + brann->AI()->DoAction(ACTION_SJONNIR_WIPE_START); } } + + ScheduleHealthCheckEvent(75, [&] { + scheduler.CancelGroup(GROUP_SUMMONS); + scheduler.Schedule(1s, GROUP_SUMMONS, [&](TaskContext context) { + uint8 Pos = urand(POS_GEN_RIGHT, POS_GEN_LEFT); + me->SummonCreature(NPC_FORGED_IRON_TROGG, RoomPosition[Pos].GetPositionX(), RoomPosition[Pos].GetPositionY(), RoomPosition[Pos].GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000); + ActivatePipe(Pos); + context.Repeat(5s, 7s); + }); + }); + + ScheduleHealthCheckEvent(50, [&] { + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRANN))) + brann->AI()->Talk(SAY_BRANN_SPAWN_OOZE); + + scheduler.CancelGroup(GROUP_SUMMONS); + scheduler.Schedule(3s, GROUP_SUMMONS, [&](TaskContext context) { + uint8 pos = urand(POS_GEN_RIGHT, POS_GEN_LEFT); + if (Creature* ooze = me->SummonCreature(NPC_OOZE, RoomPosition[pos], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) + { + ActivatePipe(pos); + ooze->GetMotionMaster()->MovePoint(0, RoomPosition[POS_ROOM_CENTER].GetPositionX(), RoomPosition[POS_ROOM_CENTER].GetPositionY(), RoomPosition[POS_ROOM_CENTER].GetPositionZ()); + ooze->SetReactState(REACT_PASSIVE); + ooze->SetWalk(true); + } + + context.Repeat(); + }); + }); + + ScheduleHealthCheckEvent(25, [&] { + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRANN))) + brann->AI()->Talk(SAY_BRANN_SPAWN_EARTHEN); + + scheduler.CancelGroup(GROUP_SUMMONS); + scheduler.Schedule(1s, GROUP_SUMMONS, [&](TaskContext context) { + for (int i = 0; i < 3; i++) + { + uint8 pos = urand(POS_GEN_RIGHT, POS_GEN_LEFT); + if (Creature* dwarf = me->SummonCreature(NPC_DWARFES_FRIENDLY, RoomPosition[pos], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) + { + if (Player* plr = SelectTargetFromPlayerList(100.0f)) + dwarf->SetFaction(plr->GetFaction()); + + ActivatePipe(pos); + dwarf->AI()->AttackStart(me); + } + } + + context.Repeat(10s, 20s); + }); + }); + + ScheduleHealthCheckEvent(20, [&] { + scheduler.CancelGroup(GROUP_LIGHTNING_RING); + DoCastSelf(SPELL_FRENZY, true); + + ScheduleTimedEvent(1s, [&] { + DoCastSelf(SPELL_LIGHTNING_RING_5S); + }, 11s); + }); + } + + void ScheduleTasks() override + { + ScheduleTimedEvent(14s, 19s, [&] { + DoCastSelf(SPELL_LIGHTNING_SHIELD); + }, 14s, 19s); + + ScheduleTimedEvent(6s, 12s, [&] { + DoCastVictim(SPELL_CHAIN_LIGHTNING); + }, 6s, 12s); + + ScheduleTimedEvent(24s, [&] { + DoCastRandomTarget(SPELL_STATIC_CHARGE, 0, 50.0f); + }, 20s); + + scheduler.Schedule(30s, GROUP_LIGHTNING_RING, [&](TaskContext context) { + DoCastAOE(SPELL_LIGHTNING_RING); + context.Repeat(40s); + }); + + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRANN))) + brann->AI()->Talk(SAY_BRANN_SPAWN_TROGG, 20s); + + scheduler.Schedule(5s, GROUP_SUMMONS, [&](TaskContext context) { + uint8 pos = urand(POS_GEN_RIGHT, POS_GEN_LEFT); + me->SummonCreature(NPC_FORGED_IRON_DWARF, RoomPosition[pos], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000); + ActivatePipe(pos); + context.Repeat(30s); + }); } void JustEngagedWith(Unit* /*who*/) override { + _JustEngagedWith(); Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_CHECK_HEALTH, 1s); - events.ScheduleEvent(EVENT_SHIELD, 14s, 19s); - events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 6s, 12s); - events.ScheduleEvent(EVENT_STATIC_CHARGE, 24s); - events.ScheduleEvent(EVENT_LIGHTNING_RING, 25s, 31s); - events.ScheduleEvent(EVENT_SUMMON, 20s); - events.ScheduleEvent(EVENT_SUMMON, 21s + 500ms); - events.ScheduleEvent(EVENT_SUMMON_SPEACH, 20s); + if (GameObject* doors = me->GetMap()->GetGameObject(instance->GetGuidData(GO_SJONNIR_DOOR))) + doors->SetGoState(GO_STATE_READY); - if (pInstance) - { - pInstance->SetData(BOSS_SJONNIR, IN_PROGRESS); - - if (GameObject* doors = me->GetMap()->GetGameObject(pInstance->GetGuidData(GO_SJONNIR_DOOR))) - doors->SetGoState(GO_STATE_READY); - - if (pInstance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE) - if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN))) - brann->AI()->DoAction(ACTION_START_SJONNIR_FIGHT); - } + if (instance->GetData(BOSS_TRIBUNAL_OF_AGES) == DONE) + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRANN))) + brann->AI()->DoAction(ACTION_START_SJONNIR_FIGHT); } void DoAction(int32 param) override @@ -183,144 +230,20 @@ public: if (param == ACTION_SLUG_KILLED) { SlugeCount++; - if (SlugeCount >= 5 && pInstance) - pInstance->SetData(DATA_SJONNIR_ACHIEVEMENT, true); + if (SlugeCount >= 5) + instance->SetData(DATA_SJONNIR_ACHIEVEMENT, true); } } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_CHECK_HEALTH: - { - if (SummonPhase == PHASE_SUMMON_UNFRIENDLY_DWARFES && HealthBelowPct(50)) - { - SummonPhase = PHASE_SUMMON_OOZE; - events.CancelEvent(EVENT_SUMMON); - events.ScheduleEvent(EVENT_SUMMON, 0ms); - events.ScheduleEvent(EVENT_SUMMON, 1500ms); - - if (pInstance) - if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN))) - { - brann->AI()->Talk(SAY_BRANN_SPAWN_OOZE); - } - } - - if (HealthBelowPct(20)) - { - if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN))) - { - brann->AI()->Talk(SAY_BRANN_SPAWN_EARTHEN); - } - SummonPhase = PHASE_SUMMON_FRIENDLY_DWARFES; - me->CastSpell(me, SPELL_FRENZY, false); - - events.CancelEvent(EVENT_SUMMON); - events.ScheduleEvent(EVENT_SUMMON, 0ms); - break; - } - - events.Repeat(1s); - break; - } - case EVENT_SHIELD: - { - me->CastSpell(me, SPELL_LIGHTNING_SHIELD, false); - events.Repeat(14s, 19s); - break; - } - case EVENT_CHAIN_LIGHTNING: - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true, 0)) - me->CastSpell(target, SPELL_CHAIN_LIGHTNING, false); - - events.Repeat(6s, 12s); - break; - } - case EVENT_STATIC_CHARGE: - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true, 0)) - me->CastSpell(target, SPELL_STATIC_CHARGE, false); - - events.Repeat(20s); - break; - } - case EVENT_LIGHTNING_RING: - { - me->CastSpell(me, SPELL_LIGHTNING_RING, false); - events.Repeat(25s, 31s); - events.DelayEvents(10s); // Channel duration - break; - } - case EVENT_SUMMON_SPEACH: - { - if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN))) - { - brann->AI()->Talk(SAY_BRANN_SPAWN_TROGG); - } - - break; - } - case EVENT_SUMMON: - { - switch (SummonPhase) - { - case PHASE_SUMMON_UNFRIENDLY_DWARFES: - { - SummonDwarfes(false); - events.Repeat(20s); - break; - } - case PHASE_SUMMON_OOZE: - { - for (uint8 i = POS_GEN_RIGHT; i <= POS_GEN_LEFT; i++) - { - if (Creature* ooze = me->SummonCreature(NPC_OOZE, RoomPosition[i].GetPositionX(), RoomPosition[i].GetPositionY(), RoomPosition[i].GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) - { - ActivatePipe(i); - ooze->GetMotionMaster()->MovePoint(0, RoomPosition[POS_ROOM_CENTER].GetPositionX(), RoomPosition[POS_ROOM_CENTER].GetPositionY(), RoomPosition[POS_ROOM_CENTER].GetPositionZ()); - summons.Summon(ooze); - } - } - events.Repeat(10s); - break; - } - case PHASE_SUMMON_FRIENDLY_DWARFES: - { - SummonDwarfes(true); - break; - } - } - break; - } - } - - DoMeleeAttackIfReady(); - } - void JustDied(Unit* /*killer*/) override { Talk(SAY_DEATH); + _JustDied(); + if (GameObject* sd = me->GetMap()->GetGameObject(instance->GetGuidData(GO_SJONNIR_DOOR))) + sd->SetGoState(GO_STATE_ACTIVE); - summons.DespawnAll(); - if (pInstance) - { - pInstance->SetData(BOSS_SJONNIR, DONE); - if (GameObject* sd = me->GetMap()->GetGameObject(pInstance->GetGuidData(GO_SJONNIR_DOOR))) - sd->SetGoState(GO_STATE_ACTIVE); - - if (Creature* brann = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_BRANN))) - brann->AI()->DoAction(ACTION_SJONNIR_DEAD); - } + if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BRANN))) + brann->AI()->DoAction(ACTION_SJONNIR_DEAD); } void KilledUnit(Unit* /*victim*/) override @@ -333,42 +256,8 @@ public: void ActivatePipe(uint8 side) { - if (pInstance) - if (GameObject* pipe = me->GetMap()->GetGameObject(pInstance->GetGuidData(side == POS_GEN_RIGHT ? GO_RIGHT_PIPE : GO_LEFT_PIPE))) - pipe->SendCustomAnim(0); - } - - void SummonDwarfes(bool friendly) - { - if (friendly) - { - for (int i = 0; i < 3; i++) - { - uint8 Pos = urand(POS_GEN_RIGHT, POS_GEN_LEFT); - if (Creature* dwarf = me->SummonCreature(NPC_DWARFES_FRIENDLY, RoomPosition[Pos].GetPositionX(), RoomPosition[Pos].GetPositionY(), RoomPosition[Pos].GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) - { - if (Player* plr = SelectTargetFromPlayerList(100.0f)) - dwarf->SetFaction(plr->GetFaction()); - - ActivatePipe(Pos); - dwarf->AI()->AttackStart(me); - summons.Summon(dwarf); - } - } - } - else - { - for (int i = 0; i < 2; i++) - { - uint8 Pos = urand(POS_GEN_RIGHT, POS_GEN_LEFT); - if (Creature* dwarf = me->SummonCreature(urand(0, 1) ? NPC_FORGED_IRON_TROGG : NPC_FORGED_IRON_DWARF, RoomPosition[Pos].GetPositionX(), RoomPosition[Pos].GetPositionY(), RoomPosition[Pos].GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) - { - ActivatePipe(Pos); - dwarf->SetInCombatWithZone(); - summons.Summon(dwarf); - } - } - } + if (GameObject* pipe = me->GetMap()->GetGameObject(instance->GetGuidData(side == POS_GEN_RIGHT ? GO_RIGHT_PIPE : GO_LEFT_PIPE))) + pipe->SendCustomAnim(0); } }; }; @@ -423,8 +312,8 @@ public: } void JustDied(Unit* /*killer*/) override { - if (InstanceScript* pInstance = me->GetInstanceScript()) - if (Creature* sjonnir = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_SJONNIR))) + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* sjonnir = instance->GetCreature(BOSS_SJONNIR)) sjonnir->AI()->DoAction(ACTION_SLUG_KILLED); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/brann_bronzebeard.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/brann_bronzebeard.cpp index e4305328f..c03ee6813 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/brann_bronzebeard.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/brann_bronzebeard.cpp @@ -424,6 +424,7 @@ public: DoCast(me, 58506, false); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY_UNARMED); me->SendMovementFlagUpdate(); + me->SetImmuneToAll(true); break; case ACTION_START_SJONNIR_FIGHT: me->SetFaction(FACTION_FRIENDLY); @@ -560,14 +561,9 @@ public: if (!plr) return; //no target - float speed = 10.0f; - float tooFarAwaySpeed = me->GetDistance(plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ()) / (5000.0f * 0.001f); - if (speed < tooFarAwaySpeed) - speed = tooFarAwaySpeed; + darkMatterTarget->GetMotionMaster()->MovePoint(0, plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ()); - darkMatterTarget->GetMotionMaster()->MovePoint(0, plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), FORCED_MOVEMENT_NONE, speed); - - if (darkMatterTarget->GetDistance(plr) < 15.0f) + if (darkMatterTarget->GetDistance(plr) < 5.0f) { events.RescheduleEvent(EVENT_DARK_MATTER_END, 3s); } @@ -898,8 +894,6 @@ void brann_bronzebeard::brann_bronzebeardAI::WaypointReached(uint32 id) { pInstance->SetData(BRANN_BRONZEBEARD, 4); me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); - if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(NPC_SJONNIR))) - cr->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); me->SetOrientation(3.132660f); DoCast(me, 58506, false); me->SendMovementFlagUpdate(); diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.h b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.h index c9188b35e..bcb41d0f3 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.h +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.h @@ -78,6 +78,7 @@ enum npcs NPC_ABEDNEUM = 30899, NPC_SJONNIR = 27978, NPC_BRANN = 28070, + NPC_IRON_SLUDGE = 28165, ACTION_START_ESCORT_EVENT = 0, ACTION_START_TRIBUNAL = 1, diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp index dd6cd84b8..9bafefa92 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp @@ -20,6 +20,18 @@ #include "ScriptedCreature.h" #include "halls_of_stone.h" +ObjectData const summonData[] = +{ + { NPC_IRON_SLUDGE, BOSS_SJONNIR }, + { 0, 0 } +}; + +ObjectData const creatureData[] = +{ + { NPC_SJONNIR, BOSS_SJONNIR }, + { 0, 0 } +}; + class instance_halls_of_stone : public InstanceMapScript { public: @@ -57,6 +69,9 @@ public: void Initialize() override { SetHeaders(DataHeader); + SetBossNumber(MAX_ENCOUNTER); + LoadObjectData(creatureData, nullptr); + LoadSummonData(summonData); memset(&Encounter, 0, sizeof(Encounter)); brannAchievement = false; @@ -121,13 +136,12 @@ public: { switch (creature->GetEntry()) { - case NPC_SJONNIR: - SjonnirGUID = creature->GetGUID(); - break; case NPC_BRANN: BrannGUID = creature->GetGUID(); break; } + + InstanceScript::OnCreatureCreate(creature); } ObjectGuid GetGuidData(uint32 id) const override diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp index 97fa245be..05cd1ad05 100644 --- a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp @@ -182,7 +182,7 @@ public: case EVENT_SUMMON_KEEPER_OR_GUARDIAN: bKorG = true; spawned = true; - if (Creature* c = DoSummon(RAND(NPC_PORTAL_GUARDIAN, NPC_PORTAL_KEEPER), me, 2.0f, 0, TEMPSUMMON_DEAD_DESPAWN)) + if (Creature* c = DoSummon(RAND(NPC_PORTAL_GUARDIAN, NPC_PORTAL_KEEPER_1, NPC_PORTAL_KEEPER_2), me, 2.0f, 0, TEMPSUMMON_DEAD_DESPAWN)) me->CastSpell(c, SPELL_PORTAL_CHANNEL, false); events.RescheduleEvent(EVENT_SUMMON_KEEPER_TRASH, 20s); break; @@ -220,11 +220,12 @@ public: if (pInstance) for (SummonList::iterator itr = listOfMobs.begin(); itr != listOfMobs.end(); ++itr) if (Creature* c = pInstance->instance->GetCreature(*itr)) - if (c->IsAlive() && (c->GetEntry() == NPC_PORTAL_GUARDIAN || c->GetEntry() == NPC_PORTAL_KEEPER)) + if (c->IsAlive() && c->EntryEquals(NPC_PORTAL_GUARDIAN, NPC_PORTAL_KEEPER_1, NPC_PORTAL_KEEPER_2)) { me->CastSpell(c, SPELL_PORTAL_CHANNEL, false); return; } + Unit::Kill(me, me, false); } } diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.h b/src/server/scripts/Northrend/VioletHold/violet_hold.h index 4a3614089..cabf56383 100644 --- a/src/server/scripts/Northrend/VioletHold/violet_hold.h +++ b/src/server/scripts/Northrend/VioletHold/violet_hold.h @@ -47,7 +47,8 @@ enum Creatures NPC_CYANIGOSA = 31134, NPC_PORTAL_GUARDIAN = 30660, - NPC_PORTAL_KEEPER = 30695, + NPC_PORTAL_KEEPER_1 = 30695, + NPC_PORTAL_KEEPER_2 = 30893, NPC_AZURE_INVADER_1 = 30661, NPC_AZURE_INVADER_2 = 30961, NPC_AZURE_SPELLBREAKER_1 = 30662, diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index 3ee7f2272..9dbd17d05 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -562,200 +562,13 @@ private: Position _fezzix; }; -/*###### -## Quest 11590: Abduction -######*/ - -// NPC 25316: Beryl Sorcerer -enum BerylSorcerer -{ - EVENT_FROSTBOLT = 1, - EVENT_ARCANE_CHAINS = 2, - NPC_LIBRARIAN_DONATHAN = 25262, - NPC_CAPTURED_BERLY_SORCERER = 25474, - SPELL_FROSTBOLT = 9672, - SPELL_ARCANE_CHAINS = 45611, - SPELL_ARCANE_CHAINS_CHARACTER_FORCE_CAST = 45625, - SPELL_ARCANE_CHAINS_SUMMON_CHAINED_MAGE_HUNTER = 45626, - SPELL_COSMETIC_ENSLAVE_CHAINS_SELF = 45631, - SPELL_ARCANE_CHAINS_CHANNEL_II = 45735 -}; - -class npc_beryl_sorcerer : public CreatureScript -{ -public: - npc_beryl_sorcerer() : CreatureScript("npc_beryl_sorcerer") { } - -struct npc_beryl_sorcererAI : public CreatureAI - { - npc_beryl_sorcererAI(Creature* creature) : CreatureAI(creature) - { - Initialize(); - } - - void Initialize() - { - _playerGUID.Clear(); - _chainsCast = false; - } - - void Reset() override - { - me->SetReactState(REACT_AGGRESSIVE); - Initialize(); - } - - void JustEngagedWith(Unit* who) override - { - if (me->IsValidAttackTarget(who)) - { - AttackStart(who); - } - - _events.ScheduleEvent(EVENT_FROSTBOLT, 3s, 4s); - } - - void SpellHit(Unit* unit, SpellInfo const* spell) override - { - if (spell->Id == SPELL_ARCANE_CHAINS && !_chainsCast) - { - if (Player* player = unit->ToPlayer()) - { - _playerGUID = player->GetGUID(); - _chainsCast = true; - _events.ScheduleEvent(EVENT_ARCANE_CHAINS, 4s); - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - { - return; - } - - _events.Update(diff); - - if (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_FROSTBOLT: - DoCastVictim(SPELL_FROSTBOLT); - _events.ScheduleEvent(EVENT_FROSTBOLT, 3s, 4s); - break; - case EVENT_ARCANE_CHAINS: - if (me->HasAura(SPELL_ARCANE_CHAINS)) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) - { - me->CastSpell(player, SPELL_ARCANE_CHAINS_CHARACTER_FORCE_CAST, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS & ~TRIGGERED_IGNORE_CAST_ITEM)); - player->KilledMonsterCredit(NPC_CAPTURED_BERLY_SORCERER); - me->DisappearAndDie(); - } - } - break; - } - } - DoMeleeAttackIfReady(); - } - - private: - EventMap _events; - ObjectGuid _playerGUID; - bool _chainsCast; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_beryl_sorcererAI(creature); - } -}; - -// NPC 25474: Captured Beryl Sorcerer -enum CapturedBerylSorcerer -{ - EVENT_ADD_ARCANE_CHAINS = 1, - EVENT_FOLLOW_PLAYER = 2 -}; - -class npc_captured_beryl_sorcerer : public CreatureScript -{ -public: - npc_captured_beryl_sorcerer() : CreatureScript("npc_captured_beryl_sorcerer") {} - - struct npc_captured_beryl_sorcererAI : public FollowerAI - { - npc_captured_beryl_sorcererAI(Creature* creature) : FollowerAI(creature) - { - Initialize(); - } - - void Initialize() - { - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); - _events.ScheduleEvent(EVENT_ADD_ARCANE_CHAINS, 0ms); - } - - void Reset() override - { - Initialize(); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - if (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_ADD_ARCANE_CHAINS: - if (TempSummon* tempSummon = me->ToTempSummon()) - { - if (Unit* summoner = tempSummon->GetSummonerUnit()) - { - summoner->CastSpell(summoner, SPELL_ARCANE_CHAINS_CHANNEL_II, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS & ~TRIGGERED_IGNORE_CAST_ITEM & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST & ~TRIGGERED_IGNORE_GCD)); - _events.ScheduleEvent(EVENT_FOLLOW_PLAYER, 1s); - } - } - break; - - case EVENT_FOLLOW_PLAYER: - if (TempSummon* tempSummon = me->ToTempSummon()) - { - if (Player* summoner = tempSummon->GetSummonerUnit()->ToPlayer()) - { - StartFollow(summoner); - } - } - break; - } - } - } - - void MoveInLineOfSight(Unit* who) override - { - FollowerAI::MoveInLineOfSight(who); - - if (who->GetEntry() == NPC_LIBRARIAN_DONATHAN && me->IsWithinDistInMap(who, INTERACTION_DISTANCE)) - { - SetFollowComplete(); - me->DespawnOrUnsummon(); - } - } - private: - EventMap _events; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_captured_beryl_sorcererAI(creature); - } -}; - // Spell 45625: - Arcane Chains: Character Force Cast +enum ArcaneChains +{ + SPELL_ARCANE_CHAINS_CHARACTER_FORCE_CAST = 45625, + SPELL_ARCANE_CHAINS_SUMMON_CHAINED_MAGE_HUNTER = 45626 +}; + class spell_arcane_chains_character_force_cast : public SpellScript { PrepareSpellScript(spell_arcane_chains_character_force_cast); @@ -781,7 +594,8 @@ class spell_arcane_chains_character_force_cast : public SpellScript ######*/ enum ImprisionedBerylSorcerer { - SPELL_NEURAL_NEEDLE = 45634, + SPELL_NEURAL_NEEDLE = 45634, + SPELL_COSMETIC_ENSLAVE_CHAINS_SELF = 45631, NPC_IMPRISONED_BERYL_SORCERER = 25478, @@ -2187,8 +2001,6 @@ void AddSC_borean_tundra() new npc_iruk(); new npc_nerubar_victim(); new npc_lurgglbr(); - new npc_beryl_sorcerer(); - new npc_captured_beryl_sorcerer(); RegisterSpellScript(spell_arcane_chains_character_force_cast); new npc_imprisoned_beryl_sorcerer(); new npc_mootoo_the_younger(); diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp index f7b1252a6..aca0f0803 100644 --- a/src/server/scripts/Northrend/zone_dragonblight.cpp +++ b/src/server/scripts/Northrend/zone_dragonblight.cpp @@ -789,7 +789,11 @@ class spell_q12237_rescue_villager : public SpellScript result = SPELL_FAILED_CUSTOM_ERROR; } - if (!GetCaster()->FindNearestCreature(NPC_HELPLESS_VILLAGER_A, 5.0f) && !GetCaster()->FindNearestCreature(NPC_HELPLESS_VILLAGER_B, 5.0f)) + std::list villagers; + GetCaster()->GetCreatureListWithEntryInGrid(villagers, { NPC_HELPLESS_VILLAGER_A, NPC_HELPLESS_VILLAGER_B }, 5.0f); + villagers.remove_if([](Creature* c) { return !c->IsAlive() || c->HasAura(SPELL_RIDE_VEHICLE); }); + + if (villagers.empty()) { extension = SPELL_CUSTOM_ERROR_MUST_BE_NEAR_HELPLESS_VILLAGER; result = SPELL_FAILED_CUSTOM_ERROR; diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp index 5a50bee8a..f50c8e442 100644 --- a/src/server/scripts/Northrend/zone_storm_peaks.cpp +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -1169,6 +1169,43 @@ class spell_feed_stormcrest_eagle : public SpellScript } }; +enum MammothExplosion +{ + SPELL_MAMMOTH_EXPL_1 = 54627, + SPELL_MAMMOTH_EXPL_2 = 54628, + SPELL_MAMMOTH_EXPL_3 = 54623, + SPELL_MAIN_MAMMOTH_MEAT = 57444 +}; + +// 54581 - Mammoth Explosion Spell Spawner +class spell_mammoth_explosion : public SpellScript +{ + PrepareSpellScript(spell_mammoth_explosion); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAMMOTH_EXPL_1, SPELL_MAMMOTH_EXPL_2, SPELL_MAMMOTH_EXPL_3, SPELL_MAIN_MAMMOTH_MEAT }); + } + + void HandleOnEffectHit(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + { + for (uint32 spellId : { SPELL_MAMMOTH_EXPL_1, SPELL_MAMMOTH_EXPL_2, SPELL_MAMMOTH_EXPL_3 }) + target->CastSpell(GetHitUnit(), spellId, true); + + target->CastSpell(GetHitUnit(), SPELL_MAIN_MAMMOTH_MEAT, true); + + target->SetVisible(false); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mammoth_explosion::HandleOnEffectHit, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + void AddSC_storm_peaks() { RegisterCreatureAI(npc_frosthound); @@ -1186,4 +1223,5 @@ void AddSC_storm_peaks() new npc_vehicle_d16_propelled_delivery(); RegisterSpellScript(spell_q12823_remove_collapsing_cave_aura); RegisterSpellScript(spell_feed_stormcrest_eagle); + RegisterSpellScript(spell_mammoth_explosion); } diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index b2d312a5a..aee556af8 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -152,7 +152,7 @@ class spell_dk_raise_ally : public SpellScript SpellCastResult CheckCast() { - Player* unitTarget = GetHitPlayer(); + Unit* unitTarget = GetExplTargetUnit(); if (!unitTarget) return SPELL_FAILED_BAD_TARGETS;