mirror of
https://gitcode.com/GitHub_Trending/az/azerothcore-wotlk.git
synced 2026-10-10 07:06:38 +08:00
fix(Core/GameObject): trigger chest traps once per loot generation (#27381)
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
--
|
||||
-- Shallow Grave
|
||||
-- Entry 128403 summons through its WDB-linked trap; entry 128308 is the inert alternative.
|
||||
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 128308) AND (`source_type` = 1);
|
||||
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 128403) AND (`source_type` = 1);
|
||||
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||
(128308, 1, 0, 0, 64, 0, 100, 1, 0, 0, 0, 0, 0, 41, 300000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shallow Grave - On Gossip Hello - Despawn after 5 minutes'),
|
||||
(128403, 1, 0, 0, 64, 0, 100, 1, 0, 0, 0, 0, 0, 41, 300000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shallow Grave - On Gossip Hello - Despawn after 5 minutes');
|
||||
@@ -0,0 +1,25 @@
|
||||
-- Zul'Farrak grave summons: use the Loot Normalization (#24398) world loot pools.
|
||||
-- Gultask's WotLK Classic research (builds 49822, 52237 and 54261):
|
||||
-- https://github.com/azerothcore/azerothcore-wotlk/pull/27381#issuecomment-5798468763
|
||||
-- Keep Troll Sweat, cloth, food, ZF junk and quest drops unchanged.
|
||||
-- Remove direct world drops supplied by the normalized references to avoid duplicate rolls.
|
||||
DELETE FROM `creature_loot_template` WHERE `Entry` IN (7276, 7286) AND `Reference` = 0 AND `Item` IN
|
||||
(1685,3395,3831,3832,3864,3868,3873,3874,3914,3928,4300,4353,4416,4417,4419,4421,4422,4424,
|
||||
4637,4638,5974,6149,7084,7085,7086,7453,7909,7910,7975,7989,7990,7992,7993,8029,8386,8387,
|
||||
8389,8390,9293,9295,9298,10300,10301,10302,10312,10315,10320,10603,10604,10606,11167,11202,
|
||||
11204,11208,11225,12684,13068);
|
||||
DELETE FROM `creature_loot_template` WHERE `Entry` IN (7276, 7286) AND `Reference` <> 0;
|
||||
INSERT INTO `creature_loot_template`
|
||||
(`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
|
||||
(7276, 1, 1000145, 0, 0, 1, 5, 1, 1, 'Zul''Farrak Dead Hero - World Loot Level 45'),
|
||||
(7276, 2, 1000146, 0, 0, 1, 5, 1, 1, 'Zul''Farrak Dead Hero - World Loot Level 46'),
|
||||
(7286, 1, 1000343, 0, 0, 1, 5, 1, 1, 'Zul''Farrak Zombie - World Loot Level 43'),
|
||||
(7286, 2, 1000344, 0, 0, 1, 5, 1, 1, 'Zul''Farrak Zombie - World Loot Level 44'),
|
||||
(7286, 209, 1209000, 0.5, 0, 1, 0, 1, 1, 'Zul''Farrak Zombie - Zul''Farrak BoEs');
|
||||
|
||||
-- Money research from the same sniffs:
|
||||
-- https://github.com/azerothcore/azerothcore-wotlk/pull/27381#issuecomment-5798878487
|
||||
-- Zombie bounds are inferred from comparable level 44 ZF elites; keep Dead Hero money unchanged.
|
||||
UPDATE `creature_template` SET `mingold` = 186, `maxgold` = 1438 WHERE `entry` = 7286;
|
||||
-- Observed grave money range, in copper. This addon table has no VerifiedBuild column.
|
||||
UPDATE `gameobject_template_addon` SET `mingold` = 18, `maxgold` = 131 WHERE `entry` IN (128308, 128403);
|
||||
@@ -0,0 +1,215 @@
|
||||
-- Shallow Grave alternatives from Gultask's Classic sniff research:
|
||||
-- https://github.com/azerothcore/azerothcore-wotlk/pull/27381#issuecomment-5803161498
|
||||
-- Each location has an inert (128308) or trapped (128403) grave, never both.
|
||||
-- The 75% active / 25% inert weighting is inferred, not an exact measured probability.
|
||||
-- Preserve existing spawn GUIDs and the one-day respawn; add only the alternate at each location.
|
||||
DELETE FROM `gameobject` WHERE `guid` BETWEEN 27097 AND 27139 AND `id` IN (128308, 128403);
|
||||
DELETE FROM `gameobject` WHERE `guid` BETWEEN 43921 AND 43960 AND `id` IN (128308, 128403);
|
||||
INSERT INTO `gameobject`
|
||||
(`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`) VALUES
|
||||
(43921, 128308, 209, 1176, 1176, 1, 1, 1832.719, 1032.393, 9.452, 0.5759572982788086, 0, 0, 0.2840147018432617, 0.9588199257850647, 86400, 100, 1, 49822),
|
||||
(27114, 128403, 209, 1176, 1176, 1, 1, 1832.719, 1032.393, 9.452, 0.5759572982788086, 0, 0, 0.2840147018432617, 0.9588199257850647, 86400, 100, 1, 42940),
|
||||
(27116, 128308, 209, 1176, 1176, 1, 1, 1836.745, 1029.358, 9.624, 0.9424766302108765, 0, 0, 0.45398998260498047, 0.8910067677497864, 86400, 100, 1, 49345),
|
||||
(43922, 128403, 209, 1176, 1176, 1, 1, 1836.745, 1029.358, 9.624, 0.9424766302108765, 0, 0, 0.45398998260498047, 0.8910067677497864, 86400, 100, 1, 42940),
|
||||
(43923, 128308, 209, 1176, 1176, 1, 1, 1839.181, 1036.884, 9.352, 4.607671737670898, 0, 0, -0.7431440353393555, 0.6691314578056335, 86400, 100, 1, 49822),
|
||||
(27120, 128403, 209, 1176, 1176, 1, 1, 1839.181, 1036.884, 9.352, 4.607671737670898, 0, 0, -0.7431440353393555, 0.6691314578056335, 86400, 100, 1, 42940),
|
||||
(43924, 128308, 209, 1176, 1176, 1, 1, 1839.422, 1023.486, 9.563, 2.9844982624053955, 0, 0, 0.9969167709350586, 0.07846643030643463, 86400, 100, 1, 44400),
|
||||
(27102, 128403, 209, 1176, 1176, 1, 1, 1839.422, 1023.486, 9.563, 2.9844982624053955, 0, 0, 0.9969167709350586, 0.07846643030643463, 86400, 100, 1, 42940),
|
||||
(43925, 128308, 209, 1176, 1176, 1, 1, 1841.083, 1045.543, 9.216, 3.0543265342712402, 0, 0, 0.9990482330322266, 0.04361926019191742, 86400, 100, 1, 49345),
|
||||
(27115, 128403, 209, 1176, 1176, 1, 1, 1841.083, 1045.543, 9.216, 3.0543265342712402, 0, 0, 0.9990482330322266, 0.04361926019191742, 86400, 100, 1, 42940),
|
||||
(43926, 128308, 209, 1176, 1176, 1, 1, 1841.821, 1027.759, 9.151, 0.9599299430847168, 0, 0, 0.4617481231689453, 0.8870111107826233, 86400, 100, 1, 49822),
|
||||
(27119, 128403, 209, 1176, 1176, 1, 1, 1841.821, 1027.759, 9.151, 0.9599299430847168, 0, 0, 0.4617481231689453, 0.8870111107826233, 86400, 100, 1, 42940),
|
||||
(43927, 128308, 209, 1176, 1176, 1, 1, 1843.193, 1041.155, 8.877, 5.881760597229004, 0, 0, -0.19936752319335938, 0.9799247980117798, 86400, 100, 1, 49345),
|
||||
(27118, 128403, 209, 1176, 1176, 1, 1, 1843.193, 1041.155, 8.877, 5.881760597229004, 0, 0, -0.19936752319335938, 0.9799247980117798, 86400, 100, 1, 42940),
|
||||
(43928, 128308, 209, 1176, 1176, 1, 1, 1845.539, 1024.121, 9.08, 0.9773830771446228, 0, 0, 0.4694709777832031, 0.8829479217529297, 86400, 100, 1, 49822),
|
||||
(27121, 128403, 209, 1176, 1176, 1, 1, 1845.539, 1024.121, 9.08, 0.9773830771446228, 0, 0, 0.4694709777832031, 0.8829479217529297, 86400, 100, 1, 42940),
|
||||
(43929, 128308, 209, 1176, 1176, 1, 1, 1845.959, 1047.25, 8.877, 5.829400539398193, 0, 0, -0.22495079040527344, 0.9743701219558716, 86400, 100, 1, 44400),
|
||||
(27133, 128403, 209, 1176, 1176, 1, 1, 1845.959, 1047.25, 8.877, 5.829400539398193, 0, 0, -0.22495079040527344, 0.9743701219558716, 86400, 100, 1, 42940),
|
||||
(43930, 128308, 209, 1176, 1176, 1, 1, 1852.408, 1024.781, 8.877, 3.787367343902588, 0, 0, -0.9483232498168945, 0.31730589270591736, 86400, 100, 1, 49822),
|
||||
(27117, 128403, 209, 1176, 1176, 1, 1, 1852.408, 1024.781, 8.877, 3.787367343902588, 0, 0, -0.9483232498168945, 0.31730589270591736, 86400, 100, 1, 42940),
|
||||
(43931, 128308, 209, 1176, 1176, 1, 1, 1858.698, 1053.75, 8.877, 3.5430235862731934, 0, 0, -0.979924201965332, 0.1993703842163086, 86400, 100, 1, 44400),
|
||||
(27134, 128403, 209, 1176, 1176, 1, 1, 1858.698, 1053.75, 8.877, 3.5430235862731934, 0, 0, -0.979924201965332, 0.1993703842163086, 86400, 100, 1, 42940),
|
||||
(43932, 128308, 209, 1176, 1176, 1, 1, 1861.116, 1019.389, 8.877, 5.096362113952637, 0, 0, -0.5591926574707031, 0.8290377259254456, 86400, 100, 1, 49822),
|
||||
(27103, 128403, 209, 1176, 1176, 1, 1, 1861.116, 1019.389, 8.877, 5.096362113952637, 0, 0, -0.5591926574707031, 0.8290377259254456, 86400, 100, 1, 42940),
|
||||
(43933, 128308, 209, 1176, 1176, 1, 1, 1862.12, 1050.756, 9.057, 3.892086982727051, 0, 0, -0.9304170608520508, 0.3665024936199188, 86400, 100, 1, 42940),
|
||||
(27135, 128403, 209, 1176, 1176, 1, 1, 1862.12, 1050.756, 9.057, 3.892086982727051, 0, 0, -0.9304170608520508, 0.3665024936199188, 86400, 100, 1, 44400),
|
||||
(27122, 128308, 209, 1176, 1176, 1, 1, 1863.409, 1044.78, 8.877, 4.572763919830322, 0, 0, -0.7547092437744141, 0.6560594439506531, 86400, 100, 1, 42940),
|
||||
(43934, 128403, 209, 1176, 1176, 1, 1, 1863.409, 1044.78, 8.877, 4.572763919830322, 0, 0, -0.7547092437744141, 0.6560594439506531, 86400, 100, 1, 49345),
|
||||
(43935, 128308, 209, 1176, 1176, 1, 1, 1865.033, 1012.491, 8.877, 1.0471975803375244, 0, 0, 0.5, 0.8660253882408142, 86400, 100, 1, 52237),
|
||||
(27105, 128403, 209, 1176, 1176, 1, 1, 1865.033, 1012.491, 8.877, 1.0471975803375244, 0, 0, 0.5, 0.8660253882408142, 86400, 100, 1, 42940),
|
||||
(43936, 128308, 209, 1176, 1176, 1, 1, 1866.235, 1008.397, 8.877, 0.6632232069969177, 0, 0, 0.32556724548339844, 0.9455188512802124, 86400, 100, 1, 44400),
|
||||
(27104, 128403, 209, 1176, 1176, 1, 1, 1866.235, 1008.397, 8.877, 0.6632232069969177, 0, 0, 0.32556724548339844, 0.9455188512802124, 86400, 100, 1, 42940),
|
||||
(27136, 128308, 209, 1176, 1176, 1, 1, 1866.326, 1049.636, 9.015, 1.1170092821121216, 0, 0, 0.5299186706542969, 0.8480484485626221, 86400, 100, 1, 44400),
|
||||
(43937, 128403, 209, 1176, 1176, 1, 1, 1866.326, 1049.636, 9.015, 1.1170092821121216, 0, 0, 0.5299186706542969, 0.8480484485626221, 86400, 100, 1, 42940),
|
||||
(43938, 128308, 209, 1176, 1176, 1, 1, 1867.745, 1041.844, 8.877, 5.846853733062744, 0, 0, -0.21643924713134766, 0.976296067237854, 86400, 100, 1, 49822),
|
||||
(27126, 128403, 209, 1176, 1176, 1, 1, 1867.745, 1041.844, 8.877, 5.846853733062744, 0, 0, -0.21643924713134766, 0.976296067237854, 86400, 100, 1, 42940),
|
||||
(27127, 128308, 209, 1176, 1176, 1, 1, 1869.284, 1020.079, 8.877, 5.794494152069092, 0, 0, -0.24192142486572266, 0.9702958464622498, 86400, 100, 1, 49345),
|
||||
(43939, 128403, 209, 1176, 1176, 1, 1, 1869.284, 1020.079, 8.877, 5.794494152069092, 0, 0, -0.24192142486572266, 0.9702958464622498, 86400, 100, 1, 42940),
|
||||
(43940, 128308, 209, 1176, 1176, 1, 1, 1871.077, 1046.756, 9.034, 4.118979454040527, 0, 0, -0.8829469680786133, 0.4694727063179016, 86400, 100, 1, 52237),
|
||||
(27138, 128403, 209, 1176, 1176, 1, 1, 1871.077, 1046.756, 9.034, 4.118979454040527, 0, 0, -0.8829469680786133, 0.4694727063179016, 86400, 100, 1, 42940),
|
||||
(43941, 128308, 209, 1176, 1176, 1, 1, 1871.296, 1008.323, 8.877, 1.08210289478302, 0, 0, 0.5150375366210938, 0.8571676015853882, 86400, 100, 1, 54558),
|
||||
(27113, 128403, 209, 1176, 1176, 1, 1, 1871.296, 1008.323, 8.877, 1.08210289478302, 0, 0, 0.5150375366210938, 0.8571676015853882, 86400, 100, 1, 42940),
|
||||
(43942, 128308, 209, 1176, 1176, 1, 1, 1871.855, 994.256, 8.882, 0.5061445832252502, 0, 0, 0.2503795623779297, 0.9681477546691895, 86400, 100, 1, 49822),
|
||||
(27111, 128403, 209, 1176, 1176, 1, 1, 1871.855, 994.256, 8.882, 0.5061445832252502, 0, 0, 0.2503795623779297, 0.9681477546691895, 86400, 100, 1, 42940),
|
||||
(43943, 128308, 209, 1176, 1176, 1, 1, 1875.847, 1044.261, 9.078, 0.855210542678833, 0, 0, 0.41469287872314453, 0.909961462020874, 86400, 100, 1, 52237),
|
||||
(27139, 128403, 209, 1176, 1176, 1, 1, 1875.847, 1044.261, 9.078, 0.855210542678833, 0, 0, 0.41469287872314453, 0.909961462020874, 86400, 100, 1, 42940),
|
||||
(27101, 128308, 209, 1176, 1176, 1, 1, 1876.138, 976.482, 9.052, 1.0122894048690796, 0, 0, 0.48480892181396484, 0.8746200799942017, 86400, 100, 1, 52237),
|
||||
(43944, 128403, 209, 1176, 1176, 1, 1, 1876.138, 976.482, 9.052, 1.0122894048690796, 0, 0, 0.48480892181396484, 0.8746200799942017, 86400, 100, 1, 42940),
|
||||
(43945, 128308, 209, 1176, 1176, 1, 1, 1876.44, 972.207, 9.912, 2.8448827266693115, 0, 0, 0.9890155792236328, 0.14781136810779572, 86400, 100, 1, 42940),
|
||||
(27099, 128403, 209, 1176, 1176, 1, 1, 1876.44, 972.207, 9.912, 2.8448827266693115, 0, 0, 0.9890155792236328, 0.14781136810779572, 86400, 100, 1, 49345),
|
||||
(43946, 128308, 209, 1176, 1176, 1, 1, 1879.89, 974.651, 8.877, 1.0471975803375244, 0, 0, 0.5, 0.8660253882408142, 86400, 100, 1, 42940),
|
||||
(27098, 128403, 209, 1176, 1176, 1, 1, 1879.89, 974.651, 8.877, 1.0471975803375244, 0, 0, 0.5, 0.8660253882408142, 86400, 100, 1, 49345),
|
||||
(43947, 128308, 209, 1176, 1176, 1, 1, 1881.465, 1041.431, 8.877, 4.084071159362793, 0, 0, -0.8910064697265625, 0.453990638256073, 86400, 100, 1, 42940),
|
||||
(27137, 128403, 209, 1176, 1176, 1, 1, 1881.465, 1041.431, 8.877, 4.084071159362793, 0, 0, -0.8910064697265625, 0.453990638256073, 86400, 100, 1, 44400),
|
||||
(43948, 128308, 209, 1176, 1176, 1, 1, 1881.989, 1034.684, 8.877, 5.829400539398193, 0, 0, -0.22495079040527344, 0.9743701219558716, 86400, 100, 1, 54261),
|
||||
(27131, 128403, 209, 1176, 1176, 1, 1, 1881.989, 1034.684, 8.877, 5.829400539398193, 0, 0, -0.22495079040527344, 0.9743701219558716, 86400, 100, 1, 42940),
|
||||
(43949, 128308, 209, 1176, 1176, 1, 1, 1882.703, 971.825, 8.877, 0.9948371648788452, 0, 0, 0.4771585464477539, 0.8788172602653503, 86400, 100, 1, 44400),
|
||||
(27100, 128403, 209, 1176, 1176, 1, 1, 1882.703, 971.825, 8.877, 0.9948371648788452, 0, 0, 0.4771585464477539, 0.8788172602653503, 86400, 100, 1, 42940),
|
||||
(43950, 128308, 209, 1176, 1176, 1, 1, 1887.458, 967.143, 8.985, 5.969027042388916, 0, 0, -0.1564340591430664, 0.9876883625984192, 86400, 100, 1, 42940),
|
||||
(27097, 128403, 209, 1176, 1176, 1, 1, 1887.458, 967.143, 8.985, 5.969027042388916, 0, 0, -0.1564340591430664, 0.9876883625984192, 86400, 100, 1, 49345),
|
||||
(43951, 128308, 209, 1176, 1176, 1, 1, 1887.94, 1029.084, 9.148, 0.855210542678833, 0, 0, 0.41469287872314453, 0.909961462020874, 86400, 100, 1, 49822),
|
||||
(27128, 128403, 209, 1176, 1176, 1, 1, 1887.94, 1029.084, 9.148, 0.855210542678833, 0, 0, 0.41469287872314453, 0.909961462020874, 86400, 100, 1, 42940),
|
||||
(43952, 128308, 209, 1176, 1176, 1, 1, 1888.363, 1037.002, 8.921, 4.293513298034668, 0, 0, -0.8386697769165039, 0.5446402430534363, 86400, 100, 1, 42940),
|
||||
(27130, 128403, 209, 1176, 1176, 1, 1, 1888.363, 1037.002, 8.921, 4.293513298034668, 0, 0, -0.8386697769165039, 0.5446402430534363, 86400, 100, 1, 44400),
|
||||
(27110, 128308, 209, 1176, 1176, 1, 1, 1888.636, 977.75, 8.877, 3.7175536155700684, 0, 0, -0.9588193893432617, 0.2840164601802826, 86400, 100, 1, 49822),
|
||||
(43953, 128403, 209, 1176, 1176, 1, 1, 1888.636, 977.75, 8.877, 3.7175536155700684, 0, 0, -0.9588193893432617, 0.2840164601802826, 86400, 100, 1, 42940),
|
||||
(43954, 128308, 209, 1176, 1176, 1, 1, 1890.123, 989.759, 8.877, 2.7052552700042725, 0, 0, 0.9762954711914062, 0.2164420634508133, 86400, 100, 1, 49345),
|
||||
(27106, 128403, 209, 1176, 1176, 1, 1, 1890.123, 989.759, 8.877, 2.7052552700042725, 0, 0, 0.9762954711914062, 0.2164420634508133, 86400, 100, 1, 42940),
|
||||
(27112, 128308, 209, 1176, 1176, 1, 1, 1890.268, 970.862, 9.014, 2.565631866455078, 0, 0, 0.9588193893432617, 0.2840164601802826, 86400, 100, 1, 42940),
|
||||
(43955, 128403, 209, 1176, 1176, 1, 1, 1890.268, 970.862, 9.014, 2.565631866455078, 0, 0, 0.9588193893432617, 0.2840164601802826, 86400, 100, 1, 44400),
|
||||
(43956, 128308, 209, 1176, 1176, 1, 1, 1891.598, 1023.06, 9.371, 2.792518377304077, 0, 0, 0.984807014465332, 0.1736523061990738, 86400, 100, 1, 49822),
|
||||
(27132, 128403, 209, 1176, 1176, 1, 1, 1891.598, 1023.06, 9.371, 2.792518377304077, 0, 0, 0.984807014465332, 0.1736523061990738, 86400, 100, 1, 42940),
|
||||
(43957, 128308, 209, 1176, 1176, 1, 1, 1892.571, 1006.369, 9.068, 4.1538848876953125, 0, 0, -0.8746194839477539, 0.4848100543022156, 86400, 100, 1, 49345),
|
||||
(27129, 128403, 209, 1176, 1176, 1, 1, 1892.571, 1006.369, 9.068, 4.1538848876953125, 0, 0, -0.8746194839477539, 0.4848100543022156, 86400, 100, 1, 42940),
|
||||
(43958, 128308, 209, 1176, 1176, 1, 1, 1894.394, 977.006, 8.926, 6.003933906555176, 0, 0, -0.13917255401611328, 0.9902681708335876, 86400, 100, 1, 42940),
|
||||
(27108, 128403, 209, 1176, 1176, 1, 1, 1894.394, 977.006, 8.926, 6.003933906555176, 0, 0, -0.13917255401611328, 0.9902681708335876, 86400, 100, 1, 44400),
|
||||
(27107, 128308, 209, 1176, 1176, 1, 1, 1897.079, 980.836, 8.959, 3.298687219619751, 0, 0, -0.9969167709350586, 0.07846643030643463, 86400, 100, 1, 42940),
|
||||
(43959, 128403, 209, 1176, 1176, 1, 1, 1897.079, 980.836, 8.959, 3.298687219619751, 0, 0, -0.9969167709350586, 0.07846643030643463, 86400, 100, 1, 49345),
|
||||
(27109, 128308, 209, 1176, 1176, 1, 1, 1897.983, 985.276, 8.898, 2.757613182067871, 0, 0, 0.9816265106201172, 0.19081240892410278, 86400, 100, 1, 59415),
|
||||
(43960, 128403, 209, 1176, 1176, 1, 1, 1897.983, 985.276, 8.898, 2.757613182067871, 0, 0, 0.9816265106201172, 0.19081240892410278, 86400, 100, 1, 42940);
|
||||
|
||||
DELETE FROM `pool_template` WHERE `entry` BETWEEN 1121 AND 1160;
|
||||
INSERT INTO `pool_template` (`entry`, `max_limit`, `description`) VALUES
|
||||
(1121, 1, 'Zul''Farrak - Shallow Grave 1'),
|
||||
(1122, 1, 'Zul''Farrak - Shallow Grave 2'),
|
||||
(1123, 1, 'Zul''Farrak - Shallow Grave 3'),
|
||||
(1124, 1, 'Zul''Farrak - Shallow Grave 4'),
|
||||
(1125, 1, 'Zul''Farrak - Shallow Grave 5'),
|
||||
(1126, 1, 'Zul''Farrak - Shallow Grave 6'),
|
||||
(1127, 1, 'Zul''Farrak - Shallow Grave 7'),
|
||||
(1128, 1, 'Zul''Farrak - Shallow Grave 8'),
|
||||
(1129, 1, 'Zul''Farrak - Shallow Grave 9'),
|
||||
(1130, 1, 'Zul''Farrak - Shallow Grave 10'),
|
||||
(1131, 1, 'Zul''Farrak - Shallow Grave 11'),
|
||||
(1132, 1, 'Zul''Farrak - Shallow Grave 12'),
|
||||
(1133, 1, 'Zul''Farrak - Shallow Grave 13'),
|
||||
(1134, 1, 'Zul''Farrak - Shallow Grave 14'),
|
||||
(1135, 1, 'Zul''Farrak - Shallow Grave 15'),
|
||||
(1136, 1, 'Zul''Farrak - Shallow Grave 16'),
|
||||
(1137, 1, 'Zul''Farrak - Shallow Grave 17'),
|
||||
(1138, 1, 'Zul''Farrak - Shallow Grave 18'),
|
||||
(1139, 1, 'Zul''Farrak - Shallow Grave 19'),
|
||||
(1140, 1, 'Zul''Farrak - Shallow Grave 20'),
|
||||
(1141, 1, 'Zul''Farrak - Shallow Grave 21'),
|
||||
(1142, 1, 'Zul''Farrak - Shallow Grave 22'),
|
||||
(1143, 1, 'Zul''Farrak - Shallow Grave 23'),
|
||||
(1144, 1, 'Zul''Farrak - Shallow Grave 24'),
|
||||
(1145, 1, 'Zul''Farrak - Shallow Grave 25'),
|
||||
(1146, 1, 'Zul''Farrak - Shallow Grave 26'),
|
||||
(1147, 1, 'Zul''Farrak - Shallow Grave 27'),
|
||||
(1148, 1, 'Zul''Farrak - Shallow Grave 28'),
|
||||
(1149, 1, 'Zul''Farrak - Shallow Grave 29'),
|
||||
(1150, 1, 'Zul''Farrak - Shallow Grave 30'),
|
||||
(1151, 1, 'Zul''Farrak - Shallow Grave 31'),
|
||||
(1152, 1, 'Zul''Farrak - Shallow Grave 32'),
|
||||
(1153, 1, 'Zul''Farrak - Shallow Grave 33'),
|
||||
(1154, 1, 'Zul''Farrak - Shallow Grave 34'),
|
||||
(1155, 1, 'Zul''Farrak - Shallow Grave 35'),
|
||||
(1156, 1, 'Zul''Farrak - Shallow Grave 36'),
|
||||
(1157, 1, 'Zul''Farrak - Shallow Grave 37'),
|
||||
(1158, 1, 'Zul''Farrak - Shallow Grave 38'),
|
||||
(1159, 1, 'Zul''Farrak - Shallow Grave 39'),
|
||||
(1160, 1, 'Zul''Farrak - Shallow Grave 40');
|
||||
|
||||
DELETE FROM `pool_gameobject` WHERE `pool_entry` BETWEEN 1121 AND 1160;
|
||||
INSERT INTO `pool_gameobject` (`guid`, `pool_entry`, `chance`, `description`) VALUES
|
||||
(43921, 1121, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27114, 1121, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(27116, 1122, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(43922, 1122, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43923, 1123, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27120, 1123, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43924, 1124, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27102, 1124, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43925, 1125, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27115, 1125, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43926, 1126, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27119, 1126, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43927, 1127, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27118, 1127, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43928, 1128, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27121, 1128, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43929, 1129, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27133, 1129, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43930, 1130, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27117, 1130, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43931, 1131, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27134, 1131, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43932, 1132, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27103, 1132, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43933, 1133, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27135, 1133, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(27122, 1134, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(43934, 1134, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43935, 1135, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27105, 1135, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43936, 1136, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27104, 1136, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(27136, 1137, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(43937, 1137, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43938, 1138, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27126, 1138, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(27127, 1139, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(43939, 1139, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43940, 1140, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27138, 1140, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43941, 1141, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27113, 1141, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43942, 1142, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27111, 1142, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43943, 1143, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27139, 1143, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(27101, 1144, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(43944, 1144, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43945, 1145, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27099, 1145, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43946, 1146, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27098, 1146, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43947, 1147, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27137, 1147, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43948, 1148, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27131, 1148, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43949, 1149, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27100, 1149, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43950, 1150, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27097, 1150, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43951, 1151, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27128, 1151, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43952, 1152, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27130, 1152, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(27110, 1153, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(43953, 1153, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43954, 1154, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27106, 1154, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(27112, 1155, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(43955, 1155, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43956, 1156, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27132, 1156, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43957, 1157, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27129, 1157, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(43958, 1158, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(27108, 1158, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(27107, 1159, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(43959, 1159, 75, 'Zul''Farrak - Trapped Shallow Grave'),
|
||||
(27109, 1160, 25, 'Zul''Farrak - Inert Shallow Grave'),
|
||||
(43960, 1160, 75, 'Zul''Farrak - Trapped Shallow Grave');
|
||||
@@ -171,6 +171,24 @@ go test -tags=e2e ./local/... -count=1 -v -timeout 30m -parallel 1
|
||||
|
||||
---
|
||||
|
||||
### Chest regression checks (PR #27381)
|
||||
|
||||
`world/chests` covers Cat Figurine reopening, Ice Chest party rolls and reward attribution,
|
||||
and both Shallow Grave variants: inert graves summon nothing; trapped graves do not summon
|
||||
again on reopening. Grave checks include full bags, another looter, consuming all loot,
|
||||
and replaying an opening request after despawn. Live execution is still pending.
|
||||
|
||||
```bash
|
||||
go test -tags=e2e ./suites/world/chests -count=2 -v -p 1 -parallel 1 -timeout 20m
|
||||
```
|
||||
|
||||
Use a disposable realm with the pending migrations applied. Tests create temporary fixtures
|
||||
through cleanup-enabled spawn helpers, not the dungeon's real graves. They sample up to
|
||||
48 fresh graves for item loot and a positive summon from the trapped variant; inability to
|
||||
obtain that fixture fails as a precondition. Initial empty-loot coverage is not claimed:
|
||||
the grave money range is now nonzero. Exact summon/drop probabilities and the dungeon's
|
||||
pool selection are not asserted by these lifecycle tests.
|
||||
|
||||
## Parallelism and isolation
|
||||
|
||||
### Model
|
||||
|
||||
@@ -0,0 +1,417 @@
|
||||
//go:build e2e
|
||||
|
||||
package chests_test
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/azerothcore/AzerothGhost/client"
|
||||
"github.com/azerothcore/AzerothGhost/e2e/e2eharness"
|
||||
"github.com/azerothcore/azerothcore-wotlk/e2e/internal/meta"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
|
||||
// PR: https://github.com/azerothcore/azerothcore-wotlk/pull/27381
|
||||
// Use fresh, cleaned-up spawns at an isolation pad, never the dungeon's real graves.
|
||||
// These are chest lifecycle tests, not tests of Ahune or Zum'rah's encounter.
|
||||
func chestBots(t *testing.T) (actor, mate, observer *e2eharness.ScenarioBot) {
|
||||
t.Helper()
|
||||
bots := e2eharness.NewScenario(t, e2eharness.ScenarioOpts{
|
||||
Prefix: "Chests", Count: 3, Race: e2eharness.RaceHuman, Class: e2eharness.ClassWarrior, Level: 80,
|
||||
})
|
||||
actor, mate, observer = bots[0], bots[1], bots[2]
|
||||
pad := e2eharness.PackagePad(t)
|
||||
e2eharness.FormPartyAtPad(t, pad, actor, mate)
|
||||
observer.TeleportPad(t, pad)
|
||||
// The Ice Chest's bunny is an invisible trigger; a separate GM observes it.
|
||||
// Neither looter gets GM-mode loot privileges.
|
||||
observer.GM(t, ".gm on")
|
||||
observer.FlushWorld(t)
|
||||
actor.CombatReady(t)
|
||||
mate.CombatReady(t)
|
||||
return
|
||||
}
|
||||
|
||||
func spawnChest(t *testing.T, observer, actor *e2eharness.ScenarioBot, entry uint32) uint64 {
|
||||
t.Helper()
|
||||
if observer.SpawnGameObject(t, entry) == 0 {
|
||||
e2eharness.Preconditionf(t, "cannot resolve cleanup spawn ID for chest %d", entry)
|
||||
}
|
||||
return actor.WaitGameObject(t, entry, 10*time.Second)
|
||||
}
|
||||
|
||||
type chestLoot struct {
|
||||
gold uint32
|
||||
items []client.LootItem
|
||||
}
|
||||
|
||||
// v1.0.8 has no gameobject-target cast helper. Use its raw packet API, with the
|
||||
// same CMSG_CAST_SPELL layout read by WorldSession::HandleCastSpellOpcode.
|
||||
// CMSG_LOOT bypasses Spell::SendLoot; CMSG_GAMEOBJ_USE alone does not open a chest.
|
||||
func castOpening(t *testing.T, bot *e2eharness.ScenarioBot, guid uint64, spell uint32) {
|
||||
t.Helper()
|
||||
payload := make([]byte, 11) // cast count, spell, cast flags, target flags, packed-GUID mask
|
||||
binary.LittleEndian.PutUint32(payload[1:5], spell)
|
||||
binary.LittleEndian.PutUint32(payload[6:10], 0x0800) // TARGET_FLAG_GAMEOBJECT
|
||||
for i := uint(0); i < 8; i++ {
|
||||
if b := byte(guid >> (8 * i)); b != 0 {
|
||||
payload[10] |= 1 << i
|
||||
payload = append(payload, b)
|
||||
}
|
||||
}
|
||||
if err := bot.World.SendPacketRaw(client.CmsgCastSpell, payload); err != nil {
|
||||
e2eharness.HarnessFailf(t, "Opening packet: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func openChest(t *testing.T, bot *e2eharness.ScenarioBot, guid uint64, spell uint32) chestLoot {
|
||||
t.Helper()
|
||||
packets := make(chan []byte, 1)
|
||||
cancel := bot.World.AddPacketHook(func(op uint16, data []byte) {
|
||||
if op == client.SmsgLootResponse && len(data) >= 8 && binary.LittleEndian.Uint64(data) == guid {
|
||||
select {
|
||||
case packets <- append([]byte(nil), data...):
|
||||
default:
|
||||
}
|
||||
}
|
||||
})
|
||||
defer cancel()
|
||||
castOpening(t, bot, guid, spell)
|
||||
select {
|
||||
case data := <-packets:
|
||||
if len(data) < 14 || len(data) < 14+22*int(data[13]) {
|
||||
e2eharness.Assertf(t, "chest 0x%X rejected opening or returned malformed loot: %x", guid, data)
|
||||
}
|
||||
result := chestLoot{gold: binary.LittleEndian.Uint32(data[9:13])}
|
||||
for i := 0; i < int(data[13]); i++ {
|
||||
row := data[14+i*22:]
|
||||
result.items = append(result.items, client.LootItem{
|
||||
Index: row[0], ItemID: binary.LittleEndian.Uint32(row[1:5]), Quantity: binary.LittleEndian.Uint32(row[5:9]),
|
||||
})
|
||||
}
|
||||
return result
|
||||
case <-time.After(12 * time.Second):
|
||||
e2eharness.Assertf(t, "chest 0x%X: no loot response to Opening spell %d", guid, spell)
|
||||
return chestLoot{}
|
||||
}
|
||||
}
|
||||
|
||||
func closeChest(t *testing.T, bot *e2eharness.ScenarioBot, guid uint64) {
|
||||
t.Helper()
|
||||
ack := make(chan struct{}, 1)
|
||||
cancel := bot.World.AddPacketHook(func(op uint16, data []byte) {
|
||||
if op == client.SmsgLootReleaseResponse && len(data) >= 8 && binary.LittleEndian.Uint64(data) == guid {
|
||||
select {
|
||||
case ack <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
})
|
||||
defer cancel()
|
||||
bot.LootRelease(t, guid)
|
||||
select {
|
||||
case <-ack:
|
||||
case <-time.After(5 * time.Second):
|
||||
e2eharness.HarnessFailf(t, "no loot release acknowledgement for 0x%X", guid)
|
||||
}
|
||||
}
|
||||
|
||||
func waitChestGone(t *testing.T, bot *e2eharness.ScenarioBot, guid uint64) {
|
||||
t.Helper()
|
||||
deadline := time.Now().Add(5 * time.Second)
|
||||
for bot.World.GetObject(guid) != nil {
|
||||
if time.Now().After(deadline) {
|
||||
e2eharness.Assertf(t, "consumed/deleted chest 0x%X remained visible", guid)
|
||||
}
|
||||
time.Sleep(25 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
// Count GUIDs, not surviving creatures: dying/despawning must not conceal a
|
||||
// repeated summon. Only new units of the fixture's entries are cleaned up.
|
||||
type summonObserver struct {
|
||||
bot *e2eharness.ScenarioBot
|
||||
entries map[uint32]bool
|
||||
seen map[uint64]bool
|
||||
owned map[uint64]bool
|
||||
}
|
||||
|
||||
func observeSummons(t *testing.T, bot *e2eharness.ScenarioBot, entries ...uint32) *summonObserver {
|
||||
t.Helper()
|
||||
o := &summonObserver{bot: bot, entries: map[uint32]bool{}, seen: map[uint64]bool{}, owned: map[uint64]bool{}}
|
||||
for _, entry := range entries {
|
||||
o.entries[entry] = true
|
||||
}
|
||||
o.scan()
|
||||
o.owned = map[uint64]bool{} // existing units are not ours
|
||||
t.Cleanup(func() { o.clean(t) })
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *summonObserver) scan() {
|
||||
for _, unit := range o.bot.World.GetNearbyUnits(100) {
|
||||
if o.entries[unit.Entry] && !o.seen[unit.GUID] {
|
||||
o.seen[unit.GUID], o.owned[unit.GUID] = true, true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *summonObserver) watch(duration time.Duration) {
|
||||
deadline := time.Now().Add(duration)
|
||||
for time.Now().Before(deadline) {
|
||||
o.scan()
|
||||
time.Sleep(25 * time.Millisecond)
|
||||
}
|
||||
o.scan()
|
||||
}
|
||||
|
||||
func (o *summonObserver) clean(t *testing.T) {
|
||||
t.Helper()
|
||||
o.scan()
|
||||
for guid := range o.owned {
|
||||
if o.bot.World.GetObject(guid) != nil {
|
||||
if err := o.bot.World.SetTarget(guid); err != nil {
|
||||
e2eharness.HarnessFailf(t, "select fixture summon: %v", err)
|
||||
}
|
||||
o.bot.FlushWorld(t)
|
||||
o.bot.GM(t, ".npc delete")
|
||||
o.bot.FlushWorld(t)
|
||||
}
|
||||
delete(o.owned, guid)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *summonObserver) unchanged(t *testing.T, baseline int) {
|
||||
t.Helper()
|
||||
// A bounded negative observation window also lets delayed object updates arrive.
|
||||
o.watch(2 * time.Second)
|
||||
if len(o.seen) != baseline {
|
||||
e2eharness.Assertf(t, "reopening summoned new creatures: distinct GUIDs %d -> %d", baseline, len(o.seen))
|
||||
}
|
||||
}
|
||||
|
||||
func TestChests_CatFigurineReopen(t *testing.T) {
|
||||
meta.Begin(t, meta.TestMeta{Tags: []string{"med", "loot", "serial"}, Runtime: "med", Category: "world/chests"})
|
||||
actor, _, observer := chestBots(t)
|
||||
o := observeSummons(t, observer, 3619)
|
||||
guid := spawnChest(t, observer, actor, 13873)
|
||||
before := len(o.seen)
|
||||
first := openChest(t, actor, guid, 3365) // lock type 5, Opening
|
||||
o.watch(2 * time.Second)
|
||||
baseline := len(o.seen)
|
||||
if baseline == before || len(first.items) != 1 || first.items[0].ItemID != 5329 {
|
||||
e2eharness.Assertf(t, "Cat Figurine must summon Ghost Saber(s) and offer item 5329: summons=%d loot=%+v", baseline-before, first)
|
||||
}
|
||||
// Existing SAI also casts 5968; this test deliberately does not assert one saber.
|
||||
closeChest(t, actor, guid)
|
||||
o.clean(t)
|
||||
for i := 0; i < 3; i++ {
|
||||
got := openChest(t, actor, guid, 3365)
|
||||
if !reflect.DeepEqual(got, first) {
|
||||
e2eharness.Assertf(t, "unclaimed figurine loot changed on reopen: %+v -> %+v", first, got)
|
||||
}
|
||||
o.unchanged(t, baseline)
|
||||
closeChest(t, actor, guid)
|
||||
}
|
||||
t.Log("PASS Cat Figurine summons on first opening; unclaimed loot survives without repeat summons")
|
||||
}
|
||||
|
||||
func fillBackpack(t *testing.T, bot *e2eharness.ScenarioBot) {
|
||||
t.Helper()
|
||||
bot.Save(t)
|
||||
var bags, used int
|
||||
if err := bot.CharDB.QueryRow("SELECT COUNT(*) FROM character_inventory WHERE guid = ? AND bag = 0 AND slot BETWEEN 19 AND 22", bot.GUID).Scan(&bags); err != nil {
|
||||
e2eharness.HarnessFailf(t, "bag query: %v", err)
|
||||
}
|
||||
if bags != 0 {
|
||||
e2eharness.Preconditionf(t, "full-bag fixture expects a fresh character without equipped bags")
|
||||
}
|
||||
if err := bot.CharDB.QueryRow("SELECT COUNT(*) FROM character_inventory WHERE guid = ? AND bag = 0 AND slot BETWEEN 23 AND 38", bot.GUID).Scan(&used); err != nil {
|
||||
e2eharness.HarnessFailf(t, "backpack query: %v", err)
|
||||
}
|
||||
if used < 16 {
|
||||
if err := bot.World.SetTarget(0); err != nil {
|
||||
e2eharness.HarnessFailf(t, "clear item-command target: %v", err)
|
||||
}
|
||||
bot.FlushWorld(t)
|
||||
bot.GM(t, fmt.Sprintf(".additem 38 %d", 16-used)) // non-stackable Recruit's Shirt
|
||||
bot.FlushWorld(t)
|
||||
}
|
||||
}
|
||||
|
||||
func assertBagFull(t *testing.T, bot *e2eharness.ScenarioBot, slot uint8) {
|
||||
t.Helper()
|
||||
ch := make(chan byte, 1)
|
||||
cancel := bot.World.AddPacketHook(func(op uint16, data []byte) {
|
||||
if op == 0x0112 && len(data) > 0 { // SMSG_INVENTORY_CHANGE_FAILURE
|
||||
select {
|
||||
case ch <- data[0]:
|
||||
default:
|
||||
}
|
||||
}
|
||||
})
|
||||
defer cancel()
|
||||
bot.LootTakeItem(t, slot)
|
||||
select {
|
||||
case reason := <-ch:
|
||||
if reason != 50 { // EQUIP_ERR_INVENTORY_FULL
|
||||
e2eharness.Preconditionf(t, "expected inventory-full error, got %d", reason)
|
||||
}
|
||||
case <-time.After(5 * time.Second):
|
||||
e2eharness.Assertf(t, "taking grave loot with full bags did not return inventory-full error")
|
||||
}
|
||||
}
|
||||
|
||||
// Issues: https://github.com/azerothcore/azerothcore-wotlk/issues/24692
|
||||
//
|
||||
// https://github.com/azerothcore/azerothcore-wotlk/issues/12433
|
||||
func TestAC_24692_ShallowGraveLifecycle(t *testing.T) {
|
||||
meta.Begin(t, meta.TestMeta{Tags: []string{"med", "loot", "issue", "serial"}, Runtime: "med", Category: "world/chests", Issue: 24692})
|
||||
for _, entry := range []uint32{128308, 128403} {
|
||||
t.Run(fmt.Sprint(entry), func(t *testing.T) {
|
||||
actor, mate, observer := chestBots(t)
|
||||
actor.SetLootMethod(t, client.LootMethodFreeForAll, 0, e2eharness.LootThresholdUncommon)
|
||||
actor.WaitLootMethod(t, client.LootMethodFreeForAll, 5*time.Second)
|
||||
fillBackpack(t, actor)
|
||||
o := observeSummons(t, observer, 7286, 7276)
|
||||
covered := false
|
||||
// Sample stock item loot and, for the trapped variant, a positive summon
|
||||
// roll. Money is now always present; an initially empty grave is not a fixture.
|
||||
for attempt := 0; attempt < 48 && !covered; attempt++ {
|
||||
sid := observer.SpawnGameObject(t, entry)
|
||||
if sid == 0 {
|
||||
e2eharness.Preconditionf(t, "cannot resolve grave spawn for cleanup")
|
||||
}
|
||||
guid := actor.WaitGameObject(t, entry, 10*time.Second)
|
||||
before := len(o.seen)
|
||||
first := openChest(t, actor, guid, 6247) // lock type 10, Opening (no text)
|
||||
o.watch(2 * time.Second)
|
||||
baseline := len(o.seen)
|
||||
if entry == 128308 && baseline != before {
|
||||
e2eharness.ConfirmedBugf(t, 24692, "inert grave summoned %d creatures", baseline-before)
|
||||
}
|
||||
if len(first.items) == 0 || (entry == 128403 && baseline == before) {
|
||||
closeChest(t, actor, guid)
|
||||
o.clean(t)
|
||||
observer.DespawnGameObjectSpawn(t, sid)
|
||||
waitChestGone(t, actor, guid)
|
||||
continue
|
||||
}
|
||||
assertBagFull(t, actor, first.items[0].Index)
|
||||
closeChest(t, actor, guid)
|
||||
o.clean(t)
|
||||
for reopen := 0; reopen < 6; reopen++ {
|
||||
looter := actor
|
||||
if reopen%2 == 1 {
|
||||
looter = mate
|
||||
}
|
||||
got := openChest(t, looter, guid, 6247)
|
||||
if !reflect.DeepEqual(got, first) {
|
||||
e2eharness.Assertf(t, "grave %d changed unclaimed loot: %+v -> %+v", entry, first, got)
|
||||
}
|
||||
closeChest(t, looter, guid)
|
||||
o.unchanged(t, baseline)
|
||||
}
|
||||
// A different player can still collect everything left by full bags.
|
||||
loot := openChest(t, mate, guid, 6247)
|
||||
for _, item := range loot.items {
|
||||
count := mate.InventoryCount(t, item.ItemID)
|
||||
mate.LootTakeItem(t, item.Index)
|
||||
mate.FlushWorld(t)
|
||||
if got := mate.InventoryCount(t, item.ItemID); got != count+int(item.Quantity) {
|
||||
e2eharness.Assertf(t, "grave %d item %d was not credited: %d -> %d", entry, item.ItemID, count, got)
|
||||
}
|
||||
}
|
||||
if loot.gold != 0 {
|
||||
if err := mate.World.SendPacketRaw(0x015E, nil); err != nil { // CMSG_LOOT_MONEY
|
||||
e2eharness.HarnessFailf(t, "loot grave money: %v", err)
|
||||
}
|
||||
mate.FlushWorld(t)
|
||||
}
|
||||
closeChest(t, mate, guid)
|
||||
waitChestGone(t, mate, guid)
|
||||
// A stale opening request must not produce another wave after consumption.
|
||||
castOpening(t, mate, guid, 6247)
|
||||
mate.FlushWorld(t)
|
||||
o.unchanged(t, baseline)
|
||||
covered = true
|
||||
observer.DespawnGameObjectSpawn(t, sid)
|
||||
waitChestGone(t, actor, guid)
|
||||
t.Logf("PASS grave %d initial summons=%d; six reopens and a consumed-GUID request added none", entry, baseline-before)
|
||||
}
|
||||
if !covered {
|
||||
e2eharness.Preconditionf(t, "48 fresh graves did not produce an item-loot fixture with the required active/inert behavior")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestChests_IceChestGroupLoot(t *testing.T) {
|
||||
meta.Begin(t, meta.TestMeta{Tags: []string{"med", "loot", "multi_bot", "serial"}, Runtime: "med", Category: "world/chests"})
|
||||
actor, mate, observer := chestBots(t)
|
||||
actor.SetLootMethod(t, client.LootMethodGroupLoot, 0, e2eharness.LootThresholdUncommon)
|
||||
actor.WaitLootMethod(t, client.LootMethodGroupLoot, 5*time.Second)
|
||||
o := observeSummons(t, observer, 26391)
|
||||
guid := spawnChest(t, observer, actor, 187892)
|
||||
waitActor, cancelActor := actor.ArmLootStartRoll()
|
||||
defer cancelActor()
|
||||
waitMate, cancelMate := mate.ArmLootStartRoll()
|
||||
defer cancelMate()
|
||||
before := len(o.seen)
|
||||
loot := openChest(t, actor, guid, 6247)
|
||||
var reward uint32
|
||||
for _, item := range loot.items {
|
||||
if item.ItemID >= 54801 && item.ItemID <= 54805 {
|
||||
reward = item.ItemID
|
||||
}
|
||||
}
|
||||
if reward == 0 {
|
||||
e2eharness.Assertf(t, "Ice Chest did not offer one of its guaranteed cloaks: %+v", loot.items)
|
||||
}
|
||||
roll, ok := waitActor(reward, 10*time.Second)
|
||||
if !ok {
|
||||
e2eharness.Assertf(t, "Ice Chest did not start a group roll for its epic reward")
|
||||
}
|
||||
otherRoll, ok := waitMate(roll.ItemID, 10*time.Second)
|
||||
if !ok || otherRoll.ItemGUID != roll.ItemGUID || otherRoll.ItemSlot != roll.ItemSlot {
|
||||
e2eharness.Assertf(t, "party members did not receive the same Ice Chest roll")
|
||||
}
|
||||
o.watch(time.Second)
|
||||
baseline := len(o.seen)
|
||||
if baseline-before != 1 {
|
||||
e2eharness.Assertf(t, "Ice Chest should summon its bunny on initial opening: got %d", baseline-before)
|
||||
}
|
||||
closeChest(t, actor, guid)
|
||||
openChest(t, mate, guid, 6247)
|
||||
closeChest(t, mate, guid)
|
||||
openChest(t, actor, guid, 6247)
|
||||
closeChest(t, actor, guid)
|
||||
o.unchanged(t, baseline)
|
||||
// The trap has a long stock cooldown; repeat-open observations here cannot
|
||||
// prove the once-per-generation guard by themselves. The reward is the oracle.
|
||||
count := actor.InventoryCount(t, roll.ItemID)
|
||||
won, _, cancel := actor.ArmLootRollOutcome(roll.ItemID)
|
||||
defer cancel()
|
||||
mate.RollGreed(t, roll)
|
||||
actor.RollNeed(t, roll)
|
||||
select {
|
||||
case result := <-won:
|
||||
if result.WinnerGUID != actor.GUID {
|
||||
e2eharness.Assertf(t, "Need did not beat Greed for Ice Chest item %d", roll.ItemID)
|
||||
}
|
||||
case <-time.After(10 * time.Second):
|
||||
e2eharness.Assertf(t, "Ice Chest roll did not resolve after both votes")
|
||||
}
|
||||
deadline := time.Now().Add(5 * time.Second)
|
||||
for actor.InventoryCount(t, roll.ItemID) != count+1 {
|
||||
if time.Now().After(deadline) {
|
||||
e2eharness.Assertf(t, "Ice Chest roll winner did not receive exactly one item %d", roll.ItemID)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
t.Logf("PASS Ice Chest first-open bunny, shared roll, second-player reopening and reward %d", roll.ItemID)
|
||||
}
|
||||
@@ -8100,6 +8100,11 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type)
|
||||
}
|
||||
|
||||
go->SetLootState(GO_ACTIVATED, this);
|
||||
|
||||
// Trigger chest traps once per loot generation, including when the generated loot is empty.
|
||||
if (go->GetGoType() == GAMEOBJECT_TYPE_CHEST)
|
||||
if (uint32 trapEntry = go->GetGOInfo()->chest.linkedTrapId)
|
||||
go->TriggeringLinkedGameObject(trapEntry, this);
|
||||
}
|
||||
|
||||
if (go->getLootState() == GO_ACTIVATED)
|
||||
|
||||
@@ -2184,11 +2184,6 @@ void Spell::SendLoot(ObjectGuid guid, LootType loottype)
|
||||
gameObjTarget->TriggeringLinkedGameObject(trapEntry, unitCaster);
|
||||
return;
|
||||
|
||||
case GAMEOBJECT_TYPE_CHEST:
|
||||
// triggering linked GO
|
||||
if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
|
||||
gameObjTarget->TriggeringLinkedGameObject(trapEntry, unitCaster);
|
||||
|
||||
// Don't return, let loots been taken
|
||||
default:
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user