Core/Transports
* Rewritten path generation, now uses splines - timers are a lot more accurate now * Implemented stopping transports * Implemented spawning transports in instances * Implemented spawning gameobjects as transport passengers * Transport passengers are now stored in creature/gameobject table using gameobject_template.data6 from transport's template as map id
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
SET @id = 400;
|
||||
|
||||
-- Add new permissions
|
||||
DELETE FROM `rbac_permissions` WHERE `id`=@id;
|
||||
INSERT INTO `rbac_permissions` (`id`, `name`) VALUES
|
||||
(@id, 'debug transport');
|
||||
|
||||
-- Add permissions to "corresponding Commands Role"
|
||||
DELETE FROM `rbac_role_permissions` WHERE `permissionId`=@id;
|
||||
INSERT INTO `rbac_role_permissions` (`roleId`, `permissionId`) VALUES
|
||||
(3, @id);
|
||||
@@ -0,0 +1,4 @@
|
||||
DELETE FROM `command` WHERE `name` = 'debug transport';
|
||||
|
||||
INSERT INTO `command` (`name`, `permission`, `help`) VALUES
|
||||
('debug transport', 400, 'Syntax: .debug transport [start/stop]\r\n\r\n Allows to stop a transport at its nearest wait point and start movement of a stopped one. Not all transports can be started or stopped.'),
|
||||
@@ -0,0 +1,276 @@
|
||||
DROP TABLE IF EXISTS `creature_transport`;
|
||||
|
||||
SET @GUID := 142717;
|
||||
|
||||
DELETE FROM `creature` WHERE `guid` BETWEEN @GUID+0 AND @GUID+269;
|
||||
INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `MovementType`) VALUES
|
||||
(@GUID+0, 24456, 582, 1, 1, 29.5627, 0.150031, 16.6147, 3.18002, 120, 0, 0),
|
||||
(@GUID+1, 24993, 582, 1, 1, 13.1874, 7.71381, 6.07001, 3.09834, 120, 0, 0),
|
||||
(@GUID+2, 24995, 582, 1, 1, 13.3456, -7.63689, 6.09325, 3.06064, 120, 0, 0),
|
||||
(@GUID+3, 24996, 582, 1, 1, -0.258897, -7.62734, 4.80823, 5.66423, 120, 0, 0),
|
||||
(@GUID+4, 24997, 582, 1, 1, -0.416482, 4.39825, 4.79739, 5.10346, 120, 0, 0),
|
||||
(@GUID+5, 25007, 582, 1, 1, 21.2462, 1.87803, 11.7334, 3.19572, 120, 0, 0),
|
||||
(@GUID+6, 25050, 586, 1, 1, 29.8662, -0.374622, 16.6206, 3.09382, 120, 0, 0),
|
||||
(@GUID+7, 25051, 586, 1, 1, 13.4899, -7.71638, 6.11067, 3.11424, 120, 0, 0),
|
||||
(@GUID+8, 25052, 586, 1, 1, 13.5093, 7.8287, 6.11039, 3.12838, 120, 0, 0),
|
||||
(@GUID+9, 25054, 586, 1, 1, -21.8863, -2.61623, 4.33103, 6.14509, 120, 0, 0),
|
||||
(@GUID+10, 25055, 586, 1, 1, -21.4646, 2.87105, 4.31055, 6.26055, 120, 0, 0),
|
||||
(@GUID+11, 25056, 586, 1, 1, 20.3045, 1.2971, 11.7088, 3.06319, 120, 0, 0),
|
||||
(@GUID+12, 3681, 587, 1, 1, -38.6477, -0.071194, 6.08577, 0.0698132, 120, 0, 0),
|
||||
(@GUID+13, 3681, 587, 1, 1, 29.5623, 0.119925, 24.4539, 0.0872665, 120, 0, 0),
|
||||
(@GUID+14, 25019, 587, 1, 1, 12.805, -7.60196, 6.10507, 2.9147, 120, 0, 0),
|
||||
(@GUID+15, 25020, 587, 1, 1, 12.9539, 7.33394, 6.13112, 3.28122, 120, 0, 0),
|
||||
(@GUID+16, 25021, 587, 1, 1, -21.4174, -2.8336, 4.39169, 6.24828, 120, 0, 0),
|
||||
(@GUID+17, 25022, 587, 1, 1, 20.8633, -1.28591, 11.809, 2.94961, 120, 0, 0),
|
||||
(@GUID+18, 25023, 587, 1, 1, -36.7691, 0.169367, 5.97592, 3.1765, 120, 0, 0),
|
||||
(@GUID+19, 25024, 587, 1, 1, -21.6595, 3.22012, 4.40273, 0.139626, 120, 0, 0),
|
||||
(@GUID+20, 25025, 587, 1, 1, 31.131, -0.454317, 16.7328, 2.96706, 120, 0, 0),
|
||||
(@GUID+21, 25009, 588, 1, 1, 25.2165, 6.9111, 16.1459, 3.94958, 120, 0, 0),
|
||||
(@GUID+22, 25010, 588, 1, 1, 13.2057, -2.817, 6.09989, 3.88733, 120, 0, 0),
|
||||
(@GUID+23, 25011, 588, 1, 1, 19.2178, -8.20848, 12.1102, 4.81518, 120, 0, 0),
|
||||
(@GUID+24, 25012, 588, 1, 1, 18.1475, -7.41572, 6.09809, 1.88535, 120, 0, 0),
|
||||
(@GUID+25, 25013, 588, 1, 1, 0.194107, 9.84585, 6.09941, 3.08731, 120, 0, 0),
|
||||
(@GUID+26, 25014, 588, 1, 1, -0.532552, -8.68575, 6.09815, 3.19019, 120, 0, 0),
|
||||
(@GUID+27, 25015, 588, 1, 1, 34.0669, 0.119702, 18.287, 3.17832, 120, 0, 0),
|
||||
(@GUID+28, 25016, 588, 1, 1, -11.1276, 6.60326, 6.09852, 3.05167, 120, 0, 0),
|
||||
(@GUID+29, 25017, 588, 1, 1, 6.22581, 9.13103, 11.4836, 1.53614, 120, 0, 0),
|
||||
(@GUID+30, 25018, 588, 1, 1, 10.2474, 2.78122, 11.803, 3.46823, 120, 0, 0),
|
||||
(@GUID+31, 24924, 589, 1, 1, -1.2076, -9.94886, -23.6749, 0.15708, 120, 0, 0),
|
||||
(@GUID+32, 24926, 589, 1, 1, -10.3057, -12.1052, -16.9691, 5.92724, 120, 0, 0),
|
||||
(@GUID+33, 24927, 589, 1, 1, -1.87417, -7.84711, -23.6872, 3.38594, 120, 0, 0),
|
||||
(@GUID+34, 24929, 589, 1, 1, 9.08301, -4.96411, -23.5921, 1.59406, 120, 0, 0),
|
||||
(@GUID+35, 24930, 589, 1, 1, -17.0083, -7.87488, -15.1878, 3.14159, 120, 0, 0),
|
||||
(@GUID+36, 24931, 589, 1, 1, 7.88492, -11.1513, -17.7623, 4.90483, 120, 0, 0),
|
||||
(@GUID+37, 24934, 589, 1, 1, 9.20919, -3.50392, -23.5121, 3.12414, 120, 0, 0),
|
||||
(@GUID+38, 24935, 589, 1, 1, 9.55492, -12.0229, -23.5059, 3.12414, 120, 0, 0),
|
||||
(@GUID+39, 25075, 589, 1, 1, -2.70556, -7.84588, -23.6967, 0.0349066, 120, 0, 0),
|
||||
(@GUID+40, 25080, 589, 1, 1, -4.91002, -4.74236, -17.6153, 1.6057, 120, 0, 0),
|
||||
(@GUID+41, 25081, 589, 1, 1, -4.93939, -10.8049, -17.6109, 4.71239, 120, 0, 0),
|
||||
(@GUID+42, 24934, 590, 1, 1, 9.63549, -3.67192, -23.588, 6.25904, 120, 0, 0),
|
||||
(@GUID+43, 24935, 590, 1, 1, 9.79838, -11.8681, -23.5848, 6.25118, 120, 0, 0),
|
||||
(@GUID+44, 25075, 590, 1, 1, -3.59133, -7.84061, -23.7802, 6.1969, 120, 0, 0),
|
||||
(@GUID+45, 25100, 590, 1, 1, -0.411733, -5.7239, -23.7457, 3.70414, 120, 0, 0),
|
||||
(@GUID+46, 25101, 590, 1, 1, 7.56919, -4.02088, -17.7543, 4.77071, 120, 0, 0),
|
||||
(@GUID+47, 25102, 590, 1, 1, -11.0882, -3.47446, -16.7988, 2.00924, 120, 0, 0),
|
||||
(@GUID+48, 25103, 590, 1, 1, 7.59398, -11.5166, -17.7745, 1.62204, 120, 0, 0),
|
||||
(@GUID+49, 25104, 590, 1, 1, -0.898213, -7.76559, -23.7548, 3.11116, 120, 0, 0),
|
||||
(@GUID+50, 25105, 590, 1, 1, -9.54405, -7.94072, -17.2053, 3.17242, 120, 0, 0),
|
||||
(@GUID+51, 25106, 590, 1, 1, -4.93938, -10.9634, -17.6988, 4.76285, 120, 0, 0),
|
||||
(@GUID+52, 25107, 590, 1, 1, -4.98215, -4.67863, -17.696, 1.59455, 120, 0, 0),
|
||||
(@GUID+53, 15214, 591, 1, 1, 7.0053, -7.64791, -16.1126, 2.89725, 120, 0, 0),
|
||||
(@GUID+54, 24934, 591, 1, 1, -4.5165, -13.1125, -22.5947, 1.53589, 120, 0, 0),
|
||||
(@GUID+55, 24935, 591, 1, 1, -6.37827, -13.1838, -22.5939, 4.71239, 120, 0, 0),
|
||||
(@GUID+56, 25070, 591, 1, 1, -9.40787, -8.02398, -17.1578, 3.1765, 120, 0, 0),
|
||||
(@GUID+57, 25071, 591, 1, 1, 7.24887, -5.48033, -17.6859, 4.81711, 120, 0, 0),
|
||||
(@GUID+58, 25072, 591, 1, 1, 8.00807, -10.7134, -17.6737, 1.16937, 120, 0, 0),
|
||||
(@GUID+59, 25074, 591, 1, 1, 5.02375, -7.69781, -17.7888, 5.98648, 120, 0, 0),
|
||||
(@GUID+60, 25075, 591, 1, 1, -4.16189, -7.68752, -23.6975, 0, 120, 0, 0),
|
||||
(@GUID+61, 25075, 591, 1, 1, 4.36215, -2.25417, -23.59, 4.71239, 120, 0, 0),
|
||||
(@GUID+62, 25075, 591, 1, 1, -3.31418, -6.12881, -23.6984, 4.67748, 120, 0, 0),
|
||||
(@GUID+63, 25075, 591, 1, 1, 4.48208, -13.4008, -23.59, 1.62316, 120, 0, 0),
|
||||
(@GUID+64, 25075, 591, 1, 1, -3.30777, -9.47416, -23.6959, 1.55334, 120, 0, 0),
|
||||
(@GUID+65, 25075, 591, 1, 1, 10.7034, -3.50542, -23.49, 3.24631, 120, 0, 0),
|
||||
(@GUID+66, 25075, 591, 1, 1, -8.87581, -11.4028, -22.5883, 6.24828, 120, 0, 0),
|
||||
(@GUID+67, 25075, 591, 1, 1, 10.8261, -12.1854, -23.4895, 3.1765, 120, 0, 0),
|
||||
(@GUID+68, 25075, 591, 1, 1, 11.7436, -10.4452, -24.2189, 6.16101, 120, 0, 0),
|
||||
(@GUID+69, 25076, 591, 1, 1, -2.72723, -7.77286, -23.6968, 1.55334, 120, 0, 0),
|
||||
(@GUID+70, 25077, 591, 1, 1, -19.6886, -8.17058, -14.3765, 3.1765, 120, 0, 0),
|
||||
(@GUID+71, 25079, 591, 1, 1, -5.1094, -11.1466, -17.606, 4.4855, 120, 0, 0),
|
||||
(@GUID+72, 25083, 591, 1, 1, -5.2125, -4.92702, -17.5966, 1.43117, 120, 0, 0),
|
||||
(@GUID+73, 25171, 591, 1, 1, -8.70329, -11.4079, -22.5887, 0.0349066, 120, 0, 0),
|
||||
(@GUID+74, 25078, 593, 1, 1, 34.095, 3.54049, 17.8892, 5.50987, 120, 0, 0),
|
||||
(@GUID+75, 25082, 593, 1, 1, 15.6121, 1.09944, 6.09764, 2.52482, 120, 0, 0),
|
||||
(@GUID+76, 25089, 593, 1, 1, 17.8437, -7.84575, 6.09877, 1.64493, 120, 0, 0),
|
||||
(@GUID+77, 25093, 593, 1, 1, 15.8067, -5.80051, 11.9732, 1.86484, 120, 0, 0),
|
||||
(@GUID+78, 25094, 593, 1, 1, 34.0585, -0.04162, 18.2865, 3.17017, 120, 0, 0),
|
||||
(@GUID+79, 25095, 593, 1, 1, 9.39981, 9.17899, 11.5941, 1.52083, 120, 0, 0),
|
||||
(@GUID+80, 25097, 593, 1, 1, -11.4014, 6.67999, 6.09785, 2.93715, 120, 0, 0),
|
||||
(@GUID+81, 25111, 593, 1, 1, 6.20811, 0.005208, 14.0554, 2.54813, 120, 0, 0),
|
||||
(@GUID+82, 24910, 594, 1, 1, 34.6962, -0.27625, 20.9157, 3.44936, 120, 0, 0),
|
||||
(@GUID+83, 24911, 594, 1, 1, -3.08712, 11.1947, 8.6042, 1.59543, 120, 0, 0),
|
||||
(@GUID+84, 24911, 594, 1, 1, -3.00336, -1.39497, 8.72655, 0.455023, 120, 0, 0),
|
||||
(@GUID+85, 24911, 594, 1, 1, 29.079, 6.02911, 19.504, 1.29931, 120, 0, 0),
|
||||
(@GUID+86, 24911, 594, 1, 1, -11.92, 6.82298, 8.72743, 2.64628, 120, 0, 0),
|
||||
(@GUID+87, 24911, 594, 1, 1, 19.1465, -9.70741, 14.7601, 4.79434, 120, 0, 0),
|
||||
(@GUID+88, 24911, 594, 1, 1, 5.55254, 10.6903, 14.0795, 1.41713, 120, 0, 0),
|
||||
(@GUID+89, 24911, 594, 1, 1, 5.53691, -10.9158, 14.0808, 4.59956, 120, 0, 0),
|
||||
(@GUID+90, 24911, 594, 1, 1, 19.1591, 9.74589, 14.7625, 1.55457, 120, 0, 0),
|
||||
(@GUID+91, 24911, 594, 1, 1, -10.8992, 6.36276, 20.589, 1.29146, 120, 0, 0),
|
||||
(@GUID+92, 24911, 594, 1, 1, -1.47544, 9.97225, 8.72811, 1.47291, 120, 0, 0),
|
||||
(@GUID+93, 24911, 594, 1, 1, -15.0531, 6.78103, 21.0344, 1.54279, 120, 0, 0),
|
||||
(@GUID+94, 24911, 594, 1, 1, 0.568386, 10.818, 8.68709, 1.24593, 120, 0, 0),
|
||||
(@GUID+95, 24911, 594, 1, 1, -16.544, 7.01147, 21.3668, 1.52708, 120, 0, 0),
|
||||
(@GUID+96, 24992, 594, 1, 1, -13.669, 5.23144, 19.2894, 1.4721, 120, 0, 0),
|
||||
(@GUID+97, 25026, 594, 1, 1, 5.50506, 5.17797, 1.39596, 1.53711, 120, 0, 0),
|
||||
(@GUID+98, 25026, 594, 1, 1, -3.34169, -4.92735, 1.39595, 4.70933, 120, 0, 0),
|
||||
(@GUID+99, 25026, 594, 1, 1, -2.64281, 5.46732, 1.39595, 0.520802, 120, 0, 0),
|
||||
(@GUID+100, 25026, 594, 1, 1, 6.52141, 0.490373, 1.39693, 6.00288, 120, 0, 0),
|
||||
(@GUID+101, 25026, 594, 1, 1, 23.0708, -2.7187, 1.39595, 5.37378, 120, 0, 0),
|
||||
(@GUID+102, 25026, 594, 1, 1, 15.3122, 6.40496, 1.39596, 4.24673, 120, 0, 0),
|
||||
(@GUID+103, 25026, 594, 1, 1, 24.9381, 4.10155, 1.44058, 1.07922, 120, 0, 0),
|
||||
(@GUID+104, 25026, 594, 1, 1, 14.4097, -6.40611, 1.39596, 1.86383, 120, 0, 0),
|
||||
(@GUID+105, 25026, 594, 1, 1, 5.51407, -5.26758, 1.39596, 4.38889, 120, 0, 0),
|
||||
(@GUID+106, 25075, 610, 1, 1, 4.36215, -2.25417, -23.59, 4.71239, 120, 0, 0),
|
||||
(@GUID+107, 31704, 610, 1, 1, 5.21605, -2.36685, -17.8223, 1.04622, 120, 0, 0),
|
||||
(@GUID+108, 31705, 610, 1, 1, 5.07824, -13.1188, -17.8135, 5.24182, 120, 0, 0),
|
||||
(@GUID+109, 31706, 610, 1, 1, -16.8964, -10.8497, -15.9745, 4.64346, 120, 0, 0),
|
||||
(@GUID+110, 31708, 610, 1, 1, -2.74581, -1.47146, -17.7765, 4.67712, 120, 0, 0),
|
||||
(@GUID+111, 31715, 610, 1, 1, -3.54276, -13.8752, -17.684, 1.53946, 120, 0, 0),
|
||||
(@GUID+112, 31716, 610, 1, 1, 11.5731, -7.65137, -16.6839, 3.20372, 120, 0, 0),
|
||||
(@GUID+113, 31759, 612, 1, 1, -9.17065, -9.22241, 9.44523, 4.33964, 120, 0, 0),
|
||||
(@GUID+114, 31760, 612, 1, 1, -24.342, -1.4956, 11.7907, 4.53119, 120, 0, 0),
|
||||
(@GUID+115, 31761, 612, 1, 1, 17.25, 3.98267, 9.8274, 1.12707, 120, 0, 0),
|
||||
(@GUID+116, 31762, 612, 1, 1, 34.0835, -0.002845, 19.7971, 3.12414, 120, 0, 0),
|
||||
(@GUID+117, 31763, 612, 1, 1, 30.1151, -5.08848, 19.3282, 3.08923, 120, 0, 0),
|
||||
(@GUID+118, 31764, 612, 1, 1, 26.0707, 2.05775, 19.328, 3.00197, 120, 0, 0),
|
||||
(@GUID+119, 25075, 613, 1, 1, 9.44542, -7.84947, -16.6006, 0.0523599, 120, 0, 0),
|
||||
(@GUID+120, 31720, 613, 1, 1, -16.5685, -5.08333, -15.9421, 1.98968, 120, 0, 0),
|
||||
(@GUID+121, 31723, 613, 1, 1, -10.7552, -12.8129, -16.7745, 4.53786, 120, 0, 0),
|
||||
(@GUID+122, 31724, 613, 1, 1, 5.77627, -2.00469, -17.7218, 1.64061, 120, 0, 0),
|
||||
(@GUID+123, 31725, 613, 1, 1, 10.6984, -7.82192, -16.6006, 3.28122, 120, 0, 0),
|
||||
(@GUID+124, 31726, 613, 1, 1, -3.45307, -13.7896, -17.6111, 1.16964, 120, 0, 0),
|
||||
(@GUID+125, 31727, 613, 1, 1, -3.38308, -1.91393, -17.6198, 5.47991, 120, 0, 0),
|
||||
(@GUID+126, 31788, 614, 1, 1, 27.5951, -2.34424, 19.3281, 3.22886, 120, 0, 0),
|
||||
(@GUID+127, 31789, 614, 1, 1, 28.0998, 5.9939, 19.328, 3.64774, 120, 0, 0),
|
||||
(@GUID+128, 31790, 614, 1, 1, 34.2236, 0.067648, 19.7627, 3.07178, 120, 0, 0),
|
||||
(@GUID+129, 31791, 614, 1, 1, 0.919363, 8.75723, 9.43661, 1.25664, 120, 0, 0),
|
||||
(@GUID+130, 31792, 614, 1, 1, -4.76611, 0.0998535, 9.36669, 4.83456, 120, 0, 0),
|
||||
(@GUID+131, 31793, 614, 1, 1, 17.146, -3.92139, 9.81305, 5.49708, 120, 0, 0),
|
||||
(@GUID+132, 29795, 622, 1, 1, 45.6197, 7.29317, 30.0955, 4.67642, 120, 0, 0),
|
||||
(@GUID+133, 30752, 622, 1, 1, 15.4321, 28.6642, 9.92277, 1.54012, 120, 0, 0),
|
||||
(@GUID+134, 30752, 622, 1, 1, 2.01988, 28.7211, 9.33565, 1.58332, 120, 0, 0),
|
||||
(@GUID+135, 30752, 622, 1, 1, -11.241, 28.5576, 9.91826, 1.5519, 120, 0, 0),
|
||||
(@GUID+136, 30752, 622, 1, 1, 8.25547, -21.6199, 34.8875, 1.73515, 120, 0, 0),
|
||||
(@GUID+137, 30752, 622, 1, 1, 7.30473, 24.2619, 34.9491, 4.43536, 120, 0, 0),
|
||||
(@GUID+138, 30753, 622, 1, 1, -26.8391, -10.402, 35.5991, 1.29366, 120, 0, 0),
|
||||
(@GUID+139, 30753, 622, 1, 1, 2.15579, 17.0338, 9.16353, 1.54405, 120, 0, 0),
|
||||
(@GUID+140, 30753, 622, 1, 1, -7.63407, 0.007234, 86.0904, 6.2728, 120, 0, 0),
|
||||
(@GUID+141, 30753, 622, 1, 1, 46.382, 7.89944, 10.4129, 3.96271, 120, 0, 0),
|
||||
(@GUID+142, 30753, 622, 1, 1, 45.981, -6.55312, 10.3636, 2.23091, 120, 0, 0),
|
||||
(@GUID+143, 30753, 622, 1, 1, 15.254, -0.009458, 86.0904, 3.14299, 120, 0, 0),
|
||||
(@GUID+144, 30753, 622, 1, 1, -34.939, -11.6484, 11.4697, 5.50858, 120, 0, 0),
|
||||
(@GUID+145, 30753, 622, 1, 1, -34.785, 11.9312, 11.4869, 0.836243, 120, 0, 0),
|
||||
(@GUID+146, 30753, 622, 1, 1, -26.9812, 10.5208, 35.5936, 4.74156, 120, 0, 0),
|
||||
(@GUID+147, 30753, 622, 1, 1, 1.98831, -18.0873, 9.16057, 4.66993, 120, 0, 0),
|
||||
(@GUID+148, 30754, 622, 1, 1, -19.0109, 27.0177, 89.9667, 6.22411, 120, 0, 0),
|
||||
(@GUID+149, 30754, 622, 1, 1, -54.639, -15.3254, 34.3972, 3.83128, 120, 0, 0),
|
||||
(@GUID+150, 30754, 622, 1, 1, -54.7182, 15.5861, 34.3897, 2.50086, 120, 0, 0),
|
||||
(@GUID+151, 30754, 622, 1, 1, -18.9215, -26.8371, 89.9664, 0.087792, 120, 0, 0),
|
||||
(@GUID+152, 30755, 622, 1, 1, -3.46042, 28.0231, 34.2784, 4.66548, 120, 0, 0),
|
||||
(@GUID+153, 30755, 622, 1, 1, 7.21494, -6.31021, 34.4191, 3.11118, 120, 0, 0),
|
||||
(@GUID+154, 30755, 622, 1, 1, 24.5852, 6.86575, 7.06382, 3.11055, 120, 0, 0),
|
||||
(@GUID+155, 30755, 622, 1, 1, 8.85995, 18.8224, 8.7027, 4.69035, 120, 0, 0),
|
||||
(@GUID+156, 30755, 622, 1, 1, 24.3302, -6.97827, 7.08356, 3.34184, 120, 0, 0),
|
||||
(@GUID+157, 30755, 622, 1, 1, -4.43012, 18.742, 8.62646, 4.66286, 120, 0, 0),
|
||||
(@GUID+158, 30755, 622, 1, 1, -5.59682, -28.2501, 34.1226, 1.55058, 120, 0, 0),
|
||||
(@GUID+159, 30755, 622, 1, 1, -4.46811, -18.5567, 8.62604, 1.53698, 120, 0, 0),
|
||||
(@GUID+160, 30755, 622, 1, 1, 29.8693, -29.5825, 89.7663, 3.05267, 120, 0, 0),
|
||||
(@GUID+161, 30755, 622, 1, 1, 8.83021, -4.6978, 84.7137, 2.34582, 120, 0, 0),
|
||||
(@GUID+162, 30755, 622, 1, 1, 37.6428, -9.00797, 30.0954, 0.004917, 120, 0, 0),
|
||||
(@GUID+163, 30755, 622, 1, 1, -26.188, -6.1712, 9.33333, 3.14217, 120, 0, 0),
|
||||
(@GUID+164, 30755, 622, 1, 1, 9.06884, -18.7113, 8.70787, 1.56054, 120, 0, 0),
|
||||
(@GUID+165, 30755, 622, 1, 1, 8.67689, 4.88796, 84.7137, 3.90012, 120, 0, 0),
|
||||
(@GUID+166, 30755, 622, 1, 1, 7.49121, 6.05275, 34.4239, 3.16615, 120, 0, 0),
|
||||
(@GUID+167, 30755, 622, 1, 1, 37.6401, 8.9586, 30.0954, 0.012771, 120, 0, 0),
|
||||
(@GUID+168, 30755, 622, 1, 1, -26.1511, 6.90449, 9.405, 3.12647, 120, 0, 0),
|
||||
(@GUID+169, 30755, 622, 1, 1, 29.4588, 29.8761, 89.7684, 3.15321, 120, 0, 0),
|
||||
(@GUID+170, 30824, 622, 1, 1, 55.5028, 0.080449, 30.5268, 3.15669, 120, 0, 0),
|
||||
(@GUID+171, 30825, 622, 1, 1, 38.4745, 0.038424, 10.1868, 3.15788, 120, 0, 0),
|
||||
(@GUID+172, 30826, 622, 1, 1, 55.0542, -3.74557, 30.0955, 2.77577, 120, 0, 0),
|
||||
(@GUID+173, 30827, 622, 1, 1, 45.884, -8.99976, 30.0955, 1.52942, 120, 0, 0),
|
||||
(@GUID+174, 30866, 622, 1, 1, -36.528, 23.9373, 33.9184, 1.89617, 120, 0, 0),
|
||||
(@GUID+175, 30866, 622, 1, 1, 15.9225, 26.2539, 35.4586, 1.60085, 120, 0, 0),
|
||||
(@GUID+176, 30866, 622, 1, 1, -36.1494, -23.2606, 33.9568, 4.2232, 120, 0, 0),
|
||||
(@GUID+177, 30866, 622, 1, 1, 17.7216, -26.2695, 35.5686, 5.06367, 120, 0, 0),
|
||||
(@GUID+178, 31243, 622, 1, 1, -11.2408, 33.2155, 10.5949, 1.58668, 120, 0, 0),
|
||||
(@GUID+179, 31243, 622, 1, 1, 1.99373, 33.0756, 10.0105, 1.53853, 120, 0, 0),
|
||||
(@GUID+180, 31243, 622, 1, 1, 15.239, 32.5832, 10.5826, 1.52441, 120, 0, 0),
|
||||
(@GUID+181, 31243, 622, 1, 1, 15.2483, -33.3678, 10.5837, 4.72649, 120, 0, 0),
|
||||
(@GUID+182, 31243, 622, 1, 1, 1.91814, -32.9286, 10.0097, 4.6891, 120, 0, 0),
|
||||
(@GUID+183, 31243, 622, 1, 1, -11.0915, -32.8872, 10.5819, 4.68507, 120, 0, 0),
|
||||
(@GUID+184, 31261, 622, 1, 1, -24.084, -22.2178, 24.3778, 1.43738, 120, 0, 0),
|
||||
(@GUID+185, 32301, 622, 1, 1, -3.37706, 0.007499, 34.0151, 4.65055, 120, 0, 0),
|
||||
(@GUID+186, 29799, 623, 1, 1, 34.5332, -38.5618, 25.0323, 3.15234, 120, 0, 0),
|
||||
(@GUID+187, 30344, 623, 1, 1, 43.6738, 0.121325, 25.1341, 3.10227, 120, 0, 0),
|
||||
(@GUID+188, 30345, 623, 1, 1, -48.0654, -0.185737, -4.98898, 3.11436, 120, 0, 0),
|
||||
(@GUID+189, 30346, 623, 1, 1, 25.0778, -0.047958, 9.59893, 3.13291, 120, 0, 0),
|
||||
(@GUID+190, 30347, 623, 1, 1, 28.6378, -7.55243, 23.2873, 0.157027, 120, 0, 0),
|
||||
(@GUID+191, 30350, 623, 1, 1, 16.4056, -2.2827, 20.4235, 3.11453, 120, 0, 0),
|
||||
(@GUID+192, 30351, 623, 1, 1, 2.42088, -23.0053, 22.5625, 0.046087, 120, 0, 0),
|
||||
(@GUID+193, 30351, 623, 1, 1, 1.29162, -9.37181, 20.458, 3.17295, 120, 0, 0),
|
||||
(@GUID+194, 30351, 623, 1, 1, 0.773476, 22.5004, 22.5503, 3.2248, 120, 0, 0),
|
||||
(@GUID+195, 30351, 623, 1, 1, 39.976, 44.3876, 25.0331, 3.16019, 120, 0, 0),
|
||||
(@GUID+196, 30351, 623, 1, 1, -36.4471, 6.81573, 20.4485, 4.73177, 120, 0, 0),
|
||||
(@GUID+197, 30351, 623, 1, 1, -36.1811, -6.90251, 20.4501, 1.6483, 120, 0, 0),
|
||||
(@GUID+198, 30351, 623, 1, 1, 1.44228, 9.63379, 20.4566, 3.15096, 120, 0, 0),
|
||||
(@GUID+199, 30352, 623, 1, 1, 48.8649, -8.72834, 40.0818, 3.12642, 120, 0, 0),
|
||||
(@GUID+200, 30352, 623, 1, 1, -17.337, 3.98796, 20.7652, 3.1541, 120, 0, 0),
|
||||
(@GUID+201, 30352, 623, 1, 1, 16.5684, 2.46962, 20.4252, 3.1329, 120, 0, 0),
|
||||
(@GUID+202, 30352, 623, 1, 1, 43.7981, 13.0009, -2.07474, 4.61776, 120, 0, 0),
|
||||
(@GUID+203, 30352, 623, 1, 1, -67.4841, 3.50927, 9.60209, 5.83577, 120, 0, 0),
|
||||
(@GUID+204, 30352, 623, 1, 1, -17.2379, -3.94242, 20.7667, 3.1541, 120, 0, 0),
|
||||
(@GUID+205, 30352, 623, 1, 1, -67.1723, -3.73439, 9.60211, 0.318344, 120, 0, 0),
|
||||
(@GUID+206, 30352, 623, 1, 1, 36.4909, 6.11523, 9.60666, 3.01117, 120, 0, 0),
|
||||
(@GUID+207, 30352, 623, 1, 1, -49.1048, 0.044213, 20.6694, 0.029782, 120, 0, 0),
|
||||
(@GUID+208, 30352, 623, 1, 1, 36.436, -6.06257, 9.60687, 3.09364, 120, 0, 0),
|
||||
(@GUID+209, 30352, 623, 1, 1, 48.8813, 8.78624, 40.0817, 3.1426, 120, 0, 0),
|
||||
(@GUID+210, 30352, 623, 1, 1, -60.5592, 0.055898, -5.27774, 0.004184, 120, 0, 0),
|
||||
(@GUID+211, 30380, 623, 1, 1, -6.13984, 21.6533, 9.991, 1.48436, 120, 0, 0),
|
||||
(@GUID+212, 30380, 623, 1, 1, 3.99105, -21.2539, 9.67311, 4.9577, 120, 0, 0),
|
||||
(@GUID+213, 30380, 623, 1, 1, -41.0289, 25.7685, 1.20385, 1.49696, 120, 0, 0),
|
||||
(@GUID+214, 30380, 623, 1, 1, -17.4619, 22.2092, 9.60018, 1.58254, 120, 0, 0),
|
||||
(@GUID+215, 30380, 623, 1, 1, -8.79147, 30.0334, -0.157799, 0.471494, 120, 0, 0),
|
||||
(@GUID+216, 30380, 623, 1, 1, -26.5726, 29.6008, -0.15773, 0.856857, 120, 0, 0),
|
||||
(@GUID+217, 30380, 623, 1, 1, 45.5093, 6.67955, 30.1788, 5.44543, 120, 0, 0),
|
||||
(@GUID+218, 30380, 623, 1, 1, 1.92073, 28.7498, 0.101361, 0.232732, 120, 0, 0),
|
||||
(@GUID+219, 30380, 623, 1, 1, -37.3836, 19.9617, 9.59771, 1.87549, 120, 0, 0),
|
||||
(@GUID+220, 30380, 623, 1, 1, -37.1975, -20.2765, 9.65711, 4.32467, 120, 0, 0),
|
||||
(@GUID+221, 30380, 623, 1, 1, -7.54172, -30.0747, 0.101348, 4.17752, 120, 0, 0),
|
||||
(@GUID+222, 30380, 623, 1, 1, -30.1731, -21.9358, 9.59686, 4.72914, 120, 0, 0),
|
||||
(@GUID+223, 30380, 623, 1, 1, 3.45962, -28.1289, 0.101388, 4.29376, 120, 0, 0),
|
||||
(@GUID+224, 30380, 623, 1, 1, -18.0212, -22.0926, 9.60068, 4.66788, 120, 0, 0),
|
||||
(@GUID+225, 30380, 623, 1, 1, -24.7068, -29.9771, 0.101334, 3.66623, 120, 0, 0),
|
||||
(@GUID+226, 30380, 623, 1, 1, 3.92454, 20.827, 9.67354, 1.30372, 120, 0, 0),
|
||||
(@GUID+227, 30380, 623, 1, 1, -6.33308, -21.7722, 9.99575, 4.85167, 120, 0, 0),
|
||||
(@GUID+228, 30380, 623, 1, 1, -39.6946, -26.8419, 0.82802, 2.93659, 120, 0, 0),
|
||||
(@GUID+229, 30392, 623, 1, 1, 28.7566, 7.6217, 23.2872, 6.08285, 120, 0, 0),
|
||||
(@GUID+230, 30394, 623, 1, 1, -14.1505, 23.0373, -5.24869, 0.027745, 120, 0, 0),
|
||||
(@GUID+231, 30394, 623, 1, 1, -11.7295, -24.7904, 9.58663, 1.63703, 120, 0, 0),
|
||||
(@GUID+232, 30394, 623, 1, 1, -11.9688, 25.5424, 9.58513, 4.66945, 120, 0, 0),
|
||||
(@GUID+233, 30394, 623, 1, 1, -57.9337, 6.01148, 23.5029, 1.54855, 120, 0, 0),
|
||||
(@GUID+234, 30394, 623, 1, 1, -14.3898, -23.2398, -5.25039, 6.16013, 120, 0, 0),
|
||||
(@GUID+235, 30394, 623, 1, 1, -48.1449, -3.10366, -5.21617, 3.11436, 120, 0, 0),
|
||||
(@GUID+236, 30833, 623, 1, 1, 6.18656, -0.008156, 20.5756, 6.28313, 120, 0, 0),
|
||||
(@GUID+237, 30867, 623, 1, 1, -11.0475, -22.7053, 22.5096, 4.51265, 120, 0, 0),
|
||||
(@GUID+238, 30867, 623, 1, 1, -32.9158, -22.1469, 22.5861, 4.59982, 120, 0, 0),
|
||||
(@GUID+239, 30867, 623, 1, 1, -10.0824, 23.2226, 22.5129, 1.54405, 120, 0, 0),
|
||||
(@GUID+240, 30867, 623, 1, 1, 36.8757, 45.226, 25.0331, 2.16509, 120, 0, 0),
|
||||
(@GUID+241, 30867, 623, 1, 1, -33.4747, 22.2096, 22.5895, 1.56211, 120, 0, 0),
|
||||
(@GUID+242, 30867, 623, 1, 1, 36.9277, -44.9241, 25.0318, 4.11052, 120, 0, 0),
|
||||
(@GUID+243, 31259, 623, 1, 1, 16.8761, -17.8635, 20.4597, 2.02864, 120, 0, 0),
|
||||
(@GUID+244, 32193, 623, 1, 1, -21.6978, 0.127903, -18.1897, 3.12341, 120, 0, 0),
|
||||
(@GUID+245, 32302, 623, 1, 1, 54.6648, -6.9431, 40.0874, 3.0302, 120, 0, 0),
|
||||
(@GUID+246, 32566, 623, 1, 1, 34.6465, -41.7087, 25.0325, 3.20731, 120, 0, 0),
|
||||
(@GUID+247, 32777, 623, 1, 1, 42.9517, 4.20903, 25.1088, 3.47298, 120, 0, 0),
|
||||
(@GUID+248, 34929, 641, 1, 1, -31.0354, 25.1286, 21.6921, 1.60659, 120, 0, 0),
|
||||
(@GUID+249, 34929, 641, 1, 1, -21.4492, 25.8326, 21.6309, 1.60659, 120, 0, 0),
|
||||
(@GUID+250, 34929, 641, 1, 1, -12.4734, 26.321, 21.6237, 1.60659, 120, 0, 0),
|
||||
(@GUID+251, 34929, 641, 1, 1, -2.81125, 26.2077, 21.6566, 1.60659, 120, 0, 0),
|
||||
(@GUID+252, 34929, 641, 1, 1, -41.7122, 23.1838, 22.5605, 1.60659, 120, 0, 0),
|
||||
(@GUID+253, 34935, 642, 1, 1, -21.401, -31.343, 34.173, 4.62057, 120, 0, 0),
|
||||
(@GUID+254, 34935, 642, 1, 1, -12.1064, -31.9697, 34.3807, 4.62057, 120, 0, 0),
|
||||
(@GUID+255, 34935, 642, 1, 1, -2.4877, -31.9885, 34.8384, 4.62057, 120, 0, 0),
|
||||
(@GUID+256, 34935, 642, 1, 1, 10.2664, -32.0713, 35.7357, 4.62057, 120, 0, 0),
|
||||
(@GUID+257, 34935, 642, 1, 1, 19.4636, -30.794, 36.2254, 4.83106, 120, 0, 0),
|
||||
(@GUID+258, 3084, 647, 1, 1, -5.20674, -11.3432, -17.6101, 4.71239, 120, 0, 0),
|
||||
(@GUID+259, 3084, 647, 1, 1, -4.83257, -4.31233, -17.6322, 1.62316, 120, 0, 0),
|
||||
(@GUID+260, 24934, 647, 1, 1, 10.321, -3.57351, -23.4941, 3.1765, 120, 0, 0),
|
||||
(@GUID+261, 24935, 647, 1, 1, 10.2871, -12.0272, -23.4942, 3.10669, 120, 0, 0),
|
||||
(@GUID+262, 25075, 647, 1, 1, -3.3964, -7.90545, -23.6967, 6.24828, 120, 0, 0),
|
||||
(@GUID+263, 34715, 647, 1, 1, -9.18316, -7.77573, -17.217, 3.28122, 120, 0, 0),
|
||||
(@GUID+264, 34717, 647, 1, 1, -13.6702, -12.4018, -15.9876, 4.59022, 120, 0, 0),
|
||||
(@GUID+265, 34718, 647, 1, 1, 13.7451, -5.12846, -24.0452, 0.139626, 120, 0, 0),
|
||||
(@GUID+266, 34719, 647, 1, 1, 7.62309, -5.02532, -17.6702, 4.92183, 120, 0, 0),
|
||||
(@GUID+267, 34721, 647, 1, 1, -0.919197, -6.16422, -23.6729, 3.57792, 120, 0, 0),
|
||||
(@GUID+268, 34723, 647, 1, 1, -17.4797, -5.60698, -14.9281, 3.22886, 120, 0, 0),
|
||||
(@GUID+269, 34730, 647, 1, 1, -2.16687, -7.85422, -23.6919, 3.38594, 120, 0, 0);
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `transports` DROP `period`;
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "SmartScript.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "Vehicle.h"
|
||||
#include "MoveSplineInit.h"
|
||||
#include "GameEventMgr.h"
|
||||
|
||||
class TrinityStringTextBuilder
|
||||
@@ -1353,7 +1354,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
break;
|
||||
|
||||
if (e.GetTargetType() == SMART_TARGET_SELF)
|
||||
me->SetFacingTo(me->GetHomePosition().GetOrientation());
|
||||
me->SetFacingTo((me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && me->GetTransGUID() ?
|
||||
me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation());
|
||||
else if (e.GetTargetType() == SMART_TARGET_POSITION)
|
||||
me->SetFacingTo(e.target.o);
|
||||
else if (ObjectList* targets = GetTargets(e, unit))
|
||||
@@ -1406,7 +1408,14 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
}
|
||||
|
||||
if (!target)
|
||||
me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, e.target.x, e.target.y, e.target.z);
|
||||
{
|
||||
G3D::Vector3 dest(e.target.x, e.target.y, e.target.z);
|
||||
if (e.action.MoveToPos.transport)
|
||||
if (TransportBase* trans = me->GetDirectTransport())
|
||||
trans->CalculatePassengerPosition(dest.x, dest.y, dest.z);
|
||||
|
||||
me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, dest.x, dest.y, dest.z);
|
||||
}
|
||||
else
|
||||
me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
|
||||
break;
|
||||
|
||||
@@ -907,6 +907,7 @@ struct SmartAction
|
||||
struct
|
||||
{
|
||||
uint32 pointId;
|
||||
uint32 transport;
|
||||
} MoveToPos;
|
||||
|
||||
struct
|
||||
|
||||
@@ -303,7 +303,7 @@ enum RBACPermissions
|
||||
RBAC_PERM_COMMAND_GOBJECT_SET_STATE = 397,
|
||||
RBAC_PERM_COMMAND_GOBJECT_TARGET = 398,
|
||||
RBAC_PERM_COMMAND_GOBJECT_TURN = 399,
|
||||
// 400 - reuse
|
||||
RBAC_PERM_COMMAND_DEBUG_TRANSPORT = 400,
|
||||
RBAC_PERM_COMMAND_GUILD = 401,
|
||||
RBAC_PERM_COMMAND_GUILD_CREATE = 402,
|
||||
RBAC_PERM_COMMAND_GUILD_DELETE = 403,
|
||||
|
||||
@@ -71,22 +71,6 @@ void BattlegroundIC::HandlePlayerResurrect(Player* player)
|
||||
player->CastSpell(player, SPELL_OIL_REFINERY, true);
|
||||
}
|
||||
|
||||
void BattlegroundIC::SendTransportInit(Player* player)
|
||||
{
|
||||
if (!gunshipAlliance || !gunshipHorde)
|
||||
return;
|
||||
|
||||
UpdateData transData;
|
||||
|
||||
gunshipAlliance->BuildCreateUpdateBlockForPlayer(&transData, player);
|
||||
gunshipHorde->BuildCreateUpdateBlockForPlayer(&transData, player);
|
||||
|
||||
WorldPacket packet;
|
||||
|
||||
transData.BuildPacket(&packet);
|
||||
player->SendDirectMessage(&packet);
|
||||
}
|
||||
|
||||
void BattlegroundIC::DoAction(uint32 action, uint64 var)
|
||||
{
|
||||
if (action != ACTION_TELEPORT_PLAYER_TO_TRANSPORT)
|
||||
@@ -300,8 +284,6 @@ void BattlegroundIC::AddPlayer(Player* player)
|
||||
|
||||
if (nodePoint[NODE_TYPE_REFINERY].nodeState == (player->GetTeamId() == TEAM_ALLIANCE ? NODE_STATE_CONTROLLED_A : NODE_STATE_CONTROLLED_H))
|
||||
player->CastSpell(player, SPELL_OIL_REFINERY, true);
|
||||
|
||||
SendTransportInit(player);
|
||||
}
|
||||
|
||||
void BattlegroundIC::RemovePlayer(Player* player, uint64 /*guid*/, uint32 /*team*/)
|
||||
@@ -409,8 +391,8 @@ bool BattlegroundIC::SetupBattleground()
|
||||
return false;
|
||||
}
|
||||
|
||||
gunshipHorde = CreateTransport(GO_HORDE_GUNSHIP, TRANSPORT_PERIOD_TIME);
|
||||
gunshipAlliance = CreateTransport(GO_ALLIANCE_GUNSHIP, TRANSPORT_PERIOD_TIME);
|
||||
gunshipHorde = sTransportMgr->CreateTransport(GO_HORDE_GUNSHIP, 0, GetBgMap());
|
||||
gunshipAlliance = sTransportMgr->CreateTransport(GO_ALLIANCE_GUNSHIP, 0, GetBgMap());
|
||||
|
||||
if (!gunshipAlliance || !gunshipHorde)
|
||||
{
|
||||
@@ -420,10 +402,8 @@ bool BattlegroundIC::SetupBattleground()
|
||||
|
||||
//Send transport init packet to all player in map
|
||||
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
{
|
||||
if (Player* player = ObjectAccessor::FindPlayer(itr->first))
|
||||
SendTransportInit(player);
|
||||
}
|
||||
GetBgMap()->SendInitTransports(player);
|
||||
|
||||
// setting correct factions for Keep Cannons
|
||||
for (uint8 i = BG_IC_NPC_KEEP_CANNON_1; i < BG_IC_NPC_KEEP_CANNON_12; ++i)
|
||||
@@ -616,8 +596,8 @@ void BattlegroundIC::HandleContestedNodes(ICNodePoint* nodePoint)
|
||||
{
|
||||
if (nodePoint->nodeType == NODE_TYPE_HANGAR)
|
||||
{
|
||||
if (gunshipAlliance && gunshipHorde)
|
||||
(nodePoint->faction == TEAM_ALLIANCE ? gunshipHorde : gunshipAlliance)->BuildStopMovePacket(GetBgMap());
|
||||
if (gunshipAlliance && gunshipHorde)
|
||||
(nodePoint->faction == TEAM_ALLIANCE ? gunshipHorde : gunshipAlliance)->EnableMovement(false);
|
||||
|
||||
for (uint8 u = BG_IC_GO_HANGAR_TELEPORTER_1; u < BG_IC_GO_HANGAR_TELEPORTER_3; ++u)
|
||||
DelObject(u);
|
||||
@@ -656,8 +636,8 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture)
|
||||
|
||||
//TC_LOG_ERROR(LOG_FILTER_BATTLEGROUND, "BG_IC_GO_HANGAR_BANNER CAPTURED Faction: %u", nodePoint->faction);
|
||||
|
||||
(nodePoint->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->BuildStartMovePacket(GetBgMap());
|
||||
(nodePoint->faction == TEAM_ALLIANCE ? gunshipHorde : gunshipAlliance)->BuildStopMovePacket(GetBgMap());
|
||||
(nodePoint->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->EnableMovement(true);
|
||||
(nodePoint->faction == TEAM_ALLIANCE ? gunshipHorde : gunshipAlliance)->EnableMovement(false);
|
||||
// we should spawn teleporters
|
||||
break;
|
||||
case BG_IC_GO_QUARRY_BANNER:
|
||||
@@ -865,7 +845,6 @@ void BattlegroundIC::DestroyGate(Player* player, GameObject* go)
|
||||
|
||||
void BattlegroundIC::EventPlayerDamagedGO(Player* /*player*/, GameObject* /*go*/, uint32 /*eventType*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry const* BattlegroundIC::GetClosestGraveYard(Player* player)
|
||||
@@ -907,52 +886,6 @@ WorldSafeLocsEntry const* BattlegroundIC::GetClosestGraveYard(Player* player)
|
||||
return good_entry;
|
||||
}
|
||||
|
||||
Transport* BattlegroundIC::CreateTransport(uint32 goEntry, uint32 period)
|
||||
{
|
||||
Transport* t = new Transport(period, 0);
|
||||
|
||||
GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(goEntry);
|
||||
|
||||
if (!goinfo)
|
||||
{
|
||||
TC_LOG_ERROR(LOG_FILTER_SQL, "Transport ID: %u will not be loaded, gameobject_template missing", goEntry);
|
||||
delete t;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::set<uint32> mapsUsed;
|
||||
|
||||
if (!t->GenerateWaypoints(goinfo->moTransport.taxiPathId, mapsUsed))
|
||||
// skip transports with empty waypoints list
|
||||
{
|
||||
TC_LOG_ERROR(LOG_FILTER_SQL, "Transport (path id %u) path size = 0. Transport ignored, check DBC files or transport GO data0 field.", goinfo->moTransport.taxiPathId);
|
||||
delete t;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32 mapid = t->m_WayPoints[0].mapid;
|
||||
|
||||
float x = t->m_WayPoints[0].x;
|
||||
float y = t->m_WayPoints[0].y;
|
||||
float z = t->m_WayPoints[0].z;
|
||||
float o = 1;
|
||||
|
||||
// creates the Gameobject
|
||||
if (!t->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_MO_TRANSPORT), goEntry, mapid, x, y, z, o, 255, 0))
|
||||
{
|
||||
delete t;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//If we someday decide to use the grid to track transports, here:
|
||||
t->SetMap(GetBgMap());
|
||||
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
t->AddNPCPassenger(0, (goEntry == GO_HORDE_GUNSHIP ? NPC_HORDE_GUNSHIP_CANNON : NPC_ALLIANCE_GUNSHIP_CANNON), (goEntry == GO_HORDE_GUNSHIP ? hordeGunshipPassengers[i].GetPositionX() : allianceGunshipPassengers[i].GetPositionX()), (goEntry == GO_HORDE_GUNSHIP ? hordeGunshipPassengers[i].GetPositionY() : allianceGunshipPassengers[i].GetPositionY()), (goEntry == GO_HORDE_GUNSHIP ? hordeGunshipPassengers[i].GetPositionZ() : allianceGunshipPassengers[i].GetPositionZ()), (goEntry == GO_HORDE_GUNSHIP ? hordeGunshipPassengers[i].GetOrientation() : allianceGunshipPassengers[i].GetOrientation()));
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
bool BattlegroundIC::IsAllNodesControlledByTeam(uint32 team) const
|
||||
{
|
||||
uint32 count = 0;
|
||||
@@ -983,4 +916,4 @@ bool BattlegroundIC::IsSpellAllowed(uint32 spellId, Player const* player) const
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -956,8 +956,6 @@ class BattlegroundIC : public Battleground
|
||||
void UpdateNodeWorldState(ICNodePoint* nodePoint);
|
||||
void HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture);
|
||||
void HandleContestedNodes(ICNodePoint* nodePoint);
|
||||
Transport* CreateTransport(uint32 goEntry, uint32 period);
|
||||
void SendTransportInit(Player* player);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "Log.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "TransportMgr.h"
|
||||
#include "DBCfmt.h"
|
||||
#include "Timer.h"
|
||||
#include "ObjectDefines.h"
|
||||
@@ -190,6 +191,8 @@ static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);
|
||||
|
||||
DBCStorage <TeamContributionPointsEntry> sTeamContributionPointsStore(TeamContributionPointsfmt);
|
||||
DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt);
|
||||
DBCStorage <TransportAnimationEntry> sTransportAnimationStore(TransportAnimationfmt);
|
||||
DBCStorage <TransportRotationEntry> sTransportRotationStore(TransportRotationfmt);
|
||||
DBCStorage <VehicleEntry> sVehicleStore(VehicleEntryfmt);
|
||||
DBCStorage <VehicleSeatEntry> sVehicleSeatStore(VehicleSeatEntryfmt);
|
||||
DBCStorage <WMOAreaTableEntry> sWMOAreaTableStore(WMOAreaTableEntryfmt);
|
||||
@@ -604,6 +607,25 @@ void LoadDBCStores(const std::string& dataPath)
|
||||
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sTeamContributionPointsStore, dbcPath, "TeamContributionPoints.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sTotemCategoryStore, dbcPath, "TotemCategory.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sTransportAnimationStore, dbcPath, "TransportAnimation.dbc");
|
||||
for (uint32 i = 0; i < sTransportAnimationStore.GetNumRows(); ++i)
|
||||
{
|
||||
TransportAnimationEntry const* anim = sTransportAnimationStore.LookupEntry(i);
|
||||
if (!anim)
|
||||
continue;
|
||||
|
||||
sTransportMgr->AddPathNodeToTransport(anim->TransportEntry, anim->TimeSeg, anim);
|
||||
}
|
||||
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sTransportRotationStore, dbcPath, "TransportRotation.dbc");
|
||||
for (uint32 i = 0; i < sTransportRotationStore.GetNumRows(); ++i)
|
||||
{
|
||||
TransportRotationEntry const* rot = sTransportRotationStore.LookupEntry(i);
|
||||
if (!rot)
|
||||
continue;
|
||||
|
||||
sTransportMgr->AddPathRotationToTransport(rot->TransportEntry, rot->TimeSeg, rot);
|
||||
}
|
||||
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleStore, dbcPath, "Vehicle.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleSeatStore, dbcPath, "VehicleSeat.dbc");
|
||||
|
||||
@@ -1875,6 +1875,28 @@ struct TotemCategoryEntry
|
||||
uint32 categoryMask; // 19 (compatibility mask for same type: different for totems, compatible from high to low for rods)
|
||||
};
|
||||
|
||||
struct TransportAnimationEntry
|
||||
{
|
||||
//uint32 Id;
|
||||
uint32 TransportEntry;
|
||||
uint32 TimeSeg;
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
//uint32 MovementId;
|
||||
};
|
||||
|
||||
struct TransportRotationEntry
|
||||
{
|
||||
//uint32 Id;
|
||||
uint32 TransportEntry;
|
||||
uint32 TimeSeg;
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
float W;
|
||||
};
|
||||
|
||||
#define MAX_VEHICLE_SEATS 8
|
||||
|
||||
struct VehicleEntry
|
||||
|
||||
@@ -120,6 +120,8 @@ char const TaxiPathEntryfmt[] = "niii";
|
||||
char const TaxiPathNodeEntryfmt[] = "diiifffiiii";
|
||||
char const TeamContributionPointsfmt[] = "df";
|
||||
char const TotemCategoryEntryfmt[] = "nxxxxxxxxxxxxxxxxxii";
|
||||
char const TransportAnimationfmt[] = "diifffx";
|
||||
char const TransportRotationfmt[] = "diiffff";
|
||||
char const VehicleEntryfmt[] = "niffffiiiiiiiifffffffffffffffssssfifiixx";
|
||||
char const VehicleSeatEntryfmt[] = "niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx";
|
||||
char const WMOAreaTableEntryfmt[] = "niiixxxxxiixxxxxxxxxxxxxxxxx";
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
// apply implementation of the singletons
|
||||
#include "Transport.h"
|
||||
|
||||
TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
|
||||
{
|
||||
@@ -141,7 +141,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
||||
return true;
|
||||
}
|
||||
|
||||
Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapCreature(),
|
||||
Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapObject(),
|
||||
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLowGUID(0),
|
||||
m_PlayerDamageReq(0), m_lootRecipient(0), m_lootRecipientGroup(0), m_corpseRemoveTime(0), m_respawnTime(0),
|
||||
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE),
|
||||
@@ -934,7 +934,8 @@ void Creature::SaveToDB()
|
||||
return;
|
||||
}
|
||||
|
||||
SaveToDB(GetMapId(), data->spawnMask, GetPhaseMask());
|
||||
uint32 mapId = GetTransport() ? GetTransport()->GetGOInfo()->moTransport.mapID : GetMapId();
|
||||
SaveToDB(mapId, data->spawnMask, GetPhaseMask());
|
||||
}
|
||||
|
||||
void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
|
||||
@@ -973,10 +974,21 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
|
||||
data.phaseMask = phaseMask;
|
||||
data.displayid = displayId;
|
||||
data.equipmentId = GetCurrentEquipmentId();
|
||||
data.posX = GetPositionX();
|
||||
data.posY = GetPositionY();
|
||||
data.posZ = GetPositionZMinusOffset();
|
||||
data.orientation = GetOrientation();
|
||||
if (!GetTransport())
|
||||
{
|
||||
data.posX = GetPositionX();
|
||||
data.posY = GetPositionY();
|
||||
data.posZ = GetPositionZMinusOffset();
|
||||
data.orientation = GetOrientation();
|
||||
}
|
||||
else
|
||||
{
|
||||
data.posX = GetTransOffsetX();
|
||||
data.posY = GetTransOffsetY();
|
||||
data.posZ = GetTransOffsetZ();
|
||||
data.orientation = GetTransOffsetO();
|
||||
}
|
||||
|
||||
data.spawntimesecs = m_respawnDelay;
|
||||
// prevent add data integrity problems
|
||||
data.spawndist = GetDefaultMovementType() == IDLE_MOTION_TYPE ? 0.0f : m_respawnradius;
|
||||
|
||||
@@ -415,36 +415,7 @@ typedef std::map<uint32, time_t> CreatureSpellCooldowns;
|
||||
|
||||
#define MAX_VENDOR_ITEMS 150 // Limitation in 3.x.x item count in SMSG_LIST_INVENTORY
|
||||
|
||||
enum CreatureCellMoveState
|
||||
{
|
||||
CREATURE_CELL_MOVE_NONE, // not in move list
|
||||
CREATURE_CELL_MOVE_ACTIVE, // in move list
|
||||
CREATURE_CELL_MOVE_INACTIVE // in move list but should not move
|
||||
};
|
||||
|
||||
class MapCreature
|
||||
{
|
||||
friend class Map; // map for moving creatures
|
||||
friend class ObjectGridLoader; // grid loader for loading creatures
|
||||
|
||||
protected:
|
||||
MapCreature() : _moveState(CREATURE_CELL_MOVE_NONE) {}
|
||||
|
||||
private:
|
||||
Cell _currentCell;
|
||||
Cell const& GetCurrentCell() const { return _currentCell; }
|
||||
void SetCurrentCell(Cell const& cell) { _currentCell = cell; }
|
||||
|
||||
CreatureCellMoveState _moveState;
|
||||
Position _newPosition;
|
||||
void SetNewCellPosition(float x, float y, float z, float o)
|
||||
{
|
||||
_moveState = CREATURE_CELL_MOVE_ACTIVE;
|
||||
_newPosition.Relocate(x, y, z, o);
|
||||
}
|
||||
};
|
||||
|
||||
class Creature : public Unit, public GridObject<Creature>, public MapCreature
|
||||
class Creature : public Unit, public GridObject<Creature>, public MapObject
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <G3D/Quat.h>
|
||||
#include "GameObjectAI.h"
|
||||
#include "Battleground.h"
|
||||
#include "CellImpl.h"
|
||||
@@ -32,8 +33,10 @@
|
||||
#include "SpellMgr.h"
|
||||
#include "UpdateFieldFlags.h"
|
||||
#include "World.h"
|
||||
#include "Transport.h"
|
||||
|
||||
GameObject::GameObject(): WorldObject(false), m_model(NULL), m_goValue(), m_AI(NULL)
|
||||
GameObject::GameObject() : WorldObject(false), MapObject(),
|
||||
m_model(NULL), m_goValue(), m_AI(NULL)
|
||||
{
|
||||
m_objectType |= TYPEMASK_GAMEOBJECT;
|
||||
m_objectTypeId = TYPEID_GAMEOBJECT;
|
||||
@@ -100,6 +103,9 @@ void GameObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
|
||||
|
||||
if (m_uint32Values) // field array can be not exist if GameOBject not loaded
|
||||
RemoveFromOwner();
|
||||
|
||||
if (GetTransport() && !ToTransport())
|
||||
GetTransport()->RemovePassenger(this);
|
||||
}
|
||||
|
||||
void GameObject::RemoveFromOwner()
|
||||
@@ -169,6 +175,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
|
||||
SetMap(map);
|
||||
|
||||
Relocate(x, y, z, ang);
|
||||
m_stationaryPosition.Relocate(x, y, z, ang);
|
||||
if (!IsPositionValid())
|
||||
{
|
||||
TC_LOG_ERROR(LOG_FILTER_GENERAL, "Gameobject (GUID: %u Entry: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)", guidlow, name_id, x, y);
|
||||
@@ -192,6 +199,9 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
|
||||
return false;
|
||||
}
|
||||
|
||||
if (goinfo->type == GAMEOBJECT_TYPE_TRANSPORT)
|
||||
m_updateFlag = (m_updateFlag | UPDATEFLAG_TRANSPORT) & ~UPDATEFLAG_POSITION;
|
||||
|
||||
Object::_Create(guidlow, goinfo->entry, HIGHGUID_GAMEOBJECT);
|
||||
|
||||
m_goInfo = goinfo;
|
||||
@@ -238,9 +248,11 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
|
||||
break;
|
||||
case GAMEOBJECT_TYPE_TRANSPORT:
|
||||
SetUInt32Value(GAMEOBJECT_LEVEL, goinfo->transport.pause);
|
||||
if (goinfo->transport.startOpen)
|
||||
SetGoState(GO_STATE_ACTIVE);
|
||||
SetGoState(goinfo->transport.startOpen ? GO_STATE_ACTIVE : GO_STATE_READY);
|
||||
SetGoAnimProgress(animprogress);
|
||||
m_goValue.Transport.PathProgress = 0;
|
||||
m_goValue.Transport.AnimationInfo = sTransportMgr->GetTransportAnimInfo(goinfo->entry);
|
||||
m_goValue.Transport.CurrentSeg = 0;
|
||||
break;
|
||||
case GAMEOBJECT_TYPE_FISHINGNODE:
|
||||
SetGoAnimProgress(0);
|
||||
@@ -274,18 +286,10 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
|
||||
|
||||
void GameObject::Update(uint32 diff)
|
||||
{
|
||||
if (!AI())
|
||||
{
|
||||
if (!AIM_Initialize())
|
||||
TC_LOG_ERROR(LOG_FILTER_GENERAL, "Could not initialize GameObjectAI");
|
||||
} else
|
||||
if (AI())
|
||||
AI()->UpdateAI(diff);
|
||||
|
||||
if (IS_MO_TRANSPORT_GUID(GetGUID()))
|
||||
{
|
||||
//((Transport*)this)->Update(p_time);
|
||||
return;
|
||||
}
|
||||
else if (!AIM_Initialize())
|
||||
TC_LOG_ERROR(LOG_FILTER_GENERAL, "Could not initialize GameObjectAI");
|
||||
|
||||
switch (m_lootState)
|
||||
{
|
||||
@@ -308,6 +312,38 @@ void GameObject::Update(uint32 diff)
|
||||
m_lootState = GO_READY;
|
||||
break;
|
||||
}
|
||||
/* TODO: Fix movement in unloaded grid - currently GO will just disappear
|
||||
case GAMEOBJECT_TYPE_TRANSPORT:
|
||||
{
|
||||
if (!m_goValue.Transport.AnimationInfo)
|
||||
break;
|
||||
|
||||
if (GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
m_goValue.Transport.PathProgress += diff;
|
||||
uint32 timer = m_goValue.Transport.PathProgress % m_goValue.Transport.AnimationInfo->TotalTime;
|
||||
TransportAnimationEntry const* node = m_goValue.Transport.AnimationInfo->GetAnimNode(timer);
|
||||
if (node && m_goValue.Transport.CurrentSeg != node->TimeSeg)
|
||||
{
|
||||
m_goValue.Transport.CurrentSeg = node->TimeSeg;
|
||||
|
||||
G3D::Quat rotation = m_goValue.Transport.AnimationInfo->GetAnimRotation(timer);
|
||||
G3D::Vector3 pos = rotation.toRotationMatrix()
|
||||
* G3D::Matrix3::fromEulerAnglesZYX(GetOrientation(), 0.0f, 0.0f)
|
||||
* G3D::Vector3(node->X, node->Y, node->Z);
|
||||
|
||||
pos += G3D::Vector3(GetStationaryX(), GetStationaryY(), GetStationaryZ());
|
||||
|
||||
G3D::Vector3 src(GetPositionX(), GetPositionY(), GetPositionZ());
|
||||
|
||||
sLog->outInfo(LOG_FILTER_GENERAL, "Src: %s Dest: %s", src.toString().c_str(), pos.toString().c_str());
|
||||
|
||||
GetMap()->GameObjectRelocation(this, pos.x, pos.y, pos.z, GetOrientation());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
*/
|
||||
case GAMEOBJECT_TYPE_FISHINGNODE:
|
||||
{
|
||||
// fishing code (bobber ready)
|
||||
@@ -1182,10 +1218,12 @@ void GameObject::Use(Unit* user)
|
||||
if (itr->second)
|
||||
{
|
||||
if (Player* ChairUser = ObjectAccessor::FindPlayer(itr->second))
|
||||
{
|
||||
if (ChairUser->IsSitState() && ChairUser->getStandState() != UNIT_STAND_STATE_SIT && ChairUser->GetExactDist2d(x_i, y_i) < 0.1f)
|
||||
continue; // This seat is already occupied by ChairUser. NOTE: Not sure if the ChairUser->getStandState() != UNIT_STAND_STATE_SIT check is required.
|
||||
else
|
||||
itr->second = 0; // This seat is unoccupied.
|
||||
}
|
||||
else
|
||||
itr->second = 0; // The seat may of had an occupant, but they're offline.
|
||||
}
|
||||
@@ -2102,6 +2140,7 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
|
||||
if (index == GAMEOBJECT_DYNAMIC)
|
||||
{
|
||||
uint16 dynFlags = 0;
|
||||
int16 pathProgress = -1;
|
||||
switch (GetGoType())
|
||||
{
|
||||
case GAMEOBJECT_TYPE_CHEST:
|
||||
@@ -2115,12 +2154,13 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
|
||||
if (ActivateToQuest(target))
|
||||
dynFlags |= GO_DYNFLAG_LO_SPARKLE;
|
||||
break;
|
||||
default:
|
||||
case GAMEOBJECT_TYPE_MO_TRANSPORT:
|
||||
pathProgress = int16(float(m_goValue.Transport.PathProgress) / float(GetUInt32Value(GAMEOBJECT_LEVEL)) * 65535.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
fieldBuffer << uint16(dynFlags);
|
||||
fieldBuffer << uint16(-1);
|
||||
fieldBuffer << int16(pathProgress);
|
||||
}
|
||||
else if (index == GAMEOBJECT_FLAGS)
|
||||
{
|
||||
@@ -2140,3 +2180,25 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
|
||||
updateMask.AppendToPacket(data);
|
||||
data->append(fieldBuffer);
|
||||
}
|
||||
|
||||
void GameObject::GetRespawnPosition(float &x, float &y, float &z, float* ori /* = NULL*/) const
|
||||
{
|
||||
if (m_DBTableGuid)
|
||||
{
|
||||
if (GameObjectData const* data = sObjectMgr->GetGOData(GetDBTableGUIDLow()))
|
||||
{
|
||||
x = data->posX;
|
||||
y = data->posY;
|
||||
z = data->posZ;
|
||||
if (ori)
|
||||
*ori = data->orientation;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
x = GetPositionX();
|
||||
y = GetPositionY();
|
||||
z = GetPositionZ();
|
||||
if (ori)
|
||||
*ori = GetOrientation();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
class GameObjectAI;
|
||||
class Group;
|
||||
class Transport;
|
||||
|
||||
#define MAX_GAMEOBJECT_QUEST_ITEMS 6
|
||||
|
||||
@@ -229,6 +230,7 @@ struct GameObjectTemplate
|
||||
uint32 transportPhysics; //5
|
||||
uint32 mapID; //6
|
||||
uint32 worldState1; //7
|
||||
uint32 canBeStopped; //8
|
||||
} moTransport;
|
||||
//16 GAMEOBJECT_TYPE_DUELFLAG - empty
|
||||
//17 GAMEOBJECT_TYPE_FISHINGNODE - empty
|
||||
@@ -539,9 +541,17 @@ struct GameObjectTemplate
|
||||
typedef UNORDERED_MAP<uint32, GameObjectTemplate> GameObjectTemplateContainer;
|
||||
|
||||
class OPvPCapturePoint;
|
||||
struct TransportAnimation;
|
||||
|
||||
union GameObjectValue
|
||||
{
|
||||
//11 GAMEOBJECT_TYPE_TRANSPORT
|
||||
struct
|
||||
{
|
||||
uint32 PathProgress;
|
||||
TransportAnimation const* AnimationInfo;
|
||||
uint32 CurrentSeg;
|
||||
} Transport;
|
||||
//25 GAMEOBJECT_TYPE_FISHINGHOLE
|
||||
struct
|
||||
{
|
||||
@@ -617,7 +627,7 @@ class GameObjectModel;
|
||||
// 5 sec for bobber catch
|
||||
#define FISHING_BOBBER_READY_TIME 5
|
||||
|
||||
class GameObject : public WorldObject, public GridObject<GameObject>
|
||||
class GameObject : public WorldObject, public GridObject<GameObject>, public MapObject
|
||||
{
|
||||
public:
|
||||
explicit GameObject();
|
||||
@@ -811,8 +821,19 @@ class GameObject : public WorldObject, public GridObject<GameObject>
|
||||
uint32 GetDisplayId() const { return GetUInt32Value(GAMEOBJECT_DISPLAYID); }
|
||||
|
||||
GameObjectModel* m_model;
|
||||
void GetRespawnPosition(float &x, float &y, float &z, float* ori = NULL) const;
|
||||
|
||||
Transport* ToTransport() { if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT) return reinterpret_cast<Transport*>(this); else return NULL; }
|
||||
Transport const* ToTransport() const { if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT) return reinterpret_cast<Transport const*>(this); else return NULL; }
|
||||
|
||||
float GetStationaryX() const { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionX(); return GetPositionX(); }
|
||||
float GetStationaryY() const { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionY(); return GetPositionY(); }
|
||||
float GetStationaryZ() const { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionZ(); return GetPositionZ(); }
|
||||
float GetStationaryO() const { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetOrientation(); return GetOrientation(); }
|
||||
|
||||
protected:
|
||||
bool AIM_Initialize();
|
||||
void UpdateModel(); // updates model in case displayId were changed
|
||||
uint32 m_spellId;
|
||||
time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()),
|
||||
uint32 m_respawnDelayTime; // (secs) if 0 then current GO state no dependent from timer
|
||||
@@ -835,6 +856,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>
|
||||
GameObjectValue m_goValue;
|
||||
|
||||
uint64 m_rotation;
|
||||
Position m_stationaryPosition;
|
||||
|
||||
uint64 m_lootRecipient;
|
||||
uint32 m_lootRecipientGroup;
|
||||
@@ -842,7 +864,6 @@ class GameObject : public WorldObject, public GridObject<GameObject>
|
||||
private:
|
||||
void RemoveFromOwner();
|
||||
void SwitchDoorOrButton(bool activate, bool alternative = false);
|
||||
void UpdateModel(); // updates model in case displayId were changed
|
||||
|
||||
//! Object distance/size - overridden from Object::_IsWithinDist. Needs to take in account proper GO size.
|
||||
bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool /*is3D*/) const
|
||||
|
||||
@@ -219,9 +219,6 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
|
||||
case GAMEOBJECT_TYPE_FLAGDROP:
|
||||
updateType = UPDATETYPE_CREATE_OBJECT2;
|
||||
break;
|
||||
case GAMEOBJECT_TYPE_TRANSPORT:
|
||||
flags |= UPDATEFLAG_TRANSPORT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -414,13 +411,10 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
|
||||
// 0x40
|
||||
if (flags & UPDATEFLAG_STATIONARY_POSITION)
|
||||
{
|
||||
*data << object->GetPositionX();
|
||||
*data << object->GetPositionY();
|
||||
if (isType(TYPEMASK_UNIT))
|
||||
*data << unit->GetPositionZMinusOffset();
|
||||
else
|
||||
*data << object->GetPositionZ();
|
||||
*data << object->GetOrientation();
|
||||
*data << object->GetStationaryX();
|
||||
*data << object->GetStationaryY();
|
||||
*data << object->GetStationaryZ();
|
||||
*data << object->GetStationaryO();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -473,7 +467,11 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
|
||||
// 0x2
|
||||
if (flags & UPDATEFLAG_TRANSPORT)
|
||||
{
|
||||
*data << uint32(getMSTime()); // Unknown - getMSTime is wrong.
|
||||
GameObject const* go = ToGameObject();
|
||||
if (go && go->IsTransport())
|
||||
*data << uint32(go->GetGOValue()->Transport.PathProgress);
|
||||
else
|
||||
*data << uint32(getMSTime());
|
||||
}
|
||||
|
||||
// 0x80
|
||||
|
||||
@@ -523,6 +523,35 @@ class FlaggedValuesArray32
|
||||
T_FLAGS m_flags;
|
||||
};
|
||||
|
||||
enum MapObjectCellMoveState
|
||||
{
|
||||
MAP_OBJECT_CELL_MOVE_NONE, //not in move list
|
||||
MAP_OBJECT_CELL_MOVE_ACTIVE, //in move list
|
||||
MAP_OBJECT_CELL_MOVE_INACTIVE, //in move list but should not move
|
||||
};
|
||||
|
||||
class MapObject
|
||||
{
|
||||
friend class Map; //map for moving creatures
|
||||
friend class ObjectGridLoader; //grid loader for loading creatures
|
||||
|
||||
protected:
|
||||
MapObject() : _moveState(MAP_OBJECT_CELL_MOVE_NONE) {}
|
||||
|
||||
private:
|
||||
Cell _currentCell;
|
||||
Cell const& GetCurrentCell() const { return _currentCell; }
|
||||
void SetCurrentCell(Cell const& cell) { _currentCell = cell; }
|
||||
|
||||
MapObjectCellMoveState _moveState;
|
||||
Position _newPosition;
|
||||
void SetNewCellPosition(float x, float y, float z, float o)
|
||||
{
|
||||
_moveState = MAP_OBJECT_CELL_MOVE_ACTIVE;
|
||||
_newPosition.Relocate(x, y, z, o);
|
||||
}
|
||||
};
|
||||
|
||||
class WorldObject : public Object, public WorldLocation
|
||||
{
|
||||
protected:
|
||||
@@ -700,16 +729,22 @@ class WorldObject : public Object, public WorldLocation
|
||||
|
||||
// Transports
|
||||
Transport* GetTransport() const { return m_transport; }
|
||||
virtual float GetTransOffsetX() const { return 0; }
|
||||
virtual float GetTransOffsetY() const { return 0; }
|
||||
virtual float GetTransOffsetZ() const { return 0; }
|
||||
virtual float GetTransOffsetO() const { return 0; }
|
||||
virtual uint32 GetTransTime() const { return 0; }
|
||||
virtual int8 GetTransSeat() const { return -1; }
|
||||
float GetTransOffsetX() const { return m_movementInfo.transport.pos.GetPositionX(); }
|
||||
float GetTransOffsetY() const { return m_movementInfo.transport.pos.GetPositionY(); }
|
||||
float GetTransOffsetZ() const { return m_movementInfo.transport.pos.GetPositionZ(); }
|
||||
float GetTransOffsetO() const { return m_movementInfo.transport.pos.GetOrientation(); }
|
||||
uint32 GetTransTime() const { return m_movementInfo.transport.time; }
|
||||
int8 GetTransSeat() const { return m_movementInfo.transport.seat; }
|
||||
virtual uint64 GetTransGUID() const;
|
||||
void SetTransport(Transport* t) { m_transport = t; }
|
||||
|
||||
MovementInfo m_movementInfo;
|
||||
|
||||
virtual float GetStationaryX() const { return GetPositionX(); }
|
||||
virtual float GetStationaryY() const { return GetPositionY(); }
|
||||
virtual float GetStationaryZ() const { return GetPositionZ(); }
|
||||
virtual float GetStationaryO() const { return GetOrientation(); }
|
||||
|
||||
protected:
|
||||
std::string m_name;
|
||||
bool m_isActive;
|
||||
@@ -739,7 +774,6 @@ class WorldObject : public Object, public WorldLocation
|
||||
|
||||
uint16 m_notifyflags;
|
||||
uint16 m_executed_notifies;
|
||||
|
||||
virtual bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const;
|
||||
|
||||
bool CanNeverSee(WorldObject const* obj) const;
|
||||
|
||||
@@ -17182,17 +17182,15 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
|
||||
}
|
||||
else
|
||||
{
|
||||
for (MapManager::TransportSet::iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
|
||||
if (GameObject* go = HashMapHolder<GameObject>::Find(m_movementInfo.transport.guid))
|
||||
m_transport = go->ToTransport();
|
||||
|
||||
if (m_transport)
|
||||
{
|
||||
if ((*iter)->GetGUIDLow() == transGUID)
|
||||
{
|
||||
m_transport = *iter;
|
||||
m_transport->AddPassenger(this);
|
||||
mapId = (m_transport->GetMapId());
|
||||
break;
|
||||
}
|
||||
m_transport->AddPassenger(this);
|
||||
mapId = m_transport->GetMapId();
|
||||
}
|
||||
if (!m_transport)
|
||||
else
|
||||
{
|
||||
TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player (guidlow %d) have problems with transport guid (%u). Teleport to bind location.",
|
||||
guid, transGUID);
|
||||
@@ -22165,7 +22163,7 @@ inline void UpdateVisibilityOf_helper(std::set<uint64>& s64, T* target, std::set
|
||||
template<>
|
||||
inline void UpdateVisibilityOf_helper(std::set<uint64>& s64, GameObject* target, std::set<Unit*>& /*v*/)
|
||||
{
|
||||
// Don't update only GAMEOBJECT_TYPE_TRANSPORT (or all transports and destructible buildings?)
|
||||
// @HACK: This is to prevent objects like deeprun tram from disappearing when player moves far from its spawn point while riding it
|
||||
if ((target->GetGOInfo()->type != GAMEOBJECT_TYPE_TRANSPORT))
|
||||
s64.insert(target->GetGUID());
|
||||
}
|
||||
@@ -22217,9 +22215,6 @@ void Player::UpdateVisibilityOf(WorldObject* target)
|
||||
{
|
||||
if (CanSeeOrDetect(target, false, true))
|
||||
{
|
||||
//if (target->isType(TYPEMASK_UNIT) && ((Unit*)target)->m_Vehicle)
|
||||
// UpdateVisibilityOf(((Unit*)target)->m_Vehicle);
|
||||
|
||||
target->SendUpdateToPlayer(this);
|
||||
m_clientGUIDs.insert(target->GetGUID());
|
||||
|
||||
@@ -22308,9 +22303,6 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& vi
|
||||
{
|
||||
if (CanSeeOrDetect(target, false, true))
|
||||
{
|
||||
//if (target->isType(TYPEMASK_UNIT) && ((Unit*)target)->m_Vehicle)
|
||||
// UpdateVisibilityOf(((Unit*)target)->m_Vehicle, data, visibleNow);
|
||||
|
||||
target->BuildCreateUpdateBlockForPlayer(&data, this);
|
||||
UpdateVisibilityOf_helper(m_clientGUIDs, target, visibleNow);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,34 +20,30 @@
|
||||
#define TRANSPORTS_H
|
||||
|
||||
#include "GameObject.h"
|
||||
#include "TransportMgr.h"
|
||||
#include "VehicleDefines.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
struct CreatureData;
|
||||
|
||||
class Transport : public GameObject, public TransportBase
|
||||
{
|
||||
friend Transport* TransportMgr::CreateTransport(uint32, uint32, Map*);
|
||||
|
||||
Transport();
|
||||
public:
|
||||
Transport(uint32 period, uint32 script);
|
||||
~Transport();
|
||||
|
||||
bool Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags);
|
||||
bool GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids);
|
||||
void Update(uint32 p_time);
|
||||
bool AddPassenger(Player* passenger);
|
||||
bool RemovePassenger(Player* passenger);
|
||||
bool Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress);
|
||||
void Update(uint32 diff);
|
||||
|
||||
void RemovePassenger(Creature* passenger) { m_NPCPassengerSet.erase(passenger); }
|
||||
void BuildUpdate(UpdateDataMapType& data_map);
|
||||
|
||||
typedef std::set<Player*> PlayerSet;
|
||||
PlayerSet const& GetPassengers() const { return m_passengers; }
|
||||
void AddPassenger(WorldObject* passenger);
|
||||
void RemovePassenger(WorldObject* passenger);
|
||||
std::set<WorldObject*> const& GetPassengers() const { return _passengers; }
|
||||
|
||||
typedef std::set<Creature*> CreatureSet;
|
||||
CreatureSet m_NPCPassengerSet;
|
||||
uint32 AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim=0);
|
||||
void UpdatePosition(MovementInfo* mi);
|
||||
void UpdatePassengerPositions();
|
||||
Creature* CreateNPCPassenger(uint32 guid, CreatureData const* data);
|
||||
GameObject* CreateGOPassenger(uint32 guid, GameObjectData const* data);
|
||||
|
||||
/// This method transforms supplied transport offsets into global coordinates
|
||||
void CalculatePassengerPosition(float& x, float& y, float& z, float* o = NULL) const;
|
||||
@@ -55,50 +51,48 @@ class Transport : public GameObject, public TransportBase
|
||||
/// This method transforms supplied global coordinates into local offsets
|
||||
void CalculatePassengerOffset(float& x, float& y, float& z, float* o = NULL) const;
|
||||
|
||||
void BuildStartMovePacket(Map const* targetMap);
|
||||
void BuildStopMovePacket(Map const* targetMap);
|
||||
uint32 GetScriptId() const { return ScriptId; }
|
||||
private:
|
||||
struct WayPoint
|
||||
{
|
||||
WayPoint() : mapid(0), x(0), y(0), z(0), teleport(false), id(0) {}
|
||||
WayPoint(uint32 _mapid, float _x, float _y, float _z, bool _teleport, uint32 _id = 0,
|
||||
uint32 _arrivalEventID = 0, uint32 _departureEventID = 0)
|
||||
: mapid(_mapid), x(_x), y(_y), z(_z), teleport(_teleport), id(_id),
|
||||
arrivalEventID(_arrivalEventID), departureEventID(_departureEventID)
|
||||
{
|
||||
}
|
||||
uint32 mapid;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
bool teleport;
|
||||
uint32 id;
|
||||
uint32 arrivalEventID;
|
||||
uint32 departureEventID;
|
||||
};
|
||||
uint32 GetPeriod() const { return GetUInt32Value(GAMEOBJECT_LEVEL); }
|
||||
void SetPeriod(uint32 period) { SetUInt32Value(GAMEOBJECT_LEVEL, period); }
|
||||
uint32 GetTimer() const { return GetGOValue()->Transport.PathProgress; }
|
||||
|
||||
typedef std::map<uint32, WayPoint> WayPointMap;
|
||||
KeyFrameVec const& GetKeyFrames() const { return _transportInfo->keyFrames; }
|
||||
|
||||
WayPointMap::const_iterator m_curr;
|
||||
WayPointMap::const_iterator m_next;
|
||||
uint32 m_pathTime;
|
||||
uint32 m_timer;
|
||||
void UpdatePosition(float x, float y, float z, float o);
|
||||
|
||||
PlayerSet m_passengers;
|
||||
//! Needed when transport moves from inactive to active grid
|
||||
void LoadStaticPassengers();
|
||||
|
||||
uint32 currenttguid;
|
||||
uint32 m_period;
|
||||
uint32 ScriptId;
|
||||
public:
|
||||
WayPointMap m_WayPoints;
|
||||
uint32 m_nextNodeTime;
|
||||
//! Needed when transport enters inactive grid
|
||||
void UnloadStaticPassengers();
|
||||
|
||||
void EnableMovement(bool enabled);
|
||||
|
||||
private:
|
||||
void MoveToNextWaypoint();
|
||||
float CalculateSegmentPos(float perc);
|
||||
void TeleportTransport(uint32 newMapid, float x, float y, float z);
|
||||
void UpdateForMap(Map const* map);
|
||||
void DoEventIfAny(WayPointMap::value_type const& node, bool departure);
|
||||
WayPointMap::const_iterator GetNextWayPoint();
|
||||
};
|
||||
#endif
|
||||
void UpdatePassengerPositions(std::set<WorldObject*>& passengers);
|
||||
void DoEventIfAny(KeyFrame const& node, bool departure);
|
||||
|
||||
//! Helpers to know if stop frame was reached
|
||||
bool IsMoving() const { return _isMoving; }
|
||||
void SetMoving(bool val) { _isMoving = val; }
|
||||
|
||||
TransportTemplate const* _transportInfo;
|
||||
|
||||
KeyFrameVec::const_iterator _currentFrame;
|
||||
KeyFrameVec::const_iterator _nextFrame;
|
||||
uint32 _moveTimer;
|
||||
TimeTrackerSmall _positionChangeTimer;
|
||||
bool _isMoving;
|
||||
bool _pendingStop;
|
||||
|
||||
//! These are needed to properly control events triggering only once for each frame
|
||||
bool _triggeredArrivalEvent;
|
||||
bool _triggeredDepartureEvent;
|
||||
|
||||
std::set<WorldObject*> _passengers;
|
||||
std::set<WorldObject*> _staticPassengers;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17329,6 +17329,8 @@ void Unit::SetFacingTo(float ori)
|
||||
{
|
||||
Movement::MoveSplineInit init(this);
|
||||
init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), false);
|
||||
if (HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && GetTransGUID())
|
||||
init.DisableTransportPathTransformations(); // It makes no sense to target global orientation
|
||||
init.SetFacing(ori);
|
||||
init.Launch();
|
||||
}
|
||||
@@ -17340,7 +17342,10 @@ void Unit::SetFacingToObject(WorldObject* object)
|
||||
return;
|
||||
|
||||
/// @todo figure out under what conditions creature will move towards object instead of facing it where it currently is.
|
||||
SetFacingTo(GetAngle(object));
|
||||
Movement::MoveSplineInit init(this);
|
||||
init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
|
||||
init.SetFacing(GetAngle(object)); // when on transport, GetAngle will still return global coordinates (and angle) that needs transforming
|
||||
init.Launch();
|
||||
}
|
||||
|
||||
bool Unit::SetWalk(bool enable)
|
||||
|
||||
@@ -2078,12 +2078,6 @@ class Unit : public WorldObject
|
||||
bool IsOnVehicle(const Unit* vehicle) const;
|
||||
Unit* GetVehicleBase() const;
|
||||
Creature* GetVehicleCreatureBase() const;
|
||||
float GetTransOffsetX() const { return m_movementInfo.transport.pos.GetPositionX(); }
|
||||
float GetTransOffsetY() const { return m_movementInfo.transport.pos.GetPositionY(); }
|
||||
float GetTransOffsetZ() const { return m_movementInfo.transport.pos.GetPositionZ(); }
|
||||
float GetTransOffsetO() const { return m_movementInfo.transport.pos.GetOrientation(); }
|
||||
uint32 GetTransTime() const { return m_movementInfo.transport.time; }
|
||||
int8 GetTransSeat() const { return m_movementInfo.transport.seat; }
|
||||
uint64 GetTransGUID() const;
|
||||
/// Returns the transport this unit is on directly (if on vehicle and transport, return vehicle)
|
||||
TransportBase* GetDirectTransport() const;
|
||||
|
||||
@@ -147,6 +147,15 @@ GameObject* ObjectAccessor::GetGameObject(WorldObject const& u, uint64 guid)
|
||||
return GetObjectInMap(guid, u.GetMap(), (GameObject*)NULL);
|
||||
}
|
||||
|
||||
Transport* ObjectAccessor::GetTransport(WorldObject const& u, uint64 guid)
|
||||
{
|
||||
if (GUID_HIPART(guid) != HIGHGUID_MO_TRANSPORT)
|
||||
return NULL;
|
||||
|
||||
GameObject* go = GetGameObject(u, guid);
|
||||
return go ? go->ToTransport() : NULL;
|
||||
}
|
||||
|
||||
DynamicObject* ObjectAccessor::GetDynamicObject(WorldObject const& u, uint64 guid)
|
||||
{
|
||||
return GetObjectInMap(guid, u.GetMap(), (DynamicObject*)NULL);
|
||||
|
||||
@@ -40,6 +40,7 @@ class WorldObject;
|
||||
class Vehicle;
|
||||
class Map;
|
||||
class WorldRunnable;
|
||||
class Transport;
|
||||
|
||||
template <class T>
|
||||
class HashMapHolder
|
||||
@@ -145,6 +146,7 @@ class ObjectAccessor
|
||||
static Object* GetObjectByTypeMask(WorldObject const&, uint64, uint32 typemask);
|
||||
static Corpse* GetCorpse(WorldObject const& u, uint64 guid);
|
||||
static GameObject* GetGameObject(WorldObject const& u, uint64 guid);
|
||||
static Transport* GetTransport(WorldObject const& u, uint64 guid);
|
||||
static DynamicObject* GetDynamicObject(WorldObject const& u, uint64 guid);
|
||||
static Unit* GetUnit(WorldObject const&, uint64 guid);
|
||||
static Creature* GetCreature(WorldObject const& u, uint64 guid);
|
||||
|
||||
@@ -1019,6 +1019,11 @@ class ObjectMgr
|
||||
return _mapObjectGuidsStore[MAKE_PAIR32(mapid, spawnMode)][cell_id];
|
||||
}
|
||||
|
||||
CellObjectGuidsMap const& GetMapObjectGuids(uint16 mapid, uint8 spawnMode)
|
||||
{
|
||||
return _mapObjectGuidsStore[MAKE_PAIR32(mapid, spawnMode)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets temp summon data for all creatures of specified group.
|
||||
*
|
||||
|
||||
@@ -35,16 +35,26 @@ void VisibleNotifier::SendToSelf()
|
||||
// at this moment i_clientGUIDs have guids that not iterate at grid level checks
|
||||
// but exist one case when this possible and object not out of range: transports
|
||||
if (Transport* transport = i_player.GetTransport())
|
||||
for (Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin();itr != transport->GetPassengers().end();++itr)
|
||||
for (std::set<WorldObject*>::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end();++itr)
|
||||
{
|
||||
if (vis_guids.find((*itr)->GetGUID()) != vis_guids.end())
|
||||
{
|
||||
vis_guids.erase((*itr)->GetGUID());
|
||||
|
||||
i_player.UpdateVisibilityOf((*itr), i_data, i_visibleNow);
|
||||
|
||||
if (!(*itr)->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
|
||||
(*itr)->UpdateVisibilityOf(&i_player);
|
||||
switch ((*itr)->GetTypeId())
|
||||
{
|
||||
case TYPEID_GAMEOBJECT:
|
||||
i_player.UpdateVisibilityOf((*itr)->ToGameObject(), i_data, i_visibleNow);
|
||||
break;
|
||||
case TYPEID_PLAYER:
|
||||
i_player.UpdateVisibilityOf((*itr)->ToPlayer(), i_data, i_visibleNow);
|
||||
if (!(*itr)->isNeedNotify(NOTIFY_VISIBILITY_CHANGED))
|
||||
(*itr)->ToPlayer()->UpdateVisibilityOf(&i_player);
|
||||
break;
|
||||
case TYPEID_UNIT:
|
||||
i_player.UpdateVisibilityOf((*itr)->ToCreature(), i_data, i_visibleNow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,10 +334,8 @@ template<class T>
|
||||
void ObjectUpdater::Visit(GridRefManager<T> &m)
|
||||
{
|
||||
for (typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
if (iter->GetSource()->IsInWorld())
|
||||
iter->GetSource()->Update(i_timeDiff);
|
||||
}
|
||||
}
|
||||
|
||||
bool AnyDeadUnitObjectInRangeCheck::operator()(Player* u)
|
||||
@@ -360,5 +368,6 @@ bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Creature* u)
|
||||
return AnyDeadUnitObjectInRangeCheck::operator()(u) && i_check(u);
|
||||
}
|
||||
|
||||
template void ObjectUpdater::Visit<GameObject>(GameObjectMapType &);
|
||||
template void ObjectUpdater::Visit<DynamicObject>(DynamicObjectMapType &);
|
||||
template void ObjectUpdater::Visit<Creature>(CreatureMapType&);
|
||||
template void ObjectUpdater::Visit<GameObject>(GameObjectMapType&);
|
||||
template void ObjectUpdater::Visit<DynamicObject>(DynamicObjectMapType&);
|
||||
|
||||
@@ -43,6 +43,20 @@ void ObjectGridEvacuator::Visit(CreatureMapType &m)
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectGridEvacuator::Visit(GameObjectMapType &m)
|
||||
{
|
||||
// gameobject in unloading grid can have respawn point in another grid
|
||||
// if it will be unloaded then it will not respawn in original grid until unload/load original grid
|
||||
// move to respawn point to prevent this case. For player view in respawn grid this will be normal respawn.
|
||||
for (GameObjectMapType::iterator iter = m.begin(); iter != m.end();)
|
||||
{
|
||||
GameObject* go = iter->GetSource();
|
||||
++iter;
|
||||
|
||||
go->GetMap()->GameObjectRespawnRelocation(go, true);
|
||||
}
|
||||
}
|
||||
|
||||
// for loading world object at grid loading (Corpses)
|
||||
/// @todo to implement npc on transport, also need to load npcs at grid loading
|
||||
class ObjectWorldLoader
|
||||
@@ -70,7 +84,12 @@ template<class T> void ObjectGridLoader::SetObjectCell(T* /*obj*/, CellCoord con
|
||||
template<> void ObjectGridLoader::SetObjectCell(Creature* obj, CellCoord const& cellCoord)
|
||||
{
|
||||
Cell cell(cellCoord);
|
||||
obj->SetCurrentCell(cell);
|
||||
}
|
||||
|
||||
template<> void ObjectGridLoader::SetObjectCell(GameObject* obj, CellCoord const& cellCoord)
|
||||
{
|
||||
Cell cell(cellCoord);
|
||||
obj->SetCurrentCell(cell);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ class ObjectGridEvacuator
|
||||
{
|
||||
public:
|
||||
void Visit(CreatureMapType &m);
|
||||
void Visit(GameObjectMapType &m);
|
||||
template<class T> void Visit(GridRefManager<T> &) {}
|
||||
};
|
||||
|
||||
|
||||
@@ -303,30 +303,21 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
|
||||
{
|
||||
if (!plrMover->GetTransport())
|
||||
{
|
||||
// elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list
|
||||
for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
|
||||
if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid))
|
||||
{
|
||||
if ((*iter)->GetGUID() == movementInfo.transport.guid)
|
||||
{
|
||||
plrMover->m_transport = *iter;
|
||||
(*iter)->AddPassenger(plrMover);
|
||||
break;
|
||||
}
|
||||
plrMover->m_transport = transport;
|
||||
transport->AddPassenger(plrMover);
|
||||
}
|
||||
}
|
||||
else if (plrMover->GetTransport()->GetGUID() != movementInfo.transport.guid)
|
||||
{
|
||||
bool foundNewTransport = false;
|
||||
plrMover->m_transport->RemovePassenger(plrMover);
|
||||
for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
|
||||
if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid))
|
||||
{
|
||||
if ((*iter)->GetGUID() == movementInfo.transport.guid)
|
||||
{
|
||||
foundNewTransport = true;
|
||||
plrMover->m_transport = *iter;
|
||||
(*iter)->AddPassenger(plrMover);
|
||||
break;
|
||||
}
|
||||
foundNewTransport = true;
|
||||
plrMover->m_transport = transport;
|
||||
transport->AddPassenger(plrMover);
|
||||
}
|
||||
|
||||
if (!foundNewTransport)
|
||||
|
||||
+348
-41
@@ -217,10 +217,12 @@ void Map::DeleteStateMachine()
|
||||
}
|
||||
|
||||
Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent):
|
||||
_creatureToMoveLock(false), i_mapEntry (sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), i_InstanceId(InstanceId),
|
||||
_creatureToMoveLock(false), _gameObjectsToMoveLock(false),
|
||||
i_mapEntry(sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), i_InstanceId(InstanceId),
|
||||
m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE),
|
||||
m_VisibilityNotifyPeriod(DEFAULT_VISIBILITY_NOTIFY_PERIOD),
|
||||
m_activeNonPlayersIter(m_activeNonPlayers.end()), i_gridExpiry(expiry),
|
||||
m_activeNonPlayersIter(m_activeNonPlayers.end()), _transportsUpdateIter(_transports.end()),
|
||||
i_gridExpiry(expiry),
|
||||
i_scriptLock(false)
|
||||
{
|
||||
m_parentMap = (_parent ? _parent : this);
|
||||
@@ -270,6 +272,21 @@ void Map::AddToGrid(Creature* obj, Cell const& cell)
|
||||
obj->SetCurrentCell(cell);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Map::AddToGrid(GameObject* obj, Cell const& cell)
|
||||
{
|
||||
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
|
||||
grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj);
|
||||
|
||||
obj->SetCurrentCell(cell);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Map::SwitchGridContainers(T* /*obj*/, bool /*on*/)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void Map::SwitchGridContainers(Creature* obj, bool on)
|
||||
{
|
||||
ASSERT(!obj->IsPermanentWorldObject());
|
||||
@@ -291,6 +308,7 @@ void Map::SwitchGridContainers(Creature* obj, bool on)
|
||||
GridType &grid = ngrid->GetGridType(cell.CellX(), cell.CellY());
|
||||
|
||||
obj->RemoveFromGrid(); //This step is not really necessary but we want to do ASSERT in remove/add
|
||||
|
||||
if (on)
|
||||
{
|
||||
grid.AddWorldObject(obj);
|
||||
@@ -301,9 +319,45 @@ void Map::SwitchGridContainers(Creature* obj, bool on)
|
||||
grid.AddGridObject(obj);
|
||||
RemoveWorldObject(obj);
|
||||
}
|
||||
|
||||
obj->m_isTempWorldObject = on;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Map::SwitchGridContainers(GameObject* obj, bool on)
|
||||
{
|
||||
ASSERT(!obj->IsPermanentWorldObject());
|
||||
CellCoord p = Trinity::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
|
||||
if (!p.IsCoordValid())
|
||||
{
|
||||
TC_LOG_ERROR(LOG_FILTER_MAPS, "Map::SwitchGridContainers: Object " UI64FMTD " has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
|
||||
return;
|
||||
}
|
||||
|
||||
Cell cell(p);
|
||||
if (!IsGridLoaded(GridCoord(cell.data.Part.grid_x, cell.data.Part.grid_y)))
|
||||
return;
|
||||
|
||||
TC_LOG_DEBUG(LOG_FILTER_MAPS, "Switch object " UI64FMTD " from grid[%u, %u] %u", obj->GetGUID(), cell.data.Part.grid_x, cell.data.Part.grid_y, on);
|
||||
NGridType *ngrid = getNGrid(cell.GridX(), cell.GridY());
|
||||
ASSERT(ngrid != NULL);
|
||||
|
||||
GridType &grid = ngrid->GetGridType(cell.CellX(), cell.CellY());
|
||||
|
||||
obj->RemoveFromGrid(); //This step is not really necessary but we want to do ASSERT in remove/add
|
||||
|
||||
if (on)
|
||||
{
|
||||
grid.AddWorldObject(obj);
|
||||
AddWorldObject(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
grid.AddGridObject(obj);
|
||||
RemoveWorldObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Map::DeleteFromWorld(T* obj)
|
||||
{
|
||||
@@ -432,11 +486,17 @@ void Map::InitializeObject(T* /*obj*/)
|
||||
template<>
|
||||
void Map::InitializeObject(Creature* obj)
|
||||
{
|
||||
obj->_moveState = CREATURE_CELL_MOVE_NONE;
|
||||
obj->_moveState = MAP_OBJECT_CELL_MOVE_NONE;
|
||||
}
|
||||
|
||||
template<>
|
||||
void Map::InitializeObject(GameObject* obj)
|
||||
{
|
||||
obj->_moveState = MAP_OBJECT_CELL_MOVE_NONE;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool Map::AddToMap(T *obj)
|
||||
bool Map::AddToMap(T* obj)
|
||||
{
|
||||
/// @todo Needs clean up. An object should not be added to map twice.
|
||||
if (obj->IsInWorld())
|
||||
@@ -480,6 +540,26 @@ bool Map::AddToMap(T *obj)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Map::AddToMap(Transport* obj)
|
||||
{
|
||||
//TODO: Needs clean up. An object should not be added to map twice.
|
||||
if (obj->IsInWorld())
|
||||
return true;
|
||||
|
||||
CellCoord cellCoord = Trinity::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
|
||||
if (!cellCoord.IsCoordValid())
|
||||
{
|
||||
TC_LOG_ERROR(LOG_FILTER_MAPS, "Map::Add: Object " UI64FMTD " has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), cellCoord.x_coord, cellCoord.y_coord);
|
||||
return false; //Should delete object
|
||||
}
|
||||
|
||||
obj->AddToWorld();
|
||||
_transports.insert(obj);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Map::IsGridLoaded(const GridCoord &p) const
|
||||
{
|
||||
return (getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord));
|
||||
@@ -565,6 +645,17 @@ void Map::Update(const uint32 t_diff)
|
||||
VisitNearbyCellsOf(obj, grid_object_update, world_object_update);
|
||||
}
|
||||
|
||||
for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();)
|
||||
{
|
||||
WorldObject* obj = *_transportsUpdateIter;
|
||||
++_transportsUpdateIter;
|
||||
|
||||
if (!obj->IsInWorld())
|
||||
continue;
|
||||
|
||||
obj->Update(t_diff);
|
||||
}
|
||||
|
||||
///- Process necessary scripts
|
||||
if (!m_scriptSchedule.empty())
|
||||
{
|
||||
@@ -574,6 +665,7 @@ void Map::Update(const uint32 t_diff)
|
||||
}
|
||||
|
||||
MoveAllCreaturesInMoveList();
|
||||
MoveAllGameObjectsInMoveList();
|
||||
|
||||
if (!m_mapRefManager.isEmpty() || !m_activeNonPlayers.empty())
|
||||
ProcessRelocationNotifies(t_diff);
|
||||
@@ -708,6 +800,34 @@ void Map::RemoveFromMap(T *obj, bool remove)
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void Map::RemoveFromMap(Transport* obj, bool remove)
|
||||
{
|
||||
obj->RemoveFromWorld();
|
||||
|
||||
if (_transportsUpdateIter != _transports.end())
|
||||
{
|
||||
TransportsContainer::iterator itr = _transports.find(obj);
|
||||
if (itr == _transports.end())
|
||||
return;
|
||||
if (itr == _transportsUpdateIter)
|
||||
++_transportsUpdateIter;
|
||||
_transports.erase(itr);
|
||||
}
|
||||
else
|
||||
_transports.erase(obj);
|
||||
|
||||
obj->ResetMap();
|
||||
|
||||
if (remove)
|
||||
{
|
||||
// if option set then object already saved at this moment
|
||||
if (!sWorld->getBoolConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY))
|
||||
obj->SaveRespawnTime();
|
||||
DeleteFromWorld(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void Map::PlayerRelocation(Player* player, float x, float y, float z, float orientation)
|
||||
{
|
||||
ASSERT(player);
|
||||
@@ -777,12 +897,44 @@ void Map::CreatureRelocation(Creature* creature, float x, float y, float z, floa
|
||||
ASSERT(CheckGridIntegrity(creature, true));
|
||||
}
|
||||
|
||||
void Map::GameObjectRelocation(GameObject* go, float x, float y, float z, float orientation, bool respawnRelocationOnFail)
|
||||
{
|
||||
Cell integrity_check(go->GetPositionX(), go->GetPositionY());
|
||||
Cell old_cell = go->GetCurrentCell();
|
||||
|
||||
ASSERT(integrity_check == old_cell);
|
||||
Cell new_cell(x, y);
|
||||
|
||||
if (!respawnRelocationOnFail && !getNGrid(new_cell.GridX(), new_cell.GridY()))
|
||||
return;
|
||||
|
||||
// delay creature move for grid/cell to grid/cell moves
|
||||
if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell))
|
||||
{
|
||||
#ifdef TRINITY_DEBUG
|
||||
TC_LOG_DEBUG(LOG_FILTER_MAPS, "GameObject (GUID: %u Entry: %u) added to moving list from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
|
||||
#endif
|
||||
AddGameObjectToMoveList(go, x, y, z, orientation);
|
||||
// in diffcell/diffgrid case notifiers called at finishing move go in Map::MoveAllGameObjectsInMoveList
|
||||
}
|
||||
else
|
||||
{
|
||||
go->Relocate(x, y, z, orientation);
|
||||
go->UpdateObjectVisibility(false);
|
||||
RemoveGameObjectFromMoveList(go);
|
||||
}
|
||||
|
||||
old_cell = go->GetCurrentCell();
|
||||
integrity_check = Cell(go->GetPositionX(), go->GetPositionY());
|
||||
ASSERT(integrity_check == old_cell);
|
||||
}
|
||||
|
||||
void Map::AddCreatureToMoveList(Creature* c, float x, float y, float z, float ang)
|
||||
{
|
||||
if (_creatureToMoveLock) //can this happen?
|
||||
return;
|
||||
|
||||
if (c->_moveState == CREATURE_CELL_MOVE_NONE)
|
||||
if (c->_moveState == MAP_OBJECT_CELL_MOVE_NONE)
|
||||
_creaturesToMove.push_back(c);
|
||||
c->SetNewCellPosition(x, y, z, ang);
|
||||
}
|
||||
@@ -792,8 +944,27 @@ void Map::RemoveCreatureFromMoveList(Creature* c)
|
||||
if (_creatureToMoveLock) //can this happen?
|
||||
return;
|
||||
|
||||
if (c->_moveState == CREATURE_CELL_MOVE_ACTIVE)
|
||||
c->_moveState = CREATURE_CELL_MOVE_INACTIVE;
|
||||
if (c->_moveState == MAP_OBJECT_CELL_MOVE_ACTIVE)
|
||||
c->_moveState = MAP_OBJECT_CELL_MOVE_INACTIVE;
|
||||
}
|
||||
|
||||
void Map::AddGameObjectToMoveList(GameObject* go, float x, float y, float z, float ang)
|
||||
{
|
||||
if (_gameObjectsToMoveLock) //can this happen?
|
||||
return;
|
||||
|
||||
if (go->_moveState == MAP_OBJECT_CELL_MOVE_NONE)
|
||||
_gameObjectsToMove.push_back(go);
|
||||
go->SetNewCellPosition(x, y, z, ang);
|
||||
}
|
||||
|
||||
void Map::RemoveGameObjectFromMoveList(GameObject* go)
|
||||
{
|
||||
if (_gameObjectsToMoveLock) //can this happen?
|
||||
return;
|
||||
|
||||
if (go->_moveState == MAP_OBJECT_CELL_MOVE_ACTIVE)
|
||||
go->_moveState = MAP_OBJECT_CELL_MOVE_INACTIVE;
|
||||
}
|
||||
|
||||
void Map::MoveAllCreaturesInMoveList()
|
||||
@@ -805,13 +976,13 @@ void Map::MoveAllCreaturesInMoveList()
|
||||
if (c->FindMap() != this) //pet is teleported to another map
|
||||
continue;
|
||||
|
||||
if (c->_moveState != CREATURE_CELL_MOVE_ACTIVE)
|
||||
if (c->_moveState != MAP_OBJECT_CELL_MOVE_ACTIVE)
|
||||
{
|
||||
c->_moveState = CREATURE_CELL_MOVE_NONE;
|
||||
c->_moveState = MAP_OBJECT_CELL_MOVE_NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
c->_moveState = CREATURE_CELL_MOVE_NONE;
|
||||
c->_moveState = MAP_OBJECT_CELL_MOVE_NONE;
|
||||
if (!c->IsInWorld())
|
||||
continue;
|
||||
|
||||
@@ -852,6 +1023,50 @@ void Map::MoveAllCreaturesInMoveList()
|
||||
_creatureToMoveLock = false;
|
||||
}
|
||||
|
||||
void Map::MoveAllGameObjectsInMoveList()
|
||||
{
|
||||
_gameObjectsToMoveLock = true;
|
||||
for (std::vector<GameObject*>::iterator itr = _gameObjectsToMove.begin(); itr != _gameObjectsToMove.end(); ++itr)
|
||||
{
|
||||
GameObject* go = *itr;
|
||||
if (go->FindMap() != this) //transport is teleported to another map
|
||||
continue;
|
||||
|
||||
if (go->_moveState != MAP_OBJECT_CELL_MOVE_ACTIVE)
|
||||
{
|
||||
go->_moveState = MAP_OBJECT_CELL_MOVE_NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
go->_moveState = MAP_OBJECT_CELL_MOVE_NONE;
|
||||
if (!go->IsInWorld())
|
||||
continue;
|
||||
|
||||
// do move or do move to respawn or remove creature if previous all fail
|
||||
if (GameObjectCellRelocation(go, Cell(go->_newPosition.m_positionX, go->_newPosition.m_positionY)))
|
||||
{
|
||||
// update pos
|
||||
go->Relocate(go->_newPosition);
|
||||
go->UpdateObjectVisibility(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if GameObject can't be move in new cell/grid (not loaded) move it to repawn cell/grid
|
||||
// GameObject coordinates will be updated and notifiers send
|
||||
if (!GameObjectRespawnRelocation(go, false))
|
||||
{
|
||||
// ... or unload (if respawn grid also not loaded)
|
||||
#ifdef TRINITY_DEBUG
|
||||
sLog->outDebug(LOG_FILTER_MAPS, "GameObject (GUID: %u Entry: %u) cannot be move to unloaded respawn grid.", go->GetGUIDLow(), go->GetEntry());
|
||||
#endif
|
||||
AddObjectToRemoveList(go);
|
||||
}
|
||||
}
|
||||
}
|
||||
_gameObjectsToMove.clear();
|
||||
_gameObjectsToMoveLock = false;
|
||||
}
|
||||
|
||||
bool Map::CreatureCellRelocation(Creature* c, Cell new_cell)
|
||||
{
|
||||
Cell const& old_cell = c->GetCurrentCell();
|
||||
@@ -913,6 +1128,67 @@ bool Map::CreatureCellRelocation(Creature* c, Cell new_cell)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Map::GameObjectCellRelocation(GameObject* go, Cell new_cell)
|
||||
{
|
||||
Cell const& old_cell = go->GetCurrentCell();
|
||||
if (!old_cell.DiffGrid(new_cell)) // in same grid
|
||||
{
|
||||
// if in same cell then none do
|
||||
if (old_cell.DiffCell(new_cell))
|
||||
{
|
||||
#ifdef TRINITY_DEBUG
|
||||
TC_LOG_DEBUG(LOG_FILTER_MAPS, "GameObject (GUID: %u Entry: %u) moved in grid[%u, %u] from cell[%u, %u] to cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY());
|
||||
#endif
|
||||
|
||||
go->RemoveFromGrid();
|
||||
AddToGrid(go, new_cell);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef TRINITY_DEBUG
|
||||
TC_LOG_DEBUG(LOG_FILTER_MAPS, "GameObject (GUID: %u Entry: %u) moved in same grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY());
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// in diff. grids but active GameObject
|
||||
if (go->isActiveObject())
|
||||
{
|
||||
EnsureGridLoadedForActiveObject(new_cell, go);
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
TC_LOG_DEBUG(LOG_FILTER_MAPS, "Active GameObject (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
|
||||
#endif
|
||||
|
||||
go->RemoveFromGrid();
|
||||
AddToGrid(go, new_cell);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// in diff. loaded grid normal GameObject
|
||||
if (IsGridLoaded(GridCoord(new_cell.GridX(), new_cell.GridY())))
|
||||
{
|
||||
#ifdef TRINITY_DEBUG
|
||||
TC_LOG_DEBUG(LOG_FILTER_MAPS, "GameObject (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
|
||||
#endif
|
||||
|
||||
go->RemoveFromGrid();
|
||||
EnsureGridCreated(GridCoord(new_cell.GridX(), new_cell.GridY()));
|
||||
AddToGrid(go, new_cell);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// fail to move: normal GameObject attempt move to unloaded grid
|
||||
#ifdef TRINITY_DEBUG
|
||||
TC_LOG_DEBUG(LOG_FILTER_MAPS, "GameObject (GUID: %u Entry: %u) attempted to move from grid[%u, %u]cell[%u, %u] to unloaded grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Map::CreatureRespawnRelocation(Creature* c, bool diffGridOnly)
|
||||
{
|
||||
float resp_x, resp_y, resp_z, resp_o;
|
||||
@@ -943,6 +1219,31 @@ bool Map::CreatureRespawnRelocation(Creature* c, bool diffGridOnly)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Map::GameObjectRespawnRelocation(GameObject* go, bool diffGridOnly)
|
||||
{
|
||||
float resp_x, resp_y, resp_z, resp_o;
|
||||
go->GetRespawnPosition(resp_x, resp_y, resp_z, &resp_o);
|
||||
Cell resp_cell(resp_x, resp_y);
|
||||
|
||||
//GameObject will be unloaded with grid
|
||||
if (diffGridOnly && !go->GetCurrentCell().DiffGrid(resp_cell))
|
||||
return true;
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
TC_LOG_DEBUG(LOG_FILTER_MAPS, "GameObject (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to respawn grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), go->GetCurrentCell().GridX(), go->GetCurrentCell().GridY(), go->GetCurrentCell().CellX(), go->GetCurrentCell().CellY(), resp_cell.GridX(), resp_cell.GridY(), resp_cell.CellX(), resp_cell.CellY());
|
||||
#endif
|
||||
|
||||
// teleport it to respawn point (like normal respawn if player see)
|
||||
if (GameObjectCellRelocation(go, resp_cell))
|
||||
{
|
||||
go->Relocate(resp_x, resp_y, resp_z, resp_o);
|
||||
go->UpdateObjectVisibility(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll)
|
||||
{
|
||||
const uint32 x = ngrid.getX();
|
||||
@@ -966,6 +1267,7 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll)
|
||||
// Finish creature moves, remove and delete all creatures with delayed remove before moving to respawn grids
|
||||
// Must know real mob position before move
|
||||
MoveAllCreaturesInMoveList();
|
||||
MoveAllGameObjectsInMoveList();
|
||||
|
||||
// move creatures to respawn grids if this is diff.grid or to remove list
|
||||
ObjectGridEvacuator worker;
|
||||
@@ -974,6 +1276,7 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll)
|
||||
|
||||
// Finish creature moves, remove and delete all creatures with delayed remove before unload
|
||||
MoveAllCreaturesInMoveList();
|
||||
MoveAllGameObjectsInMoveList();
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1041,6 +1344,7 @@ void Map::UnloadAll()
|
||||
{
|
||||
// clear all delayed moves, useless anyway do this moves before map unload.
|
||||
_creaturesToMove.clear();
|
||||
_gameObjectsToMove.clear();
|
||||
|
||||
for (GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end();)
|
||||
{
|
||||
@@ -2008,7 +2312,7 @@ void Map::SendInitSelf(Player* player)
|
||||
// build other passengers at transport also (they always visible and marked as visible and will not send at visibility update at add to map
|
||||
if (Transport* transport = player->GetTransport())
|
||||
{
|
||||
for (Transport::PlayerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr)
|
||||
for (std::set<WorldObject*>::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr)
|
||||
{
|
||||
if (player != (*itr) && player->HaveAtClient(*itr))
|
||||
{
|
||||
@@ -2025,24 +2329,10 @@ void Map::SendInitSelf(Player* player)
|
||||
void Map::SendInitTransports(Player* player)
|
||||
{
|
||||
// Hack to send out transports
|
||||
MapManager::TransportMap& tmap = sMapMgr->m_TransportsByMap;
|
||||
|
||||
// no transports at map
|
||||
if (tmap.find(player->GetMapId()) == tmap.end())
|
||||
return;
|
||||
|
||||
UpdateData transData;
|
||||
|
||||
MapManager::TransportSet& tset = tmap[player->GetMapId()];
|
||||
|
||||
for (MapManager::TransportSet::const_iterator i = tset.begin(); i != tset.end(); ++i)
|
||||
{
|
||||
// send data for current transport in other place
|
||||
if ((*i) != player->GetTransport() && (*i)->GetMapId() == GetId())
|
||||
{
|
||||
for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i)
|
||||
if (*i != player->GetTransport())
|
||||
(*i)->BuildCreateUpdateBlockForPlayer(&transData, player);
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket packet;
|
||||
transData.BuildPacket(&packet);
|
||||
@@ -2052,19 +2342,9 @@ void Map::SendInitTransports(Player* player)
|
||||
void Map::SendRemoveTransports(Player* player)
|
||||
{
|
||||
// Hack to send out transports
|
||||
MapManager::TransportMap& tmap = sMapMgr->m_TransportsByMap;
|
||||
|
||||
// no transports at map
|
||||
if (tmap.find(player->GetMapId()) == tmap.end())
|
||||
return;
|
||||
|
||||
UpdateData transData;
|
||||
|
||||
MapManager::TransportSet& tset = tmap[player->GetMapId()];
|
||||
|
||||
// except used transport
|
||||
for (MapManager::TransportSet::const_iterator i = tset.begin(); i != tset.end(); ++i)
|
||||
if ((*i) != player->GetTransport() && (*i)->GetMapId() != GetId())
|
||||
for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i)
|
||||
if (*i != player->GetTransport())
|
||||
(*i)->BuildOutOfRangeUpdateBlock(&transData);
|
||||
|
||||
WorldPacket packet;
|
||||
@@ -2137,8 +2417,8 @@ void Map::RemoveAllObjectsInRemoveList()
|
||||
bool on = itr->second;
|
||||
i_objectsToSwitch.erase(itr);
|
||||
|
||||
if (obj->GetTypeId() == TYPEID_UNIT && !obj->IsPermanentWorldObject())
|
||||
SwitchGridContainers(obj->ToCreature(), on);
|
||||
if (obj->GetTypeId() == TYPEID_UNIT || obj->GetTypeId() == TYPEID_GAMEOBJECT && !obj->IsPermanentWorldObject())
|
||||
SwitchGridContainers(obj, on);
|
||||
}
|
||||
|
||||
//TC_LOG_DEBUG(LOG_FILTER_MAPS, "Object remover 1 check.");
|
||||
@@ -2233,6 +2513,13 @@ bool Map::ActiveObjectsNearGrid(NGridType const& ngrid) const
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Map::AddToActive(T* obj)
|
||||
{
|
||||
AddToActiveHelper(obj);
|
||||
}
|
||||
|
||||
template <>
|
||||
void Map::AddToActive(Creature* c)
|
||||
{
|
||||
AddToActiveHelper(c);
|
||||
@@ -2254,6 +2541,13 @@ void Map::AddToActive(Creature* c)
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Map::RemoveFromActive(T* obj)
|
||||
{
|
||||
RemoveFromActiveHelper(obj);
|
||||
}
|
||||
|
||||
template <>
|
||||
void Map::RemoveFromActive(Creature* c)
|
||||
{
|
||||
RemoveFromActiveHelper(c);
|
||||
@@ -2285,6 +2579,10 @@ template void Map::RemoveFromMap(Creature*, bool);
|
||||
template void Map::RemoveFromMap(GameObject*, bool);
|
||||
template void Map::RemoveFromMap(DynamicObject*, bool);
|
||||
|
||||
template void Map::AddToActive(DynamicObject*);
|
||||
|
||||
template void Map::RemoveFromActive(DynamicObject*);
|
||||
|
||||
/* ******* Dungeon Instance Maps ******* */
|
||||
|
||||
InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent)
|
||||
@@ -2772,6 +3070,15 @@ GameObject* Map::GetGameObject(uint64 guid)
|
||||
return ObjectAccessor::GetObjectInMap(guid, this, (GameObject*)NULL);
|
||||
}
|
||||
|
||||
Transport* Map::GetTransport(uint64 guid)
|
||||
{
|
||||
if (GUID_HIPART(guid) != HIGHGUID_MO_TRANSPORT)
|
||||
return NULL;
|
||||
|
||||
GameObject* go = GetGameObject(guid);
|
||||
return go ? go->ToTransport() : NULL;
|
||||
}
|
||||
|
||||
DynamicObject* Map::GetDynamicObject(uint64 guid)
|
||||
{
|
||||
return ObjectAccessor::GetObjectInMap(guid, this, (DynamicObject*)NULL);
|
||||
|
||||
+24
-15
@@ -52,6 +52,7 @@ struct Position;
|
||||
class Battleground;
|
||||
class MapInstanced;
|
||||
class InstanceMap;
|
||||
class Transport;
|
||||
namespace Trinity { struct ObjectUpdater; }
|
||||
|
||||
struct ScriptAction
|
||||
@@ -278,6 +279,7 @@ class Map : public GridRefManager<NGridType>
|
||||
|
||||
void PlayerRelocation(Player*, float x, float y, float z, float orientation);
|
||||
void CreatureRelocation(Creature* creature, float x, float y, float z, float ang, bool respawnRelocationOnFail = true);
|
||||
void GameObjectRelocation(GameObject* go, float x, float y, float z, float orientation, bool respawnRelocationOnFail = true);
|
||||
|
||||
template<class T, class CONTAINER> void Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER> &visitor);
|
||||
|
||||
@@ -350,11 +352,13 @@ class Map : public GridRefManager<NGridType>
|
||||
}
|
||||
|
||||
void MoveAllCreaturesInMoveList();
|
||||
void MoveAllGameObjectsInMoveList();
|
||||
void RemoveAllObjectsInRemoveList();
|
||||
virtual void RemoveAllPlayers();
|
||||
|
||||
// used only in MoveAllCreaturesInMoveList and ObjectGridUnloader
|
||||
bool CreatureRespawnRelocation(Creature* c, bool diffGridOnly);
|
||||
bool GameObjectRespawnRelocation(GameObject* go, bool diffGridOnly);
|
||||
|
||||
// assert print helper
|
||||
bool CheckGridIntegrity(Creature* c, bool moved) const;
|
||||
@@ -415,17 +419,13 @@ class Map : public GridRefManager<NGridType>
|
||||
|
||||
// must called with AddToWorld
|
||||
template<class T>
|
||||
void AddToActive(T* obj) { AddToActiveHelper(obj); }
|
||||
|
||||
void AddToActive(Creature* obj);
|
||||
void AddToActive(T* obj);
|
||||
|
||||
// must called with RemoveFromWorld
|
||||
template<class T>
|
||||
void RemoveFromActive(T* obj) { RemoveFromActiveHelper(obj); }
|
||||
void RemoveFromActive(T* obj);
|
||||
|
||||
void RemoveFromActive(Creature* obj);
|
||||
|
||||
void SwitchGridContainers(Creature* creature, bool toWorldContainer);
|
||||
template<class T> void SwitchGridContainers(T* obj, bool on);
|
||||
template<class NOTIFIER> void VisitAll(const float &x, const float &y, float radius, NOTIFIER ¬ifier);
|
||||
template<class NOTIFIER> void VisitFirstFound(const float &x, const float &y, float radius, NOTIFIER ¬ifier);
|
||||
template<class NOTIFIER> void VisitWorld(const float &x, const float &y, float radius, NOTIFIER ¬ifier);
|
||||
@@ -438,6 +438,7 @@ class Map : public GridRefManager<NGridType>
|
||||
void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = NULL);
|
||||
Creature* GetCreature(uint64 guid);
|
||||
GameObject* GetGameObject(uint64 guid);
|
||||
Transport* GetTransport(uint64 guid);
|
||||
DynamicObject* GetDynamicObject(uint64 guid);
|
||||
|
||||
MapInstanced* ToMapInstanced(){ if (Instanceable()) return reinterpret_cast<MapInstanced*>(this); else return NULL; }
|
||||
@@ -485,6 +486,9 @@ class Map : public GridRefManager<NGridType>
|
||||
|
||||
static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId);
|
||||
|
||||
void SendInitTransports(Player* player);
|
||||
void SendRemoveTransports(Player* player);
|
||||
|
||||
private:
|
||||
void LoadMapAndVMap(int gx, int gy);
|
||||
void LoadVMap(int gx, int gy);
|
||||
@@ -496,18 +500,21 @@ class Map : public GridRefManager<NGridType>
|
||||
|
||||
void SendInitSelf(Player* player);
|
||||
|
||||
void SendInitTransports(Player* player);
|
||||
void SendRemoveTransports(Player* player);
|
||||
|
||||
bool CreatureCellRelocation(Creature* creature, Cell new_cell);
|
||||
bool GameObjectCellRelocation(GameObject* go, Cell new_cell);
|
||||
|
||||
template<class T> void InitializeObject(T* obj);
|
||||
void AddCreatureToMoveList(Creature* c, float x, float y, float z, float ang);
|
||||
void RemoveCreatureFromMoveList(Creature* c);
|
||||
void AddGameObjectToMoveList(GameObject* go, float x, float y, float z, float ang);
|
||||
void RemoveGameObjectFromMoveList(GameObject* go);
|
||||
|
||||
bool _creatureToMoveLock;
|
||||
std::vector<Creature*> _creaturesToMove;
|
||||
|
||||
bool _gameObjectsToMoveLock;
|
||||
std::vector<GameObject*> _gameObjectsToMove;
|
||||
|
||||
bool IsGridLoaded(const GridCoord &) const;
|
||||
void EnsureGridCreated(const GridCoord &);
|
||||
void EnsureGridCreated_i(const GridCoord &);
|
||||
@@ -516,9 +523,6 @@ class Map : public GridRefManager<NGridType>
|
||||
|
||||
void buildNGridLinkage(NGridType* pNGridType) { pNGridType->link(this); }
|
||||
|
||||
template<class T> void AddType(T *obj);
|
||||
template<class T> void RemoveType(T *obj, bool);
|
||||
|
||||
NGridType* getNGrid(uint32 x, uint32 y) const
|
||||
{
|
||||
ASSERT(x < MAX_NUMBER_OF_GRIDS && y < MAX_NUMBER_OF_GRIDS);
|
||||
@@ -555,6 +559,11 @@ class Map : public GridRefManager<NGridType>
|
||||
ActiveNonPlayers m_activeNonPlayers;
|
||||
ActiveNonPlayers::iterator m_activeNonPlayersIter;
|
||||
|
||||
// Objects that must update even in inactive grids without activating them
|
||||
typedef std::set<Transport*> TransportsContainer;
|
||||
TransportsContainer _transports;
|
||||
TransportsContainer::iterator _transportsUpdateIter;
|
||||
|
||||
private:
|
||||
Player* _GetScriptPlayerSourceOrTarget(Object* source, Object* target, const ScriptInfo* scriptInfo) const;
|
||||
Creature* _GetScriptCreatureSourceOrTarget(Object* source, Object* target, const ScriptInfo* scriptInfo, bool bReverse = false) const;
|
||||
@@ -589,10 +598,10 @@ class Map : public GridRefManager<NGridType>
|
||||
|
||||
// Type specific code for add/remove to/from grid
|
||||
template<class T>
|
||||
void AddToGrid(T* object, Cell const& cell);
|
||||
void AddToGrid(T* object, Cell const& cell);
|
||||
|
||||
template<class T>
|
||||
void DeleteFromWorld(T*);
|
||||
void DeleteFromWorld(T*);
|
||||
|
||||
template<class T>
|
||||
void AddToActiveHelper(T* obj)
|
||||
|
||||
@@ -292,8 +292,6 @@ void MapManager::Update(uint32 diff)
|
||||
iter->second->DelayedUpdate(uint32(i_timer.GetCurrent()));
|
||||
|
||||
sObjectAccessor->Update(uint32(i_timer.GetCurrent()));
|
||||
for (TransportSet::iterator itr = m_Transports.begin(); itr != m_Transports.end(); ++itr)
|
||||
(*itr)->Update(uint32(i_timer.GetCurrent()));
|
||||
|
||||
i_timer.SetCurrent(0);
|
||||
}
|
||||
@@ -326,12 +324,6 @@ bool MapManager::IsValidMAP(uint32 mapid, bool startUp)
|
||||
|
||||
void MapManager::UnloadAll()
|
||||
{
|
||||
for (TransportSet::iterator i = m_Transports.begin(); i != m_Transports.end(); ++i)
|
||||
{
|
||||
(*i)->RemoveFromWorld();
|
||||
delete *i;
|
||||
}
|
||||
|
||||
for (MapMapType::iterator iter = i_maps.begin(); iter != i_maps.end();)
|
||||
{
|
||||
iter->second->UnloadAll();
|
||||
|
||||
@@ -107,15 +107,6 @@ class MapManager
|
||||
|
||||
void DoDelayedMovesAndRemoves();
|
||||
|
||||
void LoadTransports();
|
||||
void LoadTransportNPCs();
|
||||
|
||||
typedef std::set<Transport*> TransportSet;
|
||||
TransportSet m_Transports;
|
||||
|
||||
typedef std::map<uint32, TransportSet> TransportMap;
|
||||
TransportMap m_TransportsByMap;
|
||||
|
||||
bool CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck = false);
|
||||
void InitializeVisibilityDistanceInfo();
|
||||
|
||||
|
||||
@@ -0,0 +1,453 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "TransportMgr.h"
|
||||
#include "Transport.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "MoveSpline.h"
|
||||
#include "MapManager.h"
|
||||
|
||||
TransportTemplate::~TransportTemplate()
|
||||
{
|
||||
// Collect shared pointers into a set to avoid deleting the same memory more than once
|
||||
std::set<TransportSpline*> splines;
|
||||
for (size_t i = 0; i < keyFrames.size(); ++i)
|
||||
splines.insert(keyFrames[i].Spline);
|
||||
|
||||
for (std::set<TransportSpline*>::iterator itr = splines.begin(); itr != splines.end(); ++itr)
|
||||
delete *itr;
|
||||
}
|
||||
|
||||
TransportMgr::TransportMgr()
|
||||
{
|
||||
}
|
||||
|
||||
TransportMgr::~TransportMgr()
|
||||
{
|
||||
}
|
||||
|
||||
void TransportMgr::Unload()
|
||||
{
|
||||
_transportTemplates.clear();
|
||||
}
|
||||
|
||||
void TransportMgr::LoadTransportTemplates()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
QueryResult result = WorldDatabase.Query("SELECT entry FROM gameobject_template WHERE type = 15 ORDER BY entry ASC");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 transport templates. DB table `gameobject_template` has no transports!");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 entry = fields[0].GetUInt32();
|
||||
GameObjectTemplate const* goInfo = sObjectMgr->GetGameObjectTemplate(entry);
|
||||
if (goInfo->moTransport.taxiPathId >= sTaxiPathNodesByPath.size())
|
||||
{
|
||||
TC_LOG_ERROR(LOG_FILTER_SQL, "Transport %u (name: %s) has an invalid path specified in `gameobject_template`.`data0` (%u) field, skipped.", entry, goInfo->name, goInfo->moTransport.taxiPathId);
|
||||
continue;
|
||||
}
|
||||
|
||||
// paths are generated per template, saves us from generating it again in case of instanced transports
|
||||
TransportTemplate& transport = _transportTemplates[entry];
|
||||
transport.entry = entry;
|
||||
GeneratePath(goInfo, &transport);
|
||||
|
||||
// transports in instance are only on one map
|
||||
if (transport.inInstance)
|
||||
_instanceTransports[*transport.mapsUsed.begin()].insert(entry);
|
||||
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Loaded %u transport templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTemplate* transport)
|
||||
{
|
||||
uint32 pathId = goInfo->moTransport.taxiPathId;
|
||||
TaxiPathNodeList const& path = sTaxiPathNodesByPath[pathId];
|
||||
std::vector<KeyFrame>& keyFrames = transport->keyFrames;
|
||||
Movement::PointsArray splinePath;
|
||||
bool mapChange = false;
|
||||
bool cyclic = true;
|
||||
for (size_t i = 1; i < path.size() - 1; ++i)
|
||||
{
|
||||
if (!mapChange)
|
||||
{
|
||||
TaxiPathNodeEntry const& node_i = path[i];
|
||||
if (node_i.actionFlag == 1 || node_i.mapid != path[i + 1].mapid)
|
||||
{
|
||||
cyclic = false;
|
||||
keyFrames.back().Teleport = true;
|
||||
mapChange = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyFrame k(node_i);
|
||||
keyFrames.push_back(k);
|
||||
splinePath.push_back(G3D::Vector3(node_i.x, node_i.y, node_i.z));
|
||||
transport->mapsUsed.insert(k.Node->mapid);
|
||||
}
|
||||
}
|
||||
else
|
||||
mapChange = false;
|
||||
}
|
||||
|
||||
if (transport->mapsUsed.size() > 1)
|
||||
{
|
||||
for (std::set<uint32>::const_iterator itr = transport->mapsUsed.begin(); itr != transport->mapsUsed.end(); ++itr)
|
||||
ASSERT(!sMapStore.LookupEntry(*itr)->Instanceable());
|
||||
|
||||
transport->inInstance = false;
|
||||
}
|
||||
else
|
||||
transport->inInstance = sMapStore.LookupEntry(*transport->mapsUsed.begin())->Instanceable();
|
||||
|
||||
// last to first is always "teleport", even for closed paths
|
||||
keyFrames.back().Teleport = true;
|
||||
|
||||
const float speed = float(goInfo->moTransport.moveSpeed);
|
||||
const float accel = float(goInfo->moTransport.accelRate);
|
||||
const float accel_dist = 0.5f * speed * speed / accel;
|
||||
|
||||
transport->accelTime = speed / accel;
|
||||
transport->accelDist = accel_dist;
|
||||
|
||||
int32 firstStop = -1;
|
||||
int32 lastStop = -1;
|
||||
|
||||
// first cell is arrived at by teleportation :S
|
||||
keyFrames[0].DistFromPrev = 0;
|
||||
keyFrames[0].Index = 1;
|
||||
if (keyFrames[0].IsStopFrame())
|
||||
{
|
||||
firstStop = 0;
|
||||
lastStop = 0;
|
||||
}
|
||||
|
||||
// find the rest of the distances between key points
|
||||
// Every path segment has its own spline
|
||||
if (cyclic)
|
||||
{
|
||||
TransportSpline* spline = new TransportSpline();
|
||||
spline->init_cyclic_spline(&splinePath[0], splinePath.size(), Movement::SplineBase::ModeCatmullrom, 0);
|
||||
spline->initLengths();
|
||||
keyFrames[0].DistFromPrev = spline->length(spline->last() - 2, spline->last() - 1);
|
||||
keyFrames[0].Spline = spline;
|
||||
for (size_t i = 1; i < keyFrames.size(); ++i)
|
||||
{
|
||||
keyFrames[i].Index = i + 1;
|
||||
keyFrames[i].DistFromPrev = spline->length(i, i + 1);
|
||||
keyFrames[i - 1].NextDistFromPrev = keyFrames[i].DistFromPrev;
|
||||
keyFrames[i].Spline = spline;
|
||||
if (keyFrames[i].IsStopFrame())
|
||||
{
|
||||
// remember first stop frame
|
||||
if (firstStop == -1)
|
||||
firstStop = i;
|
||||
lastStop = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t start = 0;
|
||||
for (size_t i = 1; i < keyFrames.size(); ++i)
|
||||
{
|
||||
if (keyFrames[i - 1].Teleport || i + 1 == keyFrames.size())
|
||||
{
|
||||
size_t extra = !keyFrames[i - 1].Teleport ? 1 : 0;
|
||||
TransportSpline* spline = new TransportSpline();
|
||||
spline->init_spline(&splinePath[start], i - start + extra, Movement::SplineBase::ModeCatmullrom);
|
||||
spline->initLengths();
|
||||
for (size_t j = start; j < i + extra; ++j)
|
||||
{
|
||||
keyFrames[j].Index = j - start + 1;
|
||||
keyFrames[j].DistFromPrev = spline->length(j - start, j + 1 - start);
|
||||
if (j > 0)
|
||||
keyFrames[j - 1].NextDistFromPrev = keyFrames[j].DistFromPrev;
|
||||
keyFrames[j].Spline = spline;
|
||||
}
|
||||
|
||||
if (keyFrames[i - 1].Teleport)
|
||||
{
|
||||
keyFrames[i].Index = i - start + 1;
|
||||
keyFrames[i].DistFromPrev = 0.0f;
|
||||
keyFrames[i - 1].NextDistFromPrev = 0.0f;
|
||||
keyFrames[i].Spline = spline;
|
||||
}
|
||||
|
||||
start = i;
|
||||
}
|
||||
|
||||
if (keyFrames[i].IsStopFrame())
|
||||
{
|
||||
// remember first stop frame
|
||||
if (firstStop == -1)
|
||||
firstStop = i;
|
||||
lastStop = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keyFrames.back().NextDistFromPrev = keyFrames.front().DistFromPrev;
|
||||
|
||||
// at stopping keyframes, we define distSinceStop == 0,
|
||||
// and distUntilStop is to the next stopping keyframe.
|
||||
// this is required to properly handle cases of two stopping frames in a row (yes they do exist)
|
||||
float tmpDist = 0.0f;
|
||||
for (size_t i = 0; i < keyFrames.size(); ++i)
|
||||
{
|
||||
int32 j = (i + lastStop) % keyFrames.size();
|
||||
if (keyFrames[j].IsStopFrame())
|
||||
tmpDist = 0.0f;
|
||||
else
|
||||
tmpDist += keyFrames[j].DistFromPrev;
|
||||
keyFrames[j].DistSinceStop = tmpDist;
|
||||
}
|
||||
|
||||
tmpDist = 0.0f;
|
||||
for (int32 i = int32(keyFrames.size()) - 1; i >= 0; i--)
|
||||
{
|
||||
int32 j = (i + firstStop) % keyFrames.size();
|
||||
tmpDist += keyFrames[(j + 1) % keyFrames.size()].DistFromPrev;
|
||||
keyFrames[j].DistUntilStop = tmpDist;
|
||||
if (keyFrames[j].IsStopFrame())
|
||||
tmpDist = 0.0f;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < keyFrames.size(); ++i)
|
||||
{
|
||||
float total_dist = keyFrames[i].DistSinceStop + keyFrames[i].DistUntilStop;
|
||||
if (total_dist < 2 * accel_dist) // won't reach full speed
|
||||
{
|
||||
if (keyFrames[i].DistSinceStop < keyFrames[i].DistUntilStop) // is still accelerating
|
||||
{
|
||||
// calculate accel+brake time for this short segment
|
||||
float segment_time = 2.0f * sqrt((keyFrames[i].DistUntilStop + keyFrames[i].DistSinceStop) / accel);
|
||||
// substract acceleration time
|
||||
keyFrames[i].TimeTo = segment_time - sqrt(2 * keyFrames[i].DistSinceStop / accel);
|
||||
}
|
||||
else // slowing down
|
||||
keyFrames[i].TimeTo = sqrt(2 * keyFrames[i].DistUntilStop / accel);
|
||||
}
|
||||
else if (keyFrames[i].DistSinceStop < accel_dist) // still accelerating (but will reach full speed)
|
||||
{
|
||||
// calculate accel + cruise + brake time for this long segment
|
||||
float segment_time = (keyFrames[i].DistUntilStop + keyFrames[i].DistSinceStop) / speed + (speed / accel);
|
||||
// substract acceleration time
|
||||
keyFrames[i].TimeTo = segment_time - sqrt(2 * keyFrames[i].DistSinceStop / accel);
|
||||
}
|
||||
else if (keyFrames[i].DistUntilStop < accel_dist) // already slowing down (but reached full speed)
|
||||
keyFrames[i].TimeTo = sqrt(2 * keyFrames[i].DistUntilStop / accel);
|
||||
else // at full speed
|
||||
keyFrames[i].TimeTo = (keyFrames[i].DistUntilStop / speed) + (0.5f * speed / accel);
|
||||
}
|
||||
|
||||
// calculate tFrom times from tTo times
|
||||
float segmentTime = 0.0f;
|
||||
for (size_t i = 0; i < keyFrames.size(); ++i)
|
||||
{
|
||||
int32 j = (i + lastStop) % keyFrames.size();
|
||||
if (keyFrames[j].IsStopFrame())
|
||||
segmentTime = keyFrames[j].TimeTo;
|
||||
keyFrames[j].TimeFrom = segmentTime - keyFrames[j].TimeTo;
|
||||
}
|
||||
|
||||
// calculate path times
|
||||
keyFrames[0].ArriveTime = 0;
|
||||
float curPathTime = 0.0f;
|
||||
if (keyFrames[0].IsStopFrame())
|
||||
{
|
||||
curPathTime = float(keyFrames[0].Node->delay);
|
||||
keyFrames[0].DepartureTime = uint32(curPathTime * IN_MILLISECONDS);
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < keyFrames.size(); ++i)
|
||||
{
|
||||
curPathTime += keyFrames[i-1].TimeTo;
|
||||
if (keyFrames[i].IsStopFrame())
|
||||
{
|
||||
keyFrames[i].ArriveTime = uint32(curPathTime * IN_MILLISECONDS);
|
||||
keyFrames[i - 1].NextArriveTime = keyFrames[i].ArriveTime;
|
||||
curPathTime += (float)keyFrames[i].Node->delay;
|
||||
keyFrames[i].DepartureTime = uint32(curPathTime * IN_MILLISECONDS);
|
||||
}
|
||||
else
|
||||
{
|
||||
curPathTime -= keyFrames[i].TimeTo;
|
||||
keyFrames[i].ArriveTime = uint32(curPathTime * IN_MILLISECONDS);
|
||||
keyFrames[i - 1].NextArriveTime = keyFrames[i].ArriveTime;
|
||||
keyFrames[i].DepartureTime = keyFrames[i].ArriveTime;
|
||||
}
|
||||
}
|
||||
keyFrames.back().NextArriveTime = keyFrames.back().DepartureTime;
|
||||
|
||||
transport->pathTime = keyFrames.back().DepartureTime;
|
||||
//WorldDatabase.DirectPExecute("UPDATE `transports` SET `period_gen`=%u WHERE `entry`=%u", transport->pathTime, transport->entry);
|
||||
}
|
||||
|
||||
void TransportMgr::AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg, TransportAnimationEntry const* node)
|
||||
{
|
||||
TransportAnimation& animNode = _transportAnimations[transportEntry];
|
||||
if (animNode.TotalTime < timeSeg)
|
||||
animNode.TotalTime = timeSeg;
|
||||
|
||||
animNode.Path[timeSeg] = node;
|
||||
}
|
||||
|
||||
Transport* TransportMgr::CreateTransport(uint32 entry, uint32 guid /*= 0*/, Map* map /*= NULL*/)
|
||||
{
|
||||
// instance case, execute GetGameObjectEntry hook
|
||||
if (map)
|
||||
{
|
||||
// SetZoneScript() is called after adding to map, so fetch the script using map
|
||||
if (map->IsDungeon())
|
||||
if (InstanceScript* instance = static_cast<InstanceMap*>(map)->GetInstanceScript())
|
||||
entry = instance->GetGameObjectEntry(0, entry);
|
||||
|
||||
if (!entry)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TransportTemplate const* tInfo = GetTransportTemplate(entry);
|
||||
if (!tInfo)
|
||||
{
|
||||
TC_LOG_ERROR(LOG_FILTER_SQL, "Transport %u will not be loaded, `transport_template` missing", entry);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// create transport...
|
||||
Transport* trans = new Transport();
|
||||
|
||||
// ...at first waypoint
|
||||
TaxiPathNodeEntry const* startNode = tInfo->keyFrames.begin()->Node;
|
||||
uint32 mapId = startNode->mapid;
|
||||
float x = startNode->x;
|
||||
float y = startNode->y;
|
||||
float z = startNode->z;
|
||||
float o = 0.0f;
|
||||
|
||||
// initialize the gameobject base
|
||||
uint32 guidLow = guid ? guid : sObjectMgr->GenerateLowGuid(HIGHGUID_MO_TRANSPORT);
|
||||
if (!trans->Create(guidLow, entry, mapId, x, y, z, o, 255))
|
||||
{
|
||||
delete trans;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (MapEntry const* mapEntry = sMapStore.LookupEntry(mapId))
|
||||
{
|
||||
if (uint32(mapEntry->Instanceable()) != tInfo->inInstance)
|
||||
{
|
||||
TC_LOG_ERROR(LOG_FILTER_TRANSPORTS, "Transport %u (name: %s) attempted creation in instance map (id: %u) but it is not an instanced transport!", entry, trans->GetName(), mapId);
|
||||
delete trans;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// use preset map for instances (need to know which instance)
|
||||
trans->SetMap(map ? map : sMapMgr->CreateMap(mapId, NULL));
|
||||
if (map && map->IsDungeon())
|
||||
trans->m_zoneScript = map->ToInstanceMap()->GetInstanceScript();
|
||||
|
||||
// Passengers will be loaded once a player is near
|
||||
|
||||
trans->GetMap()->AddToMap<Transport>(trans);
|
||||
return trans;
|
||||
}
|
||||
|
||||
void TransportMgr::SpawnContinentTransports()
|
||||
{
|
||||
if (_transportTemplates.empty())
|
||||
return;
|
||||
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
QueryResult result = WorldDatabase.Query("SELECT guid, entry FROM transports");
|
||||
|
||||
uint32 count = 0;
|
||||
if (result)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 guid = fields[0].GetUInt32();
|
||||
uint32 entry = fields[1].GetUInt32();
|
||||
|
||||
if (TransportTemplate const* tInfo = GetTransportTemplate(entry))
|
||||
if (!tInfo->inInstance)
|
||||
if (CreateTransport(entry, guid))
|
||||
++count;
|
||||
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, ">> Spawned %u continent transports in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void TransportMgr::CreateInstanceTransports(Map* map)
|
||||
{
|
||||
TransportInstanceMap::const_iterator mapTransports = _instanceTransports.find(map->GetId());
|
||||
|
||||
// no transports here
|
||||
if (mapTransports == _instanceTransports.end() || mapTransports->second.empty())
|
||||
return;
|
||||
|
||||
// create transports
|
||||
for (std::set<uint32>::const_iterator itr = mapTransports->second.begin(); itr != mapTransports->second.end(); ++itr)
|
||||
CreateTransport(*itr, 0, map);
|
||||
}
|
||||
|
||||
TransportAnimationEntry const* TransportAnimation::GetAnimNode(uint32 time) const
|
||||
{
|
||||
if (Path.empty())
|
||||
return NULL;
|
||||
|
||||
for (TransportPathContainer::const_reverse_iterator itr2 = Path.rbegin(); itr2 != Path.rend(); ++itr2)
|
||||
if (time >= itr2->first)
|
||||
return itr2->second;
|
||||
|
||||
return Path.begin()->second;
|
||||
}
|
||||
|
||||
G3D::Quat TransportAnimation::GetAnimRotation(uint32 time) const
|
||||
{
|
||||
if (Rotations.empty())
|
||||
return G3D::Quat(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
TransportRotationEntry const* rot = Rotations.begin()->second;
|
||||
for (TransportPathRotationContainer::const_reverse_iterator itr2 = Rotations.rbegin(); itr2 != Rotations.rend(); ++itr2)
|
||||
{
|
||||
if (time >= itr2->first)
|
||||
{
|
||||
rot = itr2->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return G3D::Quat(rot->X, rot->Y, rot->Z, rot->W);
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TRANSPORTMGR_H
|
||||
#define TRANSPORTMGR_H
|
||||
|
||||
#include <ace/Singleton.h>
|
||||
#include <G3D/Quat.h>
|
||||
#include "Spline.h"
|
||||
#include "DBCStores.h"
|
||||
|
||||
struct KeyFrame;
|
||||
struct GameObjectTemplate;
|
||||
struct TransportTemplate;
|
||||
class Transport;
|
||||
class Map;
|
||||
|
||||
typedef Movement::Spline<double> TransportSpline;
|
||||
typedef std::vector<KeyFrame> KeyFrameVec;
|
||||
typedef UNORDERED_MAP<uint32, TransportTemplate> TransportTemplates;
|
||||
typedef std::set<Transport*> TransportSet;
|
||||
typedef UNORDERED_MAP<uint32, TransportSet> TransportMap;
|
||||
typedef UNORDERED_MAP<uint32, std::set<uint32> > TransportInstanceMap;
|
||||
|
||||
struct KeyFrame
|
||||
{
|
||||
explicit KeyFrame(TaxiPathNodeEntry const& _node) : Node(&_node),
|
||||
DistSinceStop(-1.0f), DistUntilStop(-1.0f), DistFromPrev(-1.0f), TimeFrom(0.0f), TimeTo(0.0f),
|
||||
Teleport(false), ArriveTime(0), DepartureTime(0), Spline(NULL), NextDistFromPrev(0.0f), NextArriveTime(0)
|
||||
{
|
||||
}
|
||||
|
||||
uint32 Index;
|
||||
TaxiPathNodeEntry const* Node;
|
||||
float DistSinceStop;
|
||||
float DistUntilStop;
|
||||
float DistFromPrev;
|
||||
float TimeFrom;
|
||||
float TimeTo;
|
||||
bool Teleport;
|
||||
uint32 ArriveTime;
|
||||
uint32 DepartureTime;
|
||||
TransportSpline* Spline;
|
||||
|
||||
// Data needed for next frame
|
||||
float NextDistFromPrev;
|
||||
uint32 NextArriveTime;
|
||||
|
||||
bool IsTeleportFrame() const { return Teleport; }
|
||||
bool IsStopFrame() const { return Node->actionFlag == 2; }
|
||||
};
|
||||
|
||||
struct TransportTemplate
|
||||
{
|
||||
TransportTemplate() : pathTime(0), accelTime(0.0f), accelDist(0.0f) { }
|
||||
~TransportTemplate();
|
||||
|
||||
std::set<uint32> mapsUsed;
|
||||
bool inInstance;
|
||||
uint32 pathTime;
|
||||
KeyFrameVec keyFrames;
|
||||
float accelTime;
|
||||
float accelDist;
|
||||
uint32 entry;
|
||||
};
|
||||
|
||||
typedef std::map<uint32, TransportAnimationEntry const*> TransportPathContainer;
|
||||
typedef std::map<uint32, TransportRotationEntry const*> TransportPathRotationContainer;
|
||||
|
||||
struct TransportAnimation
|
||||
{
|
||||
TransportPathContainer Path;
|
||||
TransportPathRotationContainer Rotations;
|
||||
uint32 TotalTime;
|
||||
|
||||
TransportAnimationEntry const* GetAnimNode(uint32 time) const;
|
||||
G3D::Quat GetAnimRotation(uint32 time) const;
|
||||
};
|
||||
|
||||
typedef std::map<uint32, TransportAnimation> TransportAnimationContainer;
|
||||
|
||||
class TransportMgr
|
||||
{
|
||||
friend class ACE_Singleton<TransportMgr, ACE_Thread_Mutex>;
|
||||
friend void LoadDBCStores(std::string const&);
|
||||
|
||||
public:
|
||||
void Unload();
|
||||
|
||||
void LoadTransportTemplates();
|
||||
|
||||
// Creates a transport using given GameObject template entry
|
||||
Transport* CreateTransport(uint32 entry, uint32 guid = 0, Map* map = NULL);
|
||||
|
||||
// Spawns all continent transports, used at core startup
|
||||
void SpawnContinentTransports();
|
||||
|
||||
// creates all transports for instance
|
||||
void CreateInstanceTransports(Map* map);
|
||||
|
||||
TransportTemplate const* GetTransportTemplate(uint32 entry) const
|
||||
{
|
||||
TransportTemplates::const_iterator itr = _transportTemplates.find(entry);
|
||||
if (itr != _transportTemplates.end())
|
||||
return &itr->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TransportAnimation const* GetTransportAnimInfo(uint32 entry) const
|
||||
{
|
||||
TransportAnimationContainer::const_iterator itr = _transportAnimations.find(entry);
|
||||
if (itr != _transportAnimations.end())
|
||||
return &itr->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
TransportMgr();
|
||||
~TransportMgr();
|
||||
TransportMgr(TransportMgr const&);
|
||||
TransportMgr& operator=(TransportMgr const&);
|
||||
|
||||
// Generates and precaches a path for transport to avoid generation each time transport instance is created
|
||||
void GeneratePath(GameObjectTemplate const* goInfo, TransportTemplate* transport);
|
||||
|
||||
void AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg, TransportAnimationEntry const* node);
|
||||
|
||||
void AddPathRotationToTransport(uint32 transportEntry, uint32 timeSeg, TransportRotationEntry const* node)
|
||||
{
|
||||
_transportAnimations[transportEntry].Rotations[timeSeg] = node;
|
||||
}
|
||||
|
||||
// Container storing transport templates
|
||||
TransportTemplates _transportTemplates;
|
||||
|
||||
// Container storing transport entries to create for instanced maps
|
||||
TransportInstanceMap _instanceTransports;
|
||||
|
||||
TransportAnimationContainer _transportAnimations;
|
||||
};
|
||||
|
||||
#define sTransportMgr ACE_Singleton<TransportMgr, ACE_Thread_Mutex>::instance()
|
||||
|
||||
#endif // TRANSPORTMGR_H
|
||||
@@ -1495,7 +1495,8 @@ enum GameObjectDynamicLowFlags
|
||||
GO_DYNFLAG_LO_ACTIVATE = 0x01, // enables interaction with GO
|
||||
GO_DYNFLAG_LO_ANIMATE = 0x02, // possibly more distinct animation of GO
|
||||
GO_DYNFLAG_LO_NO_INTERACT = 0x04, // appears to disable interaction (not fully verified)
|
||||
GO_DYNFLAG_LO_SPARKLE = 0x08 // makes GO sparkle
|
||||
GO_DYNFLAG_LO_SPARKLE = 0x08, // makes GO sparkle
|
||||
GO_DYNFLAG_LO_STOPPED = 0x10 // Transport is stopped
|
||||
};
|
||||
|
||||
enum GameObjectDestructibleState
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
//Extended headers
|
||||
#include "ObjectMgr.h"
|
||||
#include "World.h"
|
||||
#include "Transport.h"
|
||||
//Flightmaster grid preloading
|
||||
#include "MapManager.h"
|
||||
//Creature-specific headers
|
||||
@@ -92,14 +93,37 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
|
||||
{
|
||||
if (!i_path || i_path->empty())
|
||||
return false;
|
||||
|
||||
if (Stopped())
|
||||
return true;
|
||||
|
||||
bool transportPath = creature->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && creature->GetTransGUID();
|
||||
|
||||
if (m_isArrivalDone)
|
||||
{
|
||||
if ((i_currentNode == i_path->size() - 1) && !repeating) // If that's our last waypoint
|
||||
{
|
||||
creature->SetHomePosition(i_path->at(i_currentNode)->x, i_path->at(i_currentNode)->y, i_path->at(i_currentNode)->z, creature->GetOrientation());
|
||||
float x = i_path->at(i_currentNode)->x;
|
||||
float y = i_path->at(i_currentNode)->y;
|
||||
float z = i_path->at(i_currentNode)->z;
|
||||
float o = creature->GetOrientation();
|
||||
|
||||
if (!transportPath)
|
||||
creature->SetHomePosition(x, y, z, o);
|
||||
else
|
||||
{
|
||||
if (Transport* trans = creature->GetTransport())
|
||||
{
|
||||
o -= trans->GetOrientation();
|
||||
creature->SetTransportHomePosition(x, y, z, o);
|
||||
trans->CalculatePassengerPosition(x, y, z, &o);
|
||||
creature->SetHomePosition(x, y, z, o);
|
||||
}
|
||||
else
|
||||
transportPath = false;
|
||||
// else if (vehicle) - this should never happen, vehicle offsets are const
|
||||
}
|
||||
|
||||
creature->GetMotionMaster()->Initialize();
|
||||
return false;
|
||||
}
|
||||
@@ -113,7 +137,19 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
|
||||
|
||||
creature->AddUnitState(UNIT_STATE_ROAMING_MOVE);
|
||||
|
||||
Movement::Location formationDest(node->x, node->y, node->z, 0.0f);
|
||||
Movement::MoveSplineInit init(creature);
|
||||
|
||||
//! If creature is on transport, we assume waypoints set in DB are already transport offsets
|
||||
if (transportPath)
|
||||
{
|
||||
init.DisableTransportPathTransformations();
|
||||
if (TransportBase* trans = creature->GetDirectTransport())
|
||||
trans->CalculatePassengerPosition(formationDest.x, formationDest.y, formationDest.z, &formationDest.orientation);
|
||||
}
|
||||
|
||||
//! Do not use formationDest here, MoveTo requires transport offsets due to DisableTransportPathTransformations() call
|
||||
//! but formationDest contains global coordinates
|
||||
init.MoveTo(node->x, node->y, node->z);
|
||||
|
||||
//! Accepts angles such as 0.00001 and -0.00001, 0 must be ignored, default value in waypoint table
|
||||
@@ -125,7 +161,7 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
|
||||
|
||||
//Call for creature group update
|
||||
if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature)
|
||||
creature->GetFormation()->LeaderMoveTo(node->x, node->y, node->z);
|
||||
creature->GetFormation()->LeaderMoveTo(formationDest.x, formationDest.y, formationDest.z);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -315,6 +315,7 @@ void Map::ScriptsProcess()
|
||||
case HIGHGUID_PLAYER:
|
||||
source = HashMapHolder<Player>::Find(step.sourceGUID);
|
||||
break;
|
||||
case HIGHGUID_TRANSPORT:
|
||||
case HIGHGUID_GAMEOBJECT:
|
||||
source = HashMapHolder<GameObject>::Find(step.sourceGUID);
|
||||
break;
|
||||
@@ -322,15 +323,11 @@ void Map::ScriptsProcess()
|
||||
source = HashMapHolder<Corpse>::Find(step.sourceGUID);
|
||||
break;
|
||||
case HIGHGUID_MO_TRANSPORT:
|
||||
for (MapManager::TransportSet::iterator itr2 = sMapMgr->m_Transports.begin(); itr2 != sMapMgr->m_Transports.end(); ++itr2)
|
||||
{
|
||||
if ((*itr2)->GetGUID() == step.sourceGUID)
|
||||
{
|
||||
source = *itr2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
GameObject* go = HashMapHolder<GameObject>::Find(step.sourceGUID);
|
||||
source = go ? go->ToTransport() : NULL;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
TC_LOG_ERROR(LOG_FILTER_TSCR, "%s source with unsupported high guid (GUID: " UI64FMTD ", high guid: %u).",
|
||||
step.script->GetDebugInfo().c_str(), step.sourceGUID, GUID_HIPART(step.sourceGUID));
|
||||
@@ -353,12 +350,19 @@ void Map::ScriptsProcess()
|
||||
case HIGHGUID_PLAYER: // empty GUID case also
|
||||
target = HashMapHolder<Player>::Find(step.targetGUID);
|
||||
break;
|
||||
case HIGHGUID_TRANSPORT:
|
||||
case HIGHGUID_GAMEOBJECT:
|
||||
target = HashMapHolder<GameObject>::Find(step.targetGUID);
|
||||
break;
|
||||
case HIGHGUID_CORPSE:
|
||||
target = HashMapHolder<Corpse>::Find(step.targetGUID);
|
||||
break;
|
||||
case HIGHGUID_MO_TRANSPORT:
|
||||
{
|
||||
GameObject* go = HashMapHolder<GameObject>::Find(step.targetGUID);
|
||||
target = go ? go->ToTransport() : NULL;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
TC_LOG_ERROR(LOG_FILTER_TSCR, "%s target with unsupported high guid (GUID: " UI64FMTD ", high guid: %u).",
|
||||
step.script->GetDebugInfo().c_str(), step.targetGUID, GUID_HIPART(step.targetGUID));
|
||||
|
||||
@@ -786,10 +786,6 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
|
||||
|
||||
if (mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT))
|
||||
data >> mi->transport.time2;
|
||||
|
||||
if (mi->pos.m_positionX != mi->transport.pos.m_positionX)
|
||||
if (GetPlayer()->GetTransport())
|
||||
GetPlayer()->GetTransport()->UpdatePosition(mi);
|
||||
}
|
||||
|
||||
if (mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (mi->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING)))
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
#include "Warden.h"
|
||||
#include "CalendarMgr.h"
|
||||
#include "BattlefieldMgr.h"
|
||||
#include "TransportMgr.h"
|
||||
|
||||
ACE_Atomic_Op<ACE_Thread_Mutex, bool> World::m_stopEvent = false;
|
||||
uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
|
||||
@@ -1374,6 +1375,9 @@ void World::SetInitialWorldSettings()
|
||||
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, "Loading Game Object Templates..."); // must be after LoadPageTexts
|
||||
sObjectMgr->LoadGameObjectTemplate();
|
||||
|
||||
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, "Loading Transport templates...");
|
||||
sTransportMgr->LoadTransportTemplates();
|
||||
|
||||
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, "Loading Spell Rank Data...");
|
||||
sSpellMgr->LoadSpellRanks();
|
||||
|
||||
@@ -1784,10 +1788,7 @@ void World::SetInitialWorldSettings()
|
||||
sBattlefieldMgr->InitBattlefield();
|
||||
|
||||
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, "Loading Transports...");
|
||||
sMapMgr->LoadTransports();
|
||||
|
||||
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, "Loading Transport NPCs...");
|
||||
sMapMgr->LoadTransportNPCs();
|
||||
sTransportMgr->SpawnContinentTransports();
|
||||
|
||||
///- Initialize Warden
|
||||
TC_LOG_INFO(LOG_FILTER_SERVER_LOADING, "Loading Warden Checks...");
|
||||
|
||||
@@ -31,6 +31,7 @@ EndScriptData */
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "GossipDef.h"
|
||||
#include "Transport.h"
|
||||
#include "Language.h"
|
||||
|
||||
#include <fstream>
|
||||
@@ -91,6 +92,7 @@ public:
|
||||
{ "areatriggers", rbac::RBAC_PERM_COMMAND_DEBUG_AREATRIGGERS, false, &HandleDebugAreaTriggersCommand, "", NULL },
|
||||
{ "los", rbac::RBAC_PERM_COMMAND_DEBUG_LOS, false, &HandleDebugLoSCommand, "", NULL },
|
||||
{ "moveflags", rbac::RBAC_PERM_COMMAND_DEBUG_MOVEFLAGS, false, &HandleDebugMoveflagsCommand, "", NULL },
|
||||
{ "transport", rbac::RBAC_PERM_COMMAND_DEBUG_TRANSPORT, false, &HandleDebugTransportCommand, "", NULL },
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
};
|
||||
static ChatCommand commandTable[] =
|
||||
@@ -1363,6 +1365,30 @@ public:
|
||||
handler->PSendSysMessage("Waypoint SQL written to SQL Developer log");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleDebugTransportCommand(ChatHandler* handler, char const* args)
|
||||
{
|
||||
Transport* transport = handler->GetSession()->GetPlayer()->GetTransport();
|
||||
if (!transport)
|
||||
return false;
|
||||
|
||||
bool start = false;
|
||||
if (!stricmp(args, "stop"))
|
||||
transport->EnableMovement(false);
|
||||
else if (!stricmp(args, "start"))
|
||||
{
|
||||
transport->EnableMovement(true);
|
||||
start = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
handler->PSendSysMessage("Transport %s is %s", transport->GetName().c_str(), transport->GetGoState() == GO_STATE_READY ? "stopped" : "moving");
|
||||
return true;
|
||||
}
|
||||
|
||||
handler->PSendSysMessage("Transport %s %s", transport->GetName().c_str(), start ? "started" : "stopped");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_debug_commandscript()
|
||||
|
||||
@@ -245,24 +245,22 @@ public:
|
||||
float o = chr->GetOrientation();
|
||||
Map* map = chr->GetMap();
|
||||
|
||||
if (chr->GetTransport())
|
||||
if (Transport* trans = chr->GetTransport())
|
||||
{
|
||||
uint32 tguid = chr->GetTransport()->AddNPCPassenger(0, id, chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO());
|
||||
if (tguid > 0)
|
||||
{
|
||||
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE_TRANSPORT);
|
||||
uint32 guid = sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT);
|
||||
CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid);
|
||||
data.id = id;
|
||||
data.phaseMask = chr->GetPhaseMaskForSpawn();
|
||||
data.posX = chr->GetTransOffsetX();
|
||||
data.posY = chr->GetTransOffsetY();
|
||||
data.posZ = chr->GetTransOffsetZ();
|
||||
data.orientation = chr->GetTransOffsetO();
|
||||
|
||||
stmt->setInt32(0, int32(tguid));
|
||||
stmt->setInt32(1, int32(id));
|
||||
stmt->setInt32(2, int32(chr->GetTransport()->GetEntry()));
|
||||
stmt->setFloat(3, chr->GetTransOffsetX());
|
||||
stmt->setFloat(4, chr->GetTransOffsetY());
|
||||
stmt->setFloat(5, chr->GetTransOffsetZ());
|
||||
stmt->setFloat(6, chr->GetTransOffsetO());
|
||||
Creature* creature = trans->CreateNPCPassenger(guid, &data);
|
||||
|
||||
WorldDatabase.Execute(stmt);
|
||||
}
|
||||
creature->SaveToDB(trans->GetGOInfo()->moTransport.mapID, 1 << map->GetSpawnMode(), chr->GetPhaseMaskForSpawn());
|
||||
|
||||
sObjectMgr->AddCreatureToGrid(guid, &data);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1337,7 +1335,8 @@ public:
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
char* charID = strtok((char*)args, " ");
|
||||
|
||||
char* charID = handler->extractKeyFromLink((char*)args, "Hcreature_entry");
|
||||
if (!charID)
|
||||
return false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user