@@ -20,6 +20,8 @@ This tool compares your existing configuration files (`.conf`) with the latest d
|
|||||||
|
|
||||||
## How to Use
|
## How to Use
|
||||||
|
|
||||||
|
There are two ways to use this. You can either copy this file directly to your `/configs` folder, or enable `TOOL_CONFIG_MERGER` in CMake. Upon compiling your core, the file will be generated in the same location as your `/configs` folder.
|
||||||
|
|
||||||
### Interactive Mode (Default)
|
### Interactive Mode (Default)
|
||||||
|
|
||||||
1. **Run the script** in your configs directory:
|
1. **Run the script** in your configs directory:
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- DB update 2026_01_14_01 -> 2026_01_15_00
|
||||||
|
|
||||||
|
-- Edit Spell Timers (Watcher Narjil, Gashra, Silthik)
|
||||||
|
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE (`entry` IN (28729, 28730, 28731));
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28729) AND (`source_type` = 0) AND (`id` IN (0, 2, 3));
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28730) AND (`source_type` = 0) AND (`id` IN (0, 1, 2));
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28731) AND (`source_type` = 0) AND (`id` IN (0, 2, 3));
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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
|
||||||
|
(28729, 0, 0, 0, 0, 0, 100, 0, 18000, 20000, 30000, 40000, 0, 0, 11, 52524, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Watcher Narjil - In Combat - Cast \'Blinding Webs\''),
|
||||||
|
(28729, 0, 2, 0, 0, 0, 100, 0, 20000, 25000, 20000, 25000, 0, 0, 11, 52086, 0, 0, 0, 0, 0, 5, 30, 0, 0, 0, 0, 0, 0, 0, 'Watcher Narjil - In Combat - Cast \'Web Wrap\''),
|
||||||
|
(28729, 0, 3, 0, 0, 0, 100, 0, 24000, 28000, 24000, 28000, 0, 0, 11, 52469, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Watcher Narjil - In Combat - Cast \'Infected Bite\''),
|
||||||
|
(28730, 0, 0, 0, 0, 0, 100, 0, 8000, 10000, 12000, 20000, 0, 0, 11, 52470, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Watcher Gashra - In Combat - Cast \'Enrage\''),
|
||||||
|
(28730, 0, 1, 0, 0, 0, 100, 0, 15000, 18000, 16000, 18000, 0, 0, 11, 52086, 0, 0, 0, 0, 0, 5, 30, 0, 0, 0, 0, 0, 0, 0, 'Watcher Gashra - In Combat - Cast \'Web Wrap\''),
|
||||||
|
(28730, 0, 2, 0, 0, 0, 100, 0, 24000, 28000, 24000, 28000, 0, 0, 11, 52469, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Watcher Gashra - In Combat - Cast \'Infected Bite\''),
|
||||||
|
(28731, 0, 0, 0, 0, 0, 100, 0, 8000, 10000, 18000, 20000, 0, 0, 11, 52493, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Watcher Silthik - In Combat - Cast \'Poison Spray\''),
|
||||||
|
(28731, 0, 2, 0, 0, 0, 100, 0, 15000, 18000, 16000, 18000, 0, 0, 11, 52086, 0, 0, 0, 0, 0, 5, 30, 0, 0, 0, 0, 0, 0, 0, 'Watcher Silthik - In Combat - Cast \'Web Wrap\''),
|
||||||
|
(28731, 0, 3, 0, 0, 0, 100, 0, 24000, 28000, 24000, 28000, 0, 0, 11, 52469, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Watcher Silthik - In Combat - Cast \'Infected Bite\'');
|
||||||
@@ -0,0 +1,243 @@
|
|||||||
|
-- DB update 2026_01_15_00 -> 2026_01_16_00
|
||||||
|
-- Delete quest credit hack
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 30954) AND (`source_type` = 0) AND (`id` IN (3));
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 30956) AND (`source_type` = 0) AND (`id` IN (6));
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 30953) AND (`source_type` = 0) AND (`id` IN (3));
|
||||||
|
|
||||||
|
DELETE FROM `creature_template_addon` WHERE (`entry` = 31159);
|
||||||
|
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES
|
||||||
|
(31159, 0, 0, 0, 1, 0, 0, '');
|
||||||
|
|
||||||
|
DELETE FROM `creature_template_addon` WHERE (`entry` = 31324);
|
||||||
|
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES
|
||||||
|
(31324, 0, 0, 50331657, 0, 0, 0, '58269');
|
||||||
|
|
||||||
|
-- Phase if Stunning View (13160) has been completed
|
||||||
|
DELETE FROM `spell_area` WHERE `spell`=58863 AND `area`=4520 AND `quest_start`=13160;
|
||||||
|
INSERT INTO `spell_area` (`spell`, `area`, `quest_start`, `quest_end`, `aura_spell`, `racemask`, `gender`, `autocast`, `quest_start_status`, `quest_end_status`) VALUES
|
||||||
|
(58863, 4520, 13160, 0, 0, 0, 2, 1, 64, 0);
|
||||||
|
|
||||||
|
SET @GUID := 140200;
|
||||||
|
DELETE FROM `creature` WHERE `guid` BETWEEN @GUID AND @GUID+108 AND `phaseMask` IN (4) AND `areaId` IN (4520);
|
||||||
|
INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `MovementType`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES
|
||||||
|
-- possibly incomplete waypoints
|
||||||
|
(@GUID+0 , 31159, 571, 210, 4520, 4, 1, 6408.76, 1725.81, 508.601, 6.02139, 300, 0, 2, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
-- definitely has waypoints, but not enough data
|
||||||
|
(@GUID+1 , 31160, 571, 210, 4520, 4, 1, 6069.33, 1921.17, 632.578, 5.48977, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
-- static afaik
|
||||||
|
(@GUID+2 , 31161, 571, 210, 4520, 4, 1, 6559.47, 1563.07, 633.629, 5.00909, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+3 , 31223, 571, 210, 4520, 4, 0, 6470.11, 1724.35, 508.684, 2.37365, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+4 , 31224, 571, 210, 4520, 4, 0, 6564.62, 1612.34, 633.629, 1.85005, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+5 , 31225, 571, 210, 4520, 4, 0, 6055.63, 1954.17, 632.578, 3.42797, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
-- Lumbering Atrocity. Those in Phase 4 have different IDs from those in Phase 1
|
||||||
|
(@GUID+6 , 31226, 571, 210, 4520, 4, 0, 6444.69, 1972.97, 631.82, 3.38594, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+7 , 31226, 571, 210, 4520, 4, 0, 6447.33, 1952.95, 631.848, 3.19395, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+8 , 31226, 571, 210, 4520, 4, 0, 6366.38, 1970.99, 508.128, 3.33358, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+9 , 31226, 571, 210, 4520, 4, 0, 6371.61, 1933.05, 508.684, 3.22886, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+10 , 31226, 571, 210, 4520, 4, 0, 6523.95, 1943.55, 640.72, 4.08407, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+11 , 31226, 571, 210, 4520, 4, 0, 6433.1, 1895.42, 508.678, 4.11898, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+12 , 31226, 571, 210, 4520, 4, 0, 6456.81, 1881.75, 508.682, 3.9968, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+13 , 31226, 571, 210, 4520, 4, 0, 6531.53, 1874.53, 629.634, 4.64258, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+14 , 31226, 571, 210, 4520, 4, 0, 6431.99, 1812.84, 508.684, 3.4383, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+15 , 31226, 571, 210, 4520, 4, 0, 6555.41, 1876.79, 629.634, 4.62512, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+16 , 31226, 571, 210, 4520, 4, 0, 6432.28, 1788.37, 508.685, 3.14159, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+17 , 31226, 571, 210, 4520, 4, 0, 6382.83, 1777.58, 508.78, 0.767945, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+18 , 31226, 571, 210, 4520, 4, 0, 6389.62, 1751.7, 508.707, 0.15708, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+19 , 31226, 571, 210, 4520, 4, 0, 6326, 1926.51, 508.681, 0.20944, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+20 , 31226, 571, 210, 4520, 4, 0, 6319.5, 1964.06, 508.453, 0.349066, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+21 , 31226, 571, 210, 4520, 4, 0, 6243.68, 1944.27, 631.86, 0.226893, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+22 , 31226, 571, 210, 4520, 4, 0, 6246.83, 1923.25, 631.843, 0.296706, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+23 , 31226, 571, 210, 4520, 4, 0, 6282.74, 1768.32, 525.276, 0.418879, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+24 , 31226, 571, 210, 4520, 4, 0, 6285.05, 1739.98, 525.469, 6.26573, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss'),
|
||||||
|
(@GUID+25 , 31325, 571, 210, 4520, 4, 1, 6407.34, 1958.04, 631.298, 0.140488, 300, 10, 1, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+26 , 31325, 571, 210, 4520, 4, 1, 6361.6, 1932.71, 508.595, 1.69059, 300, 10, 1, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+27 , 31325, 571, 210, 4520, 4, 1, 6337.11, 1948.66, 507.983, 4.91094, 300, 10, 1, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+28 , 31325, 571, 210, 4520, 4, 1, 6434.97, 1839.88, 508.601, 0.92626, 300, 10, 1, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+29 , 31325, 571, 210, 4520, 4, 1, 6553.39, 1861.26, 629.716, 1.60466, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+30 , 31325, 571, 210, 4520, 4, 1, 6370.85, 1811.2, 508.601, 5.52566, 300, 10, 1, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+31 , 31325, 571, 210, 4520, 4, 1, 6417.08, 1881.77, 508.601, 3.21955, 300, 10, 1, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+32 , 31325, 571, 210, 4520, 4, 1, 6348.4, 1857.11, 508.601, 0.0470463, 300, 10, 1, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+33 , 31325, 571, 210, 4520, 4, 1, 6278.17, 1938.88, 631.367, 3.29251, 300, 10, 1, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+34 , 31325, 571, 210, 4520, 4, 1, 6116.33, 1923.28, 632.661, 6.10865, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+35 , 31325, 571, 210, 4520, 4, 1, 6112.24, 1906.16, 632.673, 6.26573, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+36 , 31325, 571, 210, 4520, 4, 1, 6259.45, 1808.62, 525.193, 4.829, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+37 , 31325, 571, 210, 4520, 4, 1, 6297.2, 1744.42, 525.193, 1.59532, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+38 , 31325, 571, 210, 4520, 4, 1, 6545.26, 1632.77, 632.545, 1.55334, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+39 , 31325, 571, 210, 4520, 4, 1, 6564.46, 1633.7, 632.528, 1.62316, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
(@GUID+40 , 31325, 571, 210, 4520, 4, 1, 6543.76, 1676.96, 629.716, 4.7391, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Movement'),
|
||||||
|
-- 31326 and 31327 Spar, not necessarily against the other entry, using factions 1847 and 1848
|
||||||
|
-- Reset behaviours have not been observed, so this will be skipped
|
||||||
|
(@GUID+41 , 31326, 571, 210, 4520, 4, 1, 6421, 1972.77, 631.884, 5.64803, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+42 , 31326, 571, 210, 4520, 4, 1, 6409.48, 1971.11, 631.886, 5.89921, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+43 , 31326, 571, 210, 4520, 4, 1, 6410.79, 1970.23, 631.859, 2.55091, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+44 , 31326, 571, 210, 4520, 4, 1, 6388.46, 1966.7, 631.854, 2.54847, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+45 , 31326, 571, 210, 4520, 4, 1, 6413.71, 1945.59, 631.885, 1.03795, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+46 , 31326, 571, 210, 4520, 4, 1, 6402.12, 1944.07, 631.88, 0.899389, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+47 , 31326, 571, 210, 4520, 4, 1, 6375.5, 1965.78, 631.88, 5.69264, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+48 , 31326, 571, 210, 4520, 4, 1, 6414.83, 1947.49, 631.842, 4.17954, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+49 , 31326, 571, 210, 4520, 4, 1, 6390.57, 1942.33, 631.88, 0.930497, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+50 , 31326, 571, 210, 4520, 4, 1, 6380.64, 1942.28, 631.845, 4.06142, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+51 , 31326, 571, 210, 4520, 4, 1, 6350.3, 1964.71, 631.734, 5.95226, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+52 , 31326, 571, 210, 4520, 4, 1, 6379.43, 1940.68, 631.88, 0.91983, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+53 , 31326, 571, 210, 4520, 4, 1, 6355.59, 1934.22, 631.734, 0.489751, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+54 , 31326, 571, 210, 4520, 4, 1, 6341.18, 1931.79, 631.734, 2.77019, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+55 , 31326, 571, 210, 4520, 4, 1, 6514.8, 1855.03, 632.15, 3.24635, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+56 , 31326, 571, 210, 4520, 4, 1, 6512.74, 1837.83, 632.15, 5.97852, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+57 , 31326, 571, 210, 4520, 4, 1, 6335.24, 1961.79, 631.734, 0.504561, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+58 , 31326, 571, 210, 4520, 4, 1, 6517.62, 1769.83, 632.15, 3.42335, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+59 , 31326, 571, 210, 4520, 4, 1, 6515.39, 1769.18, 632.15, 0.281759, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+60 , 31326, 571, 210, 4520, 4, 1, 6316.04, 1931.22, 631.879, 2.49931, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+61 , 31326, 571, 210, 4520, 4, 1, 6293.26, 1927.77, 631.881, 2.54989, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+62 , 31326, 571, 210, 4520, 4, 1, 6314.37, 1932.47, 631.842, 5.6409, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+63 , 31326, 571, 210, 4520, 4, 1, 6303.14, 1930.49, 631.849, 5.67288, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+64 , 31326, 571, 210, 4520, 4, 1, 6288.14, 1951.45, 631.849, 0.969426, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+65 , 31326, 571, 210, 4520, 4, 1, 6259.95, 1923.17, 631.88, 2.52023, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+66 , 31326, 571, 210, 4520, 4, 1, 6289.28, 1953.11, 631.886, 4.11102, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+67 , 31326, 571, 210, 4520, 4, 1, 6254.01, 1946.15, 631.857, 0.823756, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+68 , 31326, 571, 210, 4520, 4, 1, 6299.69, 1953.39, 631.853, 0.815526, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+69 , 31326, 571, 210, 4520, 4, 1, 6276.51, 1949.8, 631.85, 0.849777, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+70 , 31326, 571, 210, 4520, 4, 1, 6255.31, 1947.56, 631.884, 3.87463, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+71 , 31326, 571, 210, 4520, 4, 1, 6268.72, 1925.74, 631.84, 5.70028, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+72 , 31326, 571, 210, 4520, 4, 1, 6300.99, 1954.76, 631.882, 3.95712, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+73 , 31326, 571, 210, 4520, 4, 1, 6521.29, 1666.02, 632.15, 2.81779, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+74 , 31326, 571, 210, 4520, 4, 1, 6566, 1681.54, 629.634, 1.60577, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+75 , 31326, 571, 210, 4520, 4, 1, 6519.12, 1683.8, 632.15, 3.58536, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+76 , 31326, 571, 210, 4520, 4, 1, 6565.26, 1706.1, 629.634, 4.71059, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+77 , 31326, 571, 210, 4520, 4, 1, 6565.25, 1704.2, 629.634, 1.569, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+78 , 31327, 571, 210, 4520, 4, 1, 6422.62, 1971.57, 631.849, 2.50643, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+79 , 31327, 571, 210, 4520, 4, 1, 6398.41, 1969.36, 631.884, 5.76359, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+80 , 31327, 571, 210, 4520, 4, 1, 6399.89, 1968.52, 631.858, 2.62199, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+81 , 31327, 571, 210, 4520, 4, 1, 6387.05, 1967.65, 631.883, 5.8294, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+82 , 31327, 571, 210, 4520, 4, 1, 6426.32, 1949.09, 631.845, 4.12847, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+83 , 31327, 571, 210, 4520, 4, 1, 6403.49, 1945.79, 631.843, 4.04098, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+84 , 31327, 571, 210, 4520, 4, 1, 6391.79, 1943.95, 631.844, 4.07209, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+85 , 31327, 571, 210, 4520, 4, 1, 6376.98, 1964.78, 631.85, 2.42601, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+86 , 31327, 571, 210, 4520, 4, 1, 6425, 1947.09, 631.889, 0.986876, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+87 , 31327, 571, 210, 4520, 4, 1, 6352.29, 1964.02, 631.734, 2.81067, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+88 , 31327, 571, 210, 4520, 4, 1, 6357, 1934.97, 631.734, 3.63134, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+89 , 31327, 571, 210, 4520, 4, 1, 6336.87, 1962.69, 631.734, 3.64615, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+90 , 31327, 571, 210, 4520, 4, 1, 6339.55, 1932.42, 631.734, 5.91178, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+91 , 31327, 571, 210, 4520, 4, 1, 6512.19, 1854.76, 632.15, 0.104753, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+92 , 31327, 571, 210, 4520, 4, 1, 6514.94, 1837.14, 632.15, 2.83693, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+93 , 31327, 571, 210, 4520, 4, 1, 6514.89, 1751.23, 632.15, 5.98097, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+94 , 31327, 571, 210, 4520, 4, 1, 6517.42, 1750.44, 632.15, 2.83938, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+95 , 31327, 571, 210, 4520, 4, 1, 6291.56, 1928.92, 631.846, 5.69148, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+96 , 31327, 571, 210, 4520, 4, 1, 6312.67, 1956.56, 631.884, 3.9432, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+97 , 31327, 571, 210, 4520, 4, 1, 6311.42, 1955.28, 631.857, 0.80161, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+98 , 31327, 571, 210, 4520, 4, 1, 6282.06, 1925.98, 631.883, 2.56944, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+99 , 31327, 571, 210, 4520, 4, 1, 6304.76, 1929.36, 631.883, 2.42601, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+100, 31327, 571, 210, 4520, 4, 1, 6280.15, 1927.21, 631.845, 5.71103, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+101, 31327, 571, 210, 4520, 4, 1, 6277.85, 1951.31, 631.883, 3.99137, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+102, 31327, 571, 210, 4520, 4, 1, 6265, 1947.88, 631.846, 0.792263, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+103, 31327, 571, 210, 4520, 4, 1, 6270.51, 1924.56, 631.875, 2.55869, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+104, 31327, 571, 210, 4520, 4, 1, 6266.5, 1949.4, 631.877, 3.93386, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+105, 31327, 571, 210, 4520, 4, 1, 6258.28, 1924.36, 631.848, 5.66182, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+106, 31327, 571, 210, 4520, 4, 1, 6517.89, 1667.16, 632.15, 5.95938, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+107, 31327, 571, 210, 4520, 4, 1, 6565.9, 1684.19, 629.634, 4.74737, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring'),
|
||||||
|
(@GUID+108, 31327, 571, 210, 4520, 4, 1, 6516.86, 1682.72, 632.15, 0.443765, 300, 0, 0, 52237, 1, 'Phase Shift 2: Malykriss, WIP: Sparring');
|
||||||
|
|
||||||
|
-- Baelok
|
||||||
|
DELETE FROM `waypoint_data` WHERE `id` = @GUID*10;
|
||||||
|
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`) VALUES
|
||||||
|
(@GUID*10, 1, 6408.756, 1725.8109, 508.60083, 6.021385669708251953, 5000, 0), -- Guessed delay, incomplete path
|
||||||
|
(@GUID*10, 2, 6417.155, 1737.2736, 508.6008, NULL, 0, 0),
|
||||||
|
(@GUID*10, 3, 6430.235, 1737.4037, 508.60077, NULL, 0, 0);
|
||||||
|
|
||||||
|
DELETE FROM `creature_addon` WHERE `guid` = @GUID;
|
||||||
|
INSERT INTO `creature_addon` (`guid`, `path_id`, `bytes2`, `auras`) VALUES
|
||||||
|
(@GUID, @GUID*10, 1, NULL);
|
||||||
|
|
||||||
|
-- Worst part: Creatures from this phase are different id than those from phase 1, these are duplicated from what we already have because what I have on hand is basically the same thing
|
||||||
|
-- We can't really just upgrade their phases since then invisible players would be killing visible enemies
|
||||||
|
DELETE FROM `creature` WHERE `guid` BETWEEN @GUID+109 AND @GUID+172 AND `phaseMask` IN (4) AND `areaId` IN (4520);
|
||||||
|
INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `MovementType`, `Comment`) VALUES
|
||||||
|
(@GUID+109, 31321, 571, 210, 4520, 4, 1, 6467.82, 1811.16, 527.525, 5.67232, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+110, 31321, 571, 210, 4520, 4, 1, 6369.65, 1665.45, 555.737, 5.51524, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+111, 31321, 571, 210, 4520, 4, 1, 6311.05, 1824.67, 510.092, 5.42797, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+112, 31321, 571, 210, 4520, 4, 1, 6328.69, 1820.64, 509.913, 3.47321, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+113, 31321, 571, 210, 4520, 4, 1, 6371.53, 1748.72, 525.308, 5.28835, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+114, 31321, 571, 210, 4520, 4, 1, 6344.04, 1769.24, 525.375, 3.64774, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+115, 31321, 571, 210, 4520, 4, 1, 6355.53, 1764.52, 525.276, 4.76475, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+116, 31321, 571, 210, 4520, 4, 1, 6323.64, 1716.53, 525.551, 5.72468, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+117, 31321, 571, 210, 4520, 4, 1, 6323.45, 1731.48, 525.515, 6.23082, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+118, 31321, 571, 210, 4520, 4, 1, 6329.26, 1748.75, 525.276, 1.11701, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+119, 31321, 571, 210, 4520, 4, 1, 6360.59, 1736.24, 525.276, 4.13643, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+120, 31321, 571, 210, 4520, 4, 1, 6343.99, 1750.79, 525.739, 2.80998, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+121, 31321, 571, 210, 4520, 4, 1, 6333.84, 1766.47, 525.276, 5.02655, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+122, 31321, 571, 210, 4520, 4, 1, 6350.36, 1731.27, 525.276, 4.7822, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+123, 31321, 571, 210, 4520, 4, 1, 6322.36, 1765.4, 525.276, 0.523599, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+124, 31321, 571, 210, 4520, 4, 1, 6339.15, 1732.77, 525.276, 4.45059, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+125, 31321, 571, 210, 4520, 4, 1, 6334.4, 1717.4, 525.276, 1.79769, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+126, 31321, 571, 210, 4520, 4, 1, 6357.46, 1718.11, 525.276, 1.13446, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+127, 31321, 571, 210, 4520, 4, 1, 6361.38, 1751.44, 525.581, 2.77507, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+128, 31321, 571, 210, 4520, 4, 1, 6346.33, 1715.18, 525.276, 2.84489, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+129, 31320, 571, 210, 4520, 4, 0, 6461.65, 1811.79, 526.024, 1.28865, 300, 0, 2, 'WIP'),
|
||||||
|
(@GUID+130, 31320, 571, 210, 4520, 4, 0, 6353.97, 1712.15, 525.317, 2.58031, 300, 0, 2, 'WIP'),
|
||||||
|
(@GUID+131, 31322, 571, 210, 4520, 4, 0, 6504.06, 1844.93, 508.697, 0.10472, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+132, 31323, 571, 210, 4520, 4, 0, 6550.48, 1680.94, 629.651, 4.31997, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+133, 31323, 571, 210, 4520, 4, 0, 6595.72, 1843.64, 672.109, 3.07178, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+134, 31323, 571, 210, 4520, 4, 0, 6507.37, 1668.65, 632.067, 3.78131, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+135, 31323, 571, 210, 4520, 4, 0, 6546.2, 1834.68, 629.651, 1.10748, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+136, 31323, 571, 210, 4520, 4, 0, 6554.25, 1799.26, 629.651, 5.65689, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+137, 31323, 571, 210, 4520, 4, 0, 6509.91, 1839.99, 632.067, 5.25873, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+138, 31323, 571, 210, 4520, 4, 0, 6551.18, 1707.41, 629.651, 2.46494, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+139, 31323, 571, 210, 4520, 4, 0, 6546.51, 1767.71, 629.651, 4.41886, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+140, 31323, 571, 210, 4520, 4, 0, 6550.06, 1740.42, 629.651, 5.29382, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+141, 31323, 571, 210, 4520, 4, 0, 6227.2, 1877.56, 631.58, 5.79449, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+142, 31323, 571, 210, 4520, 4, 0, 6362.5, 1872.02, 508.726, 2.54692, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+143, 31323, 571, 210, 4520, 4, 0, 6420.17, 1862.48, 508.726, 3.89239, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+144, 31323, 571, 210, 4520, 4, 0, 6394.7, 1951.5, 631.629, 3.48342, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+145, 31323, 571, 210, 4520, 4, 0, 6271.5, 1935.59, 631.49, 3.18501, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+146, 31323, 571, 210, 4520, 4, 0, 6349.53, 1953.5, 631.751, 4.07865, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+147, 31323, 571, 210, 4520, 4, 0, 6305.2, 1934.09, 631.785, 5.88206, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+148, 31323, 571, 210, 4520, 4, 0, 6430.93, 1962.52, 631.463, 4.50238, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+149, 31323, 571, 210, 4520, 4, 0, 6402.65, 1952.95, 631.615, 3.48321, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+150, 31320, 571, 210, 4520, 4, 0, 6315.75, 1749.75, 525.318, 6.10961, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+151, 31320, 571, 210, 4520, 4, 0, 6347.47, 1653.42, 555.433, 0.048457, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+152, 31320, 571, 210, 4520, 4, 0, 6275.29, 1841.61, 523.07, 3.07487, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+153, 31320, 571, 210, 4520, 4, 0, 6319.39, 1767.24, 525.262, 5.62052, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+154, 31321, 571, 210, 4520, 4, 1, 6352.03, 1742.87, 525.318, 3.21439, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+155, 31320, 571, 210, 4520, 4, 0, 6319.64, 1728.98, 525.212, 1.56194, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+156, 31320, 571, 210, 4520, 4, 0, 6355.55, 1746.02, 525.318, 3.19243, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+157, 31320, 571, 210, 4520, 4, 0, 6291.59, 1703.77, 527.392, 0.936473, 300, 5, 1, 'WIP'),
|
||||||
|
(@GUID+158, 31324, 571, 210, 4520, 4, 0, 6420.04, 1687.55, 569.111, 1.48353, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+159, 31324, 571, 210, 4520, 4, 0, 6405.54, 1653.2, 579.39, 2.30383, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+160, 31324, 571, 210, 4520, 4, 0, 6400.35, 1643.93, 600.349, 2.33874, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+161, 31324, 571, 210, 4520, 4, 0, 6381.31, 1715.12, 546.677, 1.62316, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+162, 31324, 571, 210, 4520, 4, 0, 6208.67, 1793.61, 617.382, 0.593412, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+163, 31324, 571, 210, 4520, 4, 0, 6205.06, 1767.97, 619.533, 0.750492, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+164, 31324, 571, 210, 4520, 4, 0, 6241.39, 1706.26, 599.038, 0, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+165, 31324, 571, 210, 4520, 4, 0, 6472.36, 1677.34, 576.605, 2.35619, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+166, 31324, 571, 210, 4520, 4, 0, 6429.15, 1660.39, 595.302, 2.42601, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+167, 31324, 571, 210, 4520, 4, 0, 6216.64, 1785.2, 592.153, 0.750492, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+168, 31324, 571, 210, 4520, 4, 0, 6257.61, 1739.57, 581.576, 6.16101, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+169, 31324, 571, 210, 4520, 4, 0, 6238.85, 1729.19, 598.615, 0.017453, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+170, 31324, 571, 210, 4520, 4, 0, 6220.54, 1703.19, 627.699, 5.48033, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+171, 31324, 571, 210, 4520, 4, 0, 6385.01, 1703.41, 563.539, 1.50098, 300, 0, 0, 'WIP'),
|
||||||
|
(@GUID+172, 31324, 571, 210, 4520, 4, 0, 6235.08, 1762.35, 594.648, 0.628319, 300, 0, 0, 'WIP');
|
||||||
|
|
||||||
|
DELETE FROM `creature_addon` WHERE `guid` BETWEEN @GUID+109 AND @GUID+131;
|
||||||
|
INSERT INTO `creature_addon` (`guid`, `path_id`, `bytes2`, `emote`, `auras`) VALUES
|
||||||
|
(@GUID+109, 0, 1, 133, NULL),
|
||||||
|
(@GUID+110, 0, 1, 133, NULL),
|
||||||
|
(@GUID+111, 0, 1, 133, NULL),
|
||||||
|
(@GUID+112, 0, 1, 133, NULL),
|
||||||
|
(@GUID+113, 0, 1, 133, NULL),
|
||||||
|
(@GUID+114, 0, 1, 233, NULL),
|
||||||
|
(@GUID+115, 0, 1, 133, NULL),
|
||||||
|
(@GUID+116, 0, 1, 233, NULL),
|
||||||
|
(@GUID+117, 0, 1, 233, NULL),
|
||||||
|
(@GUID+118, 0, 1, 133, NULL),
|
||||||
|
(@GUID+119, 0, 1, 233, NULL),
|
||||||
|
(@GUID+120, 0, 1, 233, NULL),
|
||||||
|
(@GUID+121, 0, 1, 133, NULL),
|
||||||
|
(@GUID+122, 0, 1, 133, NULL),
|
||||||
|
(@GUID+123, 0, 1, 233, NULL),
|
||||||
|
(@GUID+124, 0, 1, 233, NULL),
|
||||||
|
(@GUID+125, 0, 1, 133, NULL),
|
||||||
|
(@GUID+126, 0, 1, 133, NULL),
|
||||||
|
(@GUID+127, 0, 1, 233, NULL),
|
||||||
|
(@GUID+128, 0, 1, 233, NULL),
|
||||||
|
(@GUID+129, 1242670, 1, 0, NULL),
|
||||||
|
(@GUID+130, 1242710, 1, 0, NULL),
|
||||||
|
(@GUID+131, 0, 1, 173, NULL);
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- DB update 2026_01_16_00 -> 2026_01_17_00
|
||||||
|
--
|
||||||
|
DELETE FROM `prospecting_loot_template` WHERE (`Entry` = 23424);
|
||||||
|
INSERT INTO `prospecting_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(23424, 21929, 0, 0, 0, 1, 1, 1, 2, 'Flame Spessarite'),
|
||||||
|
(23424, 23077, 0, 0, 0, 1, 1, 1, 2, 'Blood Garnet'),
|
||||||
|
(23424, 23079, 0, 0, 0, 1, 1, 1, 2, 'Deep Peridot'),
|
||||||
|
(23424, 23107, 0, 0, 0, 1, 1, 1, 2, 'Shadow Draenite'),
|
||||||
|
(23424, 23112, 0, 0, 0, 1, 1, 1, 2, 'Golden Draenite'),
|
||||||
|
(23424, 23117, 0, 0, 0, 1, 1, 1, 2, 'Azure Moonstone'),
|
||||||
|
(23424, 23436, 0, 4, 0, 1, 2, 1, 1, 'Living Ruby'),
|
||||||
|
(23424, 23437, 0, 4, 0, 1, 2, 1, 1, 'Talasite'),
|
||||||
|
(23424, 23438, 0, 4, 0, 1, 2, 1, 1, 'Star of Elune'),
|
||||||
|
(23424, 23439, 0, 4, 0, 1, 2, 1, 1, 'Noble Topaz'),
|
||||||
|
(23424, 23440, 0, 4, 0, 1, 2, 1, 1, 'Dawnstone'),
|
||||||
|
(23424, 23441, 0, 4, 0, 1, 2, 1, 1, 'Nightseye');
|
||||||
|
|
||||||
|
DELETE FROM `reference_loot_template` WHERE `Entry` = 1000;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
-- DB update 2026_01_17_00 -> 2026_01_17_01
|
||||||
|
--
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 26261) AND (`source_type` = 0) AND (`id` IN (0));
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(26261, 0, 0, 0, 8, 0, 100, 512, 47394, 0, 0, 0, 0, 0, 80, 2626100, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Grizzly Hills Giant - On Spellhit \'Kurun\'s Blessing\' - Run Script');
|
||||||
|
|
||||||
|
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 17) AND (`SourceGroup` = 0) AND (`SourceEntry` = 47394) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 29) AND (`ConditionTarget` = 1) AND (`ConditionValue1` = 26417) AND (`ConditionValue2` = 15) AND (`ConditionValue3` = 0);
|
||||||
|
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||||
|
(17, 0, 47394, 0, 0, 29, 1, 26417, 15, 0, 0, 0, 0, '', 'For Kurun\'s Blessing (47394) to have an effect the target Grizzly Hills Giant (26261) must be engaged with a Runed Giant (26417)');
|
||||||
|
|
||||||
|
UPDATE `creature` SET `spawntimesecs` = 120 WHERE `id1` = 26261;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2026_01_17_01 -> 2026_01_18_00
|
||||||
|
-- Sets "Spiritsbreath" to be 100 from 58 % drop rate for "Grumbald One-Eye"
|
||||||
|
UPDATE `creature_loot_template` SET `Chance` = 100 WHERE `Entry` = 26681 AND `Item` = 36740;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
-- DB update 2026_01_18_00 -> 2026_01_18_01
|
||||||
|
-- Add skinning loot table for creature 1933 (Sheep) to enable Ruined Leather Scraps, Wool Cloth, and Light Leather drops.
|
||||||
|
UPDATE `creature_template` SET `skinloot` = 1933 WHERE (`entry` = 1933);
|
||||||
|
|
||||||
|
DELETE FROM `skinning_loot_template` WHERE (`Entry` = 1933);
|
||||||
|
INSERT INTO `skinning_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(1933, 2934, 0, 55, 0, 1, 1, 1, 1, 'Ruined Leather Scraps'),
|
||||||
|
(1933, 2592, 0, 35, 0, 1, 1, 1, 1, 'Wool Cloth'),
|
||||||
|
(1933, 2318, 0, 10, 0, 1, 1, 1, 1, 'Light Leather');
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- DB update 2026_01_18_01 -> 2026_01_18_02
|
||||||
|
--
|
||||||
|
UPDATE `trainer_spell` SET `ReqSkillRank`=275 WHERE `SpellId`=29356;
|
||||||
|
UPDATE `trainer_spell` SET `ReqSkillRank`=230 WHERE `SpellId`=16153;
|
||||||
|
UPDATE `trainer_spell` SET `ReqSkillRank`=375 WHERE `SpellId`=29361;
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
-- DB update 2026_01_18_02 -> 2026_01_19_00
|
||||||
|
--
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24539);
|
||||||
|
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
|
||||||
|
(24539, 0, 0, 0, 0, 0, 100, 0, 3000, 6000, 15000, 22000, 0, 0, 11, 15091, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '\'Silvermoon\' Harry - In Combat - Cast \'Blast Wave\''),
|
||||||
|
(24539, 0, 1, 0, 0, 0, 100, 0, 2500, 4000, 4000, 5000, 0, 0, 11, 50183, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, '\'Silvermoon\' Harry - In Combat - Cast \'Scorch\''),
|
||||||
|
(24539, 0, 2, 0, 62, 0, 100, 0, 9010, 0, 0, 0, 0, 0, 80, 2453900, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - On Gossip Option "Taruk sent me to collect" Selected - Run Script: Attack'),
|
||||||
|
(24539, 0, 3, 4, 62, 0, 100, 0, 9011, 0, 0, 0, 0, 0, 56, 34115, 1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - On Gossip Option "Pay up, Harry!" Selected - Add Item \'"Silvermoon" Harry\'s Debt\' 1 Time'),
|
||||||
|
(24539, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - On Gossip Option 0 Selected - Close Gossip'),
|
||||||
|
(24539, 0, 5, 0, 2, 0, 100, 0, 0, 50, 30000, 30000, 0, 0, 80, 2453901, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - Between 0-50% Health - Run Script: Give Up Fight'),
|
||||||
|
(24539, 0, 7, 0, 32, 0, 100, 0, 0, 1000000, 15000, 15000, 0, 0, 42, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - On Damaged by Condition: Player in Quest - Set Invincibility'),
|
||||||
|
(24539, 0, 8, 0, 32, 0, 100, 0, 0, 1000000, 15000, 15000, 0, 0, 42, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - On Damaged by Condition: Player NOT in Quest - Remove Invincibility'),
|
||||||
|
(24539, 0, 9, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 240, 9010, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - Actionlist - Reset GossipMenuID to 9010'),
|
||||||
|
(24539, 0, 10, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 2, 1888, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - Actionlist - Reset Faction');
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2453900);
|
||||||
|
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
|
||||||
|
(2453900, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '\'Silvermoon\' Harry - On Script - Say Line 0'),
|
||||||
|
(2453900, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 83, 131, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - Actionlist - Remove Npc Flags Gossip & Questgiver & Vendor'),
|
||||||
|
(2453900, 9, 2, 0, 0, 0, 100, 0, 1200, 1200, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 21, 10, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - Actionlist - Start Attacking');
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` = 2453901);
|
||||||
|
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
|
||||||
|
(2453901, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - Actionlist - Say Line 1'),
|
||||||
|
(2453901, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 2, 1080, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - Actionlist - Set Faction Friendly'),
|
||||||
|
(2453901, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - Actionlist - Evade'),
|
||||||
|
(2453901, 9, 3, 0, 0, 0, 100, 0, 2400, 2400, 0, 0, 0, 0, 82, 131, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - Actionlist - Add Npc Flags Gossip & Questgiver & Vendor'),
|
||||||
|
(2453901, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 240, 9011, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - Actionlist - Change GossipMenuID to 9011'),
|
||||||
|
(2453901, 9, 5, 0, 0, 0, 100, 0, 60000, 60000, 0, 0, 0, 0, 240, 9010, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - Actionlist - Reset GossipMenuID to 9010'),
|
||||||
|
(2453901, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 2, 1888, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, '"Silvermoon" Harry - Actionlist - Reset Faction');
|
||||||
|
|
||||||
|
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 22) AND (`SourceEntry` = 24539) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 47);
|
||||||
|
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||||
|
(22, 8, 24539, 0, 0, 47, 0, 11464, 8, 0, 0, 0, 0, '', 'Only Play Script if Quest \'Gambling Debt\' (11464) is in progress'),
|
||||||
|
(22, 9, 24539, 0, 0, 47, 0, 11464, 8, 0, 1, 0, 0, '', 'Only Play Script if Quest \'Gambling Debt\' (11464) is in progress');
|
||||||
|
|
||||||
|
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 15) AND (`SourceGroup` IN (9010,9011)) AND (`ConditionTypeOrReference` = 2) AND (`ConditionValue1` = 34115);
|
||||||
|
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||||
|
(15, 9010, 0, 0, 0, 2, 0, 34115, 1, 0, 1, 0, 0, '', 'Only Show Gossip Option for quest Gambling Debt (11464) if player does not have Quest Item "Silvermoon" Harry\'s Debt (34115)'),
|
||||||
|
(15, 9011, 0, 0, 0, 2, 0, 34115, 1, 0, 1, 0, 0, '', 'Only Show Gossip Option for quest Gambling Debt (11464) if player does not have Quest Item "Silvermoon" Harry\'s Debt (34115)');
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
-- DB update 2026_01_19_00 -> 2026_01_19_01
|
||||||
|
|
||||||
|
-- Edit Spawn Time (Captured Rageclaw & Drakuru Shackles)
|
||||||
|
UPDATE `creature` SET `spawntimesecs` = 30 WHERE (`id1` IN (29700, 29686));
|
||||||
|
|
||||||
|
-- Remove C++ script and set SAI for Drakuru Shackles & Captured Rageclaw
|
||||||
|
UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE (`entry` IN (29700, 29686));
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 0) AND (`entryorguid` IN (29700, 29686));
|
||||||
|
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
|
||||||
|
(29700, 0, 0, 0, 8, 0, 100, 0, 54990, 0, 0, 0, 0, 0, 11, 55009, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Drakuru Shackles - On Spellhit \'Chains of the Scourge\' - Cast \'Chains of the Scourge\''),
|
||||||
|
(29700, 0, 1, 2, 8, 0, 100, 0, 55083, 0, 0, 0, 0, 0, 33, 29686, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Drakuru Shackles - On Spellhit \'Unlock Shackle\' - Quest Credit \'Captured Rageclaw\''),
|
||||||
|
(29700, 0, 2, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 223, 27, 0, 0, 0, 0, 0, 9, 29686, 0, 5, 1, 0, 0, 0, 0, 'Drakuru Shackles - On Spellhit \'Unlock Shackle\' - Do Action ID 27'),
|
||||||
|
(29686, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 0, 0, 90, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Rageclaw - On Respawn - Set Flag Standstate Kneel'),
|
||||||
|
(29686, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 54990, 0, 0, 0, 0, 0, 9, 29700, 0, 5, 1, 0, 0, 0, 0, 'Captured Rageclaw - On Respawn - Cast \'Chains of the Scourge\''),
|
||||||
|
(29686, 0, 2, 3, 72, 0, 100, 0, 27, 0, 0, 0, 0, 0, 91, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Rageclaw - On Action 27 Done - Remove FlagStandstate Kneel'),
|
||||||
|
(29686, 0, 3, 4, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Rageclaw - On Action 27 Done - Remove Aura \'all\''),
|
||||||
|
(29686, 0, 4, 5, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 55085, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Rageclaw - On Action 27 Done - Cast \'Unshackled!\''),
|
||||||
|
(29686, 0, 5, 6, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Rageclaw - On Action 27 Done - Say Line 0'),
|
||||||
|
(29686, 0, 6, 7, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 89, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Rageclaw - On Action 27 Done - Start Random Movement'),
|
||||||
|
(29686, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 12000, 30000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Captured Rageclaw - On Action 27 Done - Despawn In 12000 ms');
|
||||||
|
|
||||||
|
-- Set condition for Chains of the Scourge
|
||||||
|
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` = 54990) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 31) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 3) AND (`ConditionValue2` = 29700) AND (`ConditionValue3` = 0);
|
||||||
|
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||||
|
(13, 1, 54990, 0, 0, 31, 0, 3, 29700, 0, 0, 0, 0, '', 'Chains of the Scourge has Drakuru Shackles as implicit target');
|
||||||
|
|
||||||
|
-- Set condition for Unlock Shackle (prevent item spamming if Rageclaw is not chained/present)
|
||||||
|
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 3) AND (`SourceEntry` = 55083) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 1) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 54990) AND (`ConditionValue2` = 0) AND (`ConditionValue3` = 0);
|
||||||
|
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||||
|
(13, 3, 55083, 0, 0, 1, 0, 54990, 0, 0, 0, 0, 0, '', 'Unlock Shackle target must have Chains of the Scourge aura.');
|
||||||
@@ -0,0 +1,388 @@
|
|||||||
|
-- DB update 2026_01_19_01 -> 2026_01_20_00
|
||||||
|
-- Updates 3 vendors that spawn with arena season 5 to include missing items and correct costs.
|
||||||
|
DELETE FROM `npc_vendor` WHERE (`entry` IN (31863, 32407, 32405));
|
||||||
|
INSERT INTO `npc_vendor` (`entry`, `slot`, `item`, `maxcount`, `incrtime`, `ExtendedCost`, `VerifiedBuild`) VALUES
|
||||||
|
(31863, 0, 40784, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 40785, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 40786, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 40804, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 40805, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 40806, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 40823, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 40824, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 40825, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 40844, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 40845, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 40846, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 40862, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 40863, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 40864, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 40905, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 40926, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 40932, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 40938, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 40962, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 40990, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 40991, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 41000, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 41006, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 41012, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 41018, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 41026, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 41032, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 41037, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 41043, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 41080, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 41086, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 41136, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 41142, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 41150, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 41156, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 41198, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 41204, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 41210, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 41216, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 41274, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 41280, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 41286, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 41292, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 41297, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 41303, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 41309, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 41315, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 41320, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 41326, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 41649, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 41654, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 41660, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 41666, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 41671, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 41677, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 41682, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 41714, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 41766, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 41772, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 41853, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 41858, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 41863, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 41868, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 41873, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 41914, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 41920, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 41926, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 41933, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 41939, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 41945, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 41951, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 41958, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 41964, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 41970, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 41992, 0, 0, 2464, 0),
|
||||||
|
(31863, 0, 41997, 0, 0, 2462, 0),
|
||||||
|
(31863, 0, 42004, 0, 0, 2465, 0),
|
||||||
|
(31863, 0, 42010, 0, 0, 2470, 0),
|
||||||
|
(31863, 0, 42016, 0, 0, 2463, 0),
|
||||||
|
(31863, 0, 42208, 0, 0, 2466, 0),
|
||||||
|
(31863, 0, 42227, 0, 0, 2467, 0),
|
||||||
|
(31863, 0, 42232, 0, 0, 2467, 0),
|
||||||
|
(31863, 0, 42237, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42242, 0, 0, 2466, 0),
|
||||||
|
(31863, 0, 42248, 0, 0, 2467, 0),
|
||||||
|
(31863, 0, 42255, 0, 0, 2467, 0),
|
||||||
|
(31863, 0, 42260, 0, 0, 2466, 0),
|
||||||
|
(31863, 0, 42265, 0, 0, 2467, 0),
|
||||||
|
(31863, 0, 42270, 0, 0, 2467, 0),
|
||||||
|
(31863, 0, 42275, 0, 0, 2466, 0),
|
||||||
|
(31863, 0, 42280, 0, 0, 2467, 0),
|
||||||
|
(31863, 0, 42285, 0, 0, 2466, 0),
|
||||||
|
(31863, 0, 42290, 0, 0, 2467, 0),
|
||||||
|
(31863, 0, 42317, 0, 0, 2460, 0),
|
||||||
|
(31863, 0, 42322, 0, 0, 2460, 0),
|
||||||
|
(31863, 0, 42327, 0, 0, 2460, 0),
|
||||||
|
(31863, 0, 42332, 0, 0, 2460, 0),
|
||||||
|
(31863, 0, 42346, 0, 0, 2466, 0),
|
||||||
|
(31863, 0, 42352, 0, 0, 2466, 0),
|
||||||
|
(31863, 0, 42362, 0, 0, 2460, 0),
|
||||||
|
(31863, 0, 42384, 0, 0, 2460, 0),
|
||||||
|
(31863, 0, 42390, 0, 0, 2460, 0),
|
||||||
|
(31863, 0, 42525, 0, 0, 2467, 0),
|
||||||
|
(31863, 0, 42531, 0, 0, 2467, 0),
|
||||||
|
(31863, 0, 42537, 0, 0, 2467, 0),
|
||||||
|
(31863, 0, 42450, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42485, 0, 0, 2460, 0),
|
||||||
|
(31863, 0, 42490, 0, 0, 2460, 0),
|
||||||
|
(31863, 0, 42495, 0, 0, 2460, 0),
|
||||||
|
(31863, 0, 42502, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42513, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42519, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42559, 0, 0, 2469, 0),
|
||||||
|
(31863, 0, 42564, 0, 0, 2469, 0),
|
||||||
|
(31863, 0, 42570, 0, 0, 2469, 0),
|
||||||
|
(31863, 0, 42578, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42583, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42588, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42597, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42602, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42607, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42614, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42620, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 42852, 0, 0, 2468, 0),
|
||||||
|
(31863, 0, 44419, 0, 0, 2460, 0),
|
||||||
|
(31863, 0, 44420, 0, 0, 2460, 0),
|
||||||
|
(31863, 0, 45706, 0, 0, 2596, 0),
|
||||||
|
(32407, 0, 40784, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 40785, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 40786, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 40804, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 40805, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 40806, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 40823, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 40824, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 40825, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 40844, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 40845, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 40846, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 40862, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 40863, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 40864, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 40905, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 40926, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 40932, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 40938, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 40962, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 40990, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 40991, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 41000, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 41006, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 41012, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 41018, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 41026, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 41032, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 41037, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 41043, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 41080, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 41086, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 41136, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 41142, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 41150, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 41156, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 41198, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 41204, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 41210, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 41216, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 41274, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 41280, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 41286, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 41292, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 41297, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 41303, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 41309, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 41315, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 41320, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 41326, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 41649, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 41654, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 41660, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 41666, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 41671, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 41677, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 41682, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 41714, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 41766, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 41772, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 41853, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 41858, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 41863, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 41868, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 41873, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 41914, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 41920, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 41926, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 41933, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 41939, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 41945, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 41951, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 41958, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 41964, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 41970, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 41992, 0, 0, 2464, 0),
|
||||||
|
(32407, 0, 41997, 0, 0, 2462, 0),
|
||||||
|
(32407, 0, 42004, 0, 0, 2465, 0),
|
||||||
|
(32407, 0, 42010, 0, 0, 2470, 0),
|
||||||
|
(32407, 0, 42016, 0, 0, 2463, 0),
|
||||||
|
(32407, 0, 42208, 0, 0, 2466, 0),
|
||||||
|
(32407, 0, 42227, 0, 0, 2467, 0),
|
||||||
|
(32407, 0, 42232, 0, 0, 2467, 0),
|
||||||
|
(32407, 0, 42237, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42242, 0, 0, 2466, 0),
|
||||||
|
(32407, 0, 42248, 0, 0, 2467, 0),
|
||||||
|
(32407, 0, 42255, 0, 0, 2467, 0),
|
||||||
|
(32407, 0, 42260, 0, 0, 2466, 0),
|
||||||
|
(32407, 0, 42265, 0, 0, 2467, 0),
|
||||||
|
(32407, 0, 42270, 0, 0, 2467, 0),
|
||||||
|
(32407, 0, 42275, 0, 0, 2466, 0),
|
||||||
|
(32407, 0, 42280, 0, 0, 2467, 0),
|
||||||
|
(32407, 0, 42285, 0, 0, 2466, 0),
|
||||||
|
(32407, 0, 42290, 0, 0, 2467, 0),
|
||||||
|
(32407, 0, 42317, 0, 0, 2460, 0),
|
||||||
|
(32407, 0, 42322, 0, 0, 2460, 0),
|
||||||
|
(32407, 0, 42327, 0, 0, 2460, 0),
|
||||||
|
(32407, 0, 42332, 0, 0, 2460, 0),
|
||||||
|
(32407, 0, 42346, 0, 0, 2466, 0),
|
||||||
|
(32407, 0, 42352, 0, 0, 2466, 0),
|
||||||
|
(32407, 0, 42362, 0, 0, 2460, 0),
|
||||||
|
(32407, 0, 42384, 0, 0, 2460, 0),
|
||||||
|
(32407, 0, 42390, 0, 0, 2460, 0),
|
||||||
|
(32407, 0, 42525, 0, 0, 2467, 0),
|
||||||
|
(32407, 0, 42531, 0, 0, 2467, 0),
|
||||||
|
(32407, 0, 42537, 0, 0, 2467, 0),
|
||||||
|
(32407, 0, 42450, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42485, 0, 0, 2460, 0),
|
||||||
|
(32407, 0, 42490, 0, 0, 2460, 0),
|
||||||
|
(32407, 0, 42495, 0, 0, 2460, 0),
|
||||||
|
(32407, 0, 42502, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42513, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42519, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42559, 0, 0, 2469, 0),
|
||||||
|
(32407, 0, 42564, 0, 0, 2469, 0),
|
||||||
|
(32407, 0, 42570, 0, 0, 2469, 0),
|
||||||
|
(32407, 0, 42578, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42583, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42588, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42597, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42602, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42607, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42614, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42620, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 42852, 0, 0, 2468, 0),
|
||||||
|
(32407, 0, 44419, 0, 0, 2460, 0),
|
||||||
|
(32407, 0, 44420, 0, 0, 2460, 0),
|
||||||
|
(32407, 0, 45706, 0, 0, 2596, 0),
|
||||||
|
(32405, 0, 40784, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 40785, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 40786, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 40804, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 40805, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 40806, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 40823, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 40824, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 40825, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 40844, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 40845, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 40846, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 40862, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 40863, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 40864, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 40905, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 40926, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 40932, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 40938, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 40962, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 40990, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 40991, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 41000, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 41006, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 41012, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 41018, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 41026, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 41032, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 41037, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 41043, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 41080, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 41086, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 41136, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 41142, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 41150, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 41156, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 41198, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 41204, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 41210, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 41216, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 41274, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 41280, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 41286, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 41292, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 41297, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 41303, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 41309, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 41315, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 41320, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 41326, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 41649, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 41654, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 41660, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 41666, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 41671, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 41677, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 41682, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 41714, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 41766, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 41772, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 41853, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 41858, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 41863, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 41868, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 41873, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 41914, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 41920, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 41926, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 41933, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 41939, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 41945, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 41951, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 41958, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 41964, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 41970, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 41992, 0, 0, 2464, 0),
|
||||||
|
(32405, 0, 41997, 0, 0, 2462, 0),
|
||||||
|
(32405, 0, 42004, 0, 0, 2465, 0),
|
||||||
|
(32405, 0, 42010, 0, 0, 2470, 0),
|
||||||
|
(32405, 0, 42016, 0, 0, 2463, 0),
|
||||||
|
(32405, 0, 42208, 0, 0, 2466, 0),
|
||||||
|
(32405, 0, 42227, 0, 0, 2467, 0),
|
||||||
|
(32405, 0, 42232, 0, 0, 2467, 0),
|
||||||
|
(32405, 0, 42237, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42242, 0, 0, 2466, 0),
|
||||||
|
(32405, 0, 42248, 0, 0, 2467, 0),
|
||||||
|
(32405, 0, 42255, 0, 0, 2467, 0),
|
||||||
|
(32405, 0, 42260, 0, 0, 2466, 0),
|
||||||
|
(32405, 0, 42265, 0, 0, 2467, 0),
|
||||||
|
(32405, 0, 42270, 0, 0, 2467, 0),
|
||||||
|
(32405, 0, 42275, 0, 0, 2466, 0),
|
||||||
|
(32405, 0, 42280, 0, 0, 2467, 0),
|
||||||
|
(32405, 0, 42285, 0, 0, 2466, 0),
|
||||||
|
(32405, 0, 42290, 0, 0, 2467, 0),
|
||||||
|
(32405, 0, 42317, 0, 0, 2460, 0),
|
||||||
|
(32405, 0, 42322, 0, 0, 2460, 0),
|
||||||
|
(32405, 0, 42327, 0, 0, 2460, 0),
|
||||||
|
(32405, 0, 42332, 0, 0, 2460, 0),
|
||||||
|
(32405, 0, 42346, 0, 0, 2466, 0),
|
||||||
|
(32405, 0, 42352, 0, 0, 2466, 0),
|
||||||
|
(32405, 0, 42362, 0, 0, 2460, 0),
|
||||||
|
(32405, 0, 42384, 0, 0, 2460, 0),
|
||||||
|
(32405, 0, 42390, 0, 0, 2460, 0),
|
||||||
|
(32405, 0, 42525, 0, 0, 2467, 0),
|
||||||
|
(32405, 0, 42531, 0, 0, 2467, 0),
|
||||||
|
(32405, 0, 42537, 0, 0, 2467, 0),
|
||||||
|
(32405, 0, 42450, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42485, 0, 0, 2460, 0),
|
||||||
|
(32405, 0, 42490, 0, 0, 2460, 0),
|
||||||
|
(32405, 0, 42495, 0, 0, 2460, 0),
|
||||||
|
(32405, 0, 42502, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42513, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42519, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42559, 0, 0, 2469, 0),
|
||||||
|
(32405, 0, 42564, 0, 0, 2469, 0),
|
||||||
|
(32405, 0, 42570, 0, 0, 2469, 0),
|
||||||
|
(32405, 0, 42578, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42583, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42588, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42597, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42602, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42607, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42614, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42620, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 42852, 0, 0, 2468, 0),
|
||||||
|
(32405, 0, 44419, 0, 0, 2460, 0),
|
||||||
|
(32405, 0, 44420, 0, 0, 2460, 0),
|
||||||
|
(32405, 0, 45706, 0, 0, 2596, 0);
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
-- DB update 2026_01_20_00 -> 2026_01_20_01
|
||||||
|
--
|
||||||
|
UPDATE `smart_scripts` SET `target_param2`=40 WHERE `entryorguid`=7669 AND `source_type`=0 AND `id`=3 AND `link`=0;
|
||||||
|
UPDATE `smart_scripts` SET `target_param2`=40 WHERE `entryorguid`=7670 AND `source_type`=0 AND `id`=3 AND `link`=0;
|
||||||
|
UPDATE `smart_scripts` SET `target_param2`=40 WHERE `entryorguid`=7668 AND `source_type`=0 AND `id`=3 AND `link`=0;
|
||||||
|
UPDATE `smart_scripts` SET `target_param2`=40 WHERE `entryorguid`=7671 AND `source_type`=0 AND `id`=3 AND `link`=0;
|
||||||
|
|
||||||
|
UPDATE `smart_scripts` SET `target_param2`=40 WHERE `entryorguid`=141812 AND `source_type`=1 AND `id`=0 AND `link`=0;
|
||||||
|
UPDATE `smart_scripts` SET `target_param2`=40 WHERE `entryorguid`=141857 AND `source_type`=1 AND `id`=0 AND `link`=0;
|
||||||
|
UPDATE `smart_scripts` SET `target_param2`=40 WHERE `entryorguid`=141858 AND `source_type`=1 AND `id`=0 AND `link`=0;
|
||||||
|
UPDATE `smart_scripts` SET `target_param2`=40 WHERE `entryorguid`=141859 AND `source_type`=1 AND `id`=0 AND `link`=0;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- DB update 2026_01_20_01 -> 2026_01_20_02
|
||||||
|
--
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 6492) AND (`source_type` = 0) AND (`id` IN (17, 18));
|
||||||
|
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
|
||||||
|
(6492, 0, 17, 18, 7, 0, 100, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Rift Spawn - On Evade - Say Line 1'),
|
||||||
|
(6492, 0, 18, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 1200, 10, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Rift Spawn - On Evade - Despawn In 1200 ms');
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
-- DB update 2026_01_20_02 -> 2026_01_20_03
|
||||||
|
--
|
||||||
|
DELETE FROM `linked_respawn` WHERE `linkedGuid` = 126663 AND `linkType` = 0;
|
||||||
|
INSERT INTO `linked_respawn` (`guid`, `linkedGuid`, `linkType`) VALUES
|
||||||
|
(126619, 126663, 0),
|
||||||
|
(126620, 126663, 0),
|
||||||
|
(126621, 126663, 0),
|
||||||
|
(126622, 126663, 0),
|
||||||
|
(126623, 126663, 0),
|
||||||
|
(126624, 126663, 0),
|
||||||
|
(126625, 126663, 0),
|
||||||
|
(126626, 126663, 0),
|
||||||
|
(126627, 126663, 0),
|
||||||
|
(126628, 126663, 0),
|
||||||
|
(126629, 126663, 0),
|
||||||
|
(126630, 126663, 0),
|
||||||
|
(126631, 126663, 0),
|
||||||
|
(126632, 126663, 0),
|
||||||
|
(126633, 126663, 0),
|
||||||
|
(126634, 126663, 0),
|
||||||
|
(126635, 126663, 0),
|
||||||
|
(126636, 126663, 0),
|
||||||
|
(126637, 126663, 0),
|
||||||
|
(126638, 126663, 0),
|
||||||
|
(126639, 126663, 0),
|
||||||
|
(126640, 126663, 0),
|
||||||
|
(126641, 126663, 0),
|
||||||
|
(126642, 126663, 0),
|
||||||
|
(126643, 126663, 0),
|
||||||
|
(126644, 126663, 0),
|
||||||
|
(126645, 126663, 0),
|
||||||
|
(126646, 126663, 0),
|
||||||
|
(126647, 126663, 0),
|
||||||
|
(126648, 126663, 0),
|
||||||
|
(126649, 126663, 0),
|
||||||
|
(126650, 126663, 0),
|
||||||
|
(126651, 126663, 0),
|
||||||
|
(126652, 126663, 0),
|
||||||
|
(126653, 126663, 0),
|
||||||
|
(126654, 126663, 0),
|
||||||
|
(126655, 126663, 0),
|
||||||
|
(126656, 126663, 0),
|
||||||
|
(126657, 126663, 0),
|
||||||
|
(126658, 126663, 0),
|
||||||
|
(126659, 126663, 0),
|
||||||
|
(126660, 126663, 0),
|
||||||
|
(126661, 126663, 0),
|
||||||
|
(126662, 126663, 0);
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
-- DB update 2026_01_20_03 -> 2026_01_21_00
|
||||||
|
--
|
||||||
|
UPDATE `creature_loot_template` SET `Chance` = 100 WHERE `Entry` IN (24664, 24857) AND `Item` = 35008 AND `Reference` = 35008;
|
||||||
|
|
||||||
|
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 10) AND (`SourceGroup` = 35008) AND (`ConditionTypeOrReference` = 7) AND (`ConditionValue2` = 1);
|
||||||
|
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||||
|
(10, 35008, 35304, 0, 0, 7, 0, 755, 1, 0, 0, 0, 0, '', 'Player must have Jewelcrafting to loot BoP version of this Design'),
|
||||||
|
(10, 35008, 35305, 0, 0, 7, 0, 755, 1, 0, 0, 0, 0, '', 'Player must have Jewelcrafting to loot BoP version of this Design'),
|
||||||
|
(10, 35008, 35306, 0, 0, 7, 0, 755, 1, 0, 0, 0, 0, '', 'Player must have Jewelcrafting to loot BoP version of this Design'),
|
||||||
|
(10, 35008, 35307, 0, 0, 7, 0, 755, 1, 0, 0, 0, 0, '', 'Player must have Jewelcrafting to loot BoP version of this Design'),
|
||||||
|
(10, 35008, 35297, 0, 0, 7, 0, 333, 1, 0, 0, 0, 0, '', 'Player must have Enchanting to loot BoP version of this Formula'),
|
||||||
|
(10, 35008, 35298, 0, 0, 7, 0, 333, 1, 0, 0, 0, 0, '', 'Player must have Enchanting to loot BoP version of this Formula'),
|
||||||
|
(10, 35008, 35299, 0, 0, 7, 0, 333, 1, 0, 0, 0, 0, '', 'Player must have Enchanting to loot BoP version of this Formula'),
|
||||||
|
(10, 35008, 35300, 0, 0, 7, 0, 165, 1, 0, 0, 0, 0, '', 'Player must have Leatherworking to loot BoP version of this Pattern'),
|
||||||
|
(10, 35008, 35301, 0, 0, 7, 0, 165, 1, 0, 0, 0, 0, '', 'Player must have Leatherworking to loot BoP version of this Pattern'),
|
||||||
|
(10, 35008, 35302, 0, 0, 7, 0, 165, 1, 0, 0, 0, 0, '', 'Player must have Leatherworking to loot BoP version of this Pattern'),
|
||||||
|
(10, 35008, 35303, 0, 0, 7, 0, 165, 1, 0, 0, 0, 0, '', 'Player must have Leatherworking to loot BoP version of this Pattern'),
|
||||||
|
(10, 35008, 35308, 0, 0, 7, 0, 197, 1, 0, 0, 0, 0, '', 'Player must have Tailoring to loot BoP version of this Pattern'),
|
||||||
|
(10, 35008, 35309, 0, 0, 7, 0, 197, 1, 0, 0, 0, 0, '', 'Player must have Tailoring to loot BoP version of this Pattern'),
|
||||||
|
(10, 35008, 35296, 0, 0, 7, 0, 164, 1, 0, 0, 0, 0, '', 'Player must have Blacksmithing to loot BoP version of these Plans'),
|
||||||
|
(10, 35008, 35294, 0, 0, 7, 0, 171, 1, 0, 0, 0, 0, '', 'Player must have Alchemy to loot BoP version of this Recipe'),
|
||||||
|
(10, 35008, 35295, 0, 0, 7, 0, 171, 1, 0, 0, 0, 0, '', 'Player must have Alchemy to loot BoP version of this Recipe'),
|
||||||
|
(10, 35008, 35310, 0, 0, 7, 0, 202, 1, 0, 0, 0, 0, '', 'Player must have Engineering to loot BoP version of this Schematic'),
|
||||||
|
(10, 35008, 35311, 0, 0, 7, 0, 202, 1, 0, 0, 0, 0, '', 'Player must have Engineering to loot BoP version of this Schematic');
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
-- DB update 2026_01_21_00 -> 2026_01_21_01
|
||||||
|
-- Just missing from the mob, as it should have one pair of pants for each type (cloth, leather, etc)
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` = 18681) AND (`Item` IN (31246));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(18681, 31246, 0, 0, 0, 1, 1, 1, 1, 'Coilfang Emissary - Nagahide Leggings');
|
||||||
|
|
||||||
|
-- Gruffscale Leggings: Appears to have been added in WotLK at some point, replacing an older "Boarhide Leggings" lvl 8 green. Due to that drop rates in Wowhead may be skewed towards lower than intended
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` = 6583) AND (`Item` IN (45052));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(6583, 45052, 0, 100, 0, 1, 0, 1, 1, 'Gruff - Gruffscale Leggings');
|
||||||
|
|
||||||
|
-- Dustbringer: Super rare fishing loot item (novelty blue-quality drop)
|
||||||
|
DELETE FROM `gameobject_loot_template` WHERE `Entry` IN (25662,25663,25664,25665,25668,25669,25670,25671,25673,25674) AND `Item` = 44505;
|
||||||
|
INSERT INTO `gameobject_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(25662, 44505, 0, 0.01, 0, 1, 0, 1, 1, 'Glacial Salmon School - Dustbringer'),
|
||||||
|
(25663, 44505, 0, 0.01, 0, 1, 0, 1, 1, 'Fangtooth Herring School - Dustbringer'),
|
||||||
|
(25664, 44505, 0, 0.01, 0, 1, 0, 1, 1, 'Dragonfin Angelfish School - Dustbringer'),
|
||||||
|
(25665, 44505, 0, 0.01, 0, 1, 0, 1, 1, 'Musselback Sculpin School - Dustbringer'),
|
||||||
|
(25668, 44505, 0, 0.01, 0, 1, 0, 1, 1, 'Imperial Manta Ray School - Dustbringer'),
|
||||||
|
(25669, 44505, 0, 0.01, 0, 1, 0, 1, 1, 'Borean Man O\' War School - Dustbringer'),
|
||||||
|
(25670, 44505, 0, 0.01, 0, 1, 0, 1, 1, 'Moonglow Cuttlefish School - Dustbringer'),
|
||||||
|
(25671, 44505, 0, 0.01, 0, 1, 0, 1, 1, 'Deep Sea Monsterbelly School - Dustbringer'),
|
||||||
|
(25673, 44505, 0, 0.01, 0, 1, 0, 1, 1, 'Nettlefish School - Dustbringer'),
|
||||||
|
(25674, 44505, 0, 0.01, 0, 1, 0, 1, 1, 'Glassfin Minnow School - Dustbringer');
|
||||||
|
|
||||||
|
-- Runed Ring: Apparently these two items are rare Zul'Farrak zone BoEs, but their item level is higher than others of its type, so the only creatures that can drop them are actually the final bosses of the dungeon
|
||||||
|
-- Ensure Spellshock Leggings and Runed Ring drop from the final Zul'Farrak bosses in a separate shared loot group
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` IN (8127, 7267)) AND (`Item` IN (9484, 862));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(8127, 9484, 0, 0.25, 0, 1, 2, 1, 1, 'Antu\'Sul - Spellshock Leggings'),
|
||||||
|
(8127, 862, 0, 0.25, 0, 1, 2, 1, 1, 'Antu\'sul - Runed Ring'),
|
||||||
|
(7267, 9484, 0, 0.25, 0, 1, 2, 1, 1, 'Chief Ukorz Sandscalp - Spellshock Leggings'),
|
||||||
|
(7267, 862, 0, 0.25, 0, 1, 2, 1, 1, 'Chief Ukorz Sandscalp - Runed Ring');
|
||||||
|
|
||||||
|
-- These seem to be rare drops from Vanilla endgame dungeons. It's inconclusive if they were removed from the game at some point, and if so, why
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` = 9237) AND (`Item` IN (13175));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(9237, 13175, 0, 1, 0, 1, 0, 1, 1, 'War Master Voone - Voone\'s Twitchbow');
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` = 9568) AND (`Item` IN (13148));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(9568, 13148, 0, 1, 0, 1, 0, 1, 1, 'Overlord Wyrmthalak - Chillpike');
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` = 10429) AND (`Item` IN (12588));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(10429, 12588, 0, 1, 0, 1, 0, 1, 1, 'Warchief Rend Blackhand - Bonespike Shoulder');
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` = 1853) AND (`Item` IN (13950));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(1853, 13950, 0, 1, 0, 1, 0, 1, 1, 'Darkmaster Gandling - Detention Strap');
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` = 10503) AND (`Item` IN (14543));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(10503, 14543, 0, 1, 0, 1, 0, 1, 1, 'Jandice Barov - Darkshade Gloves');
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` = 9568) AND (`Item` IN (13164));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(9568, 13164, 0, 1, 0, 1, 0, 1, 1, 'Overlord Wyrmthalak - Heart of the Scale');
|
||||||
|
|
||||||
|
-- Sack of Spoils and Chest of Spoils (AQ event reward containers)
|
||||||
|
DELETE FROM `item_loot_template` WHERE (`Entry` = 20601) AND (`Item` IN (20696, 20698));
|
||||||
|
INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(20601, 20696, 0, 5, 0, 1, 1, 1, 1, 'Sack of Spoils - Crystal Spiked Maul'),
|
||||||
|
(20601, 20698, 0, 1, 0, 1, 1, 1, 1, 'Sack of Spoils - Elemental Attuned Blade');
|
||||||
|
DELETE FROM `item_loot_template` WHERE (`Entry` = 20602) AND (`Item` IN (20722, 20721, 20720));
|
||||||
|
INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(20602, 20722, 0, 5, 0, 1, 1, 1, 1, 'Chest of Spoils - Crystal Slugthrower'),
|
||||||
|
(20602, 20721, 0, 5, 0, 1, 1, 1, 1, 'Chest of Spoils - Band of the Cultist'),
|
||||||
|
(20602, 20720, 0, 5, 0, 1, 1, 1, 1, 'Chest of Spoils - Dark Whisper Blade');
|
||||||
|
|
||||||
|
-- Missing from Jin'do Loot Table (same ilvl as the rest)
|
||||||
|
DELETE FROM `reference_loot_template` WHERE (`Entry` = 34089) AND (`Item` IN (19875));
|
||||||
|
INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(34089, 19875, 0, 0, 0, 1, 1, 1, 1, 'Bloodstained Coif');
|
||||||
|
|
||||||
|
-- Rare drop from Phalanx
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` = 9502) AND (`Item` IN (11743));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(9502, 11743, 0, 2, 0, 1, 1, 1, 1, 'Phalanx - Rockfist');
|
||||||
|
|
||||||
|
-- Claimed to still drop during 3.3.3
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` = 9257) AND (`Item` IN (9214));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(9257, 9214, 0, 7, 0, 1, 0, 1, 1, 'Scarshield Warlock - Grimoire of Inferno');
|
||||||
|
|
||||||
|
-- Alterac Valley Bosses
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` IN (13256, 13419)) AND (`Item` IN (19105, 19109, 19110, 19111, 19112, 19113));
|
||||||
|
DELETE FROM `reference_loot_template` WHERE (`Entry` = 13256);
|
||||||
|
INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(13256, 19105, 0, 0, 0, 1, 1, 1, 1, 'Alterac Valley Summon Boss - Frost Runed Headdress'),
|
||||||
|
(13256, 19109, 0, 0, 0, 1, 1, 1, 1, 'Alterac Valley Summon Boss - Deep Rooted Ring'),
|
||||||
|
(13256, 19110, 0, 0, 0, 1, 1, 1, 1, 'Alterac Valley Summon Boss - Cold Forged Blade'),
|
||||||
|
(13256, 19111, 0, 0, 0, 1, 1, 1, 1, 'Alterac Valley Summon Boss - Winteraxe Epaulets'),
|
||||||
|
(13256, 19112, 0, 0, 0, 1, 1, 1, 1, 'Alterac Valley Summon Boss - Frozen Steel Vambraces'),
|
||||||
|
(13256, 19113, 0, 0, 0, 1, 1, 1, 1, 'Alterac Valley Summon Boss - Yeti Hide Bracers');
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` IN (13256, 13419)) AND (`Item` IN (13256));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(13256, 13256, 13256, 100, 0, 1, 0, 4, 4, 'Alterac Summon Boss Loot Table'),
|
||||||
|
(13419, 13256, 13256, 100, 0, 1, 0, 4, 4, 'Alterac Summon Boss Loot Table');
|
||||||
|
|
||||||
|
-- AQ40 Trash Epic
|
||||||
|
DELETE FROM `creature_loot_template` WHERE (`Entry` = 15312) AND (`Item` IN (21890));
|
||||||
|
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||||
|
(15312, 21890, 0, 0.2, 0, 1, 0, 1, 1, 'Obsidian Nullifier - Gloves of the Fallen Prophet');
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
-- DB update 2026_01_21_01 -> 2026_01_21_02
|
||||||
|
--
|
||||||
|
SET @REPPORTALKEEPER := 30;
|
||||||
|
SET @REPREGULAR := 18;
|
||||||
|
SET @REPBOSS := 275;
|
||||||
|
|
||||||
|
DELETE FROM `creature_onkill_reputation` WHERE `creature_id` IN (31503, 31501, 31493, 31490, 31513, 32191, 31486, 31507, 31509, 31510, 31511, 31512, 31508, 31506);
|
||||||
|
INSERT INTO `creature_onkill_reputation` (`creature_id`,`RewOnKillRepFaction1`,`RewOnKillRepFaction2`,`MaxStanding1`,`IsTeamAward1`,`RewOnKillRepValue1`,`MaxStanding2`,`IsTeamAward2`,`RewOnKillRepValue2`,`TeamDependent`) VALUES
|
||||||
|
(31503,1037,1052,7,0,@REPPORTALKEEPER,7,0,@REPPORTALKEEPER,1), -- Portal Keeper
|
||||||
|
(31501,1037,1052,7,0,@REPPORTALKEEPER,7,0,@REPPORTALKEEPER,1), -- Portal Guardian
|
||||||
|
(31493,1037,1052,7,0,@REPREGULAR,7,0,@REPREGULAR,1), -- Azure Sorceror
|
||||||
|
(31490,1037,1052,7,0,@REPREGULAR,7,0,@REPREGULAR,1), -- Azure Raider
|
||||||
|
(31513,1037,1052,7,0,@REPREGULAR,7,0,@REPREGULAR,1), -- Erekem Guard
|
||||||
|
(32191,1037,1052,7,0,@REPREGULAR,7,0,@REPREGULAR,1), -- Azure Stalker
|
||||||
|
(31486,1037,1052,7,0,@REPREGULAR,7,0,@REPREGULAR,1), -- Azure Captain
|
||||||
|
(31507,1037,1052,7,0,@REPBOSS,7,0,@REPBOSS,1), -- Erekem
|
||||||
|
(31509,1037,1052,7,0,@REPBOSS,7,0,@REPBOSS,1), -- Lavanthor
|
||||||
|
(31510,1037,1052,7,0,@REPBOSS,7,0,@REPBOSS,1), -- Moragg
|
||||||
|
(31511,1037,1052,7,0,@REPBOSS,7,0,@REPBOSS,1), -- Zevoxx
|
||||||
|
(31512,1037,1052,7,0,@REPBOSS,7,0,@REPBOSS,1), -- Zuramat
|
||||||
|
(31508,1037,1052,7,0,@REPBOSS,7,0,@REPBOSS,1), -- Ichoron
|
||||||
|
(31506,1037,1052,7,0,@REPBOSS,7,0,@REPBOSS,1); -- Cyanigosa
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- DB update 2026_01_21_02 -> 2026_01_22_00
|
||||||
|
--
|
||||||
|
DELETE FROM `spell_script_names` WHERE `spell_id` = 28375;
|
||||||
|
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||||
|
(28375, 'spell_gluth_decimate_damage');
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
-- DB update 2026_01_22_00 -> 2026_01_22_01
|
||||||
|
-- PrevQuestID from 12822 to 18221, A Flawless Plan requires Opening the Backdoor, not Know No Fear
|
||||||
|
UPDATE `quest_template_addon` SET `PrevQuestID` = 12821 WHERE `ID` = 12823;
|
||||||
|
|
||||||
|
-- Remove phase shifts in Garm and Garm's Rise for Know No Fear
|
||||||
|
DELETE FROM `spell_area`
|
||||||
|
WHERE `Quest_start` = 12822
|
||||||
|
AND `quest_start_status` = 74;
|
||||||
|
|
||||||
|
-- Add phase shift in Garm and Garm's Rise after turning in Opening the Backdoor
|
||||||
|
DELETE FROM `spell_area` WHERE `Quest_start` = 12821 AND `Spell` = 54635;
|
||||||
|
INSERT INTO `spell_area`
|
||||||
|
(
|
||||||
|
`Spell`,
|
||||||
|
`Area`,
|
||||||
|
`Quest_start`,
|
||||||
|
`Quest_end`,
|
||||||
|
`Aura_spell`,
|
||||||
|
`Racemask`,
|
||||||
|
`Gender`,
|
||||||
|
`Autocast`,
|
||||||
|
`Quest_start_status`,
|
||||||
|
`Quest_end_status`
|
||||||
|
)
|
||||||
|
VALUES
|
||||||
|
(54635, 4421, 12821, 0, 0, 0, 2, 1, 64, 0),
|
||||||
|
(54635, 4461, 12821, 0, 0, 0, 2, 1, 64, 0);
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
-- DB update 2026_01_22_01 -> 2026_01_22_02
|
||||||
|
--
|
||||||
|
DELETE FROM `smart_scripts` WHERE `entryorguid` = 28581 AND `source_type` = 0 AND `id` IN (0, 1, 2);
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `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
|
||||||
|
(28581, 0, 0, 0, 0, 0, 100, 2, 0, 9000, 11000, 14000, 0, 0, 11, 52778, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Stormforged Tactician - In Combat - Cast \'Welding Beam\' (Normal Dungeon)'),
|
||||||
|
(28581, 0, 1, 0, 0, 0, 100, 4, 0, 9000, 11000, 14000, 0, 0, 11, 59166, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 'Stormforged Tactician - In Combat - Cast \'Welding Beam\' (Heroic Dungeon)'),
|
||||||
|
(28581, 0, 2, 0, 2, 0, 100, 6, 0, 70, 15000, 27000, 0, 0, 11, 59085, 32, 0, 0, 0, 0, 5, 40, 0, 0, 0, 0, 0, 0, 0, 'Stormforged Tactician - Between 0-70% Health - Cast \'Arc Weld\' (Dungeon)');
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
-- DB update 2026_01_22_02 -> 2026_01_22_03
|
||||||
|
--
|
||||||
|
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 29134;
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 29134) AND (`source_type` = 0) AND (`id` IN (0, 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`, `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
|
||||||
|
(29134, 0, 0, 0, 54, 0, 100, 0, 0, 0, 0, 0, 0, 0, 41, 180000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Brown Rabbit - On Just Summoned - Despawn In 180000 ms'),
|
||||||
|
(29134, 0, 1, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 53273, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Brown Rabbit - On Death - Cast \'Decoy Explosive\'');
|
||||||
@@ -162,7 +162,7 @@ void AccountInfo::LoadResult(Field* fields)
|
|||||||
Utf8ToUpperOnlyLatin(Login);
|
Utf8ToUpperOnlyLatin(Login);
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthSession::AuthSession(tcp::socket&& socket) :
|
AuthSession::AuthSession(IoContextTcpSocket&& socket) :
|
||||||
Socket(std::move(socket)), _status(STATUS_CHALLENGE), _build(0), _expversion(0) { }
|
Socket(std::move(socket)), _status(STATUS_CHALLENGE), _build(0), _expversion(0) { }
|
||||||
|
|
||||||
void AuthSession::Start()
|
void AuthSession::Start()
|
||||||
@@ -216,7 +216,7 @@ void AuthSession::CheckIpCallback(PreparedQueryResult result)
|
|||||||
AsyncRead();
|
AsyncRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthSession::ReadHandler()
|
SocketReadCallbackResult AuthSession::ReadHandler()
|
||||||
{
|
{
|
||||||
MessageBuffer& packet = GetReadBuffer();
|
MessageBuffer& packet = GetReadBuffer();
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ void AuthSession::ReadHandler()
|
|||||||
if (_status != itr->second.status)
|
if (_status != itr->second.status)
|
||||||
{
|
{
|
||||||
CloseSocket();
|
CloseSocket();
|
||||||
return;
|
return SocketReadCallbackResult::Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 size = uint16(itr->second.packetSize);
|
uint16 size = uint16(itr->second.packetSize);
|
||||||
@@ -248,7 +248,7 @@ void AuthSession::ReadHandler()
|
|||||||
if (size > MAX_ACCEPTED_CHALLENGE_SIZE)
|
if (size > MAX_ACCEPTED_CHALLENGE_SIZE)
|
||||||
{
|
{
|
||||||
CloseSocket();
|
CloseSocket();
|
||||||
return;
|
return SocketReadCallbackResult::Stop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,13 +258,13 @@ void AuthSession::ReadHandler()
|
|||||||
if (!(*this.*itr->second.handler)())
|
if (!(*this.*itr->second.handler)())
|
||||||
{
|
{
|
||||||
CloseSocket();
|
CloseSocket();
|
||||||
return;
|
return SocketReadCallbackResult::Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet.ReadCompleted(size);
|
packet.ReadCompleted(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncRead();
|
return SocketReadCallbackResult::KeepReading;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthSession::SendPacket(ByteBuffer& packet)
|
void AuthSession::SendPacket(ByteBuffer& packet)
|
||||||
|
|||||||
@@ -60,22 +60,22 @@ struct AccountInfo
|
|||||||
AccountTypes SecurityLevel = SEC_PLAYER;
|
AccountTypes SecurityLevel = SEC_PLAYER;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AuthSession : public Socket<AuthSession>
|
class AuthSession final : public Socket<AuthSession>
|
||||||
{
|
{
|
||||||
typedef Socket<AuthSession> AuthSocket;
|
typedef Socket<AuthSession> AuthSocket;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static std::unordered_map<uint8, AuthHandler> InitHandlers();
|
static std::unordered_map<uint8, AuthHandler> InitHandlers();
|
||||||
|
|
||||||
AuthSession(tcp::socket&& socket);
|
AuthSession(IoContextTcpSocket&& socket);
|
||||||
|
|
||||||
void Start() override;
|
void Start() override;
|
||||||
bool Update() override;
|
bool Update() final;
|
||||||
|
|
||||||
void SendPacket(ByteBuffer& packet);
|
void SendPacket(ByteBuffer& packet);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ReadHandler() override;
|
SocketReadCallbackResult ReadHandler() final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool HandleLogonChallenge();
|
bool HandleLogonChallenge();
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ protected:
|
|||||||
return threads;
|
return threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnSocketAccept(tcp::socket&& sock, uint32 threadIndex)
|
static void OnSocketAccept(IoContextTcpSocket&& sock, uint32 threadIndex)
|
||||||
{
|
{
|
||||||
Instance().OnSocketOpen(std::forward<tcp::socket>(sock), threadIndex);
|
Instance().OnSocketOpen(std::move(sock), threadIndex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,18 +18,16 @@
|
|||||||
#ifndef __RASESSION_H__
|
#ifndef __RASESSION_H__
|
||||||
#define __RASESSION_H__
|
#define __RASESSION_H__
|
||||||
|
|
||||||
#include <boost/asio/ip/tcp.hpp>
|
#include "Socket.h"
|
||||||
#include <boost/asio/streambuf.hpp>
|
#include <boost/asio/streambuf.hpp>
|
||||||
#include <future>
|
#include <future>
|
||||||
|
|
||||||
using boost::asio::ip::tcp;
|
|
||||||
|
|
||||||
const std::size_t bufferSize = 4096;
|
const std::size_t bufferSize = 4096;
|
||||||
|
|
||||||
class RASession : public std::enable_shared_from_this<RASession>
|
class RASession : public std::enable_shared_from_this<RASession>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RASession(tcp::socket&& socket) :
|
RASession(IoContextTcpSocket&& socket) :
|
||||||
_socket(std::move(socket)), _commandExecuting(nullptr) { }
|
_socket(std::move(socket)), _commandExecuting(nullptr) { }
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
@@ -47,7 +45,7 @@ private:
|
|||||||
static void CommandPrint(void* callbackArg, std::string_view text);
|
static void CommandPrint(void* callbackArg, std::string_view text);
|
||||||
static void CommandFinished(void* callbackArg, bool);
|
static void CommandFinished(void* callbackArg, bool);
|
||||||
|
|
||||||
tcp::socket _socket;
|
IoContextTcpSocket _socket;
|
||||||
boost::asio::streambuf _readBuffer;
|
boost::asio::streambuf _readBuffer;
|
||||||
boost::asio::streambuf _writeBuffer;
|
boost::asio::streambuf _writeBuffer;
|
||||||
std::promise<void>* _commandExecuting;
|
std::promise<void>* _commandExecuting;
|
||||||
|
|||||||
@@ -3296,6 +3296,19 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
|||||||
target->ToUnit()->SetAnimTier(AnimTier(e.action.animTier.animTier));
|
target->ToUnit()->SetAnimTier(AnimTier(e.action.animTier.animTier));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SMART_ACTION_SET_GOSSIP_MENU:
|
||||||
|
{
|
||||||
|
for (WorldObject* target : targets)
|
||||||
|
{
|
||||||
|
if (Creature* creature = target->ToCreature())
|
||||||
|
{
|
||||||
|
creature->SetGossipMenuId(e.action.setGossipMenu.gossipMenuId);
|
||||||
|
LOG_DEBUG("sql.sql", "SmartScript::ProcessAction: SMART_ACTION_SET_GOSSIP_MENU: Creature {} set gossip menu to {}",
|
||||||
|
creature->GetGUID().ToString(), e.action.setGossipMenu.gossipMenuId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry {} SourceType {}, Event {}, Unhandled Action type {}", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry {} SourceType {}, Event {}, Unhandled Action type {}", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -885,6 +885,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
|
|||||||
case SMART_ACTION_WORLD_SCRIPT: return sizeof(SmartAction::worldStateScript);
|
case SMART_ACTION_WORLD_SCRIPT: return sizeof(SmartAction::worldStateScript);
|
||||||
case SMART_ACTION_DISABLE_REWARD: return sizeof(SmartAction::reward);
|
case SMART_ACTION_DISABLE_REWARD: return sizeof(SmartAction::reward);
|
||||||
case SMART_ACTION_SET_ANIM_TIER: return sizeof(SmartAction::animTier);
|
case SMART_ACTION_SET_ANIM_TIER: return sizeof(SmartAction::animTier);
|
||||||
|
case SMART_ACTION_SET_GOSSIP_MENU: return sizeof(SmartAction::setGossipMenu);
|
||||||
case SMART_ACTION_DISMOUNT: return NO_PARAMS;
|
case SMART_ACTION_DISMOUNT: return NO_PARAMS;
|
||||||
default:
|
default:
|
||||||
LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using an action with no unused params specified in SmartAIMgr::CheckUnusedActionParams(), please report this.",
|
LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using an action with no unused params specified in SmartAIMgr::CheckUnusedActionParams(), please report this.",
|
||||||
@@ -2040,6 +2041,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
|||||||
case SMART_ACTION_MOVEMENT_PAUSE:
|
case SMART_ACTION_MOVEMENT_PAUSE:
|
||||||
case SMART_ACTION_MOVEMENT_RESUME:
|
case SMART_ACTION_MOVEMENT_RESUME:
|
||||||
case SMART_ACTION_WORLD_SCRIPT:
|
case SMART_ACTION_WORLD_SCRIPT:
|
||||||
|
case SMART_ACTION_SET_GOSSIP_MENU:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("sql.sql", "SmartAIMgr: Not handled action_type({}), event_type({}), Entry {} SourceType {} Event {}, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id);
|
LOG_ERROR("sql.sql", "SmartAIMgr: Not handled action_type({}), event_type({}), Entry {} SourceType {} Event {}, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id);
|
||||||
|
|||||||
@@ -724,8 +724,9 @@ enum SMART_ACTION
|
|||||||
SMART_ACTION_WORLD_SCRIPT = 237, // eventId, param
|
SMART_ACTION_WORLD_SCRIPT = 237, // eventId, param
|
||||||
SMART_ACTION_DISABLE_REWARD = 238, // reputation 0/1, loot 0/1
|
SMART_ACTION_DISABLE_REWARD = 238, // reputation 0/1, loot 0/1
|
||||||
SMART_ACTION_SET_ANIM_TIER = 239, // animtier
|
SMART_ACTION_SET_ANIM_TIER = 239, // animtier
|
||||||
|
SMART_ACTION_SET_GOSSIP_MENU = 240, // gossipMenuId
|
||||||
|
|
||||||
SMART_ACTION_AC_END = 240, // placeholder
|
SMART_ACTION_AC_END = 241, // placeholder
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SmartActionSummonCreatureFlags
|
enum class SmartActionSummonCreatureFlags
|
||||||
@@ -1510,6 +1511,11 @@ struct SmartAction
|
|||||||
{
|
{
|
||||||
uint32 animTier;
|
uint32 animTier;
|
||||||
} animTier;
|
} animTier;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 gossipMenuId;
|
||||||
|
} setGossipMenu;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ BattlegroundSA::BattlegroundSA()
|
|||||||
EndRoundTimer = 0s;
|
EndRoundTimer = 0s;
|
||||||
ShipsStarted = false;
|
ShipsStarted = false;
|
||||||
Status = BG_SA_NOTSTARTED;
|
Status = BG_SA_NOTSTARTED;
|
||||||
|
_nextShipIsEast = true;
|
||||||
|
|
||||||
for (uint8 i = 0; i < 6; i++)
|
for (uint8 i = 0; i < 6; i++)
|
||||||
GateStatus[i] = BG_SA_GATE_OK;
|
GateStatus[i] = BG_SA_GATE_OK;
|
||||||
@@ -85,6 +86,7 @@ void BattlegroundSA::Init()
|
|||||||
_notEvenAScratch[TEAM_HORDE] = true;
|
_notEvenAScratch[TEAM_HORDE] = true;
|
||||||
Status = BG_SA_WARMUP;
|
Status = BG_SA_WARMUP;
|
||||||
_relicClicked = false;
|
_relicClicked = false;
|
||||||
|
_nextShipIsEast = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BattlegroundSA::SetupBattleground()
|
bool BattlegroundSA::SetupBattleground()
|
||||||
@@ -181,6 +183,7 @@ bool BattlegroundSA::ResetObjs()
|
|||||||
|
|
||||||
TotalTime = 0s;
|
TotalTime = 0s;
|
||||||
ShipsStarted = false;
|
ShipsStarted = false;
|
||||||
|
_nextShipIsEast = true;
|
||||||
|
|
||||||
//Graveyards!
|
//Graveyards!
|
||||||
for (uint8 i = 0; i < BG_SA_MAX_GY; i++)
|
for (uint8 i = 0; i < BG_SA_MAX_GY; i++)
|
||||||
@@ -574,10 +577,12 @@ void BattlegroundSA::TeleportToEntrancePosition(Player* player)
|
|||||||
if (!ShipsStarted)
|
if (!ShipsStarted)
|
||||||
{
|
{
|
||||||
player->CastSpell(player, 12438, true);//Without this player falls before boat loads...
|
player->CastSpell(player, 12438, true);//Without this player falls before boat loads...
|
||||||
if (urand(0, 1))
|
if (_nextShipIsEast)
|
||||||
player->TeleportTo(MAP_STRAND_OF_THE_ANCIENTS, 2682.936f, -830.368f, 15.0f, 2.895f, 0);
|
player->TeleportTo(MAP_STRAND_OF_THE_ANCIENTS, 2682.936f, -830.368f, 15.0f, 2.895f, 0);
|
||||||
else
|
else
|
||||||
player->TeleportTo(MAP_STRAND_OF_THE_ANCIENTS, 2577.003f, 980.261f, 15.0f, 0.807f, 0);
|
player->TeleportTo(MAP_STRAND_OF_THE_ANCIENTS, 2577.003f, 980.261f, 15.0f, 0.807f, 0);
|
||||||
|
|
||||||
|
_nextShipIsEast = !_nextShipIsEast;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
player->TeleportTo(MAP_STRAND_OF_THE_ANCIENTS, 1600.381f, -106.263f, 8.8745f, 3.78f, 0);
|
player->TeleportTo(MAP_STRAND_OF_THE_ANCIENTS, 1600.381f, -106.263f, 8.8745f, 3.78f, 0);
|
||||||
|
|||||||
@@ -620,5 +620,7 @@ private:
|
|||||||
|
|
||||||
// Achievement: Not Even a Scratch
|
// Achievement: Not Even a Scratch
|
||||||
bool _notEvenAScratch[PVP_TEAMS_COUNT];
|
bool _notEvenAScratch[PVP_TEAMS_COUNT];
|
||||||
|
/// Toggle for alternating player spawns between East and West ships (true = first/East ship, false = second/West ship)
|
||||||
|
bool _nextShipIsEast;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ HostileReference* ThreatContainer::SelectNextVictim(Creature* attacker, HostileR
|
|||||||
Unit* cvUnit = currentVictim->getTarget();
|
Unit* cvUnit = currentVictim->getTarget();
|
||||||
if (!attacker->CanCreatureAttack(cvUnit)) // pussywizard: if currentVictim is not valid => don't compare the threat with it, just take the highest threat valid target
|
if (!attacker->CanCreatureAttack(cvUnit)) // pussywizard: if currentVictim is not valid => don't compare the threat with it, just take the highest threat valid target
|
||||||
currentVictim = nullptr;
|
currentVictim = nullptr;
|
||||||
else if (cvUnit->IsImmunedToDamageOrSchool(attacker->GetMeleeDamageSchoolMask()) || cvUnit->HasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_TAKE_DAMAGE) || cvUnit->HasUnitState(UNIT_STATE_CONFUSED)) // pussywizard: no 10%/30% if currentVictim is immune to damage or has auras breakable by damage
|
else if (!IsPreferredTarget(attacker, cvUnit)) // pussywizard: no 10%/30% if currentVictim is immune to damage or has auras breakable by damage
|
||||||
currentVictim = nullptr;
|
currentVictim = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ HostileReference* ThreatContainer::SelectNextVictim(Creature* attacker, HostileR
|
|||||||
|
|
||||||
// pussywizard: don't go to threat comparison if this ref is immune to damage or has aura breakable on damage (second choice target)
|
// pussywizard: don't go to threat comparison if this ref is immune to damage or has aura breakable on damage (second choice target)
|
||||||
// pussywizard: if this is the last entry on the threat list, then all targets are second choice, set bool to true and loop threat list again, ignoring this section
|
// pussywizard: if this is the last entry on the threat list, then all targets are second choice, set bool to true and loop threat list again, ignoring this section
|
||||||
if (!noPriorityTargetFound && (target->IsImmunedToDamageOrSchool(attacker->GetMeleeDamageSchoolMask()) || target->HasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_TAKE_DAMAGE) || target->HasUnitState(UNIT_STATE_CONFUSED) || target->HasAuraTypeWithCaster(SPELL_AURA_IGNORED, attacker->GetGUID())))
|
if (!noPriorityTargetFound && !IsPreferredTarget(attacker, target))
|
||||||
{
|
{
|
||||||
if (iter != lastRef)
|
if (iter != lastRef)
|
||||||
{
|
{
|
||||||
@@ -394,6 +394,8 @@ HostileReference* ThreatContainer::SelectNextVictim(Creature* attacker, HostileR
|
|||||||
}
|
}
|
||||||
else // pussywizard: no currentVictim, first passing all checks is chosen (highest threat, list is sorted)
|
else // pussywizard: no currentVictim, first passing all checks is chosen (highest threat, list is sorted)
|
||||||
{
|
{
|
||||||
|
// tie-breaker if multiple targets have the same threat: select closest target
|
||||||
|
currentRef = SelectNextVictimTieBreaker(attacker, iter, noPriorityTargetFound);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -406,6 +408,69 @@ HostileReference* ThreatContainer::SelectNextVictim(Creature* attacker, HostileR
|
|||||||
return currentRef;
|
return currentRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper for Tie-breakers
|
||||||
|
HostileReference* ThreatContainer::SelectNextVictimTieBreaker(Creature* attacker, ThreatContainer::StorageType::const_iterator currentIter, bool noPriorityTargetFound) const
|
||||||
|
{
|
||||||
|
HostileReference* bestRef = *currentIter;
|
||||||
|
float bestThreat = bestRef->GetThreat();
|
||||||
|
float shortestDistSq = attacker->GetExactDistSq(bestRef->getTarget());
|
||||||
|
|
||||||
|
auto tieIter = std::next(currentIter);
|
||||||
|
|
||||||
|
while (tieIter != iThreatList.end())
|
||||||
|
{
|
||||||
|
HostileReference* nextRef = *tieIter;
|
||||||
|
|
||||||
|
if (!nextRef)
|
||||||
|
{
|
||||||
|
++tieIter;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Threatlist is sorted, so we can stop as soon as we find a lower threat
|
||||||
|
if (bestThreat - nextRef->GetThreat() > 0.01f)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Unit* target = nextRef->getTarget();
|
||||||
|
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
++tieIter;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attacker->CanCreatureAttack(target) && (noPriorityTargetFound || IsPreferredTarget(attacker, target)))
|
||||||
|
{
|
||||||
|
float distSq = attacker->GetExactDistSq(target);
|
||||||
|
if (distSq < shortestDistSq)
|
||||||
|
{
|
||||||
|
bestRef = nextRef;
|
||||||
|
shortestDistSq = distSq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++tieIter;
|
||||||
|
}
|
||||||
|
return bestRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper for checking if a target is preferred (not immune, not confused, etc)
|
||||||
|
bool ThreatContainer::IsPreferredTarget(Creature* attacker, Unit* target) const
|
||||||
|
{
|
||||||
|
if (target->IsImmunedToDamageOrSchool(attacker->GetMeleeDamageSchoolMask()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (target->HasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_TAKE_DAMAGE))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (target->HasUnitState(UNIT_STATE_CONFUSED))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (target->HasAuraTypeWithCaster(SPELL_AURA_IGNORED, attacker->GetGUID()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
//=================== ThreatMgr ==========================
|
//=================== ThreatMgr ==========================
|
||||||
//============================================================
|
//============================================================
|
||||||
|
|||||||
@@ -156,6 +156,10 @@ public:
|
|||||||
|
|
||||||
HostileReference* SelectNextVictim(Creature* attacker, HostileReference* currentVictim) const;
|
HostileReference* SelectNextVictim(Creature* attacker, HostileReference* currentVictim) const;
|
||||||
|
|
||||||
|
HostileReference* SelectNextVictimTieBreaker(Creature* attacker, ThreatContainer::StorageType::const_iterator currentIter, bool noPriorityTargetFound) const;
|
||||||
|
|
||||||
|
bool IsPreferredTarget(Creature* attacker, Unit* target) const;
|
||||||
|
|
||||||
void setDirty(bool isDirty) { iDirty = isDirty; }
|
void setDirty(bool isDirty) { iDirty = isDirty; }
|
||||||
|
|
||||||
[[nodiscard]] bool isDirty() const { return iDirty; }
|
[[nodiscard]] bool isDirty() const { return iDirty; }
|
||||||
|
|||||||
@@ -542,13 +542,13 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
|
|||||||
condMeets = object->GetMap()->GetDifficulty() == ConditionValue1;
|
condMeets = object->GetMap()->GetDifficulty() == ConditionValue1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_RANDOM_DUNGEON:
|
case CONDITION_PLAYER_QUEUED_RANDOM_DUNGEON:
|
||||||
{
|
{
|
||||||
if (Unit* unit = object->ToUnit())
|
if (Unit* unit = object->ToUnit())
|
||||||
{
|
{
|
||||||
if (Player* player = unit->GetCharmerOrOwnerPlayerOrPlayerItself())
|
if (Player* player = unit->ToPlayer())
|
||||||
{
|
{
|
||||||
if (sLFGMgr->selectedRandomLfgDungeon(player->GetGUID()))
|
if (sLFGMgr->IsPlayerQueuedForRandomDungeon(player->GetGUID()))
|
||||||
{
|
{
|
||||||
if (!ConditionValue1)
|
if (!ConditionValue1)
|
||||||
condMeets = true;
|
condMeets = true;
|
||||||
@@ -803,7 +803,7 @@ uint32 Condition::GetSearcherTypeMaskForCondition()
|
|||||||
case CONDITION_CHARMED:
|
case CONDITION_CHARMED:
|
||||||
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
|
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
|
||||||
break;
|
break;
|
||||||
case CONDITION_RANDOM_DUNGEON:
|
case CONDITION_PLAYER_QUEUED_RANDOM_DUNGEON:
|
||||||
mask |= GRID_MAP_TYPE_MASK_PLAYER;
|
mask |= GRID_MAP_TYPE_MASK_PLAYER;
|
||||||
break;
|
break;
|
||||||
case CONDITION_WORLD_SCRIPT:
|
case CONDITION_WORLD_SCRIPT:
|
||||||
@@ -2486,7 +2486,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CONDITION_RANDOM_DUNGEON:
|
case CONDITION_PLAYER_QUEUED_RANDOM_DUNGEON:
|
||||||
if (cond->ConditionValue1 > 1)
|
if (cond->ConditionValue1 > 1)
|
||||||
{
|
{
|
||||||
LOG_ERROR("sql.sql", "RandomDungeon condition has useless data in value1 ({}).", cond->ConditionValue1);
|
LOG_ERROR("sql.sql", "RandomDungeon condition has useless data in value1 ({}).", cond->ConditionValue1);
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ enum ConditionTypes
|
|||||||
CONDITION_HAS_AURA_TYPE = 102, // aura_type 0 0 true if has aura type
|
CONDITION_HAS_AURA_TYPE = 102, // aura_type 0 0 true if has aura type
|
||||||
CONDITION_WORLD_SCRIPT = 103, // conditionId state 0 true if WorldState::IsConditionFulfilled returns true
|
CONDITION_WORLD_SCRIPT = 103, // conditionId state 0 true if WorldState::IsConditionFulfilled returns true
|
||||||
CONDITION_AI_DATA = 104, // dataId value 0 true if AI::GetData returns value
|
CONDITION_AI_DATA = 104, // dataId value 0 true if AI::GetData returns value
|
||||||
CONDITION_RANDOM_DUNGEON = 105, // difficulty (0 = any) 0 0 true if player is queued for a random dungeon via RDF (param1 = Difficulty)
|
CONDITION_PLAYER_QUEUED_RANDOM_DUNGEON = 105, // checkDifficulty difficulty 0 true if player is queued for a random dungeon via RDF
|
||||||
|
|
||||||
CONDITION_AC_END = 106 // placeholder
|
CONDITION_AC_END = 106 // placeholder
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -139,4 +139,13 @@ namespace lfg
|
|||||||
return m_KicksLeft;
|
return m_KicksLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LfgGroupData::AddRandomQueuedPlayer(ObjectGuid guid)
|
||||||
|
{
|
||||||
|
m_RandomQueuedPlayers.insert(guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool LfgGroupData::IsRandomQueuedPlayer(ObjectGuid guid) const
|
||||||
|
{
|
||||||
|
return m_RandomQueuedPlayers.contains(guid);
|
||||||
|
}
|
||||||
} // namespace lfg
|
} // namespace lfg
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ namespace lfg
|
|||||||
void SetState(LfgState state);
|
void SetState(LfgState state);
|
||||||
void RestoreState();
|
void RestoreState();
|
||||||
void AddPlayer(ObjectGuid guid);
|
void AddPlayer(ObjectGuid guid);
|
||||||
|
void AddRandomQueuedPlayer(ObjectGuid guid);
|
||||||
|
[[nodiscard]] bool IsRandomQueuedPlayer(ObjectGuid guid) const;
|
||||||
uint8 RemovePlayer(ObjectGuid guid);
|
uint8 RemovePlayer(ObjectGuid guid);
|
||||||
void RemoveAllPlayers();
|
void RemoveAllPlayers();
|
||||||
void SetLeader(ObjectGuid guid);
|
void SetLeader(ObjectGuid guid);
|
||||||
@@ -66,6 +68,7 @@ namespace lfg
|
|||||||
LfgState m_OldState; ///< Old State
|
LfgState m_OldState; ///< Old State
|
||||||
ObjectGuid m_Leader; ///< Leader GUID
|
ObjectGuid m_Leader; ///< Leader GUID
|
||||||
LfgGuidSet m_Players; ///< Players in group
|
LfgGuidSet m_Players; ///< Players in group
|
||||||
|
LfgGuidSet m_RandomQueuedPlayers; ///< Players that queued for random dungeon
|
||||||
// Dungeon
|
// Dungeon
|
||||||
uint32 m_Dungeon; ///< Dungeon entry
|
uint32 m_Dungeon; ///< Dungeon entry
|
||||||
bool _isLFGGroup;
|
bool _isLFGGroup;
|
||||||
|
|||||||
@@ -2583,6 +2583,18 @@ namespace lfg
|
|||||||
GroupsStore[gguid].AddPlayer(guid);
|
GroupsStore[gguid].AddPlayer(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LFGMgr::AddPlayerQueuedForRandomDungeonToGroup(ObjectGuid gguid, ObjectGuid guid)
|
||||||
|
{
|
||||||
|
const LfgDungeonSet& dungeons = GetSelectedDungeons(guid);
|
||||||
|
if (dungeons.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32 dungeonId = *dungeons.begin();
|
||||||
|
LFGDungeonData const* dungeon = GetLFGDungeon(dungeonId);
|
||||||
|
if (dungeon && (dungeon->type == LFG_TYPE_RANDOM))
|
||||||
|
GroupsStore[gguid].AddRandomQueuedPlayer(guid);
|
||||||
|
}
|
||||||
|
|
||||||
void LFGMgr::SetLeader(ObjectGuid gguid, ObjectGuid leader)
|
void LFGMgr::SetLeader(ObjectGuid gguid, ObjectGuid leader)
|
||||||
{
|
{
|
||||||
GroupsStore[gguid].SetLeader(leader);
|
GroupsStore[gguid].SetLeader(leader);
|
||||||
@@ -2839,4 +2851,12 @@ namespace lfg
|
|||||||
sDisableMgr->IsDisabledFor(DISABLE_TYPE_LFG_MAP, mapId, nullptr);
|
sDisableMgr->IsDisabledFor(DISABLE_TYPE_LFG_MAP, mapId, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LFGMgr::IsPlayerQueuedForRandomDungeon(ObjectGuid guid)
|
||||||
|
{
|
||||||
|
auto gguid = GetGroup(guid);
|
||||||
|
if (!gguid)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return GroupsStore[gguid].IsRandomQueuedPlayer(guid);
|
||||||
|
}
|
||||||
} // namespace lfg
|
} // namespace lfg
|
||||||
|
|||||||
@@ -506,6 +506,9 @@ namespace lfg
|
|||||||
uint8 RemovePlayerFromGroup(ObjectGuid gguid, ObjectGuid guid);
|
uint8 RemovePlayerFromGroup(ObjectGuid gguid, ObjectGuid guid);
|
||||||
/// Adds player to group
|
/// Adds player to group
|
||||||
void AddPlayerToGroup(ObjectGuid gguid, ObjectGuid guid);
|
void AddPlayerToGroup(ObjectGuid gguid, ObjectGuid guid);
|
||||||
|
/// Store player that selected random queue to group
|
||||||
|
void AddPlayerQueuedForRandomDungeonToGroup(ObjectGuid gguid, ObjectGuid guid);
|
||||||
|
bool IsPlayerQueuedForRandomDungeon(ObjectGuid guid);
|
||||||
/// Xinef: Set Random Players Count
|
/// Xinef: Set Random Players Count
|
||||||
void SetRandomPlayersCount(ObjectGuid guid, uint8 count);
|
void SetRandomPlayersCount(ObjectGuid guid, uint8 count);
|
||||||
/// Xinef: Get Random Players Count
|
/// Xinef: Get Random Players Count
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ namespace lfg
|
|||||||
|
|
||||||
sLFGMgr->SetGroup(guid, gguid);
|
sLFGMgr->SetGroup(guid, gguid);
|
||||||
sLFGMgr->AddPlayerToGroup(gguid, guid);
|
sLFGMgr->AddPlayerToGroup(gguid, guid);
|
||||||
|
sLFGMgr->AddPlayerQueuedForRandomDungeonToGroup(gguid, guid);
|
||||||
|
|
||||||
// pussywizard: after all necessary actions handle raid browser
|
// pussywizard: after all necessary actions handle raid browser
|
||||||
if (sLFGMgr->GetState(guid) == LFG_STATE_RAIDBROWSER)
|
if (sLFGMgr->GetState(guid) == LFG_STATE_RAIDBROWSER)
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ Creature::Creature(): Unit(), MovableMapObject(), m_groupLootTimer(0), lootingGr
|
|||||||
m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_wanderDistance(0.0f), m_boundaryCheckTime(2500),
|
m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_wanderDistance(0.0f), m_boundaryCheckTime(2500),
|
||||||
m_transportCheckTimer(1000), lootPickPocketRestoreTime(0), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE),
|
m_transportCheckTimer(1000), lootPickPocketRestoreTime(0), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE),
|
||||||
m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_alreadyCallForHelp(false), m_AlreadyCallAssistance(false),
|
m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_alreadyCallForHelp(false), m_AlreadyCallAssistance(false),
|
||||||
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_regenPower(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_moveInLineOfSightDisabled(false), m_moveInLineOfSightStrictlyDisabled(false),
|
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_regenPower(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), _gossipMenuId(0), m_moveInLineOfSightDisabled(false), m_moveInLineOfSightStrictlyDisabled(false),
|
||||||
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f),_sparringPct(0.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), m_lastLeashExtensionTime(nullptr), m_cannotReachTimer(0),
|
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f),_sparringPct(0.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), m_lastLeashExtensionTime(nullptr), m_cannotReachTimer(0),
|
||||||
_isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0), _playerDamageReq(0), _damagedByPlayer(false), _isCombatMovementAllowed(true)
|
_isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0), _playerDamageReq(0), _damagedByPlayer(false), _isCombatMovementAllowed(true)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -204,6 +204,8 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] CreatureTemplate const* GetCreatureTemplate() const { return m_creatureInfo; }
|
[[nodiscard]] CreatureTemplate const* GetCreatureTemplate() const { return m_creatureInfo; }
|
||||||
[[nodiscard]] CreatureData const* GetCreatureData() const { return m_creatureData; }
|
[[nodiscard]] CreatureData const* GetCreatureData() const { return m_creatureData; }
|
||||||
|
[[nodiscard]] uint32 GetGossipMenuId() const { return _gossipMenuId ? _gossipMenuId : GetCreatureTemplate()->GossipMenuId; }
|
||||||
|
void SetGossipMenuId(uint32 gossipMenuId) { _gossipMenuId = gossipMenuId; }
|
||||||
void SetDetectionDistance(float dist){ m_detectionDistance = dist; }
|
void SetDetectionDistance(float dist){ m_detectionDistance = dist; }
|
||||||
[[nodiscard]] CreatureAddon const* GetCreatureAddon() const;
|
[[nodiscard]] CreatureAddon const* GetCreatureAddon() const;
|
||||||
|
|
||||||
@@ -478,6 +480,7 @@ protected:
|
|||||||
|
|
||||||
SpellSchoolMask m_meleeDamageSchoolMask;
|
SpellSchoolMask m_meleeDamageSchoolMask;
|
||||||
uint32 m_originalEntry;
|
uint32 m_originalEntry;
|
||||||
|
uint32 _gossipMenuId;
|
||||||
|
|
||||||
bool m_moveInLineOfSightDisabled;
|
bool m_moveInLineOfSightDisabled;
|
||||||
bool m_moveInLineOfSightStrictlyDisabled;
|
bool m_moveInLineOfSightStrictlyDisabled;
|
||||||
|
|||||||
@@ -1642,12 +1642,9 @@ void Player::ProcessDelayedOperations()
|
|||||||
if (m_DelayedOperations & DELAYED_SAVE_PLAYER)
|
if (m_DelayedOperations & DELAYED_SAVE_PLAYER)
|
||||||
SaveToDB(false, false);
|
SaveToDB(false, false);
|
||||||
|
|
||||||
if (m_DelayedOperations & DELAYED_SPELL_CAST_DESERTER)
|
if ((m_DelayedOperations & DELAYED_SPELL_CAST_DESERTER)
|
||||||
{
|
&& !GetAura(26013))
|
||||||
Aura* aura = GetAura(26013);
|
|
||||||
if (!aura || aura->GetDuration() <= 900000)
|
|
||||||
CastSpell(this, 26013, true);
|
CastSpell(this, 26013, true);
|
||||||
}
|
|
||||||
|
|
||||||
if (m_DelayedOperations & DELAYED_BG_MOUNT_RESTORE)
|
if (m_DelayedOperations & DELAYED_BG_MOUNT_RESTORE)
|
||||||
{
|
{
|
||||||
@@ -14378,7 +14375,7 @@ bool Player::CanSeeVendor(Creature const* creature) const
|
|||||||
if (!sConditionMgr->IsObjectMeetToConditions(const_cast<Player*>(this), const_cast<Creature*>(creature), conditions))
|
if (!sConditionMgr->IsObjectMeetToConditions(const_cast<Player*>(this), const_cast<Creature*>(creature), conditions))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32 const menuId = creature->GetCreatureTemplate()->GossipMenuId;
|
uint32 const menuId = creature->GetGossipMenuId();
|
||||||
if (!AnyVendorOptionAvailable(menuId, creature))
|
if (!AnyVendorOptionAvailable(menuId, creature))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@@ -429,7 +429,7 @@ uint32 Player::GetDefaultGossipMenuForSource(WorldObject* source)
|
|||||||
switch (source->GetTypeId())
|
switch (source->GetTypeId())
|
||||||
{
|
{
|
||||||
case TYPEID_UNIT:
|
case TYPEID_UNIT:
|
||||||
return source->ToCreature()->GetCreatureTemplate()->GossipMenuId;
|
return source->ToCreature()->GetGossipMenuId();
|
||||||
case TYPEID_GAMEOBJECT:
|
case TYPEID_GAMEOBJECT:
|
||||||
return source->ToGameObject()->GetGOInfo()->GetGossipMenuId();
|
return source->ToGameObject()->GetGOInfo()->GetGossipMenuId();
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -2148,7 +2148,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit const* attacker, Unit const* victim, co
|
|||||||
|
|
||||||
float Unit::GetEffectiveResistChance(Unit const* owner, SpellSchoolMask schoolMask, Unit const* victim)
|
float Unit::GetEffectiveResistChance(Unit const* owner, SpellSchoolMask schoolMask, Unit const* victim)
|
||||||
{
|
{
|
||||||
float victimResistance = float(victim->GetResistance(schoolMask));
|
float victimResistance = static_cast<float>(victim->GetResistance(schoolMask));
|
||||||
if (owner)
|
if (owner)
|
||||||
{
|
{
|
||||||
// Xinef: pets inherit 100% of masters penetration
|
// Xinef: pets inherit 100% of masters penetration
|
||||||
@@ -2156,28 +2156,28 @@ float Unit::GetEffectiveResistChance(Unit const* owner, SpellSchoolMask schoolMa
|
|||||||
Player const* player = owner->GetSpellModOwner();
|
Player const* player = owner->GetSpellModOwner();
|
||||||
if (player && owner->GetEntry() != WORLD_TRIGGER)
|
if (player && owner->GetEntry() != WORLD_TRIGGER)
|
||||||
{
|
{
|
||||||
victimResistance += float(player->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask));
|
victimResistance += static_cast<float>(player->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask));
|
||||||
victimResistance -= float(player->GetSpellPenetrationItemMod());
|
victimResistance -= static_cast<float>(player->GetSpellPenetrationItemMod());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
victimResistance += float(owner->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask));
|
victimResistance += static_cast<float>(owner->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask));
|
||||||
}
|
}
|
||||||
|
|
||||||
victimResistance = std::max(victimResistance, 0.0f);
|
victimResistance = std::max(victimResistance, 0.0f);
|
||||||
if (owner)
|
if (owner)
|
||||||
victimResistance += std::max((float(victim->GetLevel()) - float(owner->GetLevel())) * 5.0f, 0.0f);
|
victimResistance += std::max(static_cast<float>(victim->GetLevel() - owner->GetLevel()) * 5.0f, 0.0f);
|
||||||
|
|
||||||
static uint32 const BOSS_LEVEL = 83;
|
float level = static_cast<float>(victim->GetLevel());
|
||||||
static float const BOSS_RESISTANCE_CONSTANT = 510.0f;
|
|
||||||
uint32 level = victim->GetLevel();
|
|
||||||
float resistanceConstant = 0.0f;
|
float resistanceConstant = 0.0f;
|
||||||
|
|
||||||
if (level == BOSS_LEVEL)
|
if (level > 60.0f)
|
||||||
resistanceConstant = BOSS_RESISTANCE_CONSTANT;
|
resistanceConstant = 150.0f + (level - 60.0f) * (level - 67.5f);
|
||||||
|
else if (level > 20.0f)
|
||||||
|
resistanceConstant = 50.0f + (level - 20.0f) * 2.5f;
|
||||||
else
|
else
|
||||||
resistanceConstant = level * 5.0f;
|
resistanceConstant = 50.0f;
|
||||||
|
|
||||||
return victimResistance / (victimResistance + resistanceConstant);
|
return std::min(victimResistance / (victimResistance + resistanceConstant), 0.75f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited)
|
void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited)
|
||||||
|
|||||||
@@ -602,7 +602,10 @@ void WorldSession::HandleSellItemOpcode(WorldPackets::Item::SellItem& packet)
|
|||||||
if (pItem)
|
if (pItem)
|
||||||
{
|
{
|
||||||
if (!sScriptMgr->OnPlayerCanSellItem(_player, pItem, creature))
|
if (!sScriptMgr->OnPlayerCanSellItem(_player, pItem, creature))
|
||||||
|
{
|
||||||
|
_player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, packet.ItemGuid, 0);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// prevent sell not owner item
|
// prevent sell not owner item
|
||||||
if (_player->GetGUID() != pItem->GetOwnerGUID())
|
if (_player->GetGUID() != pItem->GetOwnerGUID())
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket& recvData)
|
|||||||
if (!sScriptMgr->OnGossipHello(_player, unit))
|
if (!sScriptMgr->OnGossipHello(_player, unit))
|
||||||
{
|
{
|
||||||
// _player->TalkedToCreature(unit->GetEntry(), unit->GetGUID());
|
// _player->TalkedToCreature(unit->GetEntry(), unit->GetGUID());
|
||||||
_player->PrepareGossipMenu(unit, unit->GetCreatureTemplate()->GossipMenuId, true);
|
_player->PrepareGossipMenu(unit, unit->GetGossipMenuId(), true);
|
||||||
_player->SendPreparedGossip(unit);
|
_player->SendPreparedGossip(unit);
|
||||||
}
|
}
|
||||||
unit->AI()->sGossipHello(_player);
|
unit->AI()->sGossipHello(_player);
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket& recvData)
|
|||||||
if (sScriptMgr->OnGossipHello(_player, creature))
|
if (sScriptMgr->OnGossipHello(_player, creature))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_player->PrepareGossipMenu(creature, creature->GetCreatureTemplate()->GossipMenuId, true);
|
_player->PrepareGossipMenu(creature, creature->GetGossipMenuId(), true);
|
||||||
_player->SendPreparedGossip(creature);
|
_player->SendPreparedGossip(creature);
|
||||||
|
|
||||||
creature->AI()->sGossipHello(_player);
|
creature->AI()->sGossipHello(_player);
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ static Optional<float> GetVelocity(Unit* owner, Unit* target, G3D::Vector3 const
|
|||||||
(owner->IsPet() || owner->IsGuardian() || owner->GetGUID() == target->GetCritterGUID() || owner->GetCharmerOrOwnerGUID() == target->GetGUID()))
|
(owner->IsPet() || owner->IsGuardian() || owner->GetGUID() == target->GetCritterGUID() || owner->GetCharmerOrOwnerGUID() == target->GetGUID()))
|
||||||
{
|
{
|
||||||
uint32 moveFlags = target->GetUnitMovementFlags();
|
uint32 moveFlags = target->GetUnitMovementFlags();
|
||||||
if (target->movespline->isWalking())
|
if (target->IsWalking())
|
||||||
{
|
{
|
||||||
moveFlags |= MOVEMENTFLAG_WALKING;
|
moveFlags |= MOVEMENTFLAG_WALKING;
|
||||||
}
|
}
|
||||||
@@ -635,7 +635,7 @@ bool FollowMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
|
|||||||
Movement::MoveSplineInit init(owner);
|
Movement::MoveSplineInit init(owner);
|
||||||
init.MovebyPath(i_path->GetPath());
|
init.MovebyPath(i_path->GetPath());
|
||||||
if (_inheritWalkState)
|
if (_inheritWalkState)
|
||||||
init.SetWalk(target->IsWalking() || target->movespline->isWalking());
|
init.SetWalk(target->IsWalking());
|
||||||
|
|
||||||
if (_inheritSpeed)
|
if (_inheritSpeed)
|
||||||
if (Optional<float> velocity = GetVelocity(owner, target, i_path->GetActualEndPosition(), owner->IsGuardian()))
|
if (Optional<float> velocity = GetVelocity(owner, target, i_path->GetActualEndPosition(), owner->IsGuardian()))
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ namespace Movement
|
|||||||
[[nodiscard]] bool Finalized() const { return splineflags.done; }
|
[[nodiscard]] bool Finalized() const { return splineflags.done; }
|
||||||
[[nodiscard]] bool isCyclic() const { return splineflags.cyclic; }
|
[[nodiscard]] bool isCyclic() const { return splineflags.cyclic; }
|
||||||
[[nodiscard]] bool isFalling() const { return splineflags.falling; }
|
[[nodiscard]] bool isFalling() const { return splineflags.falling; }
|
||||||
[[nodiscard]] bool isWalking() const { return splineflags.walkmode; }
|
|
||||||
[[nodiscard]] bool isBoarding() const { return splineflags.transportEnter || splineflags.transportExit; }
|
[[nodiscard]] bool isBoarding() const { return splineflags.transportEnter || splineflags.transportExit; }
|
||||||
[[nodiscard]] Vector3 FinalDestination() const { return Initialized() ? spline.getPoint(spline.last()) : Vector3(); }
|
[[nodiscard]] Vector3 FinalDestination() const { return Initialized() ? spline.getPoint(spline.last()) : Vector3(); }
|
||||||
[[nodiscard]] Vector3 CurrentDestination() const { return Initialized() ? spline.getPoint(point_Idx + 1) : Vector3(); }
|
[[nodiscard]] Vector3 CurrentDestination() const { return Initialized() ? spline.getPoint(point_Idx + 1) : Vector3(); }
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace Movement
|
|||||||
Falling = 0x00000200, // Affects elevation computation, can't be combined with Parabolic flag
|
Falling = 0x00000200, // Affects elevation computation, can't be combined with Parabolic flag
|
||||||
No_Spline = 0x00000400,
|
No_Spline = 0x00000400,
|
||||||
Parabolic = 0x00000800, // Affects elevation computation, can't be combined with Falling flag
|
Parabolic = 0x00000800, // Affects elevation computation, can't be combined with Falling flag
|
||||||
Walkmode = 0x00001000,
|
CanSwim = 0x00001000,
|
||||||
Flying = 0x00002000, // Smooth movement(Catmullrom interpolation mode), flying animation
|
Flying = 0x00002000, // Smooth movement(Catmullrom interpolation mode), flying animation
|
||||||
OrientationFixed = 0x00004000, // Model orientation fixed
|
OrientationFixed = 0x00004000, // Model orientation fixed
|
||||||
Final_Point = 0x00008000,
|
Final_Point = 0x00008000,
|
||||||
@@ -117,7 +117,7 @@ namespace Movement
|
|||||||
bool falling : 1;
|
bool falling : 1;
|
||||||
bool no_spline : 1;
|
bool no_spline : 1;
|
||||||
bool parabolic : 1;
|
bool parabolic : 1;
|
||||||
bool walkmode : 1;
|
bool canSwim : 1;
|
||||||
bool flying : 1;
|
bool flying : 1;
|
||||||
bool orientationFixed : 1;
|
bool orientationFixed : 1;
|
||||||
bool final_point : 1;
|
bool final_point : 1;
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ namespace Movement
|
|||||||
// If spline is initialized with SetWalk method it only means we need to select
|
// If spline is initialized with SetWalk method it only means we need to select
|
||||||
// walk move speed for it but not add walk flag to unit
|
// walk move speed for it but not add walk flag to unit
|
||||||
uint32 moveFlagsForSpeed = moveFlags;
|
uint32 moveFlagsForSpeed = moveFlags;
|
||||||
if (args.flags.walkmode)
|
if (args.walk)
|
||||||
moveFlagsForSpeed |= MOVEMENTFLAG_WALKING;
|
moveFlagsForSpeed |= MOVEMENTFLAG_WALKING;
|
||||||
else
|
else
|
||||||
moveFlagsForSpeed &= ~MOVEMENTFLAG_WALKING;
|
moveFlagsForSpeed &= ~MOVEMENTFLAG_WALKING;
|
||||||
@@ -199,7 +199,7 @@ namespace Movement
|
|||||||
args.splineId = splineIdGen.NewId();
|
args.splineId = splineIdGen.NewId();
|
||||||
args.TransformForTransport = unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID();
|
args.TransformForTransport = unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID();
|
||||||
// mix existing state into new
|
// mix existing state into new
|
||||||
args.flags.walkmode = unit->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);
|
args.walk = unit->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);
|
||||||
args.flags.flying = unit->m_movementInfo.HasMovementFlag((MovementFlags)(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY));
|
args.flags.flying = unit->m_movementInfo.HasMovementFlag((MovementFlags)(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ namespace Movement
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline void MoveSplineInit::SetFly() { args.flags.EnableFlying(); }
|
inline void MoveSplineInit::SetFly() { args.flags.EnableFlying(); }
|
||||||
inline void MoveSplineInit::SetWalk(bool enable) { args.flags.walkmode = enable; }
|
inline void MoveSplineInit::SetWalk(bool enable) { args.walk = enable; }
|
||||||
inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom(); }
|
inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom(); }
|
||||||
inline void MoveSplineInit::SetCyclic() { args.flags.cyclic = true; }
|
inline void MoveSplineInit::SetCyclic() { args.flags.cyclic = true; }
|
||||||
inline void MoveSplineInit::SetFall() { args.flags.EnableFalling(); }
|
inline void MoveSplineInit::SetFall() { args.flags.EnableFalling(); }
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ namespace Movement
|
|||||||
float initialOrientation{0.f};
|
float initialOrientation{0.f};
|
||||||
bool HasVelocity{false};
|
bool HasVelocity{false};
|
||||||
bool TransformForTransport{true};
|
bool TransformForTransport{true};
|
||||||
|
bool walk;
|
||||||
|
|
||||||
/** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */
|
/** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */
|
||||||
bool Validate(Unit* unit) const;
|
bool Validate(Unit* unit) const;
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ namespace Movement
|
|||||||
STR(Falling ), // 0x00000200, // Not Compartible With Trajectory Movement
|
STR(Falling ), // 0x00000200, // Not Compartible With Trajectory Movement
|
||||||
STR(No_Spline ), // 0x00000400,
|
STR(No_Spline ), // 0x00000400,
|
||||||
STR(Trajectory ), // 0x00000800, // Not Compartible With Fall Movement
|
STR(Trajectory ), // 0x00000800, // Not Compartible With Fall Movement
|
||||||
STR(Walkmode ), // 0x00001000,
|
STR(CanSwim ), // 0x00001000,
|
||||||
STR(Flying ), // 0x00002000, // Smooth Movement(Catmullrom Interpolation Mode), Flying Animation
|
STR(Flying ), // 0x00002000, // Smooth Movement(Catmullrom Interpolation Mode), Flying Animation
|
||||||
STR(Knockback ), // 0x00004000, // Model Orientation Fixed
|
STR(Knockback ), // 0x00004000, // Model Orientation Fixed
|
||||||
STR(Final_Point ), // 0x00008000,
|
STR(Final_Point ), // 0x00008000,
|
||||||
|
|||||||
@@ -29,14 +29,14 @@ void ScriptMgr::OnNetworkStop()
|
|||||||
CALL_ENABLED_HOOKS(ServerScript, SERVERHOOK_ON_NETWORK_STOP, script->OnNetworkStop());
|
CALL_ENABLED_HOOKS(ServerScript, SERVERHOOK_ON_NETWORK_STOP, script->OnNetworkStop());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptMgr::OnSocketOpen(std::shared_ptr<WorldSocket> socket)
|
void ScriptMgr::OnSocketOpen(std::shared_ptr<WorldSocket> const& socket)
|
||||||
{
|
{
|
||||||
ASSERT(socket);
|
ASSERT(socket);
|
||||||
|
|
||||||
CALL_ENABLED_HOOKS(ServerScript, SERVERHOOK_ON_SOCKET_OPEN, script->OnSocketOpen(socket));
|
CALL_ENABLED_HOOKS(ServerScript, SERVERHOOK_ON_SOCKET_OPEN, script->OnSocketOpen(socket));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptMgr::OnSocketClose(std::shared_ptr<WorldSocket> socket)
|
void ScriptMgr::OnSocketClose(std::shared_ptr<WorldSocket> const& socket)
|
||||||
{
|
{
|
||||||
ASSERT(socket);
|
ASSERT(socket);
|
||||||
|
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ public:
|
|||||||
virtual void OnNetworkStop() { }
|
virtual void OnNetworkStop() { }
|
||||||
|
|
||||||
// Called when a remote socket establishes a connection to the server. Do not store the socket object.
|
// Called when a remote socket establishes a connection to the server. Do not store the socket object.
|
||||||
virtual void OnSocketOpen(std::shared_ptr<WorldSocket> /*socket*/) { }
|
virtual void OnSocketOpen(std::shared_ptr<WorldSocket> const& /*socket*/) { }
|
||||||
|
|
||||||
// Called when a socket is closed. Do not store the socket object, and do not rely on the connection
|
// Called when a socket is closed. Do not store the socket object, and do not rely on the connection
|
||||||
// being open; it is not.
|
// being open; it is not.
|
||||||
virtual void OnSocketClose(std::shared_ptr<WorldSocket> /*socket*/) { }
|
virtual void OnSocketClose(std::shared_ptr<WorldSocket> const& /*socket*/) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This hook called when a packet is sent to a client. The packet object is a copy of the original packet, so reading and modifying it is safe.
|
* @brief This hook called when a packet is sent to a client. The packet object is a copy of the original packet, so reading and modifying it is safe.
|
||||||
|
|||||||
@@ -174,8 +174,8 @@ public: /* SpellScriptLoader */
|
|||||||
public: /* ServerScript */
|
public: /* ServerScript */
|
||||||
void OnNetworkStart();
|
void OnNetworkStart();
|
||||||
void OnNetworkStop();
|
void OnNetworkStop();
|
||||||
void OnSocketOpen(std::shared_ptr<WorldSocket> socket);
|
void OnSocketOpen(std::shared_ptr<WorldSocket> const& socket);
|
||||||
void OnSocketClose(std::shared_ptr<WorldSocket> socket);
|
void OnSocketClose(std::shared_ptr<WorldSocket> const& socket);
|
||||||
bool CanPacketReceive(WorldSession* session, WorldPacket const& packet);
|
bool CanPacketReceive(WorldSession* session, WorldPacket const& packet);
|
||||||
void OnPacketReceived(WorldSession* session, WorldPacket const& packet);
|
void OnPacketReceived(WorldSession* session, WorldPacket const& packet);
|
||||||
bool CanPacketSend(WorldSession* session, WorldPacket const& packet);
|
bool CanPacketSend(WorldSession* session, WorldPacket const& packet);
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ void EncryptableAndCompressiblePacket::CompressIfNeeded()
|
|||||||
SetOpcode(SMSG_COMPRESSED_UPDATE_OBJECT);
|
SetOpcode(SMSG_COMPRESSED_UPDATE_OBJECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldSocket::WorldSocket(tcp::socket&& socket)
|
WorldSocket::WorldSocket(IoContextTcpSocket&& socket)
|
||||||
: Socket(std::move(socket)), _OverSpeedPings(0), _worldSession(nullptr), _authed(false), _sendBufferSize(4096), _loggingPackets(false)
|
: Socket(std::move(socket)), _OverSpeedPings(0), _worldSession(nullptr), _authed(false), _sendBufferSize(4096), _loggingPackets(false)
|
||||||
{
|
{
|
||||||
Acore::Crypto::GetRandomBytes(_authSeed);
|
Acore::Crypto::GetRandomBytes(_authSeed);
|
||||||
@@ -238,10 +238,10 @@ void WorldSocket::OnClose()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSocket::ReadHandler()
|
SocketReadCallbackResult WorldSocket::ReadHandler()
|
||||||
{
|
{
|
||||||
if (!IsOpen())
|
if (!IsOpen())
|
||||||
return;
|
return SocketReadCallbackResult::Stop;
|
||||||
|
|
||||||
MessageBuffer& packet = GetReadBuffer();
|
MessageBuffer& packet = GetReadBuffer();
|
||||||
while (packet.GetActiveSize() > 0)
|
while (packet.GetActiveSize() > 0)
|
||||||
@@ -264,7 +264,7 @@ void WorldSocket::ReadHandler()
|
|||||||
if (!ReadHeaderHandler())
|
if (!ReadHeaderHandler())
|
||||||
{
|
{
|
||||||
CloseSocket();
|
CloseSocket();
|
||||||
return;
|
return SocketReadCallbackResult::Stop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,11 +295,11 @@ void WorldSocket::ReadHandler()
|
|||||||
CloseSocket();
|
CloseSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return SocketReadCallbackResult::Stop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncRead();
|
return SocketReadCallbackResult::KeepReading;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WorldSocket::ReadHeaderHandler()
|
bool WorldSocket::ReadHeaderHandler()
|
||||||
@@ -329,7 +329,7 @@ bool WorldSocket::ReadHeaderHandler()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AuthSession
|
struct ClientAuthSession
|
||||||
{
|
{
|
||||||
uint32 BattlegroupID = 0;
|
uint32 BattlegroupID = 0;
|
||||||
uint32 LoginServerType = 0;
|
uint32 LoginServerType = 0;
|
||||||
@@ -528,7 +528,7 @@ void WorldSocket::SendPacket(WorldPacket const& packet)
|
|||||||
|
|
||||||
void WorldSocket::HandleAuthSession(WorldPacket & recvPacket)
|
void WorldSocket::HandleAuthSession(WorldPacket & recvPacket)
|
||||||
{
|
{
|
||||||
std::shared_ptr<AuthSession> authSession = std::make_shared<AuthSession>();
|
std::shared_ptr<ClientAuthSession> authSession = std::make_shared<ClientAuthSession>();
|
||||||
|
|
||||||
// Read the content of the packet
|
// Read the content of the packet
|
||||||
recvPacket >> authSession->Build;
|
recvPacket >> authSession->Build;
|
||||||
@@ -552,7 +552,7 @@ void WorldSocket::HandleAuthSession(WorldPacket & recvPacket)
|
|||||||
_queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1)));
|
_queryProcessor.AddCallback(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSession, PreparedQueryResult result)
|
void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<ClientAuthSession> authSession, PreparedQueryResult result)
|
||||||
{
|
{
|
||||||
// Stop if the account is not found
|
// Stop if the account is not found
|
||||||
if (!result)
|
if (!result)
|
||||||
|
|||||||
@@ -65,21 +65,21 @@ struct ClientPktHeader
|
|||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
struct AuthSession;
|
struct ClientAuthSession;
|
||||||
|
|
||||||
class AC_GAME_API WorldSocket : public Socket<WorldSocket>
|
class AC_GAME_API WorldSocket final : public Socket<WorldSocket>
|
||||||
{
|
{
|
||||||
typedef Socket<WorldSocket> BaseSocket;
|
typedef Socket<WorldSocket> BaseSocket;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WorldSocket(tcp::socket&& socket);
|
WorldSocket(IoContextTcpSocket&& socket);
|
||||||
~WorldSocket();
|
~WorldSocket();
|
||||||
|
|
||||||
WorldSocket(WorldSocket const& right) = delete;
|
WorldSocket(WorldSocket const& right) = delete;
|
||||||
WorldSocket& operator=(WorldSocket const& right) = delete;
|
WorldSocket& operator=(WorldSocket const& right) = delete;
|
||||||
|
|
||||||
void Start() override;
|
void Start() override;
|
||||||
bool Update() override;
|
bool Update() final;
|
||||||
|
|
||||||
void SendPacket(WorldPacket const& packet);
|
void SendPacket(WorldPacket const& packet);
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void OnClose() override;
|
void OnClose() override;
|
||||||
void ReadHandler() override;
|
SocketReadCallbackResult ReadHandler() final;
|
||||||
bool ReadHeaderHandler();
|
bool ReadHeaderHandler();
|
||||||
|
|
||||||
enum class ReadDataHandlerResult
|
enum class ReadDataHandlerResult
|
||||||
@@ -113,7 +113,7 @@ private:
|
|||||||
void SendPacketAndLogOpcode(WorldPacket const& packet);
|
void SendPacketAndLogOpcode(WorldPacket const& packet);
|
||||||
void HandleSendAuthSession();
|
void HandleSendAuthSession();
|
||||||
void HandleAuthSession(WorldPacket& recvPacket);
|
void HandleAuthSession(WorldPacket& recvPacket);
|
||||||
void HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSession, PreparedQueryResult result);
|
void HandleAuthSessionCallback(std::shared_ptr<ClientAuthSession> authSession, PreparedQueryResult result);
|
||||||
void LoadSessionPermissionsCallback(PreparedQueryResult result);
|
void LoadSessionPermissionsCallback(PreparedQueryResult result);
|
||||||
void SendAuthResponseError(uint8 code);
|
void SendAuthResponseError(uint8 code);
|
||||||
|
|
||||||
|
|||||||
@@ -25,13 +25,13 @@
|
|||||||
class WorldSocketThread : public NetworkThread<WorldSocket>
|
class WorldSocketThread : public NetworkThread<WorldSocket>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void SocketAdded(std::shared_ptr<WorldSocket> sock) override
|
void SocketAdded(std::shared_ptr<WorldSocket> const& sock) override
|
||||||
{
|
{
|
||||||
sock->SetSendBufferSize(sWorldSocketMgr.GetApplicationSendBufferSize());
|
sock->SetSendBufferSize(sWorldSocketMgr.GetApplicationSendBufferSize());
|
||||||
sScriptMgr->OnSocketOpen(sock);
|
sScriptMgr->OnSocketOpen(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketRemoved(std::shared_ptr<WorldSocket> sock) override
|
void SocketRemoved(std::shared_ptr<WorldSocket> const& sock) override
|
||||||
{
|
{
|
||||||
sScriptMgr->OnSocketClose(sock);
|
sScriptMgr->OnSocketClose(sock);
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ void WorldSocketMgr::StopNetwork()
|
|||||||
sScriptMgr->OnNetworkStop();
|
sScriptMgr->OnNetworkStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSocketMgr::OnSocketOpen(tcp::socket&& sock, uint32 threadIndex)
|
void WorldSocketMgr::OnSocketOpen(IoContextTcpSocket&& sock, uint32 threadIndex)
|
||||||
{
|
{
|
||||||
// set some options here
|
// set some options here
|
||||||
if (_socketSystemSendBufferSize >= 0)
|
if (_socketSystemSendBufferSize >= 0)
|
||||||
@@ -109,7 +109,7 @@ void WorldSocketMgr::OnSocketOpen(tcp::socket&& sock, uint32 threadIndex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseSocketMgr::OnSocketOpen(std::forward<tcp::socket>(sock), threadIndex);
|
BaseSocketMgr::OnSocketOpen(std::move(sock), threadIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkThread<WorldSocket>* WorldSocketMgr::CreateThreads() const
|
NetworkThread<WorldSocket>* WorldSocketMgr::CreateThreads() const
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public:
|
|||||||
/// Stops all network threads, It will wait for all running threads .
|
/// Stops all network threads, It will wait for all running threads .
|
||||||
void StopNetwork() override;
|
void StopNetwork() override;
|
||||||
|
|
||||||
void OnSocketOpen(tcp::socket&& sock, uint32 threadIndex) override;
|
void OnSocketOpen(IoContextTcpSocket&& sock, uint32 threadIndex) override;
|
||||||
|
|
||||||
std::size_t GetApplicationSendBufferSize() const { return _socketApplicationSendBufferSize; }
|
std::size_t GetApplicationSendBufferSize() const { return _socketApplicationSendBufferSize; }
|
||||||
|
|
||||||
@@ -50,9 +50,9 @@ protected:
|
|||||||
|
|
||||||
NetworkThread<WorldSocket>* CreateThreads() const override;
|
NetworkThread<WorldSocket>* CreateThreads() const override;
|
||||||
|
|
||||||
static void OnSocketAccept(tcp::socket&& sock, uint32 threadIndex)
|
static void OnSocketAccept(IoContextTcpSocket&& sock, uint32 threadIndex)
|
||||||
{
|
{
|
||||||
Instance().OnSocketOpen(std::forward<tcp::socket>(sock), threadIndex);
|
Instance().OnSocketOpen(std::move(sock), threadIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "Chat.h"
|
#include "Chat.h"
|
||||||
#include "CommandScript.h"
|
#include "CommandScript.h"
|
||||||
|
#include "GroupMgr.h"
|
||||||
#include "Language.h"
|
#include "Language.h"
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "SpellAuras.h"
|
#include "SpellAuras.h"
|
||||||
@@ -211,6 +212,16 @@ public:
|
|||||||
CharacterDatabase.Execute(stmt);
|
CharacterDatabase.Execute(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isInstance)
|
||||||
|
{
|
||||||
|
if (ObjectGuid groupId = sCharacterCache->GetCharacterGroupGuidByGuid(guid))
|
||||||
|
if (Group* group = sGroupMgr->GetGroupByGUID(groupId.GetCounter()))
|
||||||
|
if (group->isLFGGroup())
|
||||||
|
Player::RemoveFromGroup(group, guid);
|
||||||
|
}
|
||||||
|
else if (target && target->GetMap()->IsBattleground())
|
||||||
|
target->LeaveBattleground();
|
||||||
|
|
||||||
handler->PSendSysMessage("{} of {} Deserter has been added to player {}.", secsToTimeString(duration), isInstance ? "Instance" : "Battleground", handler->playerLink(*playerName));
|
handler->PSendSysMessage("{} of {} Deserter has been added to player {}.", secsToTimeString(duration), isInstance ? "Instance" : "Battleground", handler->playerLink(*playerName));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ struct boss_archimonde : public BossAI
|
|||||||
scheduler.CancelAll();
|
scheduler.CancelAll();
|
||||||
me->SetReactState(REACT_PASSIVE);
|
me->SetReactState(REACT_PASSIVE);
|
||||||
DoCastAOE(SPELL_PROTECTION_OF_ELUNE, true);
|
DoCastAOE(SPELL_PROTECTION_OF_ELUNE, true);
|
||||||
Talk(SAY_ENRAGE);
|
Talk(SAY_DEATH);
|
||||||
_enraged = true;
|
_enraged = true;
|
||||||
me->GetMotionMaster()->Clear(false);
|
me->GetMotionMaster()->Clear(false);
|
||||||
me->GetMotionMaster()->MoveIdle();
|
me->GetMotionMaster()->MoveIdle();
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ struct boss_hadronox : public BossAI
|
|||||||
SummonCrusherPack(SUMMON_GROUP_CRUSHER_3);
|
SummonCrusherPack(SUMMON_GROUP_CRUSHER_3);
|
||||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE1, 0s);
|
events.ScheduleEvent(EVENT_HADRONOX_MOVE1, 0s);
|
||||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE2, 45s);
|
events.ScheduleEvent(EVENT_HADRONOX_MOVE2, 45s);
|
||||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE3, 90s);
|
events.ScheduleEvent(EVENT_HADRONOX_MOVE3, 70s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1137,7 +1137,7 @@ public:
|
|||||||
{
|
{
|
||||||
me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL);
|
me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL);
|
||||||
Talk(SAY_LK_SUMMON_VALKYR);
|
Talk(SAY_LK_SUMMON_VALKYR);
|
||||||
DoCastSelf(IsHeroic() ? SPELL_SUMMON_VALKYR_PERIODIC : SPELL_SUMMON_VALKYR);
|
DoCastSelf(Is25ManRaid() ? SPELL_SUMMON_VALKYR_PERIODIC : SPELL_SUMMON_VALKYR);
|
||||||
events.ScheduleEvent(EVENT_SUMMON_VALKYR, 45s, EVENT_GROUP_ABILITIES);
|
events.ScheduleEvent(EVENT_SUMMON_VALKYR, 45s, EVENT_GROUP_ABILITIES);
|
||||||
|
|
||||||
// schedule a defile (or reschedule it) if next defile event
|
// schedule a defile (or reschedule it) if next defile event
|
||||||
|
|||||||
@@ -44,10 +44,7 @@ enum Spells
|
|||||||
|
|
||||||
enum Misc
|
enum Misc
|
||||||
{
|
{
|
||||||
ACHIEV_TIMED_START_EVENT = 9891,
|
ACHIEV_TIMED_START_EVENT = 9891
|
||||||
EVENT_SPAWN_CRYPT_GUARDS_1 = 0,
|
|
||||||
EVENT_BERSERK = 1,
|
|
||||||
EVENT_SPAWN_CRYPT_GUARDS_EXTRA = 2,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Position const cryptguardPositions[] = {
|
Position const cryptguardPositions[] = {
|
||||||
@@ -121,9 +118,10 @@ struct boss_anubrekhan : public BossAI
|
|||||||
SummonCryptGuards();
|
SummonCryptGuards();
|
||||||
if (!Is25ManRaid())
|
if (!Is25ManRaid())
|
||||||
{
|
{
|
||||||
ScheduleUniqueTimedEvent(17500ms, [&] {
|
me->m_Events.AddEventAtOffset([this]()
|
||||||
|
{
|
||||||
me->SummonCreature(NPC_CRYPT_GUARD, cryptguardPositions[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
|
me->SummonCreature(NPC_CRYPT_GUARD, cryptguardPositions[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000);
|
||||||
}, EVENT_SPAWN_CRYPT_GUARDS_1);
|
}, 17500ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScheduleTimedEvent(15s, [&] {
|
ScheduleTimedEvent(15s, [&] {
|
||||||
|
|||||||
@@ -255,7 +255,8 @@ class spell_gluth_decimate : public SpellScript
|
|||||||
Unit::DealDamage(GetCaster(), cTarget, damage);
|
Unit::DealDamage(GetCaster(), cTarget, damage);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GetCaster()->CastCustomSpell(SPELL_DECIMATE_DAMAGE, SPELLVALUE_BASE_POINT0, damage, unitTarget);
|
|
||||||
|
GetCaster()->CastSpell(unitTarget, SPELL_DECIMATE_DAMAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,8 +266,38 @@ class spell_gluth_decimate : public SpellScript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 28375 - Decimate
|
||||||
|
class spell_gluth_decimate_damage : public SpellScript
|
||||||
|
{
|
||||||
|
PrepareSpellScript(spell_gluth_decimate_damage)
|
||||||
|
|
||||||
|
void RecalculateDamage()
|
||||||
|
{
|
||||||
|
Unit* target = GetHitUnit();
|
||||||
|
if (!target)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 targetHealth = int32(target->GetHealth());
|
||||||
|
int32 fivePctHealth = int32(target->CountPctFromMaxHealth(5));
|
||||||
|
|
||||||
|
// Damage needed to leave the target at exactly 5%
|
||||||
|
int32 damage = targetHealth - fivePctHealth;
|
||||||
|
|
||||||
|
if (damage <= 0)
|
||||||
|
damage = 0;
|
||||||
|
|
||||||
|
SetHitDamage(damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnHit += SpellHitFn(spell_gluth_decimate_damage::RecalculateDamage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void AddSC_boss_gluth()
|
void AddSC_boss_gluth()
|
||||||
{
|
{
|
||||||
new boss_gluth();
|
new boss_gluth();
|
||||||
RegisterSpellScript(spell_gluth_decimate);
|
RegisterSpellScript(spell_gluth_decimate);
|
||||||
|
RegisterSpellScript(spell_gluth_decimate_damage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "CreatureScript.h"
|
#include "CreatureScript.h"
|
||||||
#include "InstanceMapScript.h"
|
#include "InstanceMapScript.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
|
#include "TaskScheduler.h"
|
||||||
#include "nexus.h"
|
#include "nexus.h"
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "Group.h"
|
#include "Group.h"
|
||||||
@@ -44,6 +45,8 @@ public:
|
|||||||
{
|
{
|
||||||
instance_nexus_InstanceMapScript(Map* map) : InstanceScript(map) {}
|
instance_nexus_InstanceMapScript(Map* map) : InstanceScript(map) {}
|
||||||
|
|
||||||
|
GuidVector _frayerGUIDs;
|
||||||
|
|
||||||
void Initialize() override
|
void Initialize() override
|
||||||
{
|
{
|
||||||
SetHeaders(DataHeader);
|
SetHeaders(DataHeader);
|
||||||
@@ -80,6 +83,23 @@ public:
|
|||||||
if (GetTeamIdInInstance() == TEAM_ALLIANCE)
|
if (GetTeamIdInInstance() == TEAM_ALLIANCE)
|
||||||
creature->UpdateEntry(NPC_COMMANDER_KOLURG);
|
creature->UpdateEntry(NPC_COMMANDER_KOLURG);
|
||||||
break;
|
break;
|
||||||
|
case NPC_CRYSTALLINE_FRAYER:
|
||||||
|
_frayerGUIDs.push_back(creature->GetGUID());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KillAllFrayers()
|
||||||
|
{
|
||||||
|
for (ObjectGuid const& guid : _frayerGUIDs)
|
||||||
|
{
|
||||||
|
if (Creature* frayer = instance->GetCreature(guid))
|
||||||
|
{
|
||||||
|
frayer->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
frayer->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
|
||||||
|
frayer->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
|
||||||
|
Unit::Kill(frayer, frayer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +161,13 @@ public:
|
|||||||
if (!InstanceScript::SetBossState(id, state))
|
if (!InstanceScript::SetBossState(id, state))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (state != DONE || id > DATA_ORMOROK_EVENT)
|
if (state != DONE)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (id == DATA_ORMOROK_EVENT)
|
||||||
|
KillAllFrayers();
|
||||||
|
|
||||||
|
if (id > DATA_ORMOROK_EVENT)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
BossInfo const* bossInfo = GetBossInfo(id + DATA_TELESTRA_ORB);
|
BossInfo const* bossInfo = GetBossInfo(id + DATA_TELESTRA_ORB);
|
||||||
@@ -156,9 +182,17 @@ enum eFrayer
|
|||||||
{
|
{
|
||||||
SPELL_SUMMON_SEED_POD = 52796,
|
SPELL_SUMMON_SEED_POD = 52796,
|
||||||
SPELL_SEED_POD = 48082,
|
SPELL_SEED_POD = 48082,
|
||||||
SPELL_AURA_OF_REGENERATION = 52067,
|
SPELL_AURA_OF_REGENERATION = 57056,
|
||||||
SPELL_CRYSTAL_BLOOM = 48058,
|
SPELL_CRYSTAL_BLOOM = 48058,
|
||||||
SPELL_ENSNARE = 48053
|
SPELL_ENSNARE = 48053,
|
||||||
|
|
||||||
|
SAY_EMOTE = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FrayerGroups
|
||||||
|
{
|
||||||
|
GROUP_COMBAT = 1,
|
||||||
|
GROUP_SEED_POD = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
struct npc_crystalline_frayer : public ScriptedAI
|
struct npc_crystalline_frayer : public ScriptedAI
|
||||||
@@ -166,27 +200,44 @@ struct npc_crystalline_frayer : public ScriptedAI
|
|||||||
npc_crystalline_frayer(Creature* creature) : ScriptedAI(creature) { }
|
npc_crystalline_frayer(Creature* creature) : ScriptedAI(creature) { }
|
||||||
|
|
||||||
bool _allowDeath;
|
bool _allowDeath;
|
||||||
uint32 restoreTimer;
|
bool _inSeedPod;
|
||||||
uint32 abilityTimer1;
|
TaskScheduler _scheduler;
|
||||||
uint32 abilityTimer2;
|
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
restoreTimer = 0;
|
_allowDeath = false;
|
||||||
abilityTimer1 = 0;
|
_inSeedPod = false;
|
||||||
abilityTimer2 = 30000;
|
_scheduler.CancelAll();
|
||||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
|
||||||
|
me->RemoveAllAuras();
|
||||||
|
me->SetObjectScale(1.0f);
|
||||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
|
||||||
|
me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
|
||||||
|
me->SetRegeneratingHealth(true);
|
||||||
|
me->SetReactState(REACT_AGGRESSIVE);
|
||||||
|
me->GetMotionMaster()->MoveRandom(10.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustEngagedWith(Unit*) override
|
void JustEngagedWith(Unit*) override
|
||||||
{
|
{
|
||||||
_allowDeath = me->GetInstanceScript()->GetBossState(DATA_ORMOROK_EVENT) == DONE;
|
if (InstanceScript* instance = me->GetInstanceScript())
|
||||||
|
_allowDeath = instance->GetBossState(DATA_ORMOROK_EVENT) == DONE;
|
||||||
|
|
||||||
|
_scheduler.Schedule(5s, GROUP_COMBAT, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_ENSNARE);
|
||||||
|
context.Repeat(5s);
|
||||||
|
}).Schedule(0s, GROUP_COMBAT, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_CRYSTAL_BLOOM);
|
||||||
|
context.Repeat(30s);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnterEvadeMode(EvadeReason why) override
|
void EnterEvadeMode(EvadeReason why) override
|
||||||
{
|
{
|
||||||
if (me->isRegeneratingHealth())
|
if (!_inSeedPod)
|
||||||
ScriptedAI::EnterEvadeMode(why);
|
ScriptedAI::EnterEvadeMode(why);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,57 +247,67 @@ struct npc_crystalline_frayer : public ScriptedAI
|
|||||||
{
|
{
|
||||||
if (!_allowDeath)
|
if (!_allowDeath)
|
||||||
{
|
{
|
||||||
me->RemoveAllAuras();
|
|
||||||
me->GetThreatMgr().ClearAllThreat();
|
|
||||||
me->CombatStop(true);
|
|
||||||
damage = 0;
|
damage = 0;
|
||||||
|
EnterSeedPod();
|
||||||
me->SetReactState(REACT_PASSIVE);
|
|
||||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
|
||||||
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
|
||||||
me->SetRegeneratingHealth(false);
|
|
||||||
me->CastSpell(me, SPELL_SUMMON_SEED_POD, true);
|
|
||||||
me->CastSpell(me, SPELL_SEED_POD, true);
|
|
||||||
me->CastSpell(me, SPELL_AURA_OF_REGENERATION, false);
|
|
||||||
restoreTimer = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnterSeedPod()
|
||||||
|
{
|
||||||
|
_inSeedPod = true;
|
||||||
|
_scheduler.CancelGroup(GROUP_COMBAT);
|
||||||
|
|
||||||
|
me->AttackStop();
|
||||||
|
me->GetThreatMgr().ClearAllThreat();
|
||||||
|
me->CombatStop(true);
|
||||||
|
me->RemoveAllAuras();
|
||||||
|
|
||||||
|
me->SetReactState(REACT_PASSIVE);
|
||||||
|
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
|
||||||
|
me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
|
||||||
|
me->SetRegeneratingHealth(false);
|
||||||
|
me->SetObjectScale(0.6f);
|
||||||
|
|
||||||
|
DoCastSelf(SPELL_SEED_POD, true);
|
||||||
|
DoCastSelf(SPELL_SUMMON_SEED_POD, true);
|
||||||
|
DoCastSelf(SPELL_AURA_OF_REGENERATION, true);
|
||||||
|
|
||||||
|
_scheduler.Schedule(90s, GROUP_SEED_POD, [this](TaskContext /*context*/)
|
||||||
|
{
|
||||||
|
LeaveSeedPod();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void LeaveSeedPod()
|
||||||
|
{
|
||||||
|
_inSeedPod = false;
|
||||||
|
|
||||||
|
Talk(SAY_EMOTE);
|
||||||
|
|
||||||
|
me->RemoveAurasDueToSpell(SPELL_SEED_POD);
|
||||||
|
me->RemoveAurasDueToSpell(SPELL_AURA_OF_REGENERATION);
|
||||||
|
|
||||||
|
me->SetObjectScale(1.0f);
|
||||||
|
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
|
||||||
|
me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
|
||||||
|
me->SetRegeneratingHealth(true);
|
||||||
|
|
||||||
|
me->SetReactState(REACT_AGGRESSIVE);
|
||||||
|
me->GetMotionMaster()->MoveRandom(10.0f);
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void UpdateAI(uint32 diff) override
|
||||||
{
|
{
|
||||||
if (restoreTimer)
|
_scheduler.Update(diff);
|
||||||
{
|
|
||||||
restoreTimer += diff;
|
if (_inSeedPod)
|
||||||
if (restoreTimer >= 90 * IN_MILLISECONDS)
|
|
||||||
{
|
|
||||||
Talk(0);
|
|
||||||
me->SetRegeneratingHealth(true);
|
|
||||||
restoreTimer = 0;
|
|
||||||
me->SetReactState(REACT_AGGRESSIVE);
|
|
||||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
|
||||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
abilityTimer1 += diff;
|
|
||||||
abilityTimer2 += diff;
|
|
||||||
|
|
||||||
if (abilityTimer1 >= 5000)
|
|
||||||
{
|
|
||||||
me->CastSpell(me->GetVictim(), SPELL_ENSNARE, false);
|
|
||||||
abilityTimer1 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (abilityTimer2 >= 30000)
|
|
||||||
{
|
|
||||||
me->CastSpell(me->GetVictim(), SPELL_CRYSTAL_BLOOM, false);
|
|
||||||
abilityTimer2 = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ enum Npcs
|
|||||||
|
|
||||||
NPC_COMMANDER_STOUTBEARD = 26796,
|
NPC_COMMANDER_STOUTBEARD = 26796,
|
||||||
NPC_COMMANDER_KOLURG = 26798,
|
NPC_COMMANDER_KOLURG = 26798,
|
||||||
|
NPC_CRYSTALLINE_FRAYER = 26793,
|
||||||
|
|
||||||
GO_TELESTRA_SPHERE = 188526,
|
GO_TELESTRA_SPHERE = 188526,
|
||||||
GO_ANOMALUS_SPHERE = 188527,
|
GO_ANOMALUS_SPHERE = 188527,
|
||||||
|
|||||||
@@ -276,6 +276,7 @@ public:
|
|||||||
orb->RemoveAurasDueToSpell(SPELL_AWAKEN_SUBBOSS);
|
orb->RemoveAurasDueToSpell(SPELL_AWAKEN_SUBBOSS);
|
||||||
|
|
||||||
me->RemoveAurasDueToSpell(SPELL_FREEZE);
|
me->RemoveAurasDueToSpell(SPELL_FREEZE);
|
||||||
|
me->GetThreatMgr().ResetAllThreat();
|
||||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||||
// SETINCOMBATWITHZONE
|
// SETINCOMBATWITHZONE
|
||||||
|
|||||||
@@ -610,150 +610,6 @@ private:
|
|||||||
BetrayalState _state;
|
BetrayalState _state;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*####
|
|
||||||
## npc_drakuru_shackles
|
|
||||||
####*/
|
|
||||||
|
|
||||||
enum DrakuruShackles
|
|
||||||
{
|
|
||||||
NPC_RAGECLAW = 29686,
|
|
||||||
QUEST_TROLLS_IS_GONE_CRAZY = 12861,
|
|
||||||
SPELL_LEFT_CHAIN = 59951,
|
|
||||||
SPELL_RIGHT_CHAIN = 59952,
|
|
||||||
SPELL_UNLOCK_SHACKLE = 55083,
|
|
||||||
SPELL_FREE_RAGECLAW = 55223
|
|
||||||
};
|
|
||||||
|
|
||||||
class npc_drakuru_shackles : public CreatureScript
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
npc_drakuru_shackles() : CreatureScript("npc_drakuru_shackles") { }
|
|
||||||
|
|
||||||
struct npc_drakuru_shacklesAI : public NullCreatureAI
|
|
||||||
{
|
|
||||||
npc_drakuru_shacklesAI(Creature* creature) : NullCreatureAI(creature)
|
|
||||||
{
|
|
||||||
_rageclawGUID.Clear();
|
|
||||||
timer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset() override
|
|
||||||
{
|
|
||||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
timer += diff;
|
|
||||||
if (timer >= 2000)
|
|
||||||
{
|
|
||||||
timer = 0;
|
|
||||||
if (_rageclawGUID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (Creature* cr = me->FindNearestCreature(NPC_RAGECLAW, 10.0f))
|
|
||||||
{
|
|
||||||
_rageclawGUID = cr->GetGUID();
|
|
||||||
LockRageclaw(cr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LockRageclaw(Creature* rageclaw)
|
|
||||||
{
|
|
||||||
// pointer check not needed
|
|
||||||
me->SetFacingToObject(rageclaw);
|
|
||||||
rageclaw->SetFacingToObject(me);
|
|
||||||
|
|
||||||
DoCast(rageclaw, SPELL_LEFT_CHAIN, true);
|
|
||||||
DoCast(rageclaw, SPELL_RIGHT_CHAIN, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnlockRageclaw(Unit* /*who*/, Creature* rageclaw)
|
|
||||||
{
|
|
||||||
// pointer check not needed
|
|
||||||
DoCast(rageclaw, SPELL_FREE_RAGECLAW, true);
|
|
||||||
_rageclawGUID.Clear();
|
|
||||||
me->DespawnOrUnsummon(1ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpellHit(Unit* caster, SpellInfo const* spell) override
|
|
||||||
{
|
|
||||||
if (spell->Id == SPELL_UNLOCK_SHACKLE)
|
|
||||||
{
|
|
||||||
if (caster->ToPlayer()->GetQuestStatus(QUEST_TROLLS_IS_GONE_CRAZY) == QUEST_STATUS_INCOMPLETE)
|
|
||||||
{
|
|
||||||
if (Creature* rageclaw = ObjectAccessor::GetCreature(*me, _rageclawGUID))
|
|
||||||
{
|
|
||||||
UnlockRageclaw(caster, rageclaw);
|
|
||||||
caster->ToPlayer()->KilledMonster(rageclaw->GetCreatureTemplate(), _rageclawGUID);
|
|
||||||
me->DespawnOrUnsummon();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
me->setDeathState(DeathState::JustDied);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ObjectGuid _rageclawGUID;
|
|
||||||
uint32 timer;
|
|
||||||
};
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
|
||||||
{
|
|
||||||
return new npc_drakuru_shacklesAI(creature);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*####
|
|
||||||
## npc_captured_rageclaw
|
|
||||||
####*/
|
|
||||||
|
|
||||||
enum Rageclaw
|
|
||||||
{
|
|
||||||
SPELL_UNSHACKLED = 55085,
|
|
||||||
SPELL_KNEEL = 39656,
|
|
||||||
SAY_RAGECLAW = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
class npc_captured_rageclaw : public CreatureScript
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
npc_captured_rageclaw() : CreatureScript("npc_captured_rageclaw") { }
|
|
||||||
|
|
||||||
struct npc_captured_rageclawAI : public NullCreatureAI
|
|
||||||
{
|
|
||||||
npc_captured_rageclawAI(Creature* creature) : NullCreatureAI(creature) { }
|
|
||||||
|
|
||||||
void Reset() override
|
|
||||||
{
|
|
||||||
me->SetFaction(FACTION_FRIENDLY);
|
|
||||||
DoCast(me, SPELL_KNEEL, true); // Little Hack for kneel - Thanks Illy :P
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
|
|
||||||
{
|
|
||||||
if (spell->Id == SPELL_FREE_RAGECLAW)
|
|
||||||
{
|
|
||||||
me->RemoveAurasDueToSpell(SPELL_LEFT_CHAIN);
|
|
||||||
me->RemoveAurasDueToSpell(SPELL_RIGHT_CHAIN);
|
|
||||||
me->RemoveAurasDueToSpell(SPELL_KNEEL);
|
|
||||||
me->SetFaction(me->GetCreatureTemplate()->faction);
|
|
||||||
DoCast(me, SPELL_UNSHACKLED, true);
|
|
||||||
Talk(SAY_RAGECLAW);
|
|
||||||
me->GetMotionMaster()->MoveRandom(10);
|
|
||||||
me->DespawnOrUnsummon(10s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
|
||||||
{
|
|
||||||
return new npc_captured_rageclawAI(creature);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*####
|
/*####
|
||||||
## npc_released_offspring_harkoa
|
## npc_released_offspring_harkoa
|
||||||
####*/
|
####*/
|
||||||
@@ -973,8 +829,6 @@ void AddSC_zuldrak()
|
|||||||
new npc_finklestein();
|
new npc_finklestein();
|
||||||
new go_finklestein_cauldron();
|
new go_finklestein_cauldron();
|
||||||
RegisterCreatureAI(npc_overlord_drakuru_betrayal);
|
RegisterCreatureAI(npc_overlord_drakuru_betrayal);
|
||||||
new npc_drakuru_shackles();
|
|
||||||
new npc_captured_rageclaw();
|
|
||||||
new npc_released_offspring_harkoa();
|
new npc_released_offspring_harkoa();
|
||||||
new npc_crusade_recruit();
|
new npc_crusade_recruit();
|
||||||
new go_scourge_enclosure();
|
new go_scourge_enclosure();
|
||||||
|
|||||||
@@ -56,17 +56,20 @@ struct boss_talon_king_ikiss : public BossAI
|
|||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
_Reset();
|
_Reset();
|
||||||
_spoken = false;
|
me->SetReactState(REACT_AGGRESSIVE);
|
||||||
ScheduleHealthCheckEvent({ 80, 50, 25 }, [&] {
|
ScheduleHealthCheckEvent({ 80, 50, 25 }, [&] {
|
||||||
me->InterruptNonMeleeSpells(false);
|
me->InterruptNonMeleeSpells(false);
|
||||||
|
me->SetReactState(REACT_PASSIVE);
|
||||||
|
me->AttackStop();
|
||||||
DoCastAOE(SPELL_BLINK);
|
DoCastAOE(SPELL_BLINK);
|
||||||
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
||||||
Talk(EMOTE_ARCANE_EXP);
|
Talk(EMOTE_ARCANE_EXP);
|
||||||
scheduler.Schedule(1s, [this](TaskContext /*context*/)
|
scheduler.Schedule(1s, [this](TaskContext /*context*/)
|
||||||
{
|
{
|
||||||
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
||||||
}).Schedule(6500ms, [this](TaskContext /*context*/)
|
}).Schedule(7s, [this](TaskContext /*context*/)
|
||||||
{
|
{
|
||||||
|
me->SetReactState(REACT_AGGRESSIVE);
|
||||||
me->GetThreatMgr().ResetAllThreat();
|
me->GetThreatMgr().ResetAllThreat();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -160,7 +163,7 @@ class spell_talon_king_ikiss_blink : public SpellScript
|
|||||||
void HandleDummyHitTarget(SpellEffIndex effIndex)
|
void HandleDummyHitTarget(SpellEffIndex effIndex)
|
||||||
{
|
{
|
||||||
PreventHitDefaultEffect(effIndex);
|
PreventHitDefaultEffect(effIndex);
|
||||||
GetHitUnit()->CastSpell(GetCaster(), SPELL_BLINK_TELEPORT, true);
|
GetCaster()->CastSpell(GetHitUnit(), SPELL_BLINK_TELEPORT, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Register() override
|
void Register() override
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ struct boss_pathaleon_the_calculator : public BossAI
|
|||||||
me->LoadEquipment(EQUIPMENT_FRENZY);
|
me->LoadEquipment(EQUIPMENT_FRENZY);
|
||||||
});
|
});
|
||||||
|
|
||||||
scheduler.Schedule(20s, 25s, [this](TaskContext context)
|
scheduler.Schedule(10s, 16s, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
if (!_isEnraged)
|
if (!_isEnraged)
|
||||||
{
|
{
|
||||||
@@ -113,7 +113,7 @@ struct boss_pathaleon_the_calculator : public BossAI
|
|||||||
me->ModifyPower(POWER_MANA, 5000);
|
me->ModifyPower(POWER_MANA, 5000);
|
||||||
DoCastSelf(SPELL_ARCANE_TORRENT);
|
DoCastSelf(SPELL_ARCANE_TORRENT);
|
||||||
context.Repeat(15s);
|
context.Repeat(15s);
|
||||||
}).Schedule(10s, 15s, [this](TaskContext context)
|
}).Schedule(10s, 16s, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
if (DoCastRandomTarget(SPELL_DOMINATION, 0, 50.0f, true, false, false) == SPELL_CAST_OK)
|
if (DoCastRandomTarget(SPELL_DOMINATION, 0, 50.0f, true, false, false) == SPELL_CAST_OK)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "IpAddress.h"
|
#include "IpAddress.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "Socket.h"
|
||||||
#include "Systemd.h"
|
#include "Systemd.h"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <boost/asio/ip/tcp.hpp>
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
@@ -32,7 +33,7 @@ constexpr auto ACORE_MAX_LISTEN_CONNECTIONS = boost::asio::socket_base::max_list
|
|||||||
class AsyncAcceptor
|
class AsyncAcceptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef void(*AcceptCallback)(tcp::socket&& newSocket, uint32 threadIndex);
|
typedef void(*AcceptCallback)(IoContextTcpSocket&& newSocket, uint32 threadIndex);
|
||||||
|
|
||||||
AsyncAcceptor(Acore::Asio::IoContext& ioContext, std::string const& bindIp, uint16 port, bool supportSocketActivation = false) :
|
AsyncAcceptor(Acore::Asio::IoContext& ioContext, std::string const& bindIp, uint16 port, bool supportSocketActivation = false) :
|
||||||
_acceptor(ioContext), _endpoint(Acore::Net::make_address(bindIp), port),
|
_acceptor(ioContext), _endpoint(Acore::Net::make_address(bindIp), port),
|
||||||
@@ -56,7 +57,7 @@ public:
|
|||||||
template<AcceptCallback acceptCallback>
|
template<AcceptCallback acceptCallback>
|
||||||
void AsyncAcceptWithCallback()
|
void AsyncAcceptWithCallback()
|
||||||
{
|
{
|
||||||
tcp::socket* socket;
|
IoContextTcpSocket* socket;
|
||||||
uint32 threadIndex;
|
uint32 threadIndex;
|
||||||
std::tie(socket, threadIndex) = _socketFactory();
|
std::tie(socket, threadIndex) = _socketFactory();
|
||||||
_acceptor.async_accept(*socket, [this, socket, threadIndex](boost::system::error_code error)
|
_acceptor.async_accept(*socket, [this, socket, threadIndex](boost::system::error_code error)
|
||||||
@@ -129,16 +130,16 @@ public:
|
|||||||
_acceptor.close(err);
|
_acceptor.close(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSocketFactory(std::function<std::pair<tcp::socket*, uint32>()> func) { _socketFactory = func; }
|
void SetSocketFactory(std::function<std::pair<IoContextTcpSocket*, uint32>()> func) { _socketFactory = std::move(func); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::pair<tcp::socket*, uint32> DefaultSocketFactory() { return std::make_pair(&_socket, 0); }
|
std::pair<IoContextTcpSocket*, uint32> DefaultSocketFactory() { return std::make_pair(&_socket, 0); }
|
||||||
|
|
||||||
tcp::acceptor _acceptor;
|
boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, IoContextTcpSocket::executor_type> _acceptor;
|
||||||
tcp::endpoint _endpoint;
|
boost::asio::ip::tcp::endpoint _endpoint;
|
||||||
tcp::socket _socket;
|
IoContextTcpSocket _socket;
|
||||||
std::atomic<bool> _closed;
|
std::atomic<bool> _closed;
|
||||||
std::function<std::pair<tcp::socket*, uint32>()> _socketFactory;
|
std::function<std::pair<IoContextTcpSocket*, uint32>()> _socketFactory;
|
||||||
bool _supportSocketActivation;
|
bool _supportSocketActivation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -91,13 +91,13 @@ public:
|
|||||||
SocketAdded(sock);
|
SocketAdded(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
tcp::socket* GetSocketForAccept() { return &_acceptSocket; }
|
IoContextTcpSocket* GetSocketForAccept() { return &_acceptSocket; }
|
||||||
|
|
||||||
void EnableProxyProtocol() { _proxyHeaderReadingEnabled = true; }
|
void EnableProxyProtocol() { _proxyHeaderReadingEnabled = true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void SocketAdded(std::shared_ptr<SocketType> /*sock*/) { }
|
virtual void SocketAdded(std::shared_ptr<SocketType> const& /*sock*/) { }
|
||||||
virtual void SocketRemoved(std::shared_ptr<SocketType> /*sock*/) { }
|
virtual void SocketRemoved(std::shared_ptr<SocketType> const& /*sock*/) { }
|
||||||
|
|
||||||
void AddNewSockets()
|
void AddNewSockets()
|
||||||
{
|
{
|
||||||
@@ -229,7 +229,7 @@ private:
|
|||||||
SocketContainer _newSockets;
|
SocketContainer _newSockets;
|
||||||
|
|
||||||
Acore::Asio::IoContext _ioContext;
|
Acore::Asio::IoContext _ioContext;
|
||||||
tcp::socket _acceptSocket;
|
IoContextTcpSocket _acceptSocket;
|
||||||
boost::asio::steady_timer _updateTimer;
|
boost::asio::steady_timer _updateTimer;
|
||||||
|
|
||||||
bool _proxyHeaderReadingEnabled;
|
bool _proxyHeaderReadingEnabled;
|
||||||
|
|||||||
@@ -21,9 +21,8 @@
|
|||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "MessageBuffer.h"
|
#include "MessageBuffer.h"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio/io_context.hpp>
|
||||||
#include <boost/asio/ip/tcp.hpp>
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -35,6 +34,23 @@ using boost::asio::ip::tcp;
|
|||||||
#define AC_SOCKET_USE_IOCP
|
#define AC_SOCKET_USE_IOCP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Specialize boost socket for io_context executor instead of type-erased any_io_executor
|
||||||
|
// This avoids the type-erasure overhead of any_io_executor
|
||||||
|
using IoContextTcpSocket = boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::io_context::executor_type>;
|
||||||
|
|
||||||
|
enum class SocketReadCallbackResult
|
||||||
|
{
|
||||||
|
KeepReading,
|
||||||
|
Stop
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SocketState : uint8
|
||||||
|
{
|
||||||
|
Open = 0,
|
||||||
|
Closing = 1,
|
||||||
|
Closed = 2
|
||||||
|
};
|
||||||
|
|
||||||
enum ProxyHeaderReadingState {
|
enum ProxyHeaderReadingState {
|
||||||
PROXY_HEADER_READING_STATE_NOT_STARTED,
|
PROXY_HEADER_READING_STATE_NOT_STARTED,
|
||||||
PROXY_HEADER_READING_STATE_STARTED,
|
PROXY_HEADER_READING_STATE_STARTED,
|
||||||
@@ -51,8 +67,8 @@ template<class T>
|
|||||||
class Socket : public std::enable_shared_from_this<T>
|
class Socket : public std::enable_shared_from_this<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Socket(tcp::socket&& socket) : _socket(std::move(socket)), _remoteAddress(_socket.remote_endpoint().address()),
|
explicit Socket(IoContextTcpSocket&& socket) : _socket(std::move(socket)), _remoteAddress(_socket.remote_endpoint().address()),
|
||||||
_remotePort(_socket.remote_endpoint().port()), _readBuffer(), _closed(false), _closing(false), _isWritingAsync(false),
|
_remotePort(_socket.remote_endpoint().port()), _readBuffer(), _state(SocketState::Open), _isWritingAsync(false),
|
||||||
_proxyHeaderReadingState(PROXY_HEADER_READING_STATE_NOT_STARTED)
|
_proxyHeaderReadingState(PROXY_HEADER_READING_STATE_NOT_STARTED)
|
||||||
{
|
{
|
||||||
_readBuffer.Resize(READ_BLOCK_SIZE);
|
_readBuffer.Resize(READ_BLOCK_SIZE);
|
||||||
@@ -60,7 +76,7 @@ public:
|
|||||||
|
|
||||||
virtual ~Socket()
|
virtual ~Socket()
|
||||||
{
|
{
|
||||||
_closed = true;
|
_state = SocketState::Closed;
|
||||||
boost::system::error_code error;
|
boost::system::error_code error;
|
||||||
_socket.close(error);
|
_socket.close(error);
|
||||||
}
|
}
|
||||||
@@ -69,13 +85,14 @@ public:
|
|||||||
|
|
||||||
virtual bool Update()
|
virtual bool Update()
|
||||||
{
|
{
|
||||||
if (_closed)
|
SocketState state = _state.load();
|
||||||
|
if (state == SocketState::Closed)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef AC_SOCKET_USE_IOCP
|
#ifndef AC_SOCKET_USE_IOCP
|
||||||
if (_isWritingAsync || (_writeQueue.empty() && !_closing))
|
if (_isWritingAsync || (_writeQueue.empty() && state != SocketState::Closing))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -150,12 +167,18 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] ProxyHeaderReadingState GetProxyHeaderReadingState() const { return _proxyHeaderReadingState; }
|
[[nodiscard]] ProxyHeaderReadingState GetProxyHeaderReadingState() const { return _proxyHeaderReadingState; }
|
||||||
|
|
||||||
[[nodiscard]] bool IsOpen() const { return !_closed && !_closing; }
|
[[nodiscard]] bool IsOpen() const { return _state.load() == SocketState::Open; }
|
||||||
|
|
||||||
void CloseSocket()
|
void CloseSocket()
|
||||||
{
|
{
|
||||||
if (_closed.exchange(true))
|
SocketState expected = SocketState::Open;
|
||||||
return;
|
if (!_state.compare_exchange_strong(expected, SocketState::Closed))
|
||||||
|
{
|
||||||
|
// If it was Closing, try to transition to Closed
|
||||||
|
expected = SocketState::Closing;
|
||||||
|
if (!_state.compare_exchange_strong(expected, SocketState::Closed))
|
||||||
|
return; // Already closed
|
||||||
|
}
|
||||||
|
|
||||||
boost::system::error_code shutdownError;
|
boost::system::error_code shutdownError;
|
||||||
_socket.shutdown(boost::asio::socket_base::shutdown_send, shutdownError);
|
_socket.shutdown(boost::asio::socket_base::shutdown_send, shutdownError);
|
||||||
@@ -168,13 +191,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Marks the socket for closing after write buffer becomes empty
|
/// Marks the socket for closing after write buffer becomes empty
|
||||||
void DelayedCloseSocket() { _closing = true; }
|
void DelayedCloseSocket()
|
||||||
|
{
|
||||||
|
SocketState expected = SocketState::Open;
|
||||||
|
_state.compare_exchange_strong(expected, SocketState::Closing);
|
||||||
|
}
|
||||||
|
|
||||||
MessageBuffer& GetReadBuffer() { return _readBuffer; }
|
MessageBuffer& GetReadBuffer() { return _readBuffer; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void OnClose() { }
|
virtual void OnClose() { }
|
||||||
virtual void ReadHandler() = 0;
|
virtual SocketReadCallbackResult ReadHandler() = 0;
|
||||||
|
|
||||||
bool AsyncProcessQueue()
|
bool AsyncProcessQueue()
|
||||||
{
|
{
|
||||||
@@ -188,7 +215,7 @@ protected:
|
|||||||
_socket.async_write_some(boost::asio::buffer(buffer.GetReadPointer(), buffer.GetActiveSize()), std::bind(&Socket<T>::WriteHandler,
|
_socket.async_write_some(boost::asio::buffer(buffer.GetReadPointer(), buffer.GetActiveSize()), std::bind(&Socket<T>::WriteHandler,
|
||||||
this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
|
this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
|
||||||
#else
|
#else
|
||||||
_socket.async_wait(tcp::socket::wait_write, [self = this->shared_from_this()](boost::system::error_code error)
|
_socket.async_wait(boost::asio::socket_base::wait_write, [self = this->shared_from_this()](boost::system::error_code error)
|
||||||
{
|
{
|
||||||
self->WriteHandlerWrapper(error, 0);
|
self->WriteHandlerWrapper(error, 0);
|
||||||
});
|
});
|
||||||
@@ -216,7 +243,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_readBuffer.WriteCompleted(transferredBytes);
|
_readBuffer.WriteCompleted(transferredBytes);
|
||||||
ReadHandler();
|
if (ReadHandler() == SocketReadCallbackResult::KeepReading)
|
||||||
|
AsyncRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProxyReadHeaderHandler reads Proxy Protocol v2 header (v1 is not supported).
|
// ProxyReadHeaderHandler reads Proxy Protocol v2 header (v1 is not supported).
|
||||||
@@ -344,7 +372,7 @@ private:
|
|||||||
|
|
||||||
if (!_writeQueue.empty())
|
if (!_writeQueue.empty())
|
||||||
AsyncProcessQueue();
|
AsyncProcessQueue();
|
||||||
else if (_closing)
|
else if (_state.load() == SocketState::Closing)
|
||||||
CloseSocket();
|
CloseSocket();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -380,7 +408,7 @@ private:
|
|||||||
|
|
||||||
_writeQueue.pop();
|
_writeQueue.pop();
|
||||||
|
|
||||||
if (_closing && _writeQueue.empty())
|
if (_state.load() == SocketState::Closing && _writeQueue.empty())
|
||||||
{
|
{
|
||||||
CloseSocket();
|
CloseSocket();
|
||||||
}
|
}
|
||||||
@@ -391,7 +419,7 @@ private:
|
|||||||
{
|
{
|
||||||
_writeQueue.pop();
|
_writeQueue.pop();
|
||||||
|
|
||||||
if (_closing && _writeQueue.empty())
|
if (_state.load() == SocketState::Closing && _writeQueue.empty())
|
||||||
{
|
{
|
||||||
CloseSocket();
|
CloseSocket();
|
||||||
}
|
}
|
||||||
@@ -406,7 +434,7 @@ private:
|
|||||||
|
|
||||||
_writeQueue.pop();
|
_writeQueue.pop();
|
||||||
|
|
||||||
if (_closing && _writeQueue.empty())
|
if (_state.load() == SocketState::Closing && _writeQueue.empty())
|
||||||
{
|
{
|
||||||
CloseSocket();
|
CloseSocket();
|
||||||
}
|
}
|
||||||
@@ -415,7 +443,7 @@ private:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tcp::socket _socket;
|
IoContextTcpSocket _socket;
|
||||||
|
|
||||||
boost::asio::ip::address _remoteAddress;
|
boost::asio::ip::address _remoteAddress;
|
||||||
uint16 _remotePort;
|
uint16 _remotePort;
|
||||||
@@ -423,8 +451,7 @@ private:
|
|||||||
MessageBuffer _readBuffer;
|
MessageBuffer _readBuffer;
|
||||||
std::queue<MessageBuffer> _writeQueue;
|
std::queue<MessageBuffer> _writeQueue;
|
||||||
|
|
||||||
std::atomic<bool> _closed;
|
std::atomic<SocketState> _state;
|
||||||
std::atomic<bool> _closing;
|
|
||||||
|
|
||||||
bool _isWritingAsync;
|
bool _isWritingAsync;
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public:
|
|||||||
_threads[i].Wait();
|
_threads[i].Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnSocketOpen(tcp::socket&& sock, uint32 threadIndex)
|
virtual void OnSocketOpen(IoContextTcpSocket&& sock, uint32 threadIndex)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -117,7 +117,7 @@ public:
|
|||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<tcp::socket*, uint32> GetSocketForAccept()
|
std::pair<IoContextTcpSocket*, uint32> GetSocketForAccept()
|
||||||
{
|
{
|
||||||
uint32 threadIndex = SelectThreadWithMinConnections();
|
uint32 threadIndex = SelectThreadWithMinConnections();
|
||||||
return { _threads[threadIndex].GetSocketForAccept(), threadIndex };
|
return { _threads[threadIndex].GetSocketForAccept(), threadIndex };
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Socket Stress Test for AzerothCore
|
||||||
|
Tests authserver and worldserver connection handling under heavy load.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python3 socket_stress_heavy.py [duration_seconds] [auth_threads] [world_threads]
|
||||||
|
|
||||||
|
Defaults:
|
||||||
|
duration: 300 seconds (5 minutes)
|
||||||
|
auth_threads: 100
|
||||||
|
world_threads: 150
|
||||||
|
"""
|
||||||
|
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
import sys
|
||||||
|
|
||||||
|
AUTH_PORT = 3724
|
||||||
|
WORLD_PORT = 8085
|
||||||
|
HOST = '127.0.0.1'
|
||||||
|
|
||||||
|
stats = {'auth_ok': 0, 'auth_fail': 0, 'world_ok': 0, 'world_fail': 0}
|
||||||
|
running = True
|
||||||
|
|
||||||
|
|
||||||
|
def stress_auth():
|
||||||
|
"""Flood authserver with login challenge packets."""
|
||||||
|
global stats
|
||||||
|
while running:
|
||||||
|
try:
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
s.settimeout(1)
|
||||||
|
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||||
|
s.connect((HOST, AUTH_PORT))
|
||||||
|
# AUTH_LOGON_CHALLENGE packet
|
||||||
|
packet = bytes([
|
||||||
|
0x00, # cmd: AUTH_LOGON_CHALLENGE
|
||||||
|
0x00, # error
|
||||||
|
0x24, 0x00, # size (36)
|
||||||
|
0x57, 0x6F, 0x57, 0x00, # 'WoW\0'
|
||||||
|
0x03, 0x03, 0x05, # version 3.3.5
|
||||||
|
0x30, 0x30, # build 12340
|
||||||
|
0x78, 0x38, 0x36, 0x00, # 'x86\0'
|
||||||
|
0x6E, 0x69, 0x57, 0x00, # 'niW\0' (Win reversed)
|
||||||
|
0x53, 0x55, 0x6E, 0x65, # 'SUne' (enUS reversed)
|
||||||
|
0x3C, 0x00, 0x00, 0x00, # timezone
|
||||||
|
0x7F, 0x00, 0x00, 0x01, # IP 127.0.0.1
|
||||||
|
0x04, # account name length
|
||||||
|
0x54, 0x45, 0x53, 0x54 # 'TEST'
|
||||||
|
])
|
||||||
|
s.sendall(packet)
|
||||||
|
s.close()
|
||||||
|
stats['auth_ok'] += 1
|
||||||
|
except Exception:
|
||||||
|
stats['auth_fail'] += 1
|
||||||
|
|
||||||
|
|
||||||
|
def stress_world():
|
||||||
|
"""Flood worldserver with connection attempts."""
|
||||||
|
global stats
|
||||||
|
while running:
|
||||||
|
try:
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
s.settimeout(1)
|
||||||
|
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||||
|
s.connect((HOST, WORLD_PORT))
|
||||||
|
# Wait for SMSG_AUTH_CHALLENGE
|
||||||
|
s.recv(64)
|
||||||
|
s.close()
|
||||||
|
stats['world_ok'] += 1
|
||||||
|
except Exception:
|
||||||
|
stats['world_fail'] += 1
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
global running
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
duration = int(sys.argv[1]) if len(sys.argv) > 1 else 300
|
||||||
|
auth_threads = int(sys.argv[2]) if len(sys.argv) > 2 else 100
|
||||||
|
world_threads = int(sys.argv[3]) if len(sys.argv) > 3 else 150
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print("SOCKET STRESS TEST")
|
||||||
|
print("=" * 60)
|
||||||
|
print(f"Duration: {duration} seconds")
|
||||||
|
print(f"Auth threads: {auth_threads} -> {HOST}:{AUTH_PORT}")
|
||||||
|
print(f"World threads: {world_threads} -> {HOST}:{WORLD_PORT}")
|
||||||
|
print("-" * 60)
|
||||||
|
|
||||||
|
threads = []
|
||||||
|
|
||||||
|
for _ in range(auth_threads):
|
||||||
|
t = threading.Thread(target=stress_auth, daemon=True)
|
||||||
|
t.start()
|
||||||
|
threads.append(t)
|
||||||
|
|
||||||
|
for _ in range(world_threads):
|
||||||
|
t = threading.Thread(target=stress_world, daemon=True)
|
||||||
|
t.start()
|
||||||
|
threads.append(t)
|
||||||
|
|
||||||
|
print(f"Started {len(threads)} threads")
|
||||||
|
print("-" * 60)
|
||||||
|
|
||||||
|
start = time.time()
|
||||||
|
try:
|
||||||
|
while time.time() - start < duration:
|
||||||
|
elapsed = int(time.time() - start)
|
||||||
|
total = stats['auth_ok'] + stats['world_ok']
|
||||||
|
rate = total / max(elapsed, 1)
|
||||||
|
print(f"\r[{elapsed:3d}s] Auth: {stats['auth_ok']:7d} ok {stats['auth_fail']:5d} fail | "
|
||||||
|
f"World: {stats['world_ok']:7d} ok {stats['world_fail']:5d} fail | "
|
||||||
|
f"Rate: {rate:,.0f}/s ", end='', flush=True)
|
||||||
|
time.sleep(1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n\nInterrupted by user")
|
||||||
|
|
||||||
|
running = False
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
total_ok = stats['auth_ok'] + stats['world_ok']
|
||||||
|
total_fail = stats['auth_fail'] + stats['world_fail']
|
||||||
|
elapsed = time.time() - start
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("RESULTS:")
|
||||||
|
print(f" Duration: {elapsed:.1f} seconds")
|
||||||
|
print(f" Auth: {stats['auth_ok']:,} ok, {stats['auth_fail']:,} failed")
|
||||||
|
print(f" World: {stats['world_ok']:,} ok, {stats['world_fail']:,} failed")
|
||||||
|
print(f" Total: {total_ok:,} ok, {total_fail:,} failed")
|
||||||
|
print(f" Rate: {total_ok / elapsed:,.0f} connections/sec average")
|
||||||
|
if total_fail > 0:
|
||||||
|
print(f" Failure: {total_fail / (total_ok + total_fail) * 100:.2f}%")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user