diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 06d549e77..34bcd6336 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -69,7 +69,8 @@ body: attributes: label: Operating system description: | - Operating System, i.e. Windows 10 x64, Debian 10 x64, etc + The Operating System the Server is running on. + i.e. Windows 11 x64, Debian 10 x64, macOS 12, Ubuntu 20.04 validations: required: true - type: textarea diff --git a/data/sql/updates/db_world/2023_03_30_00.sql b/data/sql/updates/db_world/2023_03_30_00.sql new file mode 100644 index 000000000..759849695 --- /dev/null +++ b/data/sql/updates/db_world/2023_03_30_00.sql @@ -0,0 +1,3 @@ +-- DB update 2023_03_29_04 -> 2023_03_30_00 +-- +DELETE FROM `creature` WHERE `id1` = 20978; diff --git a/data/sql/updates/db_world/2023_03_30_01.sql b/data/sql/updates/db_world/2023_03_30_01.sql new file mode 100644 index 000000000..f82ccd4f9 --- /dev/null +++ b/data/sql/updates/db_world/2023_03_30_01.sql @@ -0,0 +1,3 @@ +-- DB update 2023_03_30_00 -> 2023_03_30_01 +-- +DELETE FROM `creature_onkill_reputation` WHERE (`creature_id` IN (21466, 21467)); diff --git a/data/sql/updates/db_world/2023_03_30_02.sql b/data/sql/updates/db_world/2023_03_30_02.sql new file mode 100644 index 000000000..3b0fa285e --- /dev/null +++ b/data/sql/updates/db_world/2023_03_30_02.sql @@ -0,0 +1,9 @@ +-- DB update 2023_03_30_01 -> 2023_03_30_02 +-- +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 1922001) AND (`source_type` = 9) AND (`id` IN (3)); +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`, `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 +(1922001, 9, 3, 0, 0, 0, 100, 512, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mechanar Gauntlet Engage - Actionlist - Set In Combat With Zone'); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 1922002) AND (`source_type` = 9) 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`, `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 +(1922002, 9, 2, 0, 0, 0, 100, 512, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mechanar Gauntlet Engage 2 - Actionlist - Set In Combat With Zone'); diff --git a/data/sql/updates/db_world/2023_03_30_03.sql b/data/sql/updates/db_world/2023_03_30_03.sql new file mode 100644 index 000000000..48cec48aa --- /dev/null +++ b/data/sql/updates/db_world/2023_03_30_03.sql @@ -0,0 +1,9 @@ +-- DB update 2023_03_30_02 -> 2023_03_30_03 +-- +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceEntry` = 35301) AND (`ConditionTypeOrReference` = 31) AND (`ConditionValue2` = 21062); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 35301, 0, 0, 31, 0, 3, 21062, 0, 0, 0, 0, '', 'Spell Suicide (35301) only targets Nether Wraith (21062)'); + +DELETE FROM `creature_equip_template` WHERE (`CreatureID` = 19220 AND `ID` = 2); +INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES +(19220, 2, 29455, 0, 0, 48526); diff --git a/data/sql/updates/db_world/2023_03_30_04.sql b/data/sql/updates/db_world/2023_03_30_04.sql new file mode 100644 index 000000000..e7f92b744 --- /dev/null +++ b/data/sql/updates/db_world/2023_03_30_04.sql @@ -0,0 +1,2 @@ +-- DB update 2023_03_30_03 -> 2023_03_30_04 +DELETE FROM reference_loot_template WHERE (`Entry` = 4110) AND (`Item` IN (30520, 30986)); diff --git a/data/sql/updates/db_world/2023_03_30_05.sql b/data/sql/updates/db_world/2023_03_30_05.sql new file mode 100644 index 000000000..d1efb0b6f --- /dev/null +++ b/data/sql/updates/db_world/2023_03_30_05.sql @@ -0,0 +1,3 @@ +-- DB update 2023_03_30_04 -> 2023_03_30_05 +-- Floating Ivory Bell +UPDATE `gameobject` SET `position_z` = 145.04 WHERE `id` = 184443 AND `guid` = 25285; diff --git a/data/sql/updates/db_world/2023_03_30_06.sql b/data/sql/updates/db_world/2023_03_30_06.sql new file mode 100644 index 000000000..d961a0fe3 --- /dev/null +++ b/data/sql/updates/db_world/2023_03_30_06.sql @@ -0,0 +1,16 @@ +-- DB update 2023_03_30_05 -> 2023_03_30_06 +-- +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 20405); +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`, `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 +(20405, 0, 0, 1, 25, 0, 100, 512, 0, 0, 0, 0, 0, 75, 35150, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nether Charge - On Reset - Add Aura \'Nether Charge Passive\''), +(20405, 0, 1, 2, 61, 0, 100, 512, 0, 0, 0, 0, 0, 11, 37670, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nether Charge - On Reset - Cast \'Nether Charge Timer\''), +(20405, 0, 2, 3, 61, 0, 100, 512, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nether Charge - On Reset - Set Reactstate Passive'), +(20405, 0, 3, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 89, 20, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nether Charge - On Reset - Start Random Movement'), +(20405, 0, 4, 0, 60, 0, 100, 513, 8500, 8500, 0, 0, 0, 80, 2040500, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nether Charge - On Update - Run Script (No Repeat)'); + +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2040500); +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`, `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 +(2040500, 9, 0, 0, 0, 0, 100, 512, 0, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nether Charge - Actionlist - Stop Random Movement'), +(2040500, 9, 1, 0, 0, 0, 100, 512, 2000, 2000, 0, 0, 0, 11, 35151, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nether Charge - Actionlist - Cast \'Nether Charge Pulse\''), +(2040500, 9, 2, 0, 0, 0, 100, 512, 2000, 2000, 0, 0, 0, 11, 35151, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nether Charge - Actionlist - Cast \'Nether Charge Pulse\''), +(2040500, 9, 3, 0, 0, 0, 100, 512, 2000, 2000, 0, 0, 0, 11, 35151, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Nether Charge - Actionlist - Cast \'Nether Charge Pulse\''); diff --git a/data/sql/updates/db_world/2023_03_30_07.sql b/data/sql/updates/db_world/2023_03_30_07.sql new file mode 100644 index 000000000..1f2cf2c89 --- /dev/null +++ b/data/sql/updates/db_world/2023_03_30_07.sql @@ -0,0 +1,5 @@ +-- DB update 2023_03_30_06 -> 2023_03_30_07 +-- +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 20210); +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`, `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 +(20210, 0, 0, 0, 1, 0, 100, 0, 0, 0, 600000, 600000, 0, 11, 36576, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shaleskin Flayer - Out Of Combat - Cast \'Shaleskin\''); diff --git a/data/sql/updates/db_world/2023_03_31_00.sql b/data/sql/updates/db_world/2023_03_31_00.sql new file mode 100644 index 000000000..e119e2c98 --- /dev/null +++ b/data/sql/updates/db_world/2023_03_31_00.sql @@ -0,0 +1,278 @@ +-- DB update 2023_03_30_07 -> 2023_03_31_00 +-- +UPDATE `spell_dbc` SET `Effect_1` = 28, `EffectMiscValueB_1` = 64, `EffectBasePoints_1` = -1 WHERE `ID` IN ( +14802 -- Idol Room Spawn B +); + +UPDATE `spell_dbc` SET `Effect_1` = 28, `EffectMiscValueB_1` = 64, `EffectBasePoints_1` = 0 WHERE `ID` IN ( +12694, -- Idol Room Spawn A +12949, -- Idol Room Spawn End Boss +14801, -- Idol Room Spawn C +19826, -- Summon Blackwing Legionnaire +19827, -- Summon Blackwing Mage +19828, -- Summon Death Talon Dragonspawn +20172, -- Summon Onyxian Whelp +21287, -- Conjure Lokholar the Usurper DND +23118, -- Conjure Scourge Footsoldier DND +23209, -- Terrordale Haunting Spirit #2 +23253, -- Terrordale Haunting Spirit #3 +23361, -- Raise Undead Drakonid +24215, -- Create Heart of Hakkar Explosion +24250, -- Summon Zulian Stalker +24349, -- Summon Bloodlord's Raptor +25151, -- Summon Vekniss Drone +26140, -- Summon Hook Tentacle +26144, -- Summon Eye Tentacle +26145, -- Summon Eye Tentacle +26146, -- Summon Eye Tentacle +26147, -- Summon Eye Tentacle +26148, -- Summon Eye Tentacle +26149, -- Summon Eye Tentacle +26150, -- Summon Eye Tentacle +26151, -- Summon Eye Tentacle +26191, -- Teleport Giant Hook Tentacle +26216, -- Summon Giant Hook Tentacles +26396, -- Summon Portal Ground State +26477, -- Summon Giant Portal Ground State +26564, -- Summon Viscidus Trigger +26617, -- Summon Ouro Mound +26768, -- Summon Giant Eye Tentacles +26837, -- Summon InCombat Trigger +27178, -- Defile +27643, -- Summon Spirit of Jarien +27644, -- Summon Spirit of Sothos +27884, -- Summon Trainee +27921, -- Summon Spectral Trainee +27932, -- Summon Spectral Knight +27939, -- Summon Spectral Rivendare +28008, -- Summon Knight +28010, -- Summon Mounted Knight +28175, -- (DND) Summon Crystal Minion, Ghost +28177, -- (DND) Summon Crystal Minion, Skeleton +28179, -- (DND) Summon Crystal Minion, Ghoul +28217, -- Summon Zombie Chow +28218, -- Summon Fallout Slime +28227, -- (DND) Summon Crystal Minion, finder +28289, -- (DND) Summon Crystal Minion, Ghoul Uncommon +28290, -- (DND) Summon Crystal Minion, Ghost Uncommon +28291, -- (DND) Summon Crystal Minion, Skeleton Uncommon +28421, -- Summon Type A +28422, -- Summon Type B +28423, -- Summon Type C +28454, -- Summon Type D +28561, -- Summon Blizzard +28627, -- Summon Web Wrap +29141, -- Marauding Crust Borer +29218, -- Summon Flame Ring +29329, -- Summon Sapphiron's Wing Buffet +29508, -- Summon Crypt Guard +29869, -- Fished Up Murloc +30083, -- Summon Root Thresher +30445, -- Stillpine Ancestor Yor +30630, -- Debris +30737, -- Summon Heathen +30785, -- Summon Reaver +30786, -- Summon Sharpshooter +30954, -- Free Webbed Creature +30955, -- Free Webbed Creature +30956, -- Free Webbed Creature +30957, -- Free Webbed Creature +30958, -- Free Webbed Creature +30959, -- Free Webbed Creature +30960, -- Free Webbed Creature +30961, -- Free Webbed Creature +30962, -- Free Webbed Creature +30963, -- Free Webbed Creature +31010, -- Free Webbed Creature +31318, -- Summon Infinite Assassin +31321, -- Summon Black Morass Rift Lord +31391, -- Summon Black Morass Chrono Lord Deja +31392, -- Summon Black Morass Temporus +31393, -- Summon Black Morass Rift End Boss +31421, -- Summon Infinite Chronomancer +31528, -- Summon Gnome +31529, -- Summon Gnome +31530, -- Summon Gnome +31544, -- Summon Distiller +31545, -- Summon Distiller +31593, -- Summon Greater Manawraith +32114, -- Summon Wisp +32151, -- Infernal +32283, -- Focus Fire +32360, -- Summon Stolen Soul +32579, -- Portal Beam +32632, -- Summon Overrun Target +33121, -- A Vision of the Forgotten +33229, -- Wrath of the Astromancer +33242, -- Infernal +33363, -- Summon Infinite Executioner +33364, -- Summon Infinite Vanquisher +33367, -- Summon Astromancer Priest +33567, -- Summon Void Portal D +33677, -- Incite Chaos +33680, -- Incite Chaos +33681, -- Incite Chaos +33682, -- Incite Chaos +33683, -- Incite Chaos +33901, -- Summon Crystalhide Crumbler +33927, -- Summon Void Summoner +34064, -- Soul Split +34125, -- Spotlight +34175, -- Arcane Orb Primer +35127, -- Summon Boom Bot Target +35136, -- Summon Captured Critter +35142, -- Drijya Summon Imp +35145, -- Drijya Summon Doomguard +35146, -- Drijya Summon Terrorguard +35256, -- Summon Unstable Mushroom +35430, -- Infernal +35861, -- Summon Nether Vapor +35862, -- Summon Nether Vapor +35863, -- Summon Nether Vapor +35864, -- Summon Nether Vapor +36026, -- Conjure Elemental Soul: Earth +36036, -- Summon Netherstorm Target +36042, -- Summon Farahlon Crumbler +36043, -- Summon Farahlon Crumbler +36044, -- Summon Farahlon Crumbler +36045, -- Summon Farahlon Shardling +36046, -- Summon Farahlon Shardling +36047, -- Summon Farahlon Shardling +36048, -- Summon Motherlode Shardling +36049, -- Summon Motherlode Shardling +36050, -- Summon Motherlode Shardling +36112, -- Conjure Elemental Soul: Fire +36168, -- Conjure Elemental Soul: Water +36180, -- Conjure Elemental Soul: Air +36221, -- Summon Eye of the Citadel +36229, -- Summon Infinite Assassin +36231, -- Summon Infinite Chronomancer +36232, -- Summon Infinite Executioner +36233, -- Summon Infinite Vanquisher +36234, -- Summon Black Morass Rift Lord Alt +36235, -- Summon Black Morass Rift Keeper +36236, -- Summon Black Morass Rift Keeper +36521, -- Summon Arcane Explosion +36579, -- Summon Netherock Crumbler +36584, -- Summon Netherock Crumbler +36585, -- Summon Netherock Crumbler +36595, -- Summon Apex Crumbler +36596, -- Summon Apex Crumbler +36597, -- Summon Apex Crumbler +36724, -- Summon Phoenix Egg +36818, -- Attacking Infernal +36865, -- Summon Gnome Cannon Channel Target (DND) +37177, -- Summon Black Morass Infinite Chrono-Lord +37178, -- Summon Black Morass Infinite Timereaver +37457, -- Windsor Dismisses Horse DND +37606, -- Summon Infinite Assassin +37758, -- Bone Wastes - Summon Auchenai Spirit +37766, -- Summon Murloc A1 +37772, -- Summon Murloc B1 +37773, -- Summon Elemental A1 +37774, -- Summon Elemental B1 +37911, -- Summon Elemental A2 +37912, -- Summon Elemental A3 +37914, -- Summon Elemental B2 +37916, -- Summon Elemental B3 +37923, -- Summon Murloc A2 +37925, -- Summon Murloc A3 +37926, -- Summon Murloc A4 +37927, -- Summon Murloc A5 +37928, -- Summon Murloc B2 +37929, -- Summon Murloc B3 +37931, -- Summon Murloc B4 +37932, -- Summon Murloc B5 +38111, -- Summon Horde Bat Rider Guard +38114, -- Summon Horde Rooftop Alarm Sensor +38118, -- Summon Area 52 Death Machine Guard +38124, -- Summon Horde Ground Alarm Sensor +38137, -- Summon Sky Marker +38179, -- Summon Alliance Ground Alarm Sensor +38180, -- Summon Alliance Rooftop Alarm Sensor +38181, -- Summon Alliance Gryphon Guard +38261, -- Summon Area 52 Rooftop Alarm Sensor +38266, -- Summon Stormspire Ethereal Guard +38268, -- Summon Scryer Dragonhawk Guard +38270, -- Summon Stormspire Rooftop Alarm Sensor +38271, -- Summon Scryer Rooftop Alarm Sensor +38278, -- Summon Aldor Gryphon Guard +38283, -- Summon Aldor Rooftop Alarm Sensor +38286, -- Summon Sporeggar Sporebat Guard +38287, -- Summon Sporeggar Rooftop Alarm Sensor +38288, -- Summon Toshley Guard +38291, -- Summon Toshley Rooftop Alarm Sensor +38402, -- Summon Cenarion Storm Crow Guard +38403, -- Summon Cenarion Expedition Rooftop Alarm Sensor +38512, -- Fiery Boulder +38587, -- Summon Spirit of Redemption +38854, -- Hatch Arakkoa +38865, -- Hatch Bad Arakkoa +39080, -- Summon Mountain Shardling +39081, -- Summon Vortex Shardling +39186, -- Summon Random Tractor +39191, -- Sha'tari Flames +39302, -- Quest - The Exorcism, Summon Foul Purge +39305 -- Summon Flying Skull +); + +UPDATE `spell_dbc` SET `Effect_1` = 28, `EffectMiscValueB_1` = 64, `EffectBasePoints_1` = 1 WHERE `ID` IN ( +20734, -- Black Arrow +30792, -- Summon Ravager Ambusher +30825, -- Summon Siltfin Ambusher +30826, -- Summon Wildkin Ambusher +30976, -- Summon Gauntlet Guards +31995, -- Shattered Rumbler +39110 -- Summon Phoenix Adds +); + +UPDATE `spell_dbc` SET `Effect_1` = 28, `EffectMiscValueB_1` = 64, `EffectBasePoints_1` = 2 WHERE `ID` IN ( +30076, -- Summon Maexxna Spiderling +30827, -- Summon Bristlelimb Ambusher +36379 -- Call Skitterers +); + +UPDATE `spell_dbc` SET `Effect_1` = 28, `EffectMiscValueB_1` = 64, `EffectBasePoints_1` = 3 WHERE `ID` IN ( +26630, -- Spawn Vekniss Hatchlings +26631, -- Spawn Vekniss Hatchlings +26632, -- Spawn Vekniss Hatchlings +30828 -- Summon Sunhawk Ambushers +); + +UPDATE `spell_dbc` SET `Effect_1` = 28, `EffectMiscValueB_1` = 64, `EffectBasePoints_1` = 4 WHERE `ID` IN ( +33362 -- Summon Astromancer Adds +); + +UPDATE `spell_dbc` SET `Effect_1` = 28, `EffectMiscValueB_1` = 64, `EffectBasePoints_1` = 5 WHERE `ID` IN ( +23119, -- Conjure Peasant DND +23121 -- Conjure Peasant DND +); + +UPDATE `spell_dbc` SET `Effect_1` = 28, `EffectMiscValueB_1` = 64, `EffectBasePoints_1` = 9 WHERE `ID` IN ( +25789, -- Summon Yauj Brood +29434 -- Summon Maexxna Spiderling +); + +UPDATE `spell_dbc` SET `Effect_2` = 28, `EffectMiscValueB_2` = 64, `EffectBasePoints_2` = 1 WHERE `ID` IN ( +21883 -- Summon Healed Celebrian Vine +); + +UPDATE `spell_dbc` SET `Effect_2` = 28, `EffectMiscValueB_2` = 64, `EffectBasePoints_2` = 0 WHERE `ID` IN ( +23201, -- Hunter Epic Anti-Cheat DND +27939, -- Summon Spectral Rivendare +29110, -- Summon Enraged Mounts +30774, -- Summon Elekk +33614, -- Summon Void Portal B +33616, -- Summon Void Portal E +36616, -- Veneratus Spawn +39074, -- [DND]Rexxars Bird Effect +69868 -- Carrying Beer Barrels [TEST] +); + +UPDATE `spell_dbc` SET `Effect_2` = 28, `EffectMiscValueB_2` = 496, `EffectBasePoints_2` = 0 WHERE `ID` IN ( +74125 -- Summon Creator Spell Test +); + +UPDATE `spell_dbc` SET `Effect_3` = 28, `EffectMiscValueB_3` = 496, `EffectBasePoints_3` = 0 WHERE `ID` IN ( +33615 -- Summon Void Portal C +); diff --git a/data/sql/updates/db_world/2023_03_31_01.sql b/data/sql/updates/db_world/2023_03_31_01.sql new file mode 100644 index 000000000..1fc983fa9 --- /dev/null +++ b/data/sql/updates/db_world/2023_03_31_01.sql @@ -0,0 +1,8 @@ +-- DB update 2023_03_31_00 -> 2023_03_31_01 +-- +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (20867, -138927)) AND (`source_type` = 0) AND (`id` IN (3, 4)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(20867, 0, 3, 4, 6, 0, 100, 0, 0, 0, 0, 0, 0, 28, 36657, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Death Watcher - On Just Died - Remove Aura \'Death Count\''), +(20867, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 28, 38818, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Death Watcher - On Just Died - Remove Aura \'Death Count\''), +(-138927, 0, 3, 4, 6, 0, 100, 0, 0, 0, 0, 0, 0, 28, 36657, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Death Watcher - On Just Died - Remove Aura \'Death Count\''), +(-138927, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 28, 38818, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Death Watcher - On Just Died - Remove Aura \'Death Count\''); diff --git a/data/sql/updates/db_world/2023_03_31_02.sql b/data/sql/updates/db_world/2023_03_31_02.sql new file mode 100644 index 000000000..ff78eedcb --- /dev/null +++ b/data/sql/updates/db_world/2023_03_31_02.sql @@ -0,0 +1,3 @@ +-- DB update 2023_03_31_01 -> 2023_03_31_02 +-- +UPDATE `smart_scripts` SET `action_param2` = 2 WHERE `id` = 3 AND `entryorguid` IN (-28368, -27554, -27555, -27794); diff --git a/data/sql/updates/db_world/2023_03_31_03.sql b/data/sql/updates/db_world/2023_03_31_03.sql new file mode 100644 index 000000000..9d9603234 --- /dev/null +++ b/data/sql/updates/db_world/2023_03_31_03.sql @@ -0,0 +1,9 @@ +-- DB update 2023_03_31_02 -> 2023_03_31_03 +DELETE FROM `smart_scripts` WHERE (`entryorguid` BETWEEN 2087501 AND 2087506) AND (`source_type` = 9) AND (`id` IN (5)); +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`, `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 +(2087501, 9, 5, 0, 0, 0, 100, 0, 1500, 1500, 0, 0, 0, 28, 34333, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Negaton Screamer - Actionlist - Remove Aura \'Damage Reduction: Fire\''), +(2087502, 9, 5, 0, 0, 0, 100, 0, 1500, 1500, 0, 0, 0, 28, 34334, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Negaton Screamer - Actionlist - Remove Aura \'Damage Reduction: Frost\''), +(2087503, 9, 5, 0, 0, 0, 100, 0, 1500, 1500, 0, 0, 0, 28, 34331, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Negaton Screamer - Actionlist - Remove Aura \'Damage Reduction: Arcane\''), +(2087504, 9, 5, 0, 0, 0, 100, 0, 1500, 1500, 0, 0, 0, 28, 34335, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Negaton Screamer - Actionlist - Remove Aura \'Damage Reduction: Nature\''), +(2087505, 9, 5, 0, 0, 0, 100, 0, 1500, 1500, 0, 0, 0, 28, 34338, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Negaton Screamer - Actionlist - Remove Aura \'Damage Reduction: Shadow\''), +(2087506, 9, 5, 0, 0, 0, 100, 0, 1500, 1500, 0, 0, 0, 28, 34336, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Negaton Screamer - Actionlist - Remove Aura \'Damage Reduction: Holy\''); diff --git a/data/sql/updates/db_world/2023_03_31_04.sql b/data/sql/updates/db_world/2023_03_31_04.sql new file mode 100644 index 000000000..ce3efda2a --- /dev/null +++ b/data/sql/updates/db_world/2023_03_31_04.sql @@ -0,0 +1,8 @@ +-- DB update 2023_03_31_03 -> 2023_03_31_04 +-- +UPDATE `creature_template` SET `AIName` = '' WHERE `entry` = 13696; +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 13696) AND (`source_type` = 0); + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 178908) AND (`source_type` = 1) AND (`id` IN (4)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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 +(178908, 1, 4, 0, 8, 0, 100, 0, 21885, 0, 0, 0, 0, 50, 178904, 90000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Vylestem Vine - On Spellhit \'Heal Vylestem Vine\' - Summon Gameobject \'Vylestem Vine\''); diff --git a/data/sql/updates/db_world/2023_03_31_05.sql b/data/sql/updates/db_world/2023_03_31_05.sql new file mode 100644 index 000000000..350f3fe65 --- /dev/null +++ b/data/sql/updates/db_world/2023_03_31_05.sql @@ -0,0 +1,3 @@ +-- DB update 2023_03_31_04 -> 2023_03_31_05 +-- +UPDATE `creature_onkill_reputation` SET `MaxStanding1` = 7 WHERE (`creature_id` = 26081); diff --git a/data/sql/updates/db_world/2023_04_01_00.sql b/data/sql/updates/db_world/2023_04_01_00.sql new file mode 100644 index 000000000..4fa44d69f --- /dev/null +++ b/data/sql/updates/db_world/2023_04_01_00.sql @@ -0,0 +1,12 @@ +-- DB update 2023_03_31_05 -> 2023_04_01_00 +DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` IN (20867, -138927) AND `id` IN (3, 4, 5, 6)); +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`, `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 +(20867, 0, 3, 4, 6, 0, 100, 0, 0, 0, 0, 0, 0, 28, 36657, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Death Watcher - On Just Died - Remove Aura \'Death Count\''), +(20867, 0, 4, 5, 61, 0, 100, 0, 0, 0, 0, 0, 0, 28, 38818, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Death Watcher - On Just Died - Remove Aura \'Death Count\''), +(20867, 0, 5, 6, 61, 0, 100, 0, 0, 0, 0, 0, 0, 28, 36657, 0, 0, 0, 0, 0, 9, 0, 0, 100, 0, 0, 0, 0, 0, 'Death Watcher - On Just Died - Remove Aura \'Death Count\''), +(20867, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 28, 38818, 0, 0, 0, 0, 0, 9, 0, 0, 100, 0, 0, 0, 0, 0, 'Death Watcher - On Just Died - Remove Aura \'Death Count\''), + +(-138927, 0, 3, 4, 6, 0, 100, 0, 0, 0, 0, 0, 0, 28, 36657, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Death Watcher - On Just Died - Remove Aura \'Death Count\''), +(-138927, 0, 4, 5, 61, 0, 100, 0, 0, 0, 0, 0, 0, 28, 38818, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 'Death Watcher - On Just Died - Remove Aura \'Death Count\''), +(-138927, 0, 5, 6, 61, 0, 100, 0, 0, 0, 0, 0, 0, 28, 36657, 0, 0, 0, 0, 0, 9, 0, 0, 100, 0, 0, 0, 0, 0, 'Death Watcher - On Just Died - Remove Aura \'Death Count\''), +(-138927, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 28, 38818, 0, 0, 0, 0, 0, 9, 0, 0, 100, 0, 0, 0, 0, 0, 'Death Watcher - On Just Died - Remove Aura \'Death Count\''); diff --git a/data/sql/updates/db_world/2023_04_01_01.sql b/data/sql/updates/db_world/2023_04_01_01.sql new file mode 100644 index 000000000..8e931e94a --- /dev/null +++ b/data/sql/updates/db_world/2023_04_01_01.sql @@ -0,0 +1,6 @@ +-- DB update 2023_04_01_00 -> 2023_04_01_01 +-- +-- Harbinger Skyriss Normal Loot +UPDATE `reference_loot_template` SET `GroupId`=3 WHERE `Entry`=25004 AND `Item` IN (28413, 28414, 28415, 28416, 28418, 28419); +DELETE FROM `creature_loot_template` WHERE `Entry`=20912 AND `Item`=25004 AND `Reference`=25004 AND `GroupId`=3; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES (20912, 25004, 25004, 100, 0, 1, 3, 1, 1, 'Harbinger Skyriss - High Value Table (ReferenceTable)'); diff --git a/data/sql/updates/db_world/2023_04_01_02.sql b/data/sql/updates/db_world/2023_04_01_02.sql new file mode 100644 index 000000000..1aedb9055 --- /dev/null +++ b/data/sql/updates/db_world/2023_04_01_02.sql @@ -0,0 +1,10 @@ +-- DB update 2023_04_01_01 -> 2023_04_01_02 +-- +DELETE FROM `event_scripts` WHERE `id` IN (14592, 14593, 14595); + +UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE `entry` IN (182196, 182197, 182198); +DELETE FROM `smart_scripts` WHERE (`source_type` = 1 AND `entryorguid` IN (182196, 182197, 182198)); +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`, `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 +(182196, 1, 0, 0, 71, 0, 100, 1, 14592, 0, 0, 0, 0, 12, 22890, 4, 300000, 0, 0, 0, 8, 0, 0, 0, 0, -108.252, -510.302, 21.4761, 2.44346, 'Arcane Container - On Event 14592 Inform - Summon Creature \'First Fragment Guardian\''), +(182197, 1, 0, 0, 71, 0, 100, 1, 14593, 0, 0, 0, 0, 12, 22891, 4, 300000, 0, 0, 0, 8, 0, 0, 0, 0, 13.49, -307.87, -66, 3.12, 'Arcane Container - On Event 14593 Inform - Summon Creature \'Second Fragment Guardian\''), +(182198, 1, 0, 0, 71, 0, 100, 1, 14595, 0, 0, 0, 0, 12, 22892, 4, 300000, 0, 0, 0, 8, 0, 0, 0, 0, 312.72, -19.24, 22.44, 2.12, 'Arcane Container - On Event 14595 Inform - Summon Creature \'Third Fragment Guardian\''); diff --git a/data/sql/updates/db_world/2023_04_02_00.sql b/data/sql/updates/db_world/2023_04_02_00.sql new file mode 100644 index 000000000..d141681de --- /dev/null +++ b/data/sql/updates/db_world/2023_04_02_00.sql @@ -0,0 +1,6 @@ +-- DB update 2023_04_01_02 -> 2023_04_02_00 +DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2202300); +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`, `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 +(2202300, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 19, 22160, 50, 0, 0, 0, 0, 0, 0, '[DND]Spirit 1 - Actionlist - Move To Closest Creature \'Bloodmaul Taskmaster\''), +(2202300, 9, 1, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '[DND]Spirit 1 - Actionlist - Move To Invoker'), +(2202300, 9, 2, 0, 0, 0, 100, 0, 5000, 5000, 0, 0, 0, 33, 22383, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '[DND]Spirit 1 - Actionlist - Quest Credit \'On Spirit\'s Wings\''); diff --git a/data/sql/updates/db_world/2023_04_02_01.sql b/data/sql/updates/db_world/2023_04_02_01.sql new file mode 100644 index 000000000..8135446c1 --- /dev/null +++ b/data/sql/updates/db_world/2023_04_02_01.sql @@ -0,0 +1,24 @@ +-- DB update 2023_04_02_00 -> 2023_04_02_01 +-- Mote of Shadow +DELETE FROM `creature_loot_template` WHERE `Item` = 22577; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(16974, 22577, 0, 20, 0, 1, 0, 1, 1, 'Rogue Voidwalker - Mote of Shadow'), +(16975, 22577, 0, 20, 0, 1, 0, 1, 1, 'Uncontrolled Voidwalker - Mote of Shadow'), +(17014, 22577, 0, 20, 0, 1, 0, 1, 2, 'Collapsing Voidwalker - Mote of Shadow'), +(17981, 22577, 0, 18.6912, 0, 1, 0, 1, 2, 'Voidspawn - Mote of Shadow'), +(18683, 22577, 0, 25, 0, 1, 0, 1, 2, 'Voidhunter Yar - Mote of Shadow'), +(18869, 22577, 0, 1.0615, 0, 1, 0, 1, 2, 'Unstable Voidwraith - Mote of Shadow'), +(18870, 22577, 0, 1.0194, 0, 1, 0, 1, 2, 'Voidshrieker - Mote of Shadow'), +(19307, 22577, 0, 17.8397, 0, 1, 0, 1, 4, 'Nexus Terror - Mote of Shadow'), +(19527, 22577, 0, 20, 0, 1, 0, 1, 2, 'Vacillating Voidcaller - Mote of Shadow'), +(19554, 22577, 0, 60, 0, 1, 0, 2, 4, 'Dimensius the All-Devouring - Mote of Shadow'), +(20554, 22577, 0, 26.6608, 0, 1, 0, 1, 2, 'Arconus the Insatiable - Mote of Shadow'), +(20873, 22577, 0, 31.15, 0, 1, 0, 2, 4, 'Negaton Warp-Master - Mote of Shadow'), +(20875, 22577, 0, 30.59, 0, 1, 0, 2, 4, 'Negaton Screamer - Mote of Shadow'), +(22295, 22577, 0, 27.0833, 0, 1, 0, 2, 4, 'Deathforge Automaton - Mote of Shadow'), +(22301, 22577, 0, 37.8378, 0, 1, 0, 1, 2, 'Throne-Guard Sentinel - Mote of Shadow'), +-- Previously missing, from TrinityCore +(19299, 22577, 0, 42.4242, 0, 1, 0, 2, 4,'Deathwhisperer - Mote of Shadow'), +(20870, 22577, 0, 15, 0, 1, 0, 2, 4, 'Zereketh the Unbound - Mote of Shadow'), +(18341, 22577, 0, 15, 0, 1, 0, 2, 4, 'Pandemonius - Mote of Shadow'), +(19354, 22577, 0, 19.0751, 0, 1, 0, 2, 4, 'Arzeth the Merciless - Mote of Shadow'); diff --git a/data/sql/updates/db_world/2023_04_02_02.sql b/data/sql/updates/db_world/2023_04_02_02.sql new file mode 100644 index 000000000..77689ee88 --- /dev/null +++ b/data/sql/updates/db_world/2023_04_02_02.sql @@ -0,0 +1,2 @@ +-- DB update 2023_04_02_01 -> 2023_04_02_02 +UPDATE `smart_scripts` SET `event_type` = 25 AND `comment` = 'Arcatraz Sentinel - On Reset - Set Health 40%' WHERE `source_type` = 0 AND `entryorguid` = 20869 AND `id` = 0; diff --git a/data/sql/updates/db_world/2023_04_02_03.sql b/data/sql/updates/db_world/2023_04_02_03.sql new file mode 100644 index 000000000..0db4848f3 --- /dev/null +++ b/data/sql/updates/db_world/2023_04_02_03.sql @@ -0,0 +1,2 @@ +-- DB update 2023_04_02_02 -> 2023_04_02_03 +UPDATE `creature_template_addon` SET `mount` = 17697 WHERE (`entry` = 35101); diff --git a/data/sql/updates/db_world/2023_04_02_04.sql b/data/sql/updates/db_world/2023_04_02_04.sql new file mode 100644 index 000000000..6e9f5860f --- /dev/null +++ b/data/sql/updates/db_world/2023_04_02_04.sql @@ -0,0 +1,8 @@ +-- DB update 2023_04_02_03 -> 2023_04_02_04 +-- +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 2179700) AND (`source_type` = 9) AND (`id` IN (12)); +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`, `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 +(2179700, 9, 12, 0, 0, 0, 100, 512, 0, 0, 0, 0, 0, 41, 300000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Ancient Shadowmoon Spirit - Actionlist - Despawn In 300000 ms'); + + DELETE FROM `smart_scripts` WHERE (`entryorguid` = 21797) AND (`source_type` = 0) AND (`id` IN (9)); + diff --git a/data/sql/updates/db_world/2023_04_02_05.sql b/data/sql/updates/db_world/2023_04_02_05.sql new file mode 100644 index 000000000..e005c27a8 --- /dev/null +++ b/data/sql/updates/db_world/2023_04_02_05.sql @@ -0,0 +1,4 @@ +-- DB update 2023_04_02_04 -> 2023_04_02_05 +-- +ALTER TABLE `spell_enchant_proc_data` ADD COLUMN `attributeMask` INT UNSIGNED DEFAULT 0 NOT NULL AFTER `procEx`; +UPDATE `spell_enchant_proc_data` SET `attributeMask`=1 WHERE `entry`=3225; diff --git a/data/sql/updates/db_world/2023_04_02_06.sql b/data/sql/updates/db_world/2023_04_02_06.sql new file mode 100644 index 000000000..5fc0b7c57 --- /dev/null +++ b/data/sql/updates/db_world/2023_04_02_06.sql @@ -0,0 +1,8 @@ +-- DB update 2023_04_02_05 -> 2023_04_02_06 +-- +DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (-138927, 20867)) AND (`source_type` = 0) AND (`id` IN (1, 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`, `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 +(20867, 0, 1, 0, 2, 0, 100, 0, 0, 75, 15000, 15000, 0, 11, 36655, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Death Watcher - Between 0-75% Health - Cast \'Drain Life\''), +(20867, 0, 2, 0, 2, 0, 100, 1, 0, 50, 0, 0, 0, 11, 36657, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Death Watcher - Between 0-50% Health - Cast \'Death Count\' (No Repeat)'), +(-138927, 0, 1, 0, 2, 0, 100, 0, 0, 75, 15000, 15000, 0, 11, 36655, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Death Watcher - Between 0-75% Health - Cast \'Drain Life\''), +(-138927, 0, 2, 0, 2, 0, 100, 1, 0, 50, 0, 0, 0, 11, 36657, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Death Watcher - Between 0-50% Health - Cast \'Death Count\' (No Repeat)'); diff --git a/data/sql/updates/db_world/2023_04_02_07.sql b/data/sql/updates/db_world/2023_04_02_07.sql new file mode 100644 index 000000000..f67d37a9f --- /dev/null +++ b/data/sql/updates/db_world/2023_04_02_07.sql @@ -0,0 +1,7 @@ +-- DB update 2023_04_02_06 -> 2023_04_02_07 +-- +UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask`|46284631 WHERE (`entry` IN (20866, 21614, 20898, 21598)); +UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask`|652689279 WHERE (`entry` IN (20870, 21626, 20912, 21601)); +UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask`|37882897 WHERE (`entry` IN (20875, 21604)); +UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask`|3089, `flags_extra`=`flags_extra`|256 WHERE (`entry` IN (20883, 21615)); +UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask`|16405, `flags_extra`=`flags_extra`|256 WHERE (`entry` IN (20869, 21586)); diff --git a/data/sql/updates/db_world/2023_04_02_08.sql b/data/sql/updates/db_world/2023_04_02_08.sql new file mode 100644 index 000000000..064ba801e --- /dev/null +++ b/data/sql/updates/db_world/2023_04_02_08.sql @@ -0,0 +1,11 @@ +-- DB update 2023_04_02_07 -> 2023_04_02_08 +-- +-- Warlord Kalithresh Normal Loot Repairs +UPDATE `creature_loot_template` SET `GroupId`=0 WHERE `Entry`=17798 AND `Item`=23572 AND `Reference`=0 AND `GroupId`=3; +UPDATE `creature_loot_template` SET `MaxCount`=1 WHERE `Entry`=17798 AND `Item`=35001 AND `Reference`=35001 AND `GroupId`=2; +UPDATE `reference_loot_template` SET `GroupId`=3 WHERE `Entry`=35001 AND `Item` IN (27475, 27510, 27804, 27805, 27806, 27874); +DELETE FROM `creature_loot_template` WHERE `Entry`=17798 AND `Item`=24313; +DELETE FROM `creature_loot_template` WHERE `Entry`=17798 AND `Item`=35001 AND `Reference`=35001 AND `GroupId`=3; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(17798, 24313, 0, 3.25, 0, 1, 0, 1, 1, 'Warlord Kalithresh - Pattern: Battlecast Hood'), +(17798, 35001, 35001, 100, 0, 1, 3, 1, 1, 'Warlord Kalithresh Table B - (ReferenceTable)'); diff --git a/data/sql/updates/db_world/2023_04_02_09.sql b/data/sql/updates/db_world/2023_04_02_09.sql new file mode 100644 index 000000000..c087781d2 --- /dev/null +++ b/data/sql/updates/db_world/2023_04_02_09.sql @@ -0,0 +1,34 @@ +-- DB update 2023_04_02_08 -> 2023_04_02_09 +-- Form Rhok'delar and Lok'delar at once +DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=23192; +INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES (23192, 24872, 0, 'Form Rhok\'delar and Lok\'delar at once '); + +-- Gossip_menu_option (30201) conditions (QUEST_REWARDED & _ITEM) +-- Require both quests 7636(Stave of the Ancients) & 7635(A Proper String) to be rewarded, to not have either Sinew or Rune and to not have either Bow or Stave. +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 15 AND `SourceGroup` = 30201; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(15, 30201, 0, 0, 0, 8, 0, 7636, 0, 0, 0, 0, 0, '', '(AND) Require quest 7636(Stave of the Ancients) to be rewarded.'), +(15, 30201, 0, 0, 0, 8, 0, 7635, 0, 0, 0, 0, 0, '', '(AND) Require quest 7635(A Proper String) to be rewarded.'), +(15, 30201, 0, 0, 0, 2, 0, 18713, 1, 1, 1, 0, 0, '', '(AND) Require item 18713(Rhok\'delar) to not be in inventory or bank.'), +(15, 30201, 0, 0, 0, 2, 0, 18707, 1, 1, 1, 0, 0, '', '(AND) Require item 18707(Ancient Rune Etched Stave) to not be in inventory or bank.'), +(15, 30201, 0, 0, 0, 2, 0, 18724, 1, 1, 1, 0, 0, '', '(AND) Require item 18724(Enchanted Black Dragon Sinew) to not be in inventory or bank.'), +(15, 30201, 1, 0, 0, 8, 0, 7636, 0, 0, 0, 0, 0, '', '(AND) Require quest 7636(Stave of the Ancients) to be rewarded.'), +(15, 30201, 1, 0, 0, 8, 0, 7635, 0, 0, 0, 0, 0, '', '(AND) Require quest 7635(A Proper String) to be rewarded.'), +(15, 30201, 1, 0, 0, 2, 0, 18715, 1, 1, 1, 0, 0, '', '(AND) Require item 18715(Lok\'delar) to not be in inventory or bank.'), +(15, 30201, 1, 0, 0, 2, 0, 18707, 1, 1, 1, 0, 0, '', '(AND) Require item 18707(Ancient Rune Etched Stave) to not be in inventory or bank.'), +(15, 30201, 1, 0, 0, 2, 0, 18724, 1, 1, 1, 0, 0, '', '(AND) Require item 18724(Enchanted Black Dragon Sinew) to not be in inventory or bank.'); + +-- Vartus the Ancient +DELETE FROM `gossip_menu_option` WHERE `MenuID`=30201; +INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES +(30201, 0, 0, 'Greetings, ancient one. I have done all that has been asked of me. I now ask that you grant me Rhok\'delar.', 10784, 1, 1, 0, 0, 0, 0, '', 0, 0), +(30201, 1, 0, 'Greetings, ancient one. I have done all that has been asked of me. I now ask that you grant me Lok\'delar.', 10785, 1, 1, 0, 0, 0, 0, '', 0, 0); + +-- SAI +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 14524; + +DELETE FROM `smart_scripts` WHERE `entryorguid` = 14524; +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`, `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 +(14524, 0, 0, 2, 62, 0, 100, 0, 30201, 0, 0, 0, 0, 56, 18713, 1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Vartrus the Ancient - On Gossip Option 0 Selected - Add Item \'Rhok\'delar, Longbow of the Ancient Keepers\' '), +(14524, 0, 1, 2, 62, 0, 100, 0, 30201, 1, 0, 0, 0, 56, 18715, 1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Vartrus the Ancient - On Gossip Option 1 Selected - Add Item \'Lok\'delar, Stave of the Ancient Keepers\''), +(14524, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Vartrus the Ancient - On Gossip Option - Close Gossip'); diff --git a/data/sql/updates/db_world/2023_04_02_10.sql b/data/sql/updates/db_world/2023_04_02_10.sql new file mode 100644 index 000000000..db811f17d --- /dev/null +++ b/data/sql/updates/db_world/2023_04_02_10.sql @@ -0,0 +1,7 @@ +-- DB update 2023_04_02_09 -> 2023_04_02_10 +-- +DELETE FROM `reference_loot_template` WHERE `Entry` = 24076 AND `Item` = 1927; + +DELETE FROM `creature_loot_template` WHERE `Entry` = 594 AND `Item` = 1927; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(594,1927,0,6,0,1,1,1,1,'Defias Henchman - Deadmines Cleaver'); diff --git a/data/sql/updates/db_world/2023_04_02_11.sql b/data/sql/updates/db_world/2023_04_02_11.sql new file mode 100644 index 000000000..88d91c606 --- /dev/null +++ b/data/sql/updates/db_world/2023_04_02_11.sql @@ -0,0 +1,5 @@ +-- DB update 2023_04_02_10 -> 2023_04_02_11 +-- +DELETE FROM `spell_proc_event` WHERE `entry`=43730; +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `procPhase`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(43730,0,0,0,0,0,0,0,2,0,0,8000); diff --git a/data/sql/updates/db_world/2023_04_03_00.sql b/data/sql/updates/db_world/2023_04_03_00.sql new file mode 100644 index 000000000..d6d4b0ffc --- /dev/null +++ b/data/sql/updates/db_world/2023_04_03_00.sql @@ -0,0 +1,13 @@ +-- DB update 2023_04_02_11 -> 2023_04_03_00 +-- +SET @PATH = 36853 * 10; +DELETE FROM `waypoint_data` WHERE `id`=@PATH; +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES +(@PATH, 1, 4551.7847, 2444.7153, 228.58171,0,0,0,0,100,0), +(@PATH, 2, 4555.238, 2370.889, 229.2206,0,0,0,0,100,0), +(@PATH, 3, 4617.6616, 2352.2952, 214.60947,0,0,0,0,100,0), +(@PATH, 4, 4673.6704, 2437.1182, 218.91505,0,0,0,0,100,0), +(@PATH, 5, 4659.0747, 2579.3906, 229.49834,0,0,0,0,100,0), +(@PATH, 6, 4591.4316, 2598.192, 229.97064,0,0,0,0,100,0), +(@PATH, 7, 4564.4287, 2562.0461, 230.72063,0,0,0,0,100,0), +(@PATH, 8, 4555.6953, 2487.9895, 229.9706,0,0,0,0,100,0); diff --git a/src/server/apps/worldserver/Main.cpp b/src/server/apps/worldserver/Main.cpp index b53f99387..436724ff8 100644 --- a/src/server/apps/worldserver/Main.cpp +++ b/src/server/apps/worldserver/Main.cpp @@ -72,13 +72,15 @@ char serviceDescription[] = "AzerothCore World of Warcraft emulator world servic * 2 - paused */ int m_ServiceStatus = -1; + +#include +#include #endif #ifndef _ACORE_CORE_CONFIG #define _ACORE_CORE_CONFIG "worldserver.conf" #endif -#define WORLD_SLEEP_CONST 10 using namespace boost::program_options; namespace fs = std::filesystem; @@ -137,6 +139,44 @@ int main(int argc, char** argv) return WinServiceUninstall() == true ? 0 : 1; else if (configService.compare("run") == 0) WinServiceRun(); + + Optional newTimerResolution; + boost::system::error_code dllError; + std::shared_ptr winmm(new boost::dll::shared_library("winmm.dll", dllError, boost::dll::load_mode::search_system_folders), [&](boost::dll::shared_library* lib) + { + try + { + if (newTimerResolution) + lib->get("timeEndPeriod")(*newTimerResolution); + } + catch (std::exception const&) + { + // ignore + } + + delete lib; + }); + + if (winmm->is_loaded()) + { + try + { + auto timeGetDevCapsPtr = winmm->get("timeGetDevCaps"); + // setup timer resolution + TIMECAPS timeResolutionLimits; + if (timeGetDevCapsPtr(&timeResolutionLimits, sizeof(TIMECAPS)) == TIMERR_NOERROR) + { + auto timeBeginPeriodPtr = winmm->get("timeBeginPeriod"); + newTimerResolution = std::min(std::max(timeResolutionLimits.wPeriodMin, 1u), timeResolutionLimits.wPeriodMax); + timeBeginPeriodPtr(*newTimerResolution); + } + } + catch (std::exception const& e) + { + printf("Failed to initialize timer resolution: %s\n", e.what()); + } + } + #endif // Add file and args in config @@ -530,9 +570,15 @@ void ShutdownCLIThread(std::thread* cliThread) void WorldUpdateLoop() { + uint32 minUpdateDiff = uint32(sConfigMgr->GetOption("MinWorldUpdateTime", 1)); uint32 realCurrTime = 0; uint32 realPrevTime = getMSTime(); + uint32 maxCoreStuckTime = uint32(sConfigMgr->GetOption("MaxCoreStuckTime", 60)) * 1000; + uint32 halfMaxCoreStuckTime = maxCoreStuckTime / 2; + if (!halfMaxCoreStuckTime) + halfMaxCoreStuckTime = std::numeric_limits::max(); + LoginDatabase.WarnAboutSyncQueries(true); CharacterDatabase.WarnAboutSyncQueries(true); WorldDatabase.WarnAboutSyncQueries(true); @@ -546,18 +592,19 @@ void WorldUpdateLoop() realCurrTime = getMSTime(); uint32 diff = getMSTimeDiff(realPrevTime, realCurrTime); + if (diff < minUpdateDiff) + { + uint32 sleepTime = minUpdateDiff - diff; + if (sleepTime >= halfMaxCoreStuckTime) + LOG_ERROR("server.worldserver", "WorldUpdateLoop() waiting for {} ms with MaxCoreStuckTime set to {} ms", sleepTime, maxCoreStuckTime); + // sleep until enough time passes that we can update all timers + std::this_thread::sleep_for(Milliseconds(sleepTime)); + continue; + } sWorld->Update(diff); realPrevTime = realCurrTime; - uint32 executionTimeDiff = getMSTimeDiff(realCurrTime, getMSTime()); - - // we know exactly how long it took to update the world, if the update took less than WORLD_SLEEP_CONST, sleep for WORLD_SLEEP_CONST - world update time - if (executionTimeDiff < WORLD_SLEEP_CONST) - { - std::this_thread::sleep_for(Milliseconds(WORLD_SLEEP_CONST - executionTimeDiff)); - } - #ifdef _WIN32 if (m_ServiceStatus == 0) World::StopNow(SHUTDOWN_EXIT_CODE); @@ -595,10 +642,14 @@ void FreezeDetector::Handler(std::weak_ptr freezeDetectorRef, bo freezeDetector->_worldLoopCounter = worldLoopCounter; } // possible freeze - else if (getMSTimeDiff(freezeDetector->_lastChangeMsTime, curtime) > freezeDetector->_maxCoreStuckTimeInMs) + else { - LOG_ERROR("server.worldserver", "World Thread hangs, kicking out server!"); - ABORT(); + uint32 msTimeDiff = getMSTimeDiff(freezeDetector->_lastChangeMsTime, curtime); + if (msTimeDiff > freezeDetector->_maxCoreStuckTimeInMs) + { + LOG_ERROR("server.worldserver", "World Thread hangs for {} ms, forcing a crash!", msTimeDiff); + ABORT("World Thread hangs for {} ms, forcing a crash!", msTimeDiff); + } } freezeDetector->_timer.expires_from_now(boost::posix_time::seconds(1)); diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index d18bea3ad..99dfc9cc0 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -339,12 +339,19 @@ SocketTimeOutTimeActive = 60000 SessionAddDelay = 10000 +# +# MinWorldUpdateTime +# Description: Minimum time (milliseconds) between world update ticks (for mostly idle servers). +# Default: 1 - (0.001 second) + +MinWorldUpdateTime = 1 + # # MapUpdateInterval # Description: Time (milliseconds) for map update interval. -# Default: 100 - (0.1 second) +# Default: 10 - (0.01 second) -MapUpdateInterval = 100 +MapUpdateInterval = 10 # # ChangeWeatherInterval @@ -467,6 +474,7 @@ LogDB.Opt.ClearTime = 1209600 # # MaxCoreStuckTime # Description: Time (in seconds) before the server is forced to crash if it is frozen. +# FreezeDetector # Default: 0 - (Disabled) # 10+ - (Enabled, Recommended 30+) # Note: If enabled and the setting is too low, it can cause unexpected crash. diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 1ac0a406b..3f2b39ef6 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3905,7 +3905,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui if (!me || !me->IsEngaged()) return; - ObjectVector targets; + Unit* unitTarget = nullptr; switch (e.GetTargetType()) { case SMART_TARGET_CREATURE_RANGE: @@ -3916,8 +3916,8 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui case SMART_TARGET_PLAYER_RANGE: case SMART_TARGET_PLAYER_DISTANCE: { - if (targets.empty()) - return; + ObjectVector targets; + GetTargets(targets, e); for (WorldObject* target : targets) { if (IsUnit(target) && me->IsFriendlyTo(target->ToUnit()) && target->ToUnit()->IsAlive() && target->ToUnit()->IsInCombat()) @@ -3928,7 +3928,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui continue; } - target = target->ToUnit(); + unitTarget = target->ToUnit(); break; } } @@ -3937,16 +3937,16 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui } case SMART_TARGET_SELF: case SMART_TARGET_ACTION_INVOKER: - DoSelectLowestHpPercentFriendly((float)e.event.friendlyHealthPct.radius, e.event.friendlyHealthPct.minHpPct, e.event.friendlyHealthPct.maxHpPct); + unitTarget = DoSelectLowestHpPercentFriendly((float)e.event.friendlyHealthPct.radius, e.event.friendlyHealthPct.minHpPct, e.event.friendlyHealthPct.maxHpPct); break; default: return; } - if (targets.empty()) + if (!unitTarget) return; - ProcessTimedAction(e, e.event.friendlyHealthPct.repeatMin, e.event.friendlyHealthPct.repeatMax); + ProcessTimedAction(e, e.event.friendlyHealthPct.repeatMin, e.event.friendlyHealthPct.repeatMax, unitTarget); break; } case SMART_EVENT_DISTANCE_CREATURE: diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 4548a76ea..d9ebd3c26 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -2101,34 +2101,52 @@ void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* onlinePet /*= nullptr*/) { // not need after this call if (owner->ToPlayer()->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) + { owner->ToPlayer()->RemoveAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS, true); + } // reset for online if (onlinePet) + { onlinePet->resetTalents(); + } PetStable* petStable = owner->GetPetStable(); if (!petStable) + { return; + } std::unordered_set petIds; if (petStable->CurrentPet) + { petIds.insert(petStable->CurrentPet->PetNumber); + } for (Optional const& stabledPet : petStable->StabledPets) + { if (stabledPet) + { petIds.insert(stabledPet->PetNumber); + } + } for (PetStable::PetInfo const& unslottedPet : petStable->UnslottedPets) + { petIds.insert(unslottedPet.PetNumber); + } // now need only reset for offline pets (all pets except online case) if (onlinePet) + { petIds.erase(onlinePet->GetCharmInfo()->GetPetNumber()); + } // no offline pets - if (!petIds.empty()) + if (petIds.empty()) + { return; + } bool need_comma = false; std::ostringstream ss; @@ -2137,7 +2155,9 @@ void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* onlinePet /*= nullptr*/) for (uint32 id : petIds) { if (need_comma) + { ss << ','; + } ss << id; @@ -2150,7 +2170,9 @@ void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* onlinePet /*= nullptr*/) for (uint32 spell : sPetTalentSpells) { if (need_comma) + { ss << ','; + } ss << spell; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 5d839108c..0c1c0dfca 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1462,7 +1462,10 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati else { if (getClass() == CLASS_DEATH_KNIGHT && GetMapId() == 609 && !IsGameMaster() && !HasSpell(50977)) + { + SendTransferAborted(mapid, TRANSFER_ABORT_UNIQUE_MESSAGE, 1); return false; + } // far teleport to another map Map* oldmap = IsInWorld() ? GetMap() : nullptr; @@ -6824,8 +6827,10 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt if (extraDPS) { float average = extraDPS * proto->Delay / 1000.0f; - minDamage = 0.7f * average; - maxDamage = 1.3f * average; + float mod = ssv->IsTwoHand(proto->ScalingStatValue) ? 0.2f : 0.3f; + + minDamage = (1.0f - mod) * average; + maxDamage = (1.0f + mod) * average; } } @@ -7220,6 +7225,15 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 continue; } + if (entry && (entry->attributeMask & ENCHANT_PROC_ATTR_EXCLUSIVE) != 0) + { + Unit* checkTarget = spellInfo->IsPositive() ? this : target; + if (checkTarget->HasAura(spellInfo->Id, GetGUID())) + { + continue; + } + } + float chance = pEnchant->amount[s] != 0 ? float(pEnchant->amount[s]) : GetWeaponProcChance(); if (entry) @@ -11579,7 +11593,6 @@ void Player::SendInitialPacketsAfterAddToMap() SendMessageToSet(&data2, true); } - GetAurasForTarget(this); SendEnchantmentDurations(); // must be after add to map SendItemDurations(); // must be after add to map SendQuestGiverStatusMultiple(); @@ -11960,9 +11973,9 @@ void Player::learnSkillRewardedSpells(uint32 skill_id, uint32 skill_value) } } -void Player::GetAurasForTarget(Unit* target) // pussywizard: contact before changing ANYTHING! +void Player::GetAurasForTarget(Unit* target, bool force /*= false*/) { - if (!target/* || target->GetVisibleAuras()->empty()*/) // speedup things + if (!target || (!force && target->GetVisibleAuras()->empty())) // speedup things return; /*! Blizz sends certain movement packets sometimes even before CreateObject diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 3e2c21807..b84a31987 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2183,7 +2183,7 @@ public: void SendBGWeekendWorldStates(); void SendBattlefieldWorldStates(); - void GetAurasForTarget(Unit* target); + void GetAurasForTarget(Unit* target, bool force = false); PlayerMenu* PlayerTalkClass; std::vector ItemSetEff; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 042081b8b..200bec4db 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3822,6 +3822,8 @@ void Unit::_UpdateSpells(uint32 time) { if (i->second->IsExpired()) RemoveOwnedAura(i, AURA_REMOVE_BY_EXPIRE); + else if (i->second->GetSpellInfo()->IsChanneled() && i->second->GetCasterGUID() != GetGUID() && !ObjectAccessor::GetWorldObject(*this, i->second->GetCasterGUID())) + RemoveOwnedAura(i, AURA_REMOVE_BY_CANCEL); // remove channeled auras when caster is not on the same map else ++i; } @@ -6498,11 +6500,12 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType } //victim may be nullptr -bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, Spell const* spellProc /*= nullptr*/) +bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, ProcEventInfo const& eventInfo) { SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo(); uint32 effIndex = triggeredByAura->GetEffIndex(); int32 triggerAmount = triggeredByAura->GetAmount(); + Spell const* spellProc = eventInfo.GetProcSpell(); Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : nullptr; @@ -7864,12 +7867,22 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere if (!procSpell || !procSpell->IsPositive()) return false; - // heal amount - basepoints0 = int32(CalculatePct(std::min(damage, GetMaxHealth() - GetHealth()), triggerAmount)); - target = this; + HealInfo const* healInfo = eventInfo.GetHealInfo(); + if (!healInfo) + { + return false; + } - if (basepoints0) - triggered_spell_id = 31786; + uint32 effectiveHeal = healInfo->GetEffectiveHeal(); + if (effectiveHeal) + { + // heal amount + basepoints0 = int32(CalculatePct(effectiveHeal, triggerAmount)); + target = this; + + if (basepoints0) + triggered_spell_id = 31786; + } break; } // Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal) @@ -11202,16 +11215,18 @@ void Unit::UnsummonAllTotems(bool onDeath /*= false*/) } } -void Unit::SendHealSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical) +void Unit::SendHealSpellLog(HealInfo const& healInfo, bool critical) { + uint32 overheal = healInfo.GetHeal() - healInfo.GetEffectiveHeal(); + // we guess size WorldPacket data(SMSG_SPELLHEALLOG, (8 + 8 + 4 + 4 + 4 + 4 + 1 + 1)); - data << victim->GetPackGUID(); + data << healInfo.GetTarget()->GetPackGUID(); data << GetPackGUID(); - data << uint32(SpellID); - data << uint32(Damage); - data << uint32(OverHeal); - data << uint32(Absorb); // Absorb amount + data << uint32(healInfo.GetSpellInfo()->Id); + data << uint32(healInfo.GetHeal()); + data << uint32(overheal); + data << uint32(healInfo.GetAbsorb()); // Absorb amount data << uint8(critical ? 1 : 0); data << uint8(0); // unused SendMessageToSet(&data, true); @@ -11227,7 +11242,9 @@ int32 Unit::HealBySpell(HealInfo& healInfo, bool critical) CalcHealAbsorb(healInfo); int32 gain = Unit::DealHeal(healInfo.GetHealer(), healInfo.GetTarget(), healInfo.GetHeal()); - SendHealSpellLog(healInfo.GetTarget(), healInfo.GetSpellInfo()->Id, healInfo.GetHeal(), uint32(healInfo.GetHeal() - gain), healInfo.GetAbsorb(), critical); + healInfo.SetEffectiveHeal(gain); + + SendHealSpellLog(healInfo, critical); return gain; } @@ -16555,7 +16572,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u case SPELL_AURA_DUMMY: { LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell id {} (triggered by {} dummy aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); - if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procSpell)) + if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, eventInfo)) takeCharges = true; break; } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index ae8eae814..2081b013f 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -806,6 +806,7 @@ private: Unit* const m_healer; Unit* const m_target; uint32 m_heal; + uint32 m_effectiveHeal; uint32 m_absorb; SpellInfo const* const m_spellInfo; SpellSchoolMask const m_schoolMask; @@ -814,12 +815,17 @@ public: : m_healer(_healer), m_target(_target), m_heal(_heal), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask) { m_absorb = 0; + m_effectiveHeal = 0; } + void AbsorbHeal(uint32 amount) { amount = std::min(amount, GetHeal()); m_absorb += amount; m_heal -= amount; + + amount = std::min(amount, GetEffectiveHeal()); + m_effectiveHeal -= amount; } void SetHeal(uint32 amount) @@ -827,9 +833,15 @@ public: m_heal = amount; } + void SetEffectiveHeal(uint32 amount) + { + m_effectiveHeal = amount; + } + [[nodiscard]] Unit* GetHealer() const { return m_healer; } [[nodiscard]] Unit* GetTarget() const { return m_target; } [[nodiscard]] uint32 GetHeal() const { return m_heal; } + [[nodiscard]] uint32 GetEffectiveHeal() const { return m_effectiveHeal; } [[nodiscard]] uint32 GetAbsorb() const { return m_absorb; } [[nodiscard]] SpellInfo const* GetSpellInfo() const { return m_spellInfo; }; [[nodiscard]] SpellSchoolMask GetSchoolMask() const { return m_schoolMask; }; @@ -1724,7 +1736,7 @@ public: [[nodiscard]] virtual bool IsUnderWater() const; bool isInAccessiblePlaceFor(Creature const* c) const; - void SendHealSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical = false); + void SendHealSpellLog(HealInfo const& healInfo, bool critical = false); int32 HealBySpell(HealInfo& healInfo, bool critical = false); void SendEnergizeSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, Powers powertype); void EnergizeBySpell(Unit* victim, uint32 SpellID, uint32 Damage, Powers powertype); @@ -2551,7 +2563,7 @@ protected: private: bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo); - bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, Spell const* spellProc = nullptr); + bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, ProcEventInfo const& eventInfo); bool HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool* handled); bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, uint32 procPhase, ProcEventInfo& eventInfo); bool HandleOverrideClassScriptAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown); diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h index fe3124aa5..cc4577f29 100644 --- a/src/server/game/Grids/GridDefines.h +++ b/src/server/game/Grids/GridDefines.h @@ -39,7 +39,7 @@ class ObjectGuid; #define CENTER_GRID_OFFSET (SIZE_OF_GRIDS/2) #define MIN_GRID_DELAY (MINUTE*IN_MILLISECONDS) -#define MIN_MAP_UPDATE_DELAY 10 +#define MIN_MAP_UPDATE_DELAY 1 #define SIZE_OF_GRID_CELL (SIZE_OF_GRIDS/MAX_NUMBER_OF_CELLS) diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 7799a36fc..1a50cf97e 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -1201,6 +1201,7 @@ void Guild::HandleRoster(WorldSession* session) { WorldPackets::Guild::GuildRoster roster; + roster.RankData.reserve(m_ranks.size()); for (RankInfo const& rank : m_ranks) { WorldPackets::Guild::GuildRankData& rankData = roster.RankData.emplace_back(); @@ -1215,6 +1216,7 @@ void Guild::HandleRoster(WorldSession* session) } bool sendOfficerNote = HasRankRight(session->GetPlayer(), GR_RIGHT_VIEWOFFNOTE); + roster.MemberData.reserve(m_members.size()); for (auto const& [guid, member] : m_members) { WorldPackets::Guild::GuildRosterMemberData& memberData = roster.MemberData.emplace_back(); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 69bde972a..195257b2a 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -784,14 +784,15 @@ void WorldSession::HandleRaidReadyCheckOpcode(WorldPacket& recvData) void WorldSession::HandleRaidReadyCheckFinishedOpcode(WorldPacket& /*recvData*/) { - //Group* group = GetPlayer()->GetGroup(); - //if (!group) - // return; + Group* group = GetPlayer()->GetGroup(); + if (!group) + return; - //if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) - // return; + if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + return; - // Is any reaction need? + WorldPacket data(MSG_RAID_READY_CHECK_FINISHED); + group->BroadcastPacket(&data, true, -1); } void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacket* data) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 16f673dcd..d1e830349 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2525,6 +2525,7 @@ void Map::SendInitSelf(Player* player) { LOG_DEBUG("maps", "Creating player data for himself {}", player->GetGUID().ToString()); + WorldPacket packet; UpdateData data; // attach to player data current transport data @@ -2534,15 +2535,25 @@ void Map::SendInitSelf(Player* player) // build data for self presence in world at own client (one time for map) player->BuildCreateUpdateBlockForPlayer(&data, player); + // build and send self update packet before sending to player his own auras + data.BuildPacket(&packet); + player->SendDirectMessage(&packet); + + // send to player his own auras (this is needed here for timely initialization of some fields on client) + player->GetAurasForTarget(player, true); + + // clean buffers for further work + packet.clear(); + data.Clear(); + // build other passengers at transport also (they always visible and marked as visible and will not send at visibility update at add to map if (Transport* transport = player->GetTransport()) for (Transport::PassengerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr) if (player != (*itr) && player->HaveAtClient(*itr)) (*itr)->BuildCreateUpdateBlockForPlayer(&data, player); - WorldPacket packet; data.BuildPacket(&packet); - player->GetSession()->SendPacket(&packet); + player->SendDirectMessage(&packet); } void Map::SendInitTransports(Player* player) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 197a17fe8..a9d12efde 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -6626,8 +6626,9 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const HealInfo healInfo(caster, target, heal, GetSpellInfo(), GetSpellInfo()->GetSchoolMask()); Unit::CalcHealAbsorb(healInfo); int32 gain = Unit::DealHeal(caster, target, healInfo.GetHeal()); + healInfo.SetEffectiveHeal(gain); - SpellPeriodicAuraLogInfo pInfo(this, healInfo.GetHeal(), healInfo.GetHeal() - gain, healInfo.GetAbsorb(), 0, 0.0f, crit); + SpellPeriodicAuraLogInfo pInfo(this, healInfo.GetHeal(), healInfo.GetHeal() - healInfo.GetEffectiveHeal(), healInfo.GetAbsorb(), 0, 0.0f, crit); target->SendPeriodicAuraLog(&pInfo); if (caster) diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index fafa9caa2..e782b7640 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -4374,7 +4374,8 @@ void SpellMgr::LoadSpellInfoCorrections() }); // Judgement (Paladin T2 8P Bonus) - ApplySpellFix({ 23591 }, [](SpellInfo* spellInfo) + // Battlegear of Eternal Justice + ApplySpellFix({ 23591, 26135 }, [](SpellInfo* spellInfo) { spellInfo->ProcFlags = PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS; }); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 552659a6c..103d93d40 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2211,8 +2211,8 @@ void SpellMgr::LoadSpellEnchantProcData() mSpellEnchantProcEventMap.clear(); // need for reload case - // 0 1 2 3 - QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx FROM spell_enchant_proc_data"); + // 0 1 2 3 4 + QueryResult result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx, attributeMask FROM spell_enchant_proc_data"); if (!result) { LOG_WARN("server.loading", ">> Loaded 0 spell enchant proc event conditions. DB table `spell_enchant_proc_data` is empty."); @@ -2239,6 +2239,7 @@ void SpellMgr::LoadSpellEnchantProcData() spe.customChance = fields[1].Get(); spe.PPMChance = fields[2].Get(); spe.procEx = fields[3].Get(); + spe.attributeMask = fields[4].Get(); mSpellEnchantProcEventMap[enchantId] = spe; diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 2ee19ecc3..80eae7fc2 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -304,11 +304,17 @@ struct SpellProcEntry typedef std::unordered_map SpellProcMap; +enum EnchantProcAttributes +{ + ENCHANT_PROC_ATTR_EXCLUSIVE = 0x1 // Only one instance of that effect can be active +}; + struct SpellEnchantProcEntry { uint32 customChance; float PPMChance; uint32 procEx; + uint32 attributeMask; }; typedef std::unordered_map SpellEnchantProcEventMap; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 5cf119292..dbbd8b2f7 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -667,7 +667,7 @@ void World::LoadConfigSettings(bool reload) _int_configs[CONFIG_MIN_LEVEL_STAT_SAVE] = 0; } - _int_configs[CONFIG_INTERVAL_MAPUPDATE] = sConfigMgr->GetOption("MapUpdateInterval", 100); + _int_configs[CONFIG_INTERVAL_MAPUPDATE] = sConfigMgr->GetOption("MapUpdateInterval", 10); if (_int_configs[CONFIG_INTERVAL_MAPUPDATE] < MIN_MAP_UPDATE_DELAY) { LOG_ERROR("server.loading", "MapUpdateInterval ({}) must be greater {}. Use this minimal value.", _int_configs[CONFIG_INTERVAL_MAPUPDATE], MIN_MAP_UPDATE_DELAY); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 532d0d087..5fa4becef 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -141,8 +141,6 @@ enum WorldStates WS_DAILY_CALENDAR_DELETION_OLD_EVENTS_TIME = 20008 // Next daily calendar deletions of old events time }; -#define WORLD_SLEEP_CONST 10 - // xinef: petitions storage struct PetitionData { diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp index 6adb4e6fa..cec746870 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp @@ -168,20 +168,19 @@ public: int32 multiplier = 1; switch (aurEff->GetTickNumber()) { - case 2: case 3: + case 4: multiplier = 2; break; - case 4: case 5: - multiplier = 3; - break; case 6: - case 7: multiplier = 4; break; + case 7: + multiplier = 6; + break; case 8: - multiplier = 5; + multiplier = 10; break; } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp index 11be933e8..063b3937c 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp @@ -134,7 +134,12 @@ public: // Not in progress instance->SetData(DATA_ARAN, NOT_STARTED); - instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), true); + + if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR))) + { + libraryDoor->SetGoState(GO_STATE_ACTIVE); + libraryDoor->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); + } } void KilledUnit(Unit* /*victim*/) override @@ -147,7 +152,12 @@ public: Talk(SAY_DEATH); instance->SetData(DATA_ARAN, DONE); - instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), true); + + if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR))) + { + libraryDoor->SetGoState(GO_STATE_ACTIVE); + libraryDoor->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE); + } } void JustEngagedWith(Unit* /*who*/) override @@ -155,7 +165,13 @@ public: Talk(SAY_AGGRO); instance->SetData(DATA_ARAN, IN_PROGRESS); - instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), false); + + if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR))) + { + libraryDoor->SetGoState(GO_STATE_READY); + libraryDoor->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); + } + DoZoneInCombat(); } @@ -203,7 +219,11 @@ public: { if (CloseDoorTimer <= diff) { - instance->HandleGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR), false); + if (GameObject* libraryDoor = instance->instance->GetGameObject(instance->GetGuidData(DATA_GO_LIBRARY_DOOR))) + { + libraryDoor->SetGoState(GO_STATE_READY); + libraryDoor->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE); + } CloseDoorTimer = 0; } else diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index bce65ffa0..a507df8ca 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -163,7 +163,6 @@ Position const RimefangFlyPos = {4413.309f, 2456.421f, 233.3795f, 2.890186f Position const RimefangLandPos = {4413.309f, 2456.421f, 203.3848f, 2.890186f}; Position const SpinestalkerFlyPos = {4418.895f, 2514.233f, 230.4864f, 3.396045f}; Position const SpinestalkerLandPos = {4418.895f, 2514.233f, 203.3848f, 3.396045f}; -Position const SindragosaSpawnPos = {4818.700f, 2483.710f, 287.0650f, 3.089233f}; Position const SindragosaFlyInPos = {4420.190f, 2484.360f, 232.5150f, 3.141593f}; Position const SindragosaLandPos = {4419.190f, 2484.570f, 203.3848f, 3.141593f}; Position const SindragosaAirPos = {4475.990f, 2484.430f, 247.9340f, 3.141593f}; @@ -273,7 +272,7 @@ public: struct boss_sindragosaAI : public BossAI { - boss_sindragosaAI(Creature* creature) : BossAI(creature, DATA_SINDRAGOSA), _summoned(false) + boss_sindragosaAI(Creature* creature) : BossAI(creature, DATA_SINDRAGOSA) { me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_HASTE_SPELLS, true); } @@ -286,16 +285,9 @@ public: _bombCount = 0; _mysticBuffetStack = 0; _Reset(); - me->DisableRotate(false); - me->SetControlled(false, UNIT_STATE_ROOT); me->SetSpeed(MOVE_RUN, me->GetCreatureTemplate()->speed_run); me->SetReactState(REACT_AGGRESSIVE); me->CastSpell(me, SPELL_TANK_MARKER, true); - - if (!_summoned) - { - me->SetDisableGravity(true); - } } void MoveInLineOfSight(Unit* who) override @@ -359,20 +351,9 @@ public: return me->IsVisible() && target->GetEntry() != NPC_CROK_SCOURGEBANE; } - void JustReachedHome() override - { - _JustReachedHome(); - instance->SetBossState(DATA_SINDRAGOSA, FAIL); - if (_summoned) - { - me->SetDisableGravity(false); - } - } - void EnterEvadeMode(EvadeReason why) override { - me->DisableRotate(false); - me->SetControlled(false, UNIT_STATE_ROOT); + instance->SetBossState(DATA_SINDRAGOSA, FAIL); BossAI::EnterEvadeMode(why); } @@ -386,10 +367,6 @@ public: { if (action == ACTION_START_FROSTWYRM) { - if (_summoned) - return; - - _summoned = true; if (TempSummon* summon = me->ToTempSummon()) summon->SetTempSummonType(TEMPSUMMON_DEAD_DESPAWN); @@ -403,7 +380,11 @@ public: float moveTime = me->GetExactDist(&SindragosaFlyInPos) / (me->GetSpeed(MOVE_RUN) * 0.001f); me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, SindragosaLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250)); me->GetMotionMaster()->MovePoint(POINT_FROSTWYRM_FLY_IN, SindragosaFlyInPos); - me->CastSpell(me, SPELL_SINDRAGOSA_S_FURY, true); + + if (!instance->GetData(DATA_SINDRAGOSA_INTRO)) + { + DoCastAOE(SPELL_SINDRAGOSA_S_FURY); + } } } @@ -685,7 +666,6 @@ public: } private: - bool _summoned; uint8 _bombCount; uint8 _mysticBuffetStack; bool _didFirstFlyPhase; @@ -1724,13 +1704,10 @@ public: if (Creature* rimefang = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_RIMEFANG))) rimefang->AI()->DoAction(ACTION_START_FROSTWYRM); - if (!instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) && !instance->GetGuidData(DATA_SINDRAGOSA) && instance->GetBossState(DATA_SINDRAGOSA) != DONE) + if (!instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS)) { - if (instance->GetData(DATA_HAS_LIMITED_ATTEMPTS) && !instance->GetData(DATA_HEROIC_ATTEMPTS)) - return true; - player->GetMap()->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY()); - if (Creature* sindragosa = player->GetMap()->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos)) + if (Creature* sindragosa = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_SINDRAGOSA))) sindragosa->AI()->DoAction(ACTION_START_FROSTWYRM); } } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index a76c44478..7b52e6ee4 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -144,6 +144,7 @@ enum DataTypes DATA_PUTRICIDE_TRAP_STATE = 254, DATA_HAS_LIMITED_ATTEMPTS = 255, DATA_LK_HC_AVAILABLE = 256, + DATA_SINDRAGOSA_INTRO = 257, DATA_BPC_TRASH_DIED = 300, }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index 7337551a2..458847e0a 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -49,7 +49,8 @@ enum TimedEvents EVENT_UPDATE_EXECUTION_TIME = 1, EVENT_QUAKE_SHATTER = 2, EVENT_REBUILD_PLATFORM = 3, - EVENT_RESPAWN_GUNSHIP = 4 + EVENT_RESPAWN_GUNSHIP = 4, + EVENT_RESPAWN_SINDRAGOSA = 5 }; enum Spells @@ -140,6 +141,7 @@ Position const JainaSpawnPos = { -48.65278f, 2211.026f, 27.98586f, 3.124139f Position const MuradinSpawnPos = { -47.34549f, 2208.087f, 27.98586f, 3.106686f }; Position const UtherSpawnPos = { -26.58507f, 2211.524f, 30.19898f, 3.124139f }; Position const SylvanasSpawnPos = { -41.45833f, 2222.891f, 27.98586f, 3.647738f }; +Position const SindragosaSpawnPos = { 4818.6997f, 2483.7102f, 287.06497f, 3.286661f }; // Set position traps Spirit Alarm std::vector GoSpiritAlarm_1 = { { -160.96f, 2210.46f, 35.24f, 0.0f }, { -176.27f, 2201.93f, 35.24f, 0.0f}, { -207.83f, 2207.38f, 35.24f, 0.0f } }; @@ -212,6 +214,7 @@ public: BloodQuickeningState = NOT_STARTED; BloodQuickeningMinutes = 0; BloodPrinceTrashCount = 0; + IsSindragosaIntroDone = false; } void FillInitialWorldStates(WorldPacket& data) override @@ -254,6 +257,11 @@ public: if (GetBossState(DATA_LADY_DEATHWHISPER) == DONE && GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != DONE) SpawnGunship(); + if (GetBossState(DATA_SINDRAGOSA) != DONE && IsSindragosaIntroDone && SindragosaGUID.IsEmpty() && Events.GetTimeUntilEvent(EVENT_RESPAWN_SINDRAGOSA) == Milliseconds::max()) + { + Events.ScheduleEvent(EVENT_RESPAWN_SINDRAGOSA, 30s); + } + if (IsBuffAvailable) { SpellAreaForAreaMapBounds saBounds = sSpellMgr->GetSpellAreaForAreaMapBounds(4812); @@ -937,6 +945,8 @@ public: return BloodQuickeningState; case DATA_HEROIC_ATTEMPTS: return HeroicAttempts; + case DATA_SINDRAGOSA_INTRO: + return (IsSindragosaIntroDone ? 1 : 0); default: break; } @@ -1161,7 +1171,21 @@ public: if (state == DONE) CheckLichKingAvailability(); else if (state == FAIL) + { + IsSindragosaIntroDone = true; HandleDropAttempt(); + if (instance->IsHeroic()) + { + if (HeroicAttempts) + { + Events.ScheduleEvent(EVENT_RESPAWN_SINDRAGOSA, 30s); + } + } + else + { + Events.ScheduleEvent(EVENT_RESPAWN_SINDRAGOSA, 30s); + } + } if (state == DONE && !instance->IsHeroic() && LichKingHeroicAvailable) { LichKingHeroicAvailable = false; @@ -1626,6 +1650,7 @@ public: data >> BloodPrinceTrashCount; data >> IsBuffAvailable; SetData(DATA_BUFF_AVAILABLE, IsBuffAvailable); + data >> IsSindragosaIntroDone; } void WriteSaveDataMore(std::ostringstream& data) override @@ -1638,7 +1663,8 @@ public: << PutricideEventProgress << ' ' << uint32(LichKingHeroicAvailable ? 1 : 0) << ' ' << BloodPrinceTrashCount << ' ' - << uint32(IsBuffAvailable ? 1 : 0); + << uint32(IsBuffAvailable ? 1 : 0) << ' ' + << uint32(IsSindragosaIntroDone ? 1 : 0); } void Update(uint32 diff) override @@ -1679,7 +1705,7 @@ public: else DarkwhisperElevatorTimer -= diff; - if (BloodQuickeningState != IN_PROGRESS && GetBossState(DATA_THE_LICH_KING) != IN_PROGRESS && GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != FAIL) + if (Events.Empty()) return; Events.Update(diff); @@ -1732,6 +1758,21 @@ public: case EVENT_RESPAWN_GUNSHIP: SpawnGunship(); break; + case EVENT_RESPAWN_SINDRAGOSA: + if (Creature* sindragosa = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos)) + { + sindragosa->setActive(true); + sindragosa->SetDisableGravity(true); + sindragosa->GetMotionMaster()->MovePath(NPC_SINDRAGOSA * 10, true); + + if (TempSummon* summon = sindragosa->ToTempSummon()) + { + summon->SetTempSummonType(TEMPSUMMON_DEAD_DESPAWN); + } + } + // Could happen more than once if more than one player enters before she respawns. + Events.CancelEvent(EVENT_RESPAWN_SINDRAGOSA); + break; default: break; } @@ -1944,6 +1985,7 @@ public: bool IsOozeDanceEligible; bool IsNauseaEligible; bool IsOrbWhispererEligible; + bool IsSindragosaIntroDone; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp index e30d3448f..fda7a2fe4 100644 --- a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp @@ -23,7 +23,9 @@ enum vYells { CYANIGOSA_SAY_SPAWN = 3, - SAY_SINCLARI_1 = 0 + SAY_SINCLARI_LEAVING = 0, + SAY_SINCLARI_DOOR_LOCK = 1, + SAY_SINCLARI_COMPLETE = 2, }; class instance_violet_hold : public InstanceMapScript @@ -214,7 +216,7 @@ public: { EncounterStatus = IN_PROGRESS; if (Creature* c = instance->GetCreature(NPC_SinclariGUID)) - c->AI()->Talk(SAY_SINCLARI_1); + c->AI()->Talk(SAY_SINCLARI_LEAVING); events.RescheduleEvent(EVENT_GUARDS_FALL_BACK, 4s); } break; @@ -251,7 +253,12 @@ public: EncounterStatus = DONE; HandleGameObject(GO_MainGateGUID, true); DoUpdateWorldState(WORLD_STATE_VH_SHOW, 0); - if (Creature* c = instance->GetCreature(NPC_SinclariGUID)) { c->DespawnOrUnsummon(); c->SetRespawnTime(3); } + if (Creature* c = instance->GetCreature(NPC_SinclariGUID)) + { + c->AI()->Talk(SAY_SINCLARI_COMPLETE); + c->DespawnOrUnsummon(); + c->SetRespawnTime(3); + } } SaveToDB(); if (WaveCount < 18) @@ -440,8 +447,14 @@ public: break; case EVENT_START_ENCOUNTER: { + if (Creature* c = instance->GetCreature(NPC_SinclariGUID)) + { + c->AI()->Talk(SAY_SINCLARI_DOOR_LOCK); + } if (Creature* c = instance->GetCreature(NPC_DoorSealGUID)) + { c->RemoveAllAuras(); // just to be sure... + } GateHealth = 100; HandleGameObject(GO_MainGateGUID, false); DoUpdateWorldState(WORLD_STATE_VH_SHOW, 1); diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp index 582cd5192..14c20d02f 100644 --- a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp @@ -24,6 +24,21 @@ #include "ScriptedGossip.h" #include "SpellScript.h" +/// @todo: Missing Sinclari Trigger announcements (32204) Look at its creature_text for more info. +/// @todo: Activation Crystals (go_vh_activation_crystal) (193611) are spammable, should be a 1 time use per crystal. + +enum Texts +{ + GOSSIP_MENU_START_EVENT = 9998, + GOSSIP_MENU_ITEM = 9997, + GOSSIP_MENU_LATE_JOIN = 10275, + + NPC_TEXT_SINCLARI_IN = 13853, + NPC_TEXT_SINCLARI_ITEM = 13854, + NPC_TEXT_SINCLARI_DONE = 13910, + NPC_TEXT_SINCLARI_LATE_JOIN = 14271, +}; + /*********** ** DEFENSE SYSTEM CRYSTAL ***********/ @@ -45,10 +60,6 @@ public: ** SINCLARI ***********/ -#define GOSSIP_START_EVENT "Get your people to safety, we'll keep the Blue Dragonflight's forces at bay." -#define GOSSIP_ITEM_1 "Activate the crystals when we get in trouble, right." -#define GOSSIP_I_WANT_IN "Sorry, I'm late! Can I get in to help my friends?" - class npc_vh_sinclari : public CreatureScript { public: @@ -60,16 +71,16 @@ public: switch (pInstance->GetData(DATA_ENCOUNTER_STATUS)) { case NOT_STARTED: - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_START_EVENT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - SendGossipMenuFor(player, 13853, creature->GetGUID()); + AddGossipItemFor(player, GOSSIP_MENU_ITEM, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + AddGossipItemFor(player, GOSSIP_MENU_START_EVENT, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + SendGossipMenuFor(player, NPC_TEXT_SINCLARI_IN, creature->GetGUID()); break; case IN_PROGRESS: - AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_I_WANT_IN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - SendGossipMenuFor(player, 13853, creature->GetGUID()); + AddGossipItemFor(player, GOSSIP_MENU_LATE_JOIN, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + SendGossipMenuFor(player, NPC_TEXT_SINCLARI_LATE_JOIN, creature->GetGUID()); break; default: // DONE or invalid - SendGossipMenuFor(player, 13910, creature->GetGUID()); + SendGossipMenuFor(player, NPC_TEXT_SINCLARI_DONE, creature->GetGUID()); } return true; } @@ -86,7 +97,7 @@ public: pInstance->SetData(DATA_START_INSTANCE, 1); break; case GOSSIP_ACTION_INFO_DEF+2: - SendGossipMenuFor(player, 13854, creature->GetGUID()); + SendGossipMenuFor(player, NPC_TEXT_SINCLARI_ITEM, creature->GetGUID()); break; case GOSSIP_ACTION_INFO_DEF+3: player->NearTeleportTo(playerTeleportPosition.GetPositionX(), playerTeleportPosition.GetPositionY(), playerTeleportPosition.GetPositionZ(), playerTeleportPosition.GetOrientation(), true); diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp index 521854100..f09f4262a 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp @@ -43,7 +43,7 @@ enum Spells struct boss_talon_king_ikiss : public BossAI { - boss_talon_king_ikiss(Creature* creature) : BossAI(creature, DATA_IKISS), _spoken(false), _manaShield(false) + boss_talon_king_ikiss(Creature* creature) : BossAI(creature, DATA_IKISS), _spoken(false) { scheduler.SetValidator([this] { @@ -55,8 +55,44 @@ struct boss_talon_king_ikiss : public BossAI { _Reset(); _spoken = false; - _manaShield = false; - _comboHealthStages.fill(false); + + ScheduleHealthCheckEvent(80, [&] { + TeleportAndCastExplosion(); + }); + + ScheduleHealthCheckEvent(50, [&] { + TeleportAndCastExplosion(); + }); + + ScheduleHealthCheckEvent(25, [&] { + TeleportAndCastExplosion(); + }); + + ScheduleHealthCheckEvent(20, [&] { + DoCast(me, SPELL_MANA_SHIELD); + }); + } + + /// @todo: remove this once pets stop going through doors. + bool CanAIAttack(Unit const* /*victim*/) const override + { + return _spoken; + } + + void TeleportAndCastExplosion() + { + me->InterruptNonMeleeSpells(false); + DoCastSelf(SPELL_ARCANE_BUBBLE, true); + DoCastAOE(SPELL_BLINK); + Talk(EMOTE_ARCANE_EXP); + + scheduler.Schedule(1s, [this](TaskContext) + { + DoCastAOE(SPELL_ARCANE_EXPLOSION); + }).Schedule(6500ms, [this](TaskContext /*context*/) + { + me->GetThreatMgr().ResetAllThreat(); + }); } void MoveInLineOfSight(Unit* who) override @@ -106,69 +142,6 @@ struct boss_talon_king_ikiss : public BossAI } } - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override - { - if (!_comboHealthStages[0] && me->HealthBelowPctDamaged(80, damage)) - { - _comboHealthStages[0] = true; - - me->InterruptNonMeleeSpells(false); - DoCastSelf(SPELL_ARCANE_BUBBLE, true); - DoCastAOE(SPELL_BLINK); - Talk(EMOTE_ARCANE_EXP); - - scheduler.Schedule(1s, [this](TaskContext) - { - DoCastAOE(SPELL_ARCANE_EXPLOSION); - }).Schedule(6500ms, [this](TaskContext /*context*/) - { - me->GetThreatMgr().ResetAllThreat(); - }); - } - - if (!_comboHealthStages[1] && me->HealthBelowPctDamaged(50, damage)) - { - _comboHealthStages[1] = true; - - me->InterruptNonMeleeSpells(false); - DoCastSelf(SPELL_ARCANE_BUBBLE, true); - DoCastAOE(SPELL_BLINK); - Talk(EMOTE_ARCANE_EXP); - - scheduler.Schedule(1s, [this](TaskContext) - { - DoCastAOE(SPELL_ARCANE_EXPLOSION); - }).Schedule(6500ms, [this](TaskContext /*context*/) - { - me->GetThreatMgr().ResetAllThreat(); - }); - } - - if (!_comboHealthStages[2] && me->HealthBelowPctDamaged(25, damage)) - { - _comboHealthStages[2] = true; - - me->InterruptNonMeleeSpells(false); - DoCastSelf(SPELL_ARCANE_BUBBLE, true); - DoCastAOE(SPELL_BLINK); - Talk(EMOTE_ARCANE_EXP); - - scheduler.Schedule(1s, [this](TaskContext) - { - DoCastAOE(SPELL_ARCANE_EXPLOSION); - }).Schedule(6500ms, [this](TaskContext /*context*/) - { - me->GetThreatMgr().ResetAllThreat(); - }); - } - - if (!_manaShield && me->HealthBelowPctDamaged(20, damage)) - { - DoCast(me, SPELL_MANA_SHIELD); - _manaShield = true; - } - } - void KilledUnit(Unit* /*victim*/) override { if (urand(0, 1)) @@ -177,8 +150,6 @@ struct boss_talon_king_ikiss : public BossAI private: bool _spoken; - bool _manaShield; - std::array _comboHealthStages; }; // 38194 - Blink diff --git a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp index 209aaae4b..0dabf465e 100644 --- a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp +++ b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp @@ -37,6 +37,8 @@ enum Spells SPELL_ARCANE_TORRENT = 36022, SPELL_MANA_TAP = 36021, SPELL_DOMINATION = 35280, + SPELL_FRENZY = 36992, + SPELL_SUICIDE = 35301, SPELL_ETHEREAL_TELEPORT = 34427, SPELL_GREATER_INVISIBILITY = 34426, SPELL_SUMMON_NETHER_WRAITH_1 = 35285, @@ -48,6 +50,8 @@ enum Spells enum Misc { ACTION_BRIDGE_MOB_DEATH = 1, // Used by SAI + EQUIPMENT_NORMAL = 1, + EQUIPMENT_FRENZY = 2, }; struct boss_pathaleon_the_calculator : public BossAI @@ -60,9 +64,13 @@ struct boss_pathaleon_the_calculator : public BossAI }); } + bool _isEnraged; + void Reset() override { _Reset(); + _isEnraged = false; + me->LoadEquipment(EQUIPMENT_NORMAL); if (instance->GetPersistentData(DATA_BRIDGE_MOB_DEATH_COUNT) < 4) { @@ -81,18 +89,23 @@ struct boss_pathaleon_the_calculator : public BossAI ScheduleHealthCheckEvent(20, [&]() { - summons.DespawnAll(); - DoCastSelf(SPELL_DISGRUNTLED_ANGER, true); + DoCastSelf(SPELL_SUICIDE, true); + DoCastSelf(SPELL_FRENZY, true); Talk(SAY_ENRAGE); + _isEnraged = true; + me->LoadEquipment(EQUIPMENT_FRENZY); }); - scheduler.Schedule(30s, [this](TaskContext context) + scheduler.Schedule(20s, 25s, [this](TaskContext context) { - for (uint8 i = 0; i < DUNGEON_MODE(3, 4); ++i) - me->CastSpell(me, SPELL_SUMMON_NETHER_WRAITH_1 + i, true); + if (!_isEnraged) + { + for (uint8 i = 0; i < DUNGEON_MODE(3, 4); ++i) + me->CastSpell(me, SPELL_SUMMON_NETHER_WRAITH_1 + i, true); - Talk(SAY_SUMMON); - context.Repeat(30s, 40s); + Talk(SAY_SUMMON); + } + context.Repeat(45s, 50s); }).Schedule(12s, [this](TaskContext context) { if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, POWER_MANA, 40.0f, false))) @@ -106,13 +119,17 @@ struct boss_pathaleon_the_calculator : public BossAI me->ModifyPower(POWER_MANA, 5000); DoCastSelf(SPELL_ARCANE_TORRENT); context.Repeat(15s); - }).Schedule(25s, [this](TaskContext context) + }).Schedule(10s, 15s, [this](TaskContext context) { if (DoCastRandomTarget(SPELL_DOMINATION, 1, 50.0f) == SPELL_CAST_OK) { Talk(SAY_DOMINATION); } - context.Repeat(30s); + context.Repeat(27s, 40s); + }).Schedule(25s, [this](TaskContext context) + { + DoCast(SPELL_DISGRUNTLED_ANGER); + context.Repeat(40s, 90s); }); if (IsHeroic()) diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp index 0362a6097..38d3de610 100644 --- a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp +++ b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp @@ -349,7 +349,10 @@ public: instance->SetBossState(DATA_WARDEN_MELLICHAR, DONE); if (Creature* creature = summons.GetCreatureWithEntry(NPC_MILLHOUSE)) { - instance->DoCastSpellOnPlayers(SPELL_QID10886); + if (IsHeroic()) + { + instance->DoCastSpellOnPlayers(SPELL_QID10886); + } creature->AI()->Talk(SAY_COMPLETE); creature->ReplaceAllNpcFlags(UNIT_NPC_FLAG_GOSSIP); } diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp index 9489da3ad..74daf78ad 100644 --- a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp +++ b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_dalliah_the_doomsayer.cpp @@ -91,15 +91,15 @@ struct boss_dalliah_the_doomsayer : public BossAI } } - scheduler.Schedule(1s, 4s, [this](TaskContext context) + scheduler.Schedule(8s, 12s, [this](TaskContext context) { DoCastVictim(SPELL_GIFT_OF_THE_DOOMSAYER); - context.Repeat(16s, 21s); - }).Schedule(7s, 9s, [this](TaskContext context) + context.Repeat(17s, 35s); + }).Schedule(20s, 30s, [this](TaskContext context) { Talk(SAY_WHIRLWIND); DoCastAOE(SPELL_WHIRLWIND); - context.Repeat(19s, 21s); + context.Repeat(); scheduler.Schedule(7s, [this](TaskContext) { @@ -110,10 +110,10 @@ struct boss_dalliah_the_doomsayer : public BossAI if (IsHeroic()) { - scheduler.Schedule(11s, 16s, [this](TaskContext context) + scheduler.Schedule(11s, 30s, [this](TaskContext context) { DoCastVictim(SPELL_SHADOW_WAVE); - context.Repeat(11s, 16s); + context.Repeat(); }); } } diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp index f4dcebefe..11317d5cf 100644 --- a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp +++ b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_wrath_scryer_soccothrates.cpp @@ -128,9 +128,10 @@ struct boss_wrath_scryer_soccothrates : public BossAI scheduler.Schedule(30s, 35s, [this](TaskContext context) { + scheduler.DelayAll(5s); me->CastSpell(me, SPELL_KNOCK_AWAY, false); - me->HandleEmoteCommand(EMOTE_ONESHOT_POINT); Talk(SAY_KNOCK_AWAY); + me->HandleEmoteCommand(EMOTE_ONESHOT_POINT); scheduler.Schedule(4600ms, [this](TaskContext) { @@ -149,7 +150,7 @@ struct boss_wrath_scryer_soccothrates : public BossAI }); context.Repeat(20s, 35s); - }).Schedule(12s, 14s, [this](TaskContext context) + }).Schedule(8500ms, 22s, [this](TaskContext context) { DoCastVictim(SPELL_FELFIRE_SHOCK); context.Repeat(); diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_zereketh_the_unbound.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_zereketh_the_unbound.cpp index 160a641ef..bfccdd779 100644 --- a/src/server/scripts/Outland/TempestKeep/arcatraz/boss_zereketh_the_unbound.cpp +++ b/src/server/scripts/Outland/TempestKeep/arcatraz/boss_zereketh_the_unbound.cpp @@ -56,22 +56,22 @@ struct boss_zereketh_the_unbound : public BossAI _JustEngagedWith(); Talk(SAY_AGGRO); - scheduler.Schedule(6s, [this](TaskContext context) + scheduler.Schedule(11s, 29s, [this](TaskContext context) { DoCastRandomTarget(SPELL_VOID_ZONE, 0, 60.0f); - context.Repeat(15s); - }).Schedule(10s, [this](TaskContext context) + context.Repeat(); + }).Schedule(12s, 22s, [this](TaskContext context) { DoCastAOE(SPELL_SHADOW_NOVA); if (roll_chance_i(50)) { Talk(SAY_SHADOW_NOVA); } - context.Repeat(12s); - }).Schedule(16s, [this](TaskContext context) + context.Repeat(); + }).Schedule(6s, 12s, [this](TaskContext context) { DoCastRandomTarget(SPELL_SEED_OF_CORRUPTION, 0, 30.0f); - context.Repeat(16s); + context.Repeat(13s, 27s); }); } diff --git a/src/server/shared/DataStores/DBCStructure.h b/src/server/shared/DataStores/DBCStructure.h index 525a0293a..53ffbed74 100644 --- a/src/server/shared/DataStores/DBCStructure.h +++ b/src/server/shared/DataStores/DBCStructure.h @@ -1554,6 +1554,16 @@ struct ScalingStatValuesEntry return 0; } + bool IsTwoHand(uint32 mask) const + { + if (mask & 0x7E00) + { + if (mask & 0x00000400) return true; + if (mask & 0x00001000) return true; + } + return false; + } + [[nodiscard]] uint32 getSpellBonus(uint32 mask) const { if (mask & 0x00008000) return spellPower; diff --git a/src/server/shared/Network/NetworkThread.h b/src/server/shared/Network/NetworkThread.h index abe0c0e27..aec20a16a 100644 --- a/src/server/shared/Network/NetworkThread.h +++ b/src/server/shared/Network/NetworkThread.h @@ -121,8 +121,8 @@ protected: { LOG_DEBUG("misc", "Network Thread Starting"); - _updateTimer.expires_from_now(boost::posix_time::milliseconds(10)); - _updateTimer.async_wait(std::bind(&NetworkThread::Update, this)); + _updateTimer.expires_from_now(boost::posix_time::milliseconds(1)); + _updateTimer.async_wait([this](boost::system::error_code const&) { Update(); }); _ioContext.run(); LOG_DEBUG("misc", "Network Thread exits"); @@ -135,8 +135,8 @@ protected: if (_stopped) return; - _updateTimer.expires_from_now(boost::posix_time::milliseconds(10)); - _updateTimer.async_wait(std::bind(&NetworkThread::Update, this)); + _updateTimer.expires_from_now(boost::posix_time::milliseconds(1)); + _updateTimer.async_wait([this](boost::system::error_code const&) { Update(); }); AddNewSockets();