From 2c1f64014ee40b56bdfcca2aa68d6271b6892523 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Mon, 22 May 2017 21:50:17 +0200 Subject: [PATCH 01/44] DB/Misc: Some fixes for human starting area By Malcrom --- .../world/4.3.4/2017_05_22_00_world.sql | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 sql/updates/world/4.3.4/2017_05_22_00_world.sql diff --git a/sql/updates/world/4.3.4/2017_05_22_00_world.sql b/sql/updates/world/4.3.4/2017_05_22_00_world.sql new file mode 100644 index 0000000000..895a91cf85 --- /dev/null +++ b/sql/updates/world/4.3.4/2017_05_22_00_world.sql @@ -0,0 +1,128 @@ +-- Fixup Blackrock Worg +UPDATE `creature_template` SET `flags_extra`=2 WHERE `entry`=49871; + +-- Fix up Blackrock Spy Entry: 49874 +UPDATE `creature` SET `spawndist`=0,`MovementType`=0 WHERE `id`=49874; +UPDATE `creature_template_addon` SET `auras`='80676' WHERE `entry`=49874; +DELETE FROM `smart_scripts` WHERE `entryorguid`=49874 AND `id` IN (1,2); + +-- Pathing for Blackrock Spy Entry: 49874 'TDB FORMAT' +SET @NPC := 279993; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-9017.051,`position_y`=-186.1771,`position_z`=76.99114 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '92857'); +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,-9017.051,-186.1771,76.99114,0,0,0,0,100,0), +(@PATH,2,-9022.958,-180.9201,76.68597,0,0,0,0,100,0), +(@PATH,3,-9025.415,-177.9479,76.53362,0,0,0,0,100,0), +(@PATH,4,-9026.482,-173.7778,77.33782,0,0,0,0,100,0), +(@PATH,5,-9024.309,-167.1191,78.75359,0,0,0,0,100,0), +(@PATH,6,-9026.482,-173.7773,77.37859,0,0,0,0,100,0), +(@PATH,7,-9025.415,-177.9479,76.53362,0,0,0,0,100,0), +(@PATH,8,-9022.958,-180.9201,76.68597,0,0,0,0,100,0); + +-- Pathing for Blackrock Spy Entry: 49874 'TDB FORMAT' +SET @NPC := 279970; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-8975.587,`position_y`=-210.8681,`position_z`=74.38621 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '92857'); +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,-8975.587,-210.8681,74.38621,0,0,0,0,100,0), +(@PATH,2,-8982.348,-208.6354,73.94993,0,0,0,0,100,0), +(@PATH,3,-8982.997,-201.5851,74.64426,0,0,0,0,100,0), +(@PATH,4,-8982.348,-208.6354,73.94993,0,0,0,0,100,0); + +-- Pathing for Blackrock Spy Entry: 49874 'TDB FORMAT' +SET @NPC := 279996; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-8959.651,`position_y`=-62.3316,`position_z`=92.46779 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '92857'); +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,-8959.651,-62.3316,92.46779,0,0,0,0,100,0), +(@PATH,2,-8962.094,-58.05729,92.43849,0,0,0,0,100,0), +(@PATH,3,-8966.278,-58.07465,92.18849,0,0,0,0,100,0), +(@PATH,4,-8966.953,-59.75868,91.97262,0,0,0,0,100,0), +(@PATH,5,-8962.488,-59.94618,92.25246,0,0,0,0,100,0), +(@PATH,6,-8966.278,-58.07465,92.18849,0,0,0,0,100,0), +(@PATH,7,-8962.094,-58.05729,92.43849,0,0,0,0,100,0), +(@PATH,8,-8958.906,-60.77083,92.43849,0,0,0,0,100,0); + +-- Pathing for Blackrock Spy Entry: 49874 'TDB FORMAT' +SET @NPC := 279821; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-8937.439,`position_y`=-246.7691,`position_z`=79.06224 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '92857'); +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,-8937.439,-246.7691,79.06224,0,0,0,0,100,0), +(@PATH,2,-8930.792,-241.4774,79.49934,0,0,0,0,100,0), +(@PATH,3,-8933.103,-246.651,78.92879,0,0,0,0,100,0); + +-- Pathing for Blackrock Spy Entry: 49874 'TDB FORMAT' +SET @NPC := 279952; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-8906.613,`position_y`=-39.17014,`position_z`=89.14458 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '92857'); +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,-8906.613,-39.17014,89.14458,0,0,0,0,100,0), +(@PATH,2,-8900.656,-43.30903,86.97442,0,0,0,0,100,0), +(@PATH,3,-8906.398,-39.31641,89.20806,0,0,0,0,100,0), +(@PATH,4,-8911.556,-40.54688,89.57232,0,0,0,0,100,0); + +-- Pathing for Blackrock Spy Entry: 49874 'TDB FORMAT' +SET @NPC := 279950; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-8926.372,`position_y`=-68.80903,`position_z`=89.75582 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '92857'); +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,-8926.372,-68.80903,89.75582,0,0,0,0,100,0), +(@PATH,2,-8929.808,-68.91666,89.97311,0,0,0,0,100,0), +(@PATH,3,-8922.819,-71.70834,89.15719,0,0,0,0,100,0); + +-- Pathing for Blackrock Spy Entry: 49874 'TDB FORMAT' +SET @NPC := 279936; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-8878.366,`position_y`=-92.23785,`position_z`=83.897 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '92857'); +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,-8878.366,-92.23785,83.897,0,0,0,0,100,0), +(@PATH,2,-8873.397,-91.30903,83.17702,0,0,0,0,100,0), +(@PATH,3,-8870.214,-93.74132,82.54983,0,0,0,0,100,0); + +-- Pathing for Blackrock Spy Entry: 49874 'TDB FORMAT' +SET @NPC := 279918; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-8832.973,`position_y`=-120.3351,`position_z`=80.8506 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '92857'); +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,-8832.973,-120.3351,80.8506,0,0,0,0,100,0), +(@PATH,2,-8831.473,-124.0399,80.79787,0,0,0,0,100,0), +(@PATH,3,-8837.326,-118.8611,80.59762,0,0,0,0,100,0); + +-- Pathing for Blackrock Spy Entry: 49874 'TDB FORMAT' +SET @NPC := 279756; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-8784.361,`position_y`=-78.68403,`position_z`=89.64127 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, '92857'); +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,-8784.361,-78.68403,89.64127,0,0,0,0,100,0), +(@PATH,2,-8776.549,-79.15799,89.33903,0,0,0,0,100,0), +(@PATH,3,-8772.433,-83.78646,88.66227,0,0,0,0,100,0), +(@PATH,4,-8776.549,-79.15799,89.33903,0,0,0,0,100,0); From 9c42ad63a827492e0b403f12dc00633e026a048b Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 12:03:55 +0200 Subject: [PATCH 02/44] DB/Misc: Fix up quest human start area By Malcrom --- .../world/4.3.4/2017_05_23_00_world.sql | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 sql/updates/world/4.3.4/2017_05_23_00_world.sql diff --git a/sql/updates/world/4.3.4/2017_05_23_00_world.sql b/sql/updates/world/4.3.4/2017_05_23_00_world.sql new file mode 100644 index 0000000000..27849544a1 --- /dev/null +++ b/sql/updates/world/4.3.4/2017_05_23_00_world.sql @@ -0,0 +1,141 @@ +DELETE FROM `quest_request_items` WHERE `ID` IN (28757,28762,28763,28764,28765,28766,28767,29078,28759,28769,28770,28771,28772,28773,28774,29079,28791,28792,28793,28794,28795,28796,28797,29081,28806,28808,28809,28810,28811,28812,28813,29082); +INSERT INTO `quest_request_items` (`ID`,`EmoteOnComplete`,`EmoteOnIncomplete`,`EmoteOnCompleteDelay`,`EmoteOnIncompleteDelay`,`CompletionText`,`VerifiedBuild`) VALUES +(28757,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), +(28762,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), +(28763,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), +(28764,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), +(28765,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), +(28766,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), +(28767,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), +(29078,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), +(28759,5,0,0,0, 'Kill the spies!',0), +(28769,5,0,0,0, 'Kill the spies!',0), +(28770,5,0,0,0, 'Kill the spies!',0), +(28771,5,0,0,0, 'Kill the spies!',0), +(28772,5,0,0,0, 'Kill the spies!',0), +(28773,5,0,0,0, 'Kill the spies!',0), +(28774,5,0,0,0, 'Kill the spies!',0), +(29079,5,0,0,0, 'Kill the spies!',0), +(28791,0,0,0,0, 'Kill the goblin assassins',0), +(28792,0,0,0,0, 'Kill the goblin assassins',0), +(28793,0,0,0,0, 'Kill the goblin assassins',0), +(28794,0,0,0,0, 'Kill the goblin assassins',0), +(28795,0,0,0,0, 'Kill the goblin assassins',0), +(28796,0,0,0,0, 'Kill the goblin assassins',0), +(28797,0,0,0,0, 'Kill the goblin assassins',0), +(29081,0,0,0,0, 'Kill the goblin assassins',0), +(28806,5,0,0,0, 'Rescue our Soldiers!',0), +(28808,5,0,0,0, 'Rescue our Soldiers!',0), +(28809,5,0,0,0, 'Rescue our Soldiers!',0), +(28810,5,0,0,0, 'Rescue our Soldiers!',0), +(28811,5,0,0,0, 'Rescue our Soldiers!',0), +(28812,5,0,0,0, 'Rescue our Soldiers!',0), +(28813,5,0,0,0, 'Rescue our Soldiers!',0), +(29082,5,0,0,0, 'Rescue our Soldiers!',0); + +DELETE FROM `quest_offer_reward` WHERE `ID` IN (28757,28762,28763,28764,28765,28766,28767,29078,28759,28769,28770,28771,28772,28773,28774,29079,28780,28784,28785,28786,28787,28788,28789,29080,28806,28808,28809,28810,28811,28812,28813,29082,28791,28792,28793,28794,28795,28796,28797,29081,28817,28818,28819,28820,28821,28822,28823,29083); +INSERT INTO `quest_offer_reward` (`ID`,`Emote1`,`Emote2`,`Emote3`,`Emote4`,`EmoteDelay1`,`EmoteDelay2`,`EmoteDelay3`,`EmoteDelay4`,`RewardText`,`VerifiedBuild`) VALUES +(28757,1,1,0,0,0,0,0,0, 'You''ve bought us a little time, $n, but we''ve got even bigger problems to deal with now.',0), +(28762,1,1,0,0,0,0,0,0, 'You''ve bought us a little time, $n, but we''ve got even bigger problems to deal with now.',0), +(28763,1,1,0,0,0,0,0,0, 'You''ve bought us a little time, $n, but we''ve got even bigger problems to deal with now.',0), +(28764,1,1,0,0,0,0,0,0, 'You''ve bought us a little time, $n, but we''ve got even bigger problems to deal with now.',0), +(28765,1,1,0,0,0,0,0,0, 'You''ve bought us a little time, $n, but we''ve got even bigger problems to deal with now.',0), +(28766,1,1,0,0,0,0,0,0, 'You''ve bought us a little time, $n, but we''ve got even bigger problems to deal with now.',0), +(28767,1,1,0,0,0,0,0,0, 'You''ve bought us a little time, $n, but we''ve got even bigger problems to deal with now.',0), +(29078,1,1,0,0,0,0,0,0, 'You''ve bought us a little time, $n, but we''ve got even bigger problems to deal with now.',0), +(28759,21,1,5,0,0,0,0,0, 'Excellent work, $n. You''ve turned out to be quite an asset to this garrison. It''s time for you to train!',0), +(28769,21,1,5,0,0,0,0,0, 'Excellent work, $n. You''ve turned out to be quite an asset to this garrison. It''s time for you to train!',0), +(28770,21,1,5,0,0,0,0,0, 'Excellent work, $n. You''ve turned out to be quite an asset to this garrison. It''s time for you to train!',0), +(28771,21,1,5,0,0,0,0,0, 'Excellent work, $n. You''ve turned out to be quite an asset to this garrison. It''s time for you to train!',0), +(28772,21,1,5,0,0,0,0,0, 'Excellent work, $n. You''ve turned out to be quite an asset to this garrison. It''s time for you to train!',0), +(28773,21,1,5,0,0,0,0,0, 'Excellent work, $n. You''ve turned out to be quite an asset to this garrison. It''s time for you to train!',0), +(28774,21,1,5,0,0,0,0,0, 'Excellent work, $n. You''ve turned out to be quite an asset to this garrison. It''s time for you to train!',0), +(29079,21,1,5,0,0,0,0,0, 'Excellent work, $n. You''ve turned out to be quite an asset to this garrison. It''s time for you to train!',0), +(28780,0,0,0,0,0,0,0,0, 'It''s true, we were ambushed. I don''t dare send any more soldiers out there and risk losing them too. I need a volunteer. Someone willing to risk their life!',0), +(28784,0,0,0,0,0,0,0,0, 'It''s true, we were ambushed. I don''t dare send any more soldiers out there and risk losing them too. I need a volunteer. Someone willing to risk their life!',0), +(28785,0,0,0,0,0,0,0,0, 'It''s true, we were ambushed. I don''t dare send any more soldiers out there and risk losing them too. I need a volunteer. Someone willing to risk their life!',0), +(28786,0,0,0,0,0,0,0,0, 'It''s true, we were ambushed. I don''t dare send any more soldiers out there and risk losing them too. I need a volunteer. Someone willing to risk their life!',0), +(28787,0,0,0,0,0,0,0,0, 'It''s true, we were ambushed. I don''t dare send any more soldiers out there and risk losing them too. I need a volunteer. Someone willing to risk their life!',0), +(28788,0,0,0,0,0,0,0,0, 'It''s true, we were ambushed. I don''t dare send any more soldiers out there and risk losing them too. I need a volunteer. Someone willing to risk their life!',0), +(28789,0,0,0,0,0,0,0,0, 'It''s true, we were ambushed. I don''t dare send any more soldiers out there and risk losing them too. I need a volunteer. Someone willing to risk their life!',0), +(29080,0,0,0,0,0,0,0,0, 'It''s true, we were ambushed. I don''t dare send any more soldiers out there and risk losing them too. I need a volunteer. Someone willing to risk their life!',0), +(28806,273,4,0,0,0,0,0,0, 'I think you now understand the power of the Light. The Light giveth hope, $g brother:sister; and the Light taketh from the darkness! BLESSED BE THE LIGHT!',0), +(28808,273,4,0,0,0,0,0,0, 'I think you now understand the power of the Light. The Light giveth hope, $g brother:sister; and the Light taketh from the darkness! BLESSED BE THE LIGHT!',0), +(28809,273,4,0,0,0,0,0,0, 'I think you now understand the power of the Light. The Light giveth hope, $g brother:sister; and the Light taketh from the darkness! BLESSED BE THE LIGHT!',0), +(28810,273,4,0,0,0,0,0,0, 'I think you now understand the power of the Light. The Light giveth hope, $g brother:sister; and the Light taketh from the darkness! BLESSED BE THE LIGHT!',0), +(28811,273,4,0,0,0,0,0,0, 'I think you now understand the power of the Light. The Light giveth hope, $g brother:sister; and the Light taketh from the darkness! BLESSED BE THE LIGHT!',0), +(28812,273,4,0,0,0,0,0,0, 'I think you now understand the power of the Light. The Light giveth hope, $g brother:sister; and the Light taketh from the darkness! BLESSED BE THE LIGHT!',0), +(28813,273,4,0,0,0,0,0,0, 'I think you now understand the power of the Light. The Light giveth hope, $g brother:sister; and the Light taketh from the darkness! BLESSED BE THE LIGHT!',0), +(29082,273,4,0,0,0,0,0,0, 'I think you now understand the power of the Light. The Light giveth hope, $g brother:sister; and the Light taketh from the darkness! BLESSED BE THE LIGHT!',0), +(28791,0,0,0,0,0,0,0,0, 'That will teach those monsters! They''ll think twice before taking another mercenary job for orcs.',0), +(28792,0,0,0,0,0,0,0,0, 'That will teach those monsters! They''ll think twice before taking another mercenary job for orcs.',0), +(28793,0,0,0,0,0,0,0,0, 'That will teach those monsters! They''ll think twice before taking another mercenary job for orcs.',0), +(28794,0,0,0,0,0,0,0,0, 'That will teach those monsters! They''ll think twice before taking another mercenary job for orcs.',0), +(28795,0,0,0,0,0,0,0,0, 'That will teach those monsters! They''ll think twice before taking another mercenary job for orcs.',0), +(28796,0,0,0,0,0,0,0,0, 'That will teach those monsters! They''ll think twice before taking another mercenary job for orcs.',0), +(28797,0,0,0,0,0,0,0,0, 'That will teach those monsters! They''ll think twice before taking another mercenary job for orcs.',0), +(29081,0,0,0,0,0,0,0,0, 'That will teach those monsters! They''ll think twice before taking another mercenary job for orcs.',0), +(28817,1,1,1,5,0,0,0,0, 'With your help we have managed to secure the northern and western sectors of Northshire. We still have a rather large contingency of Blackrock orcs to the east and they''ve begun burning down the forest!',0), +(28818,1,1,1,5,0,0,0,0, 'With your help we have managed to secure the northern and western sectors of Northshire. We still have a rather large contingency of Blackrock orcs to the east and they''ve begun burning down the forest!',0), +(28819,1,1,1,5,0,0,0,0, 'With your help we have managed to secure the northern and western sectors of Northshire. We still have a rather large contingency of Blackrock orcs to the east and they''ve begun burning down the forest!',0), +(28820,1,1,1,5,0,0,0,0, 'With your help we have managed to secure the northern and western sectors of Northshire. We still have a rather large contingency of Blackrock orcs to the east and they''ve begun burning down the forest!',0), +(28821,1,1,1,5,0,0,0,0, 'With your help we have managed to secure the northern and western sectors of Northshire. We still have a rather large contingency of Blackrock orcs to the east and they''ve begun burning down the forest!',0), +(28822,1,1,1,5,0,0,0,0, 'With your help we have managed to secure the northern and western sectors of Northshire. We still have a rather large contingency of Blackrock orcs to the east and they''ve begun burning down the forest!',0), +(28823,1,1,1,5,0,0,0,0, 'With your help we have managed to secure the northern and western sectors of Northshire. We still have a rather large contingency of Blackrock orcs to the east and they''ve begun burning down the forest!',0), +(29083,1,1,1,5,0,0,0,0, 'With your help we have managed to secure the northern and western sectors of Northshire. We still have a rather large contingency of Blackrock orcs to the east and they''ve begun burning down the forest!',0); + +UPDATE `quest_template_addon` SET `AllowableClasses`=4,`NextQuestID`=28759 WHERE `ID`=28767; -- Hunter +UPDATE `quest_template_addon` SET `AllowableClasses`=128,`NextQuestID`=28769 WHERE `ID`=28757; -- Mage +UPDATE `quest_template_addon` SET `AllowableClasses`=2,`NextQuestID`=28770 WHERE `ID`=28762; -- Paladin +UPDATE `quest_template_addon` SET `AllowableClasses`=16,`NextQuestID`=28771 WHERE `ID`=28763; -- Priest +UPDATE `quest_template_addon` SET `AllowableClasses`=8,`NextQuestID`=28772 WHERE `ID`=28764; -- Rogue +UPDATE `quest_template_addon` SET `AllowableClasses`=256,`NextQuestID`=28773 WHERE `ID`=28765; -- Warlock +UPDATE `quest_template_addon` SET `AllowableClasses`=1,`NextQuestID`=28774 WHERE `ID`=28766; -- Warrior +UPDATE `quest_template_addon` SET `AllowableClasses`=32,`NextQuestID`=29079 WHERE `ID`=29078; -- Deathknight + +UPDATE `quest_template_addon` SET `AllowableClasses`=4,`NextQuestID`=28780 WHERE `ID`=28759; -- Hunter +UPDATE `quest_template_addon` SET `AllowableClasses`=128,`NextQuestID`=28784 WHERE `ID`=28769; -- Mage +UPDATE `quest_template_addon` SET `AllowableClasses`=2,`NextQuestID`=28785 WHERE `ID`=28770; -- Paladin +UPDATE `quest_template_addon` SET `AllowableClasses`=16,`NextQuestID`=28786 WHERE `ID`=28771; -- Priest +UPDATE `quest_template_addon` SET `AllowableClasses`=8,`NextQuestID`=28787 WHERE `ID`=28772; -- Rogue +UPDATE `quest_template_addon` SET `AllowableClasses`=256,`NextQuestID`=28788 WHERE `ID`=28773; -- Warlock +UPDATE `quest_template_addon` SET `AllowableClasses`=1,`NextQuestID`=28789 WHERE `ID`=28774; -- Warrior +UPDATE `quest_template_addon` SET `AllowableClasses`=32,`NextQuestID`=29080 WHERE `ID`=29079; -- Deathknight + +UPDATE `quest_template_addon` SET `AllowableClasses`=4,`NextQuestID`=28791 WHERE `ID`=28780; -- Hunter +UPDATE `quest_template_addon` SET `AllowableClasses`=128,`NextQuestID`=28792 WHERE `ID`=28784; -- Mage +UPDATE `quest_template_addon` SET `AllowableClasses`=2,`NextQuestID`=28793 WHERE `ID`=28785; -- Paladin +UPDATE `quest_template_addon` SET `AllowableClasses`=16,`NextQuestID`=28794 WHERE `ID`=28786; -- Priest +UPDATE `quest_template_addon` SET `AllowableClasses`=8,`NextQuestID`=28795 WHERE `ID`=28787; -- Rogue +UPDATE `quest_template_addon` SET `AllowableClasses`=256,`NextQuestID`=28796 WHERE `ID`=28788; -- Warlock +UPDATE `quest_template_addon` SET `AllowableClasses`=1,`NextQuestID`=28797 WHERE `ID`=28789; -- Warrior +UPDATE `quest_template_addon` SET `AllowableClasses`=32,`NextQuestID`=29081 WHERE `ID`=29080; -- Deathknight + +UPDATE `quest_template_addon` SET `AllowableClasses`=4,`NextQuestID`=28817 WHERE `ID`=28791; -- Hunter +UPDATE `quest_template_addon` SET `AllowableClasses`=128,`NextQuestID`=28818 WHERE `ID`=28792; -- Mage +UPDATE `quest_template_addon` SET `AllowableClasses`=2,`NextQuestID`=28819 WHERE `ID`=28793; -- Paladin +UPDATE `quest_template_addon` SET `AllowableClasses`=16,`NextQuestID`=28820 WHERE `ID`=28794; -- Priest +UPDATE `quest_template_addon` SET `AllowableClasses`=8,`NextQuestID`=28821 WHERE `ID`=28795; -- Rogue +UPDATE `quest_template_addon` SET `AllowableClasses`=256,`NextQuestID`=28822 WHERE `ID`=28796; -- Warlock +UPDATE `quest_template_addon` SET `AllowableClasses`=4,`NextQuestID`=28823 WHERE `ID`=28797; -- Warrior +UPDATE `quest_template_addon` SET `AllowableClasses`=32,`NextQuestID`=29083 WHERE `ID`=29081; -- Deathknight + +UPDATE `quest_template_addon` SET `AllowableClasses`=4,`PrevQuestID`=28780 WHERE `ID`=28806; -- Hunter +UPDATE `quest_template_addon` SET `AllowableClasses`=128,`PrevQuestID`=28784 WHERE `ID`=28808; -- Mage +UPDATE `quest_template_addon` SET `AllowableClasses`=2,`PrevQuestID`=28785 WHERE `ID`=28809; -- Paladin +UPDATE `quest_template_addon` SET `AllowableClasses`=16,`PrevQuestID`=28786 WHERE `ID`=28810; -- Priest +UPDATE `quest_template_addon` SET `AllowableClasses`=8,`PrevQuestID`=28787 WHERE `ID`=28811; -- Rogue +UPDATE `quest_template_addon` SET `AllowableClasses`=256,`PrevQuestID`=28788 WHERE `ID`=28812; -- Warlock +UPDATE `quest_template_addon` SET `AllowableClasses`=4,`PrevQuestID`=28789 WHERE `ID`=28813; -- Warrior +UPDATE `quest_template_addon` SET `AllowableClasses`=32,`PrevQuestID`=29080 WHERE `ID`=29082; -- Deathknight + +UPDATE `quest_template_addon` SET `AllowableClasses`=4,`NextQuestID`=26389 WHERE `ID`=28817; -- Hunter +UPDATE `quest_template_addon` SET `AllowableClasses`=128,`NextQuestID`=26389 WHERE `ID`=28818; -- Mage +UPDATE `quest_template_addon` SET `AllowableClasses`=2,`NextQuestID`=26389 WHERE `ID`=28819; -- Paladin +UPDATE `quest_template_addon` SET `AllowableClasses`=16,`NextQuestID`=26389 WHERE `ID`=28820; -- Priest +UPDATE `quest_template_addon` SET `AllowableClasses`=8,`NextQuestID`=26389 WHERE `ID`=28821; -- Rogue +UPDATE `quest_template_addon` SET `AllowableClasses`=256,`NextQuestID`=26389 WHERE `ID`=28822; -- Warlock +UPDATE `quest_template_addon` SET `AllowableClasses`=4,`NextQuestID`=26389 WHERE `ID`=28823; -- Warrior +UPDATE `quest_template_addon` SET `AllowableClasses`=32,`NextQuestID`=26389 WHERE `ID`=29083; -- Deathknight + +UPDATE `creature_queststarter` SET `id`=197 WHERE `quest` IN (28780,28784,28785,28786,28787,28788,28789,29080); From 07e6d3362b1dec208f6c1fa84f24ffc617b87b37 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 12:44:30 +0200 Subject: [PATCH 03/44] fix structure --- .../world/4.3.4/2017_05_23_00_world.sql | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/sql/updates/world/4.3.4/2017_05_23_00_world.sql b/sql/updates/world/4.3.4/2017_05_23_00_world.sql index 27849544a1..4232af239a 100644 --- a/sql/updates/world/4.3.4/2017_05_23_00_world.sql +++ b/sql/updates/world/4.3.4/2017_05_23_00_world.sql @@ -1,37 +1,37 @@ DELETE FROM `quest_request_items` WHERE `ID` IN (28757,28762,28763,28764,28765,28766,28767,29078,28759,28769,28770,28771,28772,28773,28774,29079,28791,28792,28793,28794,28795,28796,28797,29081,28806,28808,28809,28810,28811,28812,28813,29082); -INSERT INTO `quest_request_items` (`ID`,`EmoteOnComplete`,`EmoteOnIncomplete`,`EmoteOnCompleteDelay`,`EmoteOnIncompleteDelay`,`CompletionText`,`VerifiedBuild`) VALUES -(28757,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), -(28762,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), -(28763,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), -(28764,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), -(28765,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), -(28766,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), -(28767,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), -(29078,6,0,0,0, 'Have you beaten back the Blackrock worgs?',0), -(28759,5,0,0,0, 'Kill the spies!',0), -(28769,5,0,0,0, 'Kill the spies!',0), -(28770,5,0,0,0, 'Kill the spies!',0), -(28771,5,0,0,0, 'Kill the spies!',0), -(28772,5,0,0,0, 'Kill the spies!',0), -(28773,5,0,0,0, 'Kill the spies!',0), -(28774,5,0,0,0, 'Kill the spies!',0), -(29079,5,0,0,0, 'Kill the spies!',0), -(28791,0,0,0,0, 'Kill the goblin assassins',0), -(28792,0,0,0,0, 'Kill the goblin assassins',0), -(28793,0,0,0,0, 'Kill the goblin assassins',0), -(28794,0,0,0,0, 'Kill the goblin assassins',0), -(28795,0,0,0,0, 'Kill the goblin assassins',0), -(28796,0,0,0,0, 'Kill the goblin assassins',0), -(28797,0,0,0,0, 'Kill the goblin assassins',0), -(29081,0,0,0,0, 'Kill the goblin assassins',0), -(28806,5,0,0,0, 'Rescue our Soldiers!',0), -(28808,5,0,0,0, 'Rescue our Soldiers!',0), -(28809,5,0,0,0, 'Rescue our Soldiers!',0), -(28810,5,0,0,0, 'Rescue our Soldiers!',0), -(28811,5,0,0,0, 'Rescue our Soldiers!',0), -(28812,5,0,0,0, 'Rescue our Soldiers!',0), -(28813,5,0,0,0, 'Rescue our Soldiers!',0), -(29082,5,0,0,0, 'Rescue our Soldiers!',0); +INSERT INTO `quest_request_items` (`ID`,`EmoteOnComplete`,`EmoteOnIncomplete`,`CompletionText`,`VerifiedBuild`) VALUES +(28757,6,0, 'Have you beaten back the Blackrock worgs?',0), +(28762,6,0, 'Have you beaten back the Blackrock worgs?',0), +(28763,6,0, 'Have you beaten back the Blackrock worgs?',0), +(28764,6,0, 'Have you beaten back the Blackrock worgs?',0), +(28765,6,0, 'Have you beaten back the Blackrock worgs?',0), +(28766,6,0, 'Have you beaten back the Blackrock worgs?',0), +(28767,6,0, 'Have you beaten back the Blackrock worgs?',0), +(29078,6,0, 'Have you beaten back the Blackrock worgs?',0), +(28759,5,0, 'Kill the spies!',0), +(28769,5,0, 'Kill the spies!',0), +(28770,5,0, 'Kill the spies!',0), +(28771,5,0, 'Kill the spies!',0), +(28772,5,0, 'Kill the spies!',0), +(28773,5,0, 'Kill the spies!',0), +(28774,5,0, 'Kill the spies!',0), +(29079,5,0, 'Kill the spies!',0), +(28791,0,0, 'Kill the goblin assassins',0), +(28792,0,0, 'Kill the goblin assassins',0), +(28793,0,0, 'Kill the goblin assassins',0), +(28794,0,0, 'Kill the goblin assassins',0), +(28795,0,0, 'Kill the goblin assassins',0), +(28796,0,0, 'Kill the goblin assassins',0), +(28797,0,0, 'Kill the goblin assassins',0), +(29081,0,0, 'Kill the goblin assassins',0), +(28806,5,0, 'Rescue our Soldiers!',0), +(28808,5,0, 'Rescue our Soldiers!',0), +(28809,5,0, 'Rescue our Soldiers!',0), +(28810,5,0, 'Rescue our Soldiers!',0), +(28811,5,0, 'Rescue our Soldiers!',0), +(28812,5,0, 'Rescue our Soldiers!',0), +(28813,5,0, 'Rescue our Soldiers!',0), +(29082,5,0, 'Rescue our Soldiers!',0); DELETE FROM `quest_offer_reward` WHERE `ID` IN (28757,28762,28763,28764,28765,28766,28767,29078,28759,28769,28770,28771,28772,28773,28774,29079,28780,28784,28785,28786,28787,28788,28789,29080,28806,28808,28809,28810,28811,28812,28813,29082,28791,28792,28793,28794,28795,28796,28797,29081,28817,28818,28819,28820,28821,28822,28823,29083); INSERT INTO `quest_offer_reward` (`ID`,`Emote1`,`Emote2`,`Emote3`,`Emote4`,`EmoteDelay1`,`EmoteDelay2`,`EmoteDelay3`,`EmoteDelay4`,`RewardText`,`VerifiedBuild`) VALUES From eae0f4d45e1057464887ed43959a0c616b8cda99 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 13:19:44 +0200 Subject: [PATCH 04/44] Typo fix on previous commit --- sql/updates/world/4.3.4/2017_05_23_01_world.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 sql/updates/world/4.3.4/2017_05_23_01_world.sql diff --git a/sql/updates/world/4.3.4/2017_05_23_01_world.sql b/sql/updates/world/4.3.4/2017_05_23_01_world.sql new file mode 100644 index 0000000000..94eb69aef0 --- /dev/null +++ b/sql/updates/world/4.3.4/2017_05_23_01_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `quest_template_addon` SET `AllowableClasses`=1 WHERE `ID`=28797; -- Warrior From 364dfc9c4ca2148edc2b2e5e284ed661631cb2dd Mon Sep 17 00:00:00 2001 From: joschiwald Date: Thu, 23 Mar 2017 03:44:43 -0300 Subject: [PATCH 05/44] Scripts/Ulduar: Initial implementation of the Thorim Encounter Closes #7651 Fix logic fail in achievement: SPELL_LIGHTNING_CHARGE aka 62279 is casted on Thorim itself to buff him, not the damage spell tracked by the achievement. --- .../world/3.3.5/2017_MM_DD_NN_world_15008.sql | 137 ++ .../Northrend/Ulduar/Ulduar/boss_thorim.cpp | 1882 ++++++++++++++++- .../Ulduar/Ulduar/instance_ulduar.cpp | 32 +- .../scripts/Northrend/Ulduar/Ulduar/ulduar.h | 65 +- .../Northrend/northrend_script_loader.cpp | 2 + 5 files changed, 2082 insertions(+), 36 deletions(-) create mode 100644 sql/updates/world/3.3.5/2017_MM_DD_NN_world_15008.sql diff --git a/sql/updates/world/3.3.5/2017_MM_DD_NN_world_15008.sql b/sql/updates/world/3.3.5/2017_MM_DD_NN_world_15008.sql new file mode 100644 index 0000000000..56d29c4c4e --- /dev/null +++ b/sql/updates/world/3.3.5/2017_MM_DD_NN_world_15008.sql @@ -0,0 +1,137 @@ +/* + * Thorim + */ + +-- todo: immunity runic colossus, rune giant grip and knockback + +DELETE FROM `creature_text` WHERE `CreatureID` IN (32865,32872,32873,33196); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextID`, `comment`) VALUES +-- Thorim +(32865, 0,0,'Interlopers! You mortals who dare to interfere with my sport will pay... Wait--you...',14,0,100,0,0,15733,33145,'Thorim SAY_AGGRO_1'), +(32865, 1,0,'I remember you... In the mountains... But you... what is this? Where am--',14,0,100,0,0,15734,33270,'Thorim SAY_AGGRO_2'), +(32865, 2,0,'Behold the power of the storms and despair!',14,0,100,0,0,15735,0,'Thorim SAY_SPECIAL_1'), +(32865, 3,0,'Do not hold back! Destroy them!',14,0,100,0,0,15736,34241,'Thorim SAY_SPECIAL_2'), +(32865, 4,0,'Have you begun to regret your intrusion?',14,0,100,0,0,15737,0,'Thorim SAY_SPECIAL_3'), +(32865, 5,0,'Impertinent whelps, you dare challenge me atop my pedestal? I will crush you myself!',14,0,100,0,0,15738,33148,'Thorim SAY_JUMPDOWN'), +(32865, 6,0,'Can''t you at least put up a fight!?',14,0,100,0,0,15739,34239,'Thorim SAY_SLAY_1'), +(32865, 6,1,'Pathetic.',14,0,100,0,0,15740,35768,'Thorim SAY_SLAY_2'), +(32865, 7,0,'My patience has reached its limit!',14,0,100,0,0,15741,33365,'Thorim SAY_BERSERK'), +(32865, 8,0,'Failures! Weaklings!',14,0,100,0,0,15742,33274,'Thorim SAY_WIPE'), +(32865, 9,0,'Stay your arms! I yield!',14,0,100,0,0,15743,33948,'Thorim SAY_DEATH'), +(32865,10,0,'I feel as though I am awakening from a nightmare, but the shadows in this place yet linger.',14,0,100,0,0,15744,33949,'Thorim SAY_END_NORMAL_1'), +(32865,11,0,'Sif... was Sif here? Impossible--she died by my brother''s hand. A dark nightmare indeed....',14,0,100,0,0,15745,33950,'Thorim SAY_END_NORMAL_2'), +(32865,12,0,'I need time to reflect.... I will aid your cause if you should require it. I owe you at least that much. Farewell.',14,0,100,0,0,15746,33951,'Thorim SAY_END_NORMAL_3'), +(32865,13,0,'You! Fiend! You are not my beloved! Be gone!',14,0,100,0,0,15747,33952,'Thorim SAY_END_HARD_1'), +(32865,14,0,'Behold the hand behind all the evil that has befallen Ulduar, left my kingdom in ruins, corrupted my brother, and slain my wife.',14,0,100,0,0,15748,33953,'Thorim SAY_END_HARD_2'), +(32865,15,0,'And now it falls to you, champions, to avenge us all. The task before you is great, but I will lend you my aid as I am able. You must prevail.',14,0,100,0,0,15749,33954,'Thorim SAY_END_HARD_3'), +-- Runic Colossus +(32872, 0,0,'%s surrounds itself with a crackling Runic Barrier!',41,0,100,0,0,0,33267,'Runic Colossus'), +-- Ancient Rune Giant +(32873, 0,0,'%s fortifies nearby allies with runic might!',41,0,100,0,0,0,33523,'Ancient Rune Giant'), +-- Sif +(33196, 0,0,'Thorim, my lord! Why else would these invaders have come into your sanctum but to slay you? They must be stopped!',14,0,100,0,0,15668,33325,'Sif - Start'), +(33196, 1,0,'These pathetic mortals are harmless, beneath my station. Dispose of them!',14,0,100,0,0,15669,33368,'Sif - Despawn'), +(33196, 2,0,'Impossible! Lord Thorim, I will bring your foes a frigid death!',14,0,100,0,0,15670,33369,'Sif - Event'); + +UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry`=194265; +DELETE FROM `smart_scripts` WHERE `entryorguid`=194265 AND `source_type`=1; +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`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(194265,1,0,0,70,0,100,0,2,0,0,0,9,0,0,0,0,0,0,14,34155,0,0,0,0,0,0, 'Lever - On activate - Activate Dark Iron Portcullis'); + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (62577,62603,62576,62602,62580,62604,62016,62057,62058,62042,62466,64767); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(62577,'spell_thorim_blizzard'), +(62603,'spell_thorim_blizzard'), +(62576,'spell_thorim_blizzard_effect'), +(62602,'spell_thorim_blizzard_effect'), +(62580,'spell_thorim_frostbolt_volley'), +(62604,'spell_thorim_frostbolt_volley'), +(62016,'spell_thorim_charge_orb'), +(62057,'spell_thorim_runic_smash'), +(62058,'spell_thorim_runic_smash'), +(62042,'spell_thorim_stormhammer'), +(62466,'spell_thorim_lightning_charge'), +(64767,'spell_thorim_stormhammer_sif'); + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=62042; + +DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (62131,62315,62316,62333,62334,62335,62327,62328,62321,62331,62332,62583,62577,62597,62580); +INSERT INTO `spelldifficulty_dbc` (`id`, `spellid0`, `spellid1`) VALUES +(62131,62131,64390), +(62315,62315,62415), +(62316,62316,62417), +(62333,62333,62441), +(62334,62334,62442), +(62335,62335,62443), +(62327,62327,62445), +(62328,62328,62446), +(62321,62321,62529), +(62331,62331,62418), +(62332,62332,62420), +(62583,62583,62601), +(62577,62577,62603), +(62597,62597,62605), +(62580,62580,62604); + +UPDATE `creature_template` SET `InhabitType`=4, `flags_extra`=128, `ScriptName`='' WHERE `entry` IN (33140,33141); +UPDATE `creature_template` SET `InhabitType`=4, `flags_extra`=128 WHERE `entry` IN (33054,33378); +UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry` IN (32892); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (62577,62603,62016,62976,63238,64098,62466,62565,62942,64767,62560,61964); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13,1,62577,0,0,31,0,3,32892,0,0,0,'','Thorim - Blizzard'), +(13,1,62603,0,0,31,0,3,32892,0,0,0,'','Thorim - Blizzard'), +(13,1,62016,0,0,31,0,3,33378,0,0,0,'','Thorim - Charge Orb'), +(13,1,62976,0,0,31,0,3,33378,0,0,0,'','Thorim - Lightning Pillar'), +(13,1,62976,0,0,33,0,1,0,0,1,0,'','Thorim - Lightning Pillar'), +(13,1,63238,0,0,31,0,3,33378,0,0,0,'','Thorim - Lightning Pillar'), +(13,1,63238,0,0,33,0,1,0,0,1,0,'','Thorim - Lightning Pillar'), +(13,1,64098,0,0,31,0,3,32865,0,0,0,'','Thorim - Lightning Bolt'), +(13,4,62466,0,0,31,0,3,32780,0,0,0,'','Thorim - Lightning Charge'), +(13,3,62565,0,0,31,0,3,32865,0,0,0,'','Thorim - Touch of Dominion'), +(13,7,62942,0,0,31,0,3,32874,0,0,0,'','Thorim - Runic Fortification'), +(13,7,62942,0,1,31,0,3,32875,0,0,0,'','Thorim - Runic Fortification'), +(13,7,62942,0,2,31,0,3,33110,0,0,0,'','Thorim - Runic Fortification'), +(13,1,64767,0,0,31,0,3,33196,0,0,0,'','Thorim - Stormhammer'), +(13,7,62560,0,0,31,0,3,32876,0,0,0,'','Thorim - Berserk'), +(13,7,62560,0,1,31,0,3,32877,0,0,0,'','Thorim - Berserk'), +(13,7,62560,0,2,31,0,3,32878,0,0,0,'','Thorim - Berserk'), +(13,7,62560,0,3,31,0,3,32904,0,0,0,'','Thorim - Berserk'), +(13,1,61964,0,0,31,0,3,32882,0,0,0,'','Thorim - Circle of Healing'), +(13,1,61964,0,1,31,0,3,32883,0,0,0,'','Thorim - Circle of Healing'), +(13,1,61964,0,2,31,0,3,32885,0,0,0,'','Thorim - Circle of Healing'), +(13,1,61964,0,3,31,0,3,32886,0,0,0,'','Thorim - Circle of Healing'), +(13,1,61964,0,4,31,0,3,32907,0,0,0,'','Thorim - Circle of Healing'), +(13,1,61964,0,5,31,0,3,32908,0,0,0,'','Thorim - Circle of Healing'); + +DELETE FROM `disables` WHERE `sourceType`=4 AND `entry` IN (10289,10314,10304,10313,10440,10457,10800,10801); +INSERT INTO `disables` (`sourceType`,`entry`,`flags`,`params_0`,`params_1`,`comment`) VALUES +(4,10800,0,0,0,'Siffed (10 player) - Duplicate'), +(4,10801,0,0,0,'Siffed (25 player) - Duplicate'); + +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (10289,10314,10305,10309,10440,10457); +INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES +(10289,12,0,0,''), -- Siffed (10 player) +(10314,12,1,0,''), -- Siffed (25 player) + +(10305,11,0,0,'achievement_dont_stand_in_the_lightning'), -- Don't Stand in the Lightning (10 player) +(10305,12,0,0,''), -- Don't Stand in the Lightning (10 player) +(10309,11,0,0,'achievement_dont_stand_in_the_lightning'), -- Don't Stand in the Lightning (25 player) +(10309,12,1,0,''), -- Don't Stand in the Lightning (25 player) + +(10440,11,0,0,'achievement_lose_your_illusion'), -- Lose Your Illusion (10 player) +(10440,12,0,0,''), -- Lose Your Illusion (10 player) +(10457,11,0,0,'achievement_lose_your_illusion'), -- Lose Your Illusion (25 player) +(10457,12,1,0,''); -- Lose Your Illusion (25 player) + +UPDATE `gameobject_template` SET `size`=3 WHERE `entry` IN (194312,194313,194314,194315); +UPDATE `gameobject_template_addon` SET `faction`=94 WHERE `entry` IN (194312,194313,194314,194315); + +DELETE FROM `gameobject` WHERE `id` IN (194312,194313,194314,194315); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`) values +(360300,194312,603,1,1,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-604800,255,1,0), +(360301,194313,603,1,1,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-604800,255,1,0), +(360302,194314,603,2,1,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-604800,255,1,0), +(360303,194315,603,2,1,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-604800,255,1,0); + +DELETE FROM `creature` WHERE `id`=32892 AND `position_z` < 425.0; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp index ea2fa4027a..f65aa2d676 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp @@ -15,27 +15,390 @@ * with this program. If not, see . */ +#include "MoveSplineInit.h" +#include "Player.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" #include "ulduar.h" +enum Spells +{ + // Thorim + SPELL_SHEAT_OF_LIGHTNING = 62276, + SPELL_STORMHAMMER = 62042, + SPELL_STORMHAMMER_SIF = 64767, + SPELL_STORMHAMMER_BOOMERANG = 64909, + SPELL_DEAFENING_THUNDER = 62470, + SPELL_CHARGE_ORB = 62016, + SPELL_SUMMON_LIGHTNING_ORB = 62391, + SPELL_LIGHTNING_DESTRUCTION = 62393, + SPELL_TOUCH_OF_DOMINION = 62507, + SPELL_TOUCH_OF_DOMINION_TRIGGERED = 62565, + SPELL_CHAIN_LIGHTNING = 62131, + SPELL_LIGHTNING_ORB_CHARGED = 62186, // wrong duration, triggered spell should handle lightning release + SPELL_LIGHTNING_CHARGE = 62279, + SPELL_LIGHTNING_RELEASE = 62466, + SPELL_LIGHTNING_PILLAR_2 = 62976, // caster high position, target low position + SPELL_LIGHTNING_PILLAR_1 = 63238, // caster high position, target low position + SPELL_UNBALANCING_STRIKE = 62130, + SPELL_BERSERK_PHASE_1 = 62560, + SPELL_BERSERK_PHASE_2 = 26662, + + // Credits + SPELL_CREDIT_SIFFED = 64980, + SPELL_CREDIT_KILL = 64985, + + // Lightning Field + SPELL_LIGHTNING_FIELD = 64972, + SPELL_LIGHTNING_BEAM_CHANNEL = 45537, + + // Sif + SPELL_BLIZZARD = 62577, + SPELL_BLINK = 62578, + SPELL_FROSTBOLT_VOLLEY = 62580, + SPELL_FROSTBOLT = 62583, + SPELL_FROSTNOVA = 62597, + SPELL_SIF_TRANSFORM = 64778, + + // Runic Colossus + SPELL_SMASH = 62339, + SPELL_RUNIC_BARRIER = 62338, + SPELL_RUNIC_CHARGE = 62613, + SPELL_RUNIC_SMASH = 62465, + SPELL_RUNIC_SMASH_RIGHT = 62057, + SPELL_RUNIC_SMASH_LEFT = 62058, + + // Ancient Rune Giant + SPELL_RUNIC_FORTIFICATION = 62942, + SPELL_RUNE_DETONATION = 62526, + SPELL_STOMP = 62411 +}; + +enum Phases +{ + PHASE_NULL, + PHASE_1, + PHASE_2 +}; + +enum Events +{ + // Thorim + EVENT_SAY_AGGRO_2 = 1, + EVENT_SAY_SIF_START, + EVENT_START_SIF_CHANNEL, + EVENT_STORMHAMMER, + EVENT_CHARGE_ORB, + EVENT_SUMMON_ADDS, + EVENT_BERSERK, + EVENT_JUMPDOWN, + EVENT_UNBALANCING_STRIKE, + EVENT_CHAIN_LIGHTNING, + EVENT_TRANSFER_ENERGY, + EVENT_RELEASE_ENERGY, + EVENT_ACTIVATE_LIGHNING_FIELD, + EVENT_CHECK_PLAYER, + EVENT_OUTRO_1, + EVENT_OUTRO_2, + EVENT_OUTRO_3, + + // Runic Colossus + EVENT_RUNIC_BARRIER, + EVENT_SMASH, + EVENT_RUNIC_CHARGE, + EVENT_RUNIC_SMASH, + + // Ancient Rune Giant + EVENT_RUNIC_FORTIFICATION, + EVENT_STOMP, + EVENT_RUNE_DETONATION, + + // Arena NPC + EVENT_PRIMARY_ABILITY, + EVENT_SECONDARY_ABILITY, + EVENT_THIRD_ABILITY, + EVENT_ABILITY_CHARGE, + + // Sif + EVENT_BLINK, + EVENT_FROST_NOVA, + EVENT_FROSTBOLT, + EVENT_FROSTBOLT_VOLLEY, + EVENT_BLIZZARD +}; + enum Yells { - SAY_AGGRO = 0, - SAY_SPECIAL_1 = 1, - SAY_SPECIAL_2 = 2, - SAY_SPECIAL_3 = 3, - SAY_JUMPDOWN = 4, - SAY_SLAY = 5, - SAY_BERSERK = 6, - SAY_WIPE = 7, - SAY_DEATH = 8, - SAY_END_NORMAL_1 = 9, - SAY_END_NORMAL_2 = 10, - SAY_END_NORMAL_3 = 11, - SAY_END_HARD_1 = 12, - SAY_END_HARD_2 = 13, - SAY_END_HARD_3 = 14 + // Thorim + SAY_AGGRO_1 = 0, + SAY_AGGRO_2 = 1, + //SAY_SPECIAL_1 = 2, + SAY_SPECIAL_2 = 3, + //SAY_SPECIAL_3 = 4, + SAY_JUMPDOWN = 5, + SAY_SLAY = 6, + SAY_BERSERK = 7, + SAY_WIPE = 8, + SAY_DEATH = 9, + SAY_END_NORMAL_1 = 10, + SAY_END_NORMAL_2 = 11, + SAY_END_NORMAL_3 = 12, + SAY_END_HARD_1 = 13, + SAY_END_HARD_2 = 14, + SAY_END_HARD_3 = 15, + + // Runic Colossus + EMOTE_RUNIC_BARRIER = 0, + + // Ancient Rune Giant + EMOTE_RUNIC_MIGHT = 0, + + // Sif + SAY_SIF_START = 0, + SAY_SIF_DESPAWN = 1, + SAY_SIF_EVENT = 2 +}; + +enum TrashTypes +{ + // Pre Phase Trash + BEHEMOTH, + MERCENARY_CAPTAIN, + MERCENARY_SOLDIER, + + // Arena Phase Trash + DARK_RUNE_CHAMPION, + DARK_RUNE_WARBRINGER, + DARK_RUNE_COMMONER, + DARK_RUNE_EVOKER, + + // Hall Way Trash + IRON_RING_GUARD, + IRON_HONOR_GUARD, + + // Shared + DARK_RUNE_ACOLYTE +}; + +enum PreAddSpells +{ + SPELL_ACID_BREATH = 62315, + SPELL_SWEEP = 62316, + + SPELL_DEVASTATE = 62317, + SPELL_HEROIC_SWIPE = 62444, + SPELL_SUNDER_ARMOR = 57807, + + SPELL_BARBED_SHOT = 62318, + SPELL_SHOOT = 16496, + + SPELL_RENEW = 62333, + SPELL_GREATER_HEAL = 62334, /// 61965 + SPELL_CIRCLE_OF_HEALING = 61964, + + SPELL_HOLY_SMITE = 62335, + + SPELL_CHARGE = 32323, + SPELL_MORTAL_STRIKE = 35054, + SPELL_WHIRLWIND = 33500, + + SPELL_LOW_BLOW = 62326, + SPELL_PUMMEL = 38313, + + SPELL_RUNIC_LIGHTNING = 62327, + SPELL_RUNIC_MENDING = 62328, + SPELL_RUNIC_SHIELD = 62321, + + SPELL_RUNIC_STRIKE = 62322, + SPELL_AURA_OF_CELERITY = 62320, + + SPELL_IMPALE = 62331, + SPELL_WHIRLING_TRIP = 64151, + + SPELL_CLEAVE = 42724, + SPELL_HAMSTRING = 48639, + SPELL_SHIELD_SMASH = 62332, +}; + +struct ThorimTrashInfo +{ + uint32 Type; + uint32 Entry; + uint32 PrimaryAbility; + uint32 SecondaryAbility; + uint32 ThirdAbility; +}; + +ThorimTrashInfo const StaticThorimTrashInfo[] = +{ + // Pre Phase + { BEHEMOTH, 32882, SPELL_ACID_BREATH, SPELL_SWEEP, 0 }, + { MERCENARY_CAPTAIN, 32908, SPELL_DEVASTATE, SPELL_HEROIC_SWIPE, SPELL_SUNDER_ARMOR }, // alliance? + { MERCENARY_SOLDIER, 32885, SPELL_BARBED_SHOT, SPELL_SHOOT, 0 }, // alliance? + { DARK_RUNE_ACOLYTE, 32886, SPELL_RENEW, SPELL_GREATER_HEAL, SPELL_CIRCLE_OF_HEALING }, + { MERCENARY_CAPTAIN, 32907, SPELL_DEVASTATE, SPELL_HEROIC_SWIPE, SPELL_SUNDER_ARMOR }, // horde? + { MERCENARY_SOLDIER, 32883, SPELL_BARBED_SHOT, SPELL_SHOOT, 0 }, // horde? + + // Arena Phase + { DARK_RUNE_CHAMPION, NPC_DARK_RUNE_CHAMPION, SPELL_MORTAL_STRIKE, SPELL_WHIRLWIND, 0 }, + { DARK_RUNE_WARBRINGER, NPC_DARK_RUNE_WARBRINGER, SPELL_RUNIC_STRIKE, 0, 0 }, + { DARK_RUNE_EVOKER, NPC_DARK_RUNE_EVOKER, SPELL_RUNIC_LIGHTNING, SPELL_RUNIC_SHIELD, SPELL_RUNIC_MENDING }, + { DARK_RUNE_COMMONER, NPC_DARK_RUNE_COMMONER, SPELL_LOW_BLOW, SPELL_PUMMEL, 0 }, + + // Hall Way + { IRON_RING_GUARD, NPC_IRON_RING_GUARD, SPELL_WHIRLING_TRIP, SPELL_IMPALE, 0 }, + { IRON_HONOR_GUARD, NPC_IRON_HONOR_GUARD, SPELL_CLEAVE, SPELL_SHIELD_SMASH, 0 }, + { DARK_RUNE_ACOLYTE, NPC_DARK_RUNE_ACOLYTE, SPELL_RENEW, SPELL_GREATER_HEAL, 0 }, +}; + +enum Actions +{ + ACTION_INCREASE_PREADDS_COUNT, + ACTION_ACTIVATE_RUNIC_SMASH, + ACTION_START_HARD_MODE, + ACTION_BERSERK, +}; + +#define MAX_HARD_MODE_TIME 180000 // 3 Minutes + +#define IN_ARENA(who) (who->GetPositionX() < 2181.19f && who->GetPositionY() > -299.12f) + +struct SummonLocation +{ + Position pos; + uint32 entry; +}; + +SummonLocation const PreAddLocations[] = +{ + { { 2149.68f, -263.477f, 419.679f, 3.120f }, 32882}, + { { 2131.31f, -271.640f, 419.840f, 2.188f }, 32908}, + { { 2127.24f, -259.182f, 419.974f, 5.917f }, 32885}, + { { 2123.32f, -254.770f, 419.840f, 6.170f }, 32885}, + { { 2120.10f, -258.990f, 419.840f, 6.250f }, 32885}, + { { 2129.09f, -277.142f, 419.756f, 1.222f }, 32886} +}; + +SummonLocation const ColossusAddLocations[] = +{ + { { 2218.38f, -297.50f, 412.18f, 1.030f }, NPC_IRON_RING_GUARD }, + { { 2235.07f, -297.98f, 412.18f, 1.613f }, NPC_IRON_RING_GUARD }, + { { 2235.26f, -338.34f, 412.18f, 1.589f }, NPC_IRON_RING_GUARD }, + { { 2217.69f, -337.39f, 412.18f, 1.241f }, NPC_IRON_RING_GUARD }, + { { 2227.58f, -308.30f, 412.18f, 1.591f }, NPC_DARK_RUNE_ACOLYTE }, + { { 2227.47f, -345.37f, 412.18f, 1.566f }, NPC_DARK_RUNE_ACOLYTE } +}; + +SummonLocation const GiantAddLocations[] = +{ + { { 2198.05f, -428.77f, 419.95f, 6.056f }, NPC_IRON_HONOR_GUARD }, + { { 2220.31f, -436.22f, 412.26f, 1.064f }, NPC_IRON_HONOR_GUARD }, + { { 2158.88f, -441.73f, 438.25f, 0.127f }, NPC_IRON_HONOR_GUARD }, + { { 2198.29f, -436.92f, 419.95f, 0.261f }, NPC_DARK_RUNE_ACOLYTE }, + { { 2230.93f, -434.27f, 412.26f, 1.931f }, NPC_DARK_RUNE_ACOLYTE } +}; + +Position const SifSpawnPosition = { 2148.301f, -297.8453f, 438.3308f, 2.687807f }; + +enum Achievements +{ + ACHIEVEMENT_DONT_STAND_IN_THE_LIGHTNING = 29712972, + ACHIEVEMENT_SIFFED = 29772978, + ACHIEVEMENT_LOSE_YOUR_ILLUSION = 31763183, +}; + +uint32 const LightningOrbPathSize = 8; +G3D::Vector3 const LightningOrbPath[LightningOrbPathSize] = +{ + { 2134.889893f, -298.632996f, 438.247467f }, + { 2134.570068f, -440.317993f, 438.247467f }, + { 2167.820312f, -440.330261f, 438.247589f }, + { 2213.394287f, -433.318298f, 412.665863f }, + { 2227.766113f, -433.275818f, 412.177032f }, + { 2227.551270f, -263.081085f, 412.176880f }, + { 2202.208008f, -262.939270f, 412.168976f }, + { 2182.310059f, -263.233093f, 414.739410f } +}; + +Position const ArenaCenter = { 2135.0f, -263.0f, 420.0f, 0.0f }; // used for trash jump calculation +Position const LightningFieldCenter = { 2135.0f, -312.5f, 438.0f, 0.0f }; // used for lightning field calculation + +// p2 start at 5357 + +class RunicSmashExplosionEvent : public BasicEvent +{ + public: + RunicSmashExplosionEvent(Creature* owner) : _owner(owner) { } + + bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override + { + _owner->CastSpell((Unit*)NULL, SPELL_RUNIC_SMASH); + return true; + } + + private: + Creature* _owner; +}; + +class TrashJumpEvent : public BasicEvent +{ + public: + TrashJumpEvent(Creature* owner) : _owner(owner), _stage(0) { } + + bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override + { + switch (_stage) + { + case 0: + if (Creature* stalker = _owner->FindNearestCreature(NPC_THORIM_INVISIBLE_STALKER, 30.0f)) + { + _owner->GetMotionMaster()->MoveJump(*stalker, SPEED_CHARGE, 15.0f); + _owner->SetHomePosition(*stalker); + } + ++_stage; + _owner->m_Events.AddEvent(this, _owner->m_Events.CalculateTime(2000)); + return false; + case 1: + _owner->SetReactState(REACT_AGGRESSIVE); + _owner->AI()->DoZoneInCombat(_owner, 200.0f); + return true; + default: + break; + } + + return true; + } + + private: + Creature* _owner; + uint8 _stage; +}; + +class LightningFieldEvent : public BasicEvent +{ + public: + LightningFieldEvent(Creature* owner) : _owner(owner) { } + + bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override + { + if (InstanceScript* instance = _owner->GetInstanceScript()) + { + if (instance->GetBossState(BOSS_THORIM) == IN_PROGRESS) + { + _owner->CastSpell((Unit*)NULL, SPELL_LIGHTNING_FIELD); + _owner->m_Events.AddEvent(this, _owner->m_Events.CalculateTime(1000)); + return false; + } + } + + _owner->InterruptNonMeleeSpells(false); + _owner->AI()->EnterEvadeMode(); + return true; + } + + private: + Creature* _owner; }; class boss_thorim : public CreatureScript @@ -47,17 +410,60 @@ class boss_thorim : public CreatureScript { boss_thorimAI(Creature* creature) : BossAI(creature, BOSS_THORIM) { + _encounterFinished = false; + Initialize(); + } + + void Initialize() + { + _killedCount = 0; + _waveType = 0; + _hardMode = true; + _orbSummoned = false; + _dontStandInTheLightning = true; } void Reset() override { + if (_encounterFinished) + return; + _Reset(); + Initialize(); + + me->SetReactState(REACT_PASSIVE); + SetCombatMovement(false); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + + events.SetPhase(PHASE_NULL); + + // Respawn Mini Bosses + for (uint8 i = DATA_RUNIC_COLOSSUS; i <= DATA_RUNE_GIANT; ++i) + if (Creature* miniBoss = ObjectAccessor::GetCreature(*me, instance->GetGuidData(i))) + miniBoss->Respawn(true); + + // Spawn Pre Phase Adds + for (SummonLocation const& s : PreAddLocations) + me->SummonCreature(s.entry, s.pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000); + + if (GameObject* go = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_THORIM_LEVER))) + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); } - void EnterEvadeMode(EvadeReason why) override + uint32 GetData(uint32 type) const override { - Talk(SAY_WIPE); - _EnterEvadeMode(why); + switch (type) + { + case ACHIEVEMENT_DONT_STAND_IN_THE_LIGHTNING: + return _dontStandInTheLightning ? 1 : 0; + case ACHIEVEMENT_LOSE_YOUR_ILLUSION: + case DATA_THORIM_HARDMODE: + return _hardMode ? 1 : 0; + default: + break; + } + + return 0; } void KilledUnit(Unit* who) override @@ -66,27 +472,406 @@ class boss_thorim : public CreatureScript Talk(SAY_SLAY); } - void JustDied(Unit* /*killer*/) override + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override { - Talk(SAY_DEATH); + if (spellInfo->Id == SPELL_TOUCH_OF_DOMINION_TRIGGERED) + { + if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + { + sif->AI()->Talk(SAY_SIF_DESPAWN); + sif->DespawnOrUnsummon(6000); + _hardMode = false; + } + } + } + + void SpellHitTarget(Unit* who, SpellInfo const* spellInfo) override + { + if (who->GetTypeId() == TYPEID_PLAYER && spellInfo->Id == SPELL_LIGHTNING_RELEASE) + _dontStandInTheLightning = false; + } + + void FinishEncounter() + { + if (_encounterFinished) + return; + + _encounterFinished = true; + + DoCastAOE(SPELL_CREDIT_KILL, true); // before change faction + + me->SetReactState(REACT_PASSIVE); + me->InterruptNonMeleeSpells(true); + me->RemoveAllAttackers(); + me->AttackStop(); + me->SetFaction(35); + + if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + { + summons.Despawn(sif); + sif->DespawnOrUnsummon(10000); + } + _JustDied(); + + Talk(SAY_DEATH); + events.ScheduleEvent(EVENT_OUTRO_1, 4000); + events.ScheduleEvent(EVENT_OUTRO_2, _hardMode ? 8000 : 11000); + events.ScheduleEvent(EVENT_OUTRO_3, _hardMode ? 19000 : 21000); + + me->m_Events.AddEvent(new KeeperDespawnEvent(me), me->m_Events.CalculateTime(35000)); } void EnterCombat(Unit* /*who*/) override { - Talk(SAY_AGGRO); _EnterCombat(); + Talk(SAY_AGGRO_1); + + events.SetPhase(PHASE_1); + + events.ScheduleEvent(EVENT_SAY_AGGRO_2, 9000, 0, PHASE_1); + events.ScheduleEvent(EVENT_SAY_SIF_START, 16500, 0, PHASE_1); + events.ScheduleEvent(EVENT_START_SIF_CHANNEL, 25000, 0, PHASE_1); + + events.ScheduleEvent(EVENT_STORMHAMMER, 40000, 0, PHASE_1); + events.ScheduleEvent(EVENT_CHARGE_ORB, 30000, 0, PHASE_1); + events.ScheduleEvent(EVENT_SUMMON_ADDS, 15000, 0, PHASE_1); + events.ScheduleEvent(EVENT_BERSERK, 369000); + events.ScheduleEvent(EVENT_CHECK_PLAYER, 10000); + + DoCast(me, SPELL_SHEAT_OF_LIGHTNING); + + if (Creature* runic = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RUNIC_COLOSSUS))) + runic->AI()->DoAction(ACTION_ACTIVATE_RUNIC_SMASH); + + if (GameObject* go = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_THORIM_LEVER))) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + + // Summon Sif + me->SummonCreature(NPC_SIF, SifSpawnPosition); } - void UpdateAI(uint32 /*diff*/) override + void JustSummoned(Creature* summon) override + { + switch (summon->GetEntry()) + { + case NPC_LIGHTNING_ORB: + { + summon->SetReactState(REACT_PASSIVE); + summon->CastSpell(summon, SPELL_LIGHTNING_DESTRUCTION, true); + + Position pos(LightningOrbPath[LightningOrbPathSize - 1].x, LightningOrbPath[LightningOrbPathSize - 1].y, LightningOrbPath[LightningOrbPathSize - 1].z); + summon->GetMotionMaster()->MovePoint(EVENT_CHARGE_PREPATH, pos, false); + + Movement::PointsArray path(LightningOrbPath, LightningOrbPath + LightningOrbPathSize); + + Movement::MoveSplineInit init(summon); + init.MovebyPath(path); + init.Launch(); + break; + } + case NPC_DARK_RUNE_CHAMPION: + case NPC_DARK_RUNE_WARBRINGER: + case NPC_DARK_RUNE_EVOKER: + case NPC_DARK_RUNE_COMMONER: + summon->SetReactState(REACT_PASSIVE); + summon->m_Events.AddEvent(new TrashJumpEvent(summon), summon->m_Events.CalculateTime(3000)); + break; + case NPC_SIF: + summon->SetReactState(REACT_PASSIVE); + break; + default: + break; + } + + BossAI::JustSummoned(summon); + } + + void UpdateAI(uint32 diff) override { if (!UpdateVictim()) return; - //SPELLS @todo - // + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SAY_AGGRO_2: + Talk(SAY_AGGRO_2); + break; + case EVENT_SAY_SIF_START: + if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + sif->AI()->Talk(SAY_SIF_START); + break; + case EVENT_START_SIF_CHANNEL: + if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + sif->CastSpell(me, SPELL_TOUCH_OF_DOMINION); + break; + case EVENT_STORMHAMMER: + DoCast(SPELL_STORMHAMMER); + events.ScheduleEvent(EVENT_STORMHAMMER, urand(15000, 20000), 0, PHASE_1); + break; + case EVENT_CHARGE_ORB: + DoCastAOE(SPELL_CHARGE_ORB); + events.ScheduleEvent(EVENT_CHARGE_ORB, urand(15000, 20000), 0, PHASE_1); + break; + case EVENT_SUMMON_ADDS: + SummonWave(); + events.ScheduleEvent(EVENT_SUMMON_ADDS, _orbSummoned ? 3000 : 10000, 0, PHASE_1); + break; + case EVENT_JUMPDOWN: + if (_hardMode) + if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + sif->AI()->DoAction(ACTION_START_HARD_MODE); + me->RemoveAurasDueToSpell(SPELL_SHEAT_OF_LIGHTNING); + me->SetReactState(REACT_AGGRESSIVE); + SetCombatMovement(true); + me->GetMotionMaster()->MoveJump(2134.79f, -263.03f, 419.84f, me->GetOrientation(), 30.0f, 20.0f); + events.ScheduleEvent(EVENT_UNBALANCING_STRIKE, 15000, 0, PHASE_2); + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 20000, 0, PHASE_2); + events.ScheduleEvent(EVENT_TRANSFER_ENERGY, 20000, 0, PHASE_2); + break; + case EVENT_UNBALANCING_STRIKE: + DoCastVictim(SPELL_UNBALANCING_STRIKE); + events.ScheduleEvent(EVENT_UNBALANCING_STRIKE, urand(15000, 20000), 0, PHASE_2); + break; + case EVENT_CHAIN_LIGHTNING: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + DoCast(target, SPELL_CHAIN_LIGHTNING); + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, urand(7000, 15000), 0, PHASE_2); + break; + case EVENT_TRANSFER_ENERGY: + { + std::list triggers; + me->GetCreatureListWithEntryInGrid(triggers, NPC_THUNDER_ORB, 200.0f); + triggers.remove_if([](Creature* trigger) + { + return trigger->GetPositionZ() < 425.0f; + }); + + if (!triggers.empty()) + { + Creature* pillar = Trinity::Containers::SelectRandomContainerElement(triggers); + _activePillarGUID = pillar->GetGUID(); + pillar->CastSpell(pillar, SPELL_LIGHTNING_ORB_CHARGED, true); + pillar->CastSpell((Unit*)nullptr, SPELL_LIGHTNING_PILLAR_2); + events.ScheduleEvent(EVENT_RELEASE_ENERGY, 8000, 0, PHASE_2); + } + + events.ScheduleEvent(EVENT_TRANSFER_ENERGY, 16000, 0, PHASE_2); + break; + } + case EVENT_RELEASE_ENERGY: + if (Creature* pillar = ObjectAccessor::GetCreature(*me, _activePillarGUID)) + DoCast(pillar, SPELL_LIGHTNING_RELEASE); + break; + case EVENT_BERSERK: + if (events.IsInPhase(PHASE_1)) + { + Talk(SAY_WIPE); + DoCastAOE(SPELL_BERSERK_PHASE_1, true); + DoCast(me, SPELL_SUMMON_LIGHTNING_ORB, true); + } + else + { + Talk(SAY_BERSERK); + DoCast(me, SPELL_BERSERK_PHASE_2, true); + } + break; + case EVENT_ACTIVATE_LIGHNING_FIELD: + { + std::list triggers; + me->GetCreatureListWithEntryInGrid(triggers, NPC_THORIM_EVENT_BUNNY, 100.0f); + triggers.remove_if([](Creature* bunny) + { + if (bunny->GetPositionZ() < 430.0f) + return true; + return LightningFieldCenter.GetExactDist2dSq(bunny) > 1225.0f; + }); + + uint64 timer = 1000; + for (Creature* bunny : triggers) + bunny->m_Events.AddEvent(new LightningFieldEvent(bunny), bunny->m_Events.CalculateTime(timer += 100)); + + triggers.remove_if([](Creature* bunny) + { + return LightningFieldCenter.GetExactDist2dSq(bunny) < 400.0f; + }); + + triggers.sort([](Creature* a, Creature* b) + { + return a->GetPositionX() < b->GetPositionX(); + }); + + for (std::list::const_iterator itr = triggers.begin(); itr != triggers.end();) + { + std::list::const_iterator prev = itr++; + if (itr != triggers.end()) + (*prev)->CastSpell(*itr, SPELL_LIGHTNING_BEAM_CHANNEL); + } + break; + } + case EVENT_CHECK_PLAYER: + if (!me->GetMap()->GetPlayersCountExceptGMs()) + EnterEvadeMode(); + events.ScheduleEvent(EVENT_CHECK_PLAYER, 10000); + break; + case EVENT_OUTRO_1: + Talk(_hardMode ? SAY_END_HARD_1 : SAY_END_NORMAL_1); + if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + DoCast(sif, SPELL_STORMHAMMER_SIF); + break; + case EVENT_OUTRO_2: + Talk(_hardMode ? SAY_END_HARD_2 : SAY_END_NORMAL_2); + break; + case EVENT_OUTRO_3: + Talk(_hardMode ? SAY_END_HARD_3 : SAY_END_NORMAL_3); + break; + default: + break; + } + } + DoMeleeAttackIfReady(); } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_BERSERK: + if (events.IsInPhase(PHASE_2)) + return; + + if (!_orbSummoned) + { + _orbSummoned = true; + events.RescheduleEvent(EVENT_BERSERK, 1000); + } + return; + case ACTION_INCREASE_PREADDS_COUNT: + if (++_killedCount >= 6) + { + // Event starts + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + DoZoneInCombat(me, 250.0f); + } + break; + default: + break; + } + } + + void GetTrashSpawnTriggers(std::list& triggerList, uint32 count = 1) + { + me->GetCreatureListWithEntryInGrid(triggerList, NPC_THORIM_EVENT_BUNNY, 100.0f); + triggerList.remove_if([](Creature* bunny) + { + if (bunny->GetPositionZ() < 430.0f) + return true; + return ArenaCenter.GetExactDist2dSq(bunny) < 3025.0f; + }); + + if (triggerList.empty()) + return; + + if (count == 1) + { + Creature* bunny = Trinity::Containers::SelectRandomContainerElement(triggerList); + triggerList.clear(); + triggerList.push_back(bunny); + } + else + Trinity::Containers::RandomResizeList(triggerList, count); + } + + void SummonWave() + { + switch (_waveType) + { + case 0: + { + // Dark Rune Commoner + std::list triggers; + GetTrashSpawnTriggers(triggers, urand(5, 6)); + + for (Creature* bunny : triggers) + me->SummonCreature(StaticThorimTrashInfo[6 + 3].Entry, *bunny, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000); + + ++_waveType; + break; + } + case 1: + if (urand(0, 1)) + { + // Dark Rune Champion or Dark Rune Evoker + std::list triggers; + GetTrashSpawnTriggers(triggers, urand(2, 4)); + + for (Creature* bunny : triggers) + me->SummonCreature(StaticThorimTrashInfo[6 + RAND(0, 2)].Entry, *bunny, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000); + } + else + { + // Dark Rune Warbringer + std::list triggers; + GetTrashSpawnTriggers(triggers); + + for (Creature* bunny : triggers) + me->SummonCreature(StaticThorimTrashInfo[6 + 1].Entry, *bunny, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000); + } + --_waveType; + break; + } + } + + bool CanStartPhase2(Unit* actor) const + { + if (actor->GetTypeId() != TYPEID_PLAYER || !me->IsWithinDistInMap(actor, 10.0f)) + return false; + + Creature* runicColossus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RUNIC_COLOSSUS)); + Creature* runeGiant = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RUNE_GIANT)); + return runicColossus && !runicColossus->IsAlive() && runeGiant && !runeGiant->IsAlive(); + } + + void DamageTaken(Unit* attacker, uint32& damage) override + { + if (events.IsInPhase(PHASE_1) && CanStartPhase2(attacker)) + { + Talk(SAY_JUMPDOWN); + events.SetPhase(PHASE_2); + events.ScheduleEvent(EVENT_JUMPDOWN, 8000); + events.ScheduleEvent(EVENT_ACTIVATE_LIGHNING_FIELD, 15000); + events.RescheduleEvent(EVENT_BERSERK, 300000, 0, PHASE_2); + + if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + sif->InterruptNonMeleeSpells(false); + + // Hard Mode + if (_hardMode && events.GetTimer() <= MAX_HARD_MODE_TIME) + DoCastAOE(SPELL_CREDIT_SIFFED, true); + } + else if (me->HealthBelowPctDamaged(1, damage)) + { + damage = 0; + FinishEncounter(); + } + } + + private: + ObjectGuid _activePillarGUID; + uint8 _killedCount; + uint8 _waveType; + bool _hardMode; + bool _encounterFinished; + bool _orbSummoned; + bool _dontStandInTheLightning; }; CreatureAI* GetAI(Creature* creature) const override @@ -95,7 +880,1056 @@ class boss_thorim : public CreatureScript } }; +struct npc_thorim_trashAI : public ScriptedAI +{ + npc_thorim_trashAI(Creature* creature) : ScriptedAI(creature) + { + _instance = creature->GetInstanceScript(); + for (uint8 i = 0; i < 13; ++i) + if (me->GetEntry() == StaticThorimTrashInfo[i].Entry) + _info = &StaticThorimTrashInfo[i]; + + ASSERT(_info); + } + + struct AIHelper + { + /// returns heal amount of the given spell including hots + static uint32 GetTotalHeal(SpellInfo const* spellInfo, Unit const* caster) + { + uint32 heal = 0; + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (spellInfo->Effects[i].IsEffect(SPELL_EFFECT_HEAL)) + heal += spellInfo->Effects[i].CalcValue(caster); + + if (spellInfo->Effects[i].IsEffect(SPELL_EFFECT_APPLY_AURA) && spellInfo->Effects[i].IsAura(SPELL_AURA_PERIODIC_HEAL)) + heal += spellInfo->GetMaxTicks() * spellInfo->Effects[i].CalcValue(caster); + } + return heal; + } + + /// returns heal amount of the given spell including hots + static uint32 GetTotalHeal(uint32 spellId, Unit const* caster) + { + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) + return GetTotalHeal(spellInfo, caster); + return 0; + } + + /// returns remaining heal amount on given target + static uint32 GetRemainingHealOn(Unit* target) + { + uint32 heal = 0; + Unit::AuraApplicationMap const& auras = target->GetAppliedAuras(); + for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + Aura const* aura = itr->second->GetBase(); + + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (AuraEffect const* aurEff = aura->GetEffect(i)) + { + if (aurEff->GetAuraType() == SPELL_AURA_PERIODIC_HEAL) + heal += aurEff->GetAmount() * (aurEff->GetTotalTicks() - aurEff->GetTickNumber()); + } + } + } + return heal; + } + + class MostHPMissingInRange + { + public: + MostHPMissingInRange(Unit const* referer, float range, uint32 hp, uint32 exclAura = 0, bool exclSelf = false) + : _referer(referer), _range(range), _hp(hp), _exclAura(exclAura), _exclSelf(exclSelf) { } + + bool operator()(Unit* u) + { + if (_exclSelf && u == _referer) + return false; + + if (_exclAura && u->HasAura(sSpellMgr->GetSpellIdForDifficulty(_exclAura, _referer))) + return false; + + if ((u->GetHealth() + GetRemainingHealOn(u) + _hp) > u->GetMaxHealth()) + return false; + + uint32 missingHP = u->GetMaxHealth() - u->GetHealth(); + if (u->IsAlive() && _referer->IsFriendlyTo(u) && _referer->IsWithinDistInMap(u, _range) && missingHP > _hp) + { + _hp = missingHP; + return true; + } + + return false; + } + + private: + Unit const* _referer; + float _range; + uint32 _hp; + uint32 _exclAura; + bool _exclSelf; + }; + + static Unit* GetUnitWithMostMissingHp(SpellInfo const* spellInfo, Unit* caster) + { + float range = spellInfo->GetMaxRange(false); + uint32 heal = GetTotalHeal(spellInfo, caster); + + Unit* target = nullptr; + MostHPMissingInRange checker(caster, range, heal); + Trinity::UnitLastSearcher searcher(caster, target, checker); + caster->VisitNearbyObject(range, searcher); + + return target; + } + + static Unit* GetHealTarget(uint32 spellId, Unit* caster) + { + Unit* healTarget = nullptr; + + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) + { + if (!spellInfo->HasAttribute(SPELL_ATTR1_CANT_TARGET_SELF) && !roll_chance_f(caster->GetHealthPct()) && !((caster->GetHealth() + GetRemainingHealOn(caster) + GetTotalHeal(spellInfo, caster)) > caster->GetMaxHealth())) + healTarget = caster; + else + healTarget = GetUnitWithMostMissingHp(spellInfo, caster); + } + + return healTarget; + } + }; + + bool UseAbility(uint32 spellId) + { + Unit* target = nullptr; + if (AIHelper::GetTotalHeal(spellId, me)) + target = AIHelper::GetHealTarget(spellId, me); + else + target = me->GetVictim(); + + if (target) + { + if (_info->Type == MERCENARY_SOLDIER) + { + bool allowMove = true; + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) + { + if (me->IsInRange(target, spellInfo->GetMinRange(false), spellInfo->GetMaxRange(false)) + && me->IsWithinLOSInMap(target)) + allowMove = false; + } + SetCombatMovement(allowMove); + } + + DoCast(target, spellId); + return true; + } + + return false; + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + ExecuteEvent(eventId); + } + + if (_info->Type == DARK_RUNE_ACOLYTE) + DoSpellAttackIfReady(SPELL_HOLY_SMITE); + else + DoMeleeAttackIfReady(); + } + + virtual void ExecuteEvent(uint32 eventId) = 0; + +protected: + InstanceScript* _instance; + EventMap _events; + + ThorimTrashInfo const* _info = nullptr; +}; + +class npc_thorim_pre_phase : public CreatureScript +{ + public: + npc_thorim_pre_phase() : CreatureScript("npc_thorim_pre_phase") { } + + struct npc_thorim_pre_phaseAI : public npc_thorim_trashAI + { + npc_thorim_pre_phaseAI(Creature* creature) : npc_thorim_trashAI(creature) + { + me->setActive(true); // prevent grid unload + } + + void Reset() + { + _events.Reset(); + if (_info->PrimaryAbility) + _events.ScheduleEvent(EVENT_PRIMARY_ABILITY, urand(3000, 6000)); + if (_info->SecondaryAbility) + _events.ScheduleEvent(EVENT_SECONDARY_ABILITY, _info->SecondaryAbility == SPELL_SHOOT ? 2000 : urand(12000, 15000)); + if (_info->ThirdAbility) + _events.ScheduleEvent(EVENT_THIRD_ABILITY, urand(6000, 8000)); + if (_info->Type == MERCENARY_SOLDIER) + SetCombatMovement(false); + } + + void JustDied(Unit* /*victim*/) + { + if (Creature* thorim = _instance->GetCreature(BOSS_THORIM)) + thorim->AI()->DoAction(ACTION_INCREASE_PREADDS_COUNT); + } + + void DamageTaken(Unit* attacker, uint32& damage) override + { + if (!attacker->GetAffectingPlayer()) + damage = 0; + } + + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) + { + case EVENT_PRIMARY_ABILITY: + if (UseAbility(_info->PrimaryAbility)) + _events.ScheduleEvent(eventId, urand(15000, 20000)); + else + _events.ScheduleEvent(eventId, 1000); + break; + case EVENT_SECONDARY_ABILITY: + if (UseAbility(_info->SecondaryAbility)) + _events.ScheduleEvent(eventId, _info->SecondaryAbility == SPELL_SHOOT ? 2000 : urand(4000, 8000)); + else + _events.ScheduleEvent(eventId, 1000); + break; + case EVENT_THIRD_ABILITY: + if (UseAbility(_info->ThirdAbility)) + _events.ScheduleEvent(eventId, urand(6000, 8000)); + else + _events.ScheduleEvent(eventId, 1000); + break; + default: + break; + } + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetUlduarAI(creature); + } +}; + +class npc_thorim_arena_phase : public CreatureScript +{ + public: + npc_thorim_arena_phase() : CreatureScript("npc_thorim_arena_phase") { } + + struct npc_thorim_arena_phaseAI : public npc_thorim_trashAI + { + npc_thorim_arena_phaseAI(Creature* creature) : npc_thorim_trashAI(creature) + { + switch (_info->Type) + { + case DARK_RUNE_CHAMPION: + case DARK_RUNE_WARBRINGER: + case DARK_RUNE_COMMONER: + case DARK_RUNE_EVOKER: + _isInArena = true; + break; + default: + _isInArena = false; + break; + } + //_isInArena = IN_ARENA(me); + } + + bool CanAIAttack(Unit const* who) const override + { + return _isInArena == IN_ARENA(who); + } + + void Reset() override + { + _events.Reset(); + if (_info->PrimaryAbility) + _events.ScheduleEvent(EVENT_PRIMARY_ABILITY, urand(3000, 6000)); + if (_info->SecondaryAbility) + _events.ScheduleEvent(EVENT_SECONDARY_ABILITY, urand(7000, 9000)); + if (_info->ThirdAbility) + _events.ScheduleEvent(EVENT_THIRD_ABILITY, urand(6000, 8000)); + if (_info->Type == DARK_RUNE_CHAMPION) + _events.ScheduleEvent(EVENT_ABILITY_CHARGE, 8000); + } + + void EnterCombat(Unit* /*who*/) + { + if (_info->Type == DARK_RUNE_WARBRINGER) + DoCast(me, SPELL_AURA_OF_CELERITY); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + // this should only happen if theres no alive player in the arena -> summon orb + // might be called by mind control release or controllers death? + if (Creature* thorim = _instance->GetCreature(BOSS_THORIM)) + thorim->AI()->DoAction(ACTION_BERSERK); + ScriptedAI::EnterEvadeMode(); + } + + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) + { + case EVENT_PRIMARY_ABILITY: + if (UseAbility(_info->PrimaryAbility)) + _events.ScheduleEvent(eventId, urand(3000, 6000)); + else + _events.ScheduleEvent(eventId, 1000); + break; + case EVENT_SECONDARY_ABILITY: + if (UseAbility(_info->SecondaryAbility)) + _events.ScheduleEvent(eventId, urand(12000, 16000)); + else + _events.ScheduleEvent(eventId, 1000); + break; + case EVENT_THIRD_ABILITY: + if (UseAbility(_info->ThirdAbility)) + _events.ScheduleEvent(eventId, urand(6000, 8000)); + else + _events.ScheduleEvent(eventId, 1000); + break; + case EVENT_ABILITY_CHARGE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, [this](Unit* unit){ return unit->GetTypeId() == TYPEID_PLAYER && unit->IsInRange(me, 8.0f, 25.0f); })) + DoCast(target, SPELL_CHARGE); + _events.ScheduleEvent(eventId, 12000); + break; + default: + break; + } + } + + private: + bool _isInArena; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetUlduarAI(creature); + } +}; + +struct npc_thorim_minibossAI : public ScriptedAI +{ + npc_thorim_minibossAI(Creature* creature) : ScriptedAI(creature), _summons(me) + { + _instance = creature->GetInstanceScript(); + } + + void JustSummoned(Creature* summon) override + { + _summons.Summon(summon); + ScriptedAI::JustSummoned(summon); + } + + void SummonedCreatureDespawn(Creature* summon) override + { + ScriptedAI::SummonedCreatureDespawn(summon); + _summons.Despawn(summon); + } + +protected: + InstanceScript* _instance; + EventMap _events; + SummonList _summons; +}; + +class npc_runic_colossus : public CreatureScript +{ + public: + npc_runic_colossus() : CreatureScript("npc_runic_colossus") { } + + struct npc_runic_colossusAI : public npc_thorim_minibossAI + { + npc_runic_colossusAI(Creature* creature) : npc_thorim_minibossAI(creature) + { + } + + void Reset() override + { + _events.Reset(); + + // Runed Door closed + _instance->HandleGameObject(_instance->GetGuidData(DATA_RUNIC_DOOR), false); + + // Spawn trashes + _summons.DespawnAll(); + for (SummonLocation const& s : ColossusAddLocations) + me->SummonCreature(s.entry, s.pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000); + } + + void MoveInLineOfSight(Unit* /*who*/) override + { + // don't enter combat + } + + void JustDied(Unit* /*victim*/) override + { + // Runed Door opened + _instance->HandleGameObject(_instance->GetGuidData(DATA_RUNIC_DOOR), true); + + if (Creature* thorim = _instance->GetCreature(BOSS_THORIM)) + thorim->AI()->Talk(SAY_SPECIAL_2); + } + + void DoAction(int32 action) override + { + if (action == ACTION_ACTIVATE_RUNIC_SMASH) + _events.ScheduleEvent(EVENT_RUNIC_SMASH, 12000); + } + + void EnterCombat(Unit* /*who*/) override + { + DoZoneInCombat(); + _events.Reset(); + _events.ScheduleEvent(EVENT_RUNIC_BARRIER, urand(12000, 15000)); + _events.ScheduleEvent(EVENT_SMASH, urand(15000, 18000)); + _events.ScheduleEvent(EVENT_RUNIC_CHARGE, urand(20000, 24000)); + me->InterruptNonMeleeSpells(true); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_RUNIC_BARRIER: + Talk(EMOTE_RUNIC_BARRIER); + DoCast(me, SPELL_RUNIC_BARRIER); + _events.ScheduleEvent(eventId, urand(35000, 45000)); + break; + case EVENT_SMASH: + DoCast(me, SPELL_SMASH); + _events.ScheduleEvent(eventId, urand(15000, 18000)); + break; + case EVENT_RUNIC_CHARGE: + { + Unit* referer = me; + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, [referer](Unit* unit){ return unit->GetTypeId() == TYPEID_PLAYER && unit->IsInRange(referer, 8.0f, 40.0f); })) + DoCast(target, SPELL_RUNIC_CHARGE); + _events.ScheduleEvent(eventId, 20000); + break; + } + case EVENT_RUNIC_SMASH: + DoCast(me, RAND(SPELL_RUNIC_SMASH_LEFT, SPELL_RUNIC_SMASH_RIGHT)); + _events.ScheduleEvent(eventId, 6000); + break; + default: + break; + } + } + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetUlduarAI(creature); + } +}; + +class npc_ancient_rune_giant : public CreatureScript +{ + public: + npc_ancient_rune_giant() : CreatureScript("npc_ancient_rune_giant") { } + + struct npc_ancient_rune_giantAI : public npc_thorim_minibossAI + { + npc_ancient_rune_giantAI(Creature* creature) : npc_thorim_minibossAI(creature) { } + + void Reset() override + { + _events.Reset(); + + // Stone Door closed + _instance->HandleGameObject(_instance->GetGuidData(DATA_STONE_DOOR), false); + + // Spawn trashes + _summons.DespawnAll(); + for (SummonLocation const& s : GiantAddLocations) + me->SummonCreature(s.entry, s.pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000); + } + + void EnterCombat(Unit* /*who*/) override + { + DoZoneInCombat(); + _events.Reset(); + _events.ScheduleEvent(EVENT_RUNIC_FORTIFICATION, 1); + _events.ScheduleEvent(EVENT_STOMP, urand(10000, 12000)); + _events.ScheduleEvent(EVENT_RUNE_DETONATION, 25000); + } + + void JustDied(Unit* /*victim*/) override + { + // Stone Door opened + _instance->HandleGameObject(_instance->GetGuidData(DATA_STONE_DOOR), true); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_RUNIC_FORTIFICATION: + Talk(EMOTE_RUNIC_MIGHT); + DoCastAOE(SPELL_RUNIC_FORTIFICATION); + break; + case EVENT_STOMP: + DoCastAOE(SPELL_STOMP); + _events.ScheduleEvent(eventId, urand(10000, 12000)); + break; + case EVENT_RUNE_DETONATION: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true)) + DoCast(target, SPELL_RUNE_DETONATION); + _events.ScheduleEvent(eventId, urand(10000, 12000)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetUlduarAI(creature); + } +}; + +class npc_sif : public CreatureScript +{ + public: + npc_sif() : CreatureScript("npc_sif") { } + + struct npc_sifAI : public ScriptedAI + { + npc_sifAI(Creature* creature) : ScriptedAI(creature), _summons(me) + { + SetCombatMovement(false); + } + + void Reset() override + { + _events.Reset(); + _summons.DespawnAll(); + } + + void JustSummoned(Creature* summon) override + { + _summons.Summon(summon); + if (summon->GetEntry() == NPC_THORIM_EVENT_BUNNY) + summon->GetMotionMaster()->MoveRandom(60.0f); + } + + void SummonedCreatureDespawn(Creature* summon) override + { + _summons.Despawn(summon); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id == SPELL_STORMHAMMER_SIF) + { + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + } + } + + void DoAction(int32 action) override + { + if (action == ACTION_START_HARD_MODE) + { + me->SetReactState(REACT_AGGRESSIVE); + DoZoneInCombat(me, 250.0f); + Talk(SAY_SIF_EVENT); + _events.Reset(); + _events.ScheduleEvent(EVENT_FROSTBOLT, 2000); + _events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, 15000); + _events.ScheduleEvent(EVENT_BLINK, urand(20000, 25000)); + _events.ScheduleEvent(EVENT_BLIZZARD, 30000); + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BLINK: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_BLINK); + _events.ScheduleEvent(EVENT_FROST_NOVA, 0); + _events.ScheduleEvent(eventId, urand(20000, 25000)); + return; + case EVENT_FROST_NOVA: + DoCastAOE(SPELL_FROSTNOVA); + return; + case EVENT_FROSTBOLT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_FROSTBOLT); + _events.ScheduleEvent(eventId, 2000); + return; + case EVENT_FROSTBOLT_VOLLEY: + DoCastAOE(SPELL_FROSTBOLT_VOLLEY); + _events.ScheduleEvent(eventId, urand(15000, 20000)); + return; + case EVENT_BLIZZARD: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) + me->SummonCreature(NPC_THORIM_EVENT_BUNNY, *target, TEMPSUMMON_TIMED_DESPAWN, 25000); + DoCastAOE(SPELL_BLIZZARD); + _events.ScheduleEvent(eventId, urand(35000, 45000)); + return; + default: + break; + } + } + + // no melee attack + } + + private: + EventMap _events; + SummonList _summons; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetUlduarAI(creature); + } +}; + +class HeightPositionCheck +{ + public: + HeightPositionCheck(bool ret) : _ret(ret) { } + + bool operator()(WorldObject* obj) const + { + return obj->GetPositionZ() > 425.0f == _ret; + } + + private: + bool _ret; +}; + +// 62577 - Blizzard +// 62603 - Blizzard +class spell_thorim_blizzard : public SpellScriptLoader +{ + public: + spell_thorim_blizzard() : SpellScriptLoader("spell_thorim_blizzard") { } + + class spell_thorim_blizzard_SpellScript : public SpellScript + { + PrepareSpellScript(spell_thorim_blizzard_SpellScript); + + void FilterTargets(std::list& targets) + { + targets.remove_if(HeightPositionCheck(true)); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thorim_blizzard_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_thorim_blizzard_SpellScript(); + } +}; + +// 62576 - Blizzard +// 62602 - Blizzard +class spell_thorim_blizzard_effect : public SpellScriptLoader +{ + public: + spell_thorim_blizzard_effect() : SpellScriptLoader("spell_thorim_blizzard_effect") { } + + class spell_thorim_blizzard_effect_AuraScript : public AuraScript + { + PrepareAuraScript(spell_thorim_blizzard_effect_AuraScript); + + bool CheckAreaTarget(Unit* target) + { + /// @todo: fix this for all dynobj auras + if (target != GetOwner()) + { + // check if not stacking aura already on target + // this one prevents overriding auras periodically by 2 near area aura owners + Unit::AuraApplicationMap const& auraMap = target->GetAppliedAuras(); + for (Unit::AuraApplicationMap::const_iterator iter = auraMap.begin(); iter != auraMap.end(); ++iter) + { + Aura const* aura = iter->second->GetBase(); + if (GetId() == aura->GetId() && GetOwner() != aura->GetOwner() /*!GetAura()->CanStackWith(aura)*/) + return false; + } + } + return true; + } + + void Register() override + { + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_thorim_blizzard_effect_AuraScript::CheckAreaTarget); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_thorim_blizzard_effect_AuraScript(); + } +}; + +// 62580, 62604 - Frostbolt Volley +class spell_thorim_frostbolt_volley : public SpellScriptLoader +{ + public: + spell_thorim_frostbolt_volley() : SpellScriptLoader("spell_thorim_frostbolt_volley") { } + + class spell_thorim_frostbolt_volley_SpellScript : public SpellScript + { + PrepareSpellScript(spell_thorim_frostbolt_volley_SpellScript); + + void FilterTargets(std::list& unitList) + { + unitList.remove_if(PlayerOrPetCheck()); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thorim_frostbolt_volley_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_thorim_frostbolt_volley_SpellScript(); + } +}; + +// 62016 - Charge Orb +class spell_thorim_charge_orb : public SpellScriptLoader +{ + public: + spell_thorim_charge_orb() : SpellScriptLoader("spell_thorim_charge_orb") { } + + class spell_thorim_charge_orb_SpellScript : public SpellScript + { + PrepareSpellScript(spell_thorim_charge_orb_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_LIGHTNING_PILLAR_1)) + return false; + return true; + } + + void FilterTargets(std::list& targets) + { + targets.remove_if([](WorldObject* target) + { + return target->GetPositionZ() < 425.0f; + }); + + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + + void HandleScript() + { + if (Unit* target = GetHitUnit()) + target->CastSpell((Unit*)nullptr, SPELL_LIGHTNING_PILLAR_1, true); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thorim_charge_orb_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + AfterHit += SpellHitFn(spell_thorim_charge_orb_SpellScript::HandleScript); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_thorim_charge_orb_SpellScript(); + } +}; + +// 62466 - Lightning Charge +class spell_thorim_lightning_charge : public SpellScriptLoader +{ + public: + spell_thorim_lightning_charge() : SpellScriptLoader("spell_thorim_lightning_charge") { } + + class spell_thorim_lightning_charge_SpellScript : public SpellScript + { + PrepareSpellScript(spell_thorim_lightning_charge_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_LIGHTNING_CHARGE)) + return false; + return true; + } + + void HandleFocus() + { + /// @workaround: focus target is not working because spell is triggered and instant + if (Creature* creature = GetCaster()->ToCreature()) + creature->FocusTarget(GetSpell(), GetExplTargetWorldObject()); + } + + void HandleCharge() + { + GetCaster()->CastSpell(GetCaster(), SPELL_LIGHTNING_CHARGE, true); + } + + void Register() override + { + BeforeCast += SpellCastFn(spell_thorim_lightning_charge_SpellScript::HandleFocus); + AfterCast += SpellCastFn(spell_thorim_lightning_charge_SpellScript::HandleCharge); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_thorim_lightning_charge_SpellScript(); + } +}; + +// 62042 - Stormhammer +class spell_thorim_stormhammer : public SpellScriptLoader +{ + public: + spell_thorim_stormhammer() : SpellScriptLoader("spell_thorim_stormhammer") { } + + class spell_thorim_stormhammer_SpellScript : public SpellScript + { + PrepareSpellScript(spell_thorim_stormhammer_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_STORMHAMMER_BOOMERANG) + || !sSpellMgr->GetSpellInfo(SPELL_DEAFENING_THUNDER)) + return false; + return true; + } + + void FilterTargets(std::list& targets) + { + targets.remove_if([](WorldObject* target) + { + return !IN_ARENA(target); + }); + + if (targets.empty()) + { + FinishCast(SPELL_FAILED_NO_VALID_TARGETS); + return; + } + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + { + target->CastSpell(target, SPELL_DEAFENING_THUNDER, true); + target->CastSpell(GetCaster(), SPELL_STORMHAMMER_BOOMERANG, true); + } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thorim_stormhammer_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_thorim_stormhammer_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_thorim_stormhammer_SpellScript(); + } +}; + +// 64767 - Stormhammer +class spell_thorim_stormhammer_sif : public SpellScriptLoader +{ + public: + spell_thorim_stormhammer_sif() : SpellScriptLoader("spell_thorim_stormhammer_sif") { } + + class spell_thorim_stormhammer_sif_SpellScript : public SpellScript + { + PrepareSpellScript(spell_thorim_stormhammer_sif_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_STORMHAMMER_BOOMERANG) + || !sSpellMgr->GetSpellInfo(SPELL_SIF_TRANSFORM)) + return false; + return true; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + { + target->CastSpell(GetCaster(), SPELL_STORMHAMMER_BOOMERANG, true); + target->CastSpell(target, SPELL_SIF_TRANSFORM, true); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_thorim_stormhammer_sif_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_thorim_stormhammer_sif_SpellScript(); + } +}; + +// 62057, 62058 - Runic Smash +class spell_thorim_runic_smash : public SpellScriptLoader +{ + public: + spell_thorim_runic_smash() : SpellScriptLoader("spell_thorim_runic_smash") { } + + class spell_thorim_runic_smash_SpellScript : public SpellScript + { + PrepareSpellScript(spell_thorim_runic_smash_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_RUNIC_SMASH)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + std::list triggers; + GetCaster()->GetCreatureListWithEntryInGrid(triggers, GetSpellInfo()->Id == SPELL_RUNIC_SMASH_LEFT ? NPC_GOLEM_LEFT_HAND_BUNNY : NPC_GOLEM_RIGHT_HAND_BUNNY, 150.0f); + for (Creature* bunny : triggers) + { + float dist = GetCaster()->GetExactDist(bunny); + bunny->m_Events.AddEvent(new RunicSmashExplosionEvent(bunny), bunny->m_Events.CalculateTime(uint64(dist * 30))); + }; + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_thorim_runic_smash_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_TRIGGER_SPELL); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_thorim_runic_smash_SpellScript(); + } +}; + +class achievement_dont_stand_in_the_lightning : public AchievementCriteriaScript +{ + public: + achievement_dont_stand_in_the_lightning() : AchievementCriteriaScript("achievement_dont_stand_in_the_lightning") { } + + bool OnCheck(Player* /*source*/, Unit* target) override + { + return target && target->GetAI()->GetData(ACHIEVEMENT_DONT_STAND_IN_THE_LIGHTNING); + } +}; + +class achievement_lose_your_illusion : public AchievementCriteriaScript +{ + public: + achievement_lose_your_illusion() : AchievementCriteriaScript("achievement_lose_your_illusion") { } + + bool OnCheck(Player* /*source*/, Unit* target) override + { + return target && target->GetAI()->GetData(ACHIEVEMENT_LOSE_YOUR_ILLUSION); + } +}; + void AddSC_boss_thorim() { new boss_thorim(); + new npc_thorim_pre_phase(); + new npc_thorim_arena_phase(); + new npc_runic_colossus(); + new npc_ancient_rune_giant(); + new npc_sif(); + new spell_thorim_blizzard(); + new spell_thorim_blizzard_effect(); + new spell_thorim_frostbolt_volley(); + new spell_thorim_charge_orb(); + new spell_thorim_lightning_charge(); + new spell_thorim_stormhammer(); + new spell_thorim_stormhammer_sif(); + new spell_thorim_runic_smash(); + new achievement_dont_stand_in_the_lightning(); + new achievement_lose_your_illusion(); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index 61275ff3e6..abb161d110 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -53,6 +53,7 @@ static DoorData const doorData[] = { GO_MIMIRON_DOOR_1, BOSS_MIMIRON, DOOR_TYPE_ROOM }, { GO_MIMIRON_DOOR_2, BOSS_MIMIRON, DOOR_TYPE_ROOM }, { GO_MIMIRON_DOOR_3, BOSS_MIMIRON, DOOR_TYPE_ROOM }, + { GO_THORIM_ENCOUNTER_DOOR, BOSS_THORIM, DOOR_TYPE_ROOM }, { GO_VEZAX_DOOR, BOSS_VEZAX, DOOR_TYPE_PASSAGE }, { GO_YOGG_SARON_DOOR, BOSS_YOGG_SARON, DOOR_TYPE_ROOM }, { GO_DOODAD_UL_SIGILDOOR_03, BOSS_ALGALON, DOOR_TYPE_ROOM }, @@ -89,6 +90,9 @@ ObjectData const creatureData[] = { NPC_EXPEDITION_COMMANDER, DATA_EXPEDITION_COMMANDER }, { NPC_RAZORSCALE_CONTROLLER, DATA_RAZORSCALE_CONTROL }, + { NPC_SIF, DATA_SIF }, + { NPC_RUNIC_COLOSSUS, DATA_RUNIC_COLOSSUS }, + { NPC_RUNE_GIANT, DATA_RUNE_GIANT }, { NPC_COMPUTER, DATA_COMPUTER }, { NPC_WORLD_TRIGGER_MIMIRON, DATA_MIMIRON_WORLD_TRIGGER }, { NPC_VOICE_OF_YOGG_SARON, DATA_VOICE_OF_YOGG_SARON }, @@ -112,6 +116,9 @@ ObjectData const objectData[] = { GO_RAZOR_HARPOON_2, GO_RAZOR_HARPOON_2 }, { GO_RAZOR_HARPOON_3, GO_RAZOR_HARPOON_3 }, { GO_RAZOR_HARPOON_4, GO_RAZOR_HARPOON_4 }, + { GO_THORIM_LEVER, DATA_THORIM_LEVER }, + { GO_THORIM_STONE_DOOR, DATA_STONE_DOOR }, + { GO_THORIM_RUNIC_DOOR, DATA_RUNIC_DOOR }, { 0, 0 } }; @@ -167,7 +174,8 @@ class instance_ulduar : public InstanceMapScript ObjectGuid LeviathanGateGUID; ObjectGuid KologarnChestGUID; ObjectGuid KologarnBridgeGUID; - ObjectGuid ThorimChestGUID; + ObjectGuid CacheOfStormsGUID; + ObjectGuid CacheOfStormsHardmodeGUID; ObjectGuid HodirRareCacheGUID; ObjectGuid HodirChestGUID; ObjectGuid MimironTramGUID; @@ -439,9 +447,13 @@ class instance_ulduar : public InstanceMapScript if (GetBossState(BOSS_KOLOGARN) == DONE) HandleGameObject(ObjectGuid::Empty, false, gameObject); break; - case GO_THORIM_CHEST_HERO: - case GO_THORIM_CHEST: - ThorimChestGUID = gameObject->GetGUID(); + case GO_CACHE_OF_STORMS_10: + case GO_CACHE_OF_STORMS_25: + CacheOfStormsGUID = gameObject->GetGUID(); + break; + case GO_CACHE_OF_STORMS_HARDMODE_10: + case GO_CACHE_OF_STORMS_HARDMODE_25: + CacheOfStormsHardmodeGUID = gameObject->GetGUID(); break; case GO_HODIR_RARE_CACHE_OF_WINTER_HERO: case GO_HODIR_RARE_CACHE_OF_WINTER: @@ -648,9 +660,15 @@ class instance_ulduar : public InstanceMapScript case BOSS_THORIM: if (state == DONE) { - if (GameObject* gameObject = instance->GetGameObject(ThorimChestGUID)) - gameObject->SetRespawnTime(gameObject->GetRespawnDelay()); - + if (Creature* thorim = GetCreature(BOSS_THORIM)) + { + if (GameObject* cache = instance->GetGameObject(thorim->AI()->GetData(DATA_THORIM_HARDMODE) ? CacheOfStormsHardmodeGUID : CacheOfStormsGUID)) + { + cache->SetLootRecipient(thorim->GetLootRecipient()); + cache->SetRespawnTime(cache->GetRespawnDelay()); + cache->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN); + } + } instance->SummonCreature(NPC_THORIM_OBSERVATION_RING, ObservationRingKeepersPos[2]); } break; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index 928a3eebf8..6edbea48b7 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -153,6 +153,24 @@ enum UlduarNPCs // Freya Achievement Trigger NPC_FREYA_ACHIEVE_TRIGGER = 33406, + // Thorim + NPC_THORIM_INVISIBLE_STALKER = 32780, + NPC_RUNIC_COLOSSUS = 32872, + NPC_RUNE_GIANT = 32873, + NPC_IRON_RING_GUARD = 32874, + NPC_IRON_HONOR_GUARD = 32875, + NPC_DARK_RUNE_CHAMPION = 32876, + NPC_DARK_RUNE_WARBRINGER = 32877, + NPC_DARK_RUNE_EVOKER = 32878, + NPC_DARK_RUNE_COMMONER = 32904, + NPC_DARK_RUNE_ACOLYTE = 33110, + NPC_THORIM_EVENT_BUNNY = 32892, + NPC_LIGHTNING_ORB = 33138, + NPC_GOLEM_RIGHT_HAND_BUNNY = 33140, + NPC_GOLEM_LEFT_HAND_BUNNY = 33141, + NPC_SIF = 33196, + NPC_THUNDER_ORB = 33378, + // Yogg-Saron NPC_SARA = 33134, NPC_GUARDIAN_OF_YOGG_SARON = 33136, @@ -237,8 +255,14 @@ enum UlduarGameObjects GO_HODIR_CHEST = 194307, // Thorim - GO_THORIM_CHEST_HERO = 194315, - GO_THORIM_CHEST = 194314, + GO_CACHE_OF_STORMS_10 = 194312, + GO_CACHE_OF_STORMS_HARDMODE_10 = 194313, + GO_CACHE_OF_STORMS_25 = 194315, + GO_CACHE_OF_STORMS_HARDMODE_25 = 194314, + GO_THORIM_RUNIC_DOOR = 194557, + GO_THORIM_STONE_DOOR = 194558, + GO_THORIM_ENCOUNTER_DOOR = 194559, + GO_THORIM_LEVER = 194265, // Mimiron GO_MIMIRON_TRAM = 194675, @@ -404,6 +428,15 @@ enum UlduarData DATA_ALGALON_TRAPDOOR, DATA_BRANN_BRONZEBEARD_ALG, + // Thorim + DATA_SIF, + DATA_THORIM_LEVER, + DATA_RUNIC_COLOSSUS, + DATA_RUNE_GIANT, + DATA_RUNIC_DOOR, + DATA_STONE_DOOR, + DATA_THORIM_HARDMODE, + // Misc DATA_BRANN_BRONZEBEARD_INTRO, DATA_LORE_KEEPER_OF_NORGANNON, @@ -420,10 +453,15 @@ enum UlduarWorldStates enum UlduarAchievementData { // FL Achievement boolean - DATA_UNBROKEN = 29052906, // 2905, 2906 are achievement IDs, + DATA_UNBROKEN = 29052906, // 2905, 2906 are achievement IDs, MAX_HERALD_ARMOR_ITEMLEVEL = 226, - MAX_HERALD_WEAPON_ITEMLEVEL = 232, - SPELL_LUMBERJACKED_CREDIT = 65296 + MAX_HERALD_WEAPON_ITEMLEVEL = 232 +}; + +enum UlduarSharedSpells +{ + SPELL_LUMBERJACKED_CREDIT = 65296, + SPELL_TELEPORT_KEEPER_VISUAL = 62940 // used by keepers }; enum UlduarEvents @@ -448,6 +486,23 @@ AI* GetUlduarAI(T* obj) return GetInstanceAI(obj, UlduarScriptName); } +class KeeperDespawnEvent : public BasicEvent +{ + public: + KeeperDespawnEvent(Creature* owner, uint32 despawnTimerOffset = 500) : _owner(owner), _despawnTimer(despawnTimerOffset) { } + + bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override + { + _owner->CastSpell(_owner, SPELL_TELEPORT_KEEPER_VISUAL); + _owner->DespawnOrUnsummon(1000 + _despawnTimer); + return true; + } + + private: + Creature* _owner; + uint32 _despawnTimer; +}; + class PlayerOrPetCheck { public: diff --git a/src/server/scripts/Northrend/northrend_script_loader.cpp b/src/server/scripts/Northrend/northrend_script_loader.cpp index 4678eb7843..e3c5fb720a 100644 --- a/src/server/scripts/Northrend/northrend_script_loader.cpp +++ b/src/server/scripts/Northrend/northrend_script_loader.cpp @@ -110,6 +110,7 @@ void AddSC_boss_general_vezax(); void AddSC_boss_mimiron(); void AddSC_boss_hodir(); void AddSC_boss_freya(); +void AddSC_boss_thorim(); void AddSC_boss_yogg_saron(); void AddSC_boss_algalon_the_observer(); void AddSC_instance_ulduar(); @@ -291,6 +292,7 @@ void AddNorthrendScripts() AddSC_boss_mimiron(); AddSC_boss_hodir(); AddSC_boss_freya(); + AddSC_boss_thorim(); AddSC_boss_yogg_saron(); AddSC_boss_algalon_the_observer(); AddSC_instance_ulduar(); From 092c566ad368d33b7d37105a7ff22aafa050c308 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 13:31:44 +0200 Subject: [PATCH 06/44] Core/Scripts: improvements on the Thorim script Improvements done to initial work by joschiwald: - Fixed stormhammer casting and visuals - Fixed spell credits - Implemented removal of Impale when HP is higher than 90% - Corrected faction templates for the pre combat creatures - Implemeted Leap on the arena adds (thanks to joschiwald for implementing conditions) - Scripted lighting charge using AuraScript periodic - Fixed timings - Corrections on the hallway encounters (added knockback immunity to minibosses too) - Fixed multiple blizzards issue - Lever will now reset properly, should players fail to get inside. This allows the door to be opened more than once during the combat - Corrections in the outro event - Implemented paralytic field traps on the hallway. - Implemented Ancient Gate of the Keepers opening. - Changed blizzard bunny targetting to conditions entirely. - Removed obsolete scripts - Standards: delete spell script names by ScriptName instead of spell_id - Swapped factions for pre-adds (alliance should get horde trash and vs) - Fixed Leap setting home position for adds - Removed a bunch of magic numbers - Runic Colossus should finish current Runic Explosion before beginning to attack - Fixed UpdateAI logic to put it in line with other scripts (ie don't stop casts) Special thanks to: - chaodhib for the blizzard trigger waypoints and investigation on spell radius - Malcrom for creating the Conditions Creator :P --- .../world/3.3.5/2017_05_16_01_world.sql | 263 +++++ .../world/3.3.5/2017_MM_DD_NN_world_15008.sql | 137 --- .../Northrend/Ulduar/Ulduar/boss_thorim.cpp | 929 ++++++++++++------ .../Ulduar/Ulduar/instance_ulduar.cpp | 28 +- .../scripts/Northrend/Ulduar/Ulduar/ulduar.h | 16 +- 5 files changed, 911 insertions(+), 462 deletions(-) create mode 100644 sql/updates/world/3.3.5/2017_05_16_01_world.sql delete mode 100644 sql/updates/world/3.3.5/2017_MM_DD_NN_world_15008.sql diff --git a/sql/updates/world/3.3.5/2017_05_16_01_world.sql b/sql/updates/world/3.3.5/2017_05_16_01_world.sql new file mode 100644 index 0000000000..2566669cbe --- /dev/null +++ b/sql/updates/world/3.3.5/2017_05_16_01_world.sql @@ -0,0 +1,263 @@ +/* + * Thorim + */ + +DELETE FROM `creature_text` WHERE `CreatureID` IN (32865,32872,32873,33196); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextID`, `comment`) VALUES +-- Thorim +(32865, 0,0,'Interlopers! You mortals who dare to interfere with my sport will pay... Wait--you...',14,0,100,0,0,15733,33145,'Thorim SAY_AGGRO_1'), +(32865, 1,0,'I remember you... In the mountains... But you... what is this? Where am--',14,0,100,0,0,15734,33270,'Thorim SAY_AGGRO_2'), +(32865, 2,0,'Do not hold back! Destroy them!',14,0,100,0,0,15736,34241,'Thorim SAY_SPECIAL'), +(32865, 3,0,'Impertinent whelps, you dare challenge me atop my pedestal? I will crush you myself!',14,0,100,0,0,15738,33148,'Thorim SAY_JUMPDOWN'), +(32865, 4,0,'Can''t you at least put up a fight!?',14,0,100,0,0,15739,34239,'Thorim SAY_SLAY_1'), +(32865, 4,1,'Pathetic.',14,0,100,0,0,15740,35768,'Thorim SAY_SLAY_2'), +(32865, 5,0,'My patience has reached its limit!',14,0,100,0,0,15741,33365,'Thorim SAY_BERSERK'), +(32865, 6,0,'Failures! Weaklings!',14,0,100,0,0,15742,33274,'Thorim SAY_WIPE'), +(32865, 7,0,'Stay your arms! I yield!',14,0,100,0,0,15743,33948,'Thorim SAY_DEATH'), +(32865, 8,0,'I feel as though I am awakening from a nightmare, but the shadows in this place yet linger.',14,0,100,0,0,15744,33949,'Thorim SAY_END_NORMAL_1'), +(32865, 9,0,'Sif... was Sif here? Impossible--she died by my brother''s hand. A dark nightmare indeed....',14,0,100,0,0,15745,33950,'Thorim SAY_END_NORMAL_2'), +(32865,10,0,'I need time to reflect.... I will aid your cause if you should require it. I owe you at least that much. Farewell.',14,0,100,0,0,15746,33951,'Thorim SAY_END_NORMAL_3'), +(32865,11,0,'You! Fiend! You are not my beloved! Be gone!',14,0,100,0,0,15747,33952,'Thorim SAY_END_HARD_1'), +(32865,12,0,'Behold the hand behind all the evil that has befallen Ulduar, left my kingdom in ruins, corrupted my brother, and slain my wife.',14,0,100,0,0,15748,33953,'Thorim SAY_END_HARD_2'), +(32865,13,0,'And now it falls to you, champions, to avenge us all. The task before you is great, but I will lend you my aid as I am able. You must prevail.',14,0,100,0,0,15749,33954,'Thorim SAY_END_HARD_3'), +-- Runic Colossus +(32872, 0,0,'%s surrounds itself with a crackling Runic Barrier!',41,0,100,0,0,0,33267,'Runic Colossus'), +-- Ancient Rune Giant +(32873, 0,0,'%s fortifies nearby allies with runic might!',41,0,100,0,0,0,33523,'Ancient Rune Giant'), +-- Sif +(33196, 0,0,'Thorim, my lord! Why else would these invaders have come into your sanctum but to slay you? They must be stopped!',14,0,100,0,0,15668,33325,'Sif - Start'), +(33196, 1,0,'These pathetic mortals are harmless, beneath my station. Dispose of them!',14,0,100,0,0,15669,33368,'Sif - Despawn'), +(33196, 2,0,'Impossible! Lord Thorim, I will bring your foes a frigid death!',14,0,100,0,0,15670,33369,'Sif - Event'); + +-- Lever SAI +SET @ENTRY := 194264; +UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry`=@ENTRY; +UPDATE `gameobject_template_addon` SET `flags`=32 WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=1; +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`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,1,0,0,70,0,100,0,2,0,0,0,9,0,0,0,0,0,0,14,34155,0,0,0,0,0,0,'Lever - On Gameobject State Changed - Activate Gameobject'); + +-- Thorim Trap Bunny SAI +SET @ENTRY := 33054; +UPDATE `creature_template` SET `AIName`='SmartAI', `flags_extra`=2 WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,0,10,0,100,0,0,12,17000,17000,11,62241,0,0,0,0,0,1,0,0,0,0,0,0,0,'Thorim Trap Bunny - Within 0-12 Range Out of Combat LoS - Cast Paralytic Field'); + +SET @ENTRY := 33725; +UPDATE `creature_template` SET `AIName`='SmartAI', `flags_extra`=2 WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,0,10,0,100,0,0,12,17000,17000,11,63540,0,0,0,0,0,1,0,0,0,0,0,0,0,'Thorim Trap Bunny - Within 0-12 Range Out of Combat LoS - Cast Paralytic Field'); + +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_thorim_blizzard_effect','spell_thorim_frostbolt_volley','spell_thorim_charge_orb','spell_thorim_runic_smash','spell_thorim_stormhammer','spell_thorim_lightning_charge','spell_thorim_stormhammer_sif','spell_thorim_stormhammer_boomerang','spell_thorim_activate_lightning_orb_periodic','spell_iron_ring_guard_impale','spell_thorim_arena_leap'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(62576,'spell_thorim_blizzard_effect'), +(62602,'spell_thorim_blizzard_effect'), +(62580,'spell_thorim_frostbolt_volley'), +(62604,'spell_thorim_frostbolt_volley'), +(62016,'spell_thorim_charge_orb'), +(62057,'spell_thorim_runic_smash'), +(62058,'spell_thorim_runic_smash'), +(62042,'spell_thorim_stormhammer'), +(62466,'spell_thorim_lightning_charge'), +(64767,'spell_thorim_stormhammer_sif'), +(64909,'spell_thorim_stormhammer_boomerang'), +(62184,'spell_thorim_activate_lightning_orb_periodic'), +(62331,'spell_iron_ring_guard_impale'), +(62418,'spell_iron_ring_guard_impale'), +(61934,'spell_thorim_arena_leap'); + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=62042; +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` = -62320; +INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES +(-62320, -62398, 0, 'Aura of Celerity - Remove Visual'); + +-- Add dummy effect to kill credit so it actually selects targets +UPDATE `spell_dbc` SET `EffectImplicitTargetA1`=18, `EffectImplicitTargetB1`=16, `EffectRadiusIndex1`=28, `SchoolMask`=0, `Effect1`=3 WHERE `Id`=64980; +-- Correct attributes (SPELL_ATTR0_HIDE_IN_COMBAT_LOG, SPELL_ATTR2_CAN_TARGET_DEAD, SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) +UPDATE `spell_dbc` SET `Attributes`=`Attributes`|256, `AttributesEx2`=`AttributesEx2`|1|4 WHERE `Id` IN (64980,64985); + +DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (62131,62315,62316,62333,62334,62335,62327,62328,62321,62331,62332,62613,62583,62577,62597,62580); +INSERT INTO `spelldifficulty_dbc` (`id`, `spellid0`, `spellid1`) VALUES +(62131,62131,64390), -- Chain Lightning +(62315,62315,62415), -- Acid Breath +(62316,62316,62417), -- Sweep +(62333,62333,62441), -- Renew +(62334,62334,62442), -- Greater Heal +(62335,62335,62443), -- Holy Smite +(62327,62327,62445), -- Runic Lightning +(62328,62328,62446), -- Runic Mending +(62321,62321,62529), -- Runic Shield +(62331,62331,62418), -- Impale +(62332,62332,62420), -- Shield Smash +(62613,62613,62614), -- Charge +(62583,62583,62601), -- Frostbolt +(62577,62577,62603), -- Blizzard +(62597,62597,62605), -- Frost Nova +(62580,62580,62604); -- Frostbolt Volley + +UPDATE `creature_template` SET `ScriptName`='boss_thorim' WHERE `entry`=32865; +UPDATE `creature_template` SET `ScriptName`='npc_sif' WHERE `entry`=33196; +UPDATE `creature_template` SET `ScriptName`='npc_thorim_pre_phase' WHERE `entry` IN (32885,32883,32908,32907,32882,32886); +UPDATE `creature_template` SET `ScriptName`='npc_thorim_arena_phase' WHERE `entry` IN (32876,32904,32878,32877,32874,32875,33110); +UPDATE `creature_template` SET `ScriptName`='npc_runic_colossus' WHERE `entry`=32872; +UPDATE `creature_template` SET `ScriptName`='npc_ancient_rune_giant' WHERE `entry`=32873; +UPDATE `creature_template` SET `flags_extra`=`flags_extra`|0x40000000 WHERE `entry` IN (32872, 32873, 33148, 33149); +UPDATE `creature_template` SET `difficulty_entry_1`=33150 WHERE `entry`=32908; -- Swapped Difficulty entry npcs +UPDATE `creature_template` SET `difficulty_entry_1`=33151 WHERE `entry`=32907; -- Caused swapped displayIDs in 25n +UPDATE `creature_template` SET `InhabitType`=4, `flags_extra`=128, `ScriptName`='' WHERE `entry` IN (33140,33141); +UPDATE `creature_template` SET `InhabitType`=4, `flags_extra`=128 WHERE `entry` IN (33378,32879); +UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry` IN (32892); +UPDATE `creature_template` SET `faction`=1692 WHERE `entry` IN (32885,32883,33152,33153,32908,33150,32907,33151); +UPDATE `creature_template` SET `faction`=1693 WHERE `entry` IN (32882,33154); +UPDATE `creature_template` SET `speed_walk`=2.5/2.5, `speed_run`=14.0/7.0, `BaseAttackTime`=1500, `RangeAttackTime`=1500, `flags_extra`=`flags_extra`|0x00000200 WHERE `entry` IN (32865,33147); + +SET @THORIM_BLIZZARD_BUNNY := 136515; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (62577,62603,62016,62976,63238,64098,62466,62565,62942,64767,62560,61964,61934); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 62577, 0, 0, 31, 0, 3, 32892, @THORIM_BLIZZARD_BUNNY, 0, 0, 0, '', 'Spell Blizzard (effect 0) will hit the potential target of the spell if target is unit Thorim Event Bunny guid 136515.'), +(13, 1, 62603, 0, 0, 31, 0, 3, 32892, @THORIM_BLIZZARD_BUNNY, 0, 0, 0, '', 'Spell Blizzard (effect 0) will hit the potential target of the spell if target is unit Thorim Event Bunny guid 136515.'), +(13, 1, 62016, 0, 0, 31, 0, 3, 33378, 0, 0, 0, 0, '', 'Spell Charge Orb (effect 0) will hit the potential target of the spell if target is unit Thunder Orb.'), +(13, 1, 62976, 0, 0, 31, 0, 3, 33378, 0, 0, 0, 0, '', 'Spell Lightning Pillar (effect 0) will hit the potential target of the spell if target is unit Thunder Orb.'), +(13, 1, 62976, 0, 0, 33, 0, 1, 0, 0, 1, 0, 0, '', 'Spell Lightning Pillar (effect 0) will hit the potential target of the spell if target is not the same as condition target.'), +(13, 1, 63238, 0, 0, 31, 0, 3, 33378, 0, 0, 0, 0, '', 'Spell Lightning Pillar (effect 0) will hit the potential target of the spell if target is unit Thunder Orb.'), +(13, 1, 63238, 0, 0, 33, 0, 1, 0, 0, 1, 0, 0, '', 'Spell Lightning Pillar (effect 0) will hit the potential target of the spell if target is not the same as condition target.'), +(13, 1, 64098, 0, 0, 31, 0, 3, 32865, 0, 0, 0, 0, '', 'Spell Lightning Bolt (effect 0) will hit the potential target of the spell if target is unit Thorim.'), +(13, 4, 62466, 0, 0, 31, 0, 3, 32780, 0, 0, 0, 0, '', 'Spell Lightning Charge (effect 2) will hit the potential target of the spell if target is unit Invisible Stalker (All Phases).'), +(13, 3, 62565, 0, 0, 31, 0, 3, 32865, 0, 0, 0, 0, '', 'Spell Touch of Dominion (effects 0 & 1) will hit the potential target of the spell if target is unit Thorim.'), +(13, 7, 62942, 0, 0, 31, 0, 3, 32874, 0, 0, 0, 0, '', 'Spell Runic Fortification (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Iron Ring Guard.'), +(13, 7, 62942, 0, 1, 31, 0, 3, 32875, 0, 0, 0, 0, '', 'Spell Runic Fortification (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Iron Honor Guard.'), +(13, 7, 62942, 0, 2, 31, 0, 3, 33110, 0, 0, 0, 0, '', 'Spell Runic Fortification (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Dark Rune Acolyte.'), +(13, 1, 64767, 0, 0, 31, 0, 3, 33196, 0, 0, 0, 0, '', 'Spell Stormhammer (effect 0) will hit the potential target of the spell if target is unit Sif.'), +(13, 7, 62560, 0, 0, 31, 0, 3, 32876, 0, 0, 0, 0, '', 'Spell Berserk (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Dark Rune Champion.'), +(13, 7, 62560, 0, 1, 31, 0, 3, 32877, 0, 0, 0, 0, '', 'Spell Berserk (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Dark Rune Warbringer.'), +(13, 7, 62560, 0, 2, 31, 0, 3, 32878, 0, 0, 0, 0, '', 'Spell Berserk (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Dark Rune Evoker.'), +(13, 7, 62560, 0, 3, 31, 0, 3, 32904, 0, 0, 0, 0, '', 'Spell Berserk (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Dark Rune Commoner.'), +(13, 1, 61964, 0, 0, 31, 0, 3, 32882, 0, 0, 0, 0, '', 'Spell Circle of Healing (effect 0) will hit the potential target of the spell if target is unit Jormungar Behemoth.'), +(13, 1, 61964, 0, 1, 31, 0, 3, 32883, 0, 0, 0, 0, '', 'Spell Circle of Healing (effect 0) will hit the potential target of the spell if target is unit Captured Mercenary Soldier.'), +(13, 1, 61964, 0, 2, 31, 0, 3, 32885, 0, 0, 0, 0, '', 'Spell Circle of Healing (effect 0) will hit the potential target of the spell if target is unit Captured Mercenary Soldier.'), +(13, 1, 61964, 0, 3, 31, 0, 3, 32886, 0, 0, 0, 0, '', 'Spell Circle of Healing (effect 0) will hit the potential target of the spell if target is unit Dark Rune Acolyte.'), +(13, 1, 61964, 0, 4, 31, 0, 3, 32907, 0, 0, 0, 0, '', 'Spell Circle of Healing (effect 0) will hit the potential target of the spell if target is unit Captured Mercenary Captain.'), +(13, 1, 61964, 0, 5, 31, 0, 3, 32908, 0, 0, 0, 0, '', 'Spell Circle of Healing (effect 0) will hit the potential target of the spell if target is unit Captured Mercenary Captain.'), +(13, 1, 61934, 0, 0, 31, 0, 3, 32892, 0, 0, 0, 0, 'condition_thorim_arena_leap', 'Spell Leap (effect 0) will hit the potential target of the spell if target is unit Thorim Event Bunny.'), +(13, 1, 61934, 0, 0, 31, 0, 3, 32892, @THORIM_BLIZZARD_BUNNY, 1, 0, 0, '', 'Spell Leap (effect 0) will hit the potential target of the spell if target is not unit Thorim Event Bunny guid 136515.'); + +DELETE FROM `disables` WHERE `sourceType`=4 AND `entry` IN (10289,10314,10304,10313,10440,10457,10800,10801); +INSERT INTO `disables` (`sourceType`,`entry`,`flags`,`params_0`,`params_1`,`comment`) VALUES +(4,10800,0,0,0,'Siffed (10 player) - Duplicate'), +(4,10801,0,0,0,'Siffed (25 player) - Duplicate'); + +DELETE FROM `disables` WHERE `sourceType`=0 AND `entry` IN (62042,64767,45537); +INSERT INTO `disables` (`sourceType`, `entry`, `flags`, `params_0`, `params_1`, `comment`) VALUES +(0, 62042, 64, '', '', 'Stormhammer - Ignore LOS'), +(0, 64767, 64, '', '', 'Stormhammer - Ignore LOS'), +(0, 45537, 64, '', '', 'Lightning Beam Channel - Ignore LOS'); + +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (10289,10314,10305,10309,10440,10457,10287,10288,10311,10312); +INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES +(10289,12,0,0,''), -- Siffed (10 player) +(10314,12,1,0,''), -- Siffed (25 player) + +(10305,11,0,0,'achievement_dont_stand_in_the_lightning'), -- Don't Stand in the Lightning (10 player) +(10305,12,0,0,''), -- Don't Stand in the Lightning (10 player) +(10309,11,0,0,'achievement_dont_stand_in_the_lightning'), -- Don't Stand in the Lightning (25 player) +(10309,12,1,0,''), -- Don't Stand in the Lightning (25 player) + +(10440,11,0,0,'achievement_lose_your_illusion'), -- Lose Your Illusion (10 player) +(10440,12,0,0,''), -- Lose Your Illusion (10 player) +(10457,11,0,0,'achievement_lose_your_illusion'), -- Lose Your Illusion (25 player) +(10457,12,1,0,''), -- Lose Your Illusion (25 player) + +(10287,11,0,0,'achievement_i_ll_take_you_all_on'), -- I'll Take You All On (10 player) - Participate in slaying Runic Colossus +(10287,12,0,0,''), +(10288,11,0,0,'achievement_i_ll_take_you_all_on'), -- I'll Take You All On (10 player) - Participate in slaying Ancient Rune Giant +(10288,12,0,0,''), +(10311,11,0,0,'achievement_i_ll_take_you_all_on'), -- I'll Take You All On (25 player) - Participate in slaying Runic Colossus +(10311,12,1,0,''), +(10312,11,0,0,'achievement_i_ll_take_you_all_on'), -- I'll Take You All On (25 player) - Participate in slaying Ancient Rune Giant +(10312,12,1,0,''); + +DELETE FROM `creature` WHERE `id` IN (32882,32908,32907,32885,32883,32886); -- PreAdds +DELETE FROM `creature` WHERE `id` IN (32874,32875,33110); -- Colossus, Giant Adds + +-- Fix Thorim Controller multi spawns +SET @CGUID:=136446; +DELETE FROM `creature` WHERE `id`=32879; +INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `MovementType`) VALUES +(@CGUID, 32879, 603, 3, 1, 2134.774, -262.3073, 428.6936, 1.343904, 7200, 0, 0); -- 32879 (Area: 0) (Auras: 62184 - 62184) + +UPDATE `gameobject_template` SET `size`=3 WHERE `entry`=194315; +UPDATE `gameobject_template_addon` SET `faction`=94, `flags`=16 WHERE `entry` IN (194313,194314,194315); + +SET @OGUID := 3926; -- 4 free guids +DELETE FROM `gameobject` WHERE `id` IN (194312,194313,194314,194315); +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`) values +(@OGUID+0,194312,603,1,1,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-2592000,255,1,0), +(@OGUID+1,194313,603,1,1,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-2592000,255,1,0), +(@OGUID+2,194314,603,2,1,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-2592000,255,1,0), +(@OGUID+3,194315,603,2,1,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-2592000,255,1,0); + +UPDATE `gameobject_loot_template` SET `LootMode`=1 WHERE `Entry`=27074; +DELETE FROM `gameobject_loot_template` WHERE `Entry` IN (26955,26956); +INSERT INTO `gameobject_loot_template` (`Entry`,`Item`,`Reference`,`Chance`,`QuestRequired`,`LootMode`,`GroupId`,`MinCount`,`MaxCount`,`Comment`) VALUES +(26955,1,34372,100,0,1,0,1,1,'Thorim25 HM - normal mode loot'), +(26955,2,12033,100,0,1,0,1,2,'Thorim25 HM - T8.5 tokens'), +(26955,3,34154,10,0,1,0,1,1,'Thorim25 HM - Random Ulduar craft recipe'), +(26955,45038,0,18,0,1,0,1,1,'Thorim25 HM - Val''anyr fragment'), +(26955,45087,0,10,0,1,0,1,1,'Thorim25 HM - Runed Orb'), +(26955,45470,0,0,0,1,1,1,1,'Thorim25 HM - Wisdom''s Hold'), +(26955,45471,0,0,0,1,1,1,1,'Thorim25 HM - Fate''s Clutch'), +(26955,45472,0,0,0,1,1,1,1,'Thorim25 HM - Warhelm of the Champion'), +(26955,45473,0,0,0,1,1,1,1,'Thorim25 HM - Embrace of the Gladiator'), +(26955,45474,0,0,0,1,1,1,1,'Thorim25 HM - Pauldrons of the Combatant'), +(26955,45570,0,0,0,1,1,1,1,'Thorim25 HM - Skyforge Crossbow'), +(26955,45817,0,100,1,1,0,1,1,'Thorim25 HM - Thorim''s Sigil'), +(26955,47241,0,100,0,1,0,1,1,'Thorim25 HM - Emblem of Triumph'), + +(26956,1,34372,100,0,1,0,1,1,'Thorim25 - normal mode loot'), +(26956,2,12033,100,0,1,0,1,2,'Thorim25 - T8.5 tokens'), +(26956,3,34154,10,0,1,0,1,1,'Thorim25 - Random Ulduar craft recipe'), +(26956,45038,0,8,0,1,0,1,1,'Thorim25 - Val''anyr fragment'), +(26956,45087,0,10,0,1,0,1,1,'Thorim25 - Runed Orb'), +(26956,47241,0,100,0,1,0,1,1,'Thorim25 - Emblem of Triumph'); + +-- Pathing for Thorim Event Bunny Entry: 32892 'TDB FORMAT' +SET @PATH := @THORIM_BLIZZARD_BUNNY * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=2148.425,`position_y`=-276.7478,`position_z`=419.5923 WHERE `guid`=@THORIM_BLIZZARD_BUNNY; +DELETE FROM `creature_addon` WHERE `guid`=@THORIM_BLIZZARD_BUNNY; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@THORIM_BLIZZARD_BUNNY,@PATH,0,0,1,0, ''); +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,2148.425,-276.7478,419.5923,0,0,0,0,100,0), +(@PATH,2,2145.229,-278.5732,419.6016,0,0,0,0,100,0), +(@PATH,3,2142.105,-280.7194,419.5932,0,0,0,0,100,0), +(@PATH,4,2138.419,-281.2838,419.5999,0,0,0,0,100,0), +(@PATH,5,2134.843,-281.9885,419.5996,0,0,0,0,100,0), +(@PATH,6,2131.128,-281.278,419.5985,0,0,0,0,100,0), +(@PATH,7,2127.415,-280.8166,419.5875,0,0,0,0,100,0), +(@PATH,8,2124.459,-278.4777,419.6088,0,0,0,0,100,0), +(@PATH,9,2121.098,-276.7148,419.5924,0,0,0,0,100,0), +(@PATH,10,2119.281,-273.4217,419.6069,0,0,0,0,100,0), +(@PATH,11,2116.933,-270.4605,419.5851,0,0,0,0,100,0), +(@PATH,12,2116.359,-266.7142,419.6042,0,0,0,0,100,0), +(@PATH,13,2115.436,-263.0562,419.5847,0,0,0,0,100,0), +(@PATH,14,2116.543,-259.411,419.6082,0,0,0,0,100,0), +(@PATH,15,2116.943,-255.605,419.5851,0,0,0,0,100,0), +(@PATH,16,2119.377,-252.7493,419.6096,0,0,0,0,100,0), +(@PATH,17,2121.183,-249.3546,419.5858,0,0,0,0,100,0), +(@PATH,18,2124.49,-247.5925,419.6089,0,0,0,0,100,0), +(@PATH,19,2127.329,-245.1714,419.5925,0,0,0,0,100,0), +(@PATH,20,2131.097,-244.8609,419.6089,0,0,0,0,100,0), +(@PATH,21,2134.792,-243.7036,419.585,0,0,0,0,100,0), +(@PATH,22,2138.466,-244.3162,419.5979,0,0,0,0,100,0), +(@PATH,23,2142.386,-244.7266,419.5746,0,0,0,0,100,0), +(@PATH,24,2145.455,-247.1502,419.5968,0,0,0,0,100,0), +(@PATH,25,2148.564,-249.0781,419.5791,0,0,0,0,100,0), +(@PATH,26,2150.63,-252.4069,419.598,0,0,0,0,100,0), +(@PATH,27,2153.104,-255.5907,419.5758,0,0,0,0,100,0), +(@PATH,28,2153.286,-259.4698,419.6053,0,0,0,0,100,0), +(@PATH,29,2154.193,-263.0425,419.6039,0,0,0,0,100,0), +(@PATH,30,2153.279,-266.768,419.6026,0,0,0,0,100,0), +(@PATH,31,2152.758,-270.5462,419.5822,0,0,0,0,100,0), +(@PATH,32,2150.38,-273.4614,419.605,0,0,0,0,100,0); diff --git a/sql/updates/world/3.3.5/2017_MM_DD_NN_world_15008.sql b/sql/updates/world/3.3.5/2017_MM_DD_NN_world_15008.sql deleted file mode 100644 index 56d29c4c4e..0000000000 --- a/sql/updates/world/3.3.5/2017_MM_DD_NN_world_15008.sql +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Thorim - */ - --- todo: immunity runic colossus, rune giant grip and knockback - -DELETE FROM `creature_text` WHERE `CreatureID` IN (32865,32872,32873,33196); -INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextID`, `comment`) VALUES --- Thorim -(32865, 0,0,'Interlopers! You mortals who dare to interfere with my sport will pay... Wait--you...',14,0,100,0,0,15733,33145,'Thorim SAY_AGGRO_1'), -(32865, 1,0,'I remember you... In the mountains... But you... what is this? Where am--',14,0,100,0,0,15734,33270,'Thorim SAY_AGGRO_2'), -(32865, 2,0,'Behold the power of the storms and despair!',14,0,100,0,0,15735,0,'Thorim SAY_SPECIAL_1'), -(32865, 3,0,'Do not hold back! Destroy them!',14,0,100,0,0,15736,34241,'Thorim SAY_SPECIAL_2'), -(32865, 4,0,'Have you begun to regret your intrusion?',14,0,100,0,0,15737,0,'Thorim SAY_SPECIAL_3'), -(32865, 5,0,'Impertinent whelps, you dare challenge me atop my pedestal? I will crush you myself!',14,0,100,0,0,15738,33148,'Thorim SAY_JUMPDOWN'), -(32865, 6,0,'Can''t you at least put up a fight!?',14,0,100,0,0,15739,34239,'Thorim SAY_SLAY_1'), -(32865, 6,1,'Pathetic.',14,0,100,0,0,15740,35768,'Thorim SAY_SLAY_2'), -(32865, 7,0,'My patience has reached its limit!',14,0,100,0,0,15741,33365,'Thorim SAY_BERSERK'), -(32865, 8,0,'Failures! Weaklings!',14,0,100,0,0,15742,33274,'Thorim SAY_WIPE'), -(32865, 9,0,'Stay your arms! I yield!',14,0,100,0,0,15743,33948,'Thorim SAY_DEATH'), -(32865,10,0,'I feel as though I am awakening from a nightmare, but the shadows in this place yet linger.',14,0,100,0,0,15744,33949,'Thorim SAY_END_NORMAL_1'), -(32865,11,0,'Sif... was Sif here? Impossible--she died by my brother''s hand. A dark nightmare indeed....',14,0,100,0,0,15745,33950,'Thorim SAY_END_NORMAL_2'), -(32865,12,0,'I need time to reflect.... I will aid your cause if you should require it. I owe you at least that much. Farewell.',14,0,100,0,0,15746,33951,'Thorim SAY_END_NORMAL_3'), -(32865,13,0,'You! Fiend! You are not my beloved! Be gone!',14,0,100,0,0,15747,33952,'Thorim SAY_END_HARD_1'), -(32865,14,0,'Behold the hand behind all the evil that has befallen Ulduar, left my kingdom in ruins, corrupted my brother, and slain my wife.',14,0,100,0,0,15748,33953,'Thorim SAY_END_HARD_2'), -(32865,15,0,'And now it falls to you, champions, to avenge us all. The task before you is great, but I will lend you my aid as I am able. You must prevail.',14,0,100,0,0,15749,33954,'Thorim SAY_END_HARD_3'), --- Runic Colossus -(32872, 0,0,'%s surrounds itself with a crackling Runic Barrier!',41,0,100,0,0,0,33267,'Runic Colossus'), --- Ancient Rune Giant -(32873, 0,0,'%s fortifies nearby allies with runic might!',41,0,100,0,0,0,33523,'Ancient Rune Giant'), --- Sif -(33196, 0,0,'Thorim, my lord! Why else would these invaders have come into your sanctum but to slay you? They must be stopped!',14,0,100,0,0,15668,33325,'Sif - Start'), -(33196, 1,0,'These pathetic mortals are harmless, beneath my station. Dispose of them!',14,0,100,0,0,15669,33368,'Sif - Despawn'), -(33196, 2,0,'Impossible! Lord Thorim, I will bring your foes a frigid death!',14,0,100,0,0,15670,33369,'Sif - Event'); - -UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry`=194265; -DELETE FROM `smart_scripts` WHERE `entryorguid`=194265 AND `source_type`=1; -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`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES -(194265,1,0,0,70,0,100,0,2,0,0,0,9,0,0,0,0,0,0,14,34155,0,0,0,0,0,0, 'Lever - On activate - Activate Dark Iron Portcullis'); - -DELETE FROM `spell_script_names` WHERE `spell_id` IN (62577,62603,62576,62602,62580,62604,62016,62057,62058,62042,62466,64767); -INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES -(62577,'spell_thorim_blizzard'), -(62603,'spell_thorim_blizzard'), -(62576,'spell_thorim_blizzard_effect'), -(62602,'spell_thorim_blizzard_effect'), -(62580,'spell_thorim_frostbolt_volley'), -(62604,'spell_thorim_frostbolt_volley'), -(62016,'spell_thorim_charge_orb'), -(62057,'spell_thorim_runic_smash'), -(62058,'spell_thorim_runic_smash'), -(62042,'spell_thorim_stormhammer'), -(62466,'spell_thorim_lightning_charge'), -(64767,'spell_thorim_stormhammer_sif'); - -DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=62042; - -DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (62131,62315,62316,62333,62334,62335,62327,62328,62321,62331,62332,62583,62577,62597,62580); -INSERT INTO `spelldifficulty_dbc` (`id`, `spellid0`, `spellid1`) VALUES -(62131,62131,64390), -(62315,62315,62415), -(62316,62316,62417), -(62333,62333,62441), -(62334,62334,62442), -(62335,62335,62443), -(62327,62327,62445), -(62328,62328,62446), -(62321,62321,62529), -(62331,62331,62418), -(62332,62332,62420), -(62583,62583,62601), -(62577,62577,62603), -(62597,62597,62605), -(62580,62580,62604); - -UPDATE `creature_template` SET `InhabitType`=4, `flags_extra`=128, `ScriptName`='' WHERE `entry` IN (33140,33141); -UPDATE `creature_template` SET `InhabitType`=4, `flags_extra`=128 WHERE `entry` IN (33054,33378); -UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry` IN (32892); - -DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (62577,62603,62016,62976,63238,64098,62466,62565,62942,64767,62560,61964); -INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES -(13,1,62577,0,0,31,0,3,32892,0,0,0,'','Thorim - Blizzard'), -(13,1,62603,0,0,31,0,3,32892,0,0,0,'','Thorim - Blizzard'), -(13,1,62016,0,0,31,0,3,33378,0,0,0,'','Thorim - Charge Orb'), -(13,1,62976,0,0,31,0,3,33378,0,0,0,'','Thorim - Lightning Pillar'), -(13,1,62976,0,0,33,0,1,0,0,1,0,'','Thorim - Lightning Pillar'), -(13,1,63238,0,0,31,0,3,33378,0,0,0,'','Thorim - Lightning Pillar'), -(13,1,63238,0,0,33,0,1,0,0,1,0,'','Thorim - Lightning Pillar'), -(13,1,64098,0,0,31,0,3,32865,0,0,0,'','Thorim - Lightning Bolt'), -(13,4,62466,0,0,31,0,3,32780,0,0,0,'','Thorim - Lightning Charge'), -(13,3,62565,0,0,31,0,3,32865,0,0,0,'','Thorim - Touch of Dominion'), -(13,7,62942,0,0,31,0,3,32874,0,0,0,'','Thorim - Runic Fortification'), -(13,7,62942,0,1,31,0,3,32875,0,0,0,'','Thorim - Runic Fortification'), -(13,7,62942,0,2,31,0,3,33110,0,0,0,'','Thorim - Runic Fortification'), -(13,1,64767,0,0,31,0,3,33196,0,0,0,'','Thorim - Stormhammer'), -(13,7,62560,0,0,31,0,3,32876,0,0,0,'','Thorim - Berserk'), -(13,7,62560,0,1,31,0,3,32877,0,0,0,'','Thorim - Berserk'), -(13,7,62560,0,2,31,0,3,32878,0,0,0,'','Thorim - Berserk'), -(13,7,62560,0,3,31,0,3,32904,0,0,0,'','Thorim - Berserk'), -(13,1,61964,0,0,31,0,3,32882,0,0,0,'','Thorim - Circle of Healing'), -(13,1,61964,0,1,31,0,3,32883,0,0,0,'','Thorim - Circle of Healing'), -(13,1,61964,0,2,31,0,3,32885,0,0,0,'','Thorim - Circle of Healing'), -(13,1,61964,0,3,31,0,3,32886,0,0,0,'','Thorim - Circle of Healing'), -(13,1,61964,0,4,31,0,3,32907,0,0,0,'','Thorim - Circle of Healing'), -(13,1,61964,0,5,31,0,3,32908,0,0,0,'','Thorim - Circle of Healing'); - -DELETE FROM `disables` WHERE `sourceType`=4 AND `entry` IN (10289,10314,10304,10313,10440,10457,10800,10801); -INSERT INTO `disables` (`sourceType`,`entry`,`flags`,`params_0`,`params_1`,`comment`) VALUES -(4,10800,0,0,0,'Siffed (10 player) - Duplicate'), -(4,10801,0,0,0,'Siffed (25 player) - Duplicate'); - -DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (10289,10314,10305,10309,10440,10457); -INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES -(10289,12,0,0,''), -- Siffed (10 player) -(10314,12,1,0,''), -- Siffed (25 player) - -(10305,11,0,0,'achievement_dont_stand_in_the_lightning'), -- Don't Stand in the Lightning (10 player) -(10305,12,0,0,''), -- Don't Stand in the Lightning (10 player) -(10309,11,0,0,'achievement_dont_stand_in_the_lightning'), -- Don't Stand in the Lightning (25 player) -(10309,12,1,0,''), -- Don't Stand in the Lightning (25 player) - -(10440,11,0,0,'achievement_lose_your_illusion'), -- Lose Your Illusion (10 player) -(10440,12,0,0,''), -- Lose Your Illusion (10 player) -(10457,11,0,0,'achievement_lose_your_illusion'), -- Lose Your Illusion (25 player) -(10457,12,1,0,''); -- Lose Your Illusion (25 player) - -UPDATE `gameobject_template` SET `size`=3 WHERE `entry` IN (194312,194313,194314,194315); -UPDATE `gameobject_template_addon` SET `faction`=94 WHERE `entry` IN (194312,194313,194314,194315); - -DELETE FROM `gameobject` WHERE `id` IN (194312,194313,194314,194315); -INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`) values -(360300,194312,603,1,1,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-604800,255,1,0), -(360301,194313,603,1,1,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-604800,255,1,0), -(360302,194314,603,2,1,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-604800,255,1,0), -(360303,194315,603,2,1,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-604800,255,1,0); - -DELETE FROM `creature` WHERE `id`=32892 AND `position_z` < 425.0; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp index f65aa2d676..18ccf16be8 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp @@ -20,12 +20,16 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "TypeContainerVisitor.h" +#include "CellImpl.h" +#include "GridNotifiersImpl.h" #include "ulduar.h" enum Spells { // Thorim - SPELL_SHEAT_OF_LIGHTNING = 62276, + SPELL_SHEATH_OF_LIGHTNING = 62276, SPELL_STORMHAMMER = 62042, SPELL_STORMHAMMER_SIF = 64767, SPELL_STORMHAMMER_BOOMERANG = 64909, @@ -43,7 +47,8 @@ enum Spells SPELL_LIGHTNING_PILLAR_1 = 63238, // caster high position, target low position SPELL_UNBALANCING_STRIKE = 62130, SPELL_BERSERK_PHASE_1 = 62560, - SPELL_BERSERK_PHASE_2 = 26662, + SPELL_BERSERK_PHASE_2 = 62555, + SPELL_ACTIVATE_LIGHTNING_ORB_PERIODIC = 62184, // Credits SPELL_CREDIT_SIFFED = 64980, @@ -95,10 +100,9 @@ enum Events EVENT_JUMPDOWN, EVENT_UNBALANCING_STRIKE, EVENT_CHAIN_LIGHTNING, - EVENT_TRANSFER_ENERGY, - EVENT_RELEASE_ENERGY, - EVENT_ACTIVATE_LIGHNING_FIELD, - EVENT_CHECK_PLAYER, + EVENT_START_PERIODIC_CHARGE, + EVENT_LIGHTNING_CHARGE, + EVENT_ACTIVATE_LIGHTNING_FIELD, EVENT_OUTRO_1, EVENT_OUTRO_2, EVENT_OUTRO_3, @@ -133,20 +137,18 @@ enum Yells // Thorim SAY_AGGRO_1 = 0, SAY_AGGRO_2 = 1, - //SAY_SPECIAL_1 = 2, - SAY_SPECIAL_2 = 3, - //SAY_SPECIAL_3 = 4, - SAY_JUMPDOWN = 5, - SAY_SLAY = 6, - SAY_BERSERK = 7, - SAY_WIPE = 8, - SAY_DEATH = 9, - SAY_END_NORMAL_1 = 10, - SAY_END_NORMAL_2 = 11, - SAY_END_NORMAL_3 = 12, - SAY_END_HARD_1 = 13, - SAY_END_HARD_2 = 14, - SAY_END_HARD_3 = 15, + SAY_SPECIAL = 2, + SAY_JUMPDOWN = 3, + SAY_SLAY = 4, + SAY_BERSERK = 5, + SAY_WIPE = 6, + SAY_DEATH = 7, + SAY_END_NORMAL_1 = 8, + SAY_END_NORMAL_2 = 9, + SAY_END_NORMAL_3 = 10, + SAY_END_HARD_1 = 11, + SAY_END_HARD_2 = 12, + SAY_END_HARD_3 = 13, // Runic Colossus EMOTE_RUNIC_BARRIER = 0, @@ -160,27 +162,6 @@ enum Yells SAY_SIF_EVENT = 2 }; -enum TrashTypes -{ - // Pre Phase Trash - BEHEMOTH, - MERCENARY_CAPTAIN, - MERCENARY_SOLDIER, - - // Arena Phase Trash - DARK_RUNE_CHAMPION, - DARK_RUNE_WARBRINGER, - DARK_RUNE_COMMONER, - DARK_RUNE_EVOKER, - - // Hall Way Trash - IRON_RING_GUARD, - IRON_HONOR_GUARD, - - // Shared - DARK_RUNE_ACOLYTE -}; - enum PreAddSpells { SPELL_ACID_BREATH = 62315, @@ -199,6 +180,8 @@ enum PreAddSpells SPELL_HOLY_SMITE = 62335, + SPELL_LEAP = 61934, + SPELL_CHARGE = 32323, SPELL_MORTAL_STRIKE = 35054, SPELL_WHIRLWIND = 33500, @@ -221,6 +204,27 @@ enum PreAddSpells SPELL_SHIELD_SMASH = 62332, }; +enum TrashTypes +{ + // Pre Phase Trash + BEHEMOTH, + MERCENARY_CAPTAIN, + MERCENARY_SOLDIER, + + // Arena Phase Trash + DARK_RUNE_CHAMPION, + DARK_RUNE_WARBRINGER, + DARK_RUNE_COMMONER, + DARK_RUNE_EVOKER, + + // Hall Way Trash + IRON_RING_GUARD, + IRON_HONOR_GUARD, + + // Shared + DARK_RUNE_ACOLYTE +}; + struct ThorimTrashInfo { uint32 Type; @@ -230,40 +234,39 @@ struct ThorimTrashInfo uint32 ThirdAbility; }; -ThorimTrashInfo const StaticThorimTrashInfo[] = +uint8 const ThorimTrashCount = 13; +ThorimTrashInfo const StaticThorimTrashInfo[ThorimTrashCount] = { // Pre Phase - { BEHEMOTH, 32882, SPELL_ACID_BREATH, SPELL_SWEEP, 0 }, - { MERCENARY_CAPTAIN, 32908, SPELL_DEVASTATE, SPELL_HEROIC_SWIPE, SPELL_SUNDER_ARMOR }, // alliance? - { MERCENARY_SOLDIER, 32885, SPELL_BARBED_SHOT, SPELL_SHOOT, 0 }, // alliance? - { DARK_RUNE_ACOLYTE, 32886, SPELL_RENEW, SPELL_GREATER_HEAL, SPELL_CIRCLE_OF_HEALING }, - { MERCENARY_CAPTAIN, 32907, SPELL_DEVASTATE, SPELL_HEROIC_SWIPE, SPELL_SUNDER_ARMOR }, // horde? - { MERCENARY_SOLDIER, 32883, SPELL_BARBED_SHOT, SPELL_SHOOT, 0 }, // horde? + { BEHEMOTH, NPC_JORMUNGAR_BEHEMOTH, SPELL_ACID_BREATH, SPELL_SWEEP, 0 }, + { MERCENARY_CAPTAIN, NPC_MERCENARY_CAPTAIN_A, SPELL_DEVASTATE, SPELL_HEROIC_SWIPE, SPELL_SUNDER_ARMOR }, + { MERCENARY_SOLDIER, NPC_MERCENARY_SOLDIER_A, SPELL_BARBED_SHOT, SPELL_SHOOT, 0 }, + { DARK_RUNE_ACOLYTE, NPC_DARK_RUNE_ACOLYTE_PRE, SPELL_RENEW, SPELL_GREATER_HEAL, SPELL_CIRCLE_OF_HEALING }, + { MERCENARY_CAPTAIN, NPC_MERCENARY_CAPTAIN_H, SPELL_DEVASTATE, SPELL_HEROIC_SWIPE, SPELL_SUNDER_ARMOR }, + { MERCENARY_SOLDIER, NPC_MERCENARY_SOLDIER_H, SPELL_BARBED_SHOT, SPELL_SHOOT, 0 }, // Arena Phase - { DARK_RUNE_CHAMPION, NPC_DARK_RUNE_CHAMPION, SPELL_MORTAL_STRIKE, SPELL_WHIRLWIND, 0 }, - { DARK_RUNE_WARBRINGER, NPC_DARK_RUNE_WARBRINGER, SPELL_RUNIC_STRIKE, 0, 0 }, - { DARK_RUNE_EVOKER, NPC_DARK_RUNE_EVOKER, SPELL_RUNIC_LIGHTNING, SPELL_RUNIC_SHIELD, SPELL_RUNIC_MENDING }, - { DARK_RUNE_COMMONER, NPC_DARK_RUNE_COMMONER, SPELL_LOW_BLOW, SPELL_PUMMEL, 0 }, + { DARK_RUNE_CHAMPION, NPC_DARK_RUNE_CHAMPION, SPELL_MORTAL_STRIKE, SPELL_WHIRLWIND, 0 }, + { DARK_RUNE_WARBRINGER, NPC_DARK_RUNE_WARBRINGER, SPELL_RUNIC_STRIKE, 0, 0 }, + { DARK_RUNE_EVOKER, NPC_DARK_RUNE_EVOKER, SPELL_RUNIC_LIGHTNING, SPELL_RUNIC_SHIELD, SPELL_RUNIC_MENDING }, + { DARK_RUNE_COMMONER, NPC_DARK_RUNE_COMMONER, SPELL_LOW_BLOW, SPELL_PUMMEL, 0 }, // Hall Way - { IRON_RING_GUARD, NPC_IRON_RING_GUARD, SPELL_WHIRLING_TRIP, SPELL_IMPALE, 0 }, - { IRON_HONOR_GUARD, NPC_IRON_HONOR_GUARD, SPELL_CLEAVE, SPELL_SHIELD_SMASH, 0 }, - { DARK_RUNE_ACOLYTE, NPC_DARK_RUNE_ACOLYTE, SPELL_RENEW, SPELL_GREATER_HEAL, 0 }, + { IRON_RING_GUARD, NPC_IRON_RING_GUARD, SPELL_WHIRLING_TRIP, SPELL_IMPALE, 0 }, + { IRON_HONOR_GUARD, NPC_IRON_HONOR_GUARD, SPELL_CLEAVE, SPELL_SHIELD_SMASH, 0 }, + { DARK_RUNE_ACOLYTE, NPC_DARK_RUNE_ACOLYTE, SPELL_RENEW, SPELL_GREATER_HEAL, 0 } }; enum Actions { ACTION_INCREASE_PREADDS_COUNT, ACTION_ACTIVATE_RUNIC_SMASH, + ACTION_ACTIVATE_ADDS, + ACTION_PILLAR_CHARGED, ACTION_START_HARD_MODE, - ACTION_BERSERK, + ACTION_BERSERK }; -#define MAX_HARD_MODE_TIME 180000 // 3 Minutes - -#define IN_ARENA(who) (who->GetPositionX() < 2181.19f && who->GetPositionY() > -299.12f) - struct SummonLocation { Position pos; @@ -272,12 +275,12 @@ struct SummonLocation SummonLocation const PreAddLocations[] = { - { { 2149.68f, -263.477f, 419.679f, 3.120f }, 32882}, - { { 2131.31f, -271.640f, 419.840f, 2.188f }, 32908}, - { { 2127.24f, -259.182f, 419.974f, 5.917f }, 32885}, - { { 2123.32f, -254.770f, 419.840f, 6.170f }, 32885}, - { { 2120.10f, -258.990f, 419.840f, 6.250f }, 32885}, - { { 2129.09f, -277.142f, 419.756f, 1.222f }, 32886} + { { 2149.68f, -263.477f, 419.679f, 3.120f }, NPC_JORMUNGAR_BEHEMOTH }, + { { 2131.31f, -271.640f, 419.840f, 2.188f }, NPC_MERCENARY_CAPTAIN_A }, + { { 2127.24f, -259.182f, 419.974f, 5.917f }, NPC_MERCENARY_SOLDIER_A }, + { { 2123.32f, -254.770f, 419.840f, 6.170f }, NPC_MERCENARY_SOLDIER_A }, + { { 2120.10f, -258.990f, 419.840f, 6.250f }, NPC_MERCENARY_SOLDIER_A }, + { { 2129.09f, -277.142f, 419.756f, 1.222f }, NPC_DARK_RUNE_ACOLYTE_PRE } }; SummonLocation const ColossusAddLocations[] = @@ -301,11 +304,19 @@ SummonLocation const GiantAddLocations[] = Position const SifSpawnPosition = { 2148.301f, -297.8453f, 438.3308f, 2.687807f }; -enum Achievements +enum Data { ACHIEVEMENT_DONT_STAND_IN_THE_LIGHTNING = 29712972, ACHIEVEMENT_SIFFED = 29772978, ACHIEVEMENT_LOSE_YOUR_ILLUSION = 31763183, + DATA_CHARGED_PILLAR = 1, + + FACTION_FRIENDLY = 35 +}; + +enum DisplayIds +{ + THORIM_WEAPON_DISPLAY_ID = 45900 }; uint32 const LightningOrbPathSize = 8; @@ -321,10 +332,37 @@ G3D::Vector3 const LightningOrbPath[LightningOrbPathSize] = { 2182.310059f, -263.233093f, 414.739410f } }; -Position const ArenaCenter = { 2135.0f, -263.0f, 420.0f, 0.0f }; // used for trash jump calculation -Position const LightningFieldCenter = { 2135.0f, -312.5f, 438.0f, 0.0f }; // used for lightning field calculation +// used for trash jump calculation +Position const ArenaCenter = { 2134.77f, -262.307f }; -// p2 start at 5357 +// used for lightning field calculation +Position const LightningFieldCenter = { 2135.178f, -321.122f }; + +CircleBoundary const ArenaFloorCircle(ArenaCenter, 45.4); +CircleBoundary const InvertedBalconyCircle(LightningFieldCenter, 32.0, true); + +CreatureBoundary const ArenaBoundaries = +{ + &ArenaFloorCircle, + &InvertedBalconyCircle +}; + +class HeightPositionCheck +{ + public: + HeightPositionCheck(bool ret) : _ret(ret) { } + + bool operator()(Position const* pos) const + { + return pos->GetPositionZ() > THORIM_BALCONY_Z_CHECK == _ret; + } + + private: + bool _ret; + + static float const THORIM_BALCONY_Z_CHECK; +}; +float const HeightPositionCheck::THORIM_BALCONY_Z_CHECK = 428.0f; class RunicSmashExplosionEvent : public BasicEvent { @@ -333,7 +371,7 @@ class RunicSmashExplosionEvent : public BasicEvent bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override { - _owner->CastSpell((Unit*)NULL, SPELL_RUNIC_SMASH); + _owner->CastSpell((Unit*)nullptr, SPELL_RUNIC_SMASH); return true; } @@ -346,22 +384,19 @@ class TrashJumpEvent : public BasicEvent public: TrashJumpEvent(Creature* owner) : _owner(owner), _stage(0) { } - bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override + bool Execute(uint64 eventTime, uint32 /*updateTime*/) override { switch (_stage) { case 0: - if (Creature* stalker = _owner->FindNearestCreature(NPC_THORIM_INVISIBLE_STALKER, 30.0f)) - { - _owner->GetMotionMaster()->MoveJump(*stalker, SPEED_CHARGE, 15.0f); - _owner->SetHomePosition(*stalker); - } + _owner->CastSpell((Unit*)nullptr, SPELL_LEAP); ++_stage; - _owner->m_Events.AddEvent(this, _owner->m_Events.CalculateTime(2000)); + _owner->m_Events.AddEvent(this, eventTime + 2000); return false; case 1: _owner->SetReactState(REACT_AGGRESSIVE); - _owner->AI()->DoZoneInCombat(_owner, 200.0f); + _owner->AI()->DoZoneInCombat(_owner); + _owner->AI()->SetBoundary(&ArenaBoundaries); return true; default: break; @@ -380,14 +415,14 @@ class LightningFieldEvent : public BasicEvent public: LightningFieldEvent(Creature* owner) : _owner(owner) { } - bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override + bool Execute(uint64 eventTime, uint32 /*updateTime*/) override { if (InstanceScript* instance = _owner->GetInstanceScript()) { if (instance->GetBossState(BOSS_THORIM) == IN_PROGRESS) { - _owner->CastSpell((Unit*)NULL, SPELL_LIGHTNING_FIELD); - _owner->m_Events.AddEvent(this, _owner->m_Events.CalculateTime(1000)); + _owner->CastSpell((Unit*)nullptr, SPELL_LIGHTNING_FIELD); + _owner->m_Events.AddEvent(this, eventTime + 1000); return false; } } @@ -428,11 +463,13 @@ class boss_thorim : public CreatureScript if (_encounterFinished) return; + SetBoundary(nullptr); _Reset(); Initialize(); me->SetReactState(REACT_PASSIVE); - SetCombatMovement(false); + me->SetDisableGravity(true); + me->SetControlled(true, UNIT_STATE_ROOT); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); events.SetPhase(PHASE_NULL); @@ -446,8 +483,38 @@ class boss_thorim : public CreatureScript for (SummonLocation const& s : PreAddLocations) me->SummonCreature(s.entry, s.pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000); - if (GameObject* go = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_THORIM_LEVER))) - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + if (GameObject* lever = instance->GetGameObject(DATA_THORIM_LEVER)) + lever->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + + // Remove trigger auras + if (Creature* pillar = ObjectAccessor::GetCreature(*me, _activePillarGUID)) + pillar->RemoveAllAuras(); + + if (Creature* controller = instance->GetCreature(DATA_THORIM_CONTROLLER)) + controller->RemoveAllAuras(); + + _activePillarGUID.Clear(); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + summons.DespawnAll(); + _DespawnAtEvade(); + } + + void SetGUID(ObjectGuid guid, int32 type) override + { + if (type == DATA_CHARGED_PILLAR) + { + _activePillarGUID = guid; + + if (Creature* pillar = ObjectAccessor::GetCreature(*me, _activePillarGUID)) + { + pillar->CastSpell(pillar, SPELL_LIGHTNING_ORB_CHARGED, true); + pillar->CastSpell((Unit*)nullptr, SPELL_LIGHTNING_PILLAR_2); + events.ScheduleEvent(EVENT_LIGHTNING_CHARGE, 8000, 0, PHASE_2); + } + } } uint32 GetData(uint32 type) const override @@ -476,7 +543,7 @@ class boss_thorim : public CreatureScript { if (spellInfo->Id == SPELL_TOUCH_OF_DOMINION_TRIGGERED) { - if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + if (Creature* sif = instance->GetCreature(DATA_SIF)) { sif->AI()->Talk(SAY_SIF_DESPAWN); sif->DespawnOrUnsummon(6000); @@ -504,12 +571,21 @@ class boss_thorim : public CreatureScript me->InterruptNonMeleeSpells(true); me->RemoveAllAttackers(); me->AttackStop(); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_RENAME); - if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + if (Creature* controller = instance->GetCreature(DATA_THORIM_CONTROLLER)) + controller->RemoveAllAuras(); + if (Creature* pillar = ObjectAccessor::GetCreature(*me, _activePillarGUID)) + pillar->RemoveAllAuras(); + + if (_hardMode) { - summons.Despawn(sif); - sif->DespawnOrUnsummon(10000); + if (Creature* sif = instance->GetCreature(DATA_SIF)) + { + summons.Despawn(sif); + sif->DespawnOrUnsummon(10000); + } } _JustDied(); @@ -522,6 +598,15 @@ class boss_thorim : public CreatureScript me->m_Events.AddEvent(new KeeperDespawnEvent(me), me->m_Events.CalculateTime(35000)); } + void MovementInform(uint32 type, uint32 id) override + { + if (type != EFFECT_MOTION_TYPE || id != EVENT_JUMP) + return; + + me->getThreatManager().resetAllAggro(); + SetBoundary(&ArenaBoundaries); + } + void EnterCombat(Unit* /*who*/) override { _EnterCombat(); @@ -531,21 +616,23 @@ class boss_thorim : public CreatureScript events.ScheduleEvent(EVENT_SAY_AGGRO_2, 9000, 0, PHASE_1); events.ScheduleEvent(EVENT_SAY_SIF_START, 16500, 0, PHASE_1); - events.ScheduleEvent(EVENT_START_SIF_CHANNEL, 25000, 0, PHASE_1); + events.ScheduleEvent(EVENT_START_SIF_CHANNEL, 22500, 0, PHASE_1); events.ScheduleEvent(EVENT_STORMHAMMER, 40000, 0, PHASE_1); events.ScheduleEvent(EVENT_CHARGE_ORB, 30000, 0, PHASE_1); events.ScheduleEvent(EVENT_SUMMON_ADDS, 15000, 0, PHASE_1); events.ScheduleEvent(EVENT_BERSERK, 369000); - events.ScheduleEvent(EVENT_CHECK_PLAYER, 10000); - DoCast(me, SPELL_SHEAT_OF_LIGHTNING); + DoCast(me, SPELL_SHEATH_OF_LIGHTNING); - if (Creature* runic = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RUNIC_COLOSSUS))) - runic->AI()->DoAction(ACTION_ACTIVATE_RUNIC_SMASH); + if (Creature* runicColossus = instance->GetCreature(DATA_RUNIC_COLOSSUS)) + { + runicColossus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + runicColossus->AI()->DoAction(ACTION_ACTIVATE_ADDS); + } - if (GameObject* go = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_THORIM_LEVER))) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + if (GameObject* lever = instance->GetGameObject(DATA_THORIM_LEVER)) + lever->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); // Summon Sif me->SummonCreature(NPC_SIF, SifSpawnPosition); @@ -560,8 +647,7 @@ class boss_thorim : public CreatureScript summon->SetReactState(REACT_PASSIVE); summon->CastSpell(summon, SPELL_LIGHTNING_DESTRUCTION, true); - Position pos(LightningOrbPath[LightningOrbPathSize - 1].x, LightningOrbPath[LightningOrbPathSize - 1].y, LightningOrbPath[LightningOrbPathSize - 1].z); - summon->GetMotionMaster()->MovePoint(EVENT_CHARGE_PREPATH, pos, false); + summon->GetMotionMaster()->MovePoint(EVENT_CHARGE_PREPATH, LightningOrbPath[LightningOrbPathSize - 1], false); Movement::PointsArray path(LightningOrbPath, LightningOrbPath + LightningOrbPathSize); @@ -605,68 +691,52 @@ class boss_thorim : public CreatureScript Talk(SAY_AGGRO_2); break; case EVENT_SAY_SIF_START: - if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + if (Creature* sif = instance->GetCreature(DATA_SIF)) sif->AI()->Talk(SAY_SIF_START); break; case EVENT_START_SIF_CHANNEL: - if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + if (Creature* sif = instance->GetCreature(DATA_SIF)) sif->CastSpell(me, SPELL_TOUCH_OF_DOMINION); break; case EVENT_STORMHAMMER: DoCast(SPELL_STORMHAMMER); - events.ScheduleEvent(EVENT_STORMHAMMER, urand(15000, 20000), 0, PHASE_1); + events.Repeat(15000, 20000); break; case EVENT_CHARGE_ORB: DoCastAOE(SPELL_CHARGE_ORB); - events.ScheduleEvent(EVENT_CHARGE_ORB, urand(15000, 20000), 0, PHASE_1); + events.Repeat(15000, 20000); break; case EVENT_SUMMON_ADDS: SummonWave(); - events.ScheduleEvent(EVENT_SUMMON_ADDS, _orbSummoned ? 3000 : 10000, 0, PHASE_1); + events.Repeat(_orbSummoned ? 3000 : 10000); break; case EVENT_JUMPDOWN: if (_hardMode) - if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + if (Creature* sif = instance->GetCreature(DATA_SIF)) sif->AI()->DoAction(ACTION_START_HARD_MODE); - me->RemoveAurasDueToSpell(SPELL_SHEAT_OF_LIGHTNING); + me->RemoveAurasDueToSpell(SPELL_SHEATH_OF_LIGHTNING); me->SetReactState(REACT_AGGRESSIVE); - SetCombatMovement(true); - me->GetMotionMaster()->MoveJump(2134.79f, -263.03f, 419.84f, me->GetOrientation(), 30.0f, 20.0f); + me->SetDisableGravity(false); + me->SetControlled(false, UNIT_STATE_ROOT); + me->GetMotionMaster()->MoveJump(2134.8f, -263.056f, 419.983f, me->GetOrientation(), 30.0f, 20.0f); + events.ScheduleEvent(EVENT_START_PERIODIC_CHARGE, 2000, 0, PHASE_2); events.ScheduleEvent(EVENT_UNBALANCING_STRIKE, 15000, 0, PHASE_2); events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 20000, 0, PHASE_2); - events.ScheduleEvent(EVENT_TRANSFER_ENERGY, 20000, 0, PHASE_2); break; case EVENT_UNBALANCING_STRIKE: DoCastVictim(SPELL_UNBALANCING_STRIKE); - events.ScheduleEvent(EVENT_UNBALANCING_STRIKE, urand(15000, 20000), 0, PHASE_2); + events.Repeat(15000, 20000); break; case EVENT_CHAIN_LIGHTNING: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) DoCast(target, SPELL_CHAIN_LIGHTNING); - events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, urand(7000, 15000), 0, PHASE_2); + events.Repeat(7000, 15000); break; - case EVENT_TRANSFER_ENERGY: - { - std::list triggers; - me->GetCreatureListWithEntryInGrid(triggers, NPC_THUNDER_ORB, 200.0f); - triggers.remove_if([](Creature* trigger) - { - return trigger->GetPositionZ() < 425.0f; - }); - - if (!triggers.empty()) - { - Creature* pillar = Trinity::Containers::SelectRandomContainerElement(triggers); - _activePillarGUID = pillar->GetGUID(); - pillar->CastSpell(pillar, SPELL_LIGHTNING_ORB_CHARGED, true); - pillar->CastSpell((Unit*)nullptr, SPELL_LIGHTNING_PILLAR_2); - events.ScheduleEvent(EVENT_RELEASE_ENERGY, 8000, 0, PHASE_2); - } - - events.ScheduleEvent(EVENT_TRANSFER_ENERGY, 16000, 0, PHASE_2); + case EVENT_START_PERIODIC_CHARGE: + if (Creature* controller = instance->GetCreature(DATA_THORIM_CONTROLLER)) + controller->CastSpell(controller, SPELL_ACTIVATE_LIGHTNING_ORB_PERIODIC, true); break; - } - case EVENT_RELEASE_ENERGY: + case EVENT_LIGHTNING_CHARGE: if (Creature* pillar = ObjectAccessor::GetCreature(*me, _activePillarGUID)) DoCast(pillar, SPELL_LIGHTNING_RELEASE); break; @@ -683,15 +753,15 @@ class boss_thorim : public CreatureScript DoCast(me, SPELL_BERSERK_PHASE_2, true); } break; - case EVENT_ACTIVATE_LIGHNING_FIELD: + case EVENT_ACTIVATE_LIGHTNING_FIELD: { std::list triggers; me->GetCreatureListWithEntryInGrid(triggers, NPC_THORIM_EVENT_BUNNY, 100.0f); triggers.remove_if([](Creature* bunny) { - if (bunny->GetPositionZ() < 430.0f) + if (HeightPositionCheck(false)(bunny)) return true; - return LightningFieldCenter.GetExactDist2dSq(bunny) > 1225.0f; + return LightningFieldCenter.GetExactDist2dSq(bunny) > 1296.0f; }); uint64 timer = 1000; @@ -700,7 +770,7 @@ class boss_thorim : public CreatureScript triggers.remove_if([](Creature* bunny) { - return LightningFieldCenter.GetExactDist2dSq(bunny) < 400.0f; + return LightningFieldCenter.GetExactDist2dSq(bunny) < 576.0f; }); triggers.sort([](Creature* a, Creature* b) @@ -708,26 +778,24 @@ class boss_thorim : public CreatureScript return a->GetPositionX() < b->GetPositionX(); }); - for (std::list::const_iterator itr = triggers.begin(); itr != triggers.end();) + for (auto itr = triggers.cbegin(); itr != triggers.cend();) { - std::list::const_iterator prev = itr++; + auto prev = itr++; if (itr != triggers.end()) (*prev)->CastSpell(*itr, SPELL_LIGHTNING_BEAM_CHANNEL); } break; } - case EVENT_CHECK_PLAYER: - if (!me->GetMap()->GetPlayersCountExceptGMs()) - EnterEvadeMode(); - events.ScheduleEvent(EVENT_CHECK_PLAYER, 10000); - break; case EVENT_OUTRO_1: Talk(_hardMode ? SAY_END_HARD_1 : SAY_END_NORMAL_1); - if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) - DoCast(sif, SPELL_STORMHAMMER_SIF); + if (_hardMode) + DoCast(me, SPELL_STORMHAMMER_SIF); break; case EVENT_OUTRO_2: Talk(_hardMode ? SAY_END_HARD_2 : SAY_END_NORMAL_2); + if (_hardMode) + if (Creature* sif = instance->GetCreature(DATA_SIF)) + sif->SetStandState(UNIT_STAND_STATE_DEAD); break; case EVENT_OUTRO_3: Talk(_hardMode ? SAY_END_HARD_3 : SAY_END_NORMAL_3); @@ -735,6 +803,9 @@ class boss_thorim : public CreatureScript default: break; } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } DoMeleeAttackIfReady(); @@ -759,7 +830,7 @@ class boss_thorim : public CreatureScript { // Event starts me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - DoZoneInCombat(me, 250.0f); + DoZoneInCombat(me); } break; default: @@ -772,7 +843,7 @@ class boss_thorim : public CreatureScript me->GetCreatureListWithEntryInGrid(triggerList, NPC_THORIM_EVENT_BUNNY, 100.0f); triggerList.remove_if([](Creature* bunny) { - if (bunny->GetPositionZ() < 430.0f) + if (HeightPositionCheck(false)(bunny)) return true; return ArenaCenter.GetExactDist2dSq(bunny) < 3025.0f; }); @@ -835,8 +906,8 @@ class boss_thorim : public CreatureScript if (actor->GetTypeId() != TYPEID_PLAYER || !me->IsWithinDistInMap(actor, 10.0f)) return false; - Creature* runicColossus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RUNIC_COLOSSUS)); - Creature* runeGiant = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RUNE_GIANT)); + Creature* runicColossus = instance->GetCreature(DATA_RUNIC_COLOSSUS); + Creature* runeGiant = instance->GetCreature(DATA_RUNE_GIANT); return runicColossus && !runicColossus->IsAlive() && runeGiant && !runeGiant->IsAlive(); } @@ -847,14 +918,14 @@ class boss_thorim : public CreatureScript Talk(SAY_JUMPDOWN); events.SetPhase(PHASE_2); events.ScheduleEvent(EVENT_JUMPDOWN, 8000); - events.ScheduleEvent(EVENT_ACTIVATE_LIGHNING_FIELD, 15000); + events.ScheduleEvent(EVENT_ACTIVATE_LIGHTNING_FIELD, 15000); events.RescheduleEvent(EVENT_BERSERK, 300000, 0, PHASE_2); - if (Creature* sif = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_SIF))) + if (Creature* sif = instance->GetCreature(DATA_SIF)) sif->InterruptNonMeleeSpells(false); // Hard Mode - if (_hardMode && events.GetTimer() <= MAX_HARD_MODE_TIME) + if (_hardMode) DoCastAOE(SPELL_CREDIT_SIFFED, true); } else if (me->HealthBelowPctDamaged(1, damage)) @@ -885,7 +956,7 @@ struct npc_thorim_trashAI : public ScriptedAI npc_thorim_trashAI(Creature* creature) : ScriptedAI(creature) { _instance = creature->GetInstanceScript(); - for (uint8 i = 0; i < 13; ++i) + for (uint8 i = 0; i < ThorimTrashCount; ++i) if (me->GetEntry() == StaticThorimTrashInfo[i].Entry) _info = &StaticThorimTrashInfo[i]; @@ -909,32 +980,14 @@ struct npc_thorim_trashAI : public ScriptedAI return heal; } - /// returns heal amount of the given spell including hots - static uint32 GetTotalHeal(uint32 spellId, Unit const* caster) - { - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) - return GetTotalHeal(spellInfo, caster); - return 0; - } - /// returns remaining heal amount on given target static uint32 GetRemainingHealOn(Unit* target) { uint32 heal = 0; - Unit::AuraApplicationMap const& auras = target->GetAppliedAuras(); - for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) - { - Aura const* aura = itr->second->GetBase(); + Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL); + for (AuraEffect const* aurEff : auras) + heal += aurEff->GetAmount() * (aurEff->GetTotalTicks() - aurEff->GetTickNumber()); - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (AuraEffect const* aurEff = aura->GetEffect(i)) - { - if (aurEff->GetAuraType() == SPELL_AURA_PERIODIC_HEAL) - heal += aurEff->GetAmount() * (aurEff->GetTotalTicks() - aurEff->GetTickNumber()); - } - } - } return heal; } @@ -975,8 +1028,9 @@ struct npc_thorim_trashAI : public ScriptedAI static Unit* GetUnitWithMostMissingHp(SpellInfo const* spellInfo, Unit* caster) { - float range = spellInfo->GetMaxRange(false); - uint32 heal = GetTotalHeal(spellInfo, caster); + // use positive range, it's a healing spell + float const range = spellInfo->GetMaxRange(true); + uint32 const heal = GetTotalHeal(spellInfo, caster); Unit* target = nullptr; MostHPMissingInRange checker(caster, range, heal); @@ -986,17 +1040,13 @@ struct npc_thorim_trashAI : public ScriptedAI return target; } - static Unit* GetHealTarget(uint32 spellId, Unit* caster) + static Unit* GetHealTarget(SpellInfo const* spellInfo, Unit* caster) { Unit* healTarget = nullptr; - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) - { - if (!spellInfo->HasAttribute(SPELL_ATTR1_CANT_TARGET_SELF) && !roll_chance_f(caster->GetHealthPct()) && !((caster->GetHealth() + GetRemainingHealOn(caster) + GetTotalHeal(spellInfo, caster)) > caster->GetMaxHealth())) - healTarget = caster; - else - healTarget = GetUnitWithMostMissingHp(spellInfo, caster); - } + if (!spellInfo->HasAttribute(SPELL_ATTR1_CANT_TARGET_SELF) && !roll_chance_f(caster->GetHealthPct()) && ((caster->GetHealth() + GetRemainingHealOn(caster) + GetTotalHeal(spellInfo, caster)) <= caster->GetMaxHealth())) + healTarget = caster; + else + healTarget = GetUnitWithMostMissingHp(spellInfo, caster); return healTarget; } @@ -1004,34 +1054,43 @@ struct npc_thorim_trashAI : public ScriptedAI bool UseAbility(uint32 spellId) { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!spellInfo) + return false; + Unit* target = nullptr; - if (AIHelper::GetTotalHeal(spellId, me)) - target = AIHelper::GetHealTarget(spellId, me); + if (AIHelper::GetTotalHeal(spellInfo, me)) + target = AIHelper::GetHealTarget(spellInfo, me); else target = me->GetVictim(); - if (target) - { - if (_info->Type == MERCENARY_SOLDIER) - { - bool allowMove = true; - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) - { - if (me->IsInRange(target, spellInfo->GetMinRange(false), spellInfo->GetMaxRange(false)) - && me->IsWithinLOSInMap(target)) - allowMove = false; - } - SetCombatMovement(allowMove); - } + if (!target) + return false; - DoCast(target, spellId); - return true; + if (_info->Type == MERCENARY_SOLDIER) + { + bool allowMove = true; + if (me->IsInRange(target, spellInfo->GetMinRange(), spellInfo->GetMaxRange())) + allowMove = false; + + if (IsCombatMovementAllowed() != allowMove) + { + SetCombatMovement(allowMove); + + // need relaunch movement + ScriptedAI::AttackStart(target); + + // give some time to allow reposition, try again in a second + if (allowMove) + return false; + } } - return false; + DoCast(target, spellId); + return true; } - void UpdateAI(uint32 diff) override + void UpdateAI(uint32 diff) final override { if (!UpdateVictim()) return; @@ -1044,6 +1103,9 @@ struct npc_thorim_trashAI : public ScriptedAI while (uint32 eventId = _events.ExecuteEvent()) { ExecuteEvent(eventId); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } if (_info->Type == DARK_RUNE_ACOLYTE) @@ -1073,7 +1135,7 @@ class npc_thorim_pre_phase : public CreatureScript me->setActive(true); // prevent grid unload } - void Reset() + void Reset() override { _events.Reset(); if (_info->PrimaryAbility) @@ -1086,14 +1148,20 @@ class npc_thorim_pre_phase : public CreatureScript SetCombatMovement(false); } - void JustDied(Unit* /*victim*/) + void JustDied(Unit* /*victim*/) override { if (Creature* thorim = _instance->GetCreature(BOSS_THORIM)) thorim->AI()->DoAction(ACTION_INCREASE_PREADDS_COUNT); } + bool ShouldSparWith(Unit const* target) const override + { + return !target->GetAffectingPlayer(); + } + void DamageTaken(Unit* attacker, uint32& damage) override { + // nullify spell damage if (!attacker->GetAffectingPlayer()) damage = 0; } @@ -1149,16 +1217,25 @@ class npc_thorim_arena_phase : public CreatureScript case DARK_RUNE_EVOKER: _isInArena = true; break; + case DARK_RUNE_ACOLYTE: + { + _isInArena = (_info->Entry == NPC_DARK_RUNE_ACOLYTE_PRE); + SetBoundary(&ArenaBoundaries, !_isInArena); + break; + } default: _isInArena = false; break; } - //_isInArena = IN_ARENA(me); } bool CanAIAttack(Unit const* who) const override { - return _isInArena == IN_ARENA(who); + // don't try to attack players in balcony + if (_isInArena && HeightPositionCheck(true)(who)) + return false; + + return CheckBoundary(who); } void Reset() override @@ -1174,19 +1251,25 @@ class npc_thorim_arena_phase : public CreatureScript _events.ScheduleEvent(EVENT_ABILITY_CHARGE, 8000); } - void EnterCombat(Unit* /*who*/) + void EnterCombat(Unit* /*who*/) override { if (_info->Type == DARK_RUNE_WARBRINGER) DoCast(me, SPELL_AURA_OF_CELERITY); + + if (!_isInArena) + if (Creature* colossus = _instance->GetCreature(DATA_RUNIC_COLOSSUS)) + colossus->AI()->DoAction(ACTION_ACTIVATE_RUNIC_SMASH); } - void EnterEvadeMode(EvadeReason /*why*/) override + void EnterEvadeMode(EvadeReason why) override { + if (why != EVADE_REASON_NO_HOSTILES && why != EVADE_REASON_BOUNDARY) + return; + // this should only happen if theres no alive player in the arena -> summon orb - // might be called by mind control release or controllers death? if (Creature* thorim = _instance->GetCreature(BOSS_THORIM)) thorim->AI()->DoAction(ACTION_BERSERK); - ScriptedAI::EnterEvadeMode(); + ScriptedAI::EnterEvadeMode(why); } void ExecuteEvent(uint32 eventId) override @@ -1195,27 +1278,30 @@ class npc_thorim_arena_phase : public CreatureScript { case EVENT_PRIMARY_ABILITY: if (UseAbility(_info->PrimaryAbility)) - _events.ScheduleEvent(eventId, urand(3000, 6000)); + _events.Repeat(3000, 6000); else - _events.ScheduleEvent(eventId, 1000); + _events.Repeat(1000); break; case EVENT_SECONDARY_ABILITY: if (UseAbility(_info->SecondaryAbility)) - _events.ScheduleEvent(eventId, urand(12000, 16000)); + _events.Repeat(12000, 16000); else - _events.ScheduleEvent(eventId, 1000); + _events.Repeat(1000); break; case EVENT_THIRD_ABILITY: if (UseAbility(_info->ThirdAbility)) - _events.ScheduleEvent(eventId, urand(6000, 8000)); + _events.Repeat(6000, 8000); else - _events.ScheduleEvent(eventId, 1000); + _events.Repeat(1000); break; case EVENT_ABILITY_CHARGE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, [this](Unit* unit){ return unit->GetTypeId() == TYPEID_PLAYER && unit->IsInRange(me, 8.0f, 25.0f); })) + { + Unit* referer = me; + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, [referer](Unit* unit){ return unit->GetTypeId() == TYPEID_PLAYER && unit->IsInRange(referer, 8.0f, 25.0f); })) DoCast(target, SPELL_CHARGE); _events.ScheduleEvent(eventId, 12000); break; + } default: break; } @@ -1236,20 +1322,35 @@ struct npc_thorim_minibossAI : public ScriptedAI npc_thorim_minibossAI(Creature* creature) : ScriptedAI(creature), _summons(me) { _instance = creature->GetInstanceScript(); + + SetBoundary(&ArenaBoundaries, true); } - void JustSummoned(Creature* summon) override + bool CanAIAttack(Unit const* who) const final override + { + return CheckBoundary(who); + } + + void JustSummoned(Creature* summon) final override { _summons.Summon(summon); - ScriptedAI::JustSummoned(summon); } - void SummonedCreatureDespawn(Creature* summon) override + void SummonedCreatureDespawn(Creature* summon) final override { - ScriptedAI::SummonedCreatureDespawn(summon); _summons.Despawn(summon); } + void DoAction(int32 action) override + { + if (action == ACTION_ACTIVATE_ADDS) + { + for (ObjectGuid const& guid : _summons) + if (Creature* summon = ObjectAccessor::GetCreature(*me, guid)) + summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + } + } + protected: InstanceScript* _instance; EventMap _events; @@ -1265,13 +1366,20 @@ class npc_runic_colossus : public CreatureScript { npc_runic_colossusAI(Creature* creature) : npc_thorim_minibossAI(creature) { + Initialize(); + } + + void Initialize() + { + _runicActive = false; } void Reset() override { + Initialize(); _events.Reset(); - // Runed Door closed + // close the Runic Door _instance->HandleGameObject(_instance->GetGuidData(DATA_RUNIC_DOOR), false); // Spawn trashes @@ -1285,19 +1393,33 @@ class npc_runic_colossus : public CreatureScript // don't enter combat } + void DoAction(int32 action) override + { + npc_thorim_minibossAI::DoAction(action); + + if (_runicActive) + return; + + if (action == ACTION_ACTIVATE_RUNIC_SMASH) + { + _runicActive = true; + _events.ScheduleEvent(EVENT_RUNIC_SMASH, 7000); + } + } + void JustDied(Unit* /*victim*/) override { - // Runed Door opened + // open the Runic Door _instance->HandleGameObject(_instance->GetGuidData(DATA_RUNIC_DOOR), true); if (Creature* thorim = _instance->GetCreature(BOSS_THORIM)) - thorim->AI()->Talk(SAY_SPECIAL_2); - } + thorim->AI()->Talk(SAY_SPECIAL); - void DoAction(int32 action) override - { - if (action == ACTION_ACTIVATE_RUNIC_SMASH) - _events.ScheduleEvent(EVENT_RUNIC_SMASH, 12000); + if (Creature* giant = _instance->GetCreature(DATA_RUNE_GIANT)) + { + giant->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + giant->AI()->DoAction(ACTION_ACTIVATE_ADDS); + } } void EnterCombat(Unit* /*who*/) override @@ -1307,7 +1429,6 @@ class npc_runic_colossus : public CreatureScript _events.ScheduleEvent(EVENT_RUNIC_BARRIER, urand(12000, 15000)); _events.ScheduleEvent(EVENT_SMASH, urand(15000, 18000)); _events.ScheduleEvent(EVENT_RUNIC_CHARGE, urand(20000, 24000)); - me->InterruptNonMeleeSpells(true); } void UpdateAI(uint32 diff) override @@ -1323,28 +1444,31 @@ class npc_runic_colossus : public CreatureScript { case EVENT_RUNIC_BARRIER: Talk(EMOTE_RUNIC_BARRIER); - DoCast(me, SPELL_RUNIC_BARRIER); - _events.ScheduleEvent(eventId, urand(35000, 45000)); + DoCastAOE(SPELL_RUNIC_BARRIER); + _events.Repeat(35000, 45000); break; case EVENT_SMASH: - DoCast(me, SPELL_SMASH); - _events.ScheduleEvent(eventId, urand(15000, 18000)); + DoCastAOE(SPELL_SMASH); + _events.Repeat(15000, 18000); break; case EVENT_RUNIC_CHARGE: { Unit* referer = me; if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, [referer](Unit* unit){ return unit->GetTypeId() == TYPEID_PLAYER && unit->IsInRange(referer, 8.0f, 40.0f); })) DoCast(target, SPELL_RUNIC_CHARGE); - _events.ScheduleEvent(eventId, 20000); + _events.Repeat(20000); break; } case EVENT_RUNIC_SMASH: DoCast(me, RAND(SPELL_RUNIC_SMASH_LEFT, SPELL_RUNIC_SMASH_RIGHT)); - _events.ScheduleEvent(eventId, 6000); + _events.Repeat(6000); break; default: break; } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } if (!UpdateVictim()) @@ -1352,6 +1476,9 @@ class npc_runic_colossus : public CreatureScript DoMeleeAttackIfReady(); } + + private: + bool _runicActive; }; CreatureAI* GetAI(Creature* creature) const override @@ -1373,7 +1500,7 @@ class npc_ancient_rune_giant : public CreatureScript { _events.Reset(); - // Stone Door closed + // close the Stone Door _instance->HandleGameObject(_instance->GetGuidData(DATA_STONE_DOOR), false); // Spawn trashes @@ -1393,7 +1520,7 @@ class npc_ancient_rune_giant : public CreatureScript void JustDied(Unit* /*victim*/) override { - // Stone Door opened + // opem the Stone Door _instance->HandleGameObject(_instance->GetGuidData(DATA_STONE_DOOR), true); } @@ -1417,16 +1544,19 @@ class npc_ancient_rune_giant : public CreatureScript break; case EVENT_STOMP: DoCastAOE(SPELL_STOMP); - _events.ScheduleEvent(eventId, urand(10000, 12000)); + _events.Repeat(10000, 12000); break; case EVENT_RUNE_DETONATION: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true)) DoCast(target, SPELL_RUNE_DETONATION); - _events.ScheduleEvent(eventId, urand(10000, 12000)); + _events.Repeat(10000, 12000); break; default: break; } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } DoMeleeAttackIfReady(); @@ -1446,33 +1576,22 @@ class npc_sif : public CreatureScript struct npc_sifAI : public ScriptedAI { - npc_sifAI(Creature* creature) : ScriptedAI(creature), _summons(me) + npc_sifAI(Creature* creature) : ScriptedAI(creature) { SetCombatMovement(false); + _instance = creature->GetInstanceScript(); } void Reset() override { _events.Reset(); - _summons.DespawnAll(); - } - - void JustSummoned(Creature* summon) override - { - _summons.Summon(summon); - if (summon->GetEntry() == NPC_THORIM_EVENT_BUNNY) - summon->GetMotionMaster()->MoveRandom(60.0f); - } - - void SummonedCreatureDespawn(Creature* summon) override - { - _summons.Despawn(summon); } void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override { if (spellInfo->Id == SPELL_STORMHAMMER_SIF) { + me->InterruptSpell(CURRENT_GENERIC_SPELL); me->SetReactState(REACT_PASSIVE); me->AttackStop(); } @@ -1511,7 +1630,7 @@ class npc_sif : public CreatureScript if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) DoCast(target, SPELL_BLINK); _events.ScheduleEvent(EVENT_FROST_NOVA, 0); - _events.ScheduleEvent(eventId, urand(20000, 25000)); + _events.Repeat(20000, 25000); return; case EVENT_FROST_NOVA: DoCastAOE(SPELL_FROSTNOVA); @@ -1519,21 +1638,22 @@ class npc_sif : public CreatureScript case EVENT_FROSTBOLT: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) DoCast(target, SPELL_FROSTBOLT); - _events.ScheduleEvent(eventId, 2000); + _events.Repeat(2000); return; case EVENT_FROSTBOLT_VOLLEY: DoCastAOE(SPELL_FROSTBOLT_VOLLEY); - _events.ScheduleEvent(eventId, urand(15000, 20000)); + _events.Repeat(15000, 20000); return; case EVENT_BLIZZARD: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true)) - me->SummonCreature(NPC_THORIM_EVENT_BUNNY, *target, TEMPSUMMON_TIMED_DESPAWN, 25000); DoCastAOE(SPELL_BLIZZARD); - _events.ScheduleEvent(eventId, urand(35000, 45000)); + _events.Repeat(35000, 45000); return; default: break; } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } // no melee attack @@ -1541,7 +1661,7 @@ class npc_sif : public CreatureScript private: EventMap _events; - SummonList _summons; + InstanceScript* _instance; }; CreatureAI* GetAI(Creature* creature) const override @@ -1550,48 +1670,6 @@ class npc_sif : public CreatureScript } }; -class HeightPositionCheck -{ - public: - HeightPositionCheck(bool ret) : _ret(ret) { } - - bool operator()(WorldObject* obj) const - { - return obj->GetPositionZ() > 425.0f == _ret; - } - - private: - bool _ret; -}; - -// 62577 - Blizzard -// 62603 - Blizzard -class spell_thorim_blizzard : public SpellScriptLoader -{ - public: - spell_thorim_blizzard() : SpellScriptLoader("spell_thorim_blizzard") { } - - class spell_thorim_blizzard_SpellScript : public SpellScript - { - PrepareSpellScript(spell_thorim_blizzard_SpellScript); - - void FilterTargets(std::list& targets) - { - targets.remove_if(HeightPositionCheck(true)); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thorim_blizzard_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_thorim_blizzard_SpellScript(); - } -}; - // 62576 - Blizzard // 62602 - Blizzard class spell_thorim_blizzard_effect : public SpellScriptLoader @@ -1618,6 +1696,7 @@ class spell_thorim_blizzard_effect : public SpellScriptLoader return false; } } + return true; } @@ -1679,10 +1758,7 @@ class spell_thorim_charge_orb : public SpellScriptLoader void FilterTargets(std::list& targets) { - targets.remove_if([](WorldObject* target) - { - return target->GetPositionZ() < 425.0f; - }); + targets.remove_if(HeightPositionCheck(false)); if (targets.empty()) return; @@ -1737,7 +1813,7 @@ class spell_thorim_lightning_charge : public SpellScriptLoader void HandleCharge() { - GetCaster()->CastSpell(GetCaster(), SPELL_LIGHTNING_CHARGE, true); + GetCaster()->CastSpell(GetCaster(), SPELL_LIGHTNING_CHARGE); } void Register() override @@ -1753,6 +1829,47 @@ class spell_thorim_lightning_charge : public SpellScriptLoader } }; +// 61934 - Leap +class spell_thorim_arena_leap : public SpellScriptLoader +{ + public: + spell_thorim_arena_leap() : SpellScriptLoader("spell_thorim_arena_leap") { } + + class spell_thorim_arena_leap_SpellScript : public SpellScript + { + PrepareSpellScript(spell_thorim_arena_leap_SpellScript); + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Position const* pos = GetHitDest()) + GetCaster()->ToCreature()->SetHomePosition(*pos); + } + + void Register() override + { + OnEffectLaunch += SpellEffectFn(spell_thorim_arena_leap_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_JUMP_DEST); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_thorim_arena_leap_SpellScript(); + } +}; + +struct OutOfArenaCheck +{ + bool operator()(Position const* who) const + { + return !CreatureAI::IsInBounds(ArenaBoundaries, who); + } +}; + // 62042 - Stormhammer class spell_thorim_stormhammer : public SpellScriptLoader { @@ -1773,10 +1890,7 @@ class spell_thorim_stormhammer : public SpellScriptLoader void FilterTargets(std::list& targets) { - targets.remove_if([](WorldObject* target) - { - return !IN_ARENA(target); - }); + targets.remove_if([](WorldObject* target) -> bool { return HeightPositionCheck(true)(target) || OutOfArenaCheck()(target); }); if (targets.empty()) { @@ -1798,9 +1912,15 @@ class spell_thorim_stormhammer : public SpellScriptLoader } } + void LoseHammer() + { + GetCaster()->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); + } + void Register() override { OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thorim_stormhammer_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY); + AfterCast += SpellCastFn(spell_thorim_stormhammer_SpellScript::LoseHammer); OnEffectHitTarget += SpellEffectFn(spell_thorim_stormhammer_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1838,8 +1958,14 @@ class spell_thorim_stormhammer_sif : public SpellScriptLoader } } + void LoseHammer() + { + GetCaster()->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); + } + void Register() override { + AfterCast += SpellCastFn(spell_thorim_stormhammer_sif_SpellScript::LoseHammer); OnEffectHitTarget += SpellEffectFn(spell_thorim_stormhammer_sif_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1850,6 +1976,34 @@ class spell_thorim_stormhammer_sif : public SpellScriptLoader } }; +// 64909 - Stormhammer +class spell_thorim_stormhammer_boomerang : public SpellScriptLoader +{ + public: + spell_thorim_stormhammer_boomerang() : SpellScriptLoader("spell_thorim_stormhammer_boomerang") { } + + class spell_thorim_stormhammer_boomerang_SpellScript : public SpellScript + { + PrepareSpellScript(spell_thorim_stormhammer_boomerang_SpellScript); + + void RecoverHammer(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THORIM_WEAPON_DISPLAY_ID); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_thorim_stormhammer_boomerang_SpellScript::RecoverHammer, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_thorim_stormhammer_boomerang_SpellScript(); + } +}; + // 62057, 62058 - Runic Smash class spell_thorim_runic_smash : public SpellScriptLoader { @@ -1871,12 +2025,12 @@ class spell_thorim_runic_smash : public SpellScriptLoader { PreventHitDefaultEffect(effIndex); - std::list triggers; + std::vector triggers; GetCaster()->GetCreatureListWithEntryInGrid(triggers, GetSpellInfo()->Id == SPELL_RUNIC_SMASH_LEFT ? NPC_GOLEM_LEFT_HAND_BUNNY : NPC_GOLEM_RIGHT_HAND_BUNNY, 150.0f); - for (Creature* bunny : triggers) + for (Creature* trigger : triggers) { - float dist = GetCaster()->GetExactDist(bunny); - bunny->m_Events.AddEvent(new RunicSmashExplosionEvent(bunny), bunny->m_Events.CalculateTime(uint64(dist * 30))); + float dist = GetCaster()->GetExactDist(trigger); + trigger->m_Events.AddEvent(new RunicSmashExplosionEvent(trigger), trigger->m_Events.CalculateTime(uint64(dist * 30.f))); }; } @@ -1892,6 +2046,102 @@ class spell_thorim_runic_smash : public SpellScriptLoader } }; +class UpperOrbCheck +{ + public: + UpperOrbCheck() : _check(true) { } + + bool operator() (Creature* target) const + { + return target->GetEntry() == NPC_THUNDER_ORB && _check(target); + } + + private: + HeightPositionCheck const _check; +}; + +// 62184 - Activate Lightning Orb Periodic +class spell_thorim_activate_lightning_orb_periodic : public SpellScriptLoader +{ + public: + spell_thorim_activate_lightning_orb_periodic() : SpellScriptLoader("spell_thorim_activate_lightning_orb_periodic") { } + + class spell_thorim_activate_lightning_orb_periodic_AuraScript : public AuraScript + { + PrepareAuraScript(spell_thorim_activate_lightning_orb_periodic_AuraScript); + + InstanceScript* instance = nullptr; + + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + + Unit* caster = GetCaster(); + std::vector triggers; + + UpperOrbCheck check; + Trinity::CreatureListSearcher searcher(caster, triggers, check); + caster->VisitNearbyGridObject(100.f, searcher); + + if (!triggers.empty()) + { + Creature* target = Trinity::Containers::SelectRandomContainerElement(triggers); + if (Creature* thorim = instance->GetCreature(BOSS_THORIM)) + thorim->AI()->SetGUID(target->GetGUID(), DATA_CHARGED_PILLAR); + } + } + + bool Load() override + { + if (Unit* caster = GetCaster()) + instance = caster->GetInstanceScript(); + + return instance != nullptr; + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_thorim_activate_lightning_orb_periodic_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_thorim_activate_lightning_orb_periodic_AuraScript(); + } +}; + +// 62331, 62418 - Impale +class spell_iron_ring_guard_impale : public SpellScriptLoader +{ + public: + spell_iron_ring_guard_impale() : SpellScriptLoader("spell_iron_ring_guard_impale") { } + + class spell_iron_ring_guard_impale_AuraScript : public AuraScript + { + PrepareAuraScript(spell_iron_ring_guard_impale_AuraScript); + + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + if (GetTarget()->HealthAbovePct(GetSpellInfo()->Effects[EFFECT_1].CalcValue())) + { + Remove(AURA_REMOVE_BY_ENEMY_SPELL); + PreventDefaultAction(); + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_iron_ring_guard_impale_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_iron_ring_guard_impale_AuraScript(); + } +}; + class achievement_dont_stand_in_the_lightning : public AchievementCriteriaScript { public: @@ -1914,6 +2164,40 @@ class achievement_lose_your_illusion : public AchievementCriteriaScript } }; +class achievement_i_ll_take_you_all_on : public AchievementCriteriaScript +{ + public: + achievement_i_ll_take_you_all_on() : AchievementCriteriaScript("achievement_i_ll_take_you_all_on"), _check() { } + + bool OnCheck(Player* source, Unit* /*target*/) override + { + return _check(source); + } + + private: + OutOfArenaCheck _check; +}; + +class condition_thorim_arena_leap : public ConditionScript +{ + public: + condition_thorim_arena_leap() : ConditionScript("condition_thorim_arena_leap"), _check(false) { } + + bool OnConditionCheck(Condition const* condition, ConditionSourceInfo& sourceInfo) override + { + WorldObject* target = sourceInfo.mConditionTargets[condition->ConditionTarget]; + InstanceScript* instance = target->GetInstanceScript(); + + if (!instance) + return false; + + return _check(target); + } + + private: + HeightPositionCheck _check; +}; + void AddSC_boss_thorim() { new boss_thorim(); @@ -1922,14 +2206,19 @@ void AddSC_boss_thorim() new npc_runic_colossus(); new npc_ancient_rune_giant(); new npc_sif(); - new spell_thorim_blizzard(); new spell_thorim_blizzard_effect(); new spell_thorim_frostbolt_volley(); new spell_thorim_charge_orb(); new spell_thorim_lightning_charge(); new spell_thorim_stormhammer(); new spell_thorim_stormhammer_sif(); + new spell_thorim_stormhammer_boomerang(); + new spell_thorim_arena_leap(); new spell_thorim_runic_smash(); + new spell_thorim_activate_lightning_orb_periodic(); + new spell_iron_ring_guard_impale(); new achievement_dont_stand_in_the_lightning(); new achievement_lose_your_illusion(); + new achievement_i_ll_take_you_all_on(); + new condition_thorim_arena_leap(); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index abb161d110..7127c3206e 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -34,7 +34,7 @@ static BossBoundaryData const boundaries = { BOSS_ALGALON, new CircleBoundary(Position(1632.668f, -307.7656f), 45.0) }, { BOSS_ALGALON, new ZRangeBoundary(410.0f, 440.0f) }, { BOSS_HODIR, new EllipseBoundary(Position(2001.5f, -240.0f), 50.0, 75.0) }, - { BOSS_THORIM, new CircleBoundary(Position(2134.73f, -263.2f), 50.0) }, + // Thorim sets boundaries dinamically { BOSS_FREYA, new RectangleBoundary(2094.6f, 2520.0f, -250.0f, 200.0f) }, { BOSS_MIMIRON, new CircleBoundary(Position(2744.0f, 2569.0f), 70.0) }, { BOSS_VEZAX, new RectangleBoundary(1740.0f, 1930.0f, 31.0f, 228.0f) }, @@ -54,6 +54,10 @@ static DoorData const doorData[] = { GO_MIMIRON_DOOR_2, BOSS_MIMIRON, DOOR_TYPE_ROOM }, { GO_MIMIRON_DOOR_3, BOSS_MIMIRON, DOOR_TYPE_ROOM }, { GO_THORIM_ENCOUNTER_DOOR, BOSS_THORIM, DOOR_TYPE_ROOM }, + { GO_ANCIENT_GATE_OF_THE_KEEPERS, BOSS_HODIR, DOOR_TYPE_PASSAGE }, + { GO_ANCIENT_GATE_OF_THE_KEEPERS, BOSS_MIMIRON, DOOR_TYPE_PASSAGE }, + { GO_ANCIENT_GATE_OF_THE_KEEPERS, BOSS_THORIM, DOOR_TYPE_PASSAGE }, + { GO_ANCIENT_GATE_OF_THE_KEEPERS, BOSS_FREYA, DOOR_TYPE_PASSAGE }, { GO_VEZAX_DOOR, BOSS_VEZAX, DOOR_TYPE_PASSAGE }, { GO_YOGG_SARON_DOOR, BOSS_YOGG_SARON, DOOR_TYPE_ROOM }, { GO_DOODAD_UL_SIGILDOOR_03, BOSS_ALGALON, DOOR_TYPE_ROOM }, @@ -93,6 +97,7 @@ ObjectData const creatureData[] = { NPC_SIF, DATA_SIF }, { NPC_RUNIC_COLOSSUS, DATA_RUNIC_COLOSSUS }, { NPC_RUNE_GIANT, DATA_RUNE_GIANT }, + { NPC_THORIM_CONTROLLER, DATA_THORIM_CONTROLLER }, { NPC_COMPUTER, DATA_COMPUTER }, { NPC_WORLD_TRIGGER_MIMIRON, DATA_MIMIRON_WORLD_TRIGGER }, { NPC_VOICE_OF_YOGG_SARON, DATA_VOICE_OF_YOGG_SARON }, @@ -174,6 +179,7 @@ class instance_ulduar : public InstanceMapScript ObjectGuid LeviathanGateGUID; ObjectGuid KologarnChestGUID; ObjectGuid KologarnBridgeGUID; + ObjectGuid ThorimDarkIronPortcullisGUID; ObjectGuid CacheOfStormsGUID; ObjectGuid CacheOfStormsHardmodeGUID; ObjectGuid HodirRareCacheGUID; @@ -332,6 +338,16 @@ class instance_ulduar : public InstanceMapScript creature->UpdateEntry(NPC_BATTLE_PRIEST_GINA); break; + // Thorim + case NPC_MERCENARY_CAPTAIN_H: + if (TeamInInstance == HORDE) + creature->UpdateEntry(NPC_MERCENARY_CAPTAIN_A); + break; + case NPC_MERCENARY_SOLDIER_H: + if (TeamInInstance == HORDE) + creature->UpdateEntry(NPC_MERCENARY_SOLDIER_A); + break; + // Freya case NPC_IRONBRANCH: ElderGUIDs[0] = creature->GetGUID(); @@ -447,6 +463,9 @@ class instance_ulduar : public InstanceMapScript if (GetBossState(BOSS_KOLOGARN) == DONE) HandleGameObject(ObjectGuid::Empty, false, gameObject); break; + case GO_THORIM_DARK_IRON_PORTCULLIS: + ThorimDarkIronPortcullisGUID = gameObject->GetGUID(); + break; case GO_CACHE_OF_STORMS_10: case GO_CACHE_OF_STORMS_25: CacheOfStormsGUID = gameObject->GetGUID(); @@ -669,8 +688,14 @@ class instance_ulduar : public InstanceMapScript cache->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN); } } + instance->SummonCreature(NPC_THORIM_OBSERVATION_RING, ObservationRingKeepersPos[2]); } + else + { + DoCloseDoorOrButton(GetGuidData(DATA_THORIM_LEVER)); + DoCloseDoorOrButton(ThorimDarkIronPortcullisGUID); + } break; case BOSS_ALGALON: if (state == DONE) @@ -889,7 +914,6 @@ class instance_ulduar : public InstanceMapScript return keepersCount <= 1; case CRITERIA_ALONE_IN_THE_DARKNESS_10: case CRITERIA_ALONE_IN_THE_DARKNESS_25: - case CRITERIA_DEATHS_DEMISE: return keepersCount == 0; case CRITERIA_C_O_U_LEVIATHAN_10: case CRITERIA_C_O_U_LEVIATHAN_25: diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index 6edbea48b7..1596453464 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -155,6 +155,12 @@ enum UlduarNPCs // Thorim NPC_THORIM_INVISIBLE_STALKER = 32780, + NPC_JORMUNGAR_BEHEMOTH = 32882, + NPC_MERCENARY_CAPTAIN_A = 32908, + NPC_MERCENARY_CAPTAIN_H = 32907, + NPC_MERCENARY_SOLDIER_A = 32885, + NPC_MERCENARY_SOLDIER_H = 32883, + NPC_DARK_RUNE_ACOLYTE_PRE = 32886, NPC_RUNIC_COLOSSUS = 32872, NPC_RUNE_GIANT = 32873, NPC_IRON_RING_GUARD = 32874, @@ -170,6 +176,7 @@ enum UlduarNPCs NPC_GOLEM_LEFT_HAND_BUNNY = 33141, NPC_SIF = 33196, NPC_THUNDER_ORB = 33378, + NPC_THORIM_CONTROLLER = 32879, // Yogg-Saron NPC_SARA = 33134, @@ -245,6 +252,8 @@ enum UlduarGameObjects GO_KOLOGARN_BRIDGE = 194232, GO_KOLOGARN_DOOR = 194553, + GO_ANCIENT_GATE_OF_THE_KEEPERS = 194255, + // Hodir GO_HODIR_ENTRANCE = 194442, GO_HODIR_DOOR = 194634, @@ -262,7 +271,8 @@ enum UlduarGameObjects GO_THORIM_RUNIC_DOOR = 194557, GO_THORIM_STONE_DOOR = 194558, GO_THORIM_ENCOUNTER_DOOR = 194559, - GO_THORIM_LEVER = 194265, + GO_THORIM_LEVER = 194264, + GO_THORIM_DARK_IRON_PORTCULLIS = 194560, // Mimiron GO_MIMIRON_TRAM = 194675, @@ -299,7 +309,7 @@ enum UlduarGameObjects GO_GIFT_OF_THE_OBSERVER_25 = 194822, }; -enum EventIds +enum UUEventIds { EVENT_TOWER_OF_STORM_DESTROYED = 21031, EVENT_TOWER_OF_FROST_DESTROYED = 21032, @@ -339,7 +349,6 @@ enum UlduarAchievementCriteriaIds CRITERIA_ONE_LIGHT_IN_THE_DARKNESS_25 = 10416, CRITERIA_ALONE_IN_THE_DARKNESS_10 = 10412, CRITERIA_ALONE_IN_THE_DARKNESS_25 = 10417, - CRITERIA_DEATHS_DEMISE = 10279, CRITERIA_HERALD_OF_TITANS = 10678, // Champion of Ulduar @@ -436,6 +445,7 @@ enum UlduarData DATA_RUNIC_DOOR, DATA_STONE_DOOR, DATA_THORIM_HARDMODE, + DATA_THORIM_CONTROLLER, // Misc DATA_BRANN_BRONZEBEARD_INTRO, From 724cf454b6958619bbfcbbc1917aa78771e4b4fa Mon Sep 17 00:00:00 2001 From: Killyana Date: Wed, 17 May 2017 06:07:01 +0200 Subject: [PATCH 07/44] DB: Fix some DB errors --- sql/updates/world/3.3.5/2017_05_17_00_world.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 sql/updates/world/3.3.5/2017_05_17_00_world.sql diff --git a/sql/updates/world/3.3.5/2017_05_17_00_world.sql b/sql/updates/world/3.3.5/2017_05_17_00_world.sql new file mode 100644 index 0000000000..3b946f6006 --- /dev/null +++ b/sql/updates/world/3.3.5/2017_05_17_00_world.sql @@ -0,0 +1,2 @@ +-- +DELETE FROM `creature_addon` WHERE `guid` IN (136274,136490,136555); From b2b6d55cb4e2b283a0431ba4a0900ad96a3697c4 Mon Sep 17 00:00:00 2001 From: ccrs Date: Fri, 19 May 2017 13:49:49 +0200 Subject: [PATCH 08/44] Scripts/ICC: add missing cases for Dark Martyrdom difficulty entries how come nobody noticed this? --- .../boss_lady_deathwhisper.cpp | 100 ++++++++++-------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index 4c306d937c..e980ba4d36 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -53,62 +53,68 @@ enum ScriptTexts enum Spells { // Lady Deathwhisper - SPELL_MANA_BARRIER = 70842, - SPELL_SHADOW_BOLT = 71254, - SPELL_DEATH_AND_DECAY = 71001, - SPELL_DOMINATE_MIND = 71289, - SPELL_DOMINATE_MIND_SCALE = 71290, - SPELL_FROSTBOLT = 71420, - SPELL_FROSTBOLT_VOLLEY = 72905, - SPELL_TOUCH_OF_INSIGNIFICANCE = 71204, - SPELL_SUMMON_SHADE = 71363, - SPELL_SHADOW_CHANNELING = 43897, - SPELL_DARK_TRANSFORMATION_T = 70895, - SPELL_DARK_EMPOWERMENT_T = 70896, - SPELL_DARK_MARTYRDOM_T = 70897, - SPELL_SUMMON_SPIRITS = 72478, + SPELL_MANA_BARRIER = 70842, + SPELL_SHADOW_BOLT = 71254, + SPELL_DEATH_AND_DECAY = 71001, + SPELL_DOMINATE_MIND = 71289, + SPELL_DOMINATE_MIND_SCALE = 71290, + SPELL_FROSTBOLT = 71420, + SPELL_FROSTBOLT_VOLLEY = 72905, + SPELL_TOUCH_OF_INSIGNIFICANCE = 71204, + SPELL_SUMMON_SHADE = 71363, + SPELL_SHADOW_CHANNELING = 43897, + SPELL_DARK_TRANSFORMATION_T = 70895, + SPELL_DARK_EMPOWERMENT_T = 70896, + SPELL_DARK_MARTYRDOM_T = 70897, + SPELL_SUMMON_SPIRITS = 72478, // Achievement - SPELL_FULL_HOUSE = 72827, // does not exist in dbc but still can be used for criteria check + SPELL_FULL_HOUSE = 72827, // does not exist in dbc but still can be used for criteria check // Both Adds - SPELL_TELEPORT_VISUAL = 41236, - SPELL_CLEAR_ALL_DEBUFFS = 34098, - SPELL_FULL_HEAL = 17683, - SPELL_PERMANENT_FEIGN_DEATH = 70628, + SPELL_TELEPORT_VISUAL = 41236, + SPELL_CLEAR_ALL_DEBUFFS = 34098, + SPELL_FULL_HEAL = 17683, + SPELL_PERMANENT_FEIGN_DEATH = 70628, // Fanatics - SPELL_DARK_TRANSFORMATION = 70900, - SPELL_NECROTIC_STRIKE = 70659, - SPELL_SHADOW_CLEAVE = 70670, - SPELL_VAMPIRIC_MIGHT = 70674, - SPELL_FANATIC_S_DETERMINATION = 71235, - SPELL_DARK_MARTYRDOM_FANATIC = 71236, + SPELL_DARK_TRANSFORMATION = 70900, + SPELL_NECROTIC_STRIKE = 70659, + SPELL_SHADOW_CLEAVE = 70670, + SPELL_VAMPIRIC_MIGHT = 70674, + SPELL_FANATIC_S_DETERMINATION = 71235, + SPELL_DARK_MARTYRDOM_FANATIC = 71236, + SPELL_DARK_MARTYRDOM_FANATIC_25N = 72495, + SPELL_DARK_MARTYRDOM_FANATIC_10H = 72496, + SPELL_DARK_MARTYRDOM_FANATIC_25H = 72497, // Adherents - SPELL_DARK_EMPOWERMENT = 70901, - SPELL_FROST_FEVER = 67767, - SPELL_DEATHCHILL_BOLT = 70594, - SPELL_DEATHCHILL_BLAST = 70906, - SPELL_CURSE_OF_TORPOR = 71237, - SPELL_SHROUD_OF_THE_OCCULT = 70768, - SPELL_ADHERENT_S_DETERMINATION = 71234, - SPELL_DARK_MARTYRDOM_ADHERENT = 70903, + SPELL_DARK_EMPOWERMENT = 70901, + SPELL_FROST_FEVER = 67767, + SPELL_DEATHCHILL_BOLT = 70594, + SPELL_DEATHCHILL_BLAST = 70906, + SPELL_CURSE_OF_TORPOR = 71237, + SPELL_SHROUD_OF_THE_OCCULT = 70768, + SPELL_ADHERENT_S_DETERMINATION = 71234, + SPELL_DARK_MARTYRDOM_ADHERENT = 70903, + SPELL_DARK_MARTYRDOM_ADHERENT_25N = 72498, + SPELL_DARK_MARTYRDOM_ADHERENT_10H = 72499, + SPELL_DARK_MARTYRDOM_ADHERENT_25H = 72500, // Vengeful Shade - SPELL_VENGEFUL_BLAST = 71544, - SPELL_VENGEFUL_BLAST_PASSIVE = 71494, - SPELL_VENGEFUL_BLAST_25N = 72010, - SPELL_VENGEFUL_BLAST_10H = 72011, - SPELL_VENGEFUL_BLAST_25H = 72012, + SPELL_VENGEFUL_BLAST = 71544, + SPELL_VENGEFUL_BLAST_PASSIVE = 71494, + SPELL_VENGEFUL_BLAST_25N = 72010, + SPELL_VENGEFUL_BLAST_10H = 72011, + SPELL_VENGEFUL_BLAST_25H = 72012, // Darnavan - SPELL_BLADESTORM = 65947, - SPELL_CHARGE = 65927, - SPELL_INTIMIDATING_SHOUT = 65930, - SPELL_MORTAL_STRIKE = 65926, - SPELL_SHATTERING_THROW = 65940, - SPELL_SUNDER_ARMOR = 65936, + SPELL_BLADESTORM = 65947, + SPELL_CHARGE = 65927, + SPELL_INTIMIDATING_SHOUT = 65930, + SPELL_MORTAL_STRIKE = 65926, + SPELL_SHATTERING_THROW = 65940, + SPELL_SUNDER_ARMOR = 65936, }; enum EventTypes @@ -636,6 +642,9 @@ class npc_cult_fanatic : public CreatureScript DoCastSelf(SPELL_DARK_MARTYRDOM_FANATIC); break; case SPELL_DARK_MARTYRDOM_FANATIC: + case SPELL_DARK_MARTYRDOM_FANATIC_25N: + case SPELL_DARK_MARTYRDOM_FANATIC_10H: + case SPELL_DARK_MARTYRDOM_FANATIC_25H: _scheduler .Schedule(Seconds(2), [this](TaskContext /*context*/) { @@ -735,6 +744,9 @@ class npc_cult_adherent : public CreatureScript DoCastSelf(SPELL_DARK_MARTYRDOM_ADHERENT); break; case SPELL_DARK_MARTYRDOM_ADHERENT: + case SPELL_DARK_MARTYRDOM_ADHERENT_25N: + case SPELL_DARK_MARTYRDOM_ADHERENT_10H: + case SPELL_DARK_MARTYRDOM_ADHERENT_25H: _scheduler .Schedule(Seconds(2), [this](TaskContext /*context*/) { From ec3945c3b78399f95d0d053b4bd3e53051a8282b Mon Sep 17 00:00:00 2001 From: Killyana Date: Mon, 22 May 2017 21:37:26 +0200 Subject: [PATCH 09/44] DB/Creature: Blightguard spawns --- .../world/3.3.5/2017_05_22_00_world.sql | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 sql/updates/world/3.3.5/2017_05_22_00_world.sql diff --git a/sql/updates/world/3.3.5/2017_05_22_00_world.sql b/sql/updates/world/3.3.5/2017_05_22_00_world.sql new file mode 100644 index 0000000000..77fda7e8f0 --- /dev/null +++ b/sql/updates/world/3.3.5/2017_05_22_00_world.sql @@ -0,0 +1,25 @@ +-- +DELETE FROM `creature` WHERE `guid` IN (79380,79383,79609,79614,79626,79631,79636,79650,79876,79895,79899,79921,80289,80295,80299,80300,80303,80311,80312,80315,80316,80323); +INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `curhealth`, `curmana`, `MovementType`) VALUES +(79380, 28603, 571, 1, 1, 0, 0, 6022.67, -2049.14, 238.189, 1.46482, 600, 10, 0, 0, 1), +(79383, 28603, 571, 1, 1, 0, 0, 6042.88, -2119.83, 239.522, 5.55282, 600, 10, 0, 0, 1), +(79609, 28603, 571, 1, 1, 0, 0, 6101.08, -2157.18, 239.578, 5.52926, 600, 10, 0, 0, 1), +(79614, 28603, 571, 1, 1, 0, 0, 6176.72, -2208.48, 241.65, 0.110007, 600, 10, 0, 0, 1), +(79626, 28603, 571, 1, 1, 0, 0, 6227.74, -2193.69, 236.211, 0.663713, 600, 10, 0, 0, 1), +(79631, 28603, 571, 1, 1, 0, 0, 6270.34, -2053.92, 238.548, 1.23705, 600, 10, 0, 0, 1), +(79636, 28603, 571, 1, 1, 0, 0, 6069.51, -1913.87, 236.212, 2.78429, 600, 10, 0, 0, 1), +(79650, 28603, 571, 1, 1, 0, 0, 6017.94, -1903.71, 239.384, 3.56183, 600, 10, 0, 0, 1), +(79876, 28603, 571, 1, 1, 0, 0, 5981.49, -1963.15, 237.669, 4.15088, 600, 10, 0, 0, 1), +(79895, 28603, 571, 1, 1, 0, 0, 6017.39, -2106.46, 243.382, 5.40752, 600, 10, 0, 0, 1), +(79899, 28603, 571, 1, 1, 0, 0, 5275.12, -1678.04, 236.349, 1.1703, 600, 10, 0, 0, 1), +(79921, 28603, 571, 1, 1, 0, 0, 5224.69, -1751.98, 235.717, 3.17306, 600, 10, 0, 0, 1), +(80289, 28603, 571, 1, 1, 0, 0, 5154.48, -1745.88, 238.291, 3.26731, 600, 10, 0, 0, 1), +(80295, 28603, 571, 1, 1, 0, 0, 5082.87, -1725.64, 235.624, 3.55791, 600, 10, 0, 0, 1), +(80299, 28603, 571, 1, 1, 0, 0, 5034.49, -1655.17, 240.16, 1.8693, 600, 10, 0, 0, 1), +(80300, 28603, 571, 1, 1, 0, 0, 5069.11, -1540.09, 240.561, 6.1183, 600, 10, 0, 0, 1), +(80303, 28603, 571, 1, 1, 0, 0, 5099.29, -1559.64, 238.941, 0.624444, 600, 10, 0, 0, 1), +(80311, 28603, 571, 1, 1, 0, 0, 6183.62, -2102.73, 235.653, 3.426750, 600, 10, 0, 0, 1), +(80312, 28603, 571, 1, 1, 0, 0, 6113.59, -2105.41, 234.909, 0.441447, 600, 10, 0, 0, 1), +(80315, 28603, 571, 1, 1, 0, 0, 6091.98, -2019.44, 235.639, 1.670596, 600, 10, 0, 0, 1), +(80316, 28603, 571, 1, 1, 0, 0, 6199.66, -1957.45, 234.049, 1.207211, 600, 10, 0, 0, 1), +(80323, 28603, 571, 1, 1, 0, 0, 6242.41, -2003.27, 234.282, 4.150887, 600, 10, 0, 0, 1); From f0e36b08639fd8da43f2f70c10fafbd37c4f569d Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 14:37:54 +0200 Subject: [PATCH 10/44] Core/Defines: define faction templates and replace magic numbers from scripts --- .../game/Battlefield/Zones/BattlefieldWG.cpp | 2 +- .../Battlegrounds/Zones/BattlegroundAB.cpp | 2 +- .../Battlegrounds/Zones/BattlegroundAV.cpp | 2 +- .../Battlegrounds/Zones/BattlegroundEY.cpp | 2 +- .../game/Entities/GameObject/GameObject.cpp | 2 +- src/server/game/Entities/Player/Player.cpp | 4 +- src/server/game/Miscellaneous/SharedDefines.h | 45 +++++++++++++++++++ src/server/game/Scripting/ScriptSystem.h | 24 ---------- .../BlackrockDepths/blackrock_depths.cpp | 4 +- .../BlackrockDepths/boss_coren_direbrew.cpp | 10 ++--- .../boss_emperor_dagran_thaurissan.cpp | 2 +- .../BlackrockDepths/boss_tomb_of_seven.cpp | 4 +- .../instance_blackrock_depths.cpp | 4 +- .../BlackwingLair/boss_nefarian.cpp | 6 +-- .../BlackwingLair/boss_vaelastrasz.cpp | 4 +- .../MoltenCore/boss_majordomo_executus.cpp | 1 - .../MoltenCore/boss_ragnaros.cpp | 4 +- .../EasternKingdoms/Karazhan/bosses_opera.cpp | 4 +- .../boss_felblood_kaelthas.cpp | 4 +- .../ScarletEnclave/chapter1.cpp | 11 +++-- .../ScarletEnclave/chapter5.cpp | 28 ++++++------ .../ShadowfangKeep/boss_apothecary_hummel.cpp | 8 ++-- .../SunwellPlateau/boss_kalecgos.cpp | 4 +- .../SunwellPlateau/boss_kiljaeden.cpp | 8 ++-- .../Uldaman/boss_archaedas.cpp | 14 +++--- .../Uldaman/instance_uldaman.cpp | 10 ++--- .../EasternKingdoms/ZulAman/boss_akilzon.cpp | 4 +- .../EasternKingdoms/zone_arathi_highlands.cpp | 5 +-- .../EasternKingdoms/zone_ghostlands.cpp | 5 +-- .../EasternKingdoms/zone_hinterlands.cpp | 6 +-- .../zone_stranglethorn_vale.cpp | 4 +- .../scripts/EasternKingdoms/zone_wetlands.cpp | 1 - .../BattleForMountHyjal/hyjalAI.cpp | 4 +- .../Kalimdor/Maraudon/boss_noxxion.cpp | 4 +- .../Kalimdor/RazorfenDowns/razorfen_downs.cpp | 4 +- .../RazorfenKraul/instance_razorfen_kraul.cpp | 2 +- .../Kalimdor/RazorfenKraul/razorfen_kraul.cpp | 2 +- .../Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp | 4 +- .../TempleOfAhnQiraj/boss_twinemperors.cpp | 6 +-- .../WailingCaverns/wailing_caverns.cpp | 2 +- .../Kalimdor/ZulFarrak/boss_zum_rah.cpp | 7 +-- .../scripts/Kalimdor/ZulFarrak/zulfarrak.cpp | 13 ++---- .../scripts/Kalimdor/zone_ashenvale.cpp | 5 +-- .../scripts/Kalimdor/zone_azuremyst_isle.cpp | 8 ++-- src/server/scripts/Kalimdor/zone_silithus.cpp | 9 ++-- src/server/scripts/Kalimdor/zone_tanaris.cpp | 6 +-- .../boss_argent_challenge.cpp | 4 +- .../boss_anubarak_trial.cpp | 2 +- .../boss_deathbringer_saurfang.cpp | 5 +-- .../boss_lady_deathwhisper.cpp | 2 +- .../Nexus/EyeOfEternity/boss_malygos.cpp | 6 --- .../Northrend/Nexus/Nexus/instance_nexus.cpp | 15 +++---- .../Ulduar/boss_algalon_the_observer.cpp | 2 +- .../Northrend/Ulduar/Ulduar/boss_freya.cpp | 4 +- .../Northrend/Ulduar/Ulduar/boss_hodir.cpp | 2 +- .../Northrend/Ulduar/Ulduar/boss_ignis.cpp | 2 +- .../Northrend/Ulduar/Ulduar/boss_mimiron.cpp | 2 +- .../Ulduar/Ulduar/boss_yogg_saron.cpp | 4 +- .../scripts/Northrend/zone_borean_tundra.cpp | 13 +++--- .../scripts/Northrend/zone_dragonblight.cpp | 6 +-- .../scripts/Northrend/zone_grizzly_hills.cpp | 4 +- .../scripts/Northrend/zone_howling_fjord.cpp | 3 +- .../scripts/Northrend/zone_icecrown.cpp | 6 +-- .../scripts/Northrend/zone_sholazar_basin.cpp | 2 +- .../scripts/Northrend/zone_storm_peaks.cpp | 2 +- src/server/scripts/Northrend/zone_zuldrak.cpp | 2 +- .../Outland/BlackTemple/black_temple.h | 1 - .../BlackTemple/boss_shade_of_akama.cpp | 10 ++--- .../BlackTemple/instance_black_temple.cpp | 4 +- .../SerpentShrine/boss_lady_vashj.cpp | 6 +-- .../boss_morogrim_tidewalker.cpp | 2 +- .../ShatteredHalls/boss_nethekurse.cpp | 2 +- .../Outland/TempestKeep/Eye/boss_kaelthas.cpp | 2 +- .../Outland/TempestKeep/arcatraz/arcatraz.cpp | 2 +- .../Outland/zone_hellfire_peninsula.cpp | 11 ++--- src/server/scripts/Outland/zone_nagrand.cpp | 4 +- .../scripts/Outland/zone_netherstorm.cpp | 4 +- .../Outland/zone_shadowmoon_valley.cpp | 21 +++------ .../scripts/Outland/zone_shattrath_city.cpp | 7 +-- .../scripts/Outland/zone_terokkar_forest.cpp | 14 +++--- .../scripts/Outland/zone_zangarmarsh.cpp | 5 +-- src/server/scripts/Spells/spell_generic.cpp | 2 +- src/server/scripts/World/npcs_special.cpp | 6 +-- 83 files changed, 227 insertions(+), 278 deletions(-) diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index e50d17334f..2e33b665cb 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -52,7 +52,7 @@ BfWGCoordGY const WGGraveYard[BATTLEFIELD_WG_GRAVEYARD_MAX] = }; uint32 const ClockWorldState[] = { 3781, 4354 }; -uint32 const WintergraspFaction[] = { 1732, 1735, 35 }; +uint32 const WintergraspFaction[] = { FACTION_ALLIANCE_GENERIC_WG, FACTION_HORDE_GENERIC_WG, FACTION_FRIENDLY }; Position const WintergraspStalkerPos = { 4948.985f, 2937.789f, 550.5172f, 1.815142f }; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index 1e99ead36e..394746cb6a 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -399,7 +399,7 @@ void BattlegroundAB::_NodeOccupied(uint8 node, Team team) //aura should only apply to players who have accupied the node, set correct faction for trigger if (trigger) { - trigger->SetFaction(team == ALLIANCE ? 84 : 83); + trigger->SetFaction(team == ALLIANCE ? FACTION_ALLIANCE_GENERIC : FACTION_HORDE_GENERIC); trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false); } } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp index 6348513c08..81f31bb349 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp @@ -752,7 +752,7 @@ void BattlegroundAV::PopulateNode(BG_AV_Nodes node) DelCreature(node + 302); return; } - trigger->SetFaction(owner == ALLIANCE ? 84 : 83); + trigger->SetFaction(owner == ALLIANCE ? FACTION_ALLIANCE_GENERIC : FACTION_HORDE_GENERIC); trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false); } } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index b196fb4fe6..4bf1dd15b3 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -783,7 +783,7 @@ void BattlegroundEY::EventTeamCapturedPoint(Player* player, uint32 Point) //aura should only apply to players who have accupied the node, set correct faction for trigger if (trigger) { - trigger->SetFaction(Team == ALLIANCE ? 84 : 83); + trigger->SetFaction(Team == ALLIANCE ? FACTION_ALLIANCE_GENERIC : FACTION_HORDE_GENERIC); trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false); } } diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 22e073f31a..3615674950 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1886,7 +1886,7 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, TriggerCastFlags trigge } else { - trigger->SetFaction(spellInfo->IsPositive() ? 35 : 14); + trigger->SetFaction(spellInfo->IsPositive() ? FACTION_FRIENDLY : FACTION_MONSTER); // Set owner guid for target if no owner available - needed by trigger auras // - trigger gets despawned and there's no caster avalible (see AuraEffect::TriggerSpell()) trigger->CastSpell(target ? target : trigger, spellInfo, triggered, nullptr, nullptr, target ? target->GetGUID() : ObjectGuid::Empty); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 5d4881ce39..630864d61f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2648,13 +2648,13 @@ void Player::SetGameMaster(bool on) if (on) { m_ExtraFlags |= PLAYER_EXTRA_GM_ON; - SetFaction(35); + SetFaction(FACTION_FRIENDLY); SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_ALLOW_CHEAT_SPELLS); if (Pet* pet = GetPet()) { - pet->SetFaction(35); + pet->SetFaction(FACTION_FRIENDLY); pet->getHostileRefManager().setOnlineOfflineState(false); } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 7364b20bd1..544d88f1c5 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -158,6 +158,51 @@ enum ReputationRank REP_EXALTED = 7 }; +enum FactionTemplates +{ + FACTION_NONE = 0, + FACTION_CREATURE = 7, + FACTION_ESCORTEE_A_NEUTRAL_PASSIVE = 10, + FACTION_MONSTER = 14, + FACTION_MONSTER_2 = 16, + FACTION_TROLL_BLOODSCALP = 28, + FACTION_PREY = 31, + FACTION_ESCORTEE_H_NEUTRAL_PASSIVE = 33, + FACTION_FRIENDLY = 35, + FACTION_OGRE = 45, + FACTION_ORC_DRAGONMAW = 62, + FACTION_HORDE_GENERIC = 83, + FACTION_ALLIANCE_GENERIC = 84, + FACTION_DEMON = 90, + FACTION_ELEMENTAL = 91, + FACTION_DRAGONFLIGHT_BLACK = 103, + FACTION_ESCORTEE_N_NEUTRAL_PASSIVE = 113, + FACTION_ENEMY = 168, + FACTION_ESCORTEE_A_NEUTRAL_ACTIVE = 231, + FACTION_ESCORTEE_H_NEUTRAL_ACTIVE = 232, + FACTION_ESCORTEE_N_NEUTRAL_ACTIVE = 250, + FACTION_ESCORTEE_N_FRIEND_PASSIVE = 290, + FACTION_TITAN = 415, + FACTION_ESCORTEE_N_FRIEND_ACTIVE = 495, + FACTION_GOBLIN_DARK_IRON_BAR_PATRON = 736, + FACTION_DARK_IRON_DWARVES = 754, + FACTION_ESCORTEE_A_PASSIVE = 774, + FACTION_ESCORTEE_H_PASSIVE = 775, + FACTION_UNDEAD_SCOURGE = 974, + FACTION_EARTHEN_RING = 1726, + FACTION_ALLIANCE_GENERIC_WG = 1732, + FACTION_HORDE_GENERIC_WG = 1735, + FACTION_ARAKKOA = 1738, + FACTION_ASHTONGUE_DEATHSWORN = 1820, + FACTION_FLAYER_HUNTER = 1840, + FACTION_MONSTER_SPAR_BUDDY = 1868, + FACTION_ESCORTEE_N_ACTIVE = 1986, + FACTION_ESCORTEE_H_ACTIVE = 2046, + FACTION_UNDEAD_SCOURGE_2 = 2068, + FACTION_UNDEAD_SCOURGE_3 = 2084, + FACTION_SCARLET_CRUSADE = 2089 +}; + #define MIN_REPUTATION_RANK (REP_HATED) #define MAX_REPUTATION_RANK 8 diff --git a/src/server/game/Scripting/ScriptSystem.h b/src/server/game/Scripting/ScriptSystem.h index ce4d4302e9..c67316eb64 100644 --- a/src/server/game/Scripting/ScriptSystem.h +++ b/src/server/game/Scripting/ScriptSystem.h @@ -12,30 +12,6 @@ class Creature; #define TEXT_SOURCE_RANGE -1000000 //the amount of entries each text source has available -/// @todo find better namings and definitions. -//N=Neutral, A=Alliance, H=Horde. -//NEUTRAL or FRIEND = Hostility to player surroundings (not a good definition) -//ACTIVE or PASSIVE = Hostility to environment surroundings. -enum eEscortFaction -{ - FACTION_ESCORT_A_NEUTRAL_PASSIVE = 10, - FACTION_ESCORT_H_NEUTRAL_PASSIVE = 33, - FACTION_ESCORT_N_NEUTRAL_PASSIVE = 113, - - FACTION_ESCORT_A_NEUTRAL_ACTIVE = 231, - FACTION_ESCORT_H_NEUTRAL_ACTIVE = 232, - FACTION_ESCORT_N_NEUTRAL_ACTIVE = 250, - - FACTION_ESCORT_N_FRIEND_PASSIVE = 290, - FACTION_ESCORT_N_FRIEND_ACTIVE = 495, - - FACTION_ESCORT_A_PASSIVE = 774, - FACTION_ESCORT_H_PASSIVE = 775, - - FACTION_ESCORT_N_ACTIVE = 1986, - FACTION_ESCORT_H_ACTIVE = 2046 -}; - struct ScriptPointMove { uint32 uiCreatureEntry; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp index 9b29d8c29b..547982b7dc 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp @@ -1,4 +1,4 @@ -/* +14/* * Copyright (C) 2008-2017 TrinityCore * * This program is free software; you can redistribute it and/or modify it @@ -595,7 +595,7 @@ public: //spell by trap has effect61, this indicate the bar go hostile if (Unit* tmp = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_PHALANX))) - tmp->SetFaction(14); + tmp->SetFaction(FACTION_MONSTER); //for later, this event(s) has alot more to it. //optionally, DONE can trigger bar to go hostile. diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp index c74c5ae0f8..c87325869d 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp @@ -95,8 +95,6 @@ enum DirebrewEvents enum DirebrewMisc { - COREN_DIREBREW_FACTION_HOSTILE = 736, - COREN_DIREBREW_FACTION_FRIEND = 35, GOSSIP_ID = 11388, GO_MOLE_MACHINE_TRAP = 188509, GOSSIP_OPTION_FIGHT = 0, @@ -139,7 +137,7 @@ public: { _Reset(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetFaction(COREN_DIREBREW_FACTION_FRIEND); + me->SetFaction(FACTION_FRIENDLY); events.SetPhase(PHASE_ALL); for (uint8 i = 0; i < MAX_ANTAGONISTS; ++i) @@ -162,7 +160,7 @@ public: { events.SetPhase(PHASE_ONE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetFaction(COREN_DIREBREW_FACTION_HOSTILE); + me->SetFaction(FACTION_GOBLIN_DARK_IRON_BAR_PATRON); me->SetInCombatWithZone(); EntryCheckPredicate pred(NPC_ANTAGONIST); @@ -353,7 +351,7 @@ public: void Reset() override { - me->SetFaction(COREN_DIREBREW_FACTION_HOSTILE); + me->SetFaction(FACTION_GOBLIN_DARK_IRON_BAR_PATRON); DoCastAOE(SPELL_MOLE_MACHINE_EMERGE, true); me->SetInCombatWithZone(); } @@ -395,7 +393,7 @@ public: break; case ACTION_ANTAGONIST_HOSTILE: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetFaction(COREN_DIREBREW_FACTION_HOSTILE); + me->SetFaction(FACTION_GOBLIN_DARK_IRON_BAR_PATRON); me->SetInCombatWithZone(); break; default: diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp index 56e7223654..b3b3a0f2b4 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp @@ -73,7 +73,7 @@ class boss_emperor_dagran_thaurissan : public CreatureScript if (Creature* moira = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_MOIRA))) { moira->AI()->EnterEvadeMode(); - moira->SetFaction(35); + moira->SetFaction(FACTION_FRIENDLY); } } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp index 86ae8fdcce..b4ebc8b05a 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp @@ -134,7 +134,7 @@ class boss_doomrel : public CreatureScript case GOSSIP_ACTION_INFO_DEF+2: CloseGossipMenuFor(player); //start event here - creature->SetFaction(FACTION_HOSTILE); + creature->SetFaction(FACTION_DARK_IRON_DWARVES); creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); creature->AI()->AttackStart(player); InstanceScript* instance = creature->GetInstanceScript(); @@ -170,7 +170,7 @@ class boss_doomrel : public CreatureScript { Initialize(); - me->SetFaction(FACTION_FRIEND); + me->SetFaction(FACTION_FRIENDLY); // was set before event start, so set again me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp index 8d2d316450..1bc8d78b79 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp @@ -351,7 +351,7 @@ public: { if (Creature* boss = instance->GetCreature(TombBossGUIDs[TombEventCounter])) { - boss->SetFaction(FACTION_HOSTILE); + boss->SetFaction(FACTION_DARK_IRON_DWARVES); boss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); if (Unit* target = boss->SelectNearestTarget(500)) boss->AI()->AttackStart(target); @@ -377,7 +377,7 @@ public: boss->GetMotionMaster()->MoveTargetedHome(); boss->SetLootRecipient(NULL); } - boss->SetFaction(FACTION_FRIEND); + boss->SetFaction(FACTION_FRIENDLY); } } GhostKillCount = 0; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp index cbea54d1e1..4791f4ecf1 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp @@ -187,7 +187,7 @@ public: me->SetVisible(true); me->SetUInt32Value(UNIT_NPC_FLAGS, 1); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); me->SetStandState(UNIT_STAND_STATE_SIT_HIGH_CHAIR); me->RemoveAura(SPELL_NEFARIANS_BARRIER); } @@ -204,7 +204,7 @@ public: Talk(SAY_GAMESBEGIN_2); - me->SetFaction(103); + me->SetFaction(FACTION_DRAGONFLIGHT_BLACK); me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); DoCast(me, SPELL_NEFARIANS_BARRIER); me->SetStandState(UNIT_STAND_STATE_STAND); @@ -339,7 +339,7 @@ public: CreatureID = Entry[urand(0, 4)]; if (Creature* dragon = me->SummonCreature(CreatureID, DrakeSpawnLoc[i])) { - dragon->SetFaction(103); + dragon->SetFaction(FACTION_DRAGONFLIGHT_BLACK); dragon->AI()->AttackStart(me->GetVictim()); } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp index f890b5eddb..5ed364f0f0 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp @@ -75,7 +75,7 @@ public: { Initialize(); creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - creature->SetFaction(35); + creature->SetFaction(FACTION_FRIENDLY); creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } @@ -153,7 +153,7 @@ public: events.ScheduleEvent(EVENT_SPEECH_4, 16000); break; case EVENT_SPEECH_4: - me->SetFaction(103); + me->SetFaction(FACTION_DRAGONFLIGHT_BLACK); if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) AttackStart(player); break; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp index c061ae2a42..c91b9bc813 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp @@ -55,7 +55,6 @@ enum Spells enum Extras { OPTION_ID_YOU_CHALLENGED_US = 0, - FACTION_FRIENDLY = 35, MENU_OPTION_YOU_CHALLENGED_US = 4108 }; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp index 57dc8f03f3..481472f854 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp @@ -173,7 +173,7 @@ class boss_ragnaros : public CreatureScript { //Become unbanished again me->SetReactState(REACT_AGGRESSIVE); - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); @@ -251,7 +251,7 @@ class boss_ragnaros : public CreatureScript me->InterruptNonMeleeSpells(false); //Root self //DoCast(me, 23973); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED); me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE); diff --git a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp index 16fe9b7569..0130f7b9a8 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp @@ -1378,7 +1378,7 @@ void boss_julianne::boss_julianneAI::UpdateAI(uint32 diff) { Talk(SAY_JULIANNE_AGGRO); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetFaction(16); + me->SetFaction(FACTION_MONSTER_2); AggroYellTimer = 0; } else AggroYellTimer -= diff; } @@ -1406,7 +1406,7 @@ void boss_julianne::boss_julianneAI::UpdateAI(uint32 diff) ENSURE_AI(boss_romulo::boss_romuloAI, pRomulo->AI())->Phase = PHASE_ROMULO; DoZoneInCombat(pRomulo); - pRomulo->SetFaction(16); + pRomulo->SetFaction(FACTION_MONSTER_2); } SummonedRomulo = true; } else SummonRomuloTimer -= diff; diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index 5b8fe23530..e8045f9405 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -460,7 +460,7 @@ public: Initialize(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); DoCast(me, SPELL_FLAMESTRIKE2, true); } @@ -666,7 +666,7 @@ public: me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetDisableGravity(true); - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); DoCast(me, SPELL_ARCANE_SPHERE_PASSIVE, true); } diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp index f3038407da..774cf41fd1 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp @@ -125,7 +125,7 @@ public: { Initialize(); events.Reset(); - me->SetFaction(7); + me->SetFaction(FACTION_CREATURE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); me->SetStandState(UNIT_STAND_STATE_KNEEL); me->LoadEquipment(0, true); @@ -231,7 +231,7 @@ public: wait_timer -= diff; else { - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); phase = PHASE_ATTACKING; @@ -465,8 +465,7 @@ enum Says_VBM enum Misc_VBN { - QUEST_DEATH_CHALLENGE = 12733, - FACTION_HOSTILE = 2068 + QUEST_DEATH_CHALLENGE = 12733 }; class npc_death_knight_initiate : public CreatureScript @@ -585,7 +584,7 @@ public: { if (m_uiDuelTimer <= uiDiff) { - me->SetFaction(FACTION_HOSTILE); + me->SetFaction(FACTION_UNDEAD_SCOURGE_2); if (Unit* unit = ObjectAccessor::GetUnit(*me, m_uiDuelerGUID)) AttackStart(unit); @@ -771,7 +770,7 @@ public: { charmer->RemoveAurasDueToSpell(SPELL_EFFECT_STOLEN_HORSE); caster->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); - caster->SetFaction(35); + caster->SetFaction(FACTION_FRIENDLY); DoCast(caster, SPELL_CALL_DARK_RIDER, true); if (Creature* Dark_Rider = me->FindNearestCreature(NPC_DARK_RIDER_OF_ACHERUS, 15)) ENSURE_AI(npc_dark_rider_of_acherus::npc_dark_rider_of_acherusAI, Dark_Rider->AI())->InitDespawnHorse(caster); diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp index 396d5fb2fa..42c10ed929 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp @@ -649,7 +649,7 @@ public: { Unit* temp = me->SummonCreature(NPC_ACHERUS_GHOUL, (me->GetPositionX() - 20) + rand32() % 40, (me->GetPositionY() - 20) + rand32() % 40, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); temp->SetWalk(false); - temp->SetFaction(2084); + temp->SetFaction(FACTION_UNDEAD_SCOURGE_3); uiGhoulGUID[uiSummon_counter] = temp->GetGUID(); ++uiSummon_counter; } @@ -667,7 +667,7 @@ public: { Unit* temp = me->SummonCreature(NPC_RAMPAGING_ABOMINATION, (me->GetPositionX() - 20) + rand32() % 40, (me->GetPositionY() - 20) + rand32() % 40, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); temp->SetWalk(false); - temp->SetFaction(2084); + temp->SetFaction(FACTION_UNDEAD_SCOURGE_3); uiAbominationGUID[uiSummon_counter] = temp->GetGUID(); ++uiSummon_counter; } @@ -685,7 +685,7 @@ public: { Unit* temp = me->SummonCreature(NPC_WARRIOR_OF_THE_FROZEN_WASTES, (me->GetPositionX() - 20) + rand32() % 40, (me->GetPositionY() - 20) + rand32() % 40, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); temp->SetWalk(false); - temp->SetFaction(2084); + temp->SetFaction(FACTION_UNDEAD_SCOURGE_3); uiWarriorGUID[uiSummon_counter] = temp->GetGUID(); ++uiSummon_counter; } @@ -703,7 +703,7 @@ public: { Unit* temp = me->SummonCreature(NPC_FLESH_BEHEMOTH, (me->GetPositionX() - 20) + rand32() % 40, (me->GetPositionY() - 20) + rand32() % 40, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); temp->SetWalk(false); - temp->SetFaction(2084); + temp->SetFaction(FACTION_UNDEAD_SCOURGE_3); uiBehemothGUID[uiSummon_counter] = temp->GetGUID(); ++uiSummon_counter; } @@ -1535,7 +1535,7 @@ public: if (!temp) { temp = me->SummonCreature(NPC_ACHERUS_GHOUL, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); - temp->SetFaction(2084); + temp->SetFaction(FACTION_UNDEAD_SCOURGE_3); uiGhoulGUID[i] = temp->GetGUID(); } } @@ -1545,7 +1545,7 @@ public: if (!temp) { temp = me->SummonCreature(NPC_WARRIOR_OF_THE_FROZEN_WASTES, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); - temp->SetFaction(2084); + temp->SetFaction(FACTION_UNDEAD_SCOURGE_3); uiAbominationGUID[i] = temp->GetGUID(); } } @@ -1555,7 +1555,7 @@ public: if (!temp) { temp = me->SummonCreature(NPC_RAMPAGING_ABOMINATION, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); - temp->SetFaction(2084); + temp->SetFaction(FACTION_UNDEAD_SCOURGE_3); uiWarriorGUID[i] = temp->GetGUID(); } } @@ -1565,7 +1565,7 @@ public: if (!temp) { temp = me->SummonCreature(NPC_FLESH_BEHEMOTH, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); - temp->SetFaction(2084); + temp->SetFaction(FACTION_UNDEAD_SCOURGE_3); uiBehemothGUID[i] = temp->GetGUID(); } } @@ -1577,7 +1577,7 @@ public: if (!temp) { temp = me->SummonCreature(NPC_DEFENDER_OF_THE_LIGHT, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); - temp->SetFaction(2089); + temp->SetFaction(FACTION_SCARLET_CRUSADE); me->AddThreat(temp, 0.0f); uiDefenderGUID[i] = temp->GetGUID(); } @@ -1588,7 +1588,7 @@ public: if (!temp) { temp = me->SummonCreature(NPC_RIMBLAT_EARTHSHATTER, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); - temp->SetFaction(2089); + temp->SetFaction(FACTION_SCARLET_CRUSADE); me->AddThreat(temp, 0.0f); uiEarthshatterGUID[i] = temp->GetGUID(); } @@ -1597,7 +1597,7 @@ public: if (!temp) { temp = me->SummonCreature(NPC_KORFAX_CHAMPION_OF_THE_LIGHT, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000); - temp->SetFaction(2089); + temp->SetFaction(FACTION_SCARLET_CRUSADE); me->AddThreat(temp, 0.0f); uiKorfaxGUID = temp->GetGUID(); } @@ -1605,7 +1605,7 @@ public: if (!temp) { temp = me->SummonCreature(NPC_LORD_MAXWELL_TYROSUS, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000); - temp->SetFaction(2089); + temp->SetFaction(FACTION_SCARLET_CRUSADE); me->AddThreat(temp, 0.0f); uiMaxwellGUID = temp->GetGUID(); } @@ -1613,7 +1613,7 @@ public: if (!temp) { temp = me->SummonCreature(NPC_COMMANDER_ELIGOR_DAWNBRINGER, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000); - temp->SetFaction(2089); + temp->SetFaction(FACTION_SCARLET_CRUSADE); me->AddThreat(temp, 0.0f); uiEligorGUID = temp->GetGUID(); } @@ -1621,7 +1621,7 @@ public: if (!temp) { temp = me->SummonCreature(NPC_RAYNE, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000); - temp->SetFaction(2089); + temp->SetFaction(FACTION_SCARLET_CRUSADE); me->AddThreat(temp, 0.0f); uiRayneGUID = temp->GetGUID(); } diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp index 7aadce3f4d..722a7998e6 100644 --- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp +++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp @@ -74,8 +74,6 @@ enum ApothecaryMisc { ACTION_START_EVENT = 1, ACTION_START_FIGHT = 2, - FACTION_APOTHECARY_HOSTILE = 14, - FACTION_APOTHECARY_FRIENDLY = 35, GOSSIP_OPTION_START = 0, GOSSIP_MENU_HUMMEL = 10847, QUEST_YOUVE_BEEN_SERVED = 14488, @@ -115,7 +113,7 @@ class boss_apothecary_hummel : public CreatureScript _deadCount = 0; _isDead = false; events.SetPhase(PHASE_ALL); - me->SetFaction(FACTION_APOTHECARY_FRIENDLY); + me->SetFaction(FACTION_FRIENDLY); me->SummonCreatureGroup(1); } @@ -134,7 +132,7 @@ class boss_apothecary_hummel : public CreatureScript events.ScheduleEvent(EVENT_HUMMEL_SAY_0, Milliseconds(1)); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetFaction(FACTION_APOTHECARY_HOSTILE); + me->SetFaction(FACTION_MONSTER); DummyEntryCheckPredicate pred; summons.DoAction(ACTION_START_EVENT, pred); } @@ -289,7 +287,7 @@ struct npc_apothecary_genericAI : public ScriptedAI if (action == ACTION_START_EVENT) { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetFaction(FACTION_APOTHECARY_HOSTILE); + me->SetFaction(FACTION_MONSTER); me->GetMotionMaster()->MovePoint(1, _movePos); } else if (action == ACTION_START_FIGHT) diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp index 34289a5a41..5db76065f7 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp @@ -155,7 +155,7 @@ public: if (Creature* Sath = ObjectAccessor::GetCreature(*me, SathGUID)) Sath->AI()->EnterEvadeMode(); - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); if (!bJustReset) //first reset at create { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); @@ -379,7 +379,7 @@ public: switch (TalkSequence) { case 1: - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); TalkTimer = 1000; break; case 2: diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp index dd5f9c2bf9..6e4a1cbb0c 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp @@ -287,7 +287,7 @@ public: me->RemoveDynObject(SPELL_RING_OF_BLUE_FLAMES); for (uint8 i = 0; i < 4; ++i) if (GameObject* pOrb = GetOrb(i)) - pOrb->SetFaction(0); + pOrb->SetFaction(FACTION_NONE); } void EmpowerOrb(bool all) @@ -304,7 +304,7 @@ public: if (GameObject* pOrb = GetOrb(i)) { pOrb->CastSpell(me, SPELL_RING_OF_BLUE_FLAMES); - pOrb->SetFaction(35); + pOrb->SetFaction(FACTION_FRIENDLY); pOrb->setActive(true); pOrb->Refresh(); } @@ -316,7 +316,7 @@ public: if (GameObject* pOrb = GetOrb(urand(0, 3))) { pOrb->CastSpell(me, SPELL_RING_OF_BLUE_FLAMES); - pOrb->SetFaction(35); + pOrb->SetFaction(FACTION_FRIENDLY); pOrb->setActive(true); pOrb->Refresh(); @@ -369,7 +369,7 @@ public: InstanceScript* instance = go->GetInstanceScript(); player->SummonCreature(NPC_POWER_OF_THE_BLUE_DRAGONFLIGHT, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 121000); player->CastSpell(player, SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT, false); - go->SetFaction(0); + go->SetFaction(FACTION_NONE); if (Creature* pKalec = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_KALECGOS_KJ))) ENSURE_AI(boss_kalecgos_kj::boss_kalecgos_kjAI, pKalec->AI())->SetRingOfBlueFlames(); diff --git a/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp b/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp index eae2d3a047..3e237a1876 100644 --- a/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp +++ b/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp @@ -96,7 +96,7 @@ class boss_archaedas : public CreatureScript Initialize(); instance->SetData(0, 5); // respawn any dead minions - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetControlled(true, UNIT_STATE_ROOT); me->AddAura(SPELL_FREEZE_ANIM, me); @@ -112,14 +112,14 @@ class boss_archaedas : public CreatureScript minion->CastSpell(minion, SPELL_ARCHAEDAS_AWAKEN, true); minion->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); minion->SetControlled(false, UNIT_STATE_ROOT); - minion->SetFaction(14); + minion->SetFaction(FACTION_MONSTER); minion->RemoveAura(SPELL_MINION_FREEZE_ANIM); } } void EnterCombat(Unit* /*who*/) override { - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetControlled(false, UNIT_STATE_ROOT); } @@ -259,7 +259,7 @@ class npc_archaedas_minions : public CreatureScript { Initialize(); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetControlled(true, UNIT_STATE_ROOT); me->RemoveAllAuras(); @@ -268,7 +268,7 @@ class npc_archaedas_minions : public CreatureScript void EnterCombat(Unit* /*who*/) override { - me->SetFaction (14); + me->SetFaction (FACTION_MONSTER); me->RemoveAllAuras(); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetControlled(false, UNIT_STATE_ROOT); @@ -348,7 +348,7 @@ class npc_stonekeepers : public CreatureScript void Reset() override { - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetControlled(true, UNIT_STATE_ROOT); me->RemoveAllAuras(); @@ -357,7 +357,7 @@ class npc_stonekeepers : public CreatureScript void EnterCombat(Unit* /*who*/) override { - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetControlled(false, UNIT_STATE_ROOT); } diff --git a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp index 47b8d8d4ec..bd332448f2 100644 --- a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp +++ b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp @@ -144,7 +144,7 @@ class instance_uldaman : public InstanceMapScript void SetFrozenState(Creature* creature) { - creature->SetFaction(35); + creature->SetFaction(FACTION_FRIENDLY); creature->RemoveAllAuras(); creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); creature->SetControlled(true, UNIT_STATE_ROOT); @@ -179,7 +179,7 @@ class instance_uldaman : public InstanceMapScript if (!target || !target->IsAlive()) continue; target->SetControlled(false, UNIT_STATE_ROOT); - target->SetFaction(14); + target->SetFaction(FACTION_MONSTER); target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); target->RemoveAura(SPELL_MINION_FREEZE_ANIM); @@ -200,11 +200,11 @@ class instance_uldaman : public InstanceMapScript for (GuidVector::const_iterator i = archaedasWallMinions.begin(); i != archaedasWallMinions.end(); ++i) { Creature* target = instance->GetCreature(*i); - if (!target || !target->IsAlive() || target->GetFaction() == 14) + if (!target || !target->IsAlive() || target->GetFaction() == FACTION_MONSTER) continue; target->SetControlled(false, UNIT_STATE_ROOT); target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - target->SetFaction(14); + target->SetFaction(FACTION_MONSTER); target->RemoveAura(SPELL_MINION_FREEZE_ANIM); archaedas->CastSpell(target, SPELL_AWAKEN_VAULT_WALKER, true); target->CastSpell(target, SPELL_ARCHAEDAS_AWAKEN, true); @@ -267,7 +267,7 @@ class instance_uldaman : public InstanceMapScript if (!ironaya) return; - ironaya->SetFaction(415); + ironaya->SetFaction(FACTION_TITAN); ironaya->SetControlled(false, UNIT_STATE_ROOT); ironaya->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp index 9c361a97ff..40de85ea67 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp @@ -196,7 +196,7 @@ class boss_akilzon : public CreatureScript y = 1380.0f + rand32() % 60; if (Unit* trigger = me->SummonTrigger(x, y, z, 0, 2000)) { - trigger->SetFaction(35); + trigger->SetFaction(FACTION_FRIENDLY); trigger->SetMaxHealth(100000); trigger->SetHealth(100000); trigger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); @@ -291,7 +291,7 @@ class boss_akilzon : public CreatureScript Cloud->SetDisableGravity(true); Cloud->StopMoving(); Cloud->SetObjectScale(1.0f); - Cloud->SetFaction(35); + Cloud->SetFaction(FACTION_FRIENDLY); Cloud->SetMaxHealth(9999999); Cloud->SetHealth(9999999); Cloud->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); diff --git a/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp b/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp index 33ca93739c..533031aed4 100644 --- a/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp @@ -57,8 +57,7 @@ enum ProfessorPhizzlethorpe QUEST_SUNKEN_TREASURE = 665, QUEST_GOGGLE_BOGGLE = 26050, // Creatures - NPC_VENGEFUL_SURGE = 2776, - FACTION_SUNKEN_TREASURE = 113 + NPC_VENGEFUL_SURGE = 2776 }; class npc_professor_phizzlethorpe : public CreatureScript @@ -114,7 +113,7 @@ class npc_professor_phizzlethorpe : public CreatureScript { Talk(SAY_PROGRESS_1, player); npc_escortAI::Start(false, false, player->GetGUID(), quest); - me->SetFaction(FACTION_SUNKEN_TREASURE); + me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); } } diff --git a/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp index 76d0d6c702..bdb623c4f2 100644 --- a/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp @@ -52,8 +52,7 @@ enum RangerLilatha GO_CAGE = 181152, NPC_CAPTAIN_HELIOS = 16220, NPC_MUMMIFIED_HEADHUNTER = 16342, - NPC_SHADOWPINE_ORACLE = 16343, - FACTION_QUEST_ESCAPE = 113 + NPC_SHADOWPINE_ORACLE = 16343 }; class npc_ranger_lilatha : public CreatureScript @@ -133,7 +132,7 @@ public: { if (quest->GetQuestId() == QUEST_ESCAPE_FROM_THE_CATACOMBS) { - creature->SetFaction(FACTION_QUEST_ESCAPE); + creature->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); if (npc_escortAI* pEscortAI = CAST_AI(npc_ranger_lilatha::npc_ranger_lilathaAI, creature->AI())) pEscortAI->Start(true, false, player->GetGUID()); diff --git a/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp b/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp index ff3a680b15..5dea92a763 100644 --- a/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp @@ -45,9 +45,7 @@ enum eOOX SAY_OOX_END = 4, QUEST_RESQUE_OOX_09 = 836, NPC_MARAUDING_OWL = 7808, - NPC_VILE_AMBUSHER = 7809, - FACTION_ESCORTEE_A = 774, - FACTION_ESCORTEE_H = 775 + NPC_VILE_AMBUSHER = 7809 }; class npc_oox09hl : public CreatureScript @@ -79,7 +77,7 @@ public: if (quest->GetQuestId() == QUEST_RESQUE_OOX_09) { me->SetStandState(UNIT_STAND_STATE_STAND); - me->SetFaction(player->GetTeam() == ALLIANCE ? FACTION_ESCORTEE_A : FACTION_ESCORTEE_H); + me->SetFaction(player->GetTeam() == ALLIANCE ? FACTION_ESCORTEE_A_PASSIVE : FACTION_ESCORTEE_H_PASSIVE); Talk(SAY_OOX_START, player); npc_escortAI::Start(false, false, player->GetGUID(), quest); } diff --git a/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp b/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp index 2d38b5f3d6..4fd9fa4d86 100644 --- a/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp +++ b/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp @@ -80,7 +80,7 @@ public: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); me->CombatStop(); //stop combat me->DeleteThreatList(); //unsure of this - me->SetFaction(83); //horde generic + me->SetFaction(FACTION_HORDE_GENERIC); bReset = true; Reset_Timer = 60000; @@ -98,7 +98,7 @@ public: { EnterEvadeMode(); bReset = false; - me->SetFaction(28); //troll, bloodscalp + me->SetFaction(FACTION_TROLL_BLOODSCALP); return; } diff --git a/src/server/scripts/EasternKingdoms/zone_wetlands.cpp b/src/server/scripts/EasternKingdoms/zone_wetlands.cpp index c5fd05924d..0647845b5f 100644 --- a/src/server/scripts/EasternKingdoms/zone_wetlands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_wetlands.cpp @@ -40,7 +40,6 @@ EndContentData */ enum TapokeSlim { QUEST_MISSING_DIPLO_PT11 = 1249, - FACTION_ENEMY = 168, SPELL_STEALTH = 1785, SPELL_CALL_FRIENDS = 16457, //summons 1x friend NPC_SLIMS_FRIEND = 4971, diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp index f76c8bf6ca..3464d1b022 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp @@ -923,7 +923,7 @@ void hyjalAI::HideNearPos(float x, float y) for (std::list::const_iterator itr = creatures.begin(); itr != creatures.end(); ++itr) { (*itr)->SetVisible(false); - (*itr)->SetFaction(35);//make them friendly so mobs won't attack them + (*itr)->SetFaction(FACTION_FRIENDLY);//make them friendly so mobs won't attack them } } } @@ -1022,7 +1022,7 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) if ((*itr) && (*itr)->IsAlive()) { (*itr)->CastSpell(*itr, SPELL_TELEPORT_VISUAL, true); - (*itr)->SetFaction(35);//make them friendly so mobs won't attack them + (*itr)->SetFaction(FACTION_FRIENDLY);//make them friendly so mobs won't attack them (*itr)->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); } } diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp index f839c25291..3651419901 100644 --- a/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp +++ b/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp @@ -82,7 +82,7 @@ public: if (Invisible && InvisibleTimer <= diff) { //Become visible again - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); //Noxxion model me->SetDisplayId(11172); @@ -122,7 +122,7 @@ public: //Interrupt any spell casting //me->m_canMove = true; me->InterruptNonMeleeSpells(false); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // Invisible Model me->SetDisplayId(11686); diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp index bf1b0a4598..45875f9a6e 100644 --- a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp +++ b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp @@ -57,8 +57,6 @@ enum Belnistrasz EVENT_FIREBALL = 5, EVENT_FROST_NOVA = 6, - FACTION_ESCORT = 250, - PATH_ESCORT = 871710, POINT_REACH_IDOL = 17, @@ -136,7 +134,7 @@ public: eventInProgress = true; Talk(SAY_QUEST_ACCEPTED); me->RemoveFlag(UNIT_NPC_FLAGS, GOSSIP_OPTION_QUESTGIVER); - me->SetFaction(FACTION_ESCORT); + me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_ACTIVE); me->GetMotionMaster()->MovePath(PATH_ESCORT, false); } } diff --git a/src/server/scripts/Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp b/src/server/scripts/Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp index 98d2c1d2db..08f5cc4aa9 100644 --- a/src/server/scripts/Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp +++ b/src/server/scripts/Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp @@ -68,7 +68,7 @@ public: switch (go->GetEntry()) { case 21099: DoorWardGUID = go->GetGUID(); break; - case 20920: go->SetFaction(0); break; // big fat fugly hack + case 20920: go->SetFaction(FACTION_NONE); break; // big fat fugly hack } } diff --git a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp index 07f9afcd5c..bfd92dce47 100644 --- a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp +++ b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp @@ -57,7 +57,7 @@ public: { Start(true, false, player->GetGUID()); Talk(SAY_READY, player); - me->SetFaction(113); + me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); } } diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp index 2627687586..2e8ee5f425 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp @@ -112,7 +112,7 @@ public: //Cast me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); DoCast(me, SPELL_DIRTMOUND_PASSIVE); Submerged = true; @@ -135,7 +135,7 @@ public: if (Submerged && Back_Timer <= diff) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); DoCastVictim(SPELL_GROUND_RUPTURE); diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp index 43ca24179b..dbaee5e184 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp @@ -332,7 +332,7 @@ struct boss_twinemperorsAI : public ScriptedAI if (c->isDead()) { c->Respawn(); - c->SetFaction(7); + c->SetFaction(FACTION_CREATURE); c->RemoveAllAuras(); } if (c->IsWithinDistInMap(me, ABUSE_BUG_RANGE)) @@ -427,7 +427,7 @@ public: void CastSpellOnBug(Creature* target) override { - target->SetFaction(14); + target->SetFaction(FACTION_MONSTER); target->AI()->AttackStart(me->getThreatManager().getHostilTarget()); target->AddAura(SPELL_MUTATE_BUG, target); target->SetFullHealth(); @@ -518,7 +518,7 @@ public: void CastSpellOnBug(Creature* target) override { - target->SetFaction(14); + target->SetFaction(FACTION_MONSTER); target->AddAura(SPELL_EXPLODEBUG, target); target->SetFullHealth(); } diff --git a/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp b/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp index bd77e4c954..810aa789ea 100644 --- a/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp +++ b/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp @@ -96,7 +96,7 @@ public: creature->AI()->Talk(SAY_MAKE_PREPARATIONS); - creature->SetFaction(250); + creature->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_ACTIVE); creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); ENSURE_AI(npc_escortAI, (creature->AI()))->Start(false, false, player->GetGUID()); diff --git a/src/server/scripts/Kalimdor/ZulFarrak/boss_zum_rah.cpp b/src/server/scripts/Kalimdor/ZulFarrak/boss_zum_rah.cpp index 111a897d74..3bae896e0e 100644 --- a/src/server/scripts/Kalimdor/ZulFarrak/boss_zum_rah.cpp +++ b/src/server/scripts/Kalimdor/ZulFarrak/boss_zum_rah.cpp @@ -47,11 +47,6 @@ enum Events EVENT_HEALING_WAVE = 4 }; -enum Faction -{ - ZUMRAH_FRIENDLY_FACTION = 35 -}; - class boss_zum_rah : public CreatureScript { public: @@ -73,7 +68,7 @@ public: void Reset() override { - me->SetFaction(ZUMRAH_FRIENDLY_FACTION); // areatrigger sets faction to enemy + me->SetFaction(FACTION_FRIENDLY); // areatrigger sets faction to enemy Initialize(); } diff --git a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp index 51bc5b7a94..ed166973fc 100644 --- a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp +++ b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp @@ -38,13 +38,6 @@ EndContentData */ ## npc_sergeant_bly ######*/ -enum blyAndCrewFactions -{ - FACTION_HOSTILE = 14, - FACTION_FRIENDLY = 35, //while in cages (so the trolls won't attack them while they're caged) - FACTION_FREED = 250 //after release (so they'll be hostile towards trolls) -}; - enum blySays { SAY_1 = 0, @@ -151,7 +144,7 @@ public: Text_Timer = 5000; break; case 3: - me->SetFaction(FACTION_HOSTILE); + me->SetFaction(FACTION_MONSTER); if (Player* target = ObjectAccessor::GetPlayer(*me, PlayerGUID)) AttackStart(target); @@ -196,7 +189,7 @@ public: { if (Creature* crew = ObjectAccessor::GetCreature(*me, instance->GetGuidData(entry))) if (crew->IsAlive()) - crew->SetFaction(FACTION_HOSTILE); + crew->SetFaction(FACTION_MONSTER); } }; @@ -235,7 +228,7 @@ private: crew->SetWalk(true); crew->SetHomePosition(x, y, z, 0); crew->GetMotionMaster()->MovePoint(1, x, y, z); - crew->SetFaction(FACTION_FREED); + crew->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_ACTIVE); } } }; diff --git a/src/server/scripts/Kalimdor/zone_ashenvale.cpp b/src/server/scripts/Kalimdor/zone_ashenvale.cpp index ecd1f2e4d6..d8a8affd13 100644 --- a/src/server/scripts/Kalimdor/zone_ashenvale.cpp +++ b/src/server/scripts/Kalimdor/zone_ashenvale.cpp @@ -43,7 +43,6 @@ enum RuulSnowhoof NPC_THISTLEFUR_TOTEMIC = 3922, NPC_THISTLEFUR_PATHFINDER = 3926, QUEST_FREEDOM_TO_RUUL = 6482, - FACTION_QUEST = 113, GO_CAGE = 178147 }; @@ -83,7 +82,7 @@ public: { if (quest->GetQuestId() == QUEST_FREEDOM_TO_RUUL) { - me->SetFaction(FACTION_QUEST); + me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); npc_escortAI::Start(true, false, player->GetGUID()); } } @@ -226,7 +225,7 @@ public: if (quest->GetQuestId() == QUEST_VORSHA) { Talk(SAY_MUG_START1); - me->SetFaction(FACTION_QUEST); + me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); npc_escortAI::Start(true, false, player->GetGUID()); } } diff --git a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp index e0bb4c1410..88f5185bb8 100644 --- a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp +++ b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp @@ -187,7 +187,6 @@ enum Overgrind AREA_COVE = 3579, AREA_ISLE = 3639, QUEST_GNOMERCY = 9537, - FACTION_HOSTILE = 14, SPELL_DYNAMITE = 7978 }; @@ -232,7 +231,7 @@ public: void sGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override { CloseGossipMenuFor(player); - me->SetFaction(FACTION_HOSTILE); + me->SetFaction(FACTION_MONSTER); me->Attack(player, true); } @@ -337,8 +336,7 @@ enum Magwin EVENT_STAND = 3, EVENT_TALK_END = 4, EVENT_COWLEN_TALK = 5, - QUEST_A_CRY_FOR_HELP = 9528, - FACTION_QUEST = 113 + QUEST_A_CRY_FOR_HELP = 9528 }; class npc_magwin : public CreatureScript @@ -403,7 +401,7 @@ public: case EVENT_ACCEPT_QUEST: if (Player* player = ObjectAccessor::GetPlayer(*me, _player)) Talk(SAY_START, player); - me->SetFaction(FACTION_QUEST); + me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); _events.ScheduleEvent(EVENT_START_ESCORT, Seconds(1)); break; case EVENT_START_ESCORT: diff --git a/src/server/scripts/Kalimdor/zone_silithus.cpp b/src/server/scripts/Kalimdor/zone_silithus.cpp index c07078a017..25e78a79c7 100644 --- a/src/server/scripts/Kalimdor/zone_silithus.cpp +++ b/src/server/scripts/Kalimdor/zone_silithus.cpp @@ -42,9 +42,6 @@ enum EternalBoard { QUEST_A_PAWN_ON_THE_ETERNAL_BOARD = 8519, - FACTION_HOSTILE = 14, - FACTION_FRIENDLY = 35, - EVENT_AREA_RADIUS = 65, // 65yds EVENT_COOLDOWN = 500000, // in ms. appears after event completed or failed (should be = Adds despawn time) @@ -970,7 +967,7 @@ public: Merithra->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); Merithra->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); Merithra->SetUInt32Value(UNIT_FIELD_DISPLAYID, MERITHRA_NIGHT_ELF_FORM); - Merithra->SetFaction(35); + Merithra->SetFaction(FACTION_FRIENDLY); } if (Caelestrasz) @@ -978,7 +975,7 @@ public: Caelestrasz->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); Caelestrasz->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); Caelestrasz->SetUInt32Value(UNIT_FIELD_DISPLAYID, CAELESTRASZ_NIGHT_ELF_FORM); - Caelestrasz->SetFaction(35); + Caelestrasz->SetFaction(FACTION_FRIENDLY); } if (Arygos) @@ -986,7 +983,7 @@ public: Arygos->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); Arygos->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); Arygos->SetUInt32Value(UNIT_FIELD_DISPLAYID, ARYGOS_GNOME_FORM); - Arygos->SetFaction(35); + Arygos->SetFaction(FACTION_FRIENDLY); } if (Anachronos) diff --git a/src/server/scripts/Kalimdor/zone_tanaris.cpp b/src/server/scripts/Kalimdor/zone_tanaris.cpp index fdc4cef041..e05ab14c16 100644 --- a/src/server/scripts/Kalimdor/zone_tanaris.cpp +++ b/src/server/scripts/Kalimdor/zone_tanaris.cpp @@ -91,7 +91,7 @@ public: void Reset() override { Initialize(); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); } void SendItem(Unit* receiver) @@ -121,7 +121,7 @@ public: { if (SwitchFactionTimer <= diff) { - me->SetFaction(91); + me->SetFaction(FACTION_ELEMENTAL); isFriendly = false; } else SwitchFactionTimer -= diff; } @@ -319,7 +319,7 @@ public: { if (quest->GetQuestId() == Q_OOX17) { - creature->SetFaction(113); + creature->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); creature->SetFullHealth(); creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp index ad61b20cf3..0b6c7738cc 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp @@ -192,7 +192,7 @@ public: { damage = 0; EnterEvadeMode(); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); bDone = true; } } @@ -320,7 +320,7 @@ public: { damage = 0; EnterEvadeMode(); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); bDone = true; } } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp index c315080327..5e9d6515db 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp @@ -224,7 +224,7 @@ class boss_anubarak_trial : public CreatureScript for (int i = 0; i < 10; i++) if (Creature* scarab = me->SummonCreature(NPC_SCARAB, AnubarakLoc[1].GetPositionX()+urand(0, 50)-25, AnubarakLoc[1].GetPositionY()+urand(0, 50)-25, AnubarakLoc[1].GetPositionZ())) { - scarab->SetFaction(31); + scarab->SetFaction(FACTION_PREY); scarab->GetMotionMaster()->MoveRandom(10); } } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 89da2c8c31..d46d5f6c32 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -202,7 +202,6 @@ enum Actions enum Misc { DATA_MADE_A_MESS = 45374613, // 4537, 4613 are achievement IDs - FACTION_SCOURGE = 974, GOSSIP_MENU_MURADIN_BRONZEBEARD = 10934, GOSSIP_MENU_HIGH_OVERLORD_SAURFANG = 10952 @@ -461,7 +460,7 @@ class boss_deathbringer_saurfang : public CreatureScript { case EVENT_INTRO_ALLIANCE_2: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFaction(FACTION_SCOURGE); + me->SetFaction(FACTION_UNDEAD_SCOURGE); Talk(SAY_INTRO_ALLIANCE_2); break; case EVENT_INTRO_ALLIANCE_3: @@ -474,7 +473,7 @@ class boss_deathbringer_saurfang : public CreatureScript break; case EVENT_INTRO_HORDE_2: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFaction(FACTION_SCOURGE); + me->SetFaction(FACTION_UNDEAD_SCOURGE); Talk(SAY_INTRO_HORDE_2); break; case EVENT_INTRO_HORDE_4: diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index e980ba4d36..dad8012106 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -361,7 +361,7 @@ class boss_lady_deathwhisper : public CreatureScript { if (darnavan->IsAlive()) { - darnavan->SetFaction(35); + darnavan->SetFaction(FACTION_FRIENDLY); darnavan->CombatStop(true); darnavan->GetMotionMaster()->MoveIdle(); darnavan->SetReactState(REACT_PASSIVE); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 7c4d4730b0..5f383641cf 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -170,12 +170,6 @@ enum Seats SEAT_0 = 0 }; -enum Factions -{ - // Needed for melee hover disks /when Nexus Lords die/ - FACTION_FRIENDLY = 35 -}; - enum Actions { // Malygos diff --git a/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp b/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp index 4ae82a8927..dcb1886e81 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp @@ -21,11 +21,6 @@ #include "Player.h" #include "nexus.h" -enum Factions -{ - FACTION_HOSTILE_FOR_ALL = 16 -}; - class instance_nexus : public InstanceMapScript { public: @@ -59,31 +54,31 @@ class instance_nexus : public InstanceMapScript // Alliance npcs are spawned by default, if you are alliance, you will fight against horde npcs. case NPC_ALLIANCE_BERSERKER: if (ServerAllowsTwoSideGroups()) - creature->SetFaction(FACTION_HOSTILE_FOR_ALL); + creature->SetFaction(FACTION_MONSTER_2); if (_teamInInstance == ALLIANCE) creature->UpdateEntry(NPC_HORDE_BERSERKER); break; case NPC_ALLIANCE_RANGER: if (ServerAllowsTwoSideGroups()) - creature->SetFaction(FACTION_HOSTILE_FOR_ALL); + creature->SetFaction(FACTION_MONSTER_2); if (_teamInInstance == ALLIANCE) creature->UpdateEntry(NPC_HORDE_RANGER); break; case NPC_ALLIANCE_CLERIC: if (ServerAllowsTwoSideGroups()) - creature->SetFaction(FACTION_HOSTILE_FOR_ALL); + creature->SetFaction(FACTION_MONSTER_2); if (_teamInInstance == ALLIANCE) creature->UpdateEntry(NPC_HORDE_CLERIC); break; case NPC_ALLIANCE_COMMANDER: if (ServerAllowsTwoSideGroups()) - creature->SetFaction(FACTION_HOSTILE_FOR_ALL); + creature->SetFaction(FACTION_MONSTER_2); if (_teamInInstance == ALLIANCE) creature->UpdateEntry(NPC_HORDE_COMMANDER); break; case NPC_COMMANDER_STOUTBEARD: if (ServerAllowsTwoSideGroups()) - creature->SetFaction(FACTION_HOSTILE_FOR_ALL); + creature->SetFaction(FACTION_MONSTER_2); if (_teamInInstance == ALLIANCE) creature->UpdateEntry(NPC_COMMANDER_KOLURG); break; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index 12fb89bb12..e0b7634173 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -531,7 +531,7 @@ class boss_algalon_the_observer : public CreatureScript damage = 0; me->SetReactState(REACT_PASSIVE); me->AttackStop(); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoCast(me, SPELL_SELF_STUN); events.Reset(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index 24d3a54f07..8a0be11c31 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -222,7 +222,7 @@ class npc_iron_roots : public CreatureScript SetCombatMovement(false); me->ApplySpellImmune(0, IMMUNITY_ID, 49560, true); // Death Grip - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); me->SetReactState(REACT_PASSIVE); } @@ -606,7 +606,7 @@ class boss_freya : public CreatureScript _JustDied(); me->RemoveAllAuras(); me->AttackStop(); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); me->DeleteThreatList(); me->CombatStop(true); me->DespawnOrUnsummon(7500); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp index 2d41216263..8c6f9fc94f 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp @@ -405,7 +405,7 @@ class boss_hodir : public CreatureScript DoCastAOE(SPELL_KILL_CREDIT, true); /// need to be cast before changing boss faction /// spell will target enemies only - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); me->DespawnOrUnsummon(10000); _JustDied(); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp index 5c42276e63..7aa60e8af6 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp @@ -177,7 +177,7 @@ class boss_ignis : public CreatureScript { if (summon->GetEntry() == NPC_IRON_CONSTRUCT) { - summon->SetFaction(16); + summon->SetFaction(FACTION_MONSTER_2); summon->SetReactState(REACT_AGGRESSIVE); summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED | UNIT_FLAG_STUNNED | UNIT_FLAG_IMMUNE_TO_PC); summon->SetControlled(false, UNIT_STATE_ROOT); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index 8152183231..e56de3450c 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -635,7 +635,7 @@ class boss_mimiron : public CreatureScript case EVENT_OUTTRO_1: me->RemoveAurasDueToSpell(SPELL_SLEEP_VISUAL_1); DoCast(me, SPELL_SLEEP_VISUAL_2); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); events.ScheduleEvent(EVENT_OUTTRO_2, 3000); break; case EVENT_OUTTRO_2: diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp index e94d5bd7ab..20674c376b 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp @@ -765,7 +765,7 @@ class boss_sara : public CreatureScript { me->RemoveAllAuras(); me->SetReactState(REACT_PASSIVE); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); _events.Reset(); _events.SetPhase(PHASE_ONE); } @@ -808,7 +808,7 @@ class boss_sara : public CreatureScript case EVENT_TRANSFORM_3: Talk(SAY_SARA_TRANSFORM_4); DoCast(me, SPELL_FULL_HEAL); - me->SetFaction(16); + me->SetFaction(FACTION_MONSTER_2); if (Creature* voice = _instance->GetCreature(DATA_VOICE_OF_YOGG_SARON)) voice->AI()->DoAction(ACTION_PHASE_TWO); if (Creature* mimiron = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_MIMIRON_YS))) diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index f81c06b5a3..3eaf0cc4ac 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -115,7 +115,7 @@ public: DoCast(me, SPELL_EXPLODE_CART, true); DoCast(me, SPELL_SUMMON_CART, true); if (GameObject* cart = me->FindNearestGameObject(GO_EXPLOSIVES_CART, 3.0f)) - cart->SetFaction(14); + cart->SetFaction(FACTION_MONSTER); phaseTimer = 3000; phase = 2; break; @@ -536,9 +536,6 @@ enum Lurgglbr GO_CAGE = 187369, - FACTION_ESCORTEE_A = 774, - FACTION_ESCORTEE_H = 775, - SAY_START_1 = 0, SAY_START_2 = 1, SAY_END_1 = 2, @@ -667,11 +664,11 @@ public: switch (player->GetTeam()) { case ALLIANCE: - creature->SetFaction(FACTION_ESCORTEE_A); + creature->SetFaction(FACTION_ESCORTEE_A_PASSIVE); break; default: case HORDE: - creature->SetFaction(FACTION_ESCORTEE_H); + creature->SetFaction(FACTION_ESCORTEE_H_PASSIVE); break; } @@ -1628,10 +1625,10 @@ public: switch (player->GetTeam()) { case ALLIANCE: - creature->SetFaction(FACTION_ESCORTEE_A); + creature->SetFaction(FACTION_ESCORTEE_A_PASSIVE); break; case HORDE: - creature->SetFaction(FACTION_ESCORTEE_H); + creature->SetFaction(FACTION_ESCORTEE_H_PASSIVE); break; } creature->SetStandState(UNIT_STAND_STATE_STAND); diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp index b1b838eec1..6a8bbf25de 100644 --- a/src/server/scripts/Northrend/zone_dragonblight.cpp +++ b/src/server/scripts/Northrend/zone_dragonblight.cpp @@ -379,9 +379,7 @@ enum StrengthenAncientsMisc SPELL_CREATE_ITEM_BARK = 47550, SPELL_CONFUSED = 47044, - NPC_LOTHALOR = 26321, - - FACTION_WALKER_ENEMY = 14, + NPC_LOTHALOR = 26321 }; class spell_q12096_q12092_dummy : public SpellScriptLoader // Strengthen the Ancients: On Interact Dummy to Woodlands Walker @@ -414,7 +412,7 @@ public: else if (roll == 0) // enemy version { tree->AI()->Talk(SAY_WALKER_ENEMY, player); - tree->SetFaction(FACTION_WALKER_ENEMY); + tree->SetFaction(FACTION_MONSTER); tree->Attack(player, true); } } diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp index e71a92b3e0..a59650993d 100644 --- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp +++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp @@ -102,7 +102,7 @@ public: Talk(SAY_WORGRAGGRO3); if (Creature* RWORG = me->SummonCreature(NPC_RAVENOUS_WORG, me->GetPositionX()+10, me->GetPositionY()+8, me->GetPositionZ()+2, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000)) { - RWORG->SetFaction(35); + RWORG->SetFaction(FACTION_FRIENDLY); _RavenousworgGUID = RWORG->GetGUID(); } break; @@ -135,7 +135,7 @@ public: { RWORG->Kill(Mrfloppy); Mrfloppy->ExitVehicle(); - RWORG->SetFaction(14); + RWORG->SetFaction(FACTION_MONSTER); RWORG->GetMotionMaster()->MovePoint(0, RWORG->GetPositionX()+10, RWORG->GetPositionY()+80, RWORG->GetPositionZ()); Talk(SAY_VICTORY2); } diff --git a/src/server/scripts/Northrend/zone_howling_fjord.cpp b/src/server/scripts/Northrend/zone_howling_fjord.cpp index 7fdac43dca..6cfb43f28b 100644 --- a/src/server/scripts/Northrend/zone_howling_fjord.cpp +++ b/src/server/scripts/Northrend/zone_howling_fjord.cpp @@ -41,7 +41,6 @@ EndContentData */ enum Entries { NPC_APOTHECARY_HANES = 23784, - FACTION_ESCORTEE_H = 775, QUEST_TRAIL_OF_FIRE = 11241, SPELL_HEALING_POTION = 17534, @@ -162,7 +161,7 @@ public: break; case EVENT_START_ESCORT: events.Reset(); - me->SetFaction(FACTION_ESCORTEE_H); + me->SetFaction(FACTION_ESCORTEE_H_PASSIVE); me->SetReactState(REACT_AGGRESSIVE); ENSURE_AI(npc_escortAI, (me->AI()))->Start(true, true, _player); break; diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp index 37ce1ea6d6..849a3d5568 100644 --- a/src/server/scripts/Northrend/zone_icecrown.cpp +++ b/src/server/scripts/Northrend/zone_icecrown.cpp @@ -46,7 +46,7 @@ public: { Initialize(); creature->GetMotionMaster()->MovePoint(0, 8599.258f, 963.951f, 547.553f); - creature->SetFaction(35); //wrong faction in db? + creature->SetFaction(FACTION_FRIENDLY); //wrong faction in db? } void Initialize() @@ -68,7 +68,7 @@ public: if (uiType != POINT_MOTION_TYPE) return; - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); } void DamageTaken(Unit* pDoneBy, uint32& uiDamage) override @@ -77,7 +77,7 @@ public: { uiDamage = 0; pDoneBy->CastSpell(pDoneBy, SPELL_KILL_CREDIT, true); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); me->DespawnOrUnsummon(5000); me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); EnterEvadeMode(); diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp index f252a5a68d..1e59badf45 100644 --- a/src/server/scripts/Northrend/zone_sholazar_basin.cpp +++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp @@ -322,7 +322,7 @@ public: if (npc_engineer_heliceAI* pEscortAI = CAST_AI(npc_engineer_helice::npc_engineer_heliceAI, creature->AI())) { creature->GetMotionMaster()->MoveJumpTo(0, 0.4f, 0.4f); - creature->SetFaction(113); + creature->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); pEscortAI->Start(false, false, player->GetGUID()); creature->AI()->Talk(SAY_WP_1); diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp index b902a0a215..0754ec3fe2 100644 --- a/src/server/scripts/Northrend/zone_storm_peaks.cpp +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -90,7 +90,7 @@ public: if (menuId == GOSSIP_ID && gossipListId == GOSSIP_OPTION_ID) { CloseGossipMenuFor(player); - me->SetFaction(113); + me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); Start(true, true, player->GetGUID()); } } diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp index a02ab0f128..3335b20e42 100644 --- a/src/server/scripts/Northrend/zone_zuldrak.cpp +++ b/src/server/scripts/Northrend/zone_zuldrak.cpp @@ -135,7 +135,7 @@ public: void Reset() override { - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); DoCast(me, SPELL_KNEEL, true); // Little Hack for kneel - Thanks Illy :P } diff --git a/src/server/scripts/Outland/BlackTemple/black_temple.h b/src/server/scripts/Outland/BlackTemple/black_temple.h index 745038961b..46a134886f 100644 --- a/src/server/scripts/Outland/BlackTemple/black_temple.h +++ b/src/server/scripts/Outland/BlackTemple/black_temple.h @@ -131,7 +131,6 @@ enum BTGameObjectIds enum BlackTempleMisc { - ASHTONGUE_FACTION_FRIEND = 1820, AKAMA_FACTION_COMBAT = 1868, AKAMA_INTRO = 1, AKAMA_FIGHT = 2, diff --git a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp index 8fc8c2e2f1..d67317586a 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp @@ -379,7 +379,7 @@ public: void Reset() override { Initialize(); - me->SetFaction(ASHTONGUE_FACTION_FRIEND); + me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); DoCastSelf(SPELL_STEALTH); if (_instance->GetBossState(DATA_SHADE_OF_AKAMA) != DONE) @@ -425,7 +425,7 @@ public: { _isInCombat = false; me->CombatStop(true); - me->SetFaction(ASHTONGUE_FACTION_FRIEND); + me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); me->SetWalk(true); _events.Reset(); me->GetMotionMaster()->MovePoint(AKAMA_INTRO_WAYPOINT, AkamaWP[1]); @@ -479,7 +479,7 @@ public: case EVENT_SHADE_CHANNEL: me->SetFacingTo(FACE_THE_PLATFORM); DoCastSelf(SPELL_AKAMA_SOUL_CHANNEL); - me->SetFaction(AKAMA_FACTION_COMBAT); + me->SetFaction(FACTION_MONSTER_SPAR_BUDDY); _events.ScheduleEvent(EVENT_FIXATE, Seconds(5)); break; case EVENT_FIXATE: @@ -527,7 +527,7 @@ public: } } - if (me->GetFaction() == AKAMA_FACTION_COMBAT) + if (me->GetFaction() == FACTION_MONSTER_SPAR_BUDDY) { if (!UpdateVictim()) return; @@ -1165,7 +1165,7 @@ public: Talk(SAY_BROKEN_SPECIAL); break; case ACTION_BROKEN_HAIL: - me->SetFaction(ASHTONGUE_FACTION_FRIEND); + me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); Talk(SAY_BROKEN_HAIL); break; case ACTION_BROKEN_EMOTE: diff --git a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp index 7fc4cc76a0..a12d920736 100644 --- a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp +++ b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp @@ -123,7 +123,7 @@ class instance_black_temple : public InstanceMapScript case NPC_STORM_FURY: AshtongueGUIDs.emplace_back(creature->GetGUID()); if (GetBossState(DATA_SHADE_OF_AKAMA) == DONE) - creature->SetFaction(ASHTONGUE_FACTION_FRIEND); + creature->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); break; default: break; @@ -170,7 +170,7 @@ class instance_black_temple : public InstanceMapScript if (state == DONE) for (ObjectGuid ashtongueGuid : AshtongueGUIDs) if (Creature* ashtongue = instance->GetCreature(ashtongueGuid)) - ashtongue->SetFaction(ASHTONGUE_FACTION_FRIEND); + ashtongue->SetFaction(FACTION_ASHTONGUE_DEATHSWORN); // no break case DATA_TERON_GOREFIEND: case DATA_GURTOGG_BLOODBOIL: diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp index aa88010319..815aec6ed2 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp @@ -754,7 +754,7 @@ public: void Reset() override { me->SetDisableGravity(true); - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); Initialize(); } @@ -789,7 +789,7 @@ public: { if (Creature* trig = me->SummonCreature(TOXIC_SPORES_TRIGGER, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30000)) { - trig->SetFaction(14); + trig->SetFaction(FACTION_MONSTER); trig->CastSpell(trig, SPELL_TOXIC_SPORES, true); } } @@ -807,7 +807,7 @@ public: // remove me->setDeathState(DEAD); me->RemoveCorpse(); - me->SetFaction(35); + me->SetFaction(FACTION_FRIENDLY); } CheckTimer = 1000; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp index 3e5ee17b86..8640213703 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp @@ -319,7 +319,7 @@ public: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); } void EnterCombat(Unit* /*who*/) override { } diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp index 45a863886d..2bf0b1870f 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp @@ -206,7 +206,7 @@ class boss_grand_warlock_nethekurse : public CreatureScript void JustSummoned(Creature* summoned) override { - summoned->SetFaction(16); + summoned->SetFaction(FACTION_MONSTER_2); summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index 12928ccc76..0ded5aa409 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -1277,7 +1277,7 @@ class npc_kael_flamestrike : public CreatureScript Initialize(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFaction(14); + me->SetFaction(FACTION_MONSTER); } void MoveInLineOfSight(Unit* /*who*/) override { } diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp index 0d4c615d97..6c469601ef 100644 --- a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp +++ b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp @@ -538,7 +538,7 @@ class npc_zerekethvoidzone : public CreatureScript void Reset() override { me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); - me->SetFaction(16); + me->SetFaction(FACTION_MONSTER_2); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoCast(me, SPELL_VOID_ZONE_DAMAGE); diff --git a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp index a3fc6ecb8d..d15e358376 100644 --- a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp +++ b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp @@ -45,8 +45,6 @@ enum Aeranas { SAY_SUMMON = 0, SAY_FREE = 1, - FACTION_HOSTILE = 16, - FACTION_FRIENDLY = 35, SPELL_ENVELOPING_WINDS = 15535, SPELL_SHOCK = 12553 }; @@ -86,7 +84,7 @@ public: { if (faction_Timer <= diff) { - me->SetFaction(FACTION_HOSTILE); + me->SetFaction(FACTION_MONSTER_2); faction_Timer = 0; } else faction_Timer -= diff; } @@ -250,8 +248,7 @@ enum WoundedBloodElf SAY_ELF_AGGRO = 5, QUEST_ROAD_TO_FALCON_WATCH = 9375, NPC_HAALESHI_WINDWALKER = 16966, - NPC_HAALESHI_TALONGUARD = 16967, - FACTION_FALCON_WATCH_QUEST = 775 + NPC_HAALESHI_TALONGUARD = 16967 }; class npc_wounded_blood_elf : public CreatureScript @@ -280,7 +277,7 @@ public: { if (quest->GetQuestId() == QUEST_ROAD_TO_FALCON_WATCH) { - me->SetFaction(FACTION_FALCON_WATCH_QUEST); + me->SetFaction(FACTION_ESCORTEE_H_PASSIVE); npc_escortAI::Start(true, false, player->GetGUID()); } } @@ -1003,7 +1000,7 @@ public: break; case EVENT_ATTACK: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetFaction(FACTION_HOSTILE); + me->SetFaction(FACTION_MONSTER_2); me->CombatStart(ObjectAccessor::GetPlayer(*me, _playerGUID)); _events.ScheduleEvent(EVENT_FIREBALL, 1); _events.ScheduleEvent(EVENT_FROSTNOVA, Seconds(5)); diff --git a/src/server/scripts/Outland/zone_nagrand.cpp b/src/server/scripts/Outland/zone_nagrand.cpp index 98c3433cbd..fd53ec8ba0 100644 --- a/src/server/scripts/Outland/zone_nagrand.cpp +++ b/src/server/scripts/Outland/zone_nagrand.cpp @@ -76,7 +76,7 @@ public: if (npc_maghar_captiveAI* EscortAI = dynamic_cast(creature->AI())) { creature->SetStandState(UNIT_STAND_STATE_STAND); - creature->SetFaction(232); + creature->SetFaction(FACTION_ESCORTEE_H_NEUTRAL_ACTIVE); EscortAI->Start(true, false, player->GetGUID(), quest); creature->AI()->Talk(SAY_MAG_START); @@ -430,7 +430,7 @@ public: if (npc_kurenai_captiveAI* EscortAI = dynamic_cast(creature->AI())) { creature->SetStandState(UNIT_STAND_STATE_STAND); - creature->SetFaction(231); + creature->SetFaction(FACTION_ESCORTEE_A_NEUTRAL_ACTIVE); EscortAI->Start(true, false, player->GetGUID(), quest); creature->AI()->Talk(SAY_KUR_START); diff --git a/src/server/scripts/Outland/zone_netherstorm.cpp b/src/server/scripts/Outland/zone_netherstorm.cpp index 82334302da..4f2eccd751 100644 --- a/src/server/scripts/Outland/zone_netherstorm.cpp +++ b/src/server/scripts/Outland/zone_netherstorm.cpp @@ -496,7 +496,7 @@ public: { if (quest->GetQuestId() == Q_ALMABTRIEB) { - creature->SetFaction(113); + creature->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); } @@ -662,7 +662,7 @@ public: { if (npc_maxx_a_million_escortAI* pEscortAI = CAST_AI(npc_maxx_a_million_escort::npc_maxx_a_million_escortAI, creature->AI())) { - creature->SetFaction(113); + creature->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); pEscortAI->Start(false, false, player->GetGUID()); } } diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp index ac57498ec1..b248b0cced 100644 --- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp +++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp @@ -336,10 +336,6 @@ public: enum EnshlavedNetherwingDrake { - // Factions - FACTION_DEFAULT = 62, - FACTION_FRIENDLY = 1840, // Not sure if this is correct, it was taken off of Mordenai. - // Spells SPELL_HIT_FORCE_OF_NELTHARAKU = 38762, SPELL_FORCE_OF_NELTHARAKU = 38775, @@ -375,7 +371,7 @@ public: void Reset() override { if (!Tapped) - me->SetFaction(FACTION_DEFAULT); + me->SetFaction(FACTION_ORC_DRAGONMAW); FlyTimer = 10000; me->SetDisableGravity(false); @@ -392,7 +388,7 @@ public: Tapped = true; PlayerGUID = caster->GetGUID(); - me->SetFaction(FACTION_FRIENDLY); + me->SetFaction(FACTION_FLAYER_HUNTER); DoCast(caster, SPELL_FORCE_OF_NELTHARAKU, true); Unit* Dragonmaw = me->FindNearestCreature(NPC_DRAGONMAW_SUBJUGATOR, 50); @@ -587,8 +583,7 @@ enum Earthmender SPELL_HEALING_WAVE = 12491, QUEST_ESCAPE_COILSCAR = 10451, - NPC_COILSKAR_ASSASSIN = 21044, - FACTION_EARTHEN = 1726 //guessed + NPC_COILSKAR_ASSASSIN = 21044 }; class npc_earthmender_wilda : public CreatureScript @@ -601,7 +596,7 @@ public: if (quest->GetQuestId() == QUEST_ESCAPE_COILSCAR) { creature->AI()->Talk(SAY_WIL_START, player); - creature->SetFaction(FACTION_EARTHEN); + creature->SetFaction(FACTION_EARTHEN_RING); if (npc_earthmender_wildaAI* pEscortAI = CAST_AI(npc_earthmender_wilda::npc_earthmender_wildaAI, creature->AI())) pEscortAI->Start(false, false, player->GetGUID(), quest); @@ -1407,11 +1402,7 @@ enum Enraged_Dpirits NPC_CREDIT_EARTH = 21092, // Captured Spell / Buff - SPELL_SOUL_CAPTURED = 36115, - - // Factions - FACTION_ENRAGED_SOUL_FRIENDLY = 35, - FACTION_ENRAGED_SOUL_HOSTILE = 14 + SPELL_SOUL_CAPTURED = 36115 }; class npc_enraged_spirit : public CreatureScript @@ -1479,7 +1470,7 @@ public: totemOspirits = me->FindNearestCreature(ENTRY_TOTEM_OF_SPIRITS, RADIUS_TOTEM_OF_SPIRITS); if (totemOspirits) { - Summoned->SetFaction(FACTION_ENRAGED_SOUL_FRIENDLY); + Summoned->SetFaction(FACTION_FRIENDLY); Summoned->GetMotionMaster()->MovePoint(0, totemOspirits->GetPositionX(), totemOspirits->GetPositionY(), Summoned->GetPositionZ()); if (Unit* owner = totemOspirits->GetOwner()) diff --git a/src/server/scripts/Outland/zone_shattrath_city.cpp b/src/server/scripts/Outland/zone_shattrath_city.cpp index 01c88a427f..b567d4e310 100644 --- a/src/server/scripts/Outland/zone_shattrath_city.cpp +++ b/src/server/scripts/Outland/zone_shattrath_city.cpp @@ -46,7 +46,6 @@ enum RaliqTheDrunk { SAY_RALIQ_ATTACK = 0, OPTION_ID_COLLECT_A_DEBT = 0, - FACTION_OGRE_HOSTILE = 45, MENU_ID_COLLECT_A_DEBT = 7729, NPC_TEXT_WUT_YOU_WANT = 9440, CRACKIN_SOME_SKULLS = 10009, @@ -64,7 +63,7 @@ public: if (action == GOSSIP_ACTION_INFO_DEF+1) { CloseGossipMenuFor(player); - creature->SetFaction(FACTION_OGRE_HOSTILE); + creature->SetFaction(FACTION_OGRE); creature->AI()->Talk(SAY_RALIQ_ATTACK, player); creature->AI()->AttackStart(player); } @@ -135,8 +134,6 @@ enum Salsalabim { SAY_DEMONIC_AGGRO = 0, OPTION_ID_ALTRUIS_SENT_ME = 0, - FACTION_FRIENDLY = 35, - FACTION_DEMON_HOSTILE = 90, MENU_ID_ALTRUIS_SENT_ME = 7725, NPC_TEXT_SAL_GROWLS_AT_YOU = 9435, PATIENCE_AND_UNDERSTANDING = 10004, @@ -154,7 +151,7 @@ public: if (action == GOSSIP_ACTION_INFO_DEF+1) { CloseGossipMenuFor(player); - creature->SetFaction(FACTION_DEMON_HOSTILE); + creature->SetFaction(FACTION_DEMON); creature->AI()->Talk(SAY_DEMONIC_AGGRO, player); creature->AI()->AttackStart(player); } diff --git a/src/server/scripts/Outland/zone_terokkar_forest.cpp b/src/server/scripts/Outland/zone_terokkar_forest.cpp index 5ce305b426..cce88ab584 100644 --- a/src/server/scripts/Outland/zone_terokkar_forest.cpp +++ b/src/server/scripts/Outland/zone_terokkar_forest.cpp @@ -48,8 +48,6 @@ enum UnkorTheRuthless { SAY_SUBMIT = 0, REQUIRED_KILL_COUNT = 10, - FACTION_FRIENDLY = 35, - FACTION_HOSTILE = 45, SPELL_PULVERIZE = 2676, QUEST_DONTKILLTHEFATONE = 9889, NPC_BOULDERFIST_INVADER = 18260 @@ -87,7 +85,7 @@ public: { Initialize(); me->SetStandState(UNIT_STAND_STATE_STAND); - me->SetFaction(FACTION_HOSTILE); + me->SetFaction(FACTION_OGRE); } void EnterCombat(Unit* /*who*/) override { } @@ -310,7 +308,6 @@ enum Floon SAY_FLOON_ATTACK = 0, OPTION_ID_PAY_UP_OR_DIE = 0, OPTION_ID_COLLECT_A_DEBT = 0, - FACTION_HOSTILE_FLOON = 1738, MENU_ID_PAY_UP_OR_DIE = 7731, MENU_ID_COLLECT_A_DEBT = 7732, GOSSIP_FLOON_STRANGE_SOUNDS = 9442, @@ -339,7 +336,7 @@ public: if (action == GOSSIP_ACTION_INFO_DEF+1) { CloseGossipMenuFor(player); - creature->SetFaction(FACTION_HOSTILE_FLOON); + creature->SetFaction(FACTION_ARAKKOA); creature->AI()->Talk(SAY_FLOON_ATTACK, player); creature->AI()->AttackStart(player); } @@ -427,7 +424,6 @@ enum IslaStarmaneData SAY_PROGRESS_3 = 2, SAY_PROGRESS_4 = 3, GO_DISTANCE = 10, - FACTION_ESCORTEE = 113, ESCAPE_FROM_FIREWING_POINT_A = 10051, ESCAPE_FROM_FIREWING_POINT_H = 10052, SPELL_TRAVEL_FORM_CAT = 32447, @@ -504,7 +500,7 @@ public: if (quest->GetQuestId() == ESCAPE_FROM_FIREWING_POINT_H || quest->GetQuestId() == ESCAPE_FROM_FIREWING_POINT_A) { ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); - creature->SetFaction(FACTION_ESCORTEE); + creature->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE); } return true; } @@ -644,9 +640,9 @@ public: pEscortAI->Start(false, false, player->GetGUID()); if (player->GetTeamId() == TEAM_ALLIANCE) - creature->SetFaction(FACTION_ESCORT_A_NEUTRAL_PASSIVE); + creature->SetFaction(FACTION_ESCORTEE_A_NEUTRAL_PASSIVE); else - creature->SetFaction(FACTION_ESCORT_H_NEUTRAL_PASSIVE); + creature->SetFaction(FACTION_ESCORTEE_H_NEUTRAL_PASSIVE); } return true; } diff --git a/src/server/scripts/Outland/zone_zangarmarsh.cpp b/src/server/scripts/Outland/zone_zangarmarsh.cpp index f6cc09eba8..b5b0e21362 100644 --- a/src/server/scripts/Outland/zone_zangarmarsh.cpp +++ b/src/server/scripts/Outland/zone_zangarmarsh.cpp @@ -158,8 +158,7 @@ public: enum Cooshhooosh { SPELL_LIGHTNING_BOLT = 9532, - QUEST_CRACK_SKULLS = 10009, - FACTION_HOSTILE_CO = 45 + QUEST_CRACK_SKULLS = 10009 }; class npc_cooshcoosh : public CreatureScript @@ -227,7 +226,7 @@ public: if (action == GOSSIP_ACTION_INFO_DEF) { CloseGossipMenuFor(player); - creature->SetFaction(FACTION_HOSTILE_CO); + creature->SetFaction(FACTION_OGRE); creature->AI()->AttackStart(player); } return true; diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 897f147322..add15a0a6a 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -3531,7 +3531,7 @@ class spell_gen_gm_freeze : public SpellScriptLoader if (Player* player = GetTarget()->ToPlayer()) { // stop combat + make player unattackable + duel stop + stop some spells - player->SetFaction(35); + player->SetFaction(FACTION_FRIENDLY); player->CombatStop(); if (player->IsNonMeleeSpellCast(true)) player->InterruptNonMeleeSpells(true); diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index cd33620fba..486df91a93 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -256,9 +256,7 @@ enum ChickenCluck EMOTE_HELLO_H = 1, EMOTE_CLUCK_TEXT = 2, - QUEST_CLUCK = 3861, - FACTION_FRIENDLY = 35, - FACTION_CHICKEN = 31 + QUEST_CLUCK = 3861 }; class npc_chicken_cluck : public CreatureScript @@ -283,7 +281,7 @@ public: void Reset() override { Initialize(); - me->SetFaction(FACTION_CHICKEN); + me->SetFaction(FACTION_PREY); me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); } From 2f5086479f30da9ca4e2384bb095c66596e2962c Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 12:53:11 +0200 Subject: [PATCH 11/44] Fix build --- src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp index 18ccf16be8..0856f1a457 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp @@ -309,9 +309,7 @@ enum Data ACHIEVEMENT_DONT_STAND_IN_THE_LIGHTNING = 29712972, ACHIEVEMENT_SIFFED = 29772978, ACHIEVEMENT_LOSE_YOUR_ILLUSION = 31763183, - DATA_CHARGED_PILLAR = 1, - - FACTION_FRIENDLY = 35 + DATA_CHARGED_PILLAR = 1 }; enum DisplayIds From 058c929d5ed21e63b7730444aa8f6cddb402be86 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 14:40:44 +0200 Subject: [PATCH 12/44] rename files --- .../2017_05_23_02_world_from_335_was_2017_05_16_01_world.sql} | 0 .../2017_05_23_03_world_from_335_was_2017_05_17_00_world.sql} | 0 .../2017_05_23_04_world_from_335_was_2017_05_22_00_world.sql} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename sql/updates/world/{3.3.5/2017_05_16_01_world.sql => 4.3.4/2017_05_23_02_world_from_335_was_2017_05_16_01_world.sql} (100%) rename sql/updates/world/{3.3.5/2017_05_17_00_world.sql => 4.3.4/2017_05_23_03_world_from_335_was_2017_05_17_00_world.sql} (100%) rename sql/updates/world/{3.3.5/2017_05_22_00_world.sql => 4.3.4/2017_05_23_04_world_from_335_was_2017_05_22_00_world.sql} (100%) diff --git a/sql/updates/world/3.3.5/2017_05_16_01_world.sql b/sql/updates/world/4.3.4/2017_05_23_02_world_from_335_was_2017_05_16_01_world.sql similarity index 100% rename from sql/updates/world/3.3.5/2017_05_16_01_world.sql rename to sql/updates/world/4.3.4/2017_05_23_02_world_from_335_was_2017_05_16_01_world.sql diff --git a/sql/updates/world/3.3.5/2017_05_17_00_world.sql b/sql/updates/world/4.3.4/2017_05_23_03_world_from_335_was_2017_05_17_00_world.sql similarity index 100% rename from sql/updates/world/3.3.5/2017_05_17_00_world.sql rename to sql/updates/world/4.3.4/2017_05_23_03_world_from_335_was_2017_05_17_00_world.sql diff --git a/sql/updates/world/3.3.5/2017_05_22_00_world.sql b/sql/updates/world/4.3.4/2017_05_23_04_world_from_335_was_2017_05_22_00_world.sql similarity index 100% rename from sql/updates/world/3.3.5/2017_05_22_00_world.sql rename to sql/updates/world/4.3.4/2017_05_23_04_world_from_335_was_2017_05_22_00_world.sql From a5bf17adad3ca4aec68e1a0936d3d46e3eed1fdb Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 14:45:05 +0200 Subject: [PATCH 13/44] DB/Misc: Fix 2 typos --- sql/updates/world/4.3.4/2017_05_23_05_world.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 sql/updates/world/4.3.4/2017_05_23_05_world.sql diff --git a/sql/updates/world/4.3.4/2017_05_23_05_world.sql b/sql/updates/world/4.3.4/2017_05_23_05_world.sql new file mode 100644 index 0000000000..2d0d7a6805 --- /dev/null +++ b/sql/updates/world/4.3.4/2017_05_23_05_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `quest_template_addon` SET `AllowableClasses`=1 WHERE `ID` IN (28823,29082); -- Warrior From 6e49330f54bf87093b34e0269d2ffd75511b49b7 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 15:20:21 +0200 Subject: [PATCH 14/44] Fix missing changes --- .../BlackrockMountain/BlackrockDepths/blackrock_depths.cpp | 2 +- src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp | 4 +--- src/server/scripts/Kalimdor/zone_winterspring.cpp | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp index 547982b7dc..a643d05fa9 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp @@ -1,4 +1,4 @@ -14/* +/* * Copyright (C) 2008-2017 TrinityCore * * This program is free software; you can redistribute it and/or modify it diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp index 1cfd0ea67d..732c0fed94 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp @@ -89,9 +89,7 @@ enum Misc { POINT_START_REVIVE = 1, - DATA_OHGANOT_SO_FAST = 5762, - - FACTION_NONE = 1665 + DATA_OHGANOT_SO_FAST = 5762 }; enum SummonGroups diff --git a/src/server/scripts/Kalimdor/zone_winterspring.cpp b/src/server/scripts/Kalimdor/zone_winterspring.cpp index e16fb9bd0a..ae1dc4206f 100644 --- a/src/server/scripts/Kalimdor/zone_winterspring.cpp +++ b/src/server/scripts/Kalimdor/zone_winterspring.cpp @@ -297,7 +297,7 @@ public: if (quest->GetQuestId() == QUEST_GUARDIANS_ALTAR) { creature->AI()->Talk(SAY_QUEST_START); - creature->SetFaction(FACTION_ESCORT_A_NEUTRAL_PASSIVE); + creature->SetFaction(FACTION_ESCORTEE_A_NEUTRAL_PASSIVE); if (npc_ranshallaAI* escortAI = dynamic_cast(creature->AI())) escortAI->Start(false, false, player->GetGUID(), quest); From 6c5ab2277f7341c448d38b0da497d2e2c1672a4b Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 15:37:38 +0200 Subject: [PATCH 15/44] Fix db structure --- .../2017_05_23_02_world_from_335_was_2017_05_16_01_world.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/updates/world/4.3.4/2017_05_23_02_world_from_335_was_2017_05_16_01_world.sql b/sql/updates/world/4.3.4/2017_05_23_02_world_from_335_was_2017_05_16_01_world.sql index 2566669cbe..745670aa04 100644 --- a/sql/updates/world/4.3.4/2017_05_23_02_world_from_335_was_2017_05_16_01_world.sql +++ b/sql/updates/world/4.3.4/2017_05_23_02_world_from_335_was_2017_05_16_01_world.sql @@ -74,7 +74,8 @@ INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comm (-62320, -62398, 0, 'Aura of Celerity - Remove Visual'); -- Add dummy effect to kill credit so it actually selects targets -UPDATE `spell_dbc` SET `EffectImplicitTargetA1`=18, `EffectImplicitTargetB1`=16, `EffectRadiusIndex1`=28, `SchoolMask`=0, `Effect1`=3 WHERE `Id`=64980; +UPDATE `spell_dbc` SET `SchoolMask`=0 WHERE `Id`=64980; +UPDATE `spelleffect_dbc` SET `EffectImplicitTargetA`=18, `EffectImplicitTargetB`=16, `EffectRadiusIndex`=28, `Effect`=3 WHERE `EffectSpellId`=64980; -- Correct attributes (SPELL_ATTR0_HIDE_IN_COMBAT_LOG, SPELL_ATTR2_CAN_TARGET_DEAD, SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) UPDATE `spell_dbc` SET `Attributes`=`Attributes`|256, `AttributesEx2`=`AttributesEx2`|1|4 WHERE `Id` IN (64980,64985); From e3717b254698df5d7dcf5e70be726edc0ddc1582 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 18:16:48 +0200 Subject: [PATCH 16/44] make travis happy --- sql/base/dev/world_database.sql | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sql/base/dev/world_database.sql b/sql/base/dev/world_database.sql index eba0c08a9e..9a4c760c99 100644 --- a/sql/base/dev/world_database.sql +++ b/sql/base/dev/world_database.sql @@ -657,16 +657,16 @@ DROP TABLE IF EXISTS `creature_text`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `creature_text` ( - `entry` mediumint(8) unsigned NOT NULL DEFAULT '0', - `groupid` tinyint(3) unsigned NOT NULL DEFAULT '0', - `id` tinyint(3) unsigned NOT NULL DEFAULT '0', - `text` longtext, - `type` tinyint(3) unsigned NOT NULL DEFAULT '0', - `language` tinyint(3) unsigned NOT NULL DEFAULT '0', - `probability` float NOT NULL DEFAULT '0', - `emote` mediumint(8) unsigned NOT NULL DEFAULT '0', - `duration` mediumint(8) unsigned NOT NULL DEFAULT '0', - `sound` mediumint(8) unsigned NOT NULL DEFAULT '0', + `CreatureID` mediumint(8) unsigned NOT NULL DEFAULT '0', + `GroupID` tinyint(3) unsigned NOT NULL DEFAULT '0', + `ID` tinyint(3) unsigned NOT NULL DEFAULT '0', + `Text` longtext, + `Type` tinyint(3) unsigned NOT NULL DEFAULT '0', + `Language` tinyint(3) unsigned NOT NULL DEFAULT '0', + `Probability` float NOT NULL DEFAULT '0', + `Emote` mediumint(8) unsigned NOT NULL DEFAULT '0', + `Duration` mediumint(8) unsigned NOT NULL DEFAULT '0', + `Sound` mediumint(8) unsigned NOT NULL DEFAULT '0', `BroadcastTextId` mediumint(6) NOT NULL DEFAULT '0', `TextRange` tinyint(3) unsigned NOT NULL DEFAULT '0', `comment` varchar(255) DEFAULT '', From a4d6767fcee1ccce0bb2d0af3b40412d328942df Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 19:00:46 +0200 Subject: [PATCH 17/44] missing change --- sql/base/dev/world_database.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/base/dev/world_database.sql b/sql/base/dev/world_database.sql index 9a4c760c99..9cffbbcbb3 100644 --- a/sql/base/dev/world_database.sql +++ b/sql/base/dev/world_database.sql @@ -670,7 +670,7 @@ CREATE TABLE `creature_text` ( `BroadcastTextId` mediumint(6) NOT NULL DEFAULT '0', `TextRange` tinyint(3) unsigned NOT NULL DEFAULT '0', `comment` varchar(255) DEFAULT '', - PRIMARY KEY (`entry`,`groupid`,`id`) + PRIMARY KEY (`CreatureID`,`GroupID`,`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; From 12d0a2743a61b307f1a53d414402da1d2d3ecb79 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 22:41:38 +0200 Subject: [PATCH 18/44] DB/Misc: Fix some startup errors --- sql/updates/world/4.3.4/2017_05_23_06_world.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 sql/updates/world/4.3.4/2017_05_23_06_world.sql diff --git a/sql/updates/world/4.3.4/2017_05_23_06_world.sql b/sql/updates/world/4.3.4/2017_05_23_06_world.sql new file mode 100644 index 0000000000..7277f89765 --- /dev/null +++ b/sql/updates/world/4.3.4/2017_05_23_06_world.sql @@ -0,0 +1,2 @@ +-- Delete no longer used 4.3.4 achievements for thorim +DELETE FROM achievement_criteria_data WHERE `type`=12; From b1a40e4a88a49d253b330d281b6f9ffc15b6d715 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 23:19:16 +0200 Subject: [PATCH 19/44] DB/Creature: Skitterweb spiders - missing paths By ArcaneFox --- .../world/4.3.4/2017_05_23_07_world.sql | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 sql/updates/world/4.3.4/2017_05_23_07_world.sql diff --git a/sql/updates/world/4.3.4/2017_05_23_07_world.sql b/sql/updates/world/4.3.4/2017_05_23_07_world.sql new file mode 100644 index 0000000000..e7a6977f90 --- /dev/null +++ b/sql/updates/world/4.3.4/2017_05_23_07_world.sql @@ -0,0 +1,66 @@ +-- +SET @NPC := 322219; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=1395.607,`position_y`=1967.916,`position_z`=18.21449 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, ''); +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,1395.607,1967.916,18.21449,0,0,0,0,100,0), +(@PATH,2,1394.16,1971.855,18.46909,0,0,0,0,100,0), +(@PATH,3,1384.627,1984.173,18.75889,0,0,0,0,100,0), +(@PATH,4,1378.888,1992.172,18.40506,0,0,0,0,100,0), +(@PATH,5,1368.135,1992.527,17.40968,0,0,0,0,100,0), +(@PATH,6,1376.495,1993.365,18.46769,0,0,0,0,100,0), +(@PATH,7,1381.746,1987.858,18.92303,0,0,0,0,100,0), +(@PATH,8,1391.86,1975.847,18.5155,0,0,0,0,100,0); + +SET @NPC := 322231; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=1391.356,`position_y`=2009.19,`position_z`=15.90081 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, ''); +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,1391.356,2009.19,15.90081,0,0,0,0,100,0), +(@PATH,2,1396.165,2010.43,15.85461,0,0,0,0,100,0), +(@PATH,3,1411.213,2008.864,14.35008,0,0,0,0,100,0), +(@PATH,4,1422.343,2006.244,12.90728,0,0,0,0,100,0), +(@PATH,5,1434.081,2000.935,11.78559,0,0,0,0,100,0), +(@PATH,6,1448.412,1987.407,11.08783,0,0,0,0,100,0), +(@PATH,7,1444.67,1979.197,12.00837,0,0,0,0,100,0), +(@PATH,8,1448.225,1985.995,11.50098,0,0,0,0,100,0), +(@PATH,9,1440.929,1996.727,11.48743,0,0,0,0,100,0), +(@PATH,10,1425.209,2004.932,12.75235,0,0,0,0,100,0), +(@PATH,11,1412.675,2008.376,13.90751,0,0,0,0,100,0), +(@PATH,12,1403.565,2011.907,15.41258,0,0,0,0,100,0); + +SET @NPC := 322230; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=1411.675,`position_y`=1959.445,`position_z`=15.54728 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, ''); +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,1411.675,1959.445,15.54728,0,0,0,0,100,0), +(@PATH,2,1408.175,1957.945,16.29728,0,0,0,0,100,0); + +SET @NPC := 322213; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=1292.105,`position_y`=1954.99,`position_z`=19.55139 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, ''); +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,1292.105,1954.99,19.55139,0,0,0,0,100,0), +(@PATH,2,1312.855,1964.24,15.80139,0,0,0,0,100,0); + +UPDATE `creature_template_addon` SET `bytes2`=1, `auras`='71764' WHERE `entry`=1766; -- 1766 (Rabid Worg) +UPDATE `creature_template_addon` SET `bytes2`=1 WHERE `entry`=1797; -- 1797 (Giant Rabid Bear) +UPDATE `creature_template_addon` SET `auras`='83859' WHERE `entry`=44923; -- 44923 (North Tide's Invisible Stalker (Large)) +UPDATE `creature_template_addon` SET `auras`='' WHERE `entry`=1412; -- 1412 (Squirrel) +UPDATE `creature_template_addon` SET `bytes2`=1, `auras`='13886' WHERE `entry`=1780; -- 1780 (Skitterweb Striker) +UPDATE `creature_template_addon` SET `bytes2`=1 WHERE `entry`=1781; -- 1781 (Skitterweb Lurker) + +UPDATE `creature_template` SET `maxlevel`=11, `speed_run`=1 WHERE `entry`=1797; -- Giant Rabid Bear +UPDATE `creature_template` SET `npcflag`=0 WHERE `entry`=44906; -- Skitterweb Matriarch From 435cfbdcda688da36c43c7c8b3f188bd6bf11833 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 23:22:17 +0200 Subject: [PATCH 20/44] DB/Creature: Krethis the Shadowspinner - missing paths By ArcaneFox --- .../world/4.3.4/2017_05_23_08_world.sql | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 sql/updates/world/4.3.4/2017_05_23_08_world.sql diff --git a/sql/updates/world/4.3.4/2017_05_23_08_world.sql b/sql/updates/world/4.3.4/2017_05_23_08_world.sql new file mode 100644 index 0000000000..f104b0a0f3 --- /dev/null +++ b/sql/updates/world/4.3.4/2017_05_23_08_world.sql @@ -0,0 +1,33 @@ +-- +-- Pathing for Krethis the Shadowspinner Entry: 12433 'TDB FORMAT' +SET @NPC := 322085; +SET @PATH := @NPC * 10; + +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=1274.974,`position_y`=1897.126,`position_z`=21.38938 WHERE `guid`=@NPC; + +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, ''); + +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,1274.974,1897.126,21.38938,0,0,0,0,100,0), -- 21:39:04 +(@PATH,2,1278.909,1908.219,23.45893,0,0,0,0,100,0), -- 21:39:09 +(@PATH,3,1284.339,1918.863,23.57857,0,0,0,0,100,0), -- 21:39:14 +(@PATH,4,1280.469,1924.43,20.27084,0,0,0,0,100,0), -- 21:39:18 +(@PATH,5,1271.227,1938.581,15.20391,0,0,0,0,100,0), -- 21:39:25 +(@PATH,6,1265.389,1958.833,14.73023,0,0,0,0,100,0), -- 21:39:33 +(@PATH,7,1255.614,1974.375,14.68589,0,0,0,0,100,0), -- 21:42:41 +(@PATH,8,1242.331,1979.81,12.17621,0,0,0,0,100,0), -- 21:42:47 +(@PATH,9,1221.198,1970.09,10.64629,0,0,0,0,100,0), -- 21:42:57 +(@PATH,10,1206.895,1964.751,10.06111,0,0,0,0,100,0), -- 21:43:03 +(@PATH,11,1186.084,1964.823,10.14644,0,0,0,0,100,0), -- 21:43:11 +(@PATH,12,1168.252,1950.556,9.711398,0,0,0,0,100,0), -- 21:43:21 +(@PATH,13,1167.201,1930.388,9.925863,0,0,0,0,100,0), -- 21:43:30 +(@PATH,14,1173.539,1917.193,12.24881,0,0,0,0,100,0), -- 21:43:36 +(@PATH,15,1183.568,1895.232,14.90211,0,0,0,0,100,0), -- 21:43:46 +(@PATH,16,1192.336,1879.673,16.86435,0,0,0,0,100,0), -- 21:43:53 +(@PATH,17,1211.627,1866.091,15.35263,0,0,0,0,100,0), -- 21:44:03 +(@PATH,18,1238.959,1854.467,9.821017,0,0,0,0,100,0), -- 21:44:15 +(@PATH,19,1248.241,1836.601,10.78487,0,0,0,0,100,0), -- 21:44:23 +(@PATH,20,1274.907,1834.172,18.62721,0,0,0,0,100,0), -- 21:44:36 +(@PATH,21,1273.366,1866.705,20.1383,0,0,0,0,100,0); -- 21:44:50 From ca5ed6d09fc37c2b40ed50186f0733172c0c4ebf Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 23:24:53 +0200 Subject: [PATCH 21/44] DB/Creature: Misc pathings By Malcrom --- .../world/4.3.4/2017_05_23_09_world.sql | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 sql/updates/world/4.3.4/2017_05_23_09_world.sql diff --git a/sql/updates/world/4.3.4/2017_05_23_09_world.sql b/sql/updates/world/4.3.4/2017_05_23_09_world.sql new file mode 100644 index 0000000000..da177c2fc8 --- /dev/null +++ b/sql/updates/world/4.3.4/2017_05_23_09_world.sql @@ -0,0 +1,111 @@ +-- Pathing for Ix'lar the Underlord Entry: 45744 'TDB FORMAT' +SET @NPC := 319950; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=2845.473,`position_y`=-4767.625,`position_z`=84.60523 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, ''); +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,2845.473,-4767.625,84.60523,0,0,0,0,100,0), +(@PATH,2,2854.41,-4778.39,91.96474,0,0,0,0,100,0), +(@PATH,3,2862.23,-4789.15,95.09084,0,0,0,0,100,0), +(@PATH,4,2856.74,-4803.69,94.67984,0,0,0,0,100,0), +(@PATH,5,2842.84,-4805.25,97.01968,0,0,0,0,100,0), +(@PATH,6,2833.87,-4790.56,96.84133,0,0,0,0,100,0), +(@PATH,7,2825.65,-4788.4,99.6292,0,0,0,0,100,0), +(@PATH,8,2812.69,-4791.82,95.80302,0,0,0,0,100,0), +(@PATH,9,2805.72,-4798.94,90.90422,0,0,0,0,100,0), +(@PATH,10,2795.53,-4802.25,85.21287,0,0,0,0,100,0), +(@PATH,11,2783.56,-4801.21,83.14036,0,0,0,0,100,0), +(@PATH,12,2768.65,-4800.15,79.33762,0,0,0,0,100,0), +(@PATH,13,2755.91,-4794.9,76.57204,0,0,0,0,100,0), +(@PATH,14,2747,-4777.48,76.48952,0,0,0,0,100,0), +(@PATH,15,2748.14,-4746.14,76.97128,0,0,0,0,100,0), +(@PATH,16,2747.03,-4722.73,74.83576,0,0,0,0,100,0), +(@PATH,17,2750.93,-4698.12,78.95863,0,0,0,0,100,0), +(@PATH,18,2760.24,-4670.02,80.02687,0,0,0,0,100,0), +(@PATH,19,2770.4,-4660.86,86.92216,0,0,0,0,100,0), +(@PATH,20,2783.42,-4664.73,92.67192,0,0,0,0,100,0), +(@PATH,21,2797.51,-4678.94,95.49097,0,0,0,0,100,0), +(@PATH,22,2809.22,-4682.13,95.92142,0,0,0,0,100,0), +(@PATH,23,2826.65,-4680.09,90.41763,0,0,0,0,100,0), +(@PATH,24,2838.29,-4692.48,93.17684,0,0,0,0,100,0), +(@PATH,25,2853.44,-4706.6,89.93577,0,0,0,0,100,0), +(@PATH,26,2861.5,-4729.15,82.22752,0,0,0,0,100,0), +(@PATH,27,2855.89,-4746.56,81.98978,0,0,0,0,100,0); + +-- Pathing for Yetimus the Yeti Lord Entry: 47484 'TDB FORMAT' +SET @NPC := 323060; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-151.922,`position_y`=-171.311,`position_z`=104.9993 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, ''); +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,-151.922,-171.311,104.9993,0,0,0,0,100,0), +(@PATH,2,-197.392,-164.851,92.99743,0,0,0,0,100,0), +(@PATH,3,-240.981,-167.431,80.67632,0,0,0,0,100,0), +(@PATH,4,-279.948,-174.962,74.14382,0,0,0,0,100,0), +(@PATH,5,-301.554,-187.203,68.3701,0,0,0,0,100,0), +(@PATH,6,-319.957,-198.203,64.63304,0,0,0,0,100,0), +(@PATH,7,-348.99,-235.068,62.78932,0,0,0,0,100,0), +(@PATH,8,-368.51,-265.285,60.20347,0,0,0,0,100,0), +(@PATH,9,-381.052,-305.778,59.71421,0,0,0,0,100,0), +(@PATH,10,-383.299,-340.087,59.16272,0,0,0,0,100,0), +(@PATH,11,-370.479,-366.644,58.37293,0,0,0,0,100,0), +(@PATH,12,-349.299,-399.33,58.9684,0,0,0,0,100,0), +(@PATH,13,-324.72,-430.033,59.33606,0,0,0,0,100,0), +(@PATH,14,-297.215,-456.95,60.7625,0,0,0,0,100,0), +(@PATH,15,-268.215,-460.696,64.35992,0,0,0,0,100,0), +(@PATH,16,-247.248,-462.217,65.86039,0,0,0,0,100,0), +(@PATH,17,-222.099,-464.127,67.62333,0,0,0,0,100,0), +(@PATH,18,-195.962,-466.226,71.86466,0,0,0,0,100,0), +(@PATH,19,-160.519,-459.127,76.6852,0,0,0,0,100,0), +(@PATH,20,-141.003,-451.144,76.6852,0,0,0,0,100,0), +(@PATH,21,-160.519,-459.127,76.6852,0,0,0,0,100,0), +(@PATH,22,-195.962,-466.226,71.86466,0,0,0,0,100,0), +(@PATH,23,-222.099,-464.127,67.62333,0,0,0,0,100,0), +(@PATH,24,-247.248,-462.217,65.86039,0,0,0,0,100,0), +(@PATH,25,-268.215,-460.696,64.35992,0,0,0,0,100,0), +(@PATH,26,-297.215,-456.95,60.7625,0,0,0,0,100,0), +(@PATH,27,-324.72,-430.033,59.33606,0,0,0,0,100,0), +(@PATH,28,-349.299,-399.33,58.9684,0,0,0,0,100,0), +(@PATH,29,-370.479,-366.644,58.37293,0,0,0,0,100,0), +(@PATH,30,-383.299,-340.087,59.16272,0,0,0,0,100,0), +(@PATH,31,-381.052,-305.778,59.71421,0,0,0,0,100,0), +(@PATH,32,-368.51,-265.285,60.20347,0,0,0,0,100,0), +(@PATH,33,-348.99,-235.068,62.78932,0,0,0,0,100,0), +(@PATH,34,-319.957,-198.203,64.63304,0,0,0,0,100,0), +(@PATH,35,-301.554,-187.203,68.3701,0,0,0,0,100,0), +(@PATH,36,-279.948,-174.962,74.14382,0,0,0,0,100,0), +(@PATH,37,-240.981,-167.431,80.67632,0,0,0,0,100,0), +(@PATH,38,-197.392,-164.851,92.99743,0,0,0,0,100,0); + +-- Pathing for Infernus Entry: 49266 'TDB FORMAT' +SET @NPC := 322294; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-573.0382,`position_y`=-1449.427,`position_z`=53.92358 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, ''); +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,-573.0382,-1449.427,53.92358,0,0,0,0,100,0), +(@PATH,2,-561.0801,-1444.299,52.56591,0,0,0,0,100,0), +(@PATH,3,-554.1354,-1448.941,52.56591,0,0,0,0,100,0), +(@PATH,4,-552.0695,-1463.915,52.56591,0,0,0,0,100,0), +(@PATH,5,-553.8038,-1475.297,52.56591,0,0,0,0,100,0), +(@PATH,6,-565.9965,-1476.443,52.67285,0,0,0,0,100,0), +(@PATH,7,-573.3889,-1463.563,52.94677,0,0,0,0,100,0); + +-- Pathing for Teracula Entry: 49265 'TDB FORMAT' +SET @NPC := 322435; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-462.533,`position_y`=-1424.408,`position_z`=90.77872 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,1,0, ''); +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,-462.533,-1424.408,90.77872,0,0,0,0,100,0), +(@PATH,2,-449.6858,-1420.599,96.06876,0,0,0,0,100,0), +(@PATH,3,-462.533,-1424.408,90.77872,0,0,0,0,100,0), +(@PATH,4,-477.5868,-1429.043,88.90503,0,0,0,0,100,0); From 97deb7eedab1a016a9d7b4cea40789e6570e40f3 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Wed, 24 May 2017 00:13:56 +0200 Subject: [PATCH 22/44] DB/Creature: Misc Pathing By Malcrom --- .../world/4.3.4/2017_05_24_00_world.sql | 325 ++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 sql/updates/world/4.3.4/2017_05_24_00_world.sql diff --git a/sql/updates/world/4.3.4/2017_05_24_00_world.sql b/sql/updates/world/4.3.4/2017_05_24_00_world.sql new file mode 100644 index 0000000000..ae69db75f2 --- /dev/null +++ b/sql/updates/world/4.3.4/2017_05_24_00_world.sql @@ -0,0 +1,325 @@ +-- Pathing for Stormwind Guard Entry: 1423 'TDB FORMAT' +SET @NPC := 281479; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-9621.585,`position_y`=-1009.805,`position_z`=41.4601 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,257,0, ''); +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,-9621.585,-1009.805,41.4601,0,0,0,0,100,0), +(@PATH,2,-9622.979,-993.5161,42.51941,0,0,0,0,100,0), +(@PATH,3,-9616.812,-971.4866,43.64319,0,0,0,0,100,0), +(@PATH,4,-9605.688,-952.9254,43.84697,0,0,0,0,100,0), +(@PATH,5,-9589.601,-935.541,43.71594,0,0,0,0,100,0), +(@PATH,6,-9581.84,-917.2405,43.88842,0,0,0,0,100,0), +(@PATH,7,-9582.131,-892.7952,43.52868,0,0,0,0,100,0), +(@PATH,8,-9587.052,-870.2479,43.77868,0,0,0,0,100,0), +(@PATH,9,-9603.133,-848.3824,43.8069,0,0,0,0,100,0), +(@PATH,10,-9635.435,-813.6964,43.84379,0,0,0,0,100,0), +(@PATH,11,-9646.747,-797.5594,43.59379,0,0,0,0,100,0), +(@PATH,12,-9651.212,-783.6508,44.32621,0,0,0,0,100,0), +(@PATH,13,-9651.457,-762.5749,44.47965,0,0,0,0,100,0), +(@PATH,14,-9656.33,-740.673,44.61954,0,0,0,0,100,0), +(@PATH,15,-9656.645,-723.0509,44.66413,0,0,0,0,100,0), +(@PATH,16,-9649.04,-701.8206,46.00813,0,0,0,0,100,0), +(@PATH,17,-9643.346,-663.4222,49.36496,0,0,0,0,100,0), +(@PATH,18,-9628.837,-641.6657,51.14138,0,0,0,0,100,0), +(@PATH,19,-9622.42,-603.7773,52.84998,0,0,0,0,100,0), +(@PATH,20,-9619.694,-574.7324,54.19883,0,0,0,0,100,0), +(@PATH,21,-9617.313,-551.6019,54.49004,0,0,0,0,100,0), +(@PATH,22,-9611.551,-532.0573,54.7783,0,0,0,0,100,0), +(@PATH,23,-9602.272,-517.8843,56.76878,0,0,0,0,100,0), +(@PATH,24,-9593.436,-504.3423,57.52607,0,0,0,0,100,0), +(@PATH,25,-9589.494,-487.5282,57.76851,0,0,0,0,100,0), +(@PATH,26,-9590.743,-469.7306,57.8166,0,0,0,0,100,0), +(@PATH,27,-9600.497,-453.0271,57.78099,0,0,0,0,100,0), +(@PATH,28,-9608.497,-436.1051,57.36327,0,0,0,0,100,0), +(@PATH,29,-9614.505,-416.2884,57.66486,0,0,0,0,100,0), +(@PATH,30,-9617.868,-395.8977,57.95574,0,0,0,0,100,0), +(@PATH,31,-9619.874,-371.5169,57.58074,0,0,0,0,100,0), +(@PATH,32,-9620.904,-344.161,57.28194,0,0,0,0,100,0), +(@PATH,33,-9620.884,-320.5441,57.52703,0,0,0,0,100,0), +(@PATH,34,-9618.642,-297.6285,57.18179,0,0,0,0,100,0), +(@PATH,35,-9612.653,-276.4153,57.76284,0,0,0,0,100,0), +(@PATH,36,-9608.691,-255.3432,57.32165,0,0,0,0,100,0), +(@PATH,37,-9598.686,-228.6033,57.3935,0,0,0,0,100,0), +(@PATH,38,-9588.345,-202.6797,57.81245,0,0,0,0,100,0), +(@PATH,39,-9578.535,-171.4949,57.50352,0,0,0,0,100,0), +(@PATH,40,-9567.966,-150.9942,57.1911,0,0,0,0,100,0), +(@PATH,41,-9553.459,-136.2681,57.28034,0,0,0,0,100,0), +(@PATH,42,-9549.182,-112.0365,57.55236,0,0,0,0,100,0), +(@PATH,43,-9548.437,-83.4119,57.64455,0,0,0,0,100,0), +(@PATH,44,-9546.561,-64.21647,57.19081,0,0,0,0,100,0), +(@PATH,45,-9542.052,-43.97417,56.69081,0,0,0,0,100,0), +(@PATH,46,-9531.666,-17.71886,56.00526,0,0,0,0,100,0), +(@PATH,47,-9518.505,4.58865,56.11089,0,0,0,0,100,0), +(@PATH,48,-9505.715,31.62967,56.48589,0,0,0,0,100,0), +(@PATH,49,-9495.036,54.66113,55.81353,0,0,0,0,100,0), +(@PATH,50,-9492.798,64.35981,56.02752,0,6000,0,0,100,0), +(@PATH,51,-9497.884,48.81619,55.94793,0,0,0,0,100,0), +(@PATH,52,-9503.121,36.35319,56.42255,0,0,0,0,100,0), +(@PATH,53,-9509.772,23.9451,56.53191,0,0,0,0,100,0), +(@PATH,54,-9517.83,6.747939,56.11089,0,0,0,0,100,0), +(@PATH,55,-9529.744,-15.72743,55.8871,0,0,0,0,100,0), +(@PATH,56,-9541.357,-44.91298,56.76772,0,0,0,0,100,0), +(@PATH,57,-9547.372,-71.95128,57.51955,0,0,0,0,100,0), +(@PATH,58,-9549.507,-109.4462,57.5067,0,0,0,0,100,0), +(@PATH,59,-9556.684,-136.5528,57.55939,0,0,0,0,100,0), +(@PATH,60,-9567.811,-151.0182,57.1723,0,0,0,0,100,0), +(@PATH,61,-9578.885,-170.2882,57.37852,0,0,0,0,100,0), +(@PATH,62,-9586.776,-195.1395,57.62852,0,0,0,0,100,0), +(@PATH,63,-9598.216,-224.6504,57.30341,0,0,0,0,100,0), +(@PATH,64,-9608.648,-258.0852,57.30822,0,0,0,0,100,0), +(@PATH,65,-9614.821,-289.097,57.59048,0,0,0,0,100,0), +(@PATH,66,-9618.106,-312.9915,57.58343,0,0,0,0,100,0), +(@PATH,67,-9620.264,-340.5638,57.52462,0,0,0,0,100,0), +(@PATH,68,-9619.762,-370.9549,57.58074,0,0,0,0,100,0), +(@PATH,69,-9618.118,-393.6722,57.83074,0,0,0,0,100,0), +(@PATH,70,-9610.834,-427.7363,57.52277,0,0,0,0,100,0), +(@PATH,71,-9602.774,-445.216,57.62401,0,0,0,0,100,0), +(@PATH,72,-9596.105,-461.7981,57.74839,0,0,0,0,100,0), +(@PATH,73,-9591.105,-476.2582,57.76851,0,0,0,0,100,0), +(@PATH,74,-9591.471,-488.4674,57.84004,0,0,0,0,100,0), +(@PATH,75,-9593.778,-501.4398,57.38178,0,0,0,0,100,0), +(@PATH,76,-9598.513,-512.4593,57.47431,0,0,0,0,100,0), +(@PATH,77,-9609.811,-533.6465,54.86504,0,0,0,0,100,0), +(@PATH,78,-9615.971,-550.82,54.49004,0,0,0,0,100,0), +(@PATH,79,-9618.966,-571.0148,54.37461,0,0,0,0,100,0), +(@PATH,80,-9620.506,-590.8423,53.78599,0,0,0,0,100,0), +(@PATH,81,-9623.524,-620.6938,51.94861,0,0,0,0,100,0), +(@PATH,82,-9628.995,-638.2269,51.17922,0,0,0,0,100,0), +(@PATH,83,-9636.7,-653.1119,49.69407,0,0,0,0,100,0), +(@PATH,84,-9641.278,-663.9442,49.39695,0,0,0,0,100,0), +(@PATH,85,-9645.316,-681.183,48.00885,0,0,0,0,100,0), +(@PATH,86,-9650.676,-701.9413,45.99372,0,0,0,0,100,0), +(@PATH,87,-9653.724,-722.3216,44.67292,0,0,0,0,100,0), +(@PATH,88,-9654.573,-742.368,44.55119,0,0,0,0,100,0), +(@PATH,89,-9652.612,-766.4833,44.30216,0,0,0,0,100,0), +(@PATH,90,-9648.009,-792.9749,43.62431,0,0,0,0,100,0), +(@PATH,91,-9638.621,-808.6445,43.71879,0,0,0,0,100,0), +(@PATH,92,-9626.769,-822.2813,43.88491,0,0,0,0,100,0), +(@PATH,93,-9613.571,-836.7086,43.62306,0,0,0,0,100,0), +(@PATH,94,-9600.535,-851.837,43.6819,0,0,0,0,100,0), +(@PATH,95,-9589.787,-865.6964,43.83097,0,0,0,0,100,0), +(@PATH,96,-9585.493,-875.5536,43.90368,0,0,0,0,100,0), +(@PATH,97,-9584.774,-898.893,43.90368,0,0,0,0,100,0), +(@PATH,98,-9586.063,-915.4184,43.90355,0,0,0,0,100,0), +(@PATH,99,-9592.028,-931.4844,43.74437,0,0,0,0,100,0), +(@PATH,100,-9598.08,-942.4412,43.92321,0,0,0,0,100,0), +(@PATH,101,-9607.78,-959.0113,43.49467,0,0,0,0,100,0), +(@PATH,102,-9615.448,-974.1688,43.85193,0,0,0,0,100,0), +(@PATH,103,-9620.891,-993.4722,42.6139,0,0,0,0,100,0), +(@PATH,104,-9620.597,-1003.663,42.25624,0,0,0,0,100,0), +(@PATH,105,-9620.338,-1014.109,41.06777,0,0,0,0,100,0), +(@PATH,106,-9619.945,-1024.693,40.49306,0,0,0,0,100,0), +(@PATH,107,-9619.242,-1036.472,39.87387,0,6000,0,0,100,0); + +-- Pathing for Stormwind Guard Entry: 1423 'TDB FORMAT' +SET @NPC := 280111; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-9083.599,`position_y`=-53.3508,`position_z`=86.42607 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,257,0, ''); +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,-9083.599,-53.3508,86.42607,0,0,0,0,100,0), +(@PATH,2,-9098.672,-65.61827,84.054,0,0,0,0,100,0), +(@PATH,3,-9109.419,-75.7207,82.09222,0,0,0,0,100,0), +(@PATH,4,-9125.424,-85.16591,78.16302,0,0,0,0,100,0), +(@PATH,5,-9142.284,-95.87967,75.0947,0,0,0,0,100,0), +(@PATH,6,-9163.195,-108.5354,72.56712,0,0,0,0,100,0), +(@PATH,7,-9176.171,-111.9833,71.24508,0,0,0,0,100,0), +(@PATH,8,-9195.773,-112.7946,71.12057,0,0,0,0,100,0), +(@PATH,9,-9208.957,-109.3175,71.1289,0,0,0,0,100,0), +(@PATH,10,-9225.822,-104.7172,71.1289,0,0,0,0,100,0), +(@PATH,11,-9238.654,-99.04698,70.70847,0,0,0,0,100,0), +(@PATH,12,-9249.91,-91.48221,70.40672,0,0,0,0,100,0), +(@PATH,13,-9268.238,-77.89268,68.6869,0,0,0,0,100,0), +(@PATH,14,-9280.204,-67.65853,68.24964,0,0,0,0,100,0), +(@PATH,15,-9297.876,-60.61285,67.34437,0,0,0,0,100,0), +(@PATH,16,-9322.913,-53.6008,66.44393,0,0,0,0,100,0), +(@PATH,17,-9335.962,-49.37478,65.8247,0,0,0,0,100,0), +(@PATH,18,-9351.479,-40.11382,64.81542,0,0,0,0,100,0), +(@PATH,19,-9362.026,-29.91482,63.76466,0,0,0,0,100,0), +(@PATH,20,-9376.168,-14.78429,62.24424,0,0,0,0,100,0), +(@PATH,21,-9397.745,6.895725,60.04395,0,0,0,0,100,0), +(@PATH,22,-9409.909,21.16298,58.82724,0,0,0,0,100,0), +(@PATH,23,-9438.457,54.57856,56.02,0,6000,0,0,100,0), +(@PATH,24,-9431.209,46.55914,56.69352,0,0,0,0,100,0), +(@PATH,25,-9421.634,36.47081,57.31852,0,0,0,0,100,0), +(@PATH,26,-9411.369,24.51682,58.24777,0,0,0,0,100,0), +(@PATH,27,-9401.32,13.38477,59.67916,0,0,0,0,100,0), +(@PATH,28,-9390.167,-1.145291,60.82187,0,0,0,0,100,0), +(@PATH,29,-9378.083,-13.01411,61.88828,0,0,0,0,100,0), +(@PATH,30,-9365.354,-27.72938,63.36524,0,0,0,0,100,0), +(@PATH,31,-9351.892,-40.30295,64.81542,0,0,0,0,100,0), +(@PATH,32,-9337.786,-50.15527,65.67455,0,0,0,0,100,0), +(@PATH,33,-9329.192,-52.84429,66.13094,0,0,0,0,100,0), +(@PATH,34,-9314.485,-56.48058,66.70492,0,0,0,0,100,0), +(@PATH,35,-9302.469,-59.14703,66.93221,0,0,0,0,100,0), +(@PATH,36,-9290.404,-63.35688,67.5221,0,0,0,0,100,0), +(@PATH,37,-9281.472,-69.32259,68.09779,0,0,0,0,100,0), +(@PATH,38,-9270.33,-77.17632,68.6869,0,0,0,0,100,0), +(@PATH,39,-9258.729,-86.89681,69.7136,0,0,0,0,100,0), +(@PATH,40,-9245.781,-95.48481,70.52708,0,0,0,0,100,0), +(@PATH,41,-9235.747,-101.5669,70.77646,0,0,0,0,100,0), +(@PATH,42,-9228.748,-104.1309,70.99169,0,0,0,0,100,0), +(@PATH,43,-9219.661,-106.7042,71.2539,0,0,0,0,100,0), +(@PATH,44,-9208.192,-109.8,71.17455,0,0,0,0,100,0), +(@PATH,45,-9197.428,-112.1889,71.09542,0,0,0,0,100,0), +(@PATH,46,-9185.816,-112.7407,70.99557,0,0,0,0,100,0), +(@PATH,47,-9174.032,-111.8417,71.54903,0,0,0,0,100,0), +(@PATH,48,-9159.315,-106.846,73.04197,0,0,0,0,100,0), +(@PATH,49,-9149.284,-100.6613,74.23655,0,0,0,0,100,0), +(@PATH,50,-9135.363,-91.4846,76.24387,0,0,0,0,100,0), +(@PATH,51,-9119.705,-80.96517,79.70452,0,0,0,0,100,0), +(@PATH,52,-9109.234,-73.00748,82.2177,0,0,0,0,100,0), +(@PATH,53,-9097.453,-63.84201,84.35332,0,0,0,0,100,0), +(@PATH,54,-9090.091,-58.36013,85.42094,0,0,0,0,100,0), +(@PATH,55,-9084.711,-52.9579,86.38237,0,0,0,0,100,0), +(@PATH,56,-9079.419,-48.8967,87.35429,0,0,0,0,100,0), +(@PATH,57,-9070.88,-43.41764,88.0645,0,6000,0,0,100,0); + +-- Pathing for Kira Songshine Entry: 3937 'TDB FORMAT' +SET @NPC := 280672; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-9493.627,`position_y`=67.18815,`position_z`=56.24675 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,257,0, ''); +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,-9493.627,67.18815,56.24675,0,0,0,0,100,0), +(@PATH,2,-9486.809,89.65723,56.21941,0,0,0,0,100,0), +(@PATH,3,-9483.946,102.302,56.50797,0,0,0,0,100,0), +(@PATH,4,-9480.245,126.3048,56.63297,0,0,0,0,100,0), +(@PATH,5,-9482.919,145.2651,56.43309,0,0,0,0,100,0), +(@PATH,6,-9485.429,167.3975,56.05416,0,0,0,0,100,0), +(@PATH,7,-9484.816,180.0712,55.42916,0,0,0,0,100,0), +(@PATH,8,-9493.019,196.9338,54.55416,0,0,0,0,100,0), +(@PATH,9,-9508.471,218.0667,52.96415,0,0,0,0,100,0), +(@PATH,10,-9533.104,242.1964,50.86973,0,0,0,0,100,0), +(@PATH,11,-9519.216,232.3553,51.83915,0,0,0,0,100,0), +(@PATH,12,-9515.605,227.5241,52.2238,0,0,0,0,100,0), +(@PATH,13,-9503.669,216.6386,52.90214,0,0,0,0,100,0), +(@PATH,14,-9498.017,202.3757,54.15273,0,0,0,0,100,0), +(@PATH,15,-9486.037,183.3565,55.22677,0,0,0,0,100,0), +(@PATH,16,-9483.614,166.1485,56.05247,0,0,0,0,100,0), +(@PATH,17,-9481.871,138.393,56.67747,0,0,0,0,100,0), +(@PATH,18,-9483.646,118.8074,56.60807,0,0,0,0,100,0), +(@PATH,19,-9486.335,100.2849,56.50797,0,0,0,0,100,0), +(@PATH,20,-9487.605,81.91924,56.0739,0,0,0,0,100,0), +(@PATH,21,-9485.286,71.61192,56.40178,0,0,0,0,100,0), +(@PATH,22,-9479.711,67.17296,56.32232,0,0,0,0,100,0), +(@PATH,23,-9467.877,61.33068,56.1054,0,0,0,0,100,0), +(@PATH,24,-9454.594,66.6288,56.20298,0,0,0,0,100,0), +(@PATH,25,-9415.596,86.5546,56.99038,0,0,0,0,100,0), +(@PATH,26,-9402.721,93.8989,58.41055,0,0,0,0,100,0), +(@PATH,27,-9383.628,105.0891,60.03624,0,0,0,0,100,0), +(@PATH,28,-9362.592,111.672,61.55702,0,0,0,0,100,0), +(@PATH,29,-9337.428,124.4685,63.71767,0,0,0,0,100,0), +(@PATH,30,-9316.489,136.0714,64.95474,0,0,0,0,100,0), +(@PATH,31,-9298.161,143.4155,65.91209,0,0,0,0,100,0), +(@PATH,32,-9273.096,151.2024,67.00413,0,0,0,0,100,0), +(@PATH,33,-9256.78,159.3222,67.66848,0,0,0,0,100,0), +(@PATH,34,-9242.877,174.1646,67.97204,0,0,0,0,100,0), +(@PATH,35,-9232.261,186.1395,67.72204,0,0,0,0,100,0), +(@PATH,36,-9217.805,203.6647,69.03122,0,0,0,0,100,0), +(@PATH,37,-9201.397,220.0502,71.15402,0,0,0,0,100,0), +(@PATH,38,-9188.232,236.8916,72.44244,0,0,0,0,100,0), +(@PATH,39,-9182.984,255.7783,73.85345,0,0,0,0,100,0), +(@PATH,40,-9182.252,275.1166,75.44212,0,0,0,0,100,0), +(@PATH,41,-9180.925,301.3294,78.33094,0,0,0,0,100,0), +(@PATH,42,-9178.171,323.0379,80.88319,0,0,0,0,100,0), +(@PATH,43,-9173.903,335.753,83.66998,0,0,0,0,100,0), +(@PATH,44,-9168.686,347.0231,86.27471,0,0,0,0,100,0), +(@PATH,45,-9142.421,375.9646,90.75526,0,0,0,0,100,0), +(@PATH,46,-9125.449,389.9619,91.57055,0,0,0,0,100,0), +(@PATH,47,-9144.014,376.6461,90.75526,0,0,0,0,100,0), +(@PATH,48,-9150.359,370.6424,90.63026,0,0,0,0,100,0), +(@PATH,49,-9159.769,358.9712,89.09229,0,0,0,0,100,0), +(@PATH,50,-9169.689,347.3052,86.06768,0,0,0,0,100,0), +(@PATH,51,-9176.393,336.1326,83.34795,0,0,0,0,100,0), +(@PATH,52,-9179.039,324.0334,81.12244,0,0,0,0,100,0), +(@PATH,53,-9181.582,310.6828,79.00208,0,0,0,0,100,0), +(@PATH,54,-9182.38,299.1464,77.95396,0,0,0,0,100,0), +(@PATH,55,-9183.653,286.0146,76.42735,0,0,0,0,100,0), +(@PATH,56,-9184.186,259.5755,74.10345,0,0,0,0,100,0), +(@PATH,57,-9187.476,239.7987,72.50726,0,0,0,0,100,0), +(@PATH,58,-9193.939,228.3685,71.82954,0,0,0,0,100,0), +(@PATH,59,-9217.061,204.2547,69.10202,0,0,0,0,100,0), +(@PATH,60,-9229.925,191.6477,68.03234,0,0,0,0,100,0), +(@PATH,61,-9239.118,181.4567,67.84704,0,0,0,0,100,0), +(@PATH,62,-9252.867,160.5058,67.88796,0,0,0,0,100,0), +(@PATH,63,-9270.517,152.484,67.12913,0,0,0,0,100,0), +(@PATH,64,-9281.984,150.6615,66.75413,0,0,0,0,100,0), +(@PATH,65,-9303.524,142.9477,65.81363,0,0,0,0,100,0), +(@PATH,66,-9326.493,133.6549,64.28152,0,0,0,0,100,0), +(@PATH,67,-9338.177,126.1314,63.79213,0,0,0,0,100,0), +(@PATH,68,-9357.066,114.8676,62.03004,0,0,0,0,100,0), +(@PATH,69,-9376.01,105.7821,60.5753,0,0,0,0,100,0), +(@PATH,70,-9396.483,100.0127,58.82322,0,0,0,0,100,0), +(@PATH,71,-9415.729,90.13653,57.42837,0,0,0,0,100,0), +(@PATH,72,-9430.02,79.53779,56.53139,0,0,0,0,100,0), +(@PATH,73,-9441.903,69.07547,56.12108,0,0,0,0,100,0), +(@PATH,74,-9459.128,61.95774,55.895,0,0,0,0,100,0), +(@PATH,75,-9471.797,63.62576,56.15252,0,0,0,0,100,0), +(@PATH,76,-9492.84,58.88786,55.85588,0,0,0,0,100,0), +(@PATH,77,-9502.176,40.73476,56.34699,0,0,0,0,100,0), +(@PATH,78,-9513.744,15.73003,56.48589,0,0,0,0,100,0), +(@PATH,79,-9519.953,3.746257,56.11089,0,0,0,0,100,0), +(@PATH,80,-9526.677,-8.577745,55.88026,0,0,0,0,100,0), +(@PATH,81,-9535.507,-27.89106,55.83387,0,0,0,0,100,0), +(@PATH,82,-9544.865,-53.43615,56.81581,0,0,0,0,100,0), +(@PATH,83,-9550.579,-84.43788,57.65163,0,0,0,0,100,0), +(@PATH,84,-9550.719,-113.8145,57.65856,0,0,0,0,100,0), +(@PATH,85,-9549.074,-80.8469,57.51955,0,0,0,0,100,0), +(@PATH,86,-9543.954,-52.83002,56.81581,0,0,0,0,100,0), +(@PATH,87,-9537.006,-30.56196,55.88392,0,0,0,0,100,0), +(@PATH,88,-9529.335,-14.98915,55.83778,0,0,0,0,100,0), +(@PATH,89,-9522.49,-4.730361,55.99379,0,0,0,0,100,0), +(@PATH,90,-9517.441,9.093316,56.23589,0,0,0,0,100,0), +(@PATH,91,-9508.014,28.54688,56.48589,0,0,0,0,100,0), +(@PATH,92,-9496.207,50.32487,55.88494,0,0,0,0,100,0); + +-- Pathing for Stormwind Royal Guard Entry: 1756 'TDB FORMAT' +SET @NPC := 314291; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-8415.07,`position_y`=299.125,`position_z`=147.0138 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,257,0, ''); +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,-8415.07,299.125,147.0138,0,0,0,0,100,0), +(@PATH,2,-8409.74,292.457,147.2607,0,0,0,0,100,0), +(@PATH,3,-8389.694,267.0654,155.3475,0,0,0,0,100,0), +(@PATH,4,-8381.73,257.153,155.3472,0,0,0,0,100,0), +(@PATH,5,-8363.61,254.408,155.3472,0,0,0,0,100,0), +(@PATH,6,-8384.62,237.797,155.3471,0,0,0,0,100,0), +(@PATH,7,-8383.19,255.96,155.3434,0,0,0,0,100,0), +(@PATH,8,-8391.108,265.9411,155.3471,0,0,0,0,100,0), +(@PATH,9,-8411.21,291.196,147.2786,0,0,0,0,100,0), +(@PATH,10,-8417.51,299.163,147.0138,0,0,0,0,100,0), +(@PATH,11,-8434.2,321.583,145.1534,0,4000,0,0,100,0), +(@PATH,12,-8416.243,300.5492,147.0542,0,0,0,0,100,0), +(@PATH,13,-8401.91,311.34,147.0138,0,0,0,0,100,0), +(@PATH,14,-8399.65,329.141,147.0138,0,0,0,0,100,0), +(@PATH,15,-8381.1,327.168,147.0138,0,0,0,0,100,0), +(@PATH,16,-8383.38,308.866,147.0138,0,0,0,0,100,0), +(@PATH,17,-8401.068,310.4666,147.0138,0,0,0,0,100,0); + +-- Pathing for Stormwind City Guard Entry: 68 'TDB FORMAT' +SET @NPC := 313891; +SET @PATH := @NPC * 10; +UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=-9144.325,`position_y`=374.0361,`position_z`=90.75526 WHERE `guid`=@NPC; +DELETE FROM `creature_addon` WHERE `guid`=@NPC; +INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@NPC,@PATH,0,0,257,0, ''); +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,-9144.325,374.0361,90.75526,0,0,0,0,100,0), +(@PATH,2,-9125.303,391.6143,91.78637,0,0,0,0,100,0), +(@PATH,3,-9091.403,414.3217,92.16946,0,0,0,0,100,0), +(@PATH,4,-9073.301,427.18,92.02811,0,0,0,0,100,0), +(@PATH,5,-9091.403,414.3217,92.16946,0,0,0,0,100,0), +(@PATH,6,-9125.303,391.6143,91.78637,0,0,0,0,100,0), +(@PATH,7,-9144.325,374.0361,90.75526,0,0,0,0,100,0), +(@PATH,8,-9165.44,351.6357,87.38135,0,0,0,0,100,0); From 09439c610f2982455f4fa2aa2c38577cb8044a2b Mon Sep 17 00:00:00 2001 From: Aokromes Date: Wed, 24 May 2017 01:43:59 +0200 Subject: [PATCH 23/44] DB/Misc: Fix one startup error --- sql/updates/world/4.3.4/2017_05_24_01_world.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 sql/updates/world/4.3.4/2017_05_24_01_world.sql diff --git a/sql/updates/world/4.3.4/2017_05_24_01_world.sql b/sql/updates/world/4.3.4/2017_05_24_01_world.sql new file mode 100644 index 0000000000..9904728dbb --- /dev/null +++ b/sql/updates/world/4.3.4/2017_05_24_01_world.sql @@ -0,0 +1,2 @@ +-- +DELETE FROM `creature_queststarter` WHERE `id` = 44906; From d253ff5d89f4a19ed5c5a07c645b602176b94fc0 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Wed, 24 May 2017 02:09:47 +0200 Subject: [PATCH 24/44] DB/Creature: Fix some triggers visibility --- sql/updates/world/4.3.4/2017_05_24_02_world.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 sql/updates/world/4.3.4/2017_05_24_02_world.sql diff --git a/sql/updates/world/4.3.4/2017_05_24_02_world.sql b/sql/updates/world/4.3.4/2017_05_24_02_world.sql new file mode 100644 index 0000000000..9e4912d13b --- /dev/null +++ b/sql/updates/world/4.3.4/2017_05_24_02_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_template` SET `flags_extra`=`flags_extra`|128 WHERE `entry` = 42940; From 2985952a49da117e404179da53d189d68e8d037d Mon Sep 17 00:00:00 2001 From: Naios Date: Tue, 23 May 2017 17:45:52 +0200 Subject: [PATCH 25/44] Build: Fix a build error which happened on unix debug builds * Thanks DDuarte for the fix * Closes #19786 --- dep/efsw/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/dep/efsw/CMakeLists.txt b/dep/efsw/CMakeLists.txt index eecc553194..f268558a52 100644 --- a/dep/efsw/CMakeLists.txt +++ b/dep/efsw/CMakeLists.txt @@ -1,5 +1,6 @@ if (BUILD_SHARED_LIBS) set(SRCS + src/efsw/Debug.cpp src/efsw/DirectorySnapshot.cpp src/efsw/DirectorySnapshotDiff.cpp src/efsw/DirWatcherGeneric.cpp From aa864d57f750df2f1922c3497af91d3e0d350430 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 15 Apr 2017 17:15:28 +0200 Subject: [PATCH 26/44] Core/Hotswap: Replace #ifdef conditions with comparisons of values defined in CompilerDefs.h (cherry picked from commit 43510a258c83215efcf5e70a253523e8a4199502) --- src/server/game/Scripting/ScriptReloadMgr.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/server/game/Scripting/ScriptReloadMgr.cpp b/src/server/game/Scripting/ScriptReloadMgr.cpp index 72f935e5cd..208f5c1b3a 100644 --- a/src/server/game/Scripting/ScriptReloadMgr.cpp +++ b/src/server/game/Scripting/ScriptReloadMgr.cpp @@ -64,7 +64,7 @@ ScriptReloadMgr* ScriptReloadMgr::instance() namespace fs = boost::filesystem; -#ifdef _WIN32 +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS #include #define HOTSWAP_PLATFORM_REQUIRES_CACHING #elif __APPLE__ @@ -83,7 +83,7 @@ namespace fs = boost::filesystem; // Returns "" on Windows and "lib" on posix. static char const* GetSharedLibraryPrefix() { -#ifdef _WIN32 +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS return ""; #else // Posix return "lib"; @@ -93,16 +93,16 @@ static char const* GetSharedLibraryPrefix() // Returns "dll" on Windows, "dylib" on OS X, and "so" on posix. static char const* GetSharedLibraryExtension() { -#ifdef _WIN32 +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS return "dll"; -#elif __APPLE__ +#elif TRINITY_PLATFORM == TRINITY_PLATFORM_APPLE return "dylib"; #else // Posix return "so"; #endif } -#ifdef _WIN32 +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS typedef HMODULE HandleType; #else // Posix typedef void* HandleType; @@ -131,7 +131,7 @@ public: void operator() (HandleType handle) const { // Unload the associated shared library. -#ifdef _WIN32 +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS bool success = (FreeLibrary(handle) != 0); #else // Posix bool success = (dlclose(handle) == 0); @@ -241,7 +241,7 @@ private: template static bool GetFunctionFromSharedLibrary(HandleType handle, std::string const& name, Fn& fn) { -#ifdef _WIN32 +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS fn = reinterpret_cast(GetProcAddress(handle, name.c_str())); #else // Posix fn = reinterpret_cast(dlsym(handle, name.c_str())); @@ -260,7 +260,7 @@ Optional> return path; }(); -#ifdef _WIN32 +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS HandleType handle = LoadLibrary(load_path.generic_string().c_str()); #else // Posix HandleType handle = dlopen(load_path.generic_string().c_str(), RTLD_LAZY); @@ -404,7 +404,7 @@ static std::string CalculateScriptModuleProjectName(std::string const& module) /// could block the rebuild of new shared libraries. static bool IsDebuggerBlockingRebuild() { -#ifdef _WIN32 +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS if (IsDebuggerPresent()) return true; #endif @@ -1344,7 +1344,7 @@ private: auto current_path = fs::current_path(); - #ifndef _WIN32 + #if TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS // The worldserver location is ${CMAKE_INSTALL_PREFIX}/bin // on all other platforms then windows current_path = current_path.parent_path(); From 225b6ede8198704caa59f4b9251545c169d2e359 Mon Sep 17 00:00:00 2001 From: DoctorKraft Date: Sat, 15 Apr 2017 15:55:49 +0200 Subject: [PATCH 27/44] Core/Hotswap: Fix Reload on Linux * Closes #19465 --- src/server/game/Scripting/ScriptReloadMgr.cpp | 27 +++++-------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/server/game/Scripting/ScriptReloadMgr.cpp b/src/server/game/Scripting/ScriptReloadMgr.cpp index 208f5c1b3a..18b910420b 100644 --- a/src/server/game/Scripting/ScriptReloadMgr.cpp +++ b/src/server/game/Scripting/ScriptReloadMgr.cpp @@ -66,13 +66,8 @@ namespace fs = boost::filesystem; #if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS #include - #define HOTSWAP_PLATFORM_REQUIRES_CACHING -#elif __APPLE__ +#else // Posix and Apple #include - #define HOTSWAP_PLATFORM_REQUIRES_CACHING -#else // Posix - #include - // #define HOTSWAP_PLATFORM_REQUIRES_CACHING #endif // Promote the sScriptReloadMgr to a HotSwapScriptReloadMgr @@ -609,8 +604,6 @@ public: } } - #ifdef HOTSWAP_PLATFORM_REQUIRES_CACHING - temporary_cache_path_ = CalculateTemporaryCachePath(); // We use the boost filesystem function versions which accept @@ -629,8 +622,6 @@ public: // Used to silent compiler warnings (void)code; - #endif // #ifdef HOTSWAP_PLATFORM_REQUIRES_CACHING - // Correct the CMake prefix when needed if (sWorld->getBoolConfig(CONFIG_HOTSWAP_PREFIX_CORRECTION_ENABLED)) DoCMakePrefixCorrectionIfNeeded(); @@ -867,21 +858,17 @@ private: ASSERT(_running_script_module_names.find(path) == _running_script_module_names.end(), "Can't load a module which is running already!"); - Optional cache_path; - - #ifdef HOTSWAP_PLATFORM_REQUIRES_CACHING - - // Copy the shared library into a cache on platforms which lock files on use (windows). - cache_path = GenerateUniquePathForLibraryInCache(path); + // Copy the shared library into a cache + auto cache_path = GenerateUniquePathForLibraryInCache(path); { boost::system::error_code code; - fs::copy_file(path, *cache_path, fs::copy_option::fail_if_exists, code); + fs::copy_file(path, cache_path, fs::copy_option::fail_if_exists, code); if (code) { TC_LOG_FATAL("scripts.hotswap", ">> Failed to create cache entry for module " "\"%s\" at \"%s\" with reason (\"%s\")!", - path.filename().generic_string().c_str(), cache_path->generic_string().c_str(), + path.filename().generic_string().c_str(), cache_path.generic_string().c_str(), code.message().c_str()); // Find a better solution for this but it's much better @@ -892,11 +879,9 @@ private: } TC_LOG_TRACE("scripts.hotswap", ">> Copied the shared library \"%s\" to \"%s\" for caching.", - path.filename().generic_string().c_str(), cache_path->generic_string().c_str()); + path.filename().generic_string().c_str(), cache_path.generic_string().c_str()); } - #endif // #ifdef HOTSWAP_PLATFORM_REQUIRES_CACHING - auto module = ScriptModule::CreateFromPath(path, cache_path); if (!module) { From f44b2ab7bbb893c0819dc12d1e03b638cdc26537 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Tue, 23 May 2017 23:29:18 +0200 Subject: [PATCH 28/44] DB/Commands: Typo in account set gmlevel help field Closes #19448 by Heaven31415 --- sql/updates/world/3.3.5/2017_05_23_00_world.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 sql/updates/world/3.3.5/2017_05_23_00_world.sql diff --git a/sql/updates/world/3.3.5/2017_05_23_00_world.sql b/sql/updates/world/3.3.5/2017_05_23_00_world.sql new file mode 100644 index 0000000000..635d13558d --- /dev/null +++ b/sql/updates/world/3.3.5/2017_05_23_00_world.sql @@ -0,0 +1,2 @@ +-- correct typo in account set gmlevel command help +UPDATE `command` SET `help`="Syntax: .account set gmlevel [$account] #level [#realmID]\r\n\r\nSet the security level for targeted player (can't be used at self) or for account $name to a level of #level on the realm #realmID.\r\n\r\n#level may range from 0 to 3.\r\n\r\n#realmID may be -1 for all realms." WHERE `name`='account set gmlevel'; From 70f3879c326464dff25b574875c0e984c6bd0d29 Mon Sep 17 00:00:00 2001 From: ariel- Date: Tue, 23 May 2017 20:18:45 -0300 Subject: [PATCH 29/44] Core/Player: update interaction checks, some info taken from client --- src/server/game/Entities/Player/Player.cpp | 45 ++++++++++++---------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 630864d61f..5aa865286f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2559,8 +2559,8 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid const& guid, uint32 npcflag if (creature->GetReactionTo(this) <= REP_UNFRIENDLY) return nullptr; - // not too far - if (!creature->IsWithinDistInMap(this, INTERACTION_DISTANCE)) + // not too far, taken from CGGameUI::SetInteractTarget + if (!creature->IsWithinDistInMap(this, creature->GetCombatReach() + 4.0f)) return nullptr; return creature; @@ -2568,33 +2568,36 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid const& guid, uint32 npcflag GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid) const { - if (GameObject* go = GetMap()->GetGameObject(guid)) - { - if (go->IsWithinDistInMap(this, go->GetInteractionDistance())) - return go; + if (!guid) + return nullptr; - TC_LOG_DEBUG("maps", "GetGameObjectIfCanInteractWith: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal %f is allowed)", go->GetGOInfo()->name.c_str(), - go->GetGUID().GetCounter(), GetName().c_str(), GetGUID().GetCounter(), go->GetDistance(this), go->GetInteractionDistance()); - } + if (!IsInWorld()) + return nullptr; - return nullptr; + if (IsInFlight()) + return nullptr; + + // exist + GameObject* go = ObjectAccessor::GetGameObject(*this, guid); + if (!go) + return nullptr; + + if (!go->IsWithinDistInMap(this, go->GetInteractionDistance())) + return nullptr; + + return go; } GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid, GameobjectTypes type) const { - if (GameObject* go = GetMap()->GetGameObject(guid)) - { - if (go->GetGoType() == type) - { - if (go->IsWithinDistInMap(this, go->GetInteractionDistance())) - return go; + GameObject* go = GetGameObjectIfCanInteractWith(guid); + if (!go) + return nullptr; - TC_LOG_DEBUG("maps", "Player::GetGameObjectIfCanInteractWith: GameObject '%s' (%s) is too far away from player '%s' (%s) to be used by him (Distance: %f, maximal 10 is allowed)", - go->GetGOInfo()->name.c_str(), go->GetGUID().ToString().c_str(), GetName().c_str(), GetGUID().ToString().c_str(), go->GetDistance(this)); - } - } + if (go->GetGoType() != type) + return nullptr; - return nullptr; + return go; } bool Player::IsUnderWater() const From 2e73ba1e67c23406fc1235c774fa0e8d6c27d6e9 Mon Sep 17 00:00:00 2001 From: Killyana Date: Wed, 24 May 2017 02:13:12 +0200 Subject: [PATCH 30/44] DB/Quest: Blowing Hodir's Horn requirement Ref #19787 --- sql/updates/world/3.3.5/2017_05_24_00_world.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 sql/updates/world/3.3.5/2017_05_24_00_world.sql diff --git a/sql/updates/world/3.3.5/2017_05_24_00_world.sql b/sql/updates/world/3.3.5/2017_05_24_00_world.sql new file mode 100644 index 0000000000..5d9655ebf4 --- /dev/null +++ b/sql/updates/world/3.3.5/2017_05_24_00_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `quest_template_addon` SET `PrevQuestID`=12976 WHERE `id`=12977; From 0865b12a1b66fe3b0ace2ab189f82ed91ebcfa13 Mon Sep 17 00:00:00 2001 From: Killyana Date: Wed, 24 May 2017 17:03:39 +0200 Subject: [PATCH 31/44] DB/GamObject: Sons of Hodir Gameobject quest givers Visibility Closes #19787 --- sql/updates/world/3.3.5/2017_05_24_01_world.sql | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 sql/updates/world/3.3.5/2017_05_24_01_world.sql diff --git a/sql/updates/world/3.3.5/2017_05_24_01_world.sql b/sql/updates/world/3.3.5/2017_05_24_01_world.sql new file mode 100644 index 0000000000..3830183971 --- /dev/null +++ b/sql/updates/world/3.3.5/2017_05_24_01_world.sql @@ -0,0 +1,9 @@ +-- +UPDATE `gameobject_addon` SET `invisibilityType`=9, `invisibilityValue`=1000 WHERE `guid`=270; +UPDATE `gameobject_addon` SET `invisibilityType`=8, `invisibilityValue`=1000 WHERE `guid`=21077; +UPDATE `gameobject_addon` SET `invisibilityType`=5, `invisibilityValue`=1000 WHERE `guid`=21079; +DELETE FROM `spell_area` WHERE `spell` IN (56773,56772,56774) AND `area`=4438; +INSERT INTO `spell_area` (`spell`, `area`, `quest_start`, `quest_end`, `aura_spell`, `racemask`, `gender`, `autocast`, `quest_start_status`, `quest_end_status`) VALUES +(56773, 4438, 12987, 0, 0, 0, 2, 1, 66, 0), +(56772, 4438, 13001, 0, 0, 0, 2, 1, 64, 0), +(56774, 4438, 12976, 0, 0, 0, 2, 1, 64, 0); From 63137688f55995e1e8a016f35ad8bfc19bfa56c9 Mon Sep 17 00:00:00 2001 From: Dr-J Date: Thu, 25 May 2017 12:03:41 +0100 Subject: [PATCH 32/44] DB/SAI: Tormenting the softknuckles Fix script so that if player does not sucessfully kill the hardknuckle matriach it does not remain hostile as an invisible mob to players doing damage to players who get in agro range. --- sql/updates/world/3.3.5/2017_05_25_00_world.sql | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 sql/updates/world/3.3.5/2017_05_25_00_world.sql diff --git a/sql/updates/world/3.3.5/2017_05_25_00_world.sql b/sql/updates/world/3.3.5/2017_05_25_00_world.sql new file mode 100644 index 0000000000..f8a1e0e2bf --- /dev/null +++ b/sql/updates/world/3.3.5/2017_05_25_00_world.sql @@ -0,0 +1,7 @@ +UPDATE `smart_scripts` SET `link`=13 WHERE `entryorguid`=28213 AND `source_type`=0 AND `id`IN(8,10); +UPDATE `smart_scripts` SET `event_type`=7 WHERE `entryorguid`=28213 AND `source_type`=0 AND `id`=9 AND `link`=10; +DELETE FROM `smart_scripts` WHERE `entryorguid` =28213 AND `source_type`=0 AND `id`IN(13,14,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`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(28213, 0, 13, 0, 61, 0, 100, 512, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hardknuckle Matriarch - On Respawn - Set Passive'), +(28213, 0, 14, 0, 61, 0, 100, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 21, 500, 0, 0, 0, 0, 0, 0, 'Hardknuckle Matriarch - On Data Set 1 1 - Start Attacking'), +(28213, 0, 6, 14, 61, 0, 100, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hardknuckle Matriarch - On Data Set 1 1 - Set Aggresive'); From 06168fb4123e52a479b1dd209a9edba311806e66 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Fri, 26 May 2017 14:47:59 +0200 Subject: [PATCH 33/44] Implement real time statistic visualization --- contrib/grafana/1_General.json | 889 ++++++++++++++++++ contrib/grafana/2_Maps.json | 339 +++++++ contrib/grafana/3_Network.json | 242 +++++ src/common/Collision/Maps/MapTree.cpp | 5 + src/common/Metric/Metric.cpp | 235 +++++ src/common/Metric/Metric.h | 149 +++ src/server/game/Handlers/CharacterHandler.cpp | 3 + src/server/game/Movement/PathGenerator.cpp | 3 + src/server/game/Server/WorldSession.cpp | 5 + src/server/game/World/World.cpp | 8 + src/server/worldserver/Main.cpp | 11 + src/server/worldserver/worldserver.conf.dist | 39 + 12 files changed, 1928 insertions(+) create mode 100644 contrib/grafana/1_General.json create mode 100644 contrib/grafana/2_Maps.json create mode 100644 contrib/grafana/3_Network.json create mode 100644 src/common/Metric/Metric.cpp create mode 100644 src/common/Metric/Metric.h diff --git a/contrib/grafana/1_General.json b/contrib/grafana/1_General.json new file mode 100644 index 0000000000..96b0c9170a --- /dev/null +++ b/contrib/grafana/1_General.json @@ -0,0 +1,889 @@ +{ + "id": 1, + "title": "General info", + "originalTitle": "General info", + "tags": [], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": false, + "sharedCrosshair": false, + "rows": [ + { + "collapse": false, + "editable": true, + "height": "25px", + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": null, + "editable": true, + "error": false, + "format": "none", + "id": 5, + "interval": null, + "isNew": true, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [ + { + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "auto" + ], + "type": "time" + } + ], + "measurement": "online_players", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "type": "field", + "params": [ + "value" + ] + }, + { + "type": "last", + "params": [] + } + ] + ], + "tags": [ + { + "key": "realm", + "operator": "=~", + "value": "/^$realm$/" + } + ] + } + ], + "thresholds": "", + "title": "Online players", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current", + "timeFrom": null, + "timeShift": null, + "hideTimeOverride": false + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": null, + "editable": true, + "error": false, + "format": "none", + "id": 6, + "interval": null, + "isNew": true, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [ + { + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "auto" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "update_time_diff", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "realm", + "operator": "=~", + "value": "/^$realm$/" + } + ] + } + ], + "thresholds": "", + "title": "Update diff (avg)", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg", + "timeFrom": "1m" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": null, + "editable": true, + "error": false, + "format": "none", + "id": 7, + "interval": null, + "isNew": true, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [ + { + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "auto" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "update_time_diff", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "thresholds": "", + "title": "Update diff (avg)", + "transparent": false, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg", + "timeFrom": "5m" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": null, + "editable": true, + "error": false, + "format": "none", + "id": 8, + "interval": null, + "isNew": true, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [ + { + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "auto" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "update_time_diff", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "realm", + "operator": "=~", + "value": "/^$realm$/" + } + ] + } + ], + "thresholds": "", + "title": "Update diff (avg)", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg", + "timeFrom": "15m", + "timeShift": null + } + ], + "title": "New row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": "Influx", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 1, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "Update diff", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "update_time_diff", + "policy": "default", + "query": "SELECT mean(\"value\") FROM \"update_time_diff\" WHERE \"realm\" =~ /$realm$/ AND $timeFilter GROUP BY time($interval) fill(null)", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "realm", + "operator": "=~", + "value": "/$realm$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Update diff", + "tooltip": { + "msResolution": false, + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "show": true + }, + "y-axis": true, + "y_formats": [ + "ms", + "short" + ], + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "title": "Row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": "Influx", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 4, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "Online players", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "online_players", + "policy": "default", + "query": "SELECT mean(\"value\") FROM \"online_players\" WHERE \"realm\" =~ /$realm$/ AND $timeFilter GROUP BY time($interval) fill(null)", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "realm", + "operator": "=~", + "value": "/$realm$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Online players", + "tooltip": { + "msResolution": false, + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "show": true + }, + "y-axis": true, + "y_formats": [ + "short", + "short" + ], + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "title": "New row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": "Influx", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 3, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Logouts", + "transform": "negative-Y" + } + ], + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "Logins", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "player_events", + "policy": "default", + "query": "SELECT count(\"text\") FROM \"player_events\" WHERE \"realm\" =~ /$realm$/ AND \"title\" = 'Login' AND $timeFilter GROUP BY time($interval) fill(0)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "text" + ], + "type": "field" + }, + { + "params": [], + "type": "count" + } + ] + ], + "tags": [ + { + "key": "realm", + "operator": "=", + "value": "Trinity" + } + ] + }, + { + "alias": "Logouts", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "policy": "default", + "query": "SELECT count(\"text\") FROM \"player_events\" WHERE \"realm\" =~ /$realm$/ AND \"title\" = 'Logout' AND $timeFilter GROUP BY time($interval) fill(0)", + "rawQuery": true, + "refId": "B", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Player login/logout", + "tooltip": { + "msResolution": false, + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "xaxis": { + "show": true + }, + "y-axis": true, + "y_formats": [ + "short", + "short" + ], + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "title": "New row" + } + ], + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": { + "now": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "templating": { + "list": [ + { + "allFormat": "regex values", + "current": { + "text": "Trinity", + "value": "Trinity" + }, + "datasource": null, + "includeAll": false, + "multi": false, + "multiFormat": "regex values", + "name": "realm", + "options": [ + { + "text": "Trinity", + "value": "Trinity", + "selected": true + } + ], + "query": "show tag values from events with key = realm", + "refresh": 1, + "regex": "", + "type": "query" + } + ] + }, + "annotations": { + "list": [ + { + "datasource": "Influx", + "enable": true, + "iconColor": "#C0C6BE", + "iconSize": 13, + "lineColor": "rgba(255, 96, 96, 0.592157)", + "name": "Global Events", + "query": "select title, text from events where $timeFilter and realm =~ /$realm$/", + "showLine": true, + "textColumn": "text", + "titleColumn": "title" + } + ] + }, + "refresh": "1m", + "schemaVersion": 12, + "version": 7, + "links": [] +} \ No newline at end of file diff --git a/contrib/grafana/2_Maps.json b/contrib/grafana/2_Maps.json new file mode 100644 index 0000000000..6c2cecb103 --- /dev/null +++ b/contrib/grafana/2_Maps.json @@ -0,0 +1,339 @@ +{ + "id": 2, + "title": "Maps, vmaps and mmaps", + "originalTitle": "Maps, vmaps and mmaps", + "tags": [], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": false, + "sharedCrosshair": false, + "rows": [ + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": "Influx", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 2, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Unload tile", + "transform": "negative-Y" + } + ], + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "Load tile", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "query": "SELECT count(\"title\") FROM \"map_events\" WHERE \"realm\" =~ /$realm$/ AND \"title\" = 'LoadMapTile' AND $timeFilter GROUP BY time($interval) fill(0)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + }, + { + "alias": "Unload tile", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "query": "SELECT count(\"title\") FROM \"map_events\" WHERE \"realm\" =~ /$realm$/ AND \"title\" = 'UnloadMapTile' AND $timeFilter GROUP BY time($interval) fill(0)", + "rawQuery": true, + "refId": "B", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Map", + "tooltip": { + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ] + } + ], + "title": "Row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": "Influx", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 1, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "Pathfinding queries", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "query": "SELECT count(\"title\") FROM \"mmap_events\" WHERE \"realm\" =~ /$realm$/ AND \"title\" = 'CalculatePath' AND $timeFilter GROUP BY time($interval) fill(0)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "MMap", + "tooltip": { + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ] + } + ], + "title": "New row" + } + ], + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": { + "now": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "templating": { + "list": [ + { + "allFormat": "regex values", + "current": { + "text": "Trinity", + "value": "Trinity" + }, + "datasource": "Influx", + "includeAll": false, + "multi": false, + "multiFormat": "regex values", + "name": "realm", + "options": [ + { + "text": "Trinity", + "value": "Trinity", + "selected": true + } + ], + "query": "show tag values from events with key = realm", + "refresh": true, + "type": "query" + } + ] + }, + "annotations": { + "list": [ + { + "datasource": "Influx", + "enable": true, + "iconColor": "#C0C6BE", + "iconSize": 13, + "lineColor": "rgba(255, 96, 96, 0.592157)", + "name": "Global Events", + "query": "select title, text from events where $timeFilter and realm =~ /$realm$/", + "showLine": true, + "textColumn": "text", + "titleColumn": "title" + } + ] + }, + "refresh": "1m", + "schemaVersion": 8, + "version": 11, + "links": [] +} \ No newline at end of file diff --git a/contrib/grafana/3_Network.json b/contrib/grafana/3_Network.json new file mode 100644 index 0000000000..98c190e118 --- /dev/null +++ b/contrib/grafana/3_Network.json @@ -0,0 +1,242 @@ +{ + "id": 3, + "title": "Network", + "originalTitle": "Network", + "tags": [], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": false, + "sharedCrosshair": false, + "rows": [ + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": "Influx", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 1, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "Processed packets", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "processed_packets", + "query": "SELECT sum(\"value\") FROM \"processed_packets\" WHERE \"realm\" =~ /$realm$/ AND $timeFilter GROUP BY time($interval) fill(0)", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "realm", + "operator": "=~", + "value": "/$realm$/" + } + ] + }, + { + "alias": "Processed packets / mean per session", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "processed_packets", + "query": "SELECT mean(\"value\") FROM \"processed_packets\" WHERE \"realm\" =~ /$realm$/ AND $timeFilter GROUP BY time($interval) fill(0)", + "refId": "B", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "realm", + "operator": "=~", + "value": "/$realm$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Processed packets", + "tooltip": { + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ] + } + ], + "title": "Row" + } + ], + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": { + "now": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "templating": { + "list": [ + { + "allFormat": "regex values", + "current": { + "text": "Trinity", + "value": "Trinity" + }, + "datasource": "Influx", + "includeAll": false, + "multi": false, + "multiFormat": "regex values", + "name": "realm", + "options": [ + { + "text": "Trinity", + "value": "Trinity", + "selected": true + } + ], + "query": "show tag values from events with key = realm", + "refresh": true, + "type": "query" + } + ] + }, + "annotations": { + "list": [ + { + "datasource": "Influx", + "enable": true, + "iconColor": "#C0C6BE", + "iconSize": 13, + "lineColor": "rgba(255, 96, 96, 0.592157)", + "name": "Global Events", + "query": "select title, text from events where $timeFilter and realm =~ /$realm$/", + "showLine": true, + "textColumn": "text", + "titleColumn": "title" + } + ] + }, + "refresh": "1m", + "schemaVersion": 8, + "version": 7, + "links": [] +} \ No newline at end of file diff --git a/src/common/Collision/Maps/MapTree.cpp b/src/common/Collision/Maps/MapTree.cpp index 168bee50aa..1fc9682d5d 100644 --- a/src/common/Collision/Maps/MapTree.cpp +++ b/src/common/Collision/Maps/MapTree.cpp @@ -22,6 +22,7 @@ #include "VMapDefinitions.h" #include "Log.h" #include "Errors.h" +#include "Metric.h" #include #include @@ -347,6 +348,8 @@ namespace VMAP // currently, core creates grids for all maps, whether it has terrain tiles or not // so we need "fake" tile loads to know when we can unload map geometry iLoadedTiles[packTileID(tileX, tileY)] = false; + TC_METRIC_EVENT("map_events", "LoadMapTile", + "Map: " + std::to_string(iMapID) + " TileX: " + std::to_string(tileX) + " TileY: " + std::to_string(tileY)); return true; } if (!iTreeValues) @@ -473,6 +476,8 @@ namespace VMAP } } iLoadedTiles.erase(tile); + TC_METRIC_EVENT("map_events", "UnloadMapTile", + "Map: " + std::to_string(iMapID) + " TileX: " + std::to_string(tileX) + " TileY: " + std::to_string(tileY)); } void StaticMapTree::getModelInstances(ModelInstance* &models, uint32 &count) diff --git a/src/common/Metric/Metric.cpp b/src/common/Metric/Metric.cpp new file mode 100644 index 0000000000..7091dd0d37 --- /dev/null +++ b/src/common/Metric/Metric.cpp @@ -0,0 +1,235 @@ +/* +* Copyright (C) 2008-2017 TrinityCore +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see . +*/ + +#include "Metric.h" +#include "Log.h" +#include "Config.h" +#include "Util.h" + +void Metric::Initialize(std::string const& realmName, boost::asio::io_service& ioService, std::function overallStatusLogger) +{ + _realmName = FormatInfluxDBTagValue(realmName); + _batchTimer = Trinity::make_unique(ioService); + _overallStatusTimer = Trinity::make_unique(ioService); + _overallStatusLogger = overallStatusLogger; + LoadFromConfigs(); +} + +bool Metric::Connect() +{ + _dataStream.connect(_hostname, _port); + auto error = _dataStream.error(); + if (error) + { + TC_LOG_ERROR("metric", "Error connecting to '%s:%s', disabling Metric. Error message : %s", + _hostname.c_str(), _port.c_str(), error.message().c_str()); + _enabled = false; + return false; + } + _dataStream.clear(); + return true; +} + +void Metric::LoadFromConfigs() +{ + bool previousValue = _enabled; + _enabled = sConfigMgr->GetBoolDefault("Metric.Enable", false); + _updateInterval = sConfigMgr->GetIntDefault("Metric.Interval", 10); + if (_updateInterval < 1) + { + TC_LOG_ERROR("metric", "'Metric.Interval' config set to %d, overriding to 1.", _updateInterval); + _updateInterval = 1; + } + + _overallStatusTimerInterval = sConfigMgr->GetIntDefault("Metric.OverallStatusInterval", 1); + if (_overallStatusTimerInterval < 1) + { + TC_LOG_ERROR("metric", "'Metric.OverallStatusInterval' config set to %d, overriding to 1.", _overallStatusTimerInterval); + _overallStatusTimerInterval = 1; + } + + // Schedule a send at this point only if the config changed from Disabled to Enabled. + // Cancel any scheduled operation if the config changed from Enabled to Disabled. + if (_enabled && !previousValue) + { + std::string connectionInfo = sConfigMgr->GetStringDefault("Metric.ConnectionInfo", ""); + if (connectionInfo.empty()) + { + TC_LOG_ERROR("metric", "'Metric.ConnectionInfo' not specified in configuration file."); + return; + } + + Tokenizer tokens(connectionInfo, ';'); + if (tokens.size() != 3) + { + TC_LOG_ERROR("metric", "'Metric.ConnectionInfo' specified with wrong format in configuration file."); + return; + } + + _hostname.assign(tokens[0]); + _port.assign(tokens[1]); + _databaseName.assign(tokens[2]); + Connect(); + + ScheduleSend(); + ScheduleOverallStatusLog(); + } +} + +void Metric::Update() +{ + if (_overallStatusTimerTriggered) + { + _overallStatusTimerTriggered = false; + _overallStatusLogger(); + } +} + +void Metric::LogEvent(std::string const& category, std::string const& title, std::string const& description) +{ + using namespace std::chrono; + + MetricData* data = new MetricData; + data->Category = category; + data->Timestamp = system_clock::now(); + data->Type = METRIC_DATA_EVENT; + data->Title = title; + data->Text = description; + + _queuedData.Enqueue(data); +} + +void Metric::SendBatch() +{ + using namespace std::chrono; + + std::stringstream batchedData; + MetricData* data; + bool firstLoop = true; + while (_queuedData.Dequeue(data)) + { + if (!firstLoop) + batchedData << "\n"; + + batchedData << data->Category; + if (!_realmName.empty()) + batchedData << ",realm=" << _realmName; + + batchedData << " "; + + switch (data->Type) + { + case METRIC_DATA_VALUE: + batchedData << "value=" << data->Value; + break; + case METRIC_DATA_EVENT: + batchedData << "title=\"" << data->Title << "\",text=\"" << data->Text << "\""; + break; + } + + batchedData << " "; + + batchedData << std::to_string(duration_cast(data->Timestamp.time_since_epoch()).count()); + + firstLoop = false; + delete data; + } + + // Check if there's any data to send + if (batchedData.tellp() == std::streampos(0)) + { + ScheduleSend(); + return; + } + + if (!_dataStream.good() && !Connect()) + return; + + _dataStream << "POST " << "/write?db=" << _databaseName << " HTTP/1.1\r\n"; + _dataStream << "Host: " << _hostname << ":" << _port << "\r\n"; + _dataStream << "Accept: */*\r\n"; + _dataStream << "Content-Type: application/octet-stream\r\n"; + _dataStream << "Content-Transfer-Encoding: binary\r\n"; + + _dataStream << "Content-Length: " << std::to_string(batchedData.tellp()) << "\r\n\r\n"; + _dataStream << batchedData.rdbuf(); + + std::string http_version; + _dataStream >> http_version; + unsigned int status_code = 0; + _dataStream >> status_code; + if (status_code != 204) + { + TC_LOG_ERROR("metric", "Error sending data, returned HTTP code: %u", status_code); + } + + // Read and ignore the status description + std::string status_description; + std::getline(_dataStream, status_description); + // Read headers + std::string header; + while (std::getline(_dataStream, header) && header != "\r") + { + if (header == "Connection: close\r") + _dataStream.close(); + } + + ScheduleSend(); +} + +void Metric::ScheduleSend() +{ + if (_enabled) + { + _batchTimer->expires_from_now(boost::posix_time::seconds(_updateInterval)); + _batchTimer->async_wait(std::bind(&Metric::SendBatch, this)); + } + else + { + _dataStream.close(); + MetricData* data; + // Clear the queue + while (_queuedData.Dequeue(data)) + ; + } +} + +void Metric::ForceSend() +{ + // Send what's queued only if io_service is stopped (so only on shutdown) + if (_enabled && _batchTimer->get_io_service().stopped()) + SendBatch(); +} + +void Metric::ScheduleOverallStatusLog() +{ + if (_enabled) + { + _overallStatusTimer->expires_from_now(boost::posix_time::seconds(_overallStatusTimerInterval)); + _overallStatusTimer->async_wait([this](const boost::system::error_code&) + { + _overallStatusTimerTriggered = true; + ScheduleOverallStatusLog(); + }); + } +} + +Metric* Metric::instance() +{ + static Metric instance; + return &instance; +} diff --git a/src/common/Metric/Metric.h b/src/common/Metric/Metric.h new file mode 100644 index 0000000000..f3a852c755 --- /dev/null +++ b/src/common/Metric/Metric.h @@ -0,0 +1,149 @@ +/* +* Copyright (C) 2008-2017 TrinityCore +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see . +*/ + +#ifndef METRIC_H__ +#define METRIC_H__ + +#include "Common.h" +#include "Threading/MPSCQueue.h" +#include +#include +#include + +enum MetricDataType +{ + METRIC_DATA_VALUE, + METRIC_DATA_EVENT +}; + +struct MetricData +{ + std::string Category; + std::chrono::time_point Timestamp; + MetricDataType Type; + + // LogValue-specific fields + std::string Value; + + // LogEvent-specific fields + std::string Title; + std::string Text; +}; + +class TC_COMMON_API Metric +{ +private: + boost::asio::ip::tcp::iostream _dataStream; + MPSCQueue _queuedData; + std::unique_ptr _batchTimer; + std::unique_ptr _overallStatusTimer; + int32 _updateInterval = 0; + int32 _overallStatusTimerInterval = 0; + bool _enabled = false; + bool _overallStatusTimerTriggered = false; + std::string _hostname; + std::string _port; + std::string _databaseName; + std::function _overallStatusLogger; + std::string _realmName; + + bool Connect(); + void SendBatch(); + void ScheduleSend(); + void ScheduleOverallStatusLog(); + + template::value>::type* = nullptr> + static std::string FormatInfluxDBValue(T value) { return std::to_string(value) + 'i'; } + + static std::string FormatInfluxDBValue(std::string const& value) + { + return '"' + boost::replace_all_copy(value, "\"", "\\\"") + '"'; + } + + static std::string FormatInfluxDBValue(bool value) { return value ? "t" : "f"; } + static std::string FormatInfluxDBValue(const char* value) { return FormatInfluxDBValue(std::string(value)); } + static std::string FormatInfluxDBValue(double value) { return std::to_string(value); } + static std::string FormatInfluxDBValue(float value) { return FormatInfluxDBValue(double(value)); } + + static std::string FormatInfluxDBTagValue(std::string const& value) + { + // ToDo: should handle '=' and ',' characters too + return boost::replace_all_copy(value, " ", "\\ "); + } + + // ToDo: should format TagKey and FieldKey too in the same way as TagValue + +public: + static Metric* instance(); + + void Initialize(std::string const& realmName, boost::asio::io_service& ioService, std::function overallStatusLogger = [](){}); + void LoadFromConfigs(); + void Update(); + + template + void LogValue(std::string const& category, T value) + { + using namespace std::chrono; + + MetricData* data = new MetricData; + data->Category = category; + data->Timestamp = system_clock::now(); + data->Type = METRIC_DATA_VALUE; + data->Value = FormatInfluxDBValue(value); + + _queuedData.Enqueue(data); + } + + void LogEvent(std::string const& category, std::string const& title, std::string const& description); + + void ForceSend(); + bool IsEnabled() const { return _enabled; } +}; + +#define sMetric Metric::instance() + +#if PLATFORM != PLATFORM_WINDOWS +#define TC_METRIC_EVENT(category, title, description) \ + do { \ + if (sMetric->IsEnabled()) \ + sMetric->LogEvent(category, title, description); \ + } while (0) +#define TC_METRIC_VALUE(category, value) \ + do { \ + if (sMetric->IsEnabled()) \ + sMetric->LogValue(category, value); \ + } while (0) +#else +#define TC_METRIC_EVENT(category, title, description) \ + __pragma(warning(push)) \ + __pragma(warning(disable:4127)) \ + do { \ + if (sMetric->IsEnabled()) \ + sMetric->LogEvent(category, title, description); \ + } while (0) \ + __pragma(warning(pop)) +#define TC_METRIC_VALUE(category, value) \ + __pragma(warning(push)) \ + __pragma(warning(disable:4127)) \ + do { \ + if (sMetric->IsEnabled()) \ + sMetric->LogValue(category, value); \ + } while (0) \ + __pragma(warning(pop)) +#endif + +#endif // METRIC_H__ diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 8db9e1b633..e0672d597c 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -49,6 +49,7 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" +#include "Metric.h" #include "BattlenetServerManager.h" class LoginQueryHolder : public SQLQueryHolder @@ -1048,6 +1049,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) sScriptMgr->OnPlayerLogin(pCurrChar, firstLogin); + TC_METRIC_EVENT("player_events", "Login", pCurrChar->GetName()); + sBattlenetServer.SendChangeToonOnlineState(GetBattlenetAccountId(), GetAccountId(), _player->GetGUID(), _player->GetName(), true); delete holder; diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index c4233ffc34..b354ef9e74 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -26,6 +26,7 @@ #include "DisableMgr.h" #include "DetourCommon.h" #include "DetourNavMeshQuery.h" +#include "Metric.h" ////////////////// PathGenerator ////////////////// PathGenerator::PathGenerator(const Unit* owner) : @@ -62,6 +63,8 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z)) return false; + TC_METRIC_EVENT("mmap_events", "CalculatePath", ""); + G3D::Vector3 dest(destX, destY, destZ); SetEndPosition(dest); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 9e5c9e2c90..d2db5848f8 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -47,6 +47,7 @@ #include "WardenWin.h" #include "WardenMac.h" #include "WardenMac.h" +#include "Metric.h" #include "BattlenetServerManager.h" #include @@ -422,6 +423,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) break; } + TC_METRIC_VALUE("processed_packets", processedPackets); + _recvQueue.readd(requeuePackets.begin(), requeuePackets.end()); if (m_Socket && m_Socket->IsOpen() && _warden) @@ -578,6 +581,8 @@ void WorldSession::LogoutPlayer(bool save) //! Call script hook before deletion sScriptMgr->OnPlayerLogout(_player); + TC_METRIC_EVENT("player_events", "Logout", _player->GetName()); + //! Remove the player from the world // the player may not be in the world when logging out // e.g if he got disconnected during a transfer to another map diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 8c596bb345..70dc8e831c 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -58,6 +58,7 @@ #include "ScriptReloadMgr.h" #include "SkillDiscovery.h" #include "SkillExtraItems.h" +#include "Metric.h" #include "SmartAI.h" #include "TicketMgr.h" #include "TransportMgr.h" @@ -396,6 +397,7 @@ void World::LoadConfigSettings(bool reload) return; } sLog->LoadFromConfig(); + sMetric->LoadFromConfigs(); } m_defaultDbcLocale = LocaleConstant(sConfigMgr->GetIntDefault("DBC.Locale", 0)); @@ -2062,6 +2064,8 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.worldserver", "World initialized in %u minutes %u seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000)); + TC_METRIC_EVENT("events", "World initialized", "World initialized in " + std::to_string(startupDuration / 60000) + " minutes " + std::to_string((startupDuration % 60000) / 1000) + " seconds"); + if (uint32 realmId = sConfigMgr->GetIntDefault("RealmID", 0)) // 0 reserved for auth sLog->SetRealmId(realmId); } @@ -2314,6 +2318,10 @@ void World::Update(uint32 diff) ProcessCliCommands(); sScriptMgr->OnWorldUpdate(diff); + + // Stats logger update + sMetric->Update(); + TC_METRIC_VALUE("update_time_diff", diff); } void World::ForceGameEventUpdate() diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index ee12a09342..0dbe53c092 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -47,6 +47,7 @@ #include "BattlenetServerManager.h" #include "DatabaseLoader.h" #include "AppenderDB.h" +#include "Metric.h" #include #include #include @@ -197,6 +198,13 @@ extern int main(int argc, char** argv) LoadRealmInfo(); + sMetric->Initialize(realm.Name, _ioService, []() + { + TC_METRIC_VALUE("online_players", sWorld->GetPlayerCount()); + }); + + TC_METRIC_EVENT("events", "Worldserver started", ""); + // Initialize the World sScriptMgr->SetScriptLoader(AddScripts); sWorld->SetInitialWorldSettings(); @@ -304,6 +312,9 @@ extern int main(int argc, char** argv) StopDB(); + TC_METRIC_EVENT("events", "Worldserver shutdown", ""); + sMetric->ForceSend(); + TC_LOG_INFO("server.worldserver", "Halting process..."); ShutdownCLIThread(cliThread); diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 1d0b111734..8ee38cacef 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -35,6 +35,7 @@ # LOGGING SYSTEM SETTINGS # CURRENCIES SETTINGS # PACKET SPOOF PROTECTION SETTINGS +# METRIC SETTINGS # ################################################################################################### @@ -3960,3 +3961,41 @@ BnetServer.Port = 1118 # ################################################################################################### + +################################################################################################### +# METRIC SETTINGS +# +# These settings control the statistics sent to the metric database (currently InfluxDB) +# +# Metric.Enable +# Description: Enables statistics sent to the metric database. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Metric.Enable = 0 + +# +# Metric.Interval +# Description: Interval between every batch of data sent in seconds +# Default: 10 seconds +# + +Metric.Interval = 10 + +# +# Metric.ConnectionInfo +# Description: Connection settings for metric database (currently InfluxDB). +# Example: "hostname;port;database" +# Default: "127.0.0.1;8086;worldserver" + +Metric.ConnectionInfo = "127.0.0.1;8086;worldserver" + +# +# Metric.OverallStatusInterval +# Description: Interval between every gathering of overall worldserver status data in seconds +# Default: 1 second +# + +Metric.OverallStatusInterval = 1 + +################################################################################################### \ No newline at end of file From 496bb4b105174df5d5f494c2d78801bbc7e0c773 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Fri, 26 May 2017 14:49:21 +0200 Subject: [PATCH 34/44] rename files --- .../2017_05_26_00_world_from_335_was_2017_05_23_00_world.sql} | 0 .../2017_05_26_01_world_from_335_was_2017_05_24_00_world.sql} | 0 .../2017_05_26_02_world_from_335_was_2017_05_24_01_world.sql} | 0 .../2017_05_26_03_world_from_335_was_2017_05_25_00_world.sql} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename sql/updates/world/{3.3.5/2017_05_23_00_world.sql => 4.3.4/2017_05_26_00_world_from_335_was_2017_05_23_00_world.sql} (100%) rename sql/updates/world/{3.3.5/2017_05_24_00_world.sql => 4.3.4/2017_05_26_01_world_from_335_was_2017_05_24_00_world.sql} (100%) rename sql/updates/world/{3.3.5/2017_05_24_01_world.sql => 4.3.4/2017_05_26_02_world_from_335_was_2017_05_24_01_world.sql} (100%) rename sql/updates/world/{3.3.5/2017_05_25_00_world.sql => 4.3.4/2017_05_26_03_world_from_335_was_2017_05_25_00_world.sql} (100%) diff --git a/sql/updates/world/3.3.5/2017_05_23_00_world.sql b/sql/updates/world/4.3.4/2017_05_26_00_world_from_335_was_2017_05_23_00_world.sql similarity index 100% rename from sql/updates/world/3.3.5/2017_05_23_00_world.sql rename to sql/updates/world/4.3.4/2017_05_26_00_world_from_335_was_2017_05_23_00_world.sql diff --git a/sql/updates/world/3.3.5/2017_05_24_00_world.sql b/sql/updates/world/4.3.4/2017_05_26_01_world_from_335_was_2017_05_24_00_world.sql similarity index 100% rename from sql/updates/world/3.3.5/2017_05_24_00_world.sql rename to sql/updates/world/4.3.4/2017_05_26_01_world_from_335_was_2017_05_24_00_world.sql diff --git a/sql/updates/world/3.3.5/2017_05_24_01_world.sql b/sql/updates/world/4.3.4/2017_05_26_02_world_from_335_was_2017_05_24_01_world.sql similarity index 100% rename from sql/updates/world/3.3.5/2017_05_24_01_world.sql rename to sql/updates/world/4.3.4/2017_05_26_02_world_from_335_was_2017_05_24_01_world.sql diff --git a/sql/updates/world/3.3.5/2017_05_25_00_world.sql b/sql/updates/world/4.3.4/2017_05_26_03_world_from_335_was_2017_05_25_00_world.sql similarity index 100% rename from sql/updates/world/3.3.5/2017_05_25_00_world.sql rename to sql/updates/world/4.3.4/2017_05_26_03_world_from_335_was_2017_05_25_00_world.sql From d8b9d2a9da6363bb83797e94e64d5f6c7336f43e Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 23 May 2017 18:34:02 +0200 Subject: [PATCH 35/44] Core/Misc: Prefix all preprocessor defines from CompilerDefs with TRINITY_ to avoid conflicts (PLATFORM_WINDOWS is used/defined by CascLib) (cherry picked from commit b8db320bf14e327bcd12279871b914d8635ef122) --- src/common/Common.h | 8 ++--- src/common/CompilerDefs.h | 34 +++++++++---------- src/common/Debugging/Errors.h | 2 +- .../Debugging/WheatyExceptionReport.cpp | 2 +- src/common/Debugging/WheatyExceptionReport.h | 2 +- src/common/Define.h | 18 +++++----- src/common/GitRevision.cpp | 8 ++--- src/common/Logging/AppenderConsole.cpp | 6 ++-- src/common/Logging/AppenderFile.cpp | 2 +- src/common/Logging/Log.h | 2 +- src/common/Metric/Metric.h | 2 +- src/common/Threading/ProcessPriority.h | 8 ++--- src/common/Utilities/Util.cpp | 8 ++--- src/server/authserver/Main.cpp | 12 +++---- src/server/game/World/World.cpp | 2 +- .../worldserver/CommandLine/CliRunnable.cpp | 14 ++++---- src/server/worldserver/Main.cpp | 2 +- 17 files changed, 65 insertions(+), 67 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index c9fd940641..20c442f4c0 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -53,14 +53,14 @@ #include "Threading/LockedQueue.h" -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS # include -# if defined(__INTEL_COMPILER) +# if TRINITY_COMPILER == TRINITY_COMPILER_INTEL # if !defined(BOOST_ASIO_HAS_MOVE) # define BOOST_ASIO_HAS_MOVE # endif // !defined(BOOST_ASIO_HAS_MOVE) -# endif // if defined(__INTEL_COMPILER) +# endif // if TRINITY_COMPILER == TRINITY_COMPILER_INTEL #else # include @@ -71,7 +71,7 @@ # include #endif -#if COMPILER == COMPILER_MICROSOFT +#if TRINITY_COMPILER == TRINITY_COMPILER_MICROSOFT #include diff --git a/src/common/CompilerDefs.h b/src/common/CompilerDefs.h index 10db058953..0509dcf917 100644 --- a/src/common/CompilerDefs.h +++ b/src/common/CompilerDefs.h @@ -19,37 +19,37 @@ #ifndef TRINITY_COMPILERDEFS_H #define TRINITY_COMPILERDEFS_H -#define PLATFORM_WINDOWS 0 -#define PLATFORM_UNIX 1 -#define PLATFORM_APPLE 2 -#define PLATFORM_INTEL 3 +#define TRINITY_PLATFORM_WINDOWS 0 +#define TRINITY_PLATFORM_UNIX 1 +#define TRINITY_PLATFORM_APPLE 2 +#define TRINITY_PLATFORM_INTEL 3 // must be first (win 64 also define _WIN32) #if defined( _WIN64 ) -# define PLATFORM PLATFORM_WINDOWS +# define TRINITY_PLATFORM TRINITY_PLATFORM_WINDOWS #elif defined( __WIN32__ ) || defined( WIN32 ) || defined( _WIN32 ) -# define PLATFORM PLATFORM_WINDOWS +# define TRINITY_PLATFORM TRINITY_PLATFORM_WINDOWS #elif defined( __APPLE_CC__ ) -# define PLATFORM PLATFORM_APPLE +# define TRINITY_PLATFORM TRINITY_PLATFORM_APPLE #elif defined( __INTEL_COMPILER ) -# define PLATFORM PLATFORM_INTEL +# define TRINITY_PLATFORM TRINITY_PLATFORM_INTEL #else -# define PLATFORM PLATFORM_UNIX +# define TRINITY_PLATFORM TRINITY_PLATFORM_UNIX #endif -#define COMPILER_MICROSOFT 0 -#define COMPILER_GNU 1 -#define COMPILER_BORLAND 2 -#define COMPILER_INTEL 3 +#define TRINITY_COMPILER_MICROSOFT 0 +#define TRINITY_COMPILER_GNU 1 +#define TRINITY_COMPILER_BORLAND 2 +#define TRINITY_COMPILER_INTEL 3 #ifdef _MSC_VER -# define COMPILER COMPILER_MICROSOFT +# define TRINITY_COMPILER TRINITY_COMPILER_MICROSOFT #elif defined( __BORLANDC__ ) -# define COMPILER COMPILER_BORLAND +# define TRINITY_COMPILER TRINITY_COMPILER_BORLAND #elif defined( __INTEL_COMPILER ) -# define COMPILER COMPILER_INTEL +# define TRINITY_COMPILER TRINITY_COMPILER_INTEL #elif defined( __GNUC__ ) -# define COMPILER COMPILER_GNU +# define TRINITY_COMPILER TRINITY_COMPILER_GNU # define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #else # error "FATAL ERROR: Unknown compiler." diff --git a/src/common/Debugging/Errors.h b/src/common/Debugging/Errors.h index bf06d77d30..c21972af90 100644 --- a/src/common/Debugging/Errors.h +++ b/src/common/Debugging/Errors.h @@ -38,7 +38,7 @@ namespace Trinity } // namespace Trinity -#if COMPILER == COMPILER_MICROSOFT +#if TRINITY_COMPILER == TRINITY_COMPILER_MICROSOFT #define ASSERT_BEGIN __pragma(warning(push)) __pragma(warning(disable: 4127)) #define ASSERT_END __pragma(warning(pop)) #else diff --git a/src/common/Debugging/WheatyExceptionReport.cpp b/src/common/Debugging/WheatyExceptionReport.cpp index 09a027d167..5585dd25c1 100644 --- a/src/common/Debugging/WheatyExceptionReport.cpp +++ b/src/common/Debugging/WheatyExceptionReport.cpp @@ -5,7 +5,7 @@ //========================================== #include "CompilerDefs.h" -#if PLATFORM == PLATFORM_WINDOWS && !defined(__MINGW32__) +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS && !defined(__MINGW32__) #define WIN32_LEAN_AND_MEAN #pragma warning(disable:4996) #pragma warning(disable:4312) diff --git a/src/common/Debugging/WheatyExceptionReport.h b/src/common/Debugging/WheatyExceptionReport.h index aec52b165f..91c2ae9317 100644 --- a/src/common/Debugging/WheatyExceptionReport.h +++ b/src/common/Debugging/WheatyExceptionReport.h @@ -1,7 +1,7 @@ #ifndef _WHEATYEXCEPTIONREPORT_ #define _WHEATYEXCEPTIONREPORT_ -#if PLATFORM == PLATFORM_WINDOWS && !defined(__MINGW32__) +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS && !defined(__MINGW32__) #include #include diff --git a/src/common/Define.h b/src/common/Define.h index a109c5ba1d..c1aa331b0a 100644 --- a/src/common/Define.h +++ b/src/common/Define.h @@ -21,7 +21,7 @@ #include "CompilerDefs.h" -#if COMPILER == COMPILER_GNU +#if TRINITY_COMPILER == TRINITY_COMPILER_GNU # if !defined(__STDC_FORMAT_MACROS) # define __STDC_FORMAT_MACROS # endif @@ -55,7 +55,7 @@ # endif #endif -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS # define TRINITY_PATH_MAX MAX_PATH # define _USE_MATH_DEFINES # ifndef DECLSPEC_NORETURN @@ -64,11 +64,11 @@ # ifndef DECLSPEC_DEPRECATED # define DECLSPEC_DEPRECATED __declspec(deprecated) # endif //DECLSPEC_DEPRECATED -#else //PLATFORM != PLATFORM_WINDOWS +#else // TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS # define TRINITY_PATH_MAX PATH_MAX # define DECLSPEC_NORETURN # define DECLSPEC_DEPRECATED -#endif //PLATFORM +#endif // TRINITY_PLATFORM #if !defined(COREDEBUG) # define TRINITY_INLINE inline @@ -79,21 +79,21 @@ # define TRINITY_INLINE #endif //!COREDEBUG -#if COMPILER == COMPILER_GNU +#if TRINITY_COMPILER == TRINITY_COMPILER_GNU # define ATTR_NORETURN __attribute__((__noreturn__)) # define ATTR_PRINTF(F, V) __attribute__ ((__format__ (__printf__, F, V))) # define ATTR_DEPRECATED __attribute__((__deprecated__)) -#else //COMPILER != COMPILER_GNU +#else //TRINITY_COMPILER != TRINITY_COMPILER_GNU # define ATTR_NORETURN # define ATTR_PRINTF(F, V) # define ATTR_DEPRECATED -#endif //COMPILER == COMPILER_GNU +#endif //TRINITY_COMPILER == TRINITY_COMPILER_GNU #ifdef TRINITY_API_USE_DYNAMIC_LINKING -# if COMPILER == COMPILER_MICROSOFT +# if TRINITY_COMPILER == TRINITY_COMPILER_MICROSOFT # define TC_API_EXPORT __declspec(dllexport) # define TC_API_IMPORT __declspec(dllimport) -# elif COMPILER == COMPILER_GNU +# elif TRINITY_COMPILER == TRINITY_COMPILER_GNU # define TC_API_EXPORT __attribute__((visibility("default"))) # define TC_API_IMPORT # else diff --git a/src/common/GitRevision.cpp b/src/common/GitRevision.cpp index 702cd01d84..3e578cf1ee 100644 --- a/src/common/GitRevision.cpp +++ b/src/common/GitRevision.cpp @@ -41,17 +41,17 @@ char const* GitRevision::GetFullDatabase() return _FULL_DATABASE; } -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS # ifdef _WIN64 # define TRINITY_PLATFORM_STR "Win64" # else # define TRINITY_PLATFORM_STR "Win32" # endif -#elif PLATFORM == PLATFORM_APPLE +#elif TRINITY_PLATFORM == TRINITY_PLATFORM_APPLE # define TRINITY_PLATFORM_STR "MacOSX" -#elif PLATFORM == PLATFORM_INTEL +#elif TRINITY_PLATFORM == TRINITY_PLATFORM_INTEL # define TRINITY_PLATFORM_STR "Intel" -#else // PLATFORM_UNIX +#else // TRINITY_PLATFORM_UNIX # define TRINITY_PLATFORM_STR "Unix" #endif diff --git a/src/common/Logging/AppenderConsole.cpp b/src/common/Logging/AppenderConsole.cpp index e61cfdf30f..3378c185cc 100644 --- a/src/common/Logging/AppenderConsole.cpp +++ b/src/common/Logging/AppenderConsole.cpp @@ -21,7 +21,7 @@ #include "Config.h" #include "Util.h" -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS #include #endif @@ -66,7 +66,7 @@ void AppenderConsole::InitColors(std::string const& str) void AppenderConsole::SetColor(bool stdout_stream, ColorTypes color) { -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS static WORD WinColorFG[MaxColors] = { 0, // BLACK @@ -153,7 +153,7 @@ void AppenderConsole::SetColor(bool stdout_stream, ColorTypes color) void AppenderConsole::ResetColor(bool stdout_stream) { - #if PLATFORM == PLATFORM_WINDOWS + #if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE); SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); #else diff --git a/src/common/Logging/AppenderFile.cpp b/src/common/Logging/AppenderFile.cpp index 8d9ea36bd5..6c68406667 100644 --- a/src/common/Logging/AppenderFile.cpp +++ b/src/common/Logging/AppenderFile.cpp @@ -20,7 +20,7 @@ #include "StringFormat.h" #include "Log.h" -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS # include #endif diff --git a/src/common/Logging/Log.h b/src/common/Logging/Log.h index 189971561f..fa67a8ea64 100644 --- a/src/common/Logging/Log.h +++ b/src/common/Logging/Log.h @@ -166,7 +166,7 @@ inline bool Log::ShouldLog(std::string const& type, LogLevel level) const } \ } -#if PLATFORM != PLATFORM_WINDOWS +#if TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS void check_args(const char*, ...) ATTR_PRINTF(1, 2); void check_args(std::string const&, ...); diff --git a/src/common/Metric/Metric.h b/src/common/Metric/Metric.h index f3a852c755..8e4d129251 100644 --- a/src/common/Metric/Metric.h +++ b/src/common/Metric/Metric.h @@ -116,7 +116,7 @@ public: #define sMetric Metric::instance() -#if PLATFORM != PLATFORM_WINDOWS +#if TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS #define TC_METRIC_EVENT(category, title, description) \ do { \ if (sMetric->IsEnabled()) \ diff --git a/src/common/Threading/ProcessPriority.h b/src/common/Threading/ProcessPriority.h index 65332c6dff..b4ff3f5ecf 100644 --- a/src/common/Threading/ProcessPriority.h +++ b/src/common/Threading/ProcessPriority.h @@ -28,11 +28,6 @@ void SetProcessPriority(const std::string& logChannel) { -// Suppresses Mac OS X Warning since logChannel isn't used. -#if PLATFORM_APPLE - (void)logChannel; -#endif - #if defined(_WIN32) || defined(__linux__) ///- Handle affinity for multiple processors and process priority @@ -99,6 +94,9 @@ void SetProcessPriority(const std::string& logChannel) } #endif +#else + // Suppresses unused argument warning for all other platforms + (void)logChannel; #endif } diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp index 120218f585..36910246d1 100644 --- a/src/common/Utilities/Util.cpp +++ b/src/common/Utilities/Util.cpp @@ -24,7 +24,7 @@ #include #include -#if COMPILER == COMPILER_GNU +#if TRINITY_COMPILER == TRINITY_COMPILER_GNU #include #include #include @@ -421,7 +421,7 @@ std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension) bool utf8ToConsole(const std::string& utf8str, std::string& conStr) { -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS std::wstring wstr; if (!Utf8toWStr(utf8str, wstr)) return false; @@ -438,7 +438,7 @@ bool utf8ToConsole(const std::string& utf8str, std::string& conStr) bool consoleToUtf8(const std::string& conStr, std::string& utf8str) { -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS std::wstring wstr; wstr.resize(conStr.size()); OemToCharBuffW(&conStr[0], &wstr[0], uint32(conStr.size())); @@ -477,7 +477,7 @@ void utf8printf(FILE* out, const char *str, ...) void vutf8printf(FILE* out, const char *str, va_list* ap) { -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS char temp_buf[32 * 1024]; wchar_t wtemp_buf[32 * 1024]; diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index a911275ef2..1669e0958b 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -49,7 +49,7 @@ namespace fs = boost::filesystem; # define _TRINITY_REALM_CONFIG "authserver.conf" #endif -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS #include "ServiceWin32.h" char serviceName[] = "authserver"; char serviceLongName[] = "TrinityCore auth service"; @@ -90,7 +90,7 @@ int main(int argc, char** argv) if (vm.count("help") || vm.count("version")) return 0; -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS if (configService.compare("install") == 0) return WinServiceInstall() == true ? 0 : 1; else if (configService.compare("uninstall") == 0) @@ -163,7 +163,7 @@ int main(int argc, char** argv) // Set signal handlers boost::asio::signal_set signals(*_ioService, SIGINT, SIGTERM); -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS signals.add(SIGBREAK); #endif signals.async_wait(SignalHandler); @@ -182,7 +182,7 @@ int main(int argc, char** argv) _banExpiryCheckTimer->expires_from_now(boost::posix_time::seconds(_banExpiryCheckInterval)); _banExpiryCheckTimer->async_wait(BanExpiryHandler); -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS if (m_ServiceStatus != -1) { _serviceStatusWatchTimer = new boost::asio::deadline_timer(*_ioService); @@ -271,7 +271,7 @@ void BanExpiryHandler(boost::system::error_code const& error) } } -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS void ServiceStatusWatcher(boost::system::error_code const& error) { if (!error) @@ -299,7 +299,7 @@ variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, s ("config,c", value(&configFile)->default_value(fs::absolute(_TRINITY_REALM_CONFIG)), "use as configuration file") ; -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS options_description win("Windows platform specific options"); win.add_options() ("service,s", value(&configService)->default_value(""), "Windows service options: [install | uninstall]") diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 70dc8e831c..8526561b34 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1227,7 +1227,7 @@ void World::LoadConfigSettings(bool reload) if (dataPath.empty() || (dataPath.at(dataPath.length()-1) != '/' && dataPath.at(dataPath.length()-1) != '\\')) dataPath.push_back('/'); -#if PLATFORM == PLATFORM_UNIX || PLATFORM == PLATFORM_APPLE +#if TRINITY_PLATFORM == TRINITY_PLATFORM_UNIX || TRINITY_PLATFORM == TRINITY_PLATFORM_APPLE if (dataPath[0] == '~') { const char* home = getenv("HOME"); diff --git a/src/server/worldserver/CommandLine/CliRunnable.cpp b/src/server/worldserver/CommandLine/CliRunnable.cpp index 633cde6a9a..d5e03edbd0 100644 --- a/src/server/worldserver/CommandLine/CliRunnable.cpp +++ b/src/server/worldserver/CommandLine/CliRunnable.cpp @@ -29,7 +29,7 @@ #include "Log.h" #include "Util.h" -#if PLATFORM != PLATFORM_WINDOWS +#if TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS #include #include #include "Chat.h" @@ -86,7 +86,7 @@ int cli_hook_func() void utf8print(void* /*arg*/, const char* str) { -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS wchar_t wtemp_buf[6000]; size_t wtemp_len = 6000-1; if (!Utf8toWStr(str, strlen(str), wtemp_buf, wtemp_len)) @@ -129,7 +129,7 @@ void CliThread() { ///- Display the list of available CLI functions then beep //TC_LOG_INFO("server.worldserver", ""); -#if PLATFORM != PLATFORM_WINDOWS +#if TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS rl_attempted_completion_function = cli_completion; rl_event_hook = cli_hook_func; #endif @@ -148,7 +148,7 @@ void CliThread() char *command_str ; // = fgets(commandbuf, sizeof(commandbuf), stdin); -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS char commandbuf[256]; command_str = fgets(commandbuf, sizeof(commandbuf), stdin); #else @@ -167,7 +167,7 @@ void CliThread() if (!*command_str) { -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS printf("TC>"); #else free(command_str); @@ -178,7 +178,7 @@ void CliThread() std::string command; if (!consoleToUtf8(command_str, command)) // convert from console encoding to utf8 { -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS printf("TC>"); #else free(command_str); @@ -188,7 +188,7 @@ void CliThread() fflush(stdout); sWorld->QueueCliCommand(new CliCommandHolder(NULL, command.c_str(), &utf8print, &commandFinished)); -#if PLATFORM != PLATFORM_WINDOWS +#if TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS add_history(command.c_str()); free(command_str); #endif diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 0dbe53c092..ce1ca7b131 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -168,7 +168,7 @@ extern int main(int argc, char** argv) // Set signal handlers (this must be done before starting io_service threads, because otherwise they would unblock and exit) boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM); -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS signals.add(SIGBREAK); #endif signals.async_wait(SignalHandler); From 60ec01476e96b11b037640cc128af1cc95c2c6db Mon Sep 17 00:00:00 2001 From: Aokromes Date: Fri, 26 May 2017 16:24:31 +0200 Subject: [PATCH 36/44] build fix --- src/server/bnetserver/Main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp index 9c978588e5..d7cc5b13ef 100644 --- a/src/server/bnetserver/Main.cpp +++ b/src/server/bnetserver/Main.cpp @@ -53,7 +53,7 @@ namespace fs = boost::filesystem; # define _TRINITY_BNET_CONFIG "bnetserver.conf" #endif -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS #include "ServiceWin32.h" char serviceName[] = "bnetserver"; char serviceLongName[] = "TrinityCore bnet service"; @@ -147,7 +147,7 @@ int main(int argc, char** argv) // Set signal handlers boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM); -#if PLATFORM == PLATFORM_WINDOWS +#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS signals.add(SIGBREAK); #endif signals.async_wait(SignalHandler); From 975e487cf9b9225a8ace44fad6a1149728ecd945 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Fri, 26 May 2017 18:32:37 +0200 Subject: [PATCH 37/44] Core/PlayerDump: general revamping --- src/server/game/Tools/PlayerDump.cpp | 1186 ++++++++++++++++---------- src/server/game/Tools/PlayerDump.h | 21 +- src/server/game/World/World.cpp | 4 + 3 files changed, 747 insertions(+), 464 deletions(-) diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index e4b1af8935..9631e450f0 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -25,83 +25,370 @@ #include "AccountMgr.h" #include "World.h" -#define DUMP_TABLE_COUNT 34 +// static data +enum GuidType : uint8 +{ + // 32 bit long guids + GUID_TYPE_ACCOUNT, + GUID_TYPE_CHAR, + GUID_TYPE_PET, + GUID_TYPE_MAIL, + GUID_TYPE_ITEM, + + // 64 bit long guids + GUID_TYPE_EQUIPMENT_SET, + + // special types + GUID_TYPE_NULL // set to null +}; + +// for RAII +struct FileCloser +{ + void operator()(FILE* f) const + { + if (f) + fclose(f); + } +}; +typedef std::unique_ptr FileHandle; + +inline FileHandle GetFileHandle(char const* path, char const* mode) +{ + return FileHandle(fopen(path, mode), FileCloser()); +} + +struct BaseTable +{ + char const* TableName; + char const* PrimaryKey; + char const* PlayerGuid; + + GuidType StoredType; +}; + +BaseTable const BaseTables[] = +{ + { "character_pet", "id", "owner", GUID_TYPE_PET }, + { "mail", "id", "receiver", GUID_TYPE_MAIL }, + { "item_instance", "guid", "owner_guid", GUID_TYPE_ITEM }, + + { "character_equipmentsets", "setguid", "guid", GUID_TYPE_EQUIPMENT_SET } +}; + struct DumpTable { - char const* name; - DumpTableType type; + char const* Name; + DumpTableType Type; }; -DumpTable const dumpTables[DUMP_TABLE_COUNT] = +DumpTable const DumpTables[] = { - { "characters", DTT_CHARACTER }, - { "character_account_data", DTT_CHAR_TABLE }, - { "character_achievement", DTT_CHAR_TABLE }, - { "character_achievement_progress", DTT_CHAR_TABLE }, - { "character_action", DTT_CHAR_TABLE }, - { "character_aura", DTT_CHAR_TABLE }, - { "character_currency", DTT_CHAR_TABLE }, - { "character_cuf_profiles", DTT_CHAR_TABLE }, - { "character_declinedname", DTT_CHAR_TABLE }, - { "character_equipmentsets", DTT_EQSET_TABLE}, - { "character_fishingsteps", DTT_CHAR_TABLE }, - { "character_glyphs", DTT_CHAR_TABLE }, - { "character_homebind", DTT_CHAR_TABLE }, - { "character_inventory", DTT_INVENTORY }, - { "character_pet", DTT_PET }, - { "character_pet_declinedname", DTT_PET }, - { "character_queststatus", DTT_CHAR_TABLE }, - { "character_queststatus_daily", DTT_CHAR_TABLE }, - { "character_queststatus_weekly", DTT_CHAR_TABLE }, - { "character_queststatus_monthly", DTT_CHAR_TABLE }, - { "character_queststatus_seasonal", DTT_CHAR_TABLE }, - { "character_queststatus_rewarded", DTT_CHAR_TABLE }, - { "character_reputation", DTT_CHAR_TABLE }, - { "character_skills", DTT_CHAR_TABLE }, - { "character_spell", DTT_CHAR_TABLE }, - { "character_spell_cooldown", DTT_CHAR_TABLE }, - { "character_talent", DTT_CHAR_TABLE }, - { "mail", DTT_MAIL }, - { "mail_items", DTT_MAIL_ITEM }, // must be after mail - { "pet_aura", DTT_PET_TABLE }, // must be after character_pet - { "pet_spell", DTT_PET_TABLE }, // must be after character_pet - { "pet_spell_cooldown", DTT_PET_TABLE }, // must be after character_pet - { "item_instance", DTT_ITEM }, // must be after character_inventory and mail_items - { "character_gifts", DTT_ITEM_GIFT }, // must be after item_instance + { "characters", DTT_CHARACTER }, + { "character_account_data", DTT_CHAR_TABLE }, + { "character_achievement", DTT_CHAR_TABLE }, + { "character_achievement_progress", DTT_CHAR_TABLE }, + { "character_action", DTT_CHAR_TABLE }, + { "character_aura", DTT_CHAR_TABLE }, + { "character_currency", DTT_CHAR_TABLE }, + { "character_cuf_profiles", DTT_CHAR_TABLE }, + { "character_declinedname", DTT_CHAR_TABLE }, + { "character_equipmentsets", DTT_EQSET_TABLE}, + { "character_fishingsteps", DTT_CHAR_TABLE }, + { "character_glyphs", DTT_CHAR_TABLE }, + { "character_homebind", DTT_CHAR_TABLE }, + { "character_inventory", DTT_INVENTORY }, + { "character_pet", DTT_PET }, + { "character_pet_declinedname", DTT_PET }, + { "character_queststatus", DTT_CHAR_TABLE }, + { "character_queststatus_daily", DTT_CHAR_TABLE }, + { "character_queststatus_weekly", DTT_CHAR_TABLE }, + { "character_queststatus_monthly", DTT_CHAR_TABLE }, + { "character_queststatus_seasonal", DTT_CHAR_TABLE }, + { "character_queststatus_rewarded", DTT_CHAR_TABLE }, + { "character_reputation", DTT_CHAR_TABLE }, + { "character_skills", DTT_CHAR_TABLE }, + { "character_spell", DTT_CHAR_TABLE }, + { "character_spell_cooldown", DTT_CHAR_TABLE }, + { "character_talent", DTT_CHAR_TABLE }, + { "mail", DTT_MAIL }, + { "mail_items", DTT_MAIL_ITEM }, // must be after mail + { "pet_aura", DTT_PET_TABLE }, // must be after character_pet + { "pet_spell", DTT_PET_TABLE }, // must be after character_pet + { "pet_spell_cooldown", DTT_PET_TABLE }, // must be after character_pet + { "item_instance", DTT_ITEM }, // must be after character_inventory and mail_items + { "character_gifts", DTT_ITEM_GIFT }, // must be after item_instance }; +uint32 const DUMP_TABLE_COUNT = std::extent::value; + +// helper class to dump sql queries to a printable string +class StringTransaction +{ + public: + StringTransaction() : _buf() { } + + void Append(char const* sql) + { + std::ostringstream oss; + oss << sql << '\n'; + _buf += oss.str(); + } + + char const* GetBuffer() const + { + return _buf.c_str(); + } + + private: + std::string _buf; +}; + +// dynamic data, loaded at startup +struct TableField +{ + std::string FieldName; + + GuidType FieldGuidType = GUID_TYPE_ACCOUNT; + bool IsDependentField = false; +}; + +struct TableStruct +{ + std::string TableName; + std::string WhereFieldName; + std::vector TableFields; + + // for lookup + std::unordered_map FieldIndices; +}; + +std::vector CharacterTables; + +inline bool StringsEqualCaseInsensitive(std::string const& left, std::string const& right) +{ + std::string upperLeftString = left; + ASSERT(Utf8ToUpperOnlyLatin(upperLeftString)); + + std::string upperRightString = right; + ASSERT(Utf8ToUpperOnlyLatin(upperRightString)); + + return upperLeftString == upperRightString; +} + +inline auto FindColumnByName(TableStruct& tableStruct, std::string const& columnName) -> decltype(tableStruct.TableFields.begin()) +{ + return std::find_if(tableStruct.TableFields.begin(), tableStruct.TableFields.end(), [columnName](TableField const& tableField) -> bool + { + return StringsEqualCaseInsensitive(tableField.FieldName, columnName); + }); +} + +inline int32 GetColumnIndexByName(TableStruct const& tableStruct, std::string const& columnName) +{ + auto itr = tableStruct.FieldIndices.find(columnName); + if (itr == tableStruct.FieldIndices.end()) + return -1; + + return itr->second; +} + +inline void MarkDependentColumn(TableStruct& tableStruct, std::string const& columnName, GuidType dependentType) +{ + auto itr = FindColumnByName(tableStruct, columnName); + if (itr == tableStruct.TableFields.end()) + { + TC_LOG_FATAL("server.loading", "Column `%s` declared in table `%s` marked as dependent but doesn't exist, PlayerDump will not work properly, please update table definitions", + columnName.c_str(), tableStruct.TableName.c_str()); + ABORT(); + return; + } + + if (itr->IsDependentField) + { + TC_LOG_FATAL("server.loading", "Attempt to mark column `%s` in table `%s` as dependent column but already marked! please check your code.", + columnName.c_str(), tableStruct.TableName.c_str()); + ABORT(); + return; + } + + itr->IsDependentField = true; + itr->FieldGuidType = dependentType; +} + +inline void MarkWhereField(TableStruct& tableStruct, std::string const& whereField) +{ + ASSERT(tableStruct.WhereFieldName.empty()); + + auto whereFieldItr = FindColumnByName(tableStruct, whereField); + if (whereFieldItr == tableStruct.TableFields.end()) + { + TC_LOG_FATAL("server.loading", "Column name `%s` set as 'WHERE' column for table `%s` doesn't exist. PlayerDump won't work properly", + whereField.c_str(), tableStruct.TableName.c_str()); + ABORT(); + return; + } + + tableStruct.WhereFieldName = whereField; +} + +inline void AssertBaseTable(BaseTable const& baseTable) +{ + auto itr = std::find_if(CharacterTables.begin(), CharacterTables.end(), [baseTable](TableStruct const& tableStruct) -> bool + { + return StringsEqualCaseInsensitive(tableStruct.TableName, baseTable.TableName); + }); + + ASSERT(itr != CharacterTables.end()); + + auto columnItr = FindColumnByName(*itr, baseTable.PrimaryKey); + ASSERT(columnItr != itr->TableFields.end()); + + columnItr = FindColumnByName(*itr, baseTable.PlayerGuid); + ASSERT(columnItr != itr->TableFields.end()); +} + +void PlayerDump::InitializeTables() +{ + uint32 oldMSTime = getMSTime(); + + for (DumpTable const& dumpTable : DumpTables) + { + TableStruct t; + t.TableName = dumpTable.Name; + + QueryResult result = CharacterDatabase.PQuery("DESC %s", dumpTable.Name); + // prepared statement is correct (checked at startup) so table must exist + ASSERT(result); + + int32 i = 0; + do + { + std::string columnName = (*result)[0].GetString(); + t.FieldIndices.emplace(columnName, i++); + + TableField f; + f.FieldName = columnName; + + ASSERT(Utf8ToUpperOnlyLatin(columnName)); + + t.TableFields.emplace_back(std::move(f)); + } while (result->NextRow()); + + switch (dumpTable.Type) + { + case DTT_CHARACTER: + MarkWhereField(t, "guid"); + + MarkDependentColumn(t, "guid", GUID_TYPE_CHAR); + MarkDependentColumn(t, "account", GUID_TYPE_ACCOUNT); + + MarkDependentColumn(t, "deleteInfos_Account", GUID_TYPE_NULL); + MarkDependentColumn(t, "deleteInfos_Name", GUID_TYPE_NULL); + MarkDependentColumn(t, "deleteDate", GUID_TYPE_NULL); + break; + case DTT_CHAR_TABLE: + MarkWhereField(t, "guid"); + + MarkDependentColumn(t, "guid", GUID_TYPE_CHAR); + break; + case DTT_EQSET_TABLE: + MarkWhereField(t, "guid"); + + MarkDependentColumn(t, "guid", GUID_TYPE_CHAR); + MarkDependentColumn(t, "setguid", GUID_TYPE_EQUIPMENT_SET); + + // item0 - item18 + for (uint32 j = 0; j < EQUIPMENT_SLOT_END; ++j) + { + std::string itColumn = Trinity::StringFormat("item%u", j); + MarkDependentColumn(t, itColumn, GUID_TYPE_ITEM); + } + break; + case DTT_INVENTORY: + MarkWhereField(t, "guid"); + + MarkDependentColumn(t, "guid", GUID_TYPE_CHAR); + MarkDependentColumn(t, "bag", GUID_TYPE_ITEM); + MarkDependentColumn(t, "item", GUID_TYPE_ITEM); + break; + case DTT_MAIL: + MarkWhereField(t, "receiver"); + + MarkDependentColumn(t, "id", GUID_TYPE_MAIL); + MarkDependentColumn(t, "receiver", GUID_TYPE_CHAR); + break; + case DTT_MAIL_ITEM: + MarkWhereField(t, "mail_id"); + + MarkDependentColumn(t, "mail_id", GUID_TYPE_MAIL); + MarkDependentColumn(t, "item_guid", GUID_TYPE_ITEM); + MarkDependentColumn(t, "receiver", GUID_TYPE_CHAR); + break; + case DTT_ITEM: + MarkWhereField(t, "guid"); + + MarkDependentColumn(t, "guid", GUID_TYPE_ITEM); + MarkDependentColumn(t, "owner_guid", GUID_TYPE_CHAR); + break; + case DTT_ITEM_GIFT: + MarkWhereField(t, "item_guid"); + + MarkDependentColumn(t, "guid", GUID_TYPE_CHAR); + MarkDependentColumn(t, "item_guid", GUID_TYPE_ITEM); + break; + case DTT_PET: + MarkWhereField(t, "owner"); + + MarkDependentColumn(t, "id", GUID_TYPE_PET); + MarkDependentColumn(t, "owner", GUID_TYPE_CHAR); + break; + case DTT_PET_TABLE: + MarkWhereField(t, "guid"); + + MarkDependentColumn(t, "guid", GUID_TYPE_PET); + break; + default: + TC_LOG_FATAL("server.loading", "Wrong dump table type %u, probably added a new table type without updating code", uint32(dumpTable.Type)); + ABORT(); + return; + } + + CharacterTables.emplace_back(std::move(t)); + } + + // perform some sanity checks + for (TableStruct const& tableStruct : CharacterTables) + { + if (tableStruct.WhereFieldName.empty()) + { + TC_LOG_FATAL("server.loading", "Table `%s` defined in player dump doesn't have a WHERE query field", tableStruct.TableName.c_str()); + ABORT(); + } + } + + for (BaseTable const& baseTable : BaseTables) + AssertBaseTable(baseTable); + + ASSERT(CharacterTables.size() == DUMP_TABLE_COUNT); + + TC_LOG_INFO("server.loading", ">> Initialized tables for PlayerDump in %u ms.", GetMSTimeDiffToNow(oldMSTime)); +} + // Low level functions -static bool FindTokNth(std::string const& str, uint32 n, std::string::size_type& s, std::string::size_type& e) +inline bool FindColumn(TableStruct const& ts, std::string const& str, std::string const& column, std::string::size_type& s, std::string::size_type& e) { - s = e = 0; - - uint32 i = 1; - for (; s < str.size() && i < n; ++s) - if (str[s] == ' ') - ++i; - - if (i < n) + int32 columnIndex = GetColumnIndexByName(ts, column); + if (columnIndex == -1) return false; - e = str.find(' ', s); + // array indices start at 0, compensate + ++columnIndex; - return e != std::string::npos; -} - -std::string GetTokNth(std::string const& str, uint32 n) -{ - std::string::size_type s = 0, e = 0; - if (!FindTokNth(str, n, s, e)) - return ""; - - return str.substr(s, e - s); -} - -bool FindNth(std::string const& str, uint32 n, std::string::size_type& s, std::string::size_type& e) -{ - s = str.find("VALUES ('") + 9; + s = str.find("VALUES ('"); if (s == std::string::npos) return false; + s += 9; do { @@ -110,10 +397,11 @@ bool FindNth(std::string const& str, uint32 n, std::string::size_type& s, std::s return false; } while (str[e - 1] == '\\'); - for (uint32 i = 1; i < n; ++i) + for (int32 i = 1; i < columnIndex; ++i) { do { + // length of "', '" s = e + 4; e = str.find('\'', s); if (e == std::string::npos) @@ -123,8 +411,9 @@ bool FindNth(std::string const& str, uint32 n, std::string::size_type& s, std::s return true; } -std::string GetTableName(std::string const& str) +inline std::string GetTableName(std::string const& str) { + // length of "INSERT INTO `" static std::string::size_type const s = 13; std::string::size_type e = str.find(_TABLE_SIM_, s); if (e == std::string::npos) @@ -133,247 +422,310 @@ std::string GetTableName(std::string const& str) return str.substr(s, e - s); } -bool ChangeNth(std::string& str, uint32 n, char const* with, bool insert = false, bool allowZero = false) +inline bool ValidateFields(TableStruct const& ts, std::string const& str, size_t lineNumber) { - std::string::size_type s, e; - if (!FindNth(str, n, s, e)) + std::string::size_type s = str.find("` VALUES ("); + if (s != std::string::npos) // old dump format (no column names) + return true; + + // new format has insert with columns, need validation else we risk executing an invalid query + s = str.find("` (`"); + if (s == std::string::npos) + { + TC_LOG_ERROR("misc", "LoadPlayerDump: (line " UI64FMTD ") dump format not recognized.", lineNumber); return false; + } + s += 4; - if (allowZero && str.substr(s, e - s) == "0") - return true; // not an error - - if (!insert) - str.replace(s, e - s, with); - else - str.insert(s, with); - - return true; -} - -std::string GetNth(std::string& str, uint32 n) -{ - std::string::size_type s, e; - if (!FindNth(str, n, s, e)) - return ""; - - return str.substr(s, e-s); -} - -bool ChangeTokNth(std::string& str, uint32 n, char const* with, bool insert = false, bool allowZero = false) -{ - std::string::size_type s = 0, e = 0; - if (!FindTokNth(str, n, s, e)) + std::string::size_type valPos = str.find("VALUES ('"); + std::string::size_type e = str.find(_TABLE_SIM_, s); + if (e == std::string::npos || valPos == std::string::npos) + { + TC_LOG_ERROR("misc", "LoadPlayerDump: (line " UI64FMTD ") unexpected end of line", lineNumber); return false; - - if (allowZero && str.substr(s, e - s) == "0") - return true; // not an error - - if (!insert) - str.replace(s, e-s, with); - else - str.insert(s, with); - - return true; -} - -ObjectGuid::LowType RegisterNewGuid(ObjectGuid::LowType oldGuid, PlayerDump::DumpGuidMap& guidMap, ObjectGuid::LowType guidOffset) -{ - PlayerDumpWriter::DumpGuidMap::const_iterator itr = guidMap.find(oldGuid); - if (itr != guidMap.end()) - return itr->second; - - ObjectGuid::LowType newguid = guidOffset + guidMap.size(); - guidMap[oldGuid] = newguid; - return newguid; -} - -bool ChangeGuid(std::string& str, uint32 n, PlayerDump::DumpGuidMap& guidMap, ObjectGuid::LowType guidOffset, bool allowZero = false) -{ - ObjectGuid::LowType oldGuid = strtoull(GetNth(str, n).c_str(), nullptr, 10); - if (allowZero && !oldGuid) - return true; // not an error - - char chritem[20]; - ObjectGuid::LowType newGuid = RegisterNewGuid(oldGuid, guidMap, guidOffset); - snprintf(chritem, 20, "%u", newGuid); - - return ChangeNth(str, n, chritem, false, allowZero); -} - -std::string CreateDumpString(char const* tableName, QueryResult result) -{ - if (!tableName || !result) return ""; - std::ostringstream ss; - ss << "INSERT INTO " << _TABLE_SIM_ << tableName << _TABLE_SIM_ << " VALUES ("; - Field* fields = result->Fetch(); - for (uint32 i = 0; i < result->GetFieldCount(); ++i) - { - if (i == 0) ss << '\''; - else ss << ", '"; - - std::string s = fields[i].GetString(); - CharacterDatabase.EscapeString(s); - ss << s; - - ss << '\''; } - ss << ");"; - return ss.str(); -} - -std::string PlayerDumpWriter::GenerateWhereStr(char const* field, ObjectGuid::LowType guid) -{ - std::ostringstream wherestr; - wherestr << field << " = '" << guid << '\''; - return wherestr.str(); -} - -std::string PlayerDumpWriter::GenerateWhereStr(char const* field, DumpGuidSet const& guids, DumpGuidSet::const_iterator& itr) -{ - std::ostringstream wherestr; - wherestr << field << " IN ('"; - for (; itr != guids.end();) - { - wherestr << *itr; - ++itr; - - if (wherestr.str().size() > MAX_QUERY_LEN - 50) // near to max query - break; - - if (itr != guids.end()) - wherestr << "', '"; - } - wherestr << "')"; - return wherestr.str(); -} - -void StoreGUID(QueryResult result, uint32 field, PlayerDump::DumpGuidSet &guids) -{ - Field* fields = result->Fetch(); - ObjectGuid::LowType guid = fields[field].GetUInt32(); - if (guid) - guids.insert(guid); -} - -void StoreGUID(QueryResult result, uint32 data, uint32 field, PlayerDump::DumpGuidSet& guids) -{ - Field* fields = result->Fetch(); - std::string dataStr = fields[data].GetString(); - ObjectGuid::LowType guid = strtoull(GetTokNth(dataStr, field).c_str(), nullptr, 10); - if (guid) - guids.insert(guid); -} - -// Writing - High-level functions -bool PlayerDumpWriter::DumpTable(std::string& dump, ObjectGuid::LowType guid, char const* tableFrom, char const* tableTo, DumpTableType type) -{ - DumpGuidSet const* guids = nullptr; - char const* fieldname = nullptr; - - switch (type) - { - case DTT_ITEM: fieldname = "guid"; guids = &items; break; - case DTT_ITEM_GIFT: fieldname = "item_guid"; guids = &items; break; - case DTT_PET: fieldname = "owner"; break; - case DTT_PET_TABLE: fieldname = "guid"; guids = &pets; break; - case DTT_MAIL: fieldname = "receiver"; break; - case DTT_MAIL_ITEM: fieldname = "mail_id"; guids = &mails; break; - default: fieldname = "guid"; break; - } - - // for guid set stop if set is empty - if (guids && guids->empty()) - return true; // nothing to do - - // setup for guids case start position - DumpGuidSet::const_iterator guidsItr; - if (guids) - guidsItr = guids->begin(); do { - std::string wherestr; - - if (guids) // set case, get next guids string - wherestr = GenerateWhereStr(fieldname, *guids, guidsItr); - else // not set case, get single guid string - wherestr = GenerateWhereStr(fieldname, guid); - - QueryResult result = CharacterDatabase.PQuery("SELECT * FROM %s WHERE %s", tableFrom, wherestr.c_str()); - if (!result) - return true; - - do + std::string column = str.substr(s, e - s); + int32 columnIndex = GetColumnIndexByName(ts, column); + if (columnIndex == -1) { - // collect guids - switch (type) - { - case DTT_INVENTORY: - StoreGUID(result, 3, items); // item guid collection (character_inventory.item) - break; - case DTT_PET: - StoreGUID(result, 0, pets); // pet petnumber collection (character_pet.id) - break; - case DTT_MAIL: - StoreGUID(result, 0, mails); // mail id collection (mail.id) - break; - case DTT_MAIL_ITEM: - StoreGUID(result, 1, items); // item guid collection (mail_items.item_guid) - break; - case DTT_CHARACTER: - { - if (result->GetFieldCount() <= 69) // avoid crashes on next check - { - TC_LOG_FATAL("misc", "PlayerDumpWriter::DumpTable - Trying to access non-existing or wrong positioned field (`deleteInfos_Account`) in `characters` table."); - return false; - } - - if (result->Fetch()[69].GetUInt32()) // characters.deleteInfos_Account - if filled error - return false; - break; - } - default: - break; - } - - dump += CreateDumpString(tableTo, result); - dump += "\n"; + TC_LOG_ERROR("misc", "LoadPlayerDump: (line " UI64FMTD ") unknown column name `%s` for table `%s`, aborting due to incompatible DB structure.", lineNumber, column.c_str(), ts.TableName.c_str()); + return false; } - while (result->NextRow()); - } - while (guids && guidsItr != guids->end()); // not set case iterate single time, set case iterate for all guids + + // length of "`, `" + s = e + 4; + e = str.find(_TABLE_SIM_, s); + } while (e < valPos); + return true; } -bool PlayerDumpWriter::GetDump(ObjectGuid::LowType guid, std::string &dump) +inline bool ChangeColumn(TableStruct const& ts, std::string& str, std::string const& column, std::string const& with, bool allowZero = false) +{ + std::string::size_type s, e; + if (!FindColumn(ts, str, column, s, e)) + return false; + + if (allowZero && str.substr(s, e - s) == "0") + return true; // not an error + + str.replace(s, e - s, with); + return true; +} + +inline std::string GetColumn(TableStruct const& ts, std::string& str, std::string const& column) +{ + std::string::size_type s, e; + if (!FindColumn(ts, str, column, s, e)) + return ""; + + return str.substr(s, e - s); +} + +template class MapType, class... Rest> +inline T RegisterNewGuid(T oldGuid, MapType& guidMap, T guidOffset) +{ + auto itr = guidMap.find(oldGuid); + if (itr != guidMap.end()) + return itr->second; + + T newguid = guidOffset + T(guidMap.size()); + guidMap.emplace(oldGuid, newguid); + return newguid; +} + +template class MapType, class... Rest> +inline bool ChangeGuid(TableStruct const& ts, std::string& str, std::string const& column, MapType& guidMap, T guidOffset, bool allowZero = false) +{ + T oldGuid(atoull(GetColumn(ts, str, column).c_str())); + if (allowZero && !oldGuid) + return true; // not an error + + std::string chritem; + T newGuid = RegisterNewGuid(oldGuid, guidMap, guidOffset); + chritem = std::to_string(newGuid); + + return ChangeColumn(ts, str, column, chritem, allowZero); +} + +inline void AppendTableDump(StringTransaction& trans, TableStruct const& tableStruct, QueryResult result) +{ + if (!result) + return; + + do + { + std::ostringstream ss; + ss << "INSERT INTO " << _TABLE_SIM_ << tableStruct.TableName << _TABLE_SIM_ << " ("; + for (auto itr = tableStruct.TableFields.begin(); itr != tableStruct.TableFields.end();) + { + ss << _TABLE_SIM_ << itr->FieldName << _TABLE_SIM_; + ++itr; + + if (itr != tableStruct.TableFields.end()) + ss << ", "; + } + ss << ") VALUES ("; + + uint32 const fieldSize = uint32(tableStruct.TableFields.size()); + Field* fields = result->Fetch(); + + for (uint32 i = 0; i < fieldSize;) + { + char const* cString = fields[i].GetCString(); + ++i; + + // null pointer -> we have null + if (!cString) + ss << "'NULL'"; + else + { + std::string s(cString); + CharacterDatabase.EscapeString(s); + ss << '\'' << s << '\''; + } + + if (i != fieldSize) + ss << ", "; + } + ss << ");"; + + trans.Append(ss.str().c_str()); + } while (result->NextRow()); +} + +inline std::string GenerateWhereStr(std::string const& field, ObjectGuid::LowType guid) +{ + std::ostringstream whereStr; + whereStr << field << " = '" << guid << '\''; + return whereStr.str(); +} + +template class SetType, class... Rest> +inline std::string GenerateWhereStr(std::string const& field, SetType const& guidSet) +{ + std::ostringstream whereStr; + whereStr << field << " IN ('"; + for (auto itr = guidSet.begin(); itr != guidSet.end();) + { + whereStr << *itr; + ++itr; + + if (whereStr.str().size() > MAX_QUERY_LEN - 50) // near to max query + break; + + if (itr != guidSet.end()) + whereStr << "', '"; + } + whereStr << "')"; + return whereStr.str();; +} + +// Writing - High-level functions +void PlayerDumpWriter::PopulateGuids(ObjectGuid::LowType guid) +{ + for (BaseTable const& baseTable : BaseTables) + { + switch (baseTable.StoredType) + { + case GUID_TYPE_ITEM: + case GUID_TYPE_MAIL: + case GUID_TYPE_PET: + case GUID_TYPE_EQUIPMENT_SET: + break; + default: + return; + } + + std::string whereStr = GenerateWhereStr(baseTable.PlayerGuid, guid); + QueryResult result = CharacterDatabase.PQuery("SELECT %s FROM %s WHERE %s", baseTable.PrimaryKey, baseTable.TableName, whereStr.c_str()); + + if (!result) + continue; + + do + { + switch (baseTable.StoredType) + { + case GUID_TYPE_ITEM: + if (ObjectGuid::LowType guid = (*result)[0].GetUInt32()) + _items.insert(guid); + break; + case GUID_TYPE_MAIL: + if (ObjectGuid::LowType guid = (*result)[0].GetUInt32()) + _mails.insert(guid); + break; + case GUID_TYPE_PET: + if (ObjectGuid::LowType guid = (*result)[0].GetUInt32()) + _pets.insert(guid); + break; + case GUID_TYPE_EQUIPMENT_SET: + if (uint64 eqSetId = (*result)[0].GetUInt64()) + _itemSets.insert(eqSetId); + break; + default: + break; + } + } while (result->NextRow()); + } +} +bool PlayerDumpWriter::AppendTable(StringTransaction& trans, ObjectGuid::LowType guid, TableStruct const& tableStruct, DumpTable const& dumpTable) +{ + std::string whereStr; + switch (dumpTable.Type) + { + case DTT_ITEM: + case DTT_ITEM_GIFT: + if (_items.empty()) + return true; + + whereStr = GenerateWhereStr(tableStruct.WhereFieldName, _items); + break; + case DTT_PET_TABLE: + if (_pets.empty()) + return true; + + whereStr = GenerateWhereStr(tableStruct.WhereFieldName, _pets); + break; + case DTT_MAIL_ITEM: + if (_mails.empty()) + return true; + + whereStr = GenerateWhereStr(tableStruct.WhereFieldName, _mails); + break; + case DTT_EQSET_TABLE: + if (_itemSets.empty()) + return true; + + whereStr = GenerateWhereStr(tableStruct.WhereFieldName, _itemSets); + break; + default: + // not set case, get single guid string + whereStr = GenerateWhereStr(tableStruct.WhereFieldName, guid); + break; + } + + QueryResult result = CharacterDatabase.PQuery("SELECT * FROM %s WHERE %s", dumpTable.Name, whereStr.c_str()); + switch (dumpTable.Type) + { + case DTT_CHARACTER: + if (result) + { + // characters.deleteInfos_Account - if filled error + int32 index = GetColumnIndexByName(tableStruct, "deleteInfos_Account"); + ASSERT(index != -1); // checked at startup + + if ((*result)[index].GetUInt32()) + return false; + } + break; + default: + break; + + } + + AppendTableDump(trans, tableStruct, result); + return true; +} + +bool PlayerDumpWriter::GetDump(ObjectGuid::LowType guid, std::string& dump) { dump = "IMPORTANT NOTE: THIS DUMPFILE IS MADE FOR USE WITH THE 'PDUMP' COMMAND ONLY - EITHER THROUGH INGAME CHAT OR ON CONSOLE!\n"; dump += "IMPORTANT NOTE: DO NOT apply it directly - it will irreversibly DAMAGE and CORRUPT your database! You have been warned!\n\n"; - for (uint8 i = 0; i < DUMP_TABLE_COUNT; ++i) - if (!DumpTable(dump, guid, dumpTables[i].name, dumpTables[i].name, dumpTables[i].type)) + StringTransaction trans; + + // collect guids + PopulateGuids(guid); + for (uint32 i = 0; i < DUMP_TABLE_COUNT; ++i) + if (!AppendTable(trans, guid, CharacterTables[i], DumpTables[i])) return false; + dump += trans.GetBuffer(); + /// @todo Add instance/group.. /// @todo Add a dump level option to skip some non-important tables return true; } -DumpReturn PlayerDumpWriter::WriteDump(const std::string& file, ObjectGuid::LowType guid) +DumpReturn PlayerDumpWriter::WriteDump(std::string const& file, ObjectGuid::LowType guid) { if (sWorld->getBoolConfig(CONFIG_PDUMP_NO_PATHS)) if (strstr(file.c_str(), "\\") || strstr(file.c_str(), "/")) return DUMP_FILE_OPEN_ERROR; if (sWorld->getBoolConfig(CONFIG_PDUMP_NO_OVERWRITE)) - if (FILE* f = fopen(file.c_str(), "r")) - { - fclose(f); + { + // check if file exists already + if (GetFileHandle(file.c_str(), "r")) return DUMP_FILE_OPEN_ERROR; - } + } - FILE* fout = fopen(file.c_str(), "w"); + FileHandle fout = GetFileHandle(file.c_str(), "w"); if (!fout) return DUMP_FILE_OPEN_ERROR; @@ -382,22 +734,19 @@ DumpReturn PlayerDumpWriter::WriteDump(const std::string& file, ObjectGuid::LowT if (!GetDump(guid, dump)) ret = DUMP_CHARACTER_DELETED; - fprintf(fout, "%s\n", dump.c_str()); - fclose(fout); + fprintf(fout.get(), "%s", dump.c_str()); return ret; } // Reading - High-level functions -#define ROLLBACK(DR) {fclose(fin); return (DR);} - -void fixNULLfields(std::string& line) +inline void FixNULLfields(std::string& line) { - static std::string const nullString("'NULL'"); - size_t pos = line.find(nullString); + static std::string const NullString("'NULL'"); + size_t pos = line.find(NullString); while (pos != std::string::npos) { - line.replace(pos, nullString.length(), "NULL"); - pos = line.find(nullString); + line.replace(pos, NullString.length(), "NULL"); + pos = line.find(NullString); } } @@ -407,11 +756,11 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s if (charcount >= 10) return DUMP_TOO_MANY_CHARS; - FILE* fin = fopen(file.c_str(), "r"); + FileHandle fin = GetFileHandle(file.c_str(), "r"); if (!fin) return DUMP_FILE_OPEN_ERROR; - char newguid[20], chraccount[20]; + std::string newguid, chraccount; // make sure the same guid doesn't already exist and is safe to use bool incHighest = true; @@ -419,9 +768,7 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_GUID); stmt->setUInt32(0, guid); - PreparedQueryResult result = CharacterDatabase.Query(stmt); - - if (result) + if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) guid = sObjectMgr->GetGenerator().GetNextAfterMaxUsed(); // use first free if exists else incHighest = false; @@ -429,7 +776,6 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s else guid = sObjectMgr->GetGenerator().GetNextAfterMaxUsed(); - // normalize the name if specified and check if it exists if (!normalizePlayerName(name)) name.clear(); @@ -438,94 +784,135 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME); stmt->setString(0, name); - PreparedQueryResult result = CharacterDatabase.Query(stmt); - - if (result) + if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) name.clear(); // use the one from the dump } else name.clear(); // name encoded or empty + newguid = std::to_string(guid); + chraccount = std::to_string(account); - snprintf(newguid, 20, "%u", guid); - snprintf(chraccount, 20, "%u", account); + std::map items; + ObjectGuid::LowType itemLowGuidOffset = sObjectMgr->GetGenerator().GetNextAfterMaxUsed(); - DumpGuidMap items; - DumpGuidMap mails; - char buf[32000]; - memset(buf, 0, sizeof(buf)); + std::map mails; + ObjectGuid::LowType mailLowGuidOffset = sObjectMgr->_mailId; - typedef std::map PetIds; - PetIds petIds; + std::map petIds; + ObjectGuid::LowType petLowGuidOffset = sObjectMgr->_hiPetNumber; + + std::map equipmentSetIds; + uint64 equipmentSetGuidOffset = sObjectMgr->_equipmentSetGuid; + + static size_t const BUFFER_SIZE = 32000; + char buf[BUFFER_SIZE] = { }; uint8 gender = GENDER_NONE; uint8 race = RACE_NONE; - uint8 playerClass = 0; + uint8 playerClass = CLASS_NONE; uint8 level = 1; - ObjectGuid::LowType itemLowGuidOffset = sObjectMgr->GetGenerator().GetNextAfterMaxUsed(); + // for logs + size_t lineNumber = 0; SQLTransaction trans = CharacterDatabase.BeginTransaction(); - while (!feof(fin)) + while (!feof(fin.get())) { - if (!fgets(buf, 32000, fin)) + if (!fgets(buf, BUFFER_SIZE, fin.get())) { - if (feof(fin)) + if (feof(fin.get())) break; - ROLLBACK(DUMP_FILE_BROKEN); + return DUMP_FILE_BROKEN; } - std::string line; line.assign(buf); + std::string line; + line.assign(buf); + ++lineNumber; // skip empty strings size_t nw_pos = line.find_first_not_of(" \t\n\r\7"); if (nw_pos == std::string::npos) continue; - // skip logfile-side dump start notice, the important notes and dump end notices - if ((line.substr(nw_pos, 16) == "== START DUMP ==") || - (line.substr(nw_pos, 15) == "IMPORTANT NOTE:") || - (line.substr(nw_pos, 14) == "== END DUMP ==")) + // skip the important notes + static std::string const SkippedLine = "IMPORTANT NOTE:"; + if (line.substr(nw_pos, SkippedLine.size()) == SkippedLine) continue; - // add required_ check - /* - if (line.substr(nw_pos, 41) == "UPDATE character_db_version SET required_") - { - if (!CharacterDatabase.Execute(line.c_str())) - ROLLBACK(DUMP_FILE_BROKEN); - - continue; - } - */ - // determine table name and load type std::string tn = GetTableName(line); if (tn.empty()) { - TC_LOG_ERROR("misc", "LoadPlayerDump: Can't extract table name from line: '%s'!", line.c_str()); - ROLLBACK(DUMP_FILE_BROKEN); + TC_LOG_ERROR("misc", "LoadPlayerDump: (line " UI64FMTD ") Can't extract table name!", lineNumber); + return DUMP_FILE_BROKEN; } - DumpTableType type = DumpTableType(0); - uint8 i; + DumpTableType type = DTT_CHARACTER; + uint32 i; for (i = 0; i < DUMP_TABLE_COUNT; ++i) { - if (tn == dumpTables[i].name) + if (tn == DumpTables[i].Name) { - type = dumpTables[i].type; + type = DumpTables[i].Type; break; } } if (i == DUMP_TABLE_COUNT) { - TC_LOG_ERROR("misc", "LoadPlayerDump: Unknown table: '%s'!", tn.c_str()); - ROLLBACK(DUMP_FILE_BROKEN); + TC_LOG_ERROR("misc", "LoadPlayerDump: (line " UI64FMTD ") Unknown table: `%s`!", lineNumber, tn.c_str()); + return DUMP_FILE_BROKEN; } - // change the data to server values + TableStruct const& ts = CharacterTables[i]; + if (!ValidateFields(ts, line, lineNumber)) + return DUMP_FILE_BROKEN; + + // per field guid offsetting + for (TableField const& field : ts.TableFields) + { + if (!field.IsDependentField) + continue; + + switch (field.FieldGuidType) + { + case GUID_TYPE_ACCOUNT: + if (!ChangeColumn(ts, line, field.FieldName, chraccount)) + return DUMP_FILE_BROKEN; + break; + case GUID_TYPE_CHAR: + if (!ChangeColumn(ts, line, field.FieldName, newguid)) + return DUMP_FILE_BROKEN; + break; + case GUID_TYPE_PET: + if (!ChangeGuid(ts, line, field.FieldName, petIds, petLowGuidOffset)) + return DUMP_FILE_BROKEN; + break; + case GUID_TYPE_MAIL: + if (!ChangeGuid(ts, line, field.FieldName, mails, mailLowGuidOffset)) + return DUMP_FILE_BROKEN; + break; + case GUID_TYPE_ITEM: + if (!ChangeGuid(ts, line, field.FieldName, items, itemLowGuidOffset, true)) + return DUMP_FILE_BROKEN; + break; + case GUID_TYPE_EQUIPMENT_SET: + if (!ChangeGuid(ts, line, field.FieldName, equipmentSetIds, equipmentSetGuidOffset)) + return DUMP_FILE_BROKEN; + break; + case GUID_TYPE_NULL: + { + static std::string const NullString("NULL"); + if (!ChangeColumn(ts, line, field.FieldName, NullString)) + return DUMP_FILE_BROKEN; + break; + } + } + } + + // extra modifications for other tables switch (type) { case DTT_CHARACTER: @@ -536,143 +923,33 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s if (!ChangeNth(line, 2, chraccount)) // characters.account update ROLLBACK(DUMP_FILE_BROKEN); - race = uint8(atoul(GetNth(line, 4).c_str())); - playerClass = uint8(atoul(GetNth(line, 5).c_str())); - gender = uint8(atoul(GetNth(line, 6).c_str())); - level = uint8(atoul(GetNth(line, 7).c_str())); + race = uint8(atoul(GetColumn(ts, line, "race").c_str())); + playerClass = uint8(atoul(GetColumn(ts, line, "class").c_str())); + gender = uint8(atoul(GetColumn(ts, line, "gender").c_str())); + level = uint8(atoul(GetColumn(ts, line, "level").c_str())); if (name.empty()) { // check if the original name already exists - name = GetNth(line, 3); + name = GetColumn(ts, line, "name"); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME); stmt->setString(0, name); PreparedQueryResult result = CharacterDatabase.Query(stmt); + // characters.at_login set to "rename on login" if (result) - if (!ChangeNth(line, 38, "1")) // characters.at_login set to "rename on login" - ROLLBACK(DUMP_FILE_BROKEN); + if (!ChangeColumn(ts, line, "at_login", "1")) + return DUMP_FILE_BROKEN; } - else if (!ChangeNth(line, 3, name.c_str())) // characters.name - ROLLBACK(DUMP_FILE_BROKEN); - - const char null[5] = "NULL"; - if (!ChangeNth(line, 68, null)) // characters.deleteInfos_Account - ROLLBACK(DUMP_FILE_BROKEN); - if (!ChangeNth(line, 69, null)) // characters.deleteInfos_Name - ROLLBACK(DUMP_FILE_BROKEN); - if (!ChangeNth(line, 70, null)) // characters.deleteDate - ROLLBACK(DUMP_FILE_BROKEN); - break; - } - case DTT_CHAR_TABLE: - { - if (!ChangeNth(line, 1, newguid)) // character_*.guid update - ROLLBACK(DUMP_FILE_BROKEN); - break; - } - case DTT_EQSET_TABLE: - { - if (!ChangeNth(line, 1, newguid)) - ROLLBACK(DUMP_FILE_BROKEN); // character_equipmentsets.guid - - char newSetGuid[24]; - snprintf(newSetGuid, 24, UI64FMTD, sObjectMgr->GenerateEquipmentSetGuid()); - if (!ChangeNth(line, 2, newSetGuid)) - ROLLBACK(DUMP_FILE_BROKEN); // character_equipmentsets.setguid - - for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot) - if (!ChangeGuid(line, 7 + slot, items, itemLowGuidOffset, true)) - ROLLBACK(DUMP_FILE_BROKEN); // character_equipmentsets.item - break; - } - case DTT_INVENTORY: - { - if (!ChangeNth(line, 1, newguid)) // character_inventory.guid update - ROLLBACK(DUMP_FILE_BROKEN); - - if (!ChangeGuid(line, 2, items, itemLowGuidOffset, true)) - ROLLBACK(DUMP_FILE_BROKEN); // character_inventory.bag update - if (!ChangeGuid(line, 4, items, itemLowGuidOffset)) - ROLLBACK(DUMP_FILE_BROKEN); // character_inventory.item update - break; - } - case DTT_MAIL: // mail - { - if (!ChangeGuid(line, 1, mails, sObjectMgr->_mailId)) - ROLLBACK(DUMP_FILE_BROKEN); // mail.id update - if (!ChangeNth(line, 6, newguid)) // mail.receiver update - ROLLBACK(DUMP_FILE_BROKEN); - break; - } - case DTT_MAIL_ITEM: // mail_items - { - if (!ChangeGuid(line, 1, mails, sObjectMgr->_mailId)) - ROLLBACK(DUMP_FILE_BROKEN); // mail_items.id - if (!ChangeGuid(line, 2, items, itemLowGuidOffset)) - ROLLBACK(DUMP_FILE_BROKEN); // mail_items.item_guid - if (!ChangeNth(line, 3, newguid)) // mail_items.receiver - ROLLBACK(DUMP_FILE_BROKEN); - break; - } - case DTT_ITEM: - { - // item, owner, data field:item, owner guid - if (!ChangeGuid(line, 1, items, itemLowGuidOffset)) - ROLLBACK(DUMP_FILE_BROKEN); // item_instance.guid update - if (!ChangeNth(line, 3, newguid)) // item_instance.owner_guid update - ROLLBACK(DUMP_FILE_BROKEN); - break; - } - case DTT_ITEM_GIFT: - { - if (!ChangeNth(line, 1, newguid)) // character_gifts.guid update - ROLLBACK(DUMP_FILE_BROKEN); - if (!ChangeGuid(line, 2, items, itemLowGuidOffset)) - ROLLBACK(DUMP_FILE_BROKEN); // character_gifts.item_guid update - break; - } - case DTT_PET: - { - // store a map of old pet id to new inserted pet id for use by DTT_PET_TABLE tables - std::string petIdStr = GetNth(line, 1); - - uint32 currentPetId = atoul(petIdStr.c_str()); - - PetIds::const_iterator petIdsItr = petIds.find(currentPetId); - if (petIdsItr != petIds.end()) // duplicate pets - ROLLBACK(DUMP_FILE_BROKEN); - - uint32 newPetId = sObjectMgr->GeneratePetNumber(); - petIds[currentPetId] = newPetId; - - if (!ChangeNth(line, 1, std::to_string(newPetId).c_str())) // character_pet.id update - ROLLBACK(DUMP_FILE_BROKEN); - if (!ChangeNth(line, 3, newguid)) // character_pet.owner update - ROLLBACK(DUMP_FILE_BROKEN); - - break; - } - case DTT_PET_TABLE: // pet_aura, pet_spell, pet_spell_cooldown - { - std::string petIdStr = GetNth(line, 1); - - // lookup currpetid and match to new inserted pet id - PetIds::const_iterator petIdsItr = petIds.find(atoul(petIdStr.c_str())); - if (petIdsItr == petIds.end()) // couldn't find new inserted id - ROLLBACK(DUMP_FILE_BROKEN); - - if (!ChangeNth(line, 1, std::to_string(petIdsItr->second).c_str())) - ROLLBACK(DUMP_FILE_BROKEN); - + else if (!ChangeColumn(ts, line, "name", name.c_str())) // characters.name + return DUMP_FILE_BROKEN; break; } default: - TC_LOG_ERROR("misc", "Unknown dump table type: %u", type); break; } - fixNULLfields(line); + FixNULLfields(line); trans->Append(line.c_str()); } @@ -684,13 +961,12 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s sObjectMgr->GetGenerator().Set(sObjectMgr->GetGenerator().GetNextAfterMaxUsed() + items.size()); - sObjectMgr->_mailId += mails.size(); + sObjectMgr->_mailId += mails.size(); + sObjectMgr->_hiPetNumber += petIds.size(); + sObjectMgr->_equipmentSetGuid += equipmentSetIds.size(); if (incHighest) sObjectMgr->GetGenerator().Generate(); - - fclose(fin); - return DUMP_SUCCESS; } diff --git a/src/server/game/Tools/PlayerDump.h b/src/server/game/Tools/PlayerDump.h index 3a5dfeb2e5..f6ada756ec 100644 --- a/src/server/game/Tools/PlayerDump.h +++ b/src/server/game/Tools/PlayerDump.h @@ -58,16 +58,18 @@ enum DumpReturn DUMP_SUCCESS, DUMP_FILE_OPEN_ERROR, DUMP_TOO_MANY_CHARS, - DUMP_UNEXPECTED_END, DUMP_FILE_BROKEN, DUMP_CHARACTER_DELETED }; +struct DumpTable; +struct TableStruct; +class StringTransaction; + class TC_GAME_API PlayerDump { public: - typedef std::set DumpGuidSet; - typedef std::map DumpGuidMap; + static void InitializeTables(); protected: PlayerDump() { } @@ -82,13 +84,14 @@ class TC_GAME_API PlayerDumpWriter : public PlayerDump DumpReturn WriteDump(std::string const& file, ObjectGuid::LowType guid); private: - bool DumpTable(std::string& dump, ObjectGuid::LowType guid, char const* tableFrom, char const* tableTo, DumpTableType type); - std::string GenerateWhereStr(char const* field, DumpGuidSet const& guids, DumpGuidSet::const_iterator& itr); - std::string GenerateWhereStr(char const* field, ObjectGuid::LowType guid); + bool AppendTable(StringTransaction& trans, ObjectGuid::LowType guid, TableStruct const& tableStruct, DumpTable const& dumpTable); + void PopulateGuids(ObjectGuid::LowType guid); - DumpGuidSet pets; - DumpGuidSet mails; - DumpGuidSet items; + std::set _pets; + std::set _mails; + std::set _items; + + std::set _itemSets; }; class TC_GAME_API PlayerDumpReader : public PlayerDump diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 8526561b34..90d5018386 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -52,6 +52,7 @@ #include "ObjectMgr.h" #include "OutdoorPvPMgr.h" #include "Player.h" +#include "PlayerDump.h" #include "PoolMgr.h" #include "QueryCallback.h" #include "ScriptMgr.h" @@ -1496,6 +1497,9 @@ void World::SetInitialWorldSettings() MMAP::MMapManager* mmmgr = MMAP::MMapFactory::createOrGetMMapManager(); mmmgr->InitializeThreadUnsafe(mapData); + TC_LOG_INFO("server.loading", "Initializing PlayerDump tables..."); + PlayerDump::InitializeTables(); + TC_LOG_INFO("server.loading", "Loading SpellInfo store..."); sSpellMgr->LoadSpellInfoStore(); From f3c30eabbe487a6ba56dab029c3ac29a3e653ba4 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Fri, 26 May 2017 18:43:02 +0200 Subject: [PATCH 38/44] missing part --- src/server/game/Tools/PlayerDump.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index 9631e450f0..4555326251 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -917,12 +917,6 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s { case DTT_CHARACTER: { - if (!ChangeNth(line, 1, newguid)) // characters.guid update - ROLLBACK(DUMP_FILE_BROKEN); - - if (!ChangeNth(line, 2, chraccount)) // characters.account update - ROLLBACK(DUMP_FILE_BROKEN); - race = uint8(atoul(GetColumn(ts, line, "race").c_str())); playerClass = uint8(atoul(GetColumn(ts, line, "class").c_str())); gender = uint8(atoul(GetColumn(ts, line, "gender").c_str())); From f8a222aab912eae92fa1b634aa7c6fea500b90f7 Mon Sep 17 00:00:00 2001 From: ariel- Date: Sat, 27 May 2017 00:39:32 -0300 Subject: [PATCH 39/44] Scripts/VioletHold: fix stack overflow when reflecting 'Splash' Closes #19514 --- src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp index 6054b5d457..3ce72ebd74 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp @@ -240,7 +240,7 @@ class npc_ichor_globule : public CreatureScript struct npc_ichor_globuleAI : public ScriptedAI { - npc_ichor_globuleAI(Creature* creature) : ScriptedAI(creature) + npc_ichor_globuleAI(Creature* creature) : ScriptedAI(creature), _splashTriggered(false) { _instance = creature->GetInstanceScript(); creature->SetReactState(REACT_PASSIVE); @@ -272,14 +272,21 @@ class npc_ichor_globule : public CreatureScript // this feature should be still implemented void DamageTaken(Unit* /*attacker*/, uint32& damage) override { + if (_splashTriggered) + return; + if (damage >= me->GetHealth()) + { + _splashTriggered = true; DoCastAOE(SPELL_SPLASH); + } } void UpdateAI(uint32 /*diff*/) override { } private: InstanceScript* _instance; + bool _splashTriggered; }; CreatureAI* GetAI(Creature* creature) const override From 8082b3165e9c0046617b66d99b067e0145c147be Mon Sep 17 00:00:00 2001 From: ariel- Date: Sat, 27 May 2017 01:40:14 -0300 Subject: [PATCH 40/44] Core/Spell: abort channeling if no valid targets are found after searching Closes #17624 --- src/server/game/Spells/Spell.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index df52092554..d6cb721fc3 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -792,6 +792,14 @@ void Spell::SelectSpellTargets() if (m_spellInfo->IsChanneled()) { + // maybe do this for all spells? + if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty()) + { + SendCastResult(SPELL_FAILED_BAD_IMPLICIT_TARGETS); + finish(false); + return; + } + uint8 mask = (1 << i); for (std::list::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) { From 3fa862ab38de67ecf5fee95f6efb4c7df586ade1 Mon Sep 17 00:00:00 2001 From: treeston Date: Sat, 27 May 2017 20:49:24 +0200 Subject: [PATCH 41/44] Instances/Ulduar: Fix a super edge case bug where Algalon would evade if his tank successfully tanked a Cosmic Smash and got knocked up. Shadow priests everywhere rejoiced. --- .../scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index 7127c3206e..d662578b9d 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -32,9 +32,9 @@ static BossBoundaryData const boundaries = { BOSS_XT002, new RectangleBoundary(755.0f, 940.0f, -125.0f, 95.0f) }, { BOSS_ASSEMBLY_OF_IRON, new CircleBoundary(Position(1587.2f, 121.0f), 90.0) }, { BOSS_ALGALON, new CircleBoundary(Position(1632.668f, -307.7656f), 45.0) }, - { BOSS_ALGALON, new ZRangeBoundary(410.0f, 440.0f) }, + { BOSS_ALGALON, new ZRangeBoundary(410.0f, 470.0f) }, { BOSS_HODIR, new EllipseBoundary(Position(2001.5f, -240.0f), 50.0, 75.0) }, - // Thorim sets boundaries dinamically + // Thorim sets boundaries dynamically { BOSS_FREYA, new RectangleBoundary(2094.6f, 2520.0f, -250.0f, 200.0f) }, { BOSS_MIMIRON, new CircleBoundary(Position(2744.0f, 2569.0f), 70.0) }, { BOSS_VEZAX, new RectangleBoundary(1740.0f, 1930.0f, 31.0f, 228.0f) }, From e3616823776b9e4aa9208a457f12c314de211d1c Mon Sep 17 00:00:00 2001 From: treeston Date: Sat, 27 May 2017 21:05:26 +0200 Subject: [PATCH 42/44] Quickfix a bug introduced by 2f19d97 which prevented GTAoE from being cast. --- src/server/game/Spells/Spell.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index d6cb721fc3..8a997c8694 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -793,7 +793,7 @@ void Spell::SelectSpellTargets() if (m_spellInfo->IsChanneled()) { // maybe do this for all spells? - if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty()) + if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst()) { SendCastResult(SPELL_FAILED_BAD_IMPLICIT_TARGETS); finish(false); From da65d89129a013582d32e266bbf193bb30d70002 Mon Sep 17 00:00:00 2001 From: ariel- Date: Sat, 27 May 2017 16:33:54 -0300 Subject: [PATCH 43/44] Core/Misc: fix some clang 5 warnings --- src/server/game/Pools/PoolMgr.cpp | 6 ------ src/server/worldserver/Main.cpp | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index edf56ecb5e..fbe3d7a987 100644 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -60,11 +60,6 @@ bool ActivePoolData::IsActiveObject(uint32 quest_id) const return mActiveQuests.find(quest_id) != mActiveQuests.end(); } -template TC_GAME_API bool ActivePoolData::IsActiveObject(uint32) const; -template TC_GAME_API bool ActivePoolData::IsActiveObject(uint32) const; -template TC_GAME_API bool ActivePoolData::IsActiveObject(uint32) const; -template TC_GAME_API bool ActivePoolData::IsActiveObject(uint32) const; - template<> void ActivePoolData::ActivateObject(uint32 db_guid, uint32 pool_id) { @@ -958,7 +953,6 @@ void PoolMgr::LoadFromDB() void PoolMgr::LoadQuestPools() { - } void PoolMgr::SaveQuestsToDB() diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index ce1ca7b131..a45b09a1de 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -241,7 +241,7 @@ extern int main(int argc, char** argv) if (networkThreads <= 0) { TC_LOG_ERROR("server.worldserver", "Network.Threads must be greater than 0"); - return false; + return 1; } sWorldSocketMgr.StartNetwork(_ioService, worldListener, worldPort, networkThreads); From 3d5584fb8696a449a4b749ff3e7482bc2e70bdca Mon Sep 17 00:00:00 2001 From: ariel- Date: Sat, 27 May 2017 21:13:03 -0300 Subject: [PATCH 44/44] Core/Pools: fix VS dynamic linking --- src/server/game/Pools/PoolMgr.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index fbe3d7a987..4fced58b5f 100644 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -34,28 +34,28 @@ uint32 ActivePoolData::GetActiveObjectCount(uint32 pool_id) const // Method that tell if a creature is spawned currently template<> -bool ActivePoolData::IsActiveObject(uint32 db_guid) const +TC_GAME_API bool ActivePoolData::IsActiveObject(uint32 db_guid) const { return mSpawnedCreatures.find(db_guid) != mSpawnedCreatures.end(); } // Method that tell if a gameobject is spawned currently template<> -bool ActivePoolData::IsActiveObject(uint32 db_guid) const +TC_GAME_API bool ActivePoolData::IsActiveObject(uint32 db_guid) const { return mSpawnedGameobjects.find(db_guid) != mSpawnedGameobjects.end(); } // Method that tell if a pool is spawned currently template<> -bool ActivePoolData::IsActiveObject(uint32 sub_pool_id) const +TC_GAME_API bool ActivePoolData::IsActiveObject(uint32 sub_pool_id) const { return mSpawnedPools.find(sub_pool_id) != mSpawnedPools.end(); } // Method that tell if a quest can be started template<> -bool ActivePoolData::IsActiveObject(uint32 quest_id) const +TC_GAME_API bool ActivePoolData::IsActiveObject(uint32 quest_id) const { return mActiveQuests.find(quest_id) != mActiveQuests.end(); }