Merge branch 'master' into ovv/systemd-socket-activation

This commit is contained in:
Quentin Dawans 2025-06-23 22:09:16 +02:00 committed by GitHub
commit f49c8550bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 635 additions and 298 deletions

View File

@ -0,0 +1,6 @@
-- DB update 2025_06_18_00 -> 2025_06_21_00
-- Add Condition "Player should be within 5 yard of Salanar".
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 17) AND (`SourceGroup` = 0) AND (`SourceEntry` = 52264) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 29) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 28653) AND (`ConditionValue2` = 5) AND (`ConditionValue3` = 0);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(17, 0, 52264, 0, 0, 29, 0, 28653, 5, 0, 0, 0, 0, '', 'Deliver Stolen Horse only near Salanar the Horseman');

View File

@ -0,0 +1,166 @@
-- DB update 2025_06_21_00 -> 2025_06_21_01
--
-- Pathing for Entry: 29007
SET @NPC := 29007;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1649.966,-6042.5713,127.57849,0,0,1,0,100,0);
-- 0x202F2C4C201C53C000084E0000465DB5 .go xyz 1649.966 -6042.5713 127.57849
-- Pathing for Entry: 29007
SET @NPC := 29008;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1649.966,-6042.5713,127.57849,0,0,1,0,100,0);
-- 0x202F2C4C201C53C000084E0000465DD2 .go xyz 1649.966 -6042.5713 127.57849
-- Pathing for Entry: 29007
SET @NPC := 29009;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1649.966,-6042.5713,127.57849,0,0,1,0,100,0);
-- 0x202F2C4C201C53C000084E0000465DE7 .go xyz 1649.966 -6042.5713 127.57849
-- Pathing for Entry: 29007
SET @NPC := 29010;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1640.7407,-6032.02,134.73505,0,0,1,0,100,0);
-- 0x202F2C4C201C53C000084E0000C65DB5 .go xyz 1640.7407 -6032.02 134.73505
-- Pathing for Entry: 29007
SET @NPC := 29011;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1640.7958,-6030.307,134.73505,0,0,1,0,100,0);
-- 0x202F2C4C201C53C000084E0000C65DD2 .go xyz 1640.7958 -6030.307 134.73505
-- Pathing for Entry: 29007
SET @NPC := 29012;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1646.2389,-6032.526,134.73506,0,0,1,0,100,0);
-- 0x202F2C4C201C53C000084E0000C65DE7 .go xyz 1646.2389 -6032.526 134.73506
-- Pathing for Entry: 29007
SET @NPC := 29013;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1640.6724,-6032.0527,134.73506,0,0,1,0,100,0);
-- 0x202F2C4C201C53C000084E0001465DB5 .go xyz 1640.6724 -6032.0527 134.73506
-- Pathing for Entry: 29007
SET @NPC := 29014;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1638.7998,-6036.4976,132.57643,0,0,1,0,100,0);
-- 0x202F2C4C201C53C000084E0001465DD2 .go xyz 1638.7998 -6036.4976 132.57643
-- Pathing for Entry: 29007
SET @NPC := 29015;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1638.2631,-6030.1514,134.73505,0,0,1,0,100,0);
-- 0x202F2C4C201C53C000084E0001465DE7 .go xyz 1638.2631 -6030.1514 134.73505
-- Pathing for Entry: 29007
SET @NPC := 29016;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1642.4694,-6029.949,134.73505,0,0,1,0,100,0);
-- 0x202F2C4C201C53C000084E0001C65DE7 .go xyz 1642.4694 -6029.949 134.73505
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 29007;
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 29007) AND (`source_type` = 0) AND (`id` IN (1, 2, 3, 4));
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(29007, 0, 1, 0, 0, 0, 100, 0, 1000, 4000, 4000, 6000, 0, 0, 11, 15498, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Crimson Acolyte - In Combat - Cast \'Holy Smite\''),
(29007, 0, 2, 0, 0, 0, 100, 0, 6000, 9000, 25000, 30000, 0, 0, 11, 19725, 64, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 'Crimson Acolyte - In Combat - Cast \'Turn Undead\''),
(29007, 0, 3, 4, 109, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 256, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Crimson Acolyte - On Path 0 Finished - Remove Flags Immune To Players'),
(29007, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 9, 0, 0, 50, 0, 0, 0, 0, 0, 'Crimson Acolyte - On Path 0 Finished - Set In Combat With Zone');
UPDATE `creature_template` SET `unit_flags` = `unit_flags`|256 WHERE `entry` = 29007;
-- Pathing for Entry: 29001
SET @NPC := 29001;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1648.3103,-6043.6396,127.57861,0,0,1,0,100,0);
DELETE FROM `script_waypoint` WHERE `entry` = 28912;
SET @NPC := 28912;
SET @PATH := @NPC * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1653.36,-6038.34,127.584,0,0,0,0,100,0),
(@PATH,2,1653.7653,-6035.075,127.5844,1.596199,5000,0,0,100,0),
(@PATH,3,1651.8898,-6037.1006,127.5844,0,0,0,0,100,0),
(@PATH,4,1651.8898,-6037.1006,127.5844,3.839724302291870117,0,0,0,100,0);
SET @PATH := (@NPC + 1) * 10;
DELETE FROM `waypoint_data` WHERE `id`=@PATH;
INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
(@PATH,1,1653.3759,-5971.8735,132.25667,0,0,1,0,100,0),
(@PATH,2,1685.0416,-5887.038,116.1461,0,0,1,0,100,0);
DELETE FROM `creature_text` WHERE `CreatureID` = 28912;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(28912, 0, 0, 'Damn the Crusade! I think my ribs are broken and I might be bleeding internally.', 12, 0, 100, 0, 0, 0, 29197, 0, 'koltira deathweaver'),
(28912, 1, 0, 'I\'ll need to get my runeblade and armor... Just need a little more time.', 12, 0, 100, 0, 0, 0, 29201, 0, 'koltira deathweaver'),
(28912, 2, 0, 'I\'m still weak, but I think I can get an anti-magic barrier up. Stay inside it or you\'ll be destroyed by their spells.', 12, 0, 100, 0, 0, 0, 29203, 0, 'koltira deathweaver'),
(28912, 3, 0, 'Maintaining this barrier will require all of my concentration. Kill them all!', 12, 0, 100, 0, 0, 0, 29205, 0, 'koltira deathweaver'),
(28912, 4, 0, 'There are more coming. Defend yourself! Don\'t fall out of the anti-magic field! They\'ll tear you apart without its protection!', 12, 0, 100, 0, 0, 0, 29207, 0, 'koltira deathweaver'),
(28912, 5, 0, 'I can\'t keep this barrier up much longer... Where is that coward?', 12, 0, 100, 0, 0, 0, 29208, 0, 'koltira deathweaver'),
(28912, 6, 0, 'The High Inquisitor comes! Be ready, death knight! Do not let him draw you out of the protective bounds of my anti-magic field! Kill him and take his head!', 12, 0, 100, 0, 0, 0, 29210, 0, 'koltira deathweaver'),
(28912, 7, 0, 'Stay in the anti-magic field! Make them come to you!', 12, 0, 100, 0, 0, 0, 29225, 0, 'koltira deathweaver'),
(28912, 8, 0, 'The death of the High Inquisitor of New Avalon will not go unnoticed. You need to get out of here at once! Go, before more of them show up. I\'ll be fine on my own.', 12, 0, 100, 1, 0, 0, 29239, 0, 'koltira deathweaver'),
(28912, 9, 0, 'I\'ll draw their fire, you make your escape behind me.', 12, 0, 100, 1, 0, 0, 29240, 0, 'koltira deathweaver'),
(28912, 10, 0, 'Your High Inquisitor is nothing more than a pile of meat, Crusaders! There are none beyond the grasp of the Scourge!', 14, 0, 100, 5, 0, 0, 29241, 0, 'koltira deathweaver'),
(28912, 11, 0, '%s collapses to the ground.', 41, 0, 100, 0, 0, 0, 29230, 0, 'koltira deathweaver');
UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = 29001;
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 29001) AND (`source_type` = 0) AND (`id` IN (0, 1, 2, 3, 4, 5, 6, 7));
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(29001, 0, 0, 0, 0, 0, 100, 0, 1000, 1000, 1000, 3000, 0, 0, 11, 52926, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Valroth - In Combat - Cast \'Valroth`s Smite\''),
(29001, 0, 1, 0, 2, 0, 100, 0, 0, 50, 0, 0, 0, 0, 11, 38210, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Valroth - Between 0-50% Health - Cast \'Renew\''),
(29001, 0, 2, 3, 0, 0, 100, 0, 2000, 7000, 2000, 7000, 0, 0, 11, 52922, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Valroth - In Combat - Cast \'The Inquisitor`s Penance\''),
(29001, 0, 3, 0, 61, 0, 50, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Valroth - In Combat - Say Line 2'),
(29001, 0, 4, 0, 109, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 256, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Valroth - On Path 0 Finished - Remove Flags Immune To Players'),
(29001, 0, 5, 6, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 52929, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Valroth - On Just Died - Cast \'Summon Valroth`s Remains\''),
(29001, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Valroth - On Just Died - Say Line 3'),
(29001, 0, 7, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'High Inquisitor Valroth - On Aggro - Say Line 6');
DELETE FROM `creature_text` WHERE `CreatureID` = 29001;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(29001, 0, 0, 'The Crusade will purge your kind from this world!', 14, 0, 100, 0, 0, 0, 29215, 0, 'high inquisitor valroth'),
(29001, 1, 0, 'It seems that I\'ll need to deal with you myself. The High Inquisitor comes for you, Scourge!', 14, 0, 100, 0, 0, 0, 29216, 0, 'high inquisitor valroth'),
(29001, 2, 0, 'You have come seeking deliverance? I have come to deliver!', 12, 0, 100, 0, 0, 0, 29222, 0, 'high inquisitor valroth'),
(29001, 2, 1, 'LIGHT PURGE YOU!', 12, 0, 100, 0, 0, 0, 29221, 0, 'high inquisitor'),
(29001, 2, 2, 'Coward!', 12, 0, 100, 0, 0, 0, 30699, 0, 'high inquisitor valroth'),
(29001, 3, 0, '%s\'s remains fall to the ground.', 41, 0, 100, 0, 0, 0, 29223, 0, 'high inquisitor'),
(29001, 4, 0, 'Acolytes, chain them all up! Prepare them for questioning!', 14, 0, 100, 0, 0, 0, 29202, 0, 'high inquisitor'),
(29001, 5, 0, 'Scourge filth! By the Light be cleansed!', 14, 0, 100, 0, 0, 0, 29214, 0, 'high inquisitor'),
(29001, 6, 0, 'Your dark Scourge magic won\'t protect you from the Light!', 12, 0, 100, 0, 0, 0, 29218, 0, 'high inquisitor');
DELETE FROM `gossip_menu_option` WHERE `MenuID` = 9762;
INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`) VALUES
(9762, 0, 0, 'Koltira, let\'s get out of here!', 29243, 1, 1, 0);
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` = 9762) AND (`SourceEntry` = 0) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 47) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 12727) AND (`ConditionValue2` = 8) AND (`ConditionValue3` = 0);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(15, 9762, 0, 0, 0, 47, 0, 12727, 8, 0, 0, 0, 0, '', 'Only show Koltira gossip if player has quest Bloody Breakout incomplete');
UPDATE `creature_addon` SET `auras` = '' WHERE `guid` IN (130354, 129716);

View File

@ -0,0 +1,6 @@
-- DB update 2025_06_21_01 -> 2025_06_21_02
--
DELETE FROM `spell_script_names` WHERE `spell_id` IN (58552,58533) AND `ScriptName`='spell_chapter5_return_to_capital';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(58552, 'spell_chapter5_return_to_capital'),
(58533, 'spell_chapter5_return_to_capital');

View File

@ -0,0 +1,12 @@
-- DB update 2025_06_21_02 -> 2025_06_21_03
-- Defender of the Light (update comments and edit Holy Wrath cd).
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 29174;
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 29174);
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(29174, 0, 0, 0, 0, 0, 100, 0, 10000, 20000, 10000, 20000, 0, 0, 11, 53625, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 'Defender of the Light - In Combat - Cast \'Heroic Leap\''),
(29174, 0, 1, 0, 0, 0, 100, 0, 10000, 20000, 10000, 20000, 0, 0, 11, 53643, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Defender of the Light - In Combat - Cast \'Holy Strike\''),
(29174, 0, 2, 0, 0, 0, 100, 0, 10000, 30000, 45000, 60000, 0, 0, 11, 53638, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Defender of the Light - In Combat - Cast \'Holy Wrath\''),
(29174, 0, 3, 0, 0, 0, 100, 0, 10000, 20000, 10000, 20000, 0, 0, 11, 53629, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Defender of the Light - In Combat - Cast \'Uppercut\''),
(29174, 0, 4, 0, 74, 0, 100, 0, 0, 0, 5000, 10000, 20, 0, 11, 29427, 1, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 'Defender of the Light - On Friendly Below 20% Health - Cast \'Holy Light\'');

View File

@ -69,6 +69,14 @@ Milliseconds randtime(Milliseconds min, Milliseconds max)
return min + Milliseconds(urand(0, diff));
}
Seconds randtime(Seconds min, Seconds max)
{
long long diff = max.count() - min.count();
ASSERT(diff >= 0);
ASSERT(diff <= (uint32) - 1);
return min + Seconds(urand(0, diff));
}
uint32 rand32()
{
return GetRng()->RandomUInt32();

View File

@ -38,6 +38,9 @@ AC_COMMON_API uint32 rand32();
/* Return a random time in the range min..max (up to millisecond precision). Only works for values where millisecond difference is a valid uint32. */
AC_COMMON_API Milliseconds randtime(Milliseconds min, Milliseconds max);
/* Return a random time in the range min..max (up to second precision). */
AC_COMMON_API Seconds randtime(Seconds min, Seconds max);
/* Return a random number in the range min..max */
AC_COMMON_API float frand(float min, float max);

View File

@ -191,8 +191,23 @@ SpellCastResult UnitAI::DoCast(uint32 spellId)
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
{
bool playerOnly = spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER);
target = SelectTarget(SelectTargetMethod::Random, 0, spellInfo->GetMaxRange(false), playerOnly);
DefaultTargetSelector targetSelector(me, spellInfo->GetMaxRange(false), false, true, 0);
target = SelectTarget(SelectTargetMethod::Random, 0, [&](Unit* target) {
if (target->IsPlayer())
{
if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
return false;
}
else
{
if (spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER))
return false;
if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC) && target->IsControlledByPlayer())
return false;
}
return targetSelector(target);
});
}
break;
}
@ -206,12 +221,27 @@ SpellCastResult UnitAI::DoCast(uint32 spellId)
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
{
bool playerOnly = spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER);
float range = spellInfo->GetMaxRange(false);
DefaultTargetSelector targetSelector(me, range, playerOnly, true, -(int32)spellId);
if (!(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM)
&& targetSelector(me->GetVictim()))
DefaultTargetSelector defaultTargetSelector(me, range, false, true, -(int32)spellId);
auto targetSelector = [&](Unit* target) {
if (target->IsPlayer())
{
if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
return false;
}
else
{
if (spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER))
return false;
if (spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC) && target->IsControlledByPlayer())
return false;
}
return defaultTargetSelector(target);
};
if (!(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM) && targetSelector(me->GetVictim()))
target = me->GetVictim();
else
target = SelectTarget(SelectTargetMethod::Random, 0, targetSelector);

View File

@ -3707,10 +3707,12 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
if (!units.empty() && baseObject)
for (WorldObject* unit : units)
if (IsPlayer(unit) && baseObject->IsInRange(unit, float(e.target.playerRange.minDist), float(e.target.playerRange.maxDist)))
if (IsPlayer(unit) && !unit->ToPlayer()->IsGameMaster() && baseObject->IsInRange(unit, float(e.target.playerRange.minDist), float(e.target.playerRange.maxDist)))
targets.push_back(unit);
if (e.target.playerRange.maxCount)
Acore::Containers::RandomResize(targets, e.target.playerRange.maxCount);
break;
}
case SMART_TARGET_PLAYER_DISTANCE:
@ -4664,12 +4666,11 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
if (!targets.empty())
{
for (WorldObject* target : targets)
{
if (IsPlayer(target))
if (IsPlayer(target) && !target->ToPlayer()->IsGameMaster())
playerCount++;
}
if (playerCount >= e.event.nearPlayer.minCount)
ProcessAction(e, unit);
if (playerCount >= e.event.nearPlayer.minCount)
ProcessAction(e, unit);
}
RecalcTimer(e, e.event.nearPlayer.repeatMin, e.event.nearPlayer.repeatMax);
break;
@ -4683,10 +4684,8 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
if (!targets.empty())
{
for (WorldObject* target : targets)
{
if (IsPlayer(target))
if (IsPlayer(target) && !target->ToPlayer()->IsGameMaster())
playerCount++;
}
if (playerCount < e.event.nearPlayerNegation.maxCount)
ProcessAction(e, unit);

View File

@ -20083,6 +20083,24 @@ private:
AuraType _auraType;
};
class ResetToHomeOrientation : public BasicEvent
{
public:
ResetToHomeOrientation(Creature& self) : _self(self) { }
bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override
{
if (_self.IsInWorld() && _self.FindMap() && _self.IsAlive() && !_self.IsInCombat())
{
_self.SetFacingTo(_self.GetHomePosition().GetOrientation());
}
return true;
}
private:
Creature& _self;
};
void Unit::CastDelayedSpellWithPeriodicAmount(Unit* caster, uint32 spellId, AuraType auraType, int32 addAmount, uint8 effectIndex)
{
AuraEffect* aurEff = nullptr;
@ -20329,6 +20347,24 @@ void Unit::SetFacingToObject(WorldObject* object)
init.Launch();
}
void Unit::SetTimedFacingToObject(WorldObject* object, uint32 time)
{
// never face when already moving
if (!IsStopped() || !time)
return;
/// @todo figure out under what conditions creature will move towards object instead of facing it where it currently is.
Movement::MoveSplineInit init(this);
init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZ());
init.SetFacing(GetAngle(object)); // when on transport, GetAngle will still return global coordinates (and angle) that needs transforming
init.Launch();
if (Creature* c = ToCreature())
c->m_Events.AddEvent(new ResetToHomeOrientation(*c), c->m_Events.CalculateTime(time));
else
LOG_ERROR("entities.unit", "Unit::SetTimedFacingToObject called on non-creature unit {}. This should never happen.", GetEntry());
}
bool Unit::SetWalk(bool enable)
{
if (enable == IsWalking())

View File

@ -1893,6 +1893,7 @@ public:
void SetInFront(WorldObject const* target);
void SetFacingTo(float ori);
void SetFacingToObject(WorldObject* object);
void SetTimedFacingToObject(WorldObject* object, uint32 time); // Reset to home orientation after given time
bool isInAccessiblePlaceFor(Creature const* c) const;
bool isInFrontInMap(Unit const* target, float distance, float arc = M_PI) const;

View File

@ -172,8 +172,8 @@ namespace Acore
template<class RET_TYPE, int CENTER_VAL>
inline RET_TYPE Compute(float x, float y, float size)
{
int gx = (int)(CENTER_VAL - x / size);
int gy = (int)(CENTER_VAL - y / size);
int gx = std::max<int>(0, (CENTER_VAL - x / size));
int gy = std::max<int>(0, (CENTER_VAL - y / size));
return RET_TYPE(gx, gy);
}

View File

@ -110,6 +110,7 @@ public:
uint8 GetCasterLevel() const { return m_casterLevel; }
bool CanApplyResilience() const { return m_applyResilience; }
float GetPctMods() const { return m_pctMods; }
void SetPctMods(float pctMods) { m_pctMods = pctMods; }
// xinef: stacking
uint32 GetAuraGroup() const { return m_auraGroup; }

View File

@ -2147,6 +2147,8 @@ uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList*
retMask &= GRID_MAP_TYPE_MASK_CORPSE | GRID_MAP_TYPE_MASK_PLAYER;
if (m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_GHOSTS))
retMask &= GRID_MAP_TYPE_MASK_PLAYER;
if (m_spellInfo->HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
retMask &= ~GRID_MAP_TYPE_MASK_PLAYER;
if (condList)
retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);

View File

@ -1863,8 +1863,19 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta
else return SPELL_CAST_OK;
// corpseOwner and unit specific target checks
if (AttributesEx3 & SPELL_ATTR3_ONLY_ON_PLAYER && !unitTarget->ToPlayer())
return SPELL_FAILED_TARGET_NOT_PLAYER;
if (unitTarget->IsPlayer())
{
if (HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER))
return SPELL_FAILED_TARGET_IS_PLAYER;
}
else
{
if (HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER))
return SPELL_FAILED_TARGET_NOT_PLAYER;
if (HasAttribute(SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC) && unitTarget->IsControlledByPlayer())
return SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED;
}
if (!IsAllowingDeadTarget() && !unitTarget->IsAlive())
return SPELL_FAILED_TARGETS_DEAD;

View File

@ -18,6 +18,7 @@
#include "CombatAI.h"
#include "CreatureScript.h"
#include "CreatureTextMgr.h"
#include "ScriptedGossip.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
@ -185,16 +186,23 @@ public:
enum Koltira
{
SAY_BREAKOUT1 = 0,
SAY_BREAKOUT2 = 1,
SAY_BREAKOUT3 = 2,
SAY_BREAKOUT4 = 3,
SAY_BREAKOUT5 = 4,
SAY_BREAKOUT6 = 5,
SAY_BREAKOUT7 = 6,
SAY_BREAKOUT8 = 7,
SAY_BREAKOUT9 = 8,
SAY_BREAKOUT10 = 9,
SAY_BREAKOUT0 = 0,
SAY_BREAKOUT1 = 1,
SAY_BREAKOUT2 = 2,
SAY_BREAKOUT3 = 3,
SAY_BREAKOUT4 = 4,
SAY_BREAKOUT5 = 5,
SAY_BREAKOUT6 = 6,
SAY_BREAKOUT7 = 7,
SAY_BREAKOUT8 = 8,
SAY_BREAKOUT9 = 9,
SAY_BREAKOUT10 = 10,
EMOTE_KOLTIRA_COLLAPSES = 11,
SAY_VALROTH_WAVE3 = 0,
SAY_VALROTH_AGGRO = 1,
SAY_VALROTH_WAVE1 = 4,
SAY_VALROTH_WAVE2 = 5,
SPELL_KOLTIRA_TRANSFORM = 52899,
SPELL_ANTI_MAGIC_ZONE = 52894,
@ -206,7 +214,14 @@ enum Koltira
//not sure about this id
//NPC_DEATH_KNIGHT_MOUNT = 29201,
MODEL_DEATH_KNIGHT_MOUNT = 25278
MODEL_DEATH_KNIGHT_MOUNT = 25278,
POINT_STAND_UP = 0,
POINT_BOX = 1,
POINT_ANTI_MAGIC_ZONE = 2,
POINT_MOUNT = 0,
POINT_DESPAWN = 1
};
class npc_koltira_deathweaver : public CreatureScript
@ -214,205 +229,203 @@ class npc_koltira_deathweaver : public CreatureScript
public:
npc_koltira_deathweaver() : CreatureScript("npc_koltira_deathweaver") { }
bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) override
{
if (quest->GetQuestId() == QUEST_BREAKOUT)
{
creature->SetStandState(UNIT_STAND_STATE_STAND);
creature->setActive(true);
if (npc_escortAI* pEscortAI = CAST_AI(npc_koltira_deathweaver::npc_koltira_deathweaverAI, creature->AI()))
pEscortAI->Start(false, false, player->GetGUID());
}
return true;
}
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_koltira_deathweaverAI(creature);
}
struct npc_koltira_deathweaverAI : public npc_escortAI
struct npc_koltira_deathweaverAI : public ScriptedAI
{
npc_koltira_deathweaverAI(Creature* creature) : npc_escortAI(creature), summons(me)
{
me->SetReactState(REACT_DEFENSIVE);
}
uint32 m_uiWave;
uint32 m_uiWave_Timer;
ObjectGuid m_uiValrothGUID;
SummonList summons;
npc_koltira_deathweaverAI(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
{
if (!HasEscortState(STATE_ESCORT_ESCORTING))
{
m_uiWave = 0;
m_uiWave_Timer = 3000;
m_uiValrothGUID.Clear();
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->LoadEquipment(0, true);
me->RemoveAllAuras();
summons.DespawnAll();
}
scheduler.CancelAll();
me->m_Events.KillAllEvents(false);
me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
me->setActive(false);
}
void EnterEvadeMode(EvadeReason /*why*/) override
void StartEvent()
{
me->GetThreatMgr().ClearAllThreat();
me->CombatStop(false);
me->SetLootRecipient(nullptr);
if (HasEscortState(STATE_ESCORT_ESCORTING))
{
AddEscortState(STATE_ESCORT_RETURNING);
ReturnToLastPoint();
LOG_DEBUG("scripts.ai", "EscortAI has left combat and is now returning to last point");
}
else
{
me->GetMotionMaster()->MoveTargetedHome();
me->SetImmuneToNPC(true);
Reset();
}
}
void AttackStart(Unit* who) override
{
if (HasEscortState(STATE_ESCORT_PAUSED))
if (!me->HasNpcFlag(UNIT_NPC_FLAG_GOSSIP)) // Already in progress
return;
npc_escortAI::AttackStart(who);
me->SetStandState(UNIT_STAND_STATE_SIT);
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
me->setActive(true);
Talk(SAY_BREAKOUT0);
me->m_Events.AddEventAtOffset([&] {
me->GetMotionMaster()->MovePath(me->GetEntry() * 10, false);
}, 5s);
}
void WaypointReached(uint32 waypointId) override
void sQuestAccept(Player* /*player*/, Quest const* quest) override
{
switch (waypointId)
if (quest->GetQuestId() == QUEST_BREAKOUT)
StartEvent();
}
void sGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override
{
if (player->GetQuestStatus(QUEST_BREAKOUT) == QUEST_STATUS_INCOMPLETE)
{
case 0:
Talk(SAY_BREAKOUT1);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
break;
case 1:
me->SetStandState(UNIT_STAND_STATE_KNEEL);
break;
case 2:
me->SetStandState(UNIT_STAND_STATE_STAND);
//me->UpdateEntry(NPC_KOLTIRA_ALT); //unclear if we must update or not
DoCast(me, SPELL_KOLTIRA_TRANSFORM);
me->LoadEquipment();
break;
case 3:
SetEscortPaused(true);
me->SetStandState(UNIT_STAND_STATE_KNEEL);
Talk(SAY_BREAKOUT2);
DoCast(me, SPELL_ANTI_MAGIC_ZONE); // cast again that makes bubble up
break;
case 4:
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_ALL, false);
SetRun(true);
break;
case 9:
me->Mount(MODEL_DEATH_KNIGHT_MOUNT);
break;
case 10:
me->Dismount();
break;
CloseGossipMenuFor(player);
StartEvent();
}
}
void JustSummoned(Creature* summoned) override
void MovementInform(uint32 type, uint32 id) override
{
if (Player* player = GetPlayerForEscort())
summoned->AI()->AttackStart(player);
if (type != WAYPOINT_MOTION_TYPE)
return;
if (summoned->GetEntry() == NPC_HIGH_INQUISITOR_VALROTH)
m_uiValrothGUID = summoned->GetGUID();
summoned->AddThreat(me, 0.0f);
summoned->SetImmuneToPC(false);
summons.Summon(summoned);
}
void SummonAcolyte(uint32 uiAmount)
{
for (uint32 i = 0; i < uiAmount; ++i)
me->SummonCreature(NPC_CRIMSON_ACOLYTE, 1642.329f, -6045.818f, 127.583f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
}
void UpdateAI(uint32 uiDiff) override
{
npc_escortAI::UpdateAI(uiDiff);
if (HasEscortState(STATE_ESCORT_PAUSED))
if (!me->HasUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC))
{
if (m_uiWave_Timer <= uiDiff)
if (id == POINT_MOUNT)
me->Mount(MODEL_DEATH_KNIGHT_MOUNT);
else if (id == POINT_DESPAWN)
{
switch (m_uiWave)
me->Dismount();
me->DespawnOrUnsummon();
}
return;
}
switch (id)
{
case POINT_STAND_UP:
Talk(SAY_BREAKOUT1);
break;
case POINT_BOX:
me->SetStandState(UNIT_STAND_STATE_KNEEL);
scheduler.Schedule(5s, [this](TaskContext context)
{
switch (context.GetRepeatCounter())
{
case 0:
Talk(SAY_BREAKOUT3);
SummonAcolyte(3);
m_uiWave_Timer = 20000;
// Shouldn't actually be spawned at this point, but no way to send his yells otherwise?
if (Creature* valroth = me->SummonCreature(NPC_HIGH_INQUISITOR_VALROTH, 1640.8596f, -6030.834f, 134.82211f, 4.606426715850830078f, TEMPSUMMON_MANUAL_DESPAWN))
{
_valrothGUID = valroth->GetGUID();
valroth->AI()->Talk(SAY_VALROTH_WAVE1);
valroth->SetReactState(REACT_PASSIVE);
}
if (Creature* acolyte = me->SummonCreature(NPC_CRIMSON_ACOLYTE, 1640.6724f, -6032.0527f, 134.82213f, 4.654973506927490234f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
acolyte->GetMotionMaster()->MovePath(NPC_CRIMSON_ACOLYTE * 10, false);
if (Creature* acolyte = me->SummonCreature(NPC_CRIMSON_ACOLYTE, 1641.0055f, -6031.893f, 134.82211f, 0.401425719261169433f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
acolyte->GetMotionMaster()->MovePath((NPC_CRIMSON_ACOLYTE + 1) * 10, false);
if (Creature* acolyte = me->SummonCreature(NPC_CRIMSON_ACOLYTE, 1639.7053f, -6031.7373f, 134.82213f, 2.443460941314697265f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
acolyte->GetMotionMaster()->MovePath((NPC_CRIMSON_ACOLYTE + 2) * 10, false);
break;
case 1:
Talk(SAY_BREAKOUT4);
SummonAcolyte(3);
m_uiWave_Timer = 20000;
if (Creature* valroth = ObjectAccessor::GetCreature(*me, _valrothGUID))
valroth->AI()->Talk(SAY_VALROTH_WAVE2);
if (Creature* acolyte = me->SummonCreature(NPC_CRIMSON_ACOLYTE, 1640.7958f, -6030.307f, 134.82211f, 4.65355682373046875f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
acolyte->GetMotionMaster()->MovePath((NPC_CRIMSON_ACOLYTE + 3) * 10, false);
if (Creature* acolyte = me->SummonCreature(NPC_CRIMSON_ACOLYTE, 1641.7305f, -6030.751f, 134.82211f, 6.143558979034423828f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
acolyte->GetMotionMaster()->MovePath((NPC_CRIMSON_ACOLYTE + 4) * 10, false);
if (Creature* acolyte = me->SummonCreature(NPC_CRIMSON_ACOLYTE, 1639.4657f, -6030.404f, 134.82211f, 4.502949237823486328f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
acolyte->GetMotionMaster()->MovePath((NPC_CRIMSON_ACOLYTE + 5) * 10, false);
break;
case 2:
Talk(SAY_BREAKOUT5);
SummonAcolyte(4);
m_uiWave_Timer = 20000;
if (Creature* valroth = ObjectAccessor::GetCreature(*me, _valrothGUID))
valroth->AI()->Talk(SAY_VALROTH_WAVE3);
if (Creature* acolyte = me->SummonCreature(NPC_CRIMSON_ACOLYTE, 1641.3405f, -6031.436f, 134.82211f, 4.612849712371826171f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
acolyte->GetMotionMaster()->MovePath((NPC_CRIMSON_ACOLYTE + 6) * 10, false);
if (Creature* acolyte = me->SummonCreature(NPC_CRIMSON_ACOLYTE, 1642.0404f, -6030.3843f, 134.82211f, 1.378810048103332519f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
acolyte->GetMotionMaster()->MovePath((NPC_CRIMSON_ACOLYTE + 7) * 10, false);
if (Creature* acolyte = me->SummonCreature(NPC_CRIMSON_ACOLYTE, 1640.1162f, -6029.7817f, 134.82211f, 5.707226753234863281f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
acolyte->GetMotionMaster()->MovePath((NPC_CRIMSON_ACOLYTE + 8) * 10, false);
if (Creature* acolyte = me->SummonCreature(NPC_CRIMSON_ACOLYTE, 1640.9948f, -6029.8027f, 134.82211f, 1.605702877044677734f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
acolyte->GetMotionMaster()->MovePath((NPC_CRIMSON_ACOLYTE + 9) * 10, false);
break;
case 3:
Talk(SAY_BREAKOUT6);
me->SummonCreature(NPC_HIGH_INQUISITOR_VALROTH, 1642.329f, -6045.818f, 127.583f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
m_uiWave_Timer = 1000;
break;
case 4:
me->m_Events.AddEventAtOffset([this]
{
Creature* temp = ObjectAccessor::GetCreature(*me, m_uiValrothGUID);
Talk(EMOTE_KOLTIRA_COLLAPSES, me);
me->KillSelf();
if (!temp || !temp->IsAlive())
{
Talk(SAY_BREAKOUT8);
m_uiWave_Timer = 5000;
}
else
{
// xinef: despawn check
Player* player = GetPlayerForEscort();
if (!player || me->GetDistance(player) > 60.0f)
{
me->DespawnOrUnsummon();
return;
}
if (Creature* valroth = ObjectAccessor::GetCreature(*me, _valrothGUID))
valroth->DespawnOrUnsummon();
}, 2min);
m_uiWave_Timer = 2500;
return; //return, we don't want m_uiWave to increment now
}
break;
if (Creature* valroth = ObjectAccessor::GetCreature(*me, _valrothGUID))
{
valroth->AI()->Talk(SAY_VALROTH_AGGRO);
valroth->SetReactState(REACT_AGGRESSIVE);
valroth->GetMotionMaster()->MovePath(NPC_HIGH_INQUISITOR_VALROTH * 10, false);
}
case 5:
Talk(SAY_BREAKOUT9);
me->RemoveAurasDueToSpell(SPELL_ANTI_MAGIC_ZONE);
// i do not know why the armor will also be removed
m_uiWave_Timer = 2500;
return;
default:
break;
case 6:
Talk(SAY_BREAKOUT10);
SetEscortPaused(false);
break;
}
}
++m_uiWave;
}
else
m_uiWave_Timer -= uiDiff;
context.Repeat(20s);
});
scheduler.Schedule(3s, [this](TaskContext)
{
DoCastSelf(SPELL_KOLTIRA_TRANSFORM);
me->LoadEquipment();
});
break;
case POINT_ANTI_MAGIC_ZONE:
me->SetStandState(UNIT_STAND_STATE_KNEEL);
Talk(SAY_BREAKOUT2);
DoCastSelf(SPELL_ANTI_MAGIC_ZONE);
break;
}
}
void SummonedCreatureDies(Creature* summon, Unit*) override
{
if (summon->GetEntry() == NPC_HIGH_INQUISITOR_VALROTH)
{
me->m_Events.KillAllEvents(false);
me->RemoveAurasDueToSpell(SPELL_ANTI_MAGIC_ZONE);
me->SetStandState(UNIT_STAND_STATE_STAND);
Talk(SAY_BREAKOUT8, 3s);
Talk(SAY_BREAKOUT9, 8s);
scheduler.Schedule(11s, [this](TaskContext)
{
Talk(SAY_BREAKOUT10);
SetInvincibility(true);
me->SetReactState(REACT_PASSIVE);
me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
me->GetMotionMaster()->MovePath((me->GetEntry() + 1) * 10, false);
});
}
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
}
private:
ObjectGuid _valrothGUID;
};
};
@ -504,98 +517,6 @@ public:
};
};
//Koltira & Valroth- Breakout
enum valroth
{
//SAY_VALROTH1 = 0, Unused
SAY_VALROTH_AGGRO = 1,
SAY_VALROTH_RAND = 2,
SAY_VALROTH_DEATH = 3,
SPELL_RENEW = 38210,
SPELL_INQUISITOR_PENANCE = 52922,
SPELL_VALROTH_SMITE = 52926,
SPELL_SUMMON_VALROTH_REMAINS = 52929
};
class npc_high_inquisitor_valroth : public CreatureScript
{
public:
npc_high_inquisitor_valroth() : CreatureScript("npc_high_inquisitor_valroth") { }
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_high_inquisitor_valrothAI(creature);
}
struct npc_high_inquisitor_valrothAI : public ScriptedAI
{
npc_high_inquisitor_valrothAI(Creature* creature) : ScriptedAI(creature) { }
uint32 uiRenew_timer;
uint32 uiInquisitor_Penance_timer;
uint32 uiValroth_Smite_timer;
void Reset() override
{
uiRenew_timer = 1000;
uiInquisitor_Penance_timer = 2000;
uiValroth_Smite_timer = 1000;
}
void JustEngagedWith(Unit* who) override
{
Talk(SAY_VALROTH_AGGRO);
DoCast(who, SPELL_VALROTH_SMITE);
}
void UpdateAI(uint32 diff) override
{
if (uiRenew_timer <= diff)
{
Shout();
DoCast(me, SPELL_RENEW);
uiRenew_timer = urand(1000, 6000);
}
else uiRenew_timer -= diff;
if (uiInquisitor_Penance_timer <= diff)
{
Shout();
DoCastVictim(SPELL_INQUISITOR_PENANCE);
uiInquisitor_Penance_timer = urand(2000, 7000);
}
else uiInquisitor_Penance_timer -= diff;
if (uiValroth_Smite_timer <= diff)
{
Shout();
DoCastVictim(SPELL_VALROTH_SMITE);
uiValroth_Smite_timer = urand(1000, 6000);
}
else uiValroth_Smite_timer -= diff;
DoMeleeAttackIfReady();
}
void Shout()
{
if (rand() % 100 < 15)
Talk(SAY_VALROTH_RAND);
}
void JustDied(Unit* killer) override
{
Talk(SAY_VALROTH_DEATH);
if (killer)
{
killer->CastSpell(me, SPELL_SUMMON_VALROTH_REMAINS, true);
}
}
};
};
/*######
## npc_a_special_surprise
######*/
@ -785,6 +706,5 @@ void AddSC_the_scarlet_enclave_c2()
new npc_crusade_persuaded();
new npc_scarlet_courier();
new npc_koltira_deathweaver();
new npc_high_inquisitor_valroth();
new npc_a_special_surprise();
}

View File

@ -121,7 +121,7 @@ enum LightOfDawnEncounter
EVENT_SPELL_DEATH_STRIKE,
EVENT_SPELL_DEATH_EMBRACE,
EVENT_SPELL_UNHOLY_BLIGHT,
EVENT_SPELL_TALK,
EVENT_SPELL_DARION_MOD_DAMAGE,
// Positioning
EVENT_FINISH_FIGHT_1,
EVENT_FINISH_FIGHT_2,
@ -253,6 +253,7 @@ enum LightOfDawnSpells
SPELL_DEATH_EMBRACE = 53635,
SPELL_ICY_TOUCH1 = 49723,
SPELL_UNHOLY_BLIGHT = 53640,
SPELL_DARION_MOD_DAMAGE = 53645,
// Outro
SPELL_THE_LIGHT_OF_DAWN = 53658,
@ -524,7 +525,7 @@ public:
events.RescheduleEvent(EVENT_SPELL_DEATH_STRIKE, 8000);
events.RescheduleEvent(EVENT_SPELL_DEATH_EMBRACE, 5000);
events.RescheduleEvent(EVENT_SPELL_UNHOLY_BLIGHT, 10000);
events.RescheduleEvent(EVENT_SPELL_TALK, 10000);
events.RescheduleEvent(EVENT_SPELL_DARION_MOD_DAMAGE, 500);
}
void Reset() override
@ -1146,23 +1147,24 @@ public:
{
case EVENT_SPELL_ANTI_MAGIC_ZONE:
DoCast(me, SPELL_ANTI_MAGIC_ZONE1);
events.RescheduleEvent(eventId, 25s, 30s);
events.RescheduleEvent(eventId, 30s, 45s);
break;
case EVENT_SPELL_DEATH_STRIKE:
DoCastVictim(SPELL_DEATH_STRIKE);
events.RescheduleEvent(eventId, 5s, 10s);
events.RescheduleEvent(eventId, 5s, 35s);
break;
case EVENT_SPELL_DEATH_EMBRACE:
DoCastVictim(SPELL_DEATH_EMBRACE);
events.RescheduleEvent(eventId, 15s, 20s);
events.RescheduleEvent(eventId, 45s, 60s);
break;
case EVENT_SPELL_UNHOLY_BLIGHT:
DoCast(me, SPELL_UNHOLY_BLIGHT);
events.RescheduleEvent(eventId, 60s);
break;
case EVENT_SPELL_TALK:
case EVENT_SPELL_DARION_MOD_DAMAGE:
DoCast(me, SPELL_DARION_MOD_DAMAGE);
Talk(SAY_LIGHT_OF_DAWN09);
events.RescheduleEvent(eventId, 15s, 20s);
events.RescheduleEvent(eventId, 15s, 25s);
break;
}
@ -1215,9 +1217,106 @@ class spell_chapter5_rebuke : public SpellScript
}
};
// 58552 - Return to Orgrimmar
// 58533 - Return to Stormwind
enum ReturnToCapital
{
SPELL_RETURN_TO_ORGRIMMAR_APPLE = 58509,
SPELL_RETURN_TO_ORGRIMMAR_BANANA = 58513,
SPELL_RETURN_TO_ORGRIMMAR_SPIT = 58520,
EMOTE_THROW_APPLE = 2,
EMOTE_THROW_BANANA = 3,
EMOTE_THROW_SPIT = 4,
SAY_INSULT_TO_DK = 5,
NPC_SW_GUARD = 68,
NPC_ROYAL_GUARD = 1756,
NPC_CITY_PATROLLER = 1976,
NPC_OG_GUARD = 3296,
NPC_KOR_ELITE = 14304,
TEXT_BROADCAST_COWER = 31670 // "%s cowers in fear."
};
uint32 ReturnToCapitalSpells[3] =
{
58509, // Apple
58513, // Banana
58520 // Spit
};
class spell_chapter5_return_to_capital : public SpellScript
{
PrepareSpellScript(spell_chapter5_return_to_capital);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_RETURN_TO_ORGRIMMAR_APPLE, SPELL_RETURN_TO_ORGRIMMAR_BANANA, SPELL_RETURN_TO_ORGRIMMAR_SPIT});
}
void HandleHit(SpellEffIndex /*effIndex*/)
{
Creature* creature = GetHitUnit()->ToCreature();
Player* player = GetCaster()->ToPlayer();
uint32 spellId = GetSpellInfo()->Id;
if (!spellId || !creature || !player || player->IsGameMaster() || !player->IsAlive() || !creature->IsAlive() || creature->IsInCombat())
return;
if (creature->HasSpellCooldown(spellId))
return;
if (creature->GetEntry() == NPC_SW_GUARD || creature->GetEntry() == NPC_ROYAL_GUARD || creature->GetEntry() == NPC_CITY_PATROLLER || creature->GetEntry() == NPC_OG_GUARD || creature->GetEntry() == NPC_KOR_ELITE)
{
_emote = urand(2,4);
if (creature)
{
creature->PauseMovement(5000);
creature->SetTimedFacingToObject(player, 30000);
if (roll_chance_i(30))
{
creature->AI()->Talk(_emote, player);
creature->CastSpell(player, ReturnToCapitalSpells[_emote - 2]);
}
else
{
creature->AI()->Talk(SAY_INSULT_TO_DK, player);
creature->HandleEmoteCommand(RAND(EMOTE_ONESHOT_POINT,EMOTE_ONESHOT_RUDE));
}
}
}
/*/// @todo: This needs to be further investigated as there are some "guard" npcs, that have civilian flags and non guard npcs should also insult the dk.
else
if (creature->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN)
{
creature->HandleEmoteCommand(EMOTE_STATE_COWER); // from sniff, emote 431 for a while, then reset (with "%s cowers in fear." text)
creature->PlayDirectSound(14556); // from sniff
if (player)
{
LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex();
if (BroadcastText const* bct = sObjectMgr->GetBroadcastText(TEXT_BROADCAST_COWER))
creature->TextEmote(bct->GetText(loc_idx, creature->getGender()), creature);
}
}
*/
creature->AddSpellCooldown(spellId, 0, 30000);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_chapter5_return_to_capital::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY);
}
private:
uint8 _emote;
};
void AddSC_the_scarlet_enclave_c5()
{
new npc_highlord_darion_mograine();
RegisterSpellScript(spell_chapter5_light_of_dawn_aura);
RegisterSpellScript(spell_chapter5_rebuke);
RegisterSpellScript(spell_chapter5_return_to_capital);
}

View File

@ -1727,6 +1727,16 @@ class spell_dk_pestilence : public SpellScript
{
PrepareSpellScript(spell_dk_pestilence);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo(
{
SPELL_DK_GLYPH_OF_DISEASE,
SPELL_DK_BLOOD_PLAGUE,
SPELL_DK_FROST_FEVER
});
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
@ -1743,11 +1753,38 @@ class spell_dk_pestilence : public SpellScript
// And spread them on target
// Blood Plague
if (target->GetAura(SPELL_DK_BLOOD_PLAGUE, caster->GetGUID()))
caster->CastSpell(hitUnit, SPELL_DK_BLOOD_PLAGUE, true);
if (Aura* disOld = target->GetAura(SPELL_DK_BLOOD_PLAGUE, caster->GetGUID()))
if (AuraEffect* effOld = disOld->GetEffect(EFFECT_0))
{
float pctMods = effOld->GetPctMods();
float crit = effOld->GetCritChance();
caster->CastSpell(hitUnit, SPELL_DK_BLOOD_PLAGUE, true);
if (Aura* disNew = hitUnit->GetAura(SPELL_DK_BLOOD_PLAGUE, caster->GetGUID()))
if (AuraEffect* effNew = disNew->GetEffect(EFFECT_0))
{
effNew->SetPctMods(pctMods);
effNew->SetCritChance(crit);
effNew->SetAmount(effNew->CalculateAmount(effNew->GetCaster()));
}
}
// Frost Fever
if (target->GetAura(SPELL_DK_FROST_FEVER, caster->GetGUID()))
caster->CastSpell(hitUnit, SPELL_DK_FROST_FEVER, true);
if (Aura* disOld = target->GetAura(SPELL_DK_FROST_FEVER, caster->GetGUID()))
if (AuraEffect* effOld = disOld->GetEffect(EFFECT_0))
{
float pctMods = effOld->GetPctMods();
float crit = effOld->GetCritChance();
caster->CastSpell(hitUnit, SPELL_DK_FROST_FEVER, true);
if (Aura* disNew = hitUnit->GetAura(SPELL_DK_FROST_FEVER, caster->GetGUID()))
if (AuraEffect* effNew = disNew->GetEffect(EFFECT_0))
{
effNew->SetPctMods(pctMods);
effNew->SetCritChance(crit);
effNew->SetAmount(effNew->CalculateAmount(effNew->GetCaster()));
}
}
}
}

View File

@ -391,8 +391,8 @@ enum SpellAttr0 : uint32
SPELL_ATTR0_HELD_ITEM_ONLY = 0x00000200, // TITLE Auto-target mainhand item (client only) DESCRIPTION Client will automatically select main-hand item as cast target
SPELL_ATTR0_ON_NEXT_SWING = 0x00000400, // TITLE On next melee (type 2) DESCRIPTION Both "on next swing" attributes have identical handling in server & client
SPELL_ATTR0_WEARER_CASTS_PROC_TRIGGER = 0x00000800, // TITLE Unknown attribute 11@Attr0
SPELL_ATTR0_SERVER_ONLY = 0x00001000, // TITLE Only usable during daytime (unused)
SPELL_ATTR0_ALLOW_ITEM_SPELL_IN_PVP = 0x00002000, // TITLE Only usable during nighttime (unused)
SPELL_ATTR0_SERVER_ONLY = 0x00001000, // TITLE Unused attribute 12@Attr0 DESCRIPTION not set in 3.3.5a
SPELL_ATTR0_ALLOW_ITEM_SPELL_IN_PVP = 0x00002000, // TITLE Only usable during nighttime
SPELL_ATTR0_ONLY_INDOORS = 0x00004000, // TITLE Only usable indoors
SPELL_ATTR0_ONLY_OUTDOORS = 0x00008000, // TITLE Only usable outdoors
SPELL_ATTR0_NOT_SHAPESHIFTED = 0x00010000, // TITLE Not usable while shapeshifted
@ -461,14 +461,14 @@ enum SpellAttr2 : uint32
SPELL_ATTR2_AUTO_REPEAT = 0x00000020, // TITLE Ranged auto-attack spell
SPELL_ATTR2_CANNOT_CAST_ON_TAPPED = 0x00000040, // TITLE Cannot target others' tapped units DESCRIPTION Can only target untapped units, or those tapped by caster
SPELL_ATTR2_DO_NOT_REPORT_SPELL_FAILURE = 0x00000080, // TITLE Unknown attribute 7@Attr2
SPELL_ATTR2_INCLUDE_IN_ADVANCED_COMBAT_LOG = 0x00000100, // TITLE Unknown attribute 8@Attr2 DESCRIPTION not set in 3.0.3
SPELL_ATTR2_INCLUDE_IN_ADVANCED_COMBAT_LOG = 0x00000100, // TITLE Unused attribute 8@Attr2 DESCRIPTION not set in 3.3.5a
SPELL_ATTR2_ALWAYS_CAST_AS_UNIT = 0x00000200, // TITLE Unknown attribute 9@Attr2
SPELL_ATTR2_SPECIAL_TAMING_FLAG = 0x00000400, // TITLE Unknown attribute 10@Attr2 DESCRIPTION Related to taming?
SPELL_ATTR2_NO_TARGET_PER_SECOND_COST = 0x00000800, // TITLE Health Funnel
SPELL_ATTR2_CHAIN_FROM_CASTER = 0x00001000, // TITLE Unknown attribute 12@Attr2 DESCRIPTION Cleave, Heart Strike, Maul, Sunder Armor, Swipe
SPELL_ATTR2_ENCHANT_OWN_ITEM_ONLY = 0x00002000, // TITLE Enchant persists when entering arena
SPELL_ATTR2_ALLOW_WHILE_INVISIBLE = 0x00004000, // TITLE Unknown attribute 14@Attr2
SPELL_ATTR2_DO_NOT_CONSUME_IF_GAINED_DURING_CAST = 0x00008000, // TITLE Unknown attribute 15@Attr2 DESCRIPTION not set in 3.0.3
SPELL_ATTR2_DO_NOT_CONSUME_IF_GAINED_DURING_CAST = 0x00008000, // TITLE Unused attribute 15@Attr2 DESCRIPTION not set in 3.3.5a
SPELL_ATTR2_NO_ACTIVE_PETS = 0x00010000, // TITLE Tame Beast
SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS = 0x00020000, // TITLE Don't reset swing timer DESCRIPTION Does not reset melee/ranged autoattack timer on cast
SPELL_ATTR2_NO_JUMP_WHILE_CAST_PENDING = 0x00040000, // TITLE Requires dead pet
@ -511,8 +511,8 @@ enum SpellAttr3 : uint32
SPELL_ATTR3_ALWAYS_HIT = 0x00040000, // TITLE Ignore hit result DESCRIPTION Spell cannot miss, or be dodged/parried/blocked
SPELL_ATTR3_INSTANT_TARGET_PROCS = 0x00080000, // TITLE Cannot trigger spells during aura proc
SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD = 0x00100000, // TITLE Persists through death
SPELL_ATTR3_ONLY_PROC_OUTDOORS = 0x00200000, // TITLE Unknown attribute 21@Attr3
SPELL_ATTR3_CASTING_CANCELS_AUTOREPEAT = 0x00400000, // TITLE Requires equipped Wand (Mainline: Do Not Trigger Target Stand)
SPELL_ATTR3_ONLY_PROC_OUTDOORS = 0x00200000, // TITLE Unused attribute 21@Attr3 DESCRIPTION Not set in 3.3.5a
SPELL_ATTR3_CASTING_CANCELS_AUTOREPEAT = 0x00400000, // TITLE Unused attribute 22@Attr3 DESCRIPTION Not set in 3.3.5a
SPELL_ATTR3_NO_DAMAGE_HISTORY = 0x00800000, // TITLE Unknown attribute 23@Attr3
SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON = 0x01000000, // TITLE Requires offhand weapon
SPELL_ATTR3_TREAT_AS_PERIODIC = 0x02000000, // TITLE Treat as periodic effect
@ -571,7 +571,7 @@ enum SpellAttr5 : uint32
SPELL_ATTR5_TRIGGERS_CHANNELING = 0x00000010, // TITLE Unknown attribute 4@Attr5
SPELL_ATTR5_LIMIT_N = 0x00000020, // TITLE Single-target aura DESCRIPTION Remove previous application to another unit if applied
SPELL_ATTR5_IGNORE_AREA_EFFECT_PVP_CHECK = 0x00000040, // TITLE Unknown attribute 6@Attr5
SPELL_ATTR5_NOT_ON_PLAYER = 0x00000080, // TITLE Unknown attribute 7@Attr5
SPELL_ATTR5_NOT_ON_PLAYER = 0x00000080, // TITLE Cannot target players
SPELL_ATTR5_NOT_ON_PLAYER_CONTROLLED_NPC = 0x00000100, // TITLE Cannot target player controlled units but can target players
SPELL_ATTR5_EXTRA_INITIAL_PERIOD = 0x00000200, // TITLE Immediately do periodic tick on apply
SPELL_ATTR5_DO_NOT_DISPLAY_DURATION = 0x00000400, // TITLE Do not send aura duration to client
@ -650,8 +650,8 @@ enum SpellAttr7 : uint32
SPELL_ATTR7_ALLIANCE_SPECIFIC_SPELL = 0x00000200, // TITLE Alliance only
SPELL_ATTR7_DISPEL_REMOVES_CHARGES = 0x00000400, // TITLE Dispel/Spellsteal remove individual charges
SPELL_ATTR7_CAN_CAUSE_INTERRUPT = 0x00000800, // TITLE Only interrupt non-player casting
SPELL_ATTR7_CAN_CAUSE_SILENCE = 0x00001000, // TITLE Unknown attribute 12@Attr7 DESCRIPTION Not set in 3.2.2a.
SPELL_ATTR7_NO_UI_NOT_INTERRUPTIBLE = 0x00002000, // TITLE Unknown attribute 13@Attr7 DESCRIPTION Not set in 3.2.2a.
SPELL_ATTR7_CAN_CAUSE_SILENCE = 0x00001000, // TITLE Unused attribute 12@Attr7 DESCRIPTION Not set in 3.3.5a.
SPELL_ATTR7_NO_UI_NOT_INTERRUPTIBLE = 0x00002000, // TITLE Unused attribute 13@Attr7 DESCRIPTION Not set in 3.3.5a.
SPELL_ATTR7_RECAST_ON_RESUMMON = 0x00004000, // TITLE Unknown attribute 14@Attr7 DESCRIPTION Only 52150 (Raise Dead - Pet) spell.
SPELL_ATTR7_RESET_SWING_TIMER_AT_SPELL_START = 0x00008000, // TITLE Unknown attribute 15@Attr7 DESCRIPTION Exorcism - guaranteed crit vs families?
SPELL_ATTR7_ONLY_IN_SPELLBOOK_UNTIL_LEARNED = 0x00010000, // TITLE Can restore secondary power DESCRIPTION Only spells with this attribute can replenish a non-active power type
@ -659,7 +659,7 @@ enum SpellAttr7 : uint32
SPELL_ATTR7_ATTACK_ON_CHARGE_TO_UNIT = 0x00040000, // TITLE Has charge effect
SPELL_ATTR7_REPORT_SPELL_FAILURE_TO_UNIT_TARGET = 0x00080000, // TITLE Is zone teleport
SPELL_ATTR7_NO_CLIENT_FAIL_WHILE_STUNNED_FLEEING_CONFUSED = 0x00100000, // TITLE Unknown attribute 20@Attr7 DESCRIPTION Invulnerability related?
SPELL_ATTR7_RETAIN_COOLDOWN_THROUGH_LOAD = 0x00200000, // TITLE Unknown attribute 21@Attr7
SPELL_ATTR7_RETAIN_COOLDOWN_THROUGH_LOAD = 0x00200000, // TITLE Unused attribute 21@Attr7 DESCRPIPTION Not set in 3.3.5a
SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT = 0x00400000, // TITLE Ignore cold weather flying restriction DESCRIPTION Set for loaner mounts, allows them to be used despite lacking required flight skill
SPELL_ATTR7_NO_ATTACK_DODGE = 0x00800000, // TITLE Spell cannot be dodged 23@Attr7 DESCRIPTION Motivate, Mutilate, Shattering Throw
SPELL_ATTR7_NO_ATTACK_PARRY = 0x01000000, // TITLE Spell cannot be parried 24@Attr7 DESCRIPTION Motivate, Mutilate, Perform Speech, Shattering Throw