diff --git a/apps/config-merger/python/README.md b/apps/config-merger/python/README.md index bdbe408a7..8692bee5c 100644 --- a/apps/config-merger/python/README.md +++ b/apps/config-merger/python/README.md @@ -20,6 +20,8 @@ This tool compares your existing configuration files (`.conf`) with the latest d ## 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) 1. **Run the script** in your configs directory: diff --git a/data/sql/updates/db_world/2026_01_15_00.sql b/data/sql/updates/db_world/2026_01_15_00.sql new file mode 100644 index 000000000..36af95fb3 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_15_00.sql @@ -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\''); diff --git a/data/sql/updates/db_world/2026_01_16_00.sql b/data/sql/updates/db_world/2026_01_16_00.sql new file mode 100644 index 000000000..f2783b7e0 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_16_00.sql @@ -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); diff --git a/data/sql/updates/db_world/2026_01_17_00.sql b/data/sql/updates/db_world/2026_01_17_00.sql new file mode 100644 index 000000000..cb4cfaaaf --- /dev/null +++ b/data/sql/updates/db_world/2026_01_17_00.sql @@ -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; diff --git a/data/sql/updates/db_world/2026_01_17_01.sql b/data/sql/updates/db_world/2026_01_17_01.sql new file mode 100644 index 000000000..1f39655a0 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_17_01.sql @@ -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; diff --git a/data/sql/updates/db_world/2026_01_18_00.sql b/data/sql/updates/db_world/2026_01_18_00.sql new file mode 100644 index 000000000..d443158a7 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_18_00.sql @@ -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; diff --git a/data/sql/updates/db_world/2026_01_18_01.sql b/data/sql/updates/db_world/2026_01_18_01.sql new file mode 100644 index 000000000..75a392ce2 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_18_01.sql @@ -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'); diff --git a/data/sql/updates/db_world/2026_01_18_02.sql b/data/sql/updates/db_world/2026_01_18_02.sql new file mode 100644 index 000000000..bf76971d3 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_18_02.sql @@ -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; diff --git a/data/sql/updates/db_world/2026_01_19_00.sql b/data/sql/updates/db_world/2026_01_19_00.sql new file mode 100644 index 000000000..a66547e2a --- /dev/null +++ b/data/sql/updates/db_world/2026_01_19_00.sql @@ -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)'); diff --git a/data/sql/updates/db_world/2026_01_19_01.sql b/data/sql/updates/db_world/2026_01_19_01.sql new file mode 100644 index 000000000..44106b5a6 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_19_01.sql @@ -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.'); diff --git a/data/sql/updates/db_world/2026_01_20_00.sql b/data/sql/updates/db_world/2026_01_20_00.sql new file mode 100644 index 000000000..8f3fb1378 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_20_00.sql @@ -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); diff --git a/data/sql/updates/db_world/2026_01_20_01.sql b/data/sql/updates/db_world/2026_01_20_01.sql new file mode 100644 index 000000000..0f81f300a --- /dev/null +++ b/data/sql/updates/db_world/2026_01_20_01.sql @@ -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; diff --git a/data/sql/updates/db_world/2026_01_20_02.sql b/data/sql/updates/db_world/2026_01_20_02.sql new file mode 100644 index 000000000..9d609e601 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_20_02.sql @@ -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'); diff --git a/data/sql/updates/db_world/2026_01_20_03.sql b/data/sql/updates/db_world/2026_01_20_03.sql new file mode 100644 index 000000000..27e5fc1d9 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_20_03.sql @@ -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); diff --git a/data/sql/updates/db_world/2026_01_21_00.sql b/data/sql/updates/db_world/2026_01_21_00.sql new file mode 100644 index 000000000..a46efa738 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_21_00.sql @@ -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'); diff --git a/data/sql/updates/db_world/2026_01_21_01.sql b/data/sql/updates/db_world/2026_01_21_01.sql new file mode 100644 index 000000000..8814727da --- /dev/null +++ b/data/sql/updates/db_world/2026_01_21_01.sql @@ -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'); diff --git a/data/sql/updates/db_world/2026_01_21_02.sql b/data/sql/updates/db_world/2026_01_21_02.sql new file mode 100644 index 000000000..ccbb9161c --- /dev/null +++ b/data/sql/updates/db_world/2026_01_21_02.sql @@ -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 diff --git a/data/sql/updates/db_world/2026_01_22_00.sql b/data/sql/updates/db_world/2026_01_22_00.sql new file mode 100644 index 000000000..d7d46e803 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_22_00.sql @@ -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'); diff --git a/data/sql/updates/db_world/2026_01_22_01.sql b/data/sql/updates/db_world/2026_01_22_01.sql new file mode 100644 index 000000000..025903ea3 --- /dev/null +++ b/data/sql/updates/db_world/2026_01_22_01.sql @@ -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); diff --git a/data/sql/updates/db_world/2026_01_22_02.sql b/data/sql/updates/db_world/2026_01_22_02.sql new file mode 100644 index 000000000..043d3ef5c --- /dev/null +++ b/data/sql/updates/db_world/2026_01_22_02.sql @@ -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)'); diff --git a/data/sql/updates/db_world/2026_01_22_03.sql b/data/sql/updates/db_world/2026_01_22_03.sql new file mode 100644 index 000000000..b70dd267e --- /dev/null +++ b/data/sql/updates/db_world/2026_01_22_03.sql @@ -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\''); diff --git a/src/server/apps/authserver/Server/AuthSession.cpp b/src/server/apps/authserver/Server/AuthSession.cpp index 29c0c643c..e5315c9ec 100644 --- a/src/server/apps/authserver/Server/AuthSession.cpp +++ b/src/server/apps/authserver/Server/AuthSession.cpp @@ -162,7 +162,7 @@ void AccountInfo::LoadResult(Field* fields) Utf8ToUpperOnlyLatin(Login); } -AuthSession::AuthSession(tcp::socket&& socket) : +AuthSession::AuthSession(IoContextTcpSocket&& socket) : Socket(std::move(socket)), _status(STATUS_CHALLENGE), _build(0), _expversion(0) { } void AuthSession::Start() @@ -216,7 +216,7 @@ void AuthSession::CheckIpCallback(PreparedQueryResult result) AsyncRead(); } -void AuthSession::ReadHandler() +SocketReadCallbackResult AuthSession::ReadHandler() { MessageBuffer& packet = GetReadBuffer(); @@ -234,7 +234,7 @@ void AuthSession::ReadHandler() if (_status != itr->second.status) { CloseSocket(); - return; + return SocketReadCallbackResult::Stop; } uint16 size = uint16(itr->second.packetSize); @@ -248,7 +248,7 @@ void AuthSession::ReadHandler() if (size > MAX_ACCEPTED_CHALLENGE_SIZE) { CloseSocket(); - return; + return SocketReadCallbackResult::Stop; } } @@ -258,13 +258,13 @@ void AuthSession::ReadHandler() if (!(*this.*itr->second.handler)()) { CloseSocket(); - return; + return SocketReadCallbackResult::Stop; } packet.ReadCompleted(size); } - AsyncRead(); + return SocketReadCallbackResult::KeepReading; } void AuthSession::SendPacket(ByteBuffer& packet) diff --git a/src/server/apps/authserver/Server/AuthSession.h b/src/server/apps/authserver/Server/AuthSession.h index 1c5e28eee..0c61e5e2f 100644 --- a/src/server/apps/authserver/Server/AuthSession.h +++ b/src/server/apps/authserver/Server/AuthSession.h @@ -60,22 +60,22 @@ struct AccountInfo AccountTypes SecurityLevel = SEC_PLAYER; }; -class AuthSession : public Socket +class AuthSession final : public Socket { typedef Socket AuthSocket; public: static std::unordered_map InitHandlers(); - AuthSession(tcp::socket&& socket); + AuthSession(IoContextTcpSocket&& socket); void Start() override; - bool Update() override; + bool Update() final; void SendPacket(ByteBuffer& packet); protected: - void ReadHandler() override; + SocketReadCallbackResult ReadHandler() final; private: bool HandleLogonChallenge(); diff --git a/src/server/apps/authserver/Server/AuthSocketMgr.h b/src/server/apps/authserver/Server/AuthSocketMgr.h index 162a6363c..99cf080e2 100644 --- a/src/server/apps/authserver/Server/AuthSocketMgr.h +++ b/src/server/apps/authserver/Server/AuthSocketMgr.h @@ -54,9 +54,9 @@ protected: return threads; } - static void OnSocketAccept(tcp::socket&& sock, uint32 threadIndex) + static void OnSocketAccept(IoContextTcpSocket&& sock, uint32 threadIndex) { - Instance().OnSocketOpen(std::forward(sock), threadIndex); + Instance().OnSocketOpen(std::move(sock), threadIndex); } }; diff --git a/src/server/apps/worldserver/RemoteAccess/RASession.h b/src/server/apps/worldserver/RemoteAccess/RASession.h index 27e2ab4a6..1f06b32ae 100644 --- a/src/server/apps/worldserver/RemoteAccess/RASession.h +++ b/src/server/apps/worldserver/RemoteAccess/RASession.h @@ -18,18 +18,16 @@ #ifndef __RASESSION_H__ #define __RASESSION_H__ -#include +#include "Socket.h" #include #include -using boost::asio::ip::tcp; - const std::size_t bufferSize = 4096; class RASession : public std::enable_shared_from_this { public: - RASession(tcp::socket&& socket) : + RASession(IoContextTcpSocket&& socket) : _socket(std::move(socket)), _commandExecuting(nullptr) { } void Start(); @@ -47,7 +45,7 @@ private: static void CommandPrint(void* callbackArg, std::string_view text); static void CommandFinished(void* callbackArg, bool); - tcp::socket _socket; + IoContextTcpSocket _socket; boost::asio::streambuf _readBuffer; boost::asio::streambuf _writeBuffer; std::promise* _commandExecuting; diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index d1da816d5..f714491bf 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3296,6 +3296,19 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u target->ToUnit()->SetAnimTier(AnimTier(e.action.animTier.animTier)); 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: LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry {} SourceType {}, Event {}, Unhandled Action type {}", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); break; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index aef961781..834c1bc79 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -885,6 +885,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e) case SMART_ACTION_WORLD_SCRIPT: return sizeof(SmartAction::worldStateScript); case SMART_ACTION_DISABLE_REWARD: return sizeof(SmartAction::reward); 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; 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.", @@ -2040,6 +2041,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_MOVEMENT_PAUSE: case SMART_ACTION_MOVEMENT_RESUME: case SMART_ACTION_WORLD_SCRIPT: + case SMART_ACTION_SET_GOSSIP_MENU: break; 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); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index d12819603..08d454663 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -724,8 +724,9 @@ enum SMART_ACTION SMART_ACTION_WORLD_SCRIPT = 237, // eventId, param SMART_ACTION_DISABLE_REWARD = 238, // reputation 0/1, loot 0/1 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 @@ -1510,6 +1511,11 @@ struct SmartAction { uint32 animTier; } animTier; + + struct + { + uint32 gossipMenuId; + } setGossipMenu; }; }; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp index 0bfa0abec..ec5718d66 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp @@ -52,6 +52,7 @@ BattlegroundSA::BattlegroundSA() EndRoundTimer = 0s; ShipsStarted = false; Status = BG_SA_NOTSTARTED; + _nextShipIsEast = true; for (uint8 i = 0; i < 6; i++) GateStatus[i] = BG_SA_GATE_OK; @@ -85,6 +86,7 @@ void BattlegroundSA::Init() _notEvenAScratch[TEAM_HORDE] = true; Status = BG_SA_WARMUP; _relicClicked = false; + _nextShipIsEast = true; } bool BattlegroundSA::SetupBattleground() @@ -181,6 +183,7 @@ bool BattlegroundSA::ResetObjs() TotalTime = 0s; ShipsStarted = false; + _nextShipIsEast = true; //Graveyards! for (uint8 i = 0; i < BG_SA_MAX_GY; i++) @@ -574,10 +577,12 @@ void BattlegroundSA::TeleportToEntrancePosition(Player* player) if (!ShipsStarted) { 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); else player->TeleportTo(MAP_STRAND_OF_THE_ANCIENTS, 2577.003f, 980.261f, 15.0f, 0.807f, 0); + + _nextShipIsEast = !_nextShipIsEast; } else player->TeleportTo(MAP_STRAND_OF_THE_ANCIENTS, 1600.381f, -106.263f, 8.8745f, 3.78f, 0); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h index e76f22da7..97c101497 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h @@ -620,5 +620,7 @@ private: // Achievement: Not Even a Scratch 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 diff --git a/src/server/game/Combat/ThreatMgr.cpp b/src/server/game/Combat/ThreatMgr.cpp index a421b3ac9..59da5a32a 100644 --- a/src/server/game/Combat/ThreatMgr.cpp +++ b/src/server/game/Combat/ThreatMgr.cpp @@ -328,7 +328,7 @@ HostileReference* ThreatContainer::SelectNextVictim(Creature* attacker, HostileR 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 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; } @@ -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: 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) { @@ -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) { + // tie-breaker if multiple targets have the same threat: select closest target + currentRef = SelectNextVictimTieBreaker(attacker, iter, noPriorityTargetFound); found = true; break; } @@ -406,6 +408,69 @@ HostileReference* ThreatContainer::SelectNextVictim(Creature* attacker, HostileR 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 ========================== //============================================================ diff --git a/src/server/game/Combat/ThreatMgr.h b/src/server/game/Combat/ThreatMgr.h index 3f31c9ac8..105c405a9 100644 --- a/src/server/game/Combat/ThreatMgr.h +++ b/src/server/game/Combat/ThreatMgr.h @@ -156,6 +156,10 @@ public: 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; } [[nodiscard]] bool isDirty() const { return iDirty; } diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index add31c1b1..688820001 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -542,13 +542,13 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) condMeets = object->GetMap()->GetDifficulty() == ConditionValue1; break; } - case CONDITION_RANDOM_DUNGEON: + case CONDITION_PLAYER_QUEUED_RANDOM_DUNGEON: { 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) condMeets = true; @@ -803,7 +803,7 @@ uint32 Condition::GetSearcherTypeMaskForCondition() case CONDITION_CHARMED: mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER; break; - case CONDITION_RANDOM_DUNGEON: + case CONDITION_PLAYER_QUEUED_RANDOM_DUNGEON: mask |= GRID_MAP_TYPE_MASK_PLAYER; break; case CONDITION_WORLD_SCRIPT: @@ -2486,7 +2486,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) return false; } break; - case CONDITION_RANDOM_DUNGEON: + case CONDITION_PLAYER_QUEUED_RANDOM_DUNGEON: if (cond->ConditionValue1 > 1) { LOG_ERROR("sql.sql", "RandomDungeon condition has useless data in value1 ({}).", cond->ConditionValue1); diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index c472451a3..f4db6429b 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -88,7 +88,7 @@ enum ConditionTypes 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_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 }; diff --git a/src/server/game/DungeonFinding/LFGGroupData.cpp b/src/server/game/DungeonFinding/LFGGroupData.cpp index 0f522d278..96c71a2b3 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.cpp +++ b/src/server/game/DungeonFinding/LFGGroupData.cpp @@ -139,4 +139,13 @@ namespace lfg 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 diff --git a/src/server/game/DungeonFinding/LFGGroupData.h b/src/server/game/DungeonFinding/LFGGroupData.h index 281beaff4..a6eecfcf6 100644 --- a/src/server/game/DungeonFinding/LFGGroupData.h +++ b/src/server/game/DungeonFinding/LFGGroupData.h @@ -37,6 +37,8 @@ namespace lfg void SetState(LfgState state); void RestoreState(); void AddPlayer(ObjectGuid guid); + void AddRandomQueuedPlayer(ObjectGuid guid); + [[nodiscard]] bool IsRandomQueuedPlayer(ObjectGuid guid) const; uint8 RemovePlayer(ObjectGuid guid); void RemoveAllPlayers(); void SetLeader(ObjectGuid guid); @@ -66,6 +68,7 @@ namespace lfg LfgState m_OldState; ///< Old State ObjectGuid m_Leader; ///< Leader GUID LfgGuidSet m_Players; ///< Players in group + LfgGuidSet m_RandomQueuedPlayers; ///< Players that queued for random dungeon // Dungeon uint32 m_Dungeon; ///< Dungeon entry bool _isLFGGroup; diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 9e097ab9b..fe44c400d 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -2583,6 +2583,18 @@ namespace lfg 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) { GroupsStore[gguid].SetLeader(leader); @@ -2839,4 +2851,12 @@ namespace lfg 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 diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index fd4bd6ce9..3d451e8eb 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -506,6 +506,9 @@ namespace lfg uint8 RemovePlayerFromGroup(ObjectGuid gguid, ObjectGuid guid); /// Adds player to group 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 void SetRandomPlayersCount(ObjectGuid guid, uint8 count); /// Xinef: Get Random Players Count diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index b4faf18fa..c4c7969ce 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -187,6 +187,7 @@ namespace lfg sLFGMgr->SetGroup(guid, gguid); sLFGMgr->AddPlayerToGroup(gguid, guid); + sLFGMgr->AddPlayerQueuedForRandomDungeonToGroup(gguid, guid); // pussywizard: after all necessary actions handle raid browser if (sLFGMgr->GetState(guid) == LFG_STATE_RAIDBROWSER) diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 23077fe9b..851bf23db 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -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_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_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), _isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0), _playerDamageReq(0), _damagedByPlayer(false), _isCombatMovementAllowed(true) { diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 67d07b26b..3c8617da1 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -204,6 +204,8 @@ public: [[nodiscard]] CreatureTemplate const* GetCreatureTemplate() const { return m_creatureInfo; } [[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; } [[nodiscard]] CreatureAddon const* GetCreatureAddon() const; @@ -478,6 +480,7 @@ protected: SpellSchoolMask m_meleeDamageSchoolMask; uint32 m_originalEntry; + uint32 _gossipMenuId; bool m_moveInLineOfSightDisabled; bool m_moveInLineOfSightStrictlyDisabled; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index efd8b8a88..b23de7959 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1642,12 +1642,9 @@ void Player::ProcessDelayedOperations() if (m_DelayedOperations & DELAYED_SAVE_PLAYER) SaveToDB(false, false); - if (m_DelayedOperations & DELAYED_SPELL_CAST_DESERTER) - { - Aura* aura = GetAura(26013); - if (!aura || aura->GetDuration() <= 900000) + if ((m_DelayedOperations & DELAYED_SPELL_CAST_DESERTER) + && !GetAura(26013)) CastSpell(this, 26013, true); - } if (m_DelayedOperations & DELAYED_BG_MOUNT_RESTORE) { @@ -14378,7 +14375,7 @@ bool Player::CanSeeVendor(Creature const* creature) const if (!sConditionMgr->IsObjectMeetToConditions(const_cast(this), const_cast(creature), conditions)) return false; - uint32 const menuId = creature->GetCreatureTemplate()->GossipMenuId; + uint32 const menuId = creature->GetGossipMenuId(); if (!AnyVendorOptionAvailable(menuId, creature)) return false; diff --git a/src/server/game/Entities/Player/PlayerGossip.cpp b/src/server/game/Entities/Player/PlayerGossip.cpp index 77317f78a..dc6a48924 100644 --- a/src/server/game/Entities/Player/PlayerGossip.cpp +++ b/src/server/game/Entities/Player/PlayerGossip.cpp @@ -429,7 +429,7 @@ uint32 Player::GetDefaultGossipMenuForSource(WorldObject* source) switch (source->GetTypeId()) { case TYPEID_UNIT: - return source->ToCreature()->GetCreatureTemplate()->GossipMenuId; + return source->ToCreature()->GetGossipMenuId(); case TYPEID_GAMEOBJECT: return source->ToGameObject()->GetGOInfo()->GetGossipMenuId(); default: diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index c1249c925..e6db65263 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -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 victimResistance = float(victim->GetResistance(schoolMask)); + float victimResistance = static_cast(victim->GetResistance(schoolMask)); if (owner) { // Xinef: pets inherit 100% of masters penetration @@ -2156,28 +2156,28 @@ float Unit::GetEffectiveResistChance(Unit const* owner, SpellSchoolMask schoolMa Player const* player = owner->GetSpellModOwner(); if (player && owner->GetEntry() != WORLD_TRIGGER) { - victimResistance += float(player->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask)); - victimResistance -= float(player->GetSpellPenetrationItemMod()); + victimResistance += static_cast(player->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask)); + victimResistance -= static_cast(player->GetSpellPenetrationItemMod()); } else - victimResistance += float(owner->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask)); + victimResistance += static_cast(owner->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, schoolMask)); } victimResistance = std::max(victimResistance, 0.0f); if (owner) - victimResistance += std::max((float(victim->GetLevel()) - float(owner->GetLevel())) * 5.0f, 0.0f); + victimResistance += std::max(static_cast(victim->GetLevel() - owner->GetLevel()) * 5.0f, 0.0f); - static uint32 const BOSS_LEVEL = 83; - static float const BOSS_RESISTANCE_CONSTANT = 510.0f; - uint32 level = victim->GetLevel(); + float level = static_cast(victim->GetLevel()); float resistanceConstant = 0.0f; - if (level == BOSS_LEVEL) - resistanceConstant = BOSS_RESISTANCE_CONSTANT; + if (level > 60.0f) + resistanceConstant = 150.0f + (level - 60.0f) * (level - 67.5f); + else if (level > 20.0f) + resistanceConstant = 50.0f + (level - 20.0f) * 2.5f; 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) diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 9fc5643d0..e6e51086a 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -602,7 +602,10 @@ void WorldSession::HandleSellItemOpcode(WorldPackets::Item::SellItem& packet) if (pItem) { if (!sScriptMgr->OnPlayerCanSellItem(_player, pItem, creature)) + { + _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, packet.ItemGuid, 0); return; + } // prevent sell not owner item if (_player->GetGUID() != pItem->GetOwnerGUID()) diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index d89a92539..8323cde9e 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -179,7 +179,7 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket& recvData) if (!sScriptMgr->OnGossipHello(_player, unit)) { // _player->TalkedToCreature(unit->GetEntry(), unit->GetGUID()); - _player->PrepareGossipMenu(unit, unit->GetCreatureTemplate()->GossipMenuId, true); + _player->PrepareGossipMenu(unit, unit->GetGossipMenuId(), true); _player->SendPreparedGossip(unit); } unit->AI()->sGossipHello(_player); diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 946d23b85..25ebc3d32 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -101,7 +101,7 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket& recvData) if (sScriptMgr->OnGossipHello(_player, creature)) return; - _player->PrepareGossipMenu(creature, creature->GetCreatureTemplate()->GossipMenuId, true); + _player->PrepareGossipMenu(creature, creature->GetGossipMenuId(), true); _player->SendPreparedGossip(creature); creature->AI()->sGossipHello(_player); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index c64a75b49..8b6e2efcd 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -436,7 +436,7 @@ static Optional GetVelocity(Unit* owner, Unit* target, G3D::Vector3 const (owner->IsPet() || owner->IsGuardian() || owner->GetGUID() == target->GetCritterGUID() || owner->GetCharmerOrOwnerGUID() == target->GetGUID())) { uint32 moveFlags = target->GetUnitMovementFlags(); - if (target->movespline->isWalking()) + if (target->IsWalking()) { moveFlags |= MOVEMENTFLAG_WALKING; } @@ -635,7 +635,7 @@ bool FollowMovementGenerator::DoUpdate(T* owner, uint32 time_diff) Movement::MoveSplineInit init(owner); init.MovebyPath(i_path->GetPath()); if (_inheritWalkState) - init.SetWalk(target->IsWalking() || target->movespline->isWalking()); + init.SetWalk(target->IsWalking()); if (_inheritSpeed) if (Optional velocity = GetVelocity(owner, target, i_path->GetActualEndPosition(), owner->IsGuardian())) diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h index 40aee1254..b74d0d244 100644 --- a/src/server/game/Movement/Spline/MoveSpline.h +++ b/src/server/game/Movement/Spline/MoveSpline.h @@ -116,7 +116,6 @@ namespace Movement [[nodiscard]] bool Finalized() const { return splineflags.done; } [[nodiscard]] bool isCyclic() const { return splineflags.cyclic; } [[nodiscard]] bool isFalling() const { return splineflags.falling; } - [[nodiscard]] bool isWalking() const { return splineflags.walkmode; } [[nodiscard]] bool isBoarding() const { return splineflags.transportEnter || splineflags.transportExit; } [[nodiscard]] Vector3 FinalDestination() const { return Initialized() ? spline.getPoint(spline.last()) : Vector3(); } [[nodiscard]] Vector3 CurrentDestination() const { return Initialized() ? spline.getPoint(point_Idx + 1) : Vector3(); } diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h index 3020e46c2..08c9c3d6a 100644 --- a/src/server/game/Movement/Spline/MoveSplineFlag.h +++ b/src/server/game/Movement/Spline/MoveSplineFlag.h @@ -40,7 +40,7 @@ namespace Movement Falling = 0x00000200, // Affects elevation computation, can't be combined with Parabolic flag No_Spline = 0x00000400, 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 OrientationFixed = 0x00004000, // Model orientation fixed Final_Point = 0x00008000, @@ -117,7 +117,7 @@ namespace Movement bool falling : 1; bool no_spline : 1; bool parabolic : 1; - bool walkmode : 1; + bool canSwim : 1; bool flying : 1; bool orientationFixed : 1; bool final_point : 1; diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 8cdb1ffdf..e1dbd9be5 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -118,7 +118,7 @@ namespace Movement // 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 uint32 moveFlagsForSpeed = moveFlags; - if (args.flags.walkmode) + if (args.walk) moveFlagsForSpeed |= MOVEMENTFLAG_WALKING; else moveFlagsForSpeed &= ~MOVEMENTFLAG_WALKING; @@ -199,7 +199,7 @@ namespace Movement args.splineId = splineIdGen.NewId(); args.TransformForTransport = unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID(); // 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)); } diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index e0761129c..5e26dad04 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -154,7 +154,7 @@ namespace Movement }; 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::SetCyclic() { args.flags.cyclic = true; } inline void MoveSplineInit::SetFall() { args.flags.EnableFalling(); } diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h index ed4a268b7..1093ca705 100644 --- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h +++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h @@ -59,6 +59,7 @@ namespace Movement float initialOrientation{0.f}; bool HasVelocity{false}; bool TransformForTransport{true}; + bool walk; /** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */ bool Validate(Unit* unit) const; diff --git a/src/server/game/Movement/Spline/MovementUtil.cpp b/src/server/game/Movement/Spline/MovementUtil.cpp index 86f293dd3..a16fadb2c 100644 --- a/src/server/game/Movement/Spline/MovementUtil.cpp +++ b/src/server/game/Movement/Spline/MovementUtil.cpp @@ -153,7 +153,7 @@ namespace Movement STR(Falling ), // 0x00000200, // Not Compartible With Trajectory Movement STR(No_Spline ), // 0x00000400, 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(Knockback ), // 0x00004000, // Model Orientation Fixed STR(Final_Point ), // 0x00008000, diff --git a/src/server/game/Scripting/ScriptDefines/ServerScript.cpp b/src/server/game/Scripting/ScriptDefines/ServerScript.cpp index 2860141a8..7c531081c 100644 --- a/src/server/game/Scripting/ScriptDefines/ServerScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/ServerScript.cpp @@ -29,14 +29,14 @@ void ScriptMgr::OnNetworkStop() CALL_ENABLED_HOOKS(ServerScript, SERVERHOOK_ON_NETWORK_STOP, script->OnNetworkStop()); } -void ScriptMgr::OnSocketOpen(std::shared_ptr socket) +void ScriptMgr::OnSocketOpen(std::shared_ptr const& socket) { ASSERT(socket); CALL_ENABLED_HOOKS(ServerScript, SERVERHOOK_ON_SOCKET_OPEN, script->OnSocketOpen(socket)); } -void ScriptMgr::OnSocketClose(std::shared_ptr socket) +void ScriptMgr::OnSocketClose(std::shared_ptr const& socket) { ASSERT(socket); diff --git a/src/server/game/Scripting/ScriptDefines/ServerScript.h b/src/server/game/Scripting/ScriptDefines/ServerScript.h index 64b6762d2..ed5fd07cd 100644 --- a/src/server/game/Scripting/ScriptDefines/ServerScript.h +++ b/src/server/game/Scripting/ScriptDefines/ServerScript.h @@ -46,11 +46,11 @@ public: virtual void OnNetworkStop() { } // Called when a remote socket establishes a connection to the server. Do not store the socket object. - virtual void OnSocketOpen(std::shared_ptr /*socket*/) { } + virtual void OnSocketOpen(std::shared_ptr const& /*socket*/) { } // Called when a socket is closed. Do not store the socket object, and do not rely on the connection // being open; it is not. - virtual void OnSocketClose(std::shared_ptr /*socket*/) { } + virtual void OnSocketClose(std::shared_ptr 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. diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index e1d535007..4e839a465 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -174,8 +174,8 @@ public: /* SpellScriptLoader */ public: /* ServerScript */ void OnNetworkStart(); void OnNetworkStop(); - void OnSocketOpen(std::shared_ptr socket); - void OnSocketClose(std::shared_ptr socket); + void OnSocketOpen(std::shared_ptr const& socket); + void OnSocketClose(std::shared_ptr const& socket); bool CanPacketReceive(WorldSession* session, WorldPacket const& packet); void OnPacketReceived(WorldSession* session, WorldPacket const& packet); bool CanPacketSend(WorldSession* session, WorldPacket const& packet); diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 452a16ad1..cf809ba0a 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -116,7 +116,7 @@ void EncryptableAndCompressiblePacket::CompressIfNeeded() 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) { Acore::Crypto::GetRandomBytes(_authSeed); @@ -238,10 +238,10 @@ void WorldSocket::OnClose() } } -void WorldSocket::ReadHandler() +SocketReadCallbackResult WorldSocket::ReadHandler() { if (!IsOpen()) - return; + return SocketReadCallbackResult::Stop; MessageBuffer& packet = GetReadBuffer(); while (packet.GetActiveSize() > 0) @@ -264,7 +264,7 @@ void WorldSocket::ReadHandler() if (!ReadHeaderHandler()) { CloseSocket(); - return; + return SocketReadCallbackResult::Stop; } } @@ -295,11 +295,11 @@ void WorldSocket::ReadHandler() CloseSocket(); } - return; + return SocketReadCallbackResult::Stop; } } - AsyncRead(); + return SocketReadCallbackResult::KeepReading; } bool WorldSocket::ReadHeaderHandler() @@ -329,7 +329,7 @@ bool WorldSocket::ReadHeaderHandler() return true; } -struct AuthSession +struct ClientAuthSession { uint32 BattlegroupID = 0; uint32 LoginServerType = 0; @@ -528,7 +528,7 @@ void WorldSocket::SendPacket(WorldPacket const& packet) void WorldSocket::HandleAuthSession(WorldPacket & recvPacket) { - std::shared_ptr authSession = std::make_shared(); + std::shared_ptr authSession = std::make_shared(); // Read the content of the packet 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))); } -void WorldSocket::HandleAuthSessionCallback(std::shared_ptr authSession, PreparedQueryResult result) +void WorldSocket::HandleAuthSessionCallback(std::shared_ptr authSession, PreparedQueryResult result) { // Stop if the account is not found if (!result) diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index 347e9b506..a5dcc4fc6 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -65,21 +65,21 @@ struct ClientPktHeader }; #pragma pack(pop) -struct AuthSession; +struct ClientAuthSession; -class AC_GAME_API WorldSocket : public Socket +class AC_GAME_API WorldSocket final : public Socket { typedef Socket BaseSocket; public: - WorldSocket(tcp::socket&& socket); + WorldSocket(IoContextTcpSocket&& socket); ~WorldSocket(); WorldSocket(WorldSocket const& right) = delete; WorldSocket& operator=(WorldSocket const& right) = delete; void Start() override; - bool Update() override; + bool Update() final; void SendPacket(WorldPacket const& packet); @@ -90,7 +90,7 @@ public: protected: void OnClose() override; - void ReadHandler() override; + SocketReadCallbackResult ReadHandler() final; bool ReadHeaderHandler(); enum class ReadDataHandlerResult @@ -113,7 +113,7 @@ private: void SendPacketAndLogOpcode(WorldPacket const& packet); void HandleSendAuthSession(); void HandleAuthSession(WorldPacket& recvPacket); - void HandleAuthSessionCallback(std::shared_ptr authSession, PreparedQueryResult result); + void HandleAuthSessionCallback(std::shared_ptr authSession, PreparedQueryResult result); void LoadSessionPermissionsCallback(PreparedQueryResult result); void SendAuthResponseError(uint8 code); diff --git a/src/server/game/Server/WorldSocketMgr.cpp b/src/server/game/Server/WorldSocketMgr.cpp index 07e9d4dce..3b5053e1d 100644 --- a/src/server/game/Server/WorldSocketMgr.cpp +++ b/src/server/game/Server/WorldSocketMgr.cpp @@ -25,13 +25,13 @@ class WorldSocketThread : public NetworkThread { public: - void SocketAdded(std::shared_ptr sock) override + void SocketAdded(std::shared_ptr const& sock) override { sock->SetSendBufferSize(sWorldSocketMgr.GetApplicationSendBufferSize()); sScriptMgr->OnSocketOpen(sock); } - void SocketRemoved(std::shared_ptr sock) override + void SocketRemoved(std::shared_ptr const& sock) override { sScriptMgr->OnSocketClose(sock); } @@ -81,7 +81,7 @@ void WorldSocketMgr::StopNetwork() sScriptMgr->OnNetworkStop(); } -void WorldSocketMgr::OnSocketOpen(tcp::socket&& sock, uint32 threadIndex) +void WorldSocketMgr::OnSocketOpen(IoContextTcpSocket&& sock, uint32 threadIndex) { // set some options here if (_socketSystemSendBufferSize >= 0) @@ -109,7 +109,7 @@ void WorldSocketMgr::OnSocketOpen(tcp::socket&& sock, uint32 threadIndex) } } - BaseSocketMgr::OnSocketOpen(std::forward(sock), threadIndex); + BaseSocketMgr::OnSocketOpen(std::move(sock), threadIndex); } NetworkThread* WorldSocketMgr::CreateThreads() const diff --git a/src/server/game/Server/WorldSocketMgr.h b/src/server/game/Server/WorldSocketMgr.h index a93a12fa6..efd2f91d7 100644 --- a/src/server/game/Server/WorldSocketMgr.h +++ b/src/server/game/Server/WorldSocketMgr.h @@ -41,7 +41,7 @@ public: /// Stops all network threads, It will wait for all running threads . 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; } @@ -50,9 +50,9 @@ protected: NetworkThread* CreateThreads() const override; - static void OnSocketAccept(tcp::socket&& sock, uint32 threadIndex) + static void OnSocketAccept(IoContextTcpSocket&& sock, uint32 threadIndex) { - Instance().OnSocketOpen(std::forward(sock), threadIndex); + Instance().OnSocketOpen(std::move(sock), threadIndex); } private: diff --git a/src/server/scripts/Commands/cs_deserter.cpp b/src/server/scripts/Commands/cs_deserter.cpp index f6e359403..860046d10 100644 --- a/src/server/scripts/Commands/cs_deserter.cpp +++ b/src/server/scripts/Commands/cs_deserter.cpp @@ -24,6 +24,7 @@ #include "Chat.h" #include "CommandScript.h" +#include "GroupMgr.h" #include "Language.h" #include "Player.h" #include "SpellAuras.h" @@ -211,6 +212,16 @@ public: 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)); return true; } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp index 792f5f5ca..f2f6c003d 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp @@ -215,7 +215,7 @@ struct boss_archimonde : public BossAI scheduler.CancelAll(); me->SetReactState(REACT_PASSIVE); DoCastAOE(SPELL_PROTECTION_OF_ELUNE, true); - Talk(SAY_ENRAGE); + Talk(SAY_DEATH); _enraged = true; me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp index 2264c6e3d..0baaa5ca2 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp @@ -172,7 +172,7 @@ struct boss_hadronox : public BossAI SummonCrusherPack(SUMMON_GROUP_CRUSHER_3); events.ScheduleEvent(EVENT_HADRONOX_MOVE1, 0s); events.ScheduleEvent(EVENT_HADRONOX_MOVE2, 45s); - events.ScheduleEvent(EVENT_HADRONOX_MOVE3, 90s); + events.ScheduleEvent(EVENT_HADRONOX_MOVE3, 70s); } } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index cf0c22a64..f32da2d84 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -1137,7 +1137,7 @@ public: { me->GetMap()->SetZoneMusic(AREA_THE_FROZEN_THRONE, MUSIC_SPECIAL); 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); // schedule a defile (or reschedule it) if next defile event diff --git a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp index 18fe7a772..8bddb1452 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp @@ -44,10 +44,7 @@ enum Spells enum Misc { - ACHIEV_TIMED_START_EVENT = 9891, - EVENT_SPAWN_CRYPT_GUARDS_1 = 0, - EVENT_BERSERK = 1, - EVENT_SPAWN_CRYPT_GUARDS_EXTRA = 2, + ACHIEV_TIMED_START_EVENT = 9891 }; Position const cryptguardPositions[] = { @@ -121,9 +118,10 @@ struct boss_anubrekhan : public BossAI SummonCryptGuards(); if (!Is25ManRaid()) { - ScheduleUniqueTimedEvent(17500ms, [&] { + me->m_Events.AddEventAtOffset([this]() + { me->SummonCreature(NPC_CRYPT_GUARD, cryptguardPositions[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000); - }, EVENT_SPAWN_CRYPT_GUARDS_1); + }, 17500ms); } ScheduleTimedEvent(15s, [&] { diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp index 189b24880..7076ab750 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp @@ -255,7 +255,8 @@ class spell_gluth_decimate : public SpellScript Unit::DealDamage(GetCaster(), cTarget, damage); 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() { new boss_gluth(); RegisterSpellScript(spell_gluth_decimate); + RegisterSpellScript(spell_gluth_decimate_damage); } diff --git a/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp b/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp index 87dbcdfe9..51ead3e43 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp @@ -18,6 +18,7 @@ #include "CreatureScript.h" #include "InstanceMapScript.h" #include "ScriptedCreature.h" +#include "TaskScheduler.h" #include "nexus.h" #include "Player.h" #include "Group.h" @@ -44,6 +45,8 @@ public: { instance_nexus_InstanceMapScript(Map* map) : InstanceScript(map) {} + GuidVector _frayerGUIDs; + void Initialize() override { SetHeaders(DataHeader); @@ -80,6 +83,23 @@ public: if (GetTeamIdInInstance() == TEAM_ALLIANCE) creature->UpdateEntry(NPC_COMMANDER_KOLURG); 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)) 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; BossInfo const* bossInfo = GetBossInfo(id + DATA_TELESTRA_ORB); @@ -156,9 +182,17 @@ enum eFrayer { SPELL_SUMMON_SEED_POD = 52796, SPELL_SEED_POD = 48082, - SPELL_AURA_OF_REGENERATION = 52067, + SPELL_AURA_OF_REGENERATION = 57056, 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 @@ -166,27 +200,44 @@ struct npc_crystalline_frayer : public ScriptedAI npc_crystalline_frayer(Creature* creature) : ScriptedAI(creature) { } bool _allowDeath; - uint32 restoreTimer; - uint32 abilityTimer1; - uint32 abilityTimer2; + bool _inSeedPod; + TaskScheduler _scheduler; void Reset() override { - restoreTimer = 0; - abilityTimer1 = 0; - abilityTimer2 = 30000; - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + _allowDeath = false; + _inSeedPod = false; + _scheduler.CancelAll(); + + me->RemoveAllAuras(); + 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 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 { - if (me->isRegeneratingHealth()) + if (!_inSeedPod) ScriptedAI::EnterEvadeMode(why); } @@ -196,57 +247,67 @@ struct npc_crystalline_frayer : public ScriptedAI { if (!_allowDeath) { - me->RemoveAllAuras(); - me->GetThreatMgr().ClearAllThreat(); - me->CombatStop(true); damage = 0; - - 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; + EnterSeedPod(); } } } + 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 { - if (restoreTimer) - { - restoreTimer += diff; - 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); - } + _scheduler.Update(diff); + + if (_inSeedPod) return; - } if (!UpdateVictim()) 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; - } } }; diff --git a/src/server/scripts/Northrend/Nexus/Nexus/nexus.h b/src/server/scripts/Northrend/Nexus/Nexus/nexus.h index 4d84bfa96..cc4184802 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/nexus.h +++ b/src/server/scripts/Northrend/Nexus/Nexus/nexus.h @@ -50,6 +50,7 @@ enum Npcs NPC_COMMANDER_STOUTBEARD = 26796, NPC_COMMANDER_KOLURG = 26798, + NPC_CRYSTALLINE_FRAYER = 26793, GO_TELESTRA_SPHERE = 188526, GO_ANOMALUS_SPHERE = 188527, diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp index 5f6478e64..3af170ba6 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp @@ -276,6 +276,7 @@ public: orb->RemoveAurasDueToSpell(SPELL_AWAKEN_SUBBOSS); me->RemoveAurasDueToSpell(SPELL_FREEZE); + me->GetThreatMgr().ResetAllThreat(); me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->SetControlled(false, UNIT_STATE_STUNNED); // SETINCOMBATWITHZONE diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp index 230678a4e..71c7fb42b 100644 --- a/src/server/scripts/Northrend/zone_zuldrak.cpp +++ b/src/server/scripts/Northrend/zone_zuldrak.cpp @@ -610,150 +610,6 @@ private: 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 ####*/ @@ -973,8 +829,6 @@ void AddSC_zuldrak() new npc_finklestein(); new go_finklestein_cauldron(); RegisterCreatureAI(npc_overlord_drakuru_betrayal); - new npc_drakuru_shackles(); - new npc_captured_rageclaw(); new npc_released_offspring_harkoa(); new npc_crusade_recruit(); new go_scourge_enclosure(); diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp index 639f88bd2..51cb46a99 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_talon_king_ikiss.cpp @@ -56,17 +56,20 @@ struct boss_talon_king_ikiss : public BossAI void Reset() override { _Reset(); - _spoken = false; + me->SetReactState(REACT_AGGRESSIVE); ScheduleHealthCheckEvent({ 80, 50, 25 }, [&] { me->InterruptNonMeleeSpells(false); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); DoCastAOE(SPELL_BLINK); DoCastSelf(SPELL_ARCANE_BUBBLE, true); Talk(EMOTE_ARCANE_EXP); scheduler.Schedule(1s, [this](TaskContext /*context*/) { DoCastAOE(SPELL_ARCANE_EXPLOSION); - }).Schedule(6500ms, [this](TaskContext /*context*/) + }).Schedule(7s, [this](TaskContext /*context*/) { + me->SetReactState(REACT_AGGRESSIVE); me->GetThreatMgr().ResetAllThreat(); }); }); @@ -160,7 +163,7 @@ class spell_talon_king_ikiss_blink : public SpellScript void HandleDummyHitTarget(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); - GetHitUnit()->CastSpell(GetCaster(), SPELL_BLINK_TELEPORT, true); + GetCaster()->CastSpell(GetHitUnit(), SPELL_BLINK_TELEPORT, true); } void Register() override diff --git a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp index 613596d5c..bd6e6d82c 100644 --- a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp +++ b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp @@ -90,7 +90,7 @@ struct boss_pathaleon_the_calculator : public BossAI me->LoadEquipment(EQUIPMENT_FRENZY); }); - scheduler.Schedule(20s, 25s, [this](TaskContext context) + scheduler.Schedule(10s, 16s, [this](TaskContext context) { if (!_isEnraged) { @@ -113,7 +113,7 @@ struct boss_pathaleon_the_calculator : public BossAI me->ModifyPower(POWER_MANA, 5000); DoCastSelf(SPELL_ARCANE_TORRENT); 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) { diff --git a/src/server/shared/Network/AsyncAcceptor.h b/src/server/shared/Network/AsyncAcceptor.h index 71c58ed93..1de085aaa 100644 --- a/src/server/shared/Network/AsyncAcceptor.h +++ b/src/server/shared/Network/AsyncAcceptor.h @@ -20,6 +20,7 @@ #include "IpAddress.h" #include "Log.h" +#include "Socket.h" #include "Systemd.h" #include #include @@ -32,7 +33,7 @@ constexpr auto ACORE_MAX_LISTEN_CONNECTIONS = boost::asio::socket_base::max_list class AsyncAcceptor { 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) : _acceptor(ioContext), _endpoint(Acore::Net::make_address(bindIp), port), @@ -56,7 +57,7 @@ public: template void AsyncAcceptWithCallback() { - tcp::socket* socket; + IoContextTcpSocket* socket; uint32 threadIndex; std::tie(socket, threadIndex) = _socketFactory(); _acceptor.async_accept(*socket, [this, socket, threadIndex](boost::system::error_code error) @@ -129,16 +130,16 @@ public: _acceptor.close(err); } - void SetSocketFactory(std::function()> func) { _socketFactory = func; } + void SetSocketFactory(std::function()> func) { _socketFactory = std::move(func); } private: - std::pair DefaultSocketFactory() { return std::make_pair(&_socket, 0); } + std::pair DefaultSocketFactory() { return std::make_pair(&_socket, 0); } - tcp::acceptor _acceptor; - tcp::endpoint _endpoint; - tcp::socket _socket; + boost::asio::basic_socket_acceptor _acceptor; + boost::asio::ip::tcp::endpoint _endpoint; + IoContextTcpSocket _socket; std::atomic _closed; - std::function()> _socketFactory; + std::function()> _socketFactory; bool _supportSocketActivation; }; diff --git a/src/server/shared/Network/NetworkThread.h b/src/server/shared/Network/NetworkThread.h index 674ad60ec..df39cd7f9 100644 --- a/src/server/shared/Network/NetworkThread.h +++ b/src/server/shared/Network/NetworkThread.h @@ -91,13 +91,13 @@ public: SocketAdded(sock); } - tcp::socket* GetSocketForAccept() { return &_acceptSocket; } + IoContextTcpSocket* GetSocketForAccept() { return &_acceptSocket; } void EnableProxyProtocol() { _proxyHeaderReadingEnabled = true; } protected: - virtual void SocketAdded(std::shared_ptr /*sock*/) { } - virtual void SocketRemoved(std::shared_ptr /*sock*/) { } + virtual void SocketAdded(std::shared_ptr const& /*sock*/) { } + virtual void SocketRemoved(std::shared_ptr const& /*sock*/) { } void AddNewSockets() { @@ -229,7 +229,7 @@ private: SocketContainer _newSockets; Acore::Asio::IoContext _ioContext; - tcp::socket _acceptSocket; + IoContextTcpSocket _acceptSocket; boost::asio::steady_timer _updateTimer; bool _proxyHeaderReadingEnabled; diff --git a/src/server/shared/Network/Socket.h b/src/server/shared/Network/Socket.h index c4ff85c30..4d551b19c 100644 --- a/src/server/shared/Network/Socket.h +++ b/src/server/shared/Network/Socket.h @@ -21,9 +21,8 @@ #include "Log.h" #include "MessageBuffer.h" #include -#include +#include #include -#include #include #include #include @@ -35,6 +34,23 @@ using boost::asio::ip::tcp; #define AC_SOCKET_USE_IOCP #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; + +enum class SocketReadCallbackResult +{ + KeepReading, + Stop +}; + +enum class SocketState : uint8 +{ + Open = 0, + Closing = 1, + Closed = 2 +}; + enum ProxyHeaderReadingState { PROXY_HEADER_READING_STATE_NOT_STARTED, PROXY_HEADER_READING_STATE_STARTED, @@ -51,8 +67,8 @@ template class Socket : public std::enable_shared_from_this { public: - explicit Socket(tcp::socket&& socket) : _socket(std::move(socket)), _remoteAddress(_socket.remote_endpoint().address()), - _remotePort(_socket.remote_endpoint().port()), _readBuffer(), _closed(false), _closing(false), _isWritingAsync(false), + explicit Socket(IoContextTcpSocket&& socket) : _socket(std::move(socket)), _remoteAddress(_socket.remote_endpoint().address()), + _remotePort(_socket.remote_endpoint().port()), _readBuffer(), _state(SocketState::Open), _isWritingAsync(false), _proxyHeaderReadingState(PROXY_HEADER_READING_STATE_NOT_STARTED) { _readBuffer.Resize(READ_BLOCK_SIZE); @@ -60,7 +76,7 @@ public: virtual ~Socket() { - _closed = true; + _state = SocketState::Closed; boost::system::error_code error; _socket.close(error); } @@ -69,13 +85,14 @@ public: virtual bool Update() { - if (_closed) + SocketState state = _state.load(); + if (state == SocketState::Closed) { return false; } #ifndef AC_SOCKET_USE_IOCP - if (_isWritingAsync || (_writeQueue.empty() && !_closing)) + if (_isWritingAsync || (_writeQueue.empty() && state != SocketState::Closing)) { return true; } @@ -150,12 +167,18 @@ public: [[nodiscard]] ProxyHeaderReadingState GetProxyHeaderReadingState() const { return _proxyHeaderReadingState; } - [[nodiscard]] bool IsOpen() const { return !_closed && !_closing; } + [[nodiscard]] bool IsOpen() const { return _state.load() == SocketState::Open; } void CloseSocket() { - if (_closed.exchange(true)) - return; + SocketState expected = SocketState::Open; + 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; _socket.shutdown(boost::asio::socket_base::shutdown_send, shutdownError); @@ -168,13 +191,17 @@ public: } /// 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; } protected: virtual void OnClose() { } - virtual void ReadHandler() = 0; + virtual SocketReadCallbackResult ReadHandler() = 0; bool AsyncProcessQueue() { @@ -188,7 +215,7 @@ protected: _socket.async_write_some(boost::asio::buffer(buffer.GetReadPointer(), buffer.GetActiveSize()), std::bind(&Socket::WriteHandler, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2)); #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); }); @@ -216,7 +243,8 @@ private: } _readBuffer.WriteCompleted(transferredBytes); - ReadHandler(); + if (ReadHandler() == SocketReadCallbackResult::KeepReading) + AsyncRead(); } // ProxyReadHeaderHandler reads Proxy Protocol v2 header (v1 is not supported). @@ -344,7 +372,7 @@ private: if (!_writeQueue.empty()) AsyncProcessQueue(); - else if (_closing) + else if (_state.load() == SocketState::Closing) CloseSocket(); } else @@ -380,7 +408,7 @@ private: _writeQueue.pop(); - if (_closing && _writeQueue.empty()) + if (_state.load() == SocketState::Closing && _writeQueue.empty()) { CloseSocket(); } @@ -391,7 +419,7 @@ private: { _writeQueue.pop(); - if (_closing && _writeQueue.empty()) + if (_state.load() == SocketState::Closing && _writeQueue.empty()) { CloseSocket(); } @@ -406,7 +434,7 @@ private: _writeQueue.pop(); - if (_closing && _writeQueue.empty()) + if (_state.load() == SocketState::Closing && _writeQueue.empty()) { CloseSocket(); } @@ -415,7 +443,7 @@ private: } #endif - tcp::socket _socket; + IoContextTcpSocket _socket; boost::asio::ip::address _remoteAddress; uint16 _remotePort; @@ -423,8 +451,7 @@ private: MessageBuffer _readBuffer; std::queue _writeQueue; - std::atomic _closed; - std::atomic _closing; + std::atomic _state; bool _isWritingAsync; diff --git a/src/server/shared/Network/SocketMgr.h b/src/server/shared/Network/SocketMgr.h index 085e4e238..56d0ed9a7 100644 --- a/src/server/shared/Network/SocketMgr.h +++ b/src/server/shared/Network/SocketMgr.h @@ -91,7 +91,7 @@ public: _threads[i].Wait(); } - virtual void OnSocketOpen(tcp::socket&& sock, uint32 threadIndex) + virtual void OnSocketOpen(IoContextTcpSocket&& sock, uint32 threadIndex) { try { @@ -117,7 +117,7 @@ public: return min; } - std::pair GetSocketForAccept() + std::pair GetSocketForAccept() { uint32 threadIndex = SelectThreadWithMinConnections(); return { _threads[threadIndex].GetSocketForAccept(), threadIndex }; diff --git a/tools/socket_stress_heavy.py b/tools/socket_stress_heavy.py new file mode 100644 index 000000000..8352a8bd8 --- /dev/null +++ b/tools/socket_stress_heavy.py @@ -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()