diff options
76 files changed, 4271 insertions, 1536 deletions
diff --git a/sql/updates/hotfixes/2015_05_17_00_hotfixes.sql b/sql/updates/hotfixes/2015_05_17_00_hotfixes.sql new file mode 100644 index 00000000000..29d18a31703 --- /dev/null +++ b/sql/updates/hotfixes/2015_05_17_00_hotfixes.sql @@ -0,0 +1,205 @@ +-- +-- Table structure for table `garr_ability` +-- + +DROP TABLE IF EXISTS `garr_ability`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `garr_ability` ( + `ID` int(10) unsigned NOT NULL DEFAULT '0', + `Flags` int(10) unsigned NOT NULL DEFAULT '0', + `Name` text, + `Description` text, + `IconFileDataID` int(10) unsigned NOT NULL DEFAULT '0', + `OtherFactionGarrAbilityID` int(10) unsigned NOT NULL DEFAULT '0', + `GarrAbilityCategoryID` int(10) unsigned NOT NULL DEFAULT '0', + `VerifiedBuild` smallint(6) NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `garr_ability` +-- + +LOCK TABLES `garr_ability` WRITE; +/*!40000 ALTER TABLE `garr_ability` DISABLE KEYS */; +/*!40000 ALTER TABLE `garr_ability` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `garr_ability_locale` +-- + +DROP TABLE IF EXISTS `garr_ability_locale`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `garr_ability_locale` ( + `ID` int(10) unsigned NOT NULL DEFAULT '0', + `locale` varchar(4) NOT NULL, + `Name_lang` text, + `Description_lang` text, + `VerifiedBuild` smallint(6) NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`,`locale`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `garr_ability_locale` +-- + +LOCK TABLES `garr_ability_locale` WRITE; +/*!40000 ALTER TABLE `garr_ability_locale` DISABLE KEYS */; +/*!40000 ALTER TABLE `garr_ability_locale` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `garr_class_spec` +-- + +DROP TABLE IF EXISTS `garr_class_spec`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `garr_class_spec` ( + `ID` int(10) unsigned NOT NULL DEFAULT '0', + `NameMale` text, + `NameFemale` text, + `NameGenderless` text, + `ClassAtlasID` int(10) unsigned NOT NULL DEFAULT '0', + `GarrFollItemSetID` int(10) unsigned NOT NULL DEFAULT '0', + `VerifiedBuild` smallint(6) NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `garr_class_spec` +-- + +LOCK TABLES `garr_class_spec` WRITE; +/*!40000 ALTER TABLE `garr_class_spec` DISABLE KEYS */; +/*!40000 ALTER TABLE `garr_class_spec` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `garr_class_spec_locale` +-- + +DROP TABLE IF EXISTS `garr_class_spec_locale`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `garr_class_spec_locale` ( + `ID` int(10) unsigned NOT NULL DEFAULT '0', + `locale` varchar(4) NOT NULL, + `NameMale_lang` text, + `NameFemale_lang` text, + `NameGenderless_lang` text, + `VerifiedBuild` smallint(6) NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`,`locale`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `garr_class_spec_locale` +-- + +LOCK TABLES `garr_class_spec_locale` WRITE; +/*!40000 ALTER TABLE `garr_class_spec_locale` DISABLE KEYS */; +/*!40000 ALTER TABLE `garr_class_spec_locale` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `garr_follower` +-- + +DROP TABLE IF EXISTS `garr_follower`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `garr_follower` ( + `ID` int(10) unsigned NOT NULL DEFAULT '0', + `HordeCreatureID` int(10) unsigned NOT NULL DEFAULT '0', + `AllianceCreatureID` int(10) unsigned NOT NULL DEFAULT '0', + `HordeUiAnimRaceInfoID` int(10) unsigned NOT NULL DEFAULT '0', + `AllianceUiAnimRaceInfoID` int(10) unsigned NOT NULL DEFAULT '0', + `Quality` int(10) unsigned NOT NULL DEFAULT '0', + `HordeGarrClassSpecID` int(10) unsigned NOT NULL DEFAULT '0', + `AllianceGarrClassSpecID` int(10) unsigned NOT NULL DEFAULT '0', + `HordeGarrFollItemSetID` int(10) unsigned NOT NULL DEFAULT '0', + `AllianceGarrFollItemSetID` int(10) unsigned NOT NULL DEFAULT '0', + `Level` int(10) unsigned NOT NULL DEFAULT '0', + `ItemLevelWeapon` int(10) unsigned NOT NULL DEFAULT '0', + `ItemLevelArmor` int(10) unsigned NOT NULL DEFAULT '0', + `Unknown1` int(10) unsigned NOT NULL DEFAULT '0', + `Flags` int(10) unsigned NOT NULL DEFAULT '0', + `HordeSourceText` text, + `AllianceSourceText` text, + `Unknown2` int(11) NOT NULL DEFAULT '0', + `Unknown3` int(11) NOT NULL DEFAULT '0', + `HordePortraitIconID` int(10) unsigned NOT NULL DEFAULT '0', + `AlliancePortraitIconID` int(10) unsigned NOT NULL DEFAULT '0', + `VerifiedBuild` smallint(6) NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `garr_follower` +-- + +LOCK TABLES `garr_follower` WRITE; +/*!40000 ALTER TABLE `garr_follower` DISABLE KEYS */; +/*!40000 ALTER TABLE `garr_follower` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `garr_follower_locale` +-- + +DROP TABLE IF EXISTS `garr_follower_locale`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `garr_follower_locale` ( + `ID` int(10) unsigned NOT NULL DEFAULT '0', + `locale` varchar(4) NOT NULL, + `HordeSourceText_lang` text, + `AllianceSourceText_lang` text, + `VerifiedBuild` smallint(6) NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`,`locale`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `garr_follower_locale` +-- + +LOCK TABLES `garr_follower_locale` WRITE; +/*!40000 ALTER TABLE `garr_follower_locale` DISABLE KEYS */; +/*!40000 ALTER TABLE `garr_follower_locale` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `garr_follower_x_ability` +-- + +DROP TABLE IF EXISTS `garr_follower_x_ability`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `garr_follower_x_ability` ( + `ID` int(10) unsigned NOT NULL DEFAULT '0', + `GarrFollowerID` int(10) unsigned NOT NULL DEFAULT '0', + `GarrAbilityID` int(10) unsigned NOT NULL DEFAULT '0', + `FactionIndex` int(10) unsigned NOT NULL DEFAULT '0', + `VerifiedBuild` smallint(6) NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `garr_follower_x_ability` +-- + +LOCK TABLES `garr_follower_x_ability` WRITE; +/*!40000 ALTER TABLE `garr_follower_x_ability` DISABLE KEYS */; +/*!40000 ALTER TABLE `garr_follower_x_ability` ENABLE KEYS */; +UNLOCK TABLES; + diff --git a/sql/updates/world/2015_05_10_00_world.sql b/sql/updates/world/2015_05_10_00_world.sql new file mode 100644 index 00000000000..d1117dc931d --- /dev/null +++ b/sql/updates/world/2015_05_10_00_world.sql @@ -0,0 +1 @@ +DELETE FROM `gameobject` WHERE `id` IN (80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 121, 122, 123, 124, 298, 299, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 376, 377, 378, 379, 380, 381, 382, 387, 388, 389, 1162, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1572, 1573, 1595, 1596, 1597, 1598, 1630, 1633, 1634, 1639, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1668, 1669, 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2036, 2037, 2038, 2048, 2049, 2050, 2051, 2052, 2670, 2672, 2673, 2674, 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2683, 2684, 2685, 2968, 2969, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 3194, 3195, 3196, 3197, 3198, 3199, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3210, 3211, 3212, 3213, 3214, 3215, 3216, 3217, 3225, 3226, 3227, 3228, 3229, 3230, 3231, 3232, 3233, 3234, 3235, 3276, 3314, 4097, 4098, 4099, 4100, 4101, 4104, 4105, 4106, 4115, 4116, 4117, 4118, 4119, 4120, 4121, 4122, 4123, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 12351, 12352, 12353, 12354, 12355, 12356, 12357, 12358, 12359, 12360, 12361, 12362, 12363, 12364, 12365, 12366, 12893, 12894, 12895, 12896, 12897, 12898, 12899, 12900, 12901, 12902, 12903, 12904, 12907, 12908, 12909, 13348, 13349, 13350, 13351, 13352, 13353, 13354, 13355, 13356, 13357, 13358, 13405, 13406, 13407, 13408, 13409, 13410, 13411, 13412, 16396, 18033, 18034, 19028, 19033, 19545, 19546, 19553, 19554, 19555, 19556, 19557, 19558, 19559, 19560, 19561, 19562, 19563, 19564, 19565, 19566, 19567, 19568, 19569, 19570, 19571, 19572, 19573, 19574, 19575, 19576, 19578, 19579, 19580, 19581, 19583, 19585, 19839, 19840, 19841, 19842, 19843, 19844, 19845, 19846, 19847, 19863, 21053, 21054, 21055, 21056, 21057, 21058, 21059, 21060, 21061, 21062, 21063, 21064, 21065, 21066, 21067, 21068, 21069, 21070, 21071, 21072, 21073, 21074, 21075, 21076, 21077, 21078, 21079, 21080, 21081, 21082, 21083, 21084, 21085, 21086, 21087, 21088, 21089, 21509, 38927, 41195, 50484, 50485, 50486, 50487, 50488, 50489, 50490, 50491, 50492, 50493, 50494, 50495, 50496, 50497, 50498, 50499, 50500, 50501, 50502, 50503, 50504, 50505, 50506, 50507, 50508, 50509, 50510, 50511, 50512, 50513, 50514, 50515, 50516, 50517, 50518, 50519, 50520, 50521, 50522, 50523, 50524, 50525, 50526, 50527, 50528, 50529, 50530, 50531, 50532, 50533, 50534, 50535, 50536, 50537, 50538, 55774, 113528, 123215, 123216, 123217, 146079, 146080, 146081, 148424, 148425, 148426, 149024, 151974, 151975, 151976, 151977, 151978, 151979, 151983, 151984, 152574, 152575, 152576, 152577, 152578, 152579, 152580, 152581, 152582, 152584, 152585, 152586, 152587, 165549, 165558, 176348, 176794, 176795, 176796, 176797, 176798, 176799, 176800, 176801, 176945, 176946, 176947, 176948, 176949, 176950, 176958, 176959, 176960, 176961, 176967, 176968, 176969, 176970, 176971, 176972, 176973, 176978, 176979, 176980, 176981, 176982, 176983, 176984, 176985, 176986, 176987, 176988, 176989, 176990, 176991, 176992, 176993, 176994, 177104, 177105, 177106, 177107, 177108, 177109, 177110, 177111, 177112, 177113, 177114, 177115, 177116, 177117, 177118, 177119, 177120, 177121, 177122, 177123, 177124, 177125, 177126, 177127, 177128, 177129, 177130, 177131, 177132, 177133, 177134, 177135, 177136, 177137, 177138, 177139, 177140, 177141, 177142, 177143, 177144, 177145, 177146, 177147, 177148, 177149, 177150, 177151, 177152, 177153, 177154, 177155, 177185, 177186, 179144, 179224, 181361, 181367, 181368, 181691, 181692, 181693, 181760, 181761, 181762, 181763, 181764, 181765, 181776, 181777, 181778, 181791, 181792, 181793, 181794, 181795, 181796, 181826, 181827, 181830, 181934, 181935, 181936, 181937, 181938, 181939, 181940, 181941, 181942, 181943, 181944, 181945, 181946, 181947, 181948, 181949, 181950, 181951, 181952, 181953, 181967, 181968, 181969, 181970, 181971, 181972, 181973, 181974, 181975, 181976, 181977, 181985, 181986, 182002, 182003, 182004, 182014, 182018, 182020, 182021, 182022, 182023, 182028, 182029, 182100, 182101, 182102, 182103, 182104, 182105, 182109, 182113, 182123, 182124, 182125, 182126, 182129, 182130, 182131, 182132, 182133, 182134, 182135, 182136, 182137, 182138, 182168, 182169, 182170, 182171, 182172, 182177, 182178, 182179, 182180, 182181, 182189, 182190, 182191, 182192, 182193, 182194, 182212, 182283, 182284, 182285, 182286, 182287, 182288, 182289, 182290, 182291, 182292, 182293, 182294, 182295, 182296, 182309, 182310, 182311, 182312, 182313, 182314, 182347, 182348, 182370, 182371, 182372, 182373, 182374, 182375, 182379, 182380, 182381, 182382, 182383, 182384, 182385, 182394, 182395, 182396, 182397, 182398, 182399, 182406, 182407, 182408, 182409, 182410, 182411, 182412, 182511, 182512, 182513, 182514, 182515, 182516, 182517, 182518, 182552, 182553, 182554, 182555, 182556, 182557, 183199, 183200, 183201, 183205, 183206, 183207, 183208, 183209, 183210, 183211, 183212, 183213, 183214, 183215, 183216, 183231, 183232, 183233, 183234, 183235, 183236, 183237, 183238, 183239, 183240, 183241, 183242, 183243, 183244, 183245, 183246, 183247, 183248, 183249, 183250, 183251, 183252, 183253, 183254, 183255, 183256, 183257, 183258, 183259, 183260, 183261, 183262, 183263, 183264, 183350, 183351, 183468, 183469, 183470, 183471, 183472, 183473, 183474, 183475, 183476, 183477, 183478, 183479, 183480, 183481, 183482, 183485, 183486, 183487, 183853, 183854, 183921, 184057, 184058, 184059, 184060, 184061, 184062, 184063, 184064, 184065, 184066, 184067, 184068, 184074, 184149, 184150, 184151, 184153, 184154, 184155, 184156, 184157, 184158, 184159, 184160, 184248, 184249, 184250, 184256, 184257, 184258, 184259, 184260, 184261, 184262, 184263, 184264, 184266, 184267, 184268, 184269, 184270, 184271, 184272, 184291, 184292, 184293, 184402, 184403, 184404, 184405, 184406, 184407, 184408, 184409, 184410, 184411, 184412, 184518, 184519, 184520, 184521, 184522, 184523, 184533, 184534, 184535, 184536, 184537, 184538, 184539, 184540, 184541, 184542, 184543, 184544, 184545, 184546, 184547, 184548, 184549, 184550, 184551, 184552, 184553, 184624, 184625, 184626, 184627, 184628, 184629, 184630, 185062, 185063, 185064, 185065, 185066, 185067, 185068, 185069, 185070, 185071, 185072, 185073, 185074, 185075, 185076, 185077, 185078, 185079, 185080, 185081, 185082, 185083, 185084, 185085, 185086, 185087, 185088, 185089, 185090, 185091, 185092, 185093, 185094, 185095, 185096, 185097, 185098, 185099, 185100, 185101, 186240, 186241, 186242, 186479, 186480, 186481, 186519, 186520, 186521, 186522, 186523, 186524, 186525, 186526, 186527, 186528, 186529, 186530, 186531, 186532, 186533, 186534, 186535, 186536, 186537, 186538, 186539, 186540, 186541, 186542, 186543, 186544, 186545, 186546, 186547, 186548, 186549, 186550, 186551, 186552, 186553, 186554, 186577, 186578, 186579, 186580, 186603, 186604, 186757, 187275, 187276, 187277, 187278, 187279, 187280, 187281, 187282, 187283, 187284, 187285, 187286, 187287, 187297, 187298, 187300, 187301, 187302, 187303, 187304, 187305, 187306, 187307, 187312, 187313, 187324, 187325, 187326, 187327, 187328, 187338, 187339, 187341, 187343, 187346, 187348, 187349, 187350, 187351, 187352, 187353, 187354, 187355, 188265, 188266, 188267, 188268, 188269, 188270, 188271, 188272, 188273, 188274, 188275, 188276, 188277, 188278, 188279, 188280, 188281, 188282, 188283, 188284, 188285, 188286, 188290, 188291, 188292, 188293, 188294, 188295, 188296, 188297, 188298, 188299, 188300, 188301, 188302, 188303, 188304, 188305, 188306, 188307, 188308, 188309, 188310, 188311, 188312, 188313, 188314, 188315, 188316, 188317, 188318, 188319, 188320, 188321, 188322, 188323, 188324, 188325, 188326, 188327, 188328, 188329, 188330, 188331, 188332, 188333, 188334, 188335, 188336, 188337, 188338, 188339, 188371, 188372, 188373, 188375, 188376, 188377, 188378, 188379, 188380, 188381, 188382, 188383, 188387, 188388, 188389, 188390, 188391, 188392, 188393, 188394, 188395, 188398, 188399, 188400, 188401, 188402, 188403, 188404, 188405, 188406, 188407, 188408, 188409, 188410, 188411, 188412, 188413, 188414, 188496, 188535, 190179, 190180, 190662, 190789, 190791, 190792, 190793, 190799, 190800, 190801, 190802, 190804, 190805, 190806, 190807, 190808, 190809, 190810, 190811, 190812, 190813, 190814, 190815, 190859, 190860, 190861, 190862, 190863, 190864, 190865, 190866, 190867, 190868, 190869, 190870, 190871, 190872, 190873, 190874, 190875, 190876, 190877, 190878, 190879, 190880, 190881, 190882, 190883, 190884, 190885, 190886, 190887, 190888, 190889, 190890, 190891, 190892, 190893, 190894, 190895, 190896, 190898, 190899, 190900, 190901, 190902, 190903, 190904, 190905, 190906, 190907, 190908, 190909, 190910, 190911, 190912, 190913, 190919, 190920, 190921, 190922, 190923, 190924, 190925, 190926, 190927, 190928, 190929, 190930, 190931, 190932, 190933, 190934, 190935, 191165, 191166, 191167, 191168, 191169, 191170, 191171, 191172, 191173, 191174, 191175, 191176, 191177, 191178, 191190, 191191, 191203, 191204, 191205, 191206, 191207, 191208, 191223, 191224, 191261, 191262, 191263, 191264, 191265, 191266, 191267, 191268, 191269, 191270, 191271, 191511, 191512, 191513, 191514, 191515, 191516, 191517, 191660, 191661, 192038, 192044, 192161, 192162, 192166, 192252, 192253, 192254, 192255, 192266, 192267, 192268, 192269, 192270, 192271, 192272, 192273, 192274, 192275, 192276, 192277, 192278, 192279, 192280, 192281, 192282, 192283, 192284, 192285, 192286, 192287, 192288, 192289, 192290, 192291, 192292, 192299, 192304, 192305, 192306, 192307, 192308, 192309, 192310, 192312, 192313, 192314, 192316, 192317, 192318, 192319, 192320, 192321, 192322, 192323, 192324, 192325, 192326, 192327, 192328, 192329, 192330, 192331, 192332, 192333, 192334, 192335, 192336, 192338, 192339, 192349, 192350, 192351, 192352, 192353, 192354, 192355, 192356, 192357, 192358, 192359, 192360, 192361, 192362, 192363, 192364, 192366, 192367, 192368, 192369, 192370, 192371, 192372, 192373, 192374, 192375, 192376, 192378, 192379, 192400, 192401, 192406, 192407, 192408, 192409, 192414, 192415, 192416, 192417, 192418, 192423, 192424, 192425, 192426, 192427, 192428, 192429, 192430, 192431, 192432, 192433, 192434, 192435, 192440, 192441, 192442, 192443, 192444, 192449, 192450, 192451, 192452, 192453, 192458, 192459, 192460, 192461, 192522, 192575, 192576, 192577, 192578, 192579, 192657, 192658, 192714, 192715, 192716, 192718, 192722, 192723, 192724, 192725, 192726, 192727, 192728, 192729, 192730, 192731, 192767, 192768, 192769, 192770, 192771, 192772, 192787, 192797, 192798, 192799, 192800, 192801, 192802, 192803, 192804, 192805, 192806, 192807, 192808, 192809, 192810, 192811, 192812, 192813, 192814, 192815, 192816, 192817, 192821, 192822, 192859, 192860, 192919, 192920, 192921, 192922, 192923, 192924, 192925, 192926, 192927, 192928, 192929, 192930, 192931, 192934, 192935, 192936, 192937, 192938, 192953, 192954, 192955, 192956, 192957, 192958, 192959, 192960, 192961, 192962, 192963, 192964, 192965, 192966, 192967, 192968, 192969, 192970, 192971, 192972, 192973, 192974, 192975, 192976, 192977, 192978, 192979, 192980, 192981, 192982, 192983, 192985, 192986, 192987, 192988, 192989, 192990, 192991, 192992, 192993, 192994, 192995, 192996, 192997, 192999, 193000, 193001, 193002, 193029, 193049, 193050, 193096, 193097, 193098, 193099, 193100, 193101, 193102, 193103, 193104, 193105, 193106, 193107, 193108, 193109, 193110, 193111, 193112, 193113, 193114, 193115, 193116, 193117, 193118, 193119, 193120, 193121, 193122, 193123, 193124, 193127, 193128, 193129, 193130, 193131, 193132, 193133, 193134, 193135, 193136, 193137, 193138, 193139, 193140, 193141, 193142, 193143, 193144, 193145, 193146, 193147, 193148, 193149, 193150, 193151, 193152, 193153, 193154, 193155, 193156, 193157, 193158, 193159, 193160, 193161, 193162, 193163, 193164, 193165, 193191, 193192, 193193, 193198, 193428, 193429, 193430, 193431, 193432, 193433, 193434, 193435, 193436, 193437, 193438, 193439, 193440, 193441, 193442, 193443, 193444, 193445, 193446, 193447, 193448, 193449, 193450, 193451, 193452, 193453, 193454, 193455, 193456, 193466, 193467, 193468, 193469, 193470, 193472, 193473, 193474, 193475, 193476, 193477, 193478, 193479, 193480, 193481, 193482, 193483, 193484, 193485, 193486, 193487, 193488, 193489, 193490, 193491, 193492, 193493, 193494, 193495, 193496, 193497, 193498, 193499, 193500, 193501, 193502, 193503, 193504, 193505, 193506, 193507, 193508, 193509, 193510, 193511, 193512, 193513, 193514, 193515, 193516, 193517, 193518, 193519, 193520, 193521, 193522, 193523, 193524, 193525, 193526, 193527, 193528, 193529, 193530, 193531, 193532, 193533, 193534, 193535, 193536, 193537, 193538, 193539, 193540, 193541, 193542, 193543, 193544, 193545, 193546, 193547, 193548, 193549, 193550, 193551, 193552, 193553, 193554, 193555, 193556, 193557, 193558, 193559, 193797, 193798, 193799, 193800, 193801, 193802, 193803, 193804, 193805, 193806, 193807, 193808, 193809, 193810, 193811, 193812, 193813, 193814, 193815, 193816, 193817, 193818, 193819, 193820, 193821, 193822, 193823, 193824, 193825, 193826, 193827, 193828, 193829, 193830, 193831, 193832, 193833, 193834, 193835, 193836, 193837, 193838, 193839, 193840, 193841, 193842, 193843, 193844, 193845, 193846, 193847, 193848, 193849, 193850, 193851, 193852, 193853, 193854, 193855, 193856, 193857, 193858, 193859, 193860, 193861, 193862, 193863, 193864, 193865, 193866, 193867, 193868, 193869, 193870, 193871, 193872, 193873, 193874, 193875, 193876, 193877, 193878, 193879, 193880, 193881, 193882, 193883, 193884, 193885, 193886, 193887, 193888, 193889, 193890, 193891, 193892, 193893, 193894, 193895, 193940, 193985, 194163, 194164, 194165, 194166, 194167, 194168, 194169, 194170, 194171, 194172, 194176, 194177, 194178, 194205, 194206, 194207, 194589, 194590, 194591, 194592, 194593, 194594, 194595, 194596, 194597, 194598, 194599, 194600, 194601, 194602, 194603, 194604, 194605, 194606, 194607, 194608, 194632, 194648, 194649, 194780, 194781, 194782, 194783, 194784, 194785, 194786, 194811, 194812, 194813, 194814, 194815, 194816, 194817, 194818, 194819, 194832, 194833, 194834, 194835, 194836, 194837, 194838, 194839, 194840, 194841, 194842, 194843, 194844, 194845, 194846, 194847, 194848, 194849, 194850, 194851, 194852, 194853, 194854, 194855, 194856, 194857, 194858, 194859, 194860, 194861, 194862, 194863, 194864, 194865, 194866, 194867, 194868, 194869, 194870, 194871, 194872, 194873, 194874, 194875, 194876, 194877, 194878, 194879, 194880, 194881, 194882, 194883, 194884, 194885, 194886, 194887, 194888, 194889, 194890, 194891, 194892, 194893, 194894, 194895, 194896, 194897, 194898, 194899, 194900, 194901, 195008, 195009, 195010, 195041, 195098, 195099, 195100, 195101, 195102, 195103, 195104, 195105, 195106, 195114, 195115, 195117, 196406, 196409, 196410, 196420, 196421, 196422, 196423, 196424, 196425, 196426, 196427, 196428, 196429, 196430, 196431, 196432, 196433, 196434, 196435, 196436, 196437, 196438, 196441, 196442, 196443, 196444, 196446, 196447, 196448, 196449, 196450, 196451, 196452, 196453, 196454, 196455, 196456, 196463, 196818, 196819, 196820, 196821, 196822, 196823, 196824, 196825, 196826, 196827, 196828, 196841, 196843, 196844, 196850, 196851, 196866, 196867, 196868, 196869, 196873, 196875, 196876, 196877, 196881, 196882, 201604, 201731, 201783, 201784, 201785, 201786, 201787, 201788, 201854, 201859, 201860, 201861, 201862, 201863, 201864, 201865, 202117, 202118, 202119, 202120, 202121, 202166, 202171, 202213, 202297, 202299, 202326, 202327, 202328, 202329, 202330, 202331, 202332, 202333, 202334, 202341, 202342, 202343, 202344, 202345, 202346, 202354, 202355, 202356, 202369, 202370, 202371, 202372, 202373, 202374, 202377, 202378, 202379, 202380, 202381, 202382, 202383, 202384, 202385, 202386, 202388, 202389, 202390, 202424, 202425, 202426, 202427, 202428, 202429, 202430, 202431, 202432, 202435, 202454, 202455, 202456, 202457, 202458, 202459, 202481, 202482, 202483, 202484, 202485, 202487, 202488, 202489, 202490, 202491, 202492, 202493, 202496, 202497, 202498, 202499, 202500, 202501, 202502, 202503, 202504, 202505, 202506, 202507, 202508, 202509, 202510, 202511, 202512, 202513, 202514, 202515, 202518, 202519, 202520, 202521, 202522, 202523, 202524, 202526, 202527, 202528, 202529, 202530, 202531, 202532, 203417, 203420, 203421, 203422, 203423, 203424, 203425, 203426, 203447, 203827, 203832, 203833, 203834, 203835, 203836, 203864, 203865, 203866, 203867, 203868, 203869, 203870, 203871, 203872, 203873, 203874, 203875, 203876, 203877, 203878, 203879, 203880, 203881, 203882, 203883, 203884, 203885, 203886, 203887, 203888, 203889, 203890, 203891, 203892, 203893, 203894, 203895, 203896, 203897, 203898, 203899, 203900, 203901, 203902, 203903, 203904, 203905, 203906, 203907, 203908, 203909, 203910, 203911, 203912, 203913, 203914, 203915, 203916, 203917, 203918, 203919, 203920, 203921, 203922, 204530, 204573, 204801, 204802, 204803, 204883, 204961, 205067, 205135, 205136, 205388, 205389, 205491, 205492, 205501, 205502, 205503, 205504, 205505, 205509, 205510, 205511, 205512, 205513, 205515, 205516, 205517, 205518, 205519, 205520, 205521, 205522, 205523, 205971, 205972, 205973, 205974, 205975, 205976, 205977, 205978, 205979, 205980, 205981, 205982, 205983, 205984, 205985, 205986, 205987, 205988, 206089, 206090, 206091, 206282, 206283, 206284, 206285, 206286, 206316, 206317, 206421, 206422, 206423, 206424, 206425, 206426, 206427, 206428, 206429, 206430, 206431, 206432, 206433, 206434, 206435, 206436, 206437, 206440, 206441, 206442, 206443, 206444, 206445, 206446, 206447, 206448, 206449, 206450, 206451, 206452, 206453, 206454, 206455, 206456, 206457, 206458, 206459, 206460, 206461, 206462, 206463, 206464, 206465, 206466, 206467, 206468, 206469, 206470, 206471, 206472, 206473, 206474, 206475, 206476, 206477, 206478, 206479, 206480, 206481, 206482, 206483, 206484, 206485, 206486, 206487, 206488, 206489, 206490, 206491, 206492, 206493, 206494, 206495, 206496, 206497, 206511, 206512, 206513, 206514, 206515, 206516, 206518, 206519, 206520, 206521, 206522, 206523, 206524, 206525, 206526, 206527, 206528, 206680, 206681, 206766, 206851, 206855, 206865, 206866, 206867, 206868, 206935, 206948, 206949, 207164, 207235, 207236, 207237, 207238, 207239, 207240, 207241, 207242, 207243, 207244, 207245, 207246, 207258, 207311, 207312, 207313, 207314, 207315, 207316, 207317, 207318, 207319, 207345, 207360, 207570, 207756, 207757, 207758, 207759, 207760, 207761, 207762, 207948, 207949, 208295, 208334, 208413, 208414, 208415, 208416, 208417, 208418, 208421, 208422, 209666, 209667, 209668, 209758, 209759, 209760, 209764, 209765, 209766, 209767, 209768, 209769, 209770, 209771, 209864, 209865, 209866, 210092, 210093, 210094, 210121, 210147, 210148, 210149, 210150, 210151, 210152, 210153, 210154, 210155, 210156, 210166, 210167, 210168, 210169, 210171, 210172, 210173, 210174, 210585, 210586, 210587, 210588, 210589, 210590, 210592, 210593, 210594, 210595, 210596, 210598, 210599, 210600, 210601, 210624, 210630, 210631, 210632, 210633, 210639, 210640, 210641, 210642, 210643, 210644, 210645, 210646, 210647, 210648, 210649, 210682, 210874, 210875, 210876, 210877, 210878, 210879, 210880, 210881, 210884, 210885, 210886, 210910, 210911, 210912, 210920, 210926, 210927, 210928, 210994, 210995, 210996, 210997, 210998, 210999, 211000, 211101, 211102, 211103, 211104, 211105, 211203, 211214, 211215, 211216, 211217, 211218, 211221, 211222, 211223, 211224, 211227, 211232, 211233, 211234, 211235, 211236, 211237, 211239, 211250, 211251, 211286, 211287, 211288, 211289, 211320, 211321, 211403, 211407, 211462, 211463, 211467, 211468, 211469, 211470, 211471, 211472, 211473, 211629, 211630, 211631, 211632, 211633, 211634, 211635, 211636, 211637, 211638, 211639, 211641, 211697, 211698, 211722, 211723, 211724, 211725, 211726, 211727, 211728, 211729, 211730, 211731, 211732, 211733, 211734, 211735, 211736, 211737, 211738, 211739, 211740, 211741, 211742, 211743, 211744, 211745, 211746, 211747, 211748, 211749, 211750, 211751, 211767, 211886, 211887, 211888, 211889, 211890, 211891, 211892, 211893, 211894, 211895, 211896, 211897, 212049, 212050, 212051, 212052, 212053, 212054, 212055, 212056, 212057, 212058, 212059, 212072, 212073, 212088, 212138, 212139, 212140, 212141, 212142, 212143, 212144, 212145, 212147, 212148, 212150, 212151, 212152, 212194, 212195, 212202, 212203, 212204, 212206, 212326, 212327, 212328, 212329, 212330, 212331, 212332, 212333, 212334, 212335, 212336, 212337, 212338, 212339, 212340, 212341, 212342, 212343, 212344, 212345, 212351, 212354, 212355, 212364, 212366, 212367, 212368, 212369, 212370, 212371, 212372, 212373, 212374, 212403, 212443, 212989, 212990, 212991, 212992, 212993, 212994, 212995, 212996, 212997, 212998, 212999, 213000, 213001, 213002, 213003, 213005, 213006, 213007, 213008, 213009, 213010, 213011, 213012, 213013, 213014, 213015, 213016, 213017, 213018, 213019, 213020, 213021, 213022, 213023, 213024, 213025, 213026, 213027, 213171, 213202, 213203, 213204, 213205, 213206, 213207, 213208, 213209, 213210, 213211, 213212, 213213, 213214, 213215, 213216, 213217, 213218, 213219, 213220, 213221, 213222, 213253, 213367, 213424, 213425, 213426, 213440, 213441, 213442, 213464, 213465, 213652, 214137, 214138, 214139, 214140, 214141, 214142, 214143, 214144, 214145, 214146, 214147, 214148, 214149, 214150, 214151, 214152, 214153, 214254, 214255, 214256, 214257, 214262, 214263, 214264, 214265, 214266, 214267, 214268, 214269, 214270, 214271, 214272, 214273, 214274, 214275, 214276, 214358, 214359, 214360, 214362, 214363, 214364, 214369, 214370, 214371, 214375, 214376, 214377, 214378, 215275, 215589, 215590, 215591, 215592, 215593, 216098, 216341, 216410, 216627, 216942, 216943, 216944, 217759, 217760, 217761, 217762, 217765, 217766, 217767, 218120, 218121, 218122, 218123, 218124, 218125, 218126, 218127, 218128, 218129, 218130, 218131, 218132, 218133, 218134, 218135, 218136, 218137, 218138, 218139, 218140, 218141, 218142, 218143, 218144, 218145, 218146, 218147, 218148, 218149, 218150, 218151, 218152, 218153, 218154, 218155, 218156, 218157, 218158, 218159, 218160, 218161, 218162, 218163, 218164, 218165, 218166, 218167, 218168, 218169, 218170, 218171, 218172, 218173, 218174, 218175, 218176, 218177, 218178, 218179, 218180, 218181, 218182, 218183, 218558, 218559, 218560, 218561, 218562, 218563, 218564, 218565, 218566, 218567, 218568, 218569, 218570, 218908, 218911, 218912, 218917, 227290, 229494, 229495, 229496, 232156, 232310, 232470, 232508, 232509, 232510, 233169, 233170, 233306, 233427, 233537, 233540, 233541, 233542, 233543, 233544, 233545, 233546, 233547, 233548, 233964, 233977, 234317, 234318, 234319, 234320, 234321, 234322, 234323, 234324, 234325, 234326, 234327, 234328, 234329, 234330, 234331, 234332, 234333, 234334, 234335, 234336, 234337, 234338, 234339, 234340, 234341, 234342, 234343, 234344, 234345, 234346, 234347, 234348, 234349, 234350, 234351, 234352, 234353, 234354, 234355, 234356, 234357, 234358, 234359, 234360, 234361, 234362, 234363, 234364, 234365, 234366, 234367, 234368, 234369, 234370, 234371, 234372, 234373, 234374, 234375, 234376, 234377, 234378, 234379, 234380, 234381, 234382, 234383, 234384, 234385, 234386, 234387, 234388, 234389, 234390, 234391, 234392, 234393, 234394, 234395, 234396, 234397, 234398, 234399, 234400, 234401, 234402, 234403, 234404, 234405, 234406, 234407, 234408, 234409, 234410, 234411, 234476, 234477, 234478, 234479, 234480, 234481, 234482, 234483, 234484, 234485, 234486, 234487, 234488, 234489, 234490, 234493, 234494, 234495, 234496, 234497, 234498, 234499, 234500, 234501, 234502, 234503, 234504, 234505, 234506, 234507, 234508, 234509, 234510, 234511, 234512, 234513, 234514, 234515, 234516, 234518, 234519, 234520, 234521, 234522, 234523, 234524, 234525, 234526, 234527, 234528, 234529, 234530, 234531, 234532, 234533, 234534, 234535, 234536, 234537, 234538, 234539, 234540, 234541, 234542, 234543, 234544, 234545, 234546, 234547, 234548, 234549, 234673, 234674, 234675, 234676, 234677, 236204, 236422, 236489, 236494, 236606, 236616, 236620, 236625, 236635, 236964, 236965, 236966, 236969, 236970, 236971, 236972, 236973, 236974, 236975, 236976, 236977, 236978, 237013, 237040, 237041, 237042, 237108, 237153, 237154, 237155, 237156, 237157, 237158, 237211, 237212, 237213, 237214, 237215, 237216, 237217, 237218, 237219, 237220, 237221, 237222, 237232, 237233, 237234, 237235, 237236, 237237, 237238, 237239, 237240, 237241, 237242, 237243, 237244, 237245, 237246, 237247, 237248, 237249, 237250, 237251, 237252, 237253, 237254, 237292, 237293, 237362, 237363, 237368, 237510, 237522, 237523, 237524, 237811, 237812, 237813, 237814, 237815, 237816, 237817, 237818, 237819, 237820, 237824, 237825, 237826, 237827, 237828, 237829, 237830, 237831, 237832, 237833, 237834, 237835, 237836, 237837, 237838, 237839, 237840, 237841, 237842, 237845, 237846, 237847, 237848, 237849, 237850, 237860, 237861, 237862, 237863, 237864, 237865, 237866, 237867, 237868, 237869, 237870, 237871, 237872, 237873, 237874, 237875, 237876, 237893, 237894, 237895, 237896, 237897, 237898, 237899, 237901, 237902, 238035, 238074, 238076, 238080, 238081, 238082, 238083, 238084, 238085, 238086, 238087, 238088, 238089, 238090, 238091, 238092, 238093, 238094, 238095, 238096, 238097, 238098, 238099, 238100, 238101, 238102, 238103, 238212, 238214, 238215, 238216, 238217, 238218, 238219, 238220, 238221, 238222, 238223, 238224, 238225, 238226, 238227, 238228, 238229, 238230, 238231, 238232, 238233, 238308, 238309, 238322, 238342, 238343, 238345, 238346, 238347, 238349, 238350, 238368, 238369, 238370, 238371, 238372, 238373, 238374, 238375, 238376, 238377, 238379, 238380, 238381, 238382, 238383, 238384, 238565, 238622, 238623, 238624, 238625, 238626, 238627, 238628, 238629, 238630, 238631, 238632, 238633, 238634, 238635, 238636, 238637, 238638, 238639, 238640, 238641, 238642, 238669, 238670, 238671, 238672, 238673, 238674, 238675, 238676, 238677, 238678, 238679, 238707, 238708, 238709, 238710, 238711, 238712, 238714, 238753, 238846, 238888, 238889, 238897, 238898, 238899, 238900, 239068, 239069, 239070, 239074, 239075, 239076, 239077, 239149, 239150, 239151, 239153, 239154, 239155, 239156, 239157, 239158, 239159, 239161, 239162, 239163, 239165, 239166, 239167, 239172, 239173, 239265); diff --git a/sql/updates/world/2015_05_10_01_world.sql b/sql/updates/world/2015_05_10_01_world.sql new file mode 100644 index 00000000000..ba2dc1516f2 --- /dev/null +++ b/sql/updates/world/2015_05_10_01_world.sql @@ -0,0 +1,505 @@ +SET @CGUID := 370955; +SET @OGUID := 233610; + + +UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry`=67329; + +DELETE FROM `creature` WHERE `id` IN (55475, 56160); +DELETE FROM `gameobject` WHERE `id`=179965; +DELETE FROM `gameobject` WHERE `guid` IN (213585, 213588, 213591, 213610, 213611, 213624, 213625, 213683); + +DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+315; +INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `MovementType`) VALUES +(@CGUID+0, 55347, 974, 1, -3540.458, 6091.649, 3.064309, 2.75752, 120, 0, 0), -- 55347 (Area: 5869) (Auras: 73809 - 73809) +(@CGUID+1, 55347, 974, 1, -3544.965, 6093.71, 4.785177, 2.75752, 120, 0, 0), -- 55347 (Area: 5869) (Auras: 70764 - 70764) +(@CGUID+2, 55347, 974, 1, -3546.406, 6094.889, 3.710032, 2.75752, 120, 0, 0), -- 55347 (Area: 5869) (Auras: 73810 - 73810) +(@CGUID+3, 55347, 974, 1, -3546.455, 6089.76, 5.124798, 2.75752, 120, 0, 0), -- 55347 (Area: 5869) (Auras: 73811 - 73811) +(@CGUID+4, 55347, 974, 1, -3547.651, 6091.432, 4.107487, 2.776647, 120, 0, 0), -- 55347 (Area: 5869) (Auras: 70764 - 70764) +(@CGUID+5, 55347, 974, 1, -3552.378, 6084.578, 4.111493, 2.75752, 120, 0, 0), -- 55347 (Area: 5869) (Auras: 70764 - 70764) +(@CGUID+6, 55347, 974, 1, -3876.087, 6715.112, 3.523933, 2.75752, 120, 0, 0), -- 55347 (Area: 0) (Auras: 73811 - 73811) +(@CGUID+7, 55347, 974, 1, -3876.469, 6713.583, 3.545249, 2.75752, 120, 0, 0), -- 55347 (Area: 0) (Auras: 73810 - 73810) +(@CGUID+8, 55347, 974, 1, -3880.024, 6707.007, 2.658832, 2.164, 120, 0, 0), -- 55347 (Area: 0) (Auras: 73811 - 73811) +(@CGUID+9, 55347, 974, 1, -4018.266, 6363.103, 13.20009, 2.098049, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73809 - 73809) +(@CGUID+10, 55347, 974, 1, -4018.988, 6366.712, 13.20009, 4.435287, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 70764 - 70764) +(@CGUID+11, 55347, 974, 1, -4021.135, 6365.648, 13.20009, 5.983479, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73104 - 73104) +(@CGUID+12, 55347, 974, 1, -4046.467, 6351.809, 13.20009, 4.554671, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73811 - 73811) +(@CGUID+13, 55347, 974, 1, -4046.663, 6348.137, 13.20009, 1.936678, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 70764 - 70764) +(@CGUID+14, 55347, 974, 1, -4048.806, 6351.314, 13.20009, 5.70659, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73809 - 73809) +(@CGUID+15, 55347, 974, 1, -4085.885, 6320.245, 11.04892, 3.857727, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73809 - 73809) +(@CGUID+16, 55347, 974, 1, -4087.995, 6321.37, 11.16493, 5.009645, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73809 - 73809) +(@CGUID+17, 55347, 974, 1, -4088.007, 6318.624, 11.74757, 1.196441, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 70764 - 70764) +(@CGUID+18, 55347, 974, 1, -4397.738, 6259.018, 15.20177, 3.253297, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73810 - 73810) +(@CGUID+19, 55347, 974, 1, -4398.509, 6262.621, 14.76891, 3.253297, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73809 - 73809) +(@CGUID+20, 55347, 974, 1, -4399.425, 6416.393, 15.24004, 2.776647, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73104 - 73104) +(@CGUID+21, 55347, 974, 1, -4399.543, 6260.809, 14.18574, 3.253297, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73809 - 73809) +(@CGUID+22, 55347, 974, 1, -4399.634, 6403.269, 15.4001, 3.110595, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73810 - 73810) +(@CGUID+23, 55347, 974, 1, -4399.684, 6400.793, 15.25402, 3.091469, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73811 - 73811) +(@CGUID+24, 55347, 974, 1, -4400.174, 6390.691, 15.73887, 3.253298, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73810 - 73810) +(@CGUID+25, 55347, 974, 1, -4400.186, 6388.663, 15.59765, 3.253297, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 70764 - 70764) +(@CGUID+26, 55347, 974, 1, -4400.268, 6261.924, 13.73682, 3.253297, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73810 - 73810) +(@CGUID+27, 55347, 974, 1, -4400.337, 6263.297, 13.77441, 3.253297, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73809 - 73809) +(@CGUID+28, 55347, 974, 1, -4400.613, 6416.221, 14.66377, 2.75752, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73104 - 73104) +(@CGUID+29, 55347, 974, 1, -4401.156, 6389.884, 14.98538, 3.253297, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 70764 - 70764) +(@CGUID+30, 55347, 974, 1, -4401.266, 6386.76, 14.97509, 3.253297, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73811 - 73811) +(@CGUID+31, 55347, 974, 1, -4401.724, 6399.641, 14.2447, 3.091469, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73811 - 73811) +(@CGUID+32, 55347, 974, 1, -4401.832, 6413.436, 14.16104, 2.75752, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73811 - 73811) +(@CGUID+33, 55347, 974, 1, -4401.965, 6391.114, 14.53761, 3.253297, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73104 - 73104) +(@CGUID+34, 55347, 974, 1, -4402.168, 6387.969, 14.41535, 3.253297, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73809 - 73809) +(@CGUID+35, 55347, 974, 1, -4402.316, 6415.527, 13.68543, 2.75752, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 70764 - 70764) +(@CGUID+36, 55347, 974, 1, -4402.431, 6413.934, 13.73137, 2.75752, 120, 0, 0), -- 55347 (Area: 5870) (Auras: 73811 - 73811) +(@CGUID+37, 55348, 974, 1, -3543.615, 6081.485, 3.064309, 2.922005, 120, 0, 0), -- 55348 (Area: 5869) (Auras: 73813 - 73813) +(@CGUID+38, 55348, 974, 1, -3545.137, 6091.799, 5.200503, 2.922005, 120, 0, 0), -- 55348 (Area: 5869) (Auras: 73813 - 73813) +(@CGUID+39, 55348, 974, 1, -3547.948, 6092.467, 3.654778, 2.922005, 120, 0, 0), -- 55348 (Area: 5869) (Auras: 73814 - 73814) +(@CGUID+40, 55348, 974, 1, -3549.49, 6085.556, 5.243183, 2.922005, 120, 0, 0), -- 55348 (Area: 5869) (Auras: 73814 - 73814) +(@CGUID+41, 55348, 974, 1, -3550.72, 6085.498, 4.617259, 2.947497, 120, 0, 0), -- 55348 (Area: 5869) (Auras: 73813 - 73813) +(@CGUID+42, 55348, 974, 1, -3551.094, 6088.04, 3.703641, 3.207578, 120, 0, 0), -- 55348 (Area: 5869) (Auras: 73814 - 73814) +(@CGUID+43, 55348, 974, 1, -3552.179, 6086.276, 3.646801, 2.922005, 120, 0, 0), -- 55348 (Area: 5869) (Auras: 71084 - 71084) +(@CGUID+44, 55348, 974, 1, -3873.778, 6715.913, 4.638102, 2.947497, 120, 0, 0), -- 55348 (Area: 0) (Auras: 71084 - 71084) +(@CGUID+45, 55348, 974, 1, -3874.514, 6713.628, 4.461677, 2.922005, 120, 0, 0), -- 55348 (Area: 0) (Auras: 73815 - 73815) +(@CGUID+46, 55348, 974, 1, -3874.882, 6715.642, 4.027105, 2.922005, 120, 0, 0), -- 55348 (Area: 0) (Auras: 73815 - 73815) +(@CGUID+47, 55348, 974, 1, -3875.983, 6712.429, 3.9605, 2.922005, 120, 0, 0), -- 55348 (Area: 0) (Auras: 71084 - 71084) +(@CGUID+48, 55348, 974, 1, -3876.658, 6727.082, 2.908752, 3.207578, 120, 0, 0), -- 55348 (Area: 0) (Auras: 71084 - 71084) +(@CGUID+49, 55348, 974, 1, -4024.365, 6339.249, 13.20009, 3.659704, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73814 - 73814) +(@CGUID+50, 55348, 974, 1, -4026.936, 6336.401, 13.20008, 1.261948, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73813 - 73813) +(@CGUID+51, 55348, 974, 1, -4027.979, 6338.556, 13.20009, 5.996943, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 71084 - 71084) +(@CGUID+52, 55348, 974, 1, -4126.009, 6364.827, 10.47646, 3.212799, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73814 - 73814) +(@CGUID+53, 55348, 974, 1, -4128.361, 6366.359, 10.59303, 4.916115, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73813 - 73813) +(@CGUID+54, 55348, 974, 1, -4129.24, 6363.924, 10.10825, 0.8572226, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 71084 - 71084) +(@CGUID+55, 55348, 974, 1, -4379.616, 6380.463, 12.01801, 1.850658, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73813 - 73813) +(@CGUID+56, 55348, 974, 1, -4397.399, 6273.063, 15.19376, 2.947497, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73814 - 73814) +(@CGUID+57, 55348, 974, 1, -4398.363, 6275.321, 14.73031, 2.947497, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73815 - 73815) +(@CGUID+58, 55348, 974, 1, -4398.715, 6244.944, 14.6917, 2.947497, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73815 - 73815) +(@CGUID+59, 55348, 974, 1, -4399.198, 6272.111, 14.19004, 2.947497, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73815 - 73815) +(@CGUID+60, 55348, 974, 1, -4399.554, 6248.596, 14.33591, 2.947497, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73813 - 73813) +(@CGUID+61, 55348, 974, 1, -4399.681, 6414.704, 15.16792, 2.922005, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73813 - 73813) +(@CGUID+62, 55348, 974, 1, -4399.702, 6399.29, 15.23775, 2.922005, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73813 - 73813) +(@CGUID+63, 55348, 974, 1, -4400.215, 6274.204, 13.71256, 2.947497, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 71084 - 71084) +(@CGUID+64, 55348, 974, 1, -4400.252, 6276.461, 13.76355, 2.947497, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73814 - 73814) +(@CGUID+65, 55348, 974, 1, -4400.3, 6417.96, 14.81304, 2.947497, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73814 - 73814) +(@CGUID+66, 55348, 974, 1, -4400.573, 6401.828, 14.71149, 3.541528, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73815 - 73815) +(@CGUID+67, 55348, 974, 1, -4400.856, 6403.986, 14.89527, 3.281446, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73813 - 73813) +(@CGUID+68, 55348, 974, 1, -4400.995, 6413.729, 14.62116, 2.922005, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73813 - 73813) +(@CGUID+69, 55348, 974, 1, -4401.505, 6403.733, 14.34081, 3.255954, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 71084 - 71084) +(@CGUID+70, 55348, 974, 1, -4402.309, 6417.276, 13.71753, 2.922005, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73813 - 73813) +(@CGUID+71, 55348, 974, 1, -4402.323, 6400.667, 13.79684, 3.255954, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73815 - 73815) +(@CGUID+72, 55348, 974, 1, -4402.393, 6403.033, 13.79647, 3.255954, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73814 - 73814) +(@CGUID+73, 55348, 974, 1, -4403.847, 6417.264, 13.19444, 3.207578, 120, 0, 0), -- 55348 (Area: 5870) (Auras: 73813 - 73813) +(@CGUID+74, 55475, 974, 1, -3313.932, 6321.429, -26.46885, 5.073973, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+75, 55475, 974, 1, -3339.386, 6404.537, -27.57644, 5.386951, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+76, 55475, 974, 1, -3346.2, 6351.918, -19.01271, 5.107406, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+77, 55475, 974, 1, -3381.229, 6460.036, -24.86264, 4.886246, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+78, 55475, 974, 1, -3381.477, 6386.271, -23.9986, 1.459757, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+79, 55475, 974, 1, -3402.45, 6342.028, -17.38725, 3.010418, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+80, 55475, 974, 1, -3415.417, 6416.553, -21.49718, 2.96623, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+81, 55475, 974, 1, -3417.408, 6481.66, -23.58585, 3.368099, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+82, 55475, 974, 1, -3426.541, 6212.081, -23.02631, 1.561031, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+83, 55475, 974, 1, -3443.797, 6387.824, 1.670958, 1.845875, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+84, 55475, 974, 1, -3445.322, 6317.903, -2.592931, 0.1023915, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+85, 55475, 974, 1, -3447.342, 6363.225, 1.474651, 0.2970642, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+86, 55475, 974, 1, -3449.624, 6478.326, -7.744728, 2.338469, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+87, 55475, 974, 1, -3452.093, 6508.332, -9.212231, 1.255219, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+88, 55475, 974, 1, -3455.005, 6142.754, -30.86743, 3.929064, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+89, 55475, 974, 1, -3455.513, 6413.271, 2.663992, 4.0767, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+90, 55475, 974, 1, -3465.677, 6562.523, -13.99, 3.568454, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+91, 55475, 974, 1, -3471.428, 6459.488, -0.4364587, 0.3251488, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+92, 55475, 974, 1, -3478.317, 6469.908, 0.4252121, 5.246521, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+93, 55475, 974, 1, -3478.498, 6211.152, -27.73287, 6.228446, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+94, 55475, 974, 1, -3492.434, 6181.876, -31.7241, 2.82975, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+95, 55475, 974, 1, -3510.077, 6521.693, -6.995232, 2.019715, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+96, 55475, 974, 1, -3512.833, 6581.43, -16.43451, 5.336159, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+97, 55475, 974, 1, -3518.728, 6151.486, -35.04684, 5.750471, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+98, 55475, 974, 1, -3521.494, 6653.508, -15.92994, 1.675562, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+99, 55475, 974, 1, -3521.743, 6495.504, -0.2447563, 4.649848, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+100, 55475, 974, 1, -3532.04, 6079.061, -16.22413, 0.1291976, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+101, 55475, 974, 1, -3536.587, 5972.348, -25.70953, 3.983676, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+102, 55475, 974, 1, -3537.634, 6021.59, -12.38275, 3.854601, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+103, 55475, 974, 1, -3548.913, 6681.281, -16.2923, 2.347504, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+104, 55475, 974, 1, -3551.593, 6510.098, 0.6369895, 2.652493, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+105, 55475, 974, 1, -3576.409, 6117.609, -23.30301, 5.360305, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+106, 55475, 974, 1, -3581.899, 6165.564, -9.588398, 1.34465, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+107, 55475, 974, 1, -3583.029, 6653.2, -21.48125, 4.491813, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+108, 55475, 974, 1, -3585.837, 6713.762, -14.28456, 0.6416745, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+109, 55475, 974, 1, -3596.543, 5936.433, -28.12582, 2.927438, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+110, 55475, 974, 1, -3605.443, 6142.803, -1.119677, 1.598133, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+111, 55475, 974, 1, -3612.821, 6038.208, -22.87453, 0.3841309, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+112, 55475, 974, 1, -3612.865, 6753.339, -16.22926, 1.31397, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+113, 55475, 974, 1, -3618.269, 6117.788, -13.03176, 3.322225, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+114, 55475, 974, 1, -3623.945, 6615.721, -19.18533, 4.569964, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+115, 55475, 974, 1, -3636.703, 6153.813, 4.964289, 5.585937, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+116, 55475, 974, 1, -3641.342, 6858.263, -26.42858, 0.7066046, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+117, 55475, 974, 1, -3641.504, 6790.919, -18.86576, 0.5381923, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+118, 55475, 974, 1, -3644.3, 6652.433, 4.033398, 4.237825, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+119, 55475, 974, 1, -3644.798, 6082.059, -20.93716, 1.466425, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+120, 55475, 974, 1, -3645.861, 6883.971, -24.53216, 5.604813, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+121, 55475, 974, 1, -3650.303, 6673.94, 2.73331, 6.145986, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+122, 55475, 974, 1, -3652.542, 6726.625, -11.63122, 6.104555, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+123, 55475, 974, 1, -3653.366, 5959.856, -24.37609, 5.032287, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+124, 55475, 974, 1, -3665.284, 6686.991, 2.432378, 6.197391, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+125, 55475, 974, 1, -3673.565, 6748.247, -3.262143, 2.372767, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+126, 55475, 974, 1, -3682.457, 6819.666, -19.65886, 6.071726, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+127, 55475, 974, 1, -3685.824, 6053.145, -24.17451, 2.395765, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+128, 55475, 974, 1, -3691.061, 6708.265, 5.928362, 5.419367, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+129, 55475, 974, 1, -3696.415, 6854.742, -8.366364, 4.439289, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+130, 55475, 974, 1, -3712.752, 6769.752, 2.053334, 5.838404, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+131, 55475, 974, 1, -3714.802, 6022.569, -25.93663, 2.459033, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+132, 55475, 974, 1, -3718.174, 5984.207, -26.95175, 4.683887, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+133, 55475, 974, 1, -3729.87, 6076.369, -24.28646, 6.236253, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+134, 55475, 974, 1, -3741.677, 6808.621, -8.687475, 6.090551, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+135, 55475, 974, 1, -3749.409, 6019.45, -36.08316, 5.37283, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+136, 55475, 974, 1, -3749.938, 6747.255, 6.14193, 2.438644, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+137, 55475, 974, 1, -3776.875, 6038.385, -28.88736, 4.172343, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+138, 55475, 974, 1, -3781.219, 5985.999, -39.33307, 5.821286, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+139, 55475, 974, 1, -3785.611, 6853.598, -15.78474, 4.187766, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+140, 55475, 974, 1, -3788.819, 6793.6, -0.4130653, 2.948139, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+141, 55475, 974, 1, -3789.902, 5909.818, -34.90617, 1.069579, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+142, 55475, 974, 1, -3810.934, 6811.86, -3.405523, 3.065103, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+143, 55475, 974, 1, -3813.611, 5948.4, -34.03601, 4.259658, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+144, 55475, 974, 1, -3813.683, 6872.369, -16.24017, 5.83448, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+145, 55475, 974, 1, -3814.552, 5884.688, -31.88101, 0.6773392, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+146, 55475, 974, 1, -3815.823, 6756.446, 1.296972, 4.483981, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+147, 55475, 974, 1, -3849.52, 6848.309, -20.27527, 2.141776, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+148, 55475, 974, 1, -3851.174, 5914.97, -36.0111, 3.128898, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+149, 55475, 974, 1, -3851.811, 6790.34, -4.522545, 5.938585, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+150, 55475, 974, 1, -3852.365, 5955.535, -30.07961, 4.60087, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+151, 55475, 974, 1, -3854.069, 6726.759, 1.881665, 2.685318, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+152, 55475, 974, 1, -3876.026, 5977.604, -0.1827965, 0.2051714, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+153, 55475, 974, 1, -3882.063, 5882.401, -38.56639, 2.454017, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+154, 55475, 974, 1, -3886.623, 5815.576, -24.69967, 3.69432, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+155, 55475, 974, 1, -3891.935, 6813.063, -10.62362, 0.3393468, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+156, 55475, 974, 1, -3894.714, 6754.219, 1.289827, 3.004843, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+157, 55475, 974, 1, -3906.745, 5910.939, -28.37907, 2.851631, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+158, 55475, 974, 1, -3913.412, 6713.687, 5.58995, 4.635511, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+159, 55475, 974, 1, -3913.597, 6772.005, -7.913295, 1.181943, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+160, 55475, 974, 1, -3953.432, 5854.966, -24.49787, 2.724988, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+161, 55475, 974, 1, -3959.7, 6762.418, -4.656868, 6.195178, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+162, 55475, 974, 1, -3988.379, 6781.324, -19.78738, 3.959932, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+163, 55475, 974, 1, -4018.686, 5826.519, -24.92917, 1.823595, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+164, 55475, 974, 1, -4024.432, 6748.363, 0.7076148, 6.10209, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+165, 55475, 974, 1, -4048.701, 6780.272, -18.90916, 2.557926, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+166, 55475, 974, 1, -4079.737, 5781.727, -26.12824, 4.066347, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+167, 55475, 974, 1, -4080.309, 6725.129, 5.331882, 5.312101, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+168, 55475, 974, 1, -4085.937, 6746.07, -0.3708534, 4.537604, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+169, 55475, 974, 1, -4093.656, 5817.984, -5.46735, 2.203755, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+170, 55475, 974, 1, -4112.841, 5833.23, 12.42542, 4.525721, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+171, 55475, 974, 1, -4112.922, 5747.69, -25.27915, 2.884766, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+172, 55475, 974, 1, -4129.155, 6718.981, 0.2849679, 6.133136, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+173, 55475, 974, 1, -4145.771, 6705.766, 0.5044689, 2.851631, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+174, 55475, 974, 1, -4149.671, 5828.402, 9.382803, 3.671634, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+175, 55475, 974, 1, -4152.313, 5781.312, -11.43931, 5.392621, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+176, 55475, 974, 1, -4152.74, 5818.351, 5.761734, 2.389332, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+177, 55475, 974, 1, -4187.34, 5743.708, -24.87604, 3.728196, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+178, 55475, 974, 1, -4190.686, 6723.775, -11.94522, 2.42111, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+179, 55475, 974, 1, -4201.589, 5811.902, 3.438561, 2.781221, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+180, 55475, 974, 1, -4203.925, 6697.944, -0.4997884, 5.270574, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+181, 55475, 974, 1, -4213.943, 6751.24, -15.50737, 0.4753325, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+182, 55475, 974, 1, -4216.863, 5806.103, -0.3531361, 1.263399, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+183, 55475, 974, 1, -4222.583, 5783.536, -13.14024, 2.16576, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+184, 55475, 974, 1, -4254.156, 5827.959, 1.856683, 1.32416, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+185, 55475, 974, 1, -4255.951, 6712.135, -1.90819, 4.636142, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+186, 55475, 974, 1, -4280.682, 5781.994, -14.02826, 1.545411, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+187, 55475, 974, 1, -4281.057, 6705.473, 2.382472, 5.3203, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+188, 55475, 974, 1, -4311.102, 5776.852, -17.00743, 2.16313, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+189, 55475, 974, 1, -4318.055, 6752.943, -27.62305, 1.460733, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+190, 55475, 974, 1, -4320.882, 6684.345, 0.8362814, 1.844127, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+191, 55475, 974, 1, -4338.61, 6647.455, 3.207853, 5.542802, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+192, 55475, 974, 1, -4342.684, 6090.946, -4.94941, 3.508136, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+193, 55475, 974, 1, -4346.649, 5826.934, 1.740823, 6.089581, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+194, 55475, 974, 1, -4355.084, 6711.799, -28.20229, 4.021949, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+195, 55475, 974, 1, -4370.53, 6620.04, 2.050148, 6.087829, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+196, 55475, 974, 1, -4372.023, 5829.926, 0.8718023, 5.746428, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+197, 55475, 974, 1, -4385.319, 6681.877, -30.53719, 2.278209, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+198, 55475, 974, 1, -4387.277, 6151.067, 6.017407, 1.865997, 120, 5, 1), -- 55475 (Area: 5870) (Auras: 51583 - 51583) +(@CGUID+199, 55475, 974, 1, -4400.032, 5888.301, 1.06333, 6.147976, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+200, 55475, 974, 1, -4402.498, 6588.392, 0.4260998, 1.354246, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+201, 55475, 974, 1, -4409.666, 6035.662, -14.26149, 6.100359, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+202, 55475, 974, 1, -4411.721, 6646.702, -29.32209, 5.713609, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+203, 55475, 974, 1, -4413.792, 6085.212, -14.79804, 3.423513, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+204, 55475, 974, 1, -4413.849, 6180.515, 5.317835, 5.96668, 120, 5, 1), -- 55475 (Area: 5870) (Auras: 51583 - 51583) +(@CGUID+205, 55475, 974, 1, -4426.176, 6131.366, -9.031806, 1.985053, 120, 5, 1), -- 55475 (Area: 5870) (Auras: 51583 - 51583) +(@CGUID+206, 55475, 974, 1, -4438.476, 6527.181, 2.461359, 0.6478799, 120, 5, 1), -- 55475 (Area: 5904) (Auras: 51583 - 51583) +(@CGUID+207, 55475, 974, 1, -4439.464, 5931.841, -1.091784, 3.802293, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+208, 55475, 974, 1, -4439.572, 6291.448, -1.263654, 2.882133, 120, 5, 1), -- 55475 (Area: 5870) (Auras: 51583 - 51583) +(@CGUID+209, 55475, 974, 1, -4445.36, 6457.672, 1.502735, 5.701409, 120, 5, 1), -- 55475 (Area: 5870) (Auras: 51583 - 51583) +(@CGUID+210, 55475, 974, 1, -4446.387, 6247.357, -5.866472, 1.471781, 120, 5, 1), -- 55475 (Area: 5870) (Auras: 51583 - 51583) +(@CGUID+211, 55475, 974, 1, -4446.448, 5895.423, -2.954503, 1.039438, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+212, 55475, 974, 1, -4447.519, 6617.916, -24.75529, 0.5312068, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+213, 55475, 974, 1, -4448.618, 6556.146, -11.14995, 1.13948, 120, 5, 1), -- 55475 (Area: 5904) (Auras: 51583 - 51583) +(@CGUID+214, 55475, 974, 1, -4450.187, 6192.325, -3.249295, 0.3683649, 120, 5, 1), -- 55475 (Area: 5870) (Auras: 51583 - 51583) +(@CGUID+215, 55475, 974, 1, -4451.172, 5986.111, -24.06742, 1.44293, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+216, 55475, 974, 1, -4455.343, 6392.197, -5.747448, 3.058451, 120, 5, 1), -- 55475 (Area: 5870) (Auras: 51583 - 51583) +(@CGUID+217, 55475, 974, 1, -4462.831, 6435.464, -7.902214, 1.488819, 120, 5, 1), -- 55475 (Area: 5870) (Auras: 51583 - 51583) +(@CGUID+218, 55475, 974, 1, -4477.391, 6353.027, -14.61291, 0.2626663, 120, 5, 1), -- 55475 (Area: 5904) (Auras: 51583 - 51583) +(@CGUID+219, 55475, 974, 1, -4479.241, 6149.872, -14.53582, 5.868609, 120, 5, 1), -- 55475 (Area: 5904) (Auras: 51583 - 51583) +(@CGUID+220, 55475, 974, 1, -4480.217, 6449.47, -14.22352, 3.138663, 120, 5, 1), -- 55475 (Area: 5904) (Auras: 51583 - 51583) +(@CGUID+221, 55475, 974, 1, -4480.83, 6581.086, -24.30691, 0.2072032, 120, 5, 1), -- 55475 (Area: 0) (Auras: 51583 - 51583) +(@CGUID+222, 55475, 974, 1, -4482.029, 6284.627, -14.99236, 0.07706382, 120, 5, 1), -- 55475 (Area: 5870) (Auras: 51583 - 51583) +(@CGUID+223, 55475, 974, 1, -4482.697, 5949.789, -23.48953, 0.9695857, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+224, 55475, 974, 1, -4488.297, 6515.887, -17.99799, 5.806438, 120, 5, 1), -- 55475 (Area: 5904) (Auras: 51583 - 51583) +(@CGUID+225, 55475, 974, 1, -4508.537, 6316.83, -13.48234, 5.84065, 120, 5, 1), -- 55475 (Area: 5904) (Auras: 51583 - 51583) +(@CGUID+226, 55475, 974, 1, -4512.186, 6184.926, -10.88638, 3.63606, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+227, 55475, 974, 1, -4513.816, 6388.617, -11.04589, 4.789019, 120, 5, 1), -- 55475 (Area: 5904) (Auras: 51583 - 51583) +(@CGUID+228, 55475, 974, 1, -4518.161, 6246.943, -13.29661, 3.27717, 120, 5, 1), -- 55475 (Area: 5904) (Auras: 51583 - 51583) +(@CGUID+229, 55475, 974, 1, -4546.214, 6444.699, -17.15788, 2.611551, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+230, 55475, 974, 1, -4578.979, 6450.634, -14.52264, 0.6321713, 120, 5, 1), -- 55475 (Area: 5869) (Auras: 51583 - 51583) +(@CGUID+231, 56160, 974, 1, -3793.068, 6480.5, 18.38577, 0.4216958, 120, 5, 1), -- Moonfang Snarler (Area: 0) +(@CGUID+232, 56160, 974, 1, -3818.889, 6579.251, 13.75474, 5.759191, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+233, 56160, 974, 1, -3844.143, 6465.961, 11.9775, 5.368204, 120, 5, 1), -- Moonfang Snarler (Area: 0) +(@CGUID+234, 56160, 974, 1, -3890.562, 6418.59, 14.22686, 2.802246, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+235, 56160, 974, 1, -3911.653, 6521.509, 15.92983, 0.8102549, 120, 5, 1), -- Moonfang Snarler (Area: 0) +(@CGUID+236, 56160, 974, 1, -3930.605, 6634.611, 10.02799, 5.350228, 120, 5, 1), -- Moonfang Snarler (Area: 0) (Auras: ) (possible waypoints or random movement) +(@CGUID+237, 56160, 974, 1, -3943.391, 6546.864, 13.23347, 4.229451, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+238, 56160, 974, 1, -3950.127, 6492.447, 19.88531, 2.936915, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+239, 56160, 974, 1, -3980.259, 6703.247, 12.42365, 1.112345, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+240, 56160, 974, 1, -3989.167, 6597.694, 17.62722, 4.199048, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+241, 56160, 974, 1, -4037.84, 6541.493, 16.26394, 5.63148, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+242, 56160, 974, 1, -4044.562, 6649.435, 14.87357, 1.629437, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+243, 56160, 974, 1, -4088.994, 6651.294, 13.36706, 4.611228, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+244, 56160, 974, 1, -4093.011, 6064.556, 16.05633, 0.04595588, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+245, 56160, 974, 1, -4134.839, 6585.866, 19.53601, 2.363102, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+246, 56160, 974, 1, -4158.418, 6640.745, 14.95826, 0.9648843, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+247, 56160, 974, 1, -4193.543, 6561.745, 13.59656, 4.542222, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+248, 56160, 974, 1, -4235.783, 6642.862, 14.43218, 5.552404, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+249, 56160, 974, 1, -4278.184, 6608.144, 12.35217, 0.8278429, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+250, 56160, 974, 1, -4349.397, 6576.323, 10.47269, 0.1333266, 120, 5, 1), -- Moonfang Snarler (Area: 0) (possible waypoints or random movement) +(@CGUID+251, 58570, 974, 1, -3984.116, 6292.029, 13.20008, 0, 120, 0, 0), -- 58570 (Area: 0) +(@CGUID+252, 67319, 974, 1, -4185.753, 6373.43, 14.24777, 5.030209, 120, 0, 0), -- 67319 (Area: 5870) (Auras: 132784 - 132784) +(@CGUID+253, 67329, 974, 1, -3607.139, 6278.641, 118.5082, 2.07468, 120, 5, 1), -- 67329 (Area: 5902) +(@CGUID+254, 67329, 974, 1, -3607.957, 6280.623, 118.5163, 0.9793978, 120, 5, 1), -- 67329 (Area: 0) +(@CGUID+255, 67329, 974, 1, -3626.966, 6439.831, 127.972, 5.792733, 120, 5, 1), -- 67329 (Area: 0) (possible waypoints or random movement) +(@CGUID+256, 67329, 974, 1, -3785.221, 6631.773, 53.54256, 5.370472, 120, 5, 1), -- 67329 (Area: 0) +(@CGUID+257, 67329, 974, 1, -3852.511, 6124.995, 112.3432, 5.233043, 120, 5, 1), -- 67329 (Area: 5902) (possible waypoints or random movement) +(@CGUID+258, 67329, 974, 1, -3945.39, 6414.303, 23.3153, 0.5833343, 120, 5, 1), -- 67329 (Area: 0) (possible waypoints or random movement) +(@CGUID+259, 67329, 974, 1, -4041.083, 6079.592, 22.6864, 5.979221, 120, 5, 1), -- 67329 (Area: 0) (possible waypoints or random movement) +(@CGUID+260, 67329, 974, 1, -4058.984, 6446.323, 18.21202, 3.934109, 120, 5, 1), -- 67329 (Area: 5870) (possible waypoints or random movement) +(@CGUID+261, 67329, 974, 1, -4059.942, 5947.325, 108.9655, 4.19373, 120, 5, 1), -- 67329 (Area: 0) (possible waypoints or random movement) +(@CGUID+262, 67329, 974, 1, -4119.329, 6160.051, 21.57265, 4.928595, 120, 5, 1), -- 67329 (Area: 0) (possible waypoints or random movement) +(@CGUID+263, 67329, 974, 1, -4166.705, 5942.068, 120.6176, 4.127467, 120, 5, 1), -- 67329 (Area: 0) (Auras: ) +(@CGUID+264, 67329, 974, 1, -4189.683, 6186.318, 19.26264, 3.188899, 120, 5, 1), -- 67329 (Area: 0) (possible waypoints or random movement) +(@CGUID+265, 67329, 974, 1, -4244.192, 6630.3, 20.72098, 5.278711, 120, 5, 1), -- 67329 (Area: 0) (possible waypoints or random movement) +(@CGUID+266, 67329, 974, 1, -4279.63, 6112.081, 20.84612, 5.602487, 120, 5, 1), -- 67329 (Area: 0) (possible waypoints or random movement) +(@CGUID+267, 67329, 974, 1, -4307.074, 5972.047, 99.51758, 2.038074, 120, 5, 1), -- 67329 (Area: 0) (possible waypoints or random movement) +(@CGUID+268, 67370, 974, 1, -4100.752, 6394.637, 13.20008, 4.967449, 120, 0, 0), -- 67370 (Area: 5870) +(@CGUID+269, 67382, 974, 1, -4102.958, 6394.549, 13.20009, 5.107639, 120, 0, 0), -- 67382 (Area: 5870) (Auras: ) +(@CGUID+270, 67383, 974, 1, -4098.874, 6395.912, 13.20008, 4.63765, 120, 0, 0), -- 67383 (Area: 5870) (Auras: ) +(@CGUID+271, 67384, 974, 1, -4101.963, 6394.777, 14.99535, 5.291093, 120, 0, 0), -- 67384 (Area: 5870) (Auras: ) +(@CGUID+272, 68231, 1113, 1, -6.62993, 3.931655, 1.201352, 1.110579, 120, 0, 0), +(@CGUID+273, 68232, 1113, 1, -6.316076, -3.870045, 1.201352, 2.070338, 120, 0, 0), +(@CGUID+274, 68233, 1113, 1, 6.576322, -3.682104, 1.201352, 4.203295, 120, 0, 0), +(@CGUID+275, 68238, 1113, 1, -0.162043, 7.456628, 1.201352, 0.005866661, 120, 0, 0), +(@CGUID+276, 68238, 1113, 1, 0.2709804, -7.295516, 1.201352, 3.181539, 120, 0, 0), +(@CGUID+277, 68239, 1113, 1, 6.561924, 4.008928, 1.201351, 5.255444, 120, 0, 0), +(@CGUID+278, 68402, 974, 1, -4058.214, 6331.024, 11.71875, 4.595937, 120, 0, 0), -- 68402 (Area: 5870) +(@CGUID+279, 68407, 974, 1, -4042.303, 6313.233, 12.47493, 5.918468, 120, 0, 0), -- 68407 (Area: 5870) (possible waypoints or random movement) +(@CGUID+280, 68426, 974, 1, -4030.906, 6352.476, 13.02155, 0, 120, 0, 0), -- 68426 (Area: 5870) +(@CGUID+281, 68491, 974, 1, -3628.469, 6309.486, 113.2723, 0.8599741, 120, 0, 0), -- 68491 (Area: 5902) +(@CGUID+282, 68491, 974, 1, -3632.155, 6310.541, 113.364, 1.543436, 120, 0, 0), -- 68491 (Area: 5902) +(@CGUID+283, 68491, 974, 1, -4337.907, 6194.252, 13.24175, 0.9702372, 120, 5, 1), -- 68491 (Area: 5870) (possible waypoints or random movement) +(@CGUID+284, 68492, 974, 1, -3630.217, 6310.871, 113.2768, 0.4937948, 120, 0, 0), -- 68492 (Area: 5902) +(@CGUID+285, 71982, 974, 1, -3836.375, 6482.681, 11.89613, 4.776481, 120, 5, 1), -- 71982 (Area: 0) (Auras: 133836 - 133836) (possible waypoints or random movement) +(@CGUID+286, 71982, 974, 1, -4242.462, 6114.348, 10.36993, 1.600085, 120, 5, 1), -- 71982 (Area: 0) (Auras: 133836 - 133836) (possible waypoints or random movement) +(@CGUID+287, 74056, 974, 1, -4417.674, 6358.51, 15.52252, 0.5449456, 120, 0, 0), -- 74056 (Area: 5870) +(@CGUID+288, 74333, 974, 1, -4416.618, 6256.221, 13.9757, 4.707499, 120, 0, 0), -- 74333 (Area: 5870) (Auras: 149665 - 149665) +(@CGUID+289, 74333, 974, 1, -4417.828, 6383.495, 13.50524, 4.797968, 120, 0, 0), -- 74333 (Area: 5870) (Auras: 149665 - 149665) +(@CGUID+290, 74388, 974, 1, -4406.752, 6252.348, 13.97506, 4.602068, 120, 0, 0), -- 74388 (Area: 5870) (Auras: 149746 - 149746, 151532 - 151532) +(@CGUID+291, 74388, 974, 1, -4408.347, 6385.915, 13.50524, 4.725545, 120, 0, 0), -- 74388 (Area: 5870) (Auras: 149746 - 149746, 151532 - 151532) +(@CGUID+292, 74388, 974, 1, -4425.403, 6252.244, 13.97578, 1.542731, 120, 0, 0), -- 74388 (Area: 5870) (Auras: 149746 - 149746, 151532 - 151532) +(@CGUID+293, 74388, 974, 1, -4426.769, 6385.328, 13.50524, 4.653383, 120, 0, 0), -- 74388 (Area: 5870) (Auras: 149746 - 149746, 151532 - 151532) +(@CGUID+294, 85484, 974, 1, -4253.323, 6311.426, 13.59743, 1.876229, 120, 0, 0), -- 85484 (Area: 5870) +(@CGUID+295, 85519, 974, 1, -4091.094, 6390.395, 13.21238, 3.737871, 120, 0, 0), -- 85519 (Area: 5870) +(@CGUID+296, 85522, 974, 1, -4091.582, 6392.194, 13.20008, 3.972317, 120, 0, 0), -- 85522 (Area: 5870) (Auras: ) +(@CGUID+297, 85523, 974, 1, -4089.521, 6388.737, 13.22179, 3.441971, 120, 0, 0), -- 85523 (Area: 5870) (Auras: ) +(@CGUID+298, 85525, 974, 1, -4090.34, 6389.697, 14.96317, 3.592749, 120, 0, 0), -- 85525 (Area: 5870) (Auras: ) +(@CGUID+299, 85531, 974, 1, -3852.58, 5905.405, -67.67389, 1.263545, 120, 0, 0), -- 85531 (Area: 5869) +(@CGUID+300, 85531, 974, 1, -3855.25, 5875.085, -67.02758, 5.784174, 120, 0, 0), -- 85531 (Area: 5869) +(@CGUID+301, 85531, 974, 1, -3858.149, 5898.472, -66.92779, 0.1291031, 120, 0, 0), -- 85531 (Area: 5869) +(@CGUID+302, 85531, 974, 1, -3871.529, 5879.017, -66.34899, 1.548001, 120, 5, 1), -- 85531 (Area: 5869) (possible waypoints or random movement) +(@CGUID+303, 85531, 974, 1, -3875.769, 5902.223, -66.88538, 0.07232627, 120, 5, 1), -- 85531 (Area: 5869) (possible waypoints or random movement) +(@CGUID+304, 85531, 974, 1, -3881.434, 5910.238, -67.00465, 2.112158, 120, 0, 0), -- 85531 (Area: 5869) +(@CGUID+305, 85531, 974, 1, -3884.201, 5910.596, -67.16608, 1.078099, 120, 0, 0), -- 85531 (Area: 5869) +(@CGUID+306, 85531, 974, 1, -3890.763, 5883.829, -66.31542, 3.419037, 120, 5, 1), -- 85531 (Area: 5869) (possible waypoints or random movement) +(@CGUID+307, 85546, 974, 1, -4207.55, 6369.76, 13.17307, 4.783828, 120, 0, 0), -- 85546 (Area: 5870) +(@CGUID+308, 89715, 974, 1, -4033.719, 6289.453, 10.29123, 2.597398, 120, 0, 0), -- 89715 (Area: 5870) (Auras: 46598 - 46598) +(@CGUID+309, 89734, 974, 1, -4408.507, 6273.993, 13.89466, 3.053421, 120, 0, 0), -- 89734 (Area: 5870) (Auras: 152760 - 152760, 151025 - 151025, 179281 - 179281) +(@CGUID+310, 89734, 974, 1, -4409.213, 6366.121, 13.50524, 2.65413, 120, 0, 0), -- 89734 (Area: 5870) (Auras: 152760 - 152760, 151025 - 151025, 179281 - 179281) +(@CGUID+311, 89736, 974, 1, -4424.276, 6273.732, 13.89585, 0.1174422, 120, 0, 0), -- 89736 (Area: 5870) (Auras: 152760 - 152760, 151025 - 151025, 179273 - 179273) +(@CGUID+312, 89736, 974, 1, -4425.772, 6373.782, 13.50524, 5.81508, 120, 0, 0), -- 89736 (Area: 5870) (Auras: 152760 - 152760, 151025 - 151025, 179273 - 179273) +(@CGUID+313, 90148, 974, 1, -4408.144, 6265.778, 13.94807, 2.210808, 120, 0, 0), -- 90148 (Area: 5870) (Auras: 152760 - 152760, 151025 - 151025, 179749 - 179749) +(@CGUID+314, 90148, 974, 1, -4409.493, 6374.835, 13.50524, 3.375472, 120, 0, 0), -- 90148 (Area: 5870) (Auras: 152760 - 152760, 151025 - 151025, 179749 - 179749) +(@CGUID+315, 90473, 974, 1, -4408.952, 6279.205, 14.65031, 3.060221, 120, 0, 0); -- 90473 (Area: 5870) + +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+20; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(@OGUID+0, 180859, 974, 1, -3531.196, 6087.679, 6.77413, 0, 0, 0, 0, 1, 120, 255, 1), -- 180859 (Area: 5869) +(@OGUID+1, 180859, 974, 1, -3556.832, 6083.604, 6.774127, 0, 0, 0, 0, 1, 120, 255, 1), -- 180859 (Area: 5869) +(@OGUID+2, 210216, 974, 1, -4204.649, 6709.91, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 0) +(@OGUID+3, 210216, 974, 1, -4418.03, 5864.06, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 5869) +(@OGUID+4, 210216, 974, 1, -4407.03, 6115.59, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 5869) +(@OGUID+5, 210216, 974, 1, -4444.221, 6215.84, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 5869) +(@OGUID+6, 210216, 974, 1, -4457.5, 6366.06, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 5869) +(@OGUID+7, 210216, 974, 1, -4332.729, 6702.681, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 5869) +(@OGUID+8, 210216, 974, 1, -3740.07, 6907.34, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 5869) +(@OGUID+9, 210216, 974, 1, -4399.809, 6618.7, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 0) +(@OGUID+10, 216667, 974, 1, -4447.792, 6329.229, 13.26463, 3.09827, 0, 0, 0, 1, 120, 255, 1), -- 216667 (Area: 5870) +(@OGUID+11, 210107, 974, 1, -4300.848, 6402.788, 16.55586, 3.115388, 0, 0, 0.9999143, 0.01308975, 120, 255, 1), -- 210107 (Area: 5870) +(@OGUID+12, 235370, 974, 1, -4253.208, 6311.089, 13.11677, 1.906481, 0, 0, 0, 1, 120, 255, 1), -- 235370 (Area: 5870) +(@OGUID+13, 216667, 974, 1, -3609.375, 6316.874, 113.1974, 3.09827, 0, 0, 0, 1, 120, 255, 1), -- 216667 (Area: 5902) +(@OGUID+14, 210216, 974, 1, -4014.3, 6763.641, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 0) +(@OGUID+15, 210216, 974, 1, -3941.611, 6769, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 0) +(@OGUID+16, 210216, 974, 1, -3620.46, 6682.721, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 0) +(@OGUID+17, 210216, 974, 1, -3455.5, 6469.79, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 5869) +(@OGUID+18, 210216, 974, 1, -3382.33, 6234.8, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 5869) +(@OGUID+19, 210216, 974, 1, -3579.271, 5992.71, 0, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- 210216 (Area: 5869) +(@OGUID+20, 235637, 974, 1, -3895.724, 5902.836, -54.12026, 5.723681, 0, 0, 0, 1, 120, 255, 1); -- 235637 (Area: 5869) + +DELETE FROM `creature_addon` WHERE `guid` BETWEEN @CGUID+299 AND @CGUID+306; +INSERT INTO `creature_addon` (`guid`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES +(@CGUID+299, 0, 0x1, 0x1, ''), +(@CGUID+300, 0, 0x1, 0x1, ''), +(@CGUID+301, 0, 0x3, 0x1, ''), +(@CGUID+302, 0, 0x0, 0x1, ''), +(@CGUID+303, 0, 0x0, 0x1, ''), +(@CGUID+304, 0, 0x1, 0x1, ''), +(@CGUID+305, 0, 0x1, 0x1, ''), +(@CGUID+306, 0, 0x0, 0x1, ''); + +DELETE FROM `creature_template_addon` WHERE `entry` IN (58342, 67319, 67329, 67370, 67382, 67383, 67384, 68231, 68232, 68233, 68238, 68239, 68402, 68407, 68426, 68491, 68492, 71982, 74056, 74333, 74388, 85519, 85522, 85523, 85525, 85546, 89715, 89734, 89736, 90148); +INSERT INTO `creature_template_addon` (`entry`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES +(58342, 0, 0x0, 0x1, ''), -- 58342 +(67319, 0, 0x0, 0x1, '132784'), -- 67319 - 132784 +(67329, 0, 0x3000000, 0x1, ''), -- 67329 +(67370, 0, 0x0, 0x1, ''), -- 67370 +(67382, 0, 0x0, 0x1, ''), -- 67382 +(67383, 0, 0x0, 0x1, ''), -- 67383 +(67384, 0, 0x3000000, 0x1, ''), -- 67384 +(68231, 0, 0x0, 0x1, ''), -- 68231 +(68232, 0, 0x0, 0x1, ''), -- 68232 +(68233, 0, 0x0, 0x1, ''), -- 68233 +(68238, 0, 0x0, 0x1, ''), -- 68238 +(68239, 0, 0x0, 0x1, ''), -- 68239 +(68402, 0, 0x0, 0x1, ''), -- 68402 +(68407, 0, 0x0, 0x1, ''), -- 68407 +(68426, 0, 0x0, 0x1, ''), -- 68426 +(68491, 0, 0x0, 0x1, ''), -- 68491 +(68492, 0, 0x0, 0x1, ''), -- 68492 +(71982, 0, 0x0, 0x1, '133836'), -- 71982 - 133836 +(74056, 0, 0x0, 0x1, ''), -- 74056 +(74333, 0, 0x0, 0x1, '149665'), -- 74333 - 149665 +(74388, 0, 0x0, 0x1, '149746 151532'), -- 74388 - 149746, 151532 +(85519, 2410, 0x0, 0x1, ''), -- 85519 +(85522, 0, 0x0, 0x1, ''), -- 85522 +(85523, 0, 0x0, 0x1, ''), -- 85523 +(85525, 0, 0x3000000, 0x1, ''), -- 85525 +(85546, 0, 0x0, 0x1, ''), -- 85546 +(89715, 0, 0x0, 0x1, '46598'), -- 89715 - 46598 +(89734, 0, 0x0, 0x1, '152760 151025 179281'), -- 89734 - 152760, 151025, 179281 +(89736, 0, 0x0, 0x1, '152760 151025 179273'), -- 89736 - 152760, 151025, 179273 +(90148, 0, 0x0, 0x1, '152760 151025 179749'); -- 90148 - 152760, 151025, 179749 + +DELETE FROM `creature_template_addon` WHERE `entry`=85484; +INSERT INTO `creature_template_addon` (`entry`, `bytes1`, `bytes2`, `emote`) VALUES +(85484, 0, 0x1, 461); -- 85484 + +UPDATE `creature_template` SET `HoverHeight`=1.5 WHERE `entry`=55443; -- Goldwing +UPDATE `creature_template` SET `speed_run`=1, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags2`=67110912, `VehicleId`=2724 WHERE `entry`=68231; -- Carousel Dragon +UPDATE `creature_template` SET `npcflag`=16777216, `speed_run`=1, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags2`=67110912, `VehicleId`=2724 WHERE `entry` IN (68232 /*Carousel Gryphon*/, 68233 /*Carousel Murloc*/, 68238 /*Carousel Rocket*/, 68239 /*Carousel Wyvern*/); +UPDATE `creature_template` SET `npcflag`=1, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=768, `unit_flags2`=2048 WHERE `entry` IN (58342 /*Christopher Lesson*/, 68492 /*"Dusty" Brandom*/); +UPDATE `creature_template` SET `npcflag`=128, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=768, `unit_flags2`=2048 WHERE `entry`=68402; -- Kae Ti +UPDATE `creature_template` SET `speed_run`=1, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=768, `unit_flags2`=2048 WHERE `entry`=68407; -- "Olive" Ya +UPDATE `creature_template` SET `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=33554944, `unit_flags2`=2050 WHERE `entry`=68426; -- [DND] Darkmoon Faire Carousel Bunny +UPDATE `creature_template` SET `speed_walk`=0.666668, `speed_run`=0.8571429, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=33536, `unit_flags2`=2048 WHERE `entry`=67319; -- Darkmoon Hatchling +UPDATE `creature_template` SET `speed_run`=1.142857, `unit_flags`=32768 WHERE `entry`=56160; -- Moonfang Snarler +UPDATE `creature_template` SET `npcflag`=1073741824, `speed_run`=0.8571429, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=512, `unit_flags2`=2048 WHERE `entry`=67329; -- Darkmoon Glowfly +UPDATE `creature_template` SET `npcflag`=3, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags2`=2048 WHERE `entry`=74056; -- -Unknown- +UPDATE `creature_template` SET `npcflag`=16777216, `speed_walk`=0.666668, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=33536, `unit_flags2`=2048 WHERE `entry`=68491; -- Darkmoon Strider +UPDATE `creature_template` SET `speed_run`=0.8571429, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=768, `unit_flags2`=2048 WHERE `entry`=67382; -- Fezwick +UPDATE `creature_template` SET `speed_walk`=1.6, `speed_run`=0.8571429, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=33536, `unit_flags2`=2048 WHERE `entry`=67383; -- Honky-Tonk +UPDATE `creature_template` SET `speed_run`=1.428571, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=768, `unit_flags2`=2048 WHERE `entry`=67384; -- Judgement +UPDATE `creature_template` SET `speed_walk`=1.6, `speed_run`=1.285714, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=32768, `unit_flags2`=2048 WHERE `entry`=71982; -- Moonfang Dreadhowl +UPDATE `creature_template` SET `minlevel`=95, `maxlevel`=95, `faction`=1555, `npcflag`=130, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=768, `unit_flags2`=2048 WHERE `entry`=85484; -- -Unknown- +UPDATE `creature_template` SET `speed_run`=1, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=33587712, `unit_flags2`=2099200 WHERE `entry`=74333; -- -Unknown- +UPDATE `creature_template` SET `gossip_menu_id`=16970, `minlevel`=100, `maxlevel`=100, `npcflag`=3, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=32768, `unit_flags2`=2048 WHERE `entry`=85546; -- -Unknown- +UPDATE `creature_template` SET `maxlevel`=2, `speed_run`=1.190476, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=33554432, `unit_flags2`=4196352 WHERE `entry`=74388; -- -Unknown- +UPDATE `creature_template` SET `minlevel`=60, `maxlevel`=60, `faction`=1555, `npcflag`=3, `speed_run`=1.385714, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=33536, `unit_flags2`=2048 WHERE `entry`=85519; -- -Unknown- +UPDATE `creature_template` SET `minlevel`=25, `maxlevel`=25, `speed_run`=0.8571429, `BaseAttackTime`=2000, `RangeAttackTime`=2000, `unit_flags`=768, `unit_flags2`=2048 WHERE `entry` IN (85522 /*-Unknown-*/, 85523 /*-Unknown-*/, 85525 /*-Unknown-*/); +UPDATE `creature_template` SET `minlevel`=100, `maxlevel`=100, `faction`=16, `speed_walk`=0.888888, `speed_run`=1.428571, `BaseAttackTime`=1500, `RangeAttackTime`=2000, `unit_class`=2, `unit_flags`=32832, `unit_flags2`=2048 WHERE `entry`=85531; -- -Unknown- + +DELETE FROM `npc_vendor` WHERE `entry` IN (14846, 56335, 68402, 57983, 85484); +INSERT INTO `npc_vendor` (`entry`, `item`, `slot`, `maxcount`, `ExtendedCost`, `Type`, `VerifiedBuild`) VALUES +-- 56335 +(56335, 122338, 1, 0, 5547, 1, 19865), -- 122338 +(56335, 122339, 2, 0, 5548, 1, 19865), -- 122339 +(56335, 122387, 3, 0, 3806, 1, 19865), -- 122387 +(56335, 122388, 4, 0, 3806, 1, 19865), -- 122388 +(56335, 122381, 5, 0, 3806, 1, 19865), -- 122381 +(56335, 122355, 6, 0, 3806, 1, 19865), -- 122355 +(56335, 122356, 7, 0, 3806, 1, 19865), -- 122356 +(56335, 122379, 8, 0, 3806, 1, 19865), -- 122379 +(56335, 122357, 9, 0, 3806, 1, 19865), -- 122357 +(56335, 122380, 10, 0, 3806, 1, 19865), -- 122380 +(56335, 122382, 11, 0, 3806, 1, 19865), -- 122382 +(56335, 122359, 12, 0, 3806, 1, 19865), -- 122359 +(56335, 122358, 13, 0, 3806, 1, 19865), -- 122358 +(56335, 122383, 14, 0, 3806, 1, 19865), -- 122383 +(56335, 122360, 15, 0, 3806, 1, 19865), -- 122360 +(56335, 122384, 16, 0, 3806, 1, 19865), -- 122384 +(56335, 122350, 17, 0, 3806, 1, 19865), -- 122350 +(56335, 122349, 18, 0, 3811, 1, 19865), -- 122349 +(56335, 122352, 19, 0, 3811, 1, 19865), -- 122352 +(56335, 122354, 20, 0, 3806, 1, 19865), -- 122354 +(56335, 122353, 21, 0, 3811, 1, 19865), -- 122353 +(56335, 122386, 22, 0, 3811, 1, 19865), -- 122386 +(56335, 122351, 23, 0, 3806, 1, 19865), -- 122351 +(56335, 122385, 24, 0, 3806, 1, 19865), -- 122385 +(56335, 122389, 25, 0, 3806, 1, 19865), -- 122389 +(56335, 122362, 26, 0, 3812, 1, 19865), -- 122362 +(56335, 122361, 27, 0, 3812, 1, 19865), -- 122361 +(56335, 122363, 28, 0, 3811, 1, 19865), -- 122363 +(56335, 122390, 29, 0, 3806, 1, 19865), -- 122390 +(56335, 122391, 30, 0, 3806, 1, 19865), -- 122391 +(56335, 122392, 31, 0, 3806, 1, 19865), -- 122392 +-- 68402 +(68402, 92794, 7, 0, 0, 1, 19865), -- 92794 +-- 14846 +(14846, 73766, 1, 0, 3701, 1, 19865), -- 73766 +(14846, 72140, 2, 0, 3701, 1, 19865), -- 72140 +(14846, 91003, 3, 0, 3700, 1, 19865), -- 91003 +(14846, 73764, 4, 0, 3700, 1, 19865), -- 73764 +(14846, 74981, 5, 0, 3700, 1, 19865), -- 74981 +(14846, 73765, 6, 0, 3700, 1, 19865), -- 73765 +(14846, 73762, 7, 0, 3700, 1, 19865), -- 73762 +(14846, 73903, 8, 0, 3700, 1, 19865), -- 73903 +(14846, 73905, 9, 0, 3700, 1, 19865), -- 73905 +-- 85484 +(85484, 116133, 1, 0, 3814, 1, 19865), -- 116133 +(85484, 116052, 2, 0, 3814, 1, 19865), -- 116052 +(85484, 116134, 5, 0, 3813, 1, 19865), -- 116134 +(85484, 116139, 6, 0, 3700, 1, 19865), -- 116139 +(85484, 116138, 7, 0, 5800, 1, 19865); -- 116138 + +DELETE FROM `creature_equip_template` WHERE `CreatureID` IN (74056, 85484, 85519, 90473); +INSERT INTO `creature_equip_template` (`CreatureID`, `ItemID1`, `ItemID2`, `ItemID3`) VALUES +(74056, 110708, 0, 0), -- -Unknown- +(85484, 6235, 0, 0), -- -Unknown- +(85519, 7944, 0, 0), -- -Unknown- +(90473, 110708, 0, 0); -- -Unknown- + +DELETE FROM `gossip_menu` WHERE (`entry`=13019 AND `text_id`=18290) OR (`entry`=16970 AND `text_id`=24702); +INSERT INTO `gossip_menu` (`entry`, `text_id`) VALUES +(13019, 18290), -- 54605 +(16970, 24702); -- 85546 + +DELETE FROM `gossip_menu_option` WHERE `menu_id`=16970; +INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`, `option_text`, `OptionBroadcastTextID`) VALUES +(16970, 0, 0, 'How do I play Firebird''s Challenge?', 87053), -- 85546 +(16970, 1, 0, 'Ready to fly! |cFF0008E8(Darkmoon Game Token)|r', 87062); -- 85546 + +DELETE FROM `npc_text` WHERE `ID` IN (24704, 26114, 18472, 6961, 11538, 18290, 7381, 24702); +INSERT INTO `npc_text` (`ID`, `Probability0`, `BroadcastTextId0`, `Probability1`, `BroadcastTextId1`, `Probability2`, `BroadcastTextId2`, `Probability3`, `BroadcastTextId3`, `Probability4`, `BroadcastTextId4`, `Probability5`, `BroadcastTextId5`, `Probability6`, `BroadcastTextId6`, `Probability7`, `BroadcastTextId7`, `VerifiedBuild`) VALUES +(24704, 1, 87078, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19865), -- 24704 +(26114, 1, 92741, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19865), -- 26114 +(18472, 1, 53824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19865), -- 18472 +(6961, 1, 9557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19865), -- 6961 +(11538, 1, 22574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19865), -- 11538 +(18290, 1, 53059, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19865), -- 18290 +(7381, 1, 10117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19865), -- 7381 +(24702, 1, 87077, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19865); -- 24702 diff --git a/sql/updates/world/2015_05_10_02_world_2015_05_09_00.sql b/sql/updates/world/2015_05_10_02_world_2015_05_09_00.sql new file mode 100644 index 00000000000..1ab6c7d2357 --- /dev/null +++ b/sql/updates/world/2015_05_10_02_world_2015_05_09_00.sql @@ -0,0 +1,30 @@ +-- High Priest Venoxis +UPDATE `creature_template` SET `lootid` = 52155 WHERE `entry` = 52155; + +DELETE FROM `creature_loot_template` WHERE `Entry` = 52155; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `LootMode`, `MinCount`, `MaxCount`) VALUES +(52155, 521550, 521550, 100, 1, 1, 1); + +DELETE FROM `reference_loot_template` WHERE `Entry` = 521550; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Chance`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`) VALUES +(521550, 69600, 0, 1, 1, 1, 1), -- Belt of Slithering Serpents +(521550, 69603, 0, 1, 1, 1, 1), -- Breastplate of Serenity +(521550, 69604, 0, 1, 1, 1, 1), -- Coils of Hate +(521550, 69601, 0, 1, 1, 1, 1), -- Serpentine Leggings +(521550, 69602, 0, 1, 1, 1, 1); -- Signet of Venoxis + +-- Bloodlord Mandokir +UPDATE `creature_template` SET `lootid` = 52151 WHERE `entry` = 52151; + +DELETE FROM `creature_loot_template` WHERE `entry`= 52151; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `LootMode`, `MinCount`, `MaxCount`) VALUES +(52151, 521510, 521510, 100, 1, 1, 1); + +DELETE FROM `reference_loot_template` WHERE `Entry` = 521510; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Chance`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`) VALUES +(521510, 69605, 0, 1, 1, 1, 1), -- Amulet of the Watcher +(521510, 69609, 0, 1, 1, 1, 1), -- Bloodlord's Protector +(521510, 69608, 0, 1, 1, 1, 1), -- Deathcharged Wristguards +(521510, 69606, 0, 1, 1, 1, 1), -- Hakkari Loa Drape +(521510, 69607, 0, 1, 1, 1, 1), -- Touch of Discord +(521510, 68823, 1, 1, 2, 1, 1); -- Amored Razzashi Raptor Mount diff --git a/sql/updates/world/2015_05_15_00_world.sql b/sql/updates/world/2015_05_15_00_world.sql new file mode 100644 index 00000000000..64985145721 --- /dev/null +++ b/sql/updates/world/2015_05_15_00_world.sql @@ -0,0 +1,14 @@ +UPDATE `creature_template` SET `ScriptName`="npc_meteor_strike_flame" WHERE `entry`=40055; + +DELETE FROM `spell_script_names` WHERE `spell_id`=75880 OR `ScriptName`="spell_halion_spawn_living_embers"; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(75880, "spell_halion_spawn_living_embers"); + +DELETE FROM `spelleffect_dbc` WHERE `EffectSpellId` IN (75880, 75881); +INSERT INTO `spelleffect_dbc` (`Id`, `EffectSpellId`, `EffectIndex`, `Effect`, `EffectImplicitTargetA`, `EffectImplicitTargetB`, `EffectRadiusIndex`, `EffectRadiusIndexMax`, `EffectMiscValue`, `EffectMiscValueB`) VALUES +(155915, 75880, 0, 77, 22, 7, 12, 12, 0, 0), +(155916, 75881, 0, 28, 18, 0, 12, 12, 40683, 64); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=75880; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `Comment`) VALUES +(13, 1, 75880, 31, 0, 3, 40055, "Spawn Living Embers can only target Meteor Strike (Flame)"); diff --git a/sql/updates/world/2015_05_15_01_world.sql b/sql/updates/world/2015_05_15_01_world.sql new file mode 100644 index 00000000000..bf996226a23 --- /dev/null +++ b/sql/updates/world/2015_05_15_01_world.sql @@ -0,0 +1 @@ +UPDATE `spelleffect_dbc` SET `EffectMiscValue`=40683 WHERE `Id`=155916; diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index c6c46c48f50..f37526ae71b 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -71,7 +71,7 @@ namespace Trinity void do_helper(WorldPacket& data, char const* text) { WorldPackets::Chat::Chat packet; - packet.Initalize(_msgtype, LANG_UNIVERSAL, _source, _source, text); + packet.Initialize(_msgtype, LANG_UNIVERSAL, _source, _source, text); packet.Write(); data = packet.Move(); } @@ -98,7 +98,7 @@ namespace Trinity snprintf(str, 2048, text, arg1str, arg2str); WorldPackets::Chat::Chat packet; - packet.Initalize(_msgtype, LANG_UNIVERSAL, _source, _source, str); + packet.Initialize(_msgtype, LANG_UNIVERSAL, _source, _source, str); packet.Write(); data = packet.Move(); } diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 04b6eb1b5b1..90c44aa501b 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -626,10 +626,10 @@ void Channel::Say(ObjectGuid const& guid, std::string const& what, uint32 lang) WorldPackets::Chat::Chat packet; if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) - packet.Initalize(CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name); + packet.Initialize(CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name); else { - packet.Initalize(CHAT_MSG_CHANNEL, Language(lang), nullptr, nullptr, what, 0, _name); + packet.Initialize(CHAT_MSG_CHANNEL, Language(lang), nullptr, nullptr, what, 0, _name); packet.SenderGUID = guid; packet.TargetGUID = guid; } @@ -990,32 +990,42 @@ void Channel::MakeVoiceOff(WorldPackets::Channel::ChannelNotify& data, ObjectGui void Channel::JoinNotify(Player const* player) { ObjectGuid const& guid = player->GetGUID(); - WorldPacket data(IsConstant() ? SMSG_USERLIST_ADD : SMSG_USERLIST_UPDATE, 8 + 1 + 1 + 4 + GetName().size()); - data << guid; - data << uint8(GetPlayerFlags(guid)); - data << uint8(GetFlags()); - data << uint32(GetNumPlayers()); - data << GetName(); if (IsConstant()) - SendToAllButOne(&data, guid); + { + WorldPackets::Channel::UserlistAdd userlistAdd; + userlistAdd.AddedUserGUID = guid; + userlistAdd.ChannelFlags = GetFlags(); + userlistAdd.UserFlags = GetPlayerFlags(guid); + userlistAdd.ChannelID = GetChannelId(); + userlistAdd.ChannelName = GetName(); + SendToAllButOne(userlistAdd.Write(), guid); + } else - SendToAll(&data); + { + WorldPackets::Channel::UserlistUpdate userlistUpdate; + userlistUpdate.UpdatedUserGUID = guid; + userlistUpdate.ChannelFlags = GetFlags(); + userlistUpdate.UserFlags = GetPlayerFlags(guid); + userlistUpdate.ChannelID = GetChannelId(); + userlistUpdate.ChannelName = GetName(); + SendToAll(userlistUpdate.Write()); + } } void Channel::LeaveNotify(Player const* player) { ObjectGuid const& guid = player->GetGUID(); - WorldPacket data(SMSG_USERLIST_REMOVE, 8 + 1 + 4 + GetName().size()); - data << guid; - data << uint8(GetFlags()); - data << uint32(GetNumPlayers()); - data << GetName(); + WorldPackets::Channel::UserlistRemove userlistRemove; + userlistRemove.RemovedUserGUID = guid; + userlistRemove.ChannelFlags = GetFlags(); + userlistRemove.ChannelID = GetChannelId(); + userlistRemove.ChannelName = GetName(); if (IsConstant()) - SendToAllButOne(&data, guid); + SendToAllButOne(userlistRemove.Write(), guid); else - SendToAll(&data); + SendToAll(userlistRemove.Write()); } void Channel::SetModerator(ObjectGuid const& guid, bool set) diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index c7952d7758c..ed6aa52da5a 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -201,7 +201,7 @@ void ChatHandler::SendSysMessage(const char *str) while (char* line = LineFromMessage(pos)) { - packet.Initalize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); + packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); m_session->SendPacket(packet.Write()); } @@ -219,7 +219,7 @@ void ChatHandler::SendGlobalSysMessage(const char *str) while (char* line = LineFromMessage(pos)) { - packet.Initalize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); + packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); sWorld->SendGlobalMessage(packet.Write()); } @@ -237,7 +237,7 @@ void ChatHandler::SendGlobalGMSysMessage(const char *str) while (char* line = LineFromMessage(pos)) { - packet.Initalize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); + packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); sWorld->SendGlobalGMMessage(packet.Write()); } diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index c050caa8094..01c65315d35 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -29,8 +29,12 @@ DB2Storage<BroadcastTextEntry> sBroadcastTextStore("BroadcastText.d DB2Storage<CurrencyTypesEntry> sCurrencyTypesStore("CurrencyTypes.db2", CurrencyTypesFormat, HOTFIX_SEL_CURRENCY_TYPES); DB2Storage<CurvePointEntry> sCurvePointStore("CurvePoint.db2", CurvePointFormat, HOTFIX_SEL_CURVE_POINT); DB2Storage<GameObjectsEntry> sGameObjectsStore("GameObjects.db2", GameObjectsFormat, HOTFIX_SEL_GAMEOBJECTS); +DB2Storage<GarrAbilityEntry> sGarrAbilityStore("GarrAbility.db2", GarrAbilityFormat, HOTFIX_SEL_GARR_ABILITY); DB2Storage<GarrBuildingEntry> sGarrBuildingStore("GarrBuilding.db2", GarrBuildingFormat, HOTFIX_SEL_GARR_BUILDING); DB2Storage<GarrBuildingPlotInstEntry> sGarrBuildingPlotInstStore("GarrBuildingPlotInst.db2", GarrBuildingPlotInstFormat, HOTFIX_SEL_GARR_BUILDING_PLOT_INST); +DB2Storage<GarrClassSpecEntry> sGarrClassSpecStore("GarrClassSpec.db2", GarrClassSpecFormat, HOTFIX_SEL_GARR_CLASS_SPEC); +DB2Storage<GarrFollowerEntry> sGarrFollowerStore("GarrFollower.db2", GarrFollowerFormat, HOTFIX_SEL_GARR_FOLLOWER); +DB2Storage<GarrFollowerXAbilityEntry> sGarrFollowerXAbilityStore("GarrFollowerXAbility.db2", GarrFollowerXAbilityFormat, HOTFIX_SEL_GARR_FOLLOWER_X_ABILITY); DB2Storage<GarrPlotBuildingEntry> sGarrPlotBuildingStore("GarrPlotBuilding.db2", GarrPlotBuildingFormat, HOTFIX_SEL_GARR_PLOT_BUILDING); DB2Storage<GarrPlotEntry> sGarrPlotStore("GarrPlot.db2", GarrPlotFormat, HOTFIX_SEL_GARR_PLOT); DB2Storage<GarrPlotInstanceEntry> sGarrPlotInstanceStore("GarrPlotInstance.db2", GarrPlotInstanceFormat, HOTFIX_SEL_GARR_PLOT_INSTANCE); @@ -141,8 +145,12 @@ void DB2Manager::LoadStores(std::string const& dataPath) LOAD_DB2(sCurrencyTypesStore); LOAD_DB2(sCurvePointStore); LOAD_DB2(sGameObjectsStore); - LOAD_DB2(sGarrBuildingPlotInstStore); + LOAD_DB2(sGarrAbilityStore); LOAD_DB2(sGarrBuildingStore); + LOAD_DB2(sGarrBuildingPlotInstStore); + LOAD_DB2(sGarrClassSpecStore); + LOAD_DB2(sGarrFollowerStore); + LOAD_DB2(sGarrFollowerXAbilityStore); LOAD_DB2(sGarrPlotBuildingStore); LOAD_DB2(sGarrPlotInstanceStore); LOAD_DB2(sGarrPlotStore); @@ -513,6 +521,11 @@ MountEntry const* DB2Manager::GetMount(uint32 spellId) const return nullptr; } +MountEntry const* DB2Manager::GetMountById(uint32 id) const +{ + return sMountStore.LookupEntry(id); +} + std::vector<QuestPackageItemEntry const*> const* DB2Manager::GetQuestPackageItems(uint32 questPackageID) const { auto itr = _questPackages.find(questPackageID); diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index 6e3818e8f41..a79b3d1c1fa 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -25,8 +25,12 @@ extern DB2Storage<BroadcastTextEntry> sBroadcastTextStore; extern DB2Storage<CurrencyTypesEntry> sCurrencyTypesStore; extern DB2Storage<GameObjectsEntry> sGameObjectsStore; +extern DB2Storage<GarrAbilityEntry> sGarrAbilityStore; extern DB2Storage<GarrBuildingEntry> sGarrBuildingStore; extern DB2Storage<GarrBuildingPlotInstEntry> sGarrBuildingPlotInstStore; +extern DB2Storage<GarrClassSpecEntry> sGarrClassSpecStore; +extern DB2Storage<GarrFollowerEntry> sGarrFollowerStore; +extern DB2Storage<GarrFollowerXAbilityEntry> sGarrFollowerXAbilityStore; extern DB2Storage<GarrPlotBuildingEntry> sGarrPlotBuildingStore; extern DB2Storage<GarrPlotEntry> sGarrPlotStore; extern DB2Storage<GarrPlotInstanceEntry> sGarrPlotInstanceStore; @@ -106,6 +110,7 @@ public: std::set<uint32> GetItemBonusTree(uint32 itemId, uint32 itemBonusTreeMod) const; uint32 GetItemDisplayId(uint32 itemId, uint32 appearanceModId) const; MountEntry const* GetMount(uint32 spellId) const; + MountEntry const* GetMountById(uint32 id) const; std::vector<QuestPackageItemEntry const*> const* GetQuestPackageItems(uint32 questPackageID) const; std::set<uint32> GetPhasesForGroup(uint32 group) const; std::vector<SpellPowerEntry const*> GetSpellPowers(uint32 spellId, Difficulty difficulty = DIFFICULTY_NONE, bool* hasDifficultyPowers = nullptr) const; diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index cad9ca32e69..80c79a94b96 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -100,6 +100,17 @@ struct GameObjectsEntry LocalizedString* Name; // 23 }; +struct GarrAbilityEntry +{ + uint32 ID; // 0 + uint32 Flags; // 1 + LocalizedString* Name; // 2 + LocalizedString* Description; // 3 + uint32 IconFileDataID; // 4 + uint32 OtherFactionGarrAbilityID; // 5 + uint32 GarrAbilityCategoryID; // 6 +}; + struct GarrBuildingEntry { uint32 ID; // 0 @@ -137,6 +148,49 @@ struct GarrBuildingPlotInstEntry DBCPosition2D LandmarkOffset; // 4-5 }; +struct GarrClassSpecEntry +{ + uint32 ID; // 0 + LocalizedString* NameMale; // 1 + LocalizedString* NameFemale; // 2 + LocalizedString* NameGenderless; // 3 + uint32 ClassAtlasID; // 4 UiTextureAtlasMember.db2 ref + uint32 GarrFollItemSetID; // 5 +}; + +struct GarrFollowerEntry +{ + uint32 ID; // 0 + uint32 HordeCreatureID; // 1 + uint32 AllianceCreatureID; // 2 + uint32 HordeUiAnimRaceInfoID; // 3 + uint32 AllianceUiAnimRaceInfoID; // 4 + uint32 Quality; // 5 + uint32 HordeGarrClassSpecID; // 6 + uint32 AllianceGarrClassSpecID; // 7 + uint32 HordeGarrFollItemSetID; // 8 + uint32 AllianceGarrFollItemSetID; // 9 + uint32 Level; // 10 + uint32 ItemLevelWeapon; // 11 + uint32 ItemLevelArmor; // 12 + uint32 Unknown1; // 13 + uint32 Flags; // 14 + LocalizedString* HordeSourceText; // 15 + LocalizedString* AllianceSourceText; // 16 + int32 Unknown2; // 17 + int32 Unknown3; // 18 + uint32 HordePortraitIconID; // 19 + uint32 AlliancePortraitIconID; // 20 +}; + +struct GarrFollowerXAbilityEntry +{ + uint32 ID; // 0 + uint32 GarrFollowerID; // 1 + uint32 GarrAbilityID; // 2 + uint32 FactionIndex; // 3 +}; + struct GarrPlotEntry { uint32 ID; // 0 diff --git a/src/server/game/DataStores/DB2fmt.h b/src/server/game/DataStores/DB2fmt.h index 19622dcc3d2..7c915b37326 100644 --- a/src/server/game/DataStores/DB2fmt.h +++ b/src/server/game/DataStores/DB2fmt.h @@ -24,10 +24,14 @@ char const BroadcastTextFormat[] = "nissiiiiiiiii"; char const CurrencyTypesFormat[] = "nisssiiiiiis"; char const CurvePointFormat[] = "niiff"; char const GameObjectsFormat[] = "niiffffffffiiiiiiiiiiiis"; +char const GarrAbilityFormat[] = "nissiii"; char const GarrBuildingFormat[] = "niiiiissssiiiiiiiiiiiiii"; -char const GarrPlotFormat[] = "niiisiiii"; -char const GarrPlotBuildingFormat[] = "nii"; char const GarrBuildingPlotInstFormat[] = "niiiff"; +char const GarrClassSpecFormat[] = "nsssii"; +char const GarrFollowerFormat[] = "niiiiiiiiiiiiiissiiii"; +char const GarrFollowerXAbilityFormat[] = "niii"; +char const GarrPlotBuildingFormat[] = "nii"; +char const GarrPlotFormat[] = "niiisiiii"; char const GarrPlotInstanceFormat[] = "nis"; char const GarrSiteLevelFormat[] = "niiiiffiiii"; char const GarrSiteLevelPlotInstFormat[] = "niiffi"; diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index b077f3e6110..e786c3b9c7c 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -412,7 +412,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const joinData.result = LFG_JOIN_NOT_MEET_REQS; else if (grp) { - if (grp->GetMembersCount() > MAXGROUPSIZE) + if (grp->GetMembersCount() > MAX_GROUP_SIZE) joinData.result = LFG_JOIN_TOO_MUCH_MEMBERS; else { diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp index 97f87a4d814..30e9a587353 100644 --- a/src/server/game/DungeonFinding/LFGQueue.cpp +++ b/src/server/game/DungeonFinding/LFGQueue.cpp @@ -323,7 +323,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) LfgRolesMap proposalRoles; // Check for correct size - if (check.size() > MAXGROUPSIZE || check.empty()) + if (check.size() > MAX_GROUP_SIZE || check.empty()) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s): Size wrong - Not compatibles", strGuids.c_str()); return LFG_INCOMPATIBLES_WRONG_GROUP_SIZE; @@ -349,7 +349,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) // Check if more than one LFG group and number of players joining uint8 numPlayers = 0; uint8 numLfgGroups = 0; - for (GuidList::const_iterator it = check.begin(); it != check.end() && numLfgGroups < 2 && numPlayers <= MAXGROUPSIZE; ++it) + for (GuidList::const_iterator it = check.begin(); it != check.end() && numLfgGroups < 2 && numPlayers <= MAX_GROUP_SIZE; ++it) { ObjectGuid guid = *it; LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(guid); @@ -374,8 +374,8 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) } } - // Group with less that MAXGROUPSIZE members always compatible - if (check.size() == 1 && numPlayers != MAXGROUPSIZE) + // Group with less that MAX_GROUP_SIZE members always compatible + if (check.size() == 1 && numPlayers != MAX_GROUP_SIZE) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) single group. Compatibles", strGuids.c_str()); LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(check.front()); @@ -396,7 +396,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) return LFG_INCOMPATIBLES_MULTIPLE_LFG_GROUPS; } - if (numPlayers > MAXGROUPSIZE) + if (numPlayers > MAX_GROUP_SIZE) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Too much players (%u)", strGuids.c_str(), numPlayers); SetCompatibles(strGuids, LFG_INCOMPATIBLES_TOO_MUCH_PLAYERS); @@ -473,7 +473,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) } // Enough players? - if (numPlayers != MAXGROUPSIZE) + if (numPlayers != MAX_GROUP_SIZE) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Compatibles but not enough players(%u)", strGuids.c_str(), numPlayers); LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS); diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index 4294eb57dbd..15e560a8e7e 100644 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -59,7 +59,7 @@ void Corpse::RemoveFromWorld() if (IsInWorld()) GetMap()->GetObjectsStore().Remove<Corpse>(GetGUID()); - Object::RemoveFromWorld(); + WorldObject::RemoveFromWorld(); } bool Corpse::Create(ObjectGuid::LowType guidlow, Map* map) diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 05d649fe632..82b55e23349 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -39,7 +39,7 @@ Pet::Pet(Player* owner, PetType type) : Guardian(NULL, owner, true), m_usedTalentCount(0), m_removed(false), - m_petType(type), m_duration(0), m_auraRaidUpdateMask(0), m_loading(false), + m_petType(type), m_duration(0), m_groupUpdateMask(0), m_loading(false), m_declinedname(NULL) { ASSERT(GetOwner()); @@ -337,8 +337,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c owner->PetSpellInitialize(); - if (owner->GetGroup()) - owner->SetGroupUpdateFlag(GROUP_UPDATE_PET); + SetGroupUpdateFlag(GROUP_UPDATE_PET_FULL); // TODO: 6.x remove/update pet talents //owner->SendTalentsInfoData(true); @@ -1938,6 +1937,21 @@ void Pet::SetDisplayId(uint32 modelId) if (!isControlled()) return; + SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID); +} + +void Pet::SetGroupUpdateFlag(uint32 flag) +{ + if (GetOwner()->GetGroup()) + { + m_groupUpdateMask |= flag; + GetOwner()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET); + } +} + +void Pet::ResetGroupUpdateFlag() +{ + m_groupUpdateMask = GROUP_UPDATE_FLAG_PET_NONE; if (GetOwner()->GetGroup()) - GetOwner()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID); + GetOwner()->RemoveGroupUpdateFlag(GROUP_UPDATE_FLAG_PET); } diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 494db54208d..70f14fbd7ca 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -134,9 +134,9 @@ class Pet : public Guardian uint32 m_usedTalentCount; - uint64 GetAuraUpdateMaskForRaid() const { return m_auraRaidUpdateMask; } - void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); } - void ResetAuraUpdateMaskForRaid() { m_auraRaidUpdateMask = 0; } + uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; } + void SetGroupUpdateFlag(uint32 flag); + void ResetGroupUpdateFlag(); DeclinedName const* GetDeclinedNames() const { return m_declinedname; } @@ -147,9 +147,9 @@ class Pet : public Guardian protected: PetType m_petType; int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets) - uint64 m_auraRaidUpdateMask; bool m_loading; uint32 m_regenTimer; + uint32 m_groupUpdateMask; DeclinedName *m_declinedname; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 16ae4f7e09f..419992f3408 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -100,6 +100,7 @@ #include "WorldPacket.h" #include "WorldSession.h" #include "WorldStatePackets.h" +#include "InstancePackets.h" #define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS) @@ -701,7 +702,6 @@ Player::Player(WorldSession* session): Unit(true) // group is initialized in the reference constructor SetGroupInvite(NULL); m_groupUpdateMask = 0; - m_auraRaidUpdateMask = 0; m_bPassOnGroupLoot = false; duel = NULL; @@ -887,7 +887,6 @@ Player::Player(WorldSession* session): Unit(true) _maxPersonalArenaRate = 0; memset(_voidStorageItems, 0, VOID_STORAGE_MAX_SLOT * sizeof(VoidStorageItem*)); - memset(_CUFProfiles, 0, MAX_CUF_PROFILES * sizeof(CUFProfile*)); m_achievementMgr = new AchievementMgr<Player>(this); m_reputationMgr = new ReputationMgr(this); @@ -927,9 +926,6 @@ Player::~Player() for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) delete _voidStorageItems[i]; - for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i) - delete _CUFProfiles[i]; - ClearResurrectRequestData(); sWorld->DecreasePlayerCount(); @@ -2315,17 +2311,16 @@ void Player::RemoveFromWorld() sBattlefieldMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId); } + // Remove items from world before self - player must be found in Item::RemoveFromObjectUpdate + for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i) + if (m_items[i]) + m_items[i]->RemoveFromWorld(); + ///- Do not add/remove the player from the object storage ///- It will crash when updating the ObjectAccessor ///- The player should only be removed when logging out Unit::RemoveFromWorld(); - for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i) - { - if (m_items[i]) - m_items[i]->RemoveFromWorld(); - } - for (ItemMap::iterator iter = mMitems.begin(); iter != mMitems.end(); ++iter) iter->second->RemoveFromWorld(); @@ -6209,6 +6204,22 @@ bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type) return false; } break; + case ACTION_BUTTON_MOUNT: + { + auto mount = sDB2Manager.GetMountById(action); + if (!mount) + { + TC_LOG_ERROR("entities.player", "Mount action %u not added into button %u for player %s (%s): mount does not exist", action, button, GetName().c_str(), GetGUID().ToString().c_str()); + return false; + } + + if (!HasSpell(mount->SpellId)) + { + TC_LOG_ERROR("entities.player", "Mount action %u not added into button %u for player %s (%s): Player does not know this mount", action, button, GetName().c_str(), GetGUID().ToString().c_str()); + return false; + } + break; + } case ACTION_BUTTON_C: case ACTION_BUTTON_CMACRO: case ACTION_BUTTON_MACRO: @@ -7372,7 +7383,11 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) // group update if (GetGroup()) + { SetGroupUpdateFlag(GROUP_UPDATE_FULL); + if (Pet* pet = GetPet()) + pet->SetGroupUpdateFlag(GROUP_UPDATE_PET_FULL); + } m_zoneUpdateId = newZone; m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL; @@ -17335,7 +17350,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) _LoadCUFProfiles(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES)); - std::unique_ptr<Garrison> garrison(new Garrison(this)); + std::unique_ptr<Garrison> garrison = Trinity::make_unique<Garrison>(this); if (garrison->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GARRISON), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GARRISON_BLUEPRINTS), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GARRISON_BUILDINGS))) @@ -17354,19 +17369,19 @@ void Player::_LoadCUFProfiles(PreparedQueryResult result) // SELECT id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154 FROM character_cuf_profiles WHERE guid = ? Field* fields = result->Fetch(); - uint8 id = fields[0].GetUInt8(); - std::string name = fields[1].GetString(); - uint16 frameHeight = fields[2].GetUInt16(); - uint16 frameWidth = fields[3].GetUInt16(); - uint8 sortBy = fields[4].GetUInt8(); - uint8 healthText = fields[5].GetUInt8(); - uint32 boolOptions = fields[6].GetUInt32(); - uint8 unk146 = fields[7].GetUInt8(); - uint8 unk147 = fields[8].GetUInt8(); - uint8 unk148 = fields[9].GetUInt8(); - uint16 unk150 = fields[10].GetUInt16(); - uint16 unk152 = fields[11].GetUInt16(); - uint16 unk154 = fields[12].GetUInt16(); + uint8 id = fields[0].GetUInt8(); + std::string name = fields[1].GetString(); + uint16 frameHeight = fields[2].GetUInt16(); + uint16 frameWidth = fields[3].GetUInt16(); + uint8 sortBy = fields[4].GetUInt8(); + uint8 healthText = fields[5].GetUInt8(); + uint32 boolOptions = fields[6].GetUInt32(); + uint8 topPoint = fields[7].GetUInt8(); + uint8 bottomPoint = fields[8].GetUInt8(); + uint8 leftPoint = fields[9].GetUInt8(); + uint16 topOffset = fields[10].GetUInt16(); + uint16 bottomOffset = fields[11].GetUInt16(); + uint16 leftOffset = fields[12].GetUInt16(); if (id > MAX_CUF_PROFILES) { @@ -17374,7 +17389,7 @@ void Player::_LoadCUFProfiles(PreparedQueryResult result) continue; } - _CUFProfiles[id] = new CUFProfile(name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154); + _CUFProfiles[id] = Trinity::make_unique<CUFProfile>(name, frameHeight, frameWidth, sortBy, healthText, boolOptions, topPoint, bottomPoint, leftPoint, topOffset, bottomOffset, leftOffset); } while (result->NextRow()); } @@ -18542,12 +18557,7 @@ void Player::SetPendingBind(uint32 instanceId, uint32 bindTimer) void Player::SendRaidInfo() { - uint32 counter = 0; - - WorldPacket data(SMSG_INSTANCE_INFO, 4); - - size_t p_counter = data.wpos(); - data << uint32(counter); // placeholder + WorldPackets::Instance::InstanceInfo instanceInfo; time_t now = time(NULL); @@ -18558,27 +18568,28 @@ void Player::SendRaidInfo() if (itr->second.perm) { InstanceSave* save = itr->second.save; - bool isHeroic = save->GetDifficultyID() == DIFFICULTY_10_HC || save->GetDifficultyID() == DIFFICULTY_25_HC; - uint32 completedEncounters = 0; + + WorldPackets::Instance::InstanceLockInfos lockInfos; + + lockInfos.InstanceID = save->GetInstanceId(); + lockInfos.MapID = save->GetMapId(); + lockInfos.DifficultyID = save->GetDifficultyID(); + lockInfos.TimeRemaining = save->GetResetTime() - now; + + lockInfos.CompletedMask = 0; if (Map* map = sMapMgr->FindMap(save->GetMapId(), save->GetInstanceId())) if (InstanceScript* instanceScript = ((InstanceMap*)map)->GetInstanceScript()) - completedEncounters = instanceScript->GetCompletedEncounterMask(); + lockInfos.CompletedMask = instanceScript->GetCompletedEncounterMask(); - data << uint32(save->GetMapId()); // map id - data << uint32(save->GetDifficultyID()); // difficulty - data << uint32(isHeroic); // heroic - data << uint64(save->GetInstanceId()); // instance id - data << uint8(1); // expired = 0 - data << uint8(0); // extended = 1 - data << uint32(save->GetResetTime() - now); // reset time - data << uint32(completedEncounters); // completed encounters mask - ++counter; + lockInfos.Locked = lockInfos.TimeRemaining <= 0; + lockInfos.Extended = false; + + instanceInfo.LockList.push_back(lockInfos); } } } - data.put<uint32>(p_counter, counter); - GetSession()->SendPacket(&data); + GetSession()->SendPacket(instanceInfo.Write()); } /// convert the player's binds to the group @@ -19403,13 +19414,13 @@ void Player::_SaveCUFProfiles(SQLTransaction& trans) stmt->setUInt16(4, _CUFProfiles[i]->FrameWidth); stmt->setUInt8(5, _CUFProfiles[i]->SortBy); stmt->setUInt8(6, _CUFProfiles[i]->HealthText); - stmt->setUInt32(7, _CUFProfiles[i]->BoolOptions.to_ulong()); // 27 of 32 fields used, fits in an int - stmt->setUInt8(8, _CUFProfiles[i]->Unk146); - stmt->setUInt8(9, _CUFProfiles[i]->Unk147); - stmt->setUInt8(10, _CUFProfiles[i]->Unk148); - stmt->setUInt16(11, _CUFProfiles[i]->Unk150); - stmt->setUInt16(12, _CUFProfiles[i]->Unk152); - stmt->setUInt16(13, _CUFProfiles[i]->Unk154); + stmt->setUInt32(7, _CUFProfiles[i]->BoolOptions.to_ulong()); // 25 of 32 fields used, fits in an int + stmt->setUInt8(8, _CUFProfiles[i]->TopPoint); + stmt->setUInt8(9, _CUFProfiles[i]->BottomPoint); + stmt->setUInt8(10, _CUFProfiles[i]->LeftPoint); + stmt->setUInt16(11, _CUFProfiles[i]->TopOffset); + stmt->setUInt16(12, _CUFProfiles[i]->BottomOffset); + stmt->setUInt16(13, _CUFProfiles[i]->LeftOffset); } trans->Append(stmt); @@ -20205,7 +20216,7 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) GetSession()->SendPacket(&data); if (GetGroup()) - SetGroupUpdateFlag(GROUP_UPDATE_PET); + SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET); } } @@ -20244,7 +20255,7 @@ void Player::Say(std::string const& text, Language language, WorldObject const* sScriptMgr->OnPlayerChat(this, CHAT_MSG_SAY, language, _text); WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_SAY, language, this, this, _text); + packet.Initialize(CHAT_MSG_SAY, language, this, this, _text); SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); } @@ -20254,7 +20265,7 @@ void Player::Yell(std::string const& text, Language language, WorldObject const* sScriptMgr->OnPlayerChat(this, CHAT_MSG_YELL, language, _text); WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_YELL, language, this, this, _text); + packet.Initialize(CHAT_MSG_YELL, language, this, this, _text); SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true); } @@ -20264,7 +20275,7 @@ void Player::TextEmote(std::string const& text, WorldObject const* /*= nullptr*/ sScriptMgr->OnPlayerChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text); WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text); + packet.Initialize(CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text); SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)); } @@ -20277,7 +20288,7 @@ void Player::WhisperAddon(std::string const& text, const std::string& prefix, Pl return; WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_WHISPER, LANG_ADDON, this, this, text, 0, "", DEFAULT_LOCALE, prefix); + packet.Initialize(CHAT_MSG_WHISPER, LANG_ADDON, this, this, text, 0, "", DEFAULT_LOCALE, prefix); receiver->SendDirectMessage(packet.Write()); } @@ -20294,14 +20305,14 @@ void Player::Whisper(std::string const& text, Language language, Player* target, sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, target); WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_WHISPER, Language(language), this, this, _text); + packet.Initialize(CHAT_MSG_WHISPER, Language(language), this, this, _text); target->SendDirectMessage(packet.Write()); // rest stuff shouldn't happen in case of addon message if (isAddonMessage) return; - packet.Initalize(CHAT_MSG_WHISPER_INFORM, Language(language), target, target, _text); + packet.Initialize(CHAT_MSG_WHISPER_INFORM, Language(language), target, target, _text); SendDirectMessage(packet.Write()); if (!isAcceptWhispers() && !IsGameMaster() && !target->IsGameMaster()) @@ -22269,7 +22280,7 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& vi m_clientGUIDs.erase(target->GetGUID()); #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Object %u (%s) is out of range for %s. Distance = %f", target->GetGUID().ToString().c_str(), target->GetEntry(), GetGUID().ToString().c_str(), GetDistance(target)); + TC_LOG_DEBUG("maps", "Object %s (%u) is out of range for %s. Distance = %f", target->GetGUID().ToString().c_str(), target->GetEntry(), GetGUID().ToString().c_str(), GetDistance(target)); #endif } } @@ -22281,7 +22292,7 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& vi UpdateVisibilityOf_helper(m_clientGUIDs, target, visibleNow); #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Object %u (%s) is visible now for %s. Distance = %f", target->GetGUID().ToString().c_str(), target->GetEntry(), GetGUID().ToString().c_str(), GetDistance(target)); + TC_LOG_DEBUG("maps", "Object %s (%u) is visible now for %s. Distance = %f", target->GetGUID().ToString().c_str(), target->GetEntry(), GetGUID().ToString().c_str(), GetDistance(target)); #endif } } @@ -22621,9 +22632,8 @@ void Player::SendUpdateToOutOfRangeGroupMembers() group->UpdatePlayerOutOfRange(this); m_groupUpdateMask = GROUP_UPDATE_FLAG_NONE; - m_auraRaidUpdateMask = 0; if (Pet* pet = GetPet()) - pet->ResetAuraUpdateMaskForRaid(); + pet->ResetGroupUpdateFlag(); } void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7de2b09a5cb..c7af9426623 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -207,8 +207,9 @@ enum CUFBoolOptions CUF_DISPLAY_POWER_BAR, CUF_DISPLAY_BORDER, CUF_USE_CLASS_COLORS, - CUF_DISPLAY_NON_BOSS_DEBUFFS, CUF_DISPLAY_HORIZONTAL_GROUPS, + CUF_DISPLAY_NON_BOSS_DEBUFFS, + CUF_DYNAMIC_POSITION, CUF_LOCKED, CUF_SHOWN, CUF_AUTO_ACTIVATE_2_PLAYERS, @@ -222,9 +223,6 @@ enum CUFBoolOptions CUF_AUTO_ACTIVATE_SPEC_2, CUF_AUTO_ACTIVATE_PVP, CUF_AUTO_ACTIVATE_PVE, - CUF_UNK_145, - CUF_UNK_156, - CUF_UNK_157, // The unks is _LOCKED and _SHOWN and _DYNAMIC, unknown order @@ -236,32 +234,32 @@ struct CUFProfile { CUFProfile() : ProfileName(), BoolOptions() // might want to change default value for options { - FrameHeight = 0; - FrameWidth = 0; - SortBy = 0; - HealthText = 0; - Unk146 = 0; - Unk147 = 0; - Unk148 = 0; - Unk150 = 0; - Unk152 = 0; - Unk154 = 0; + FrameHeight = 0; + FrameWidth = 0; + SortBy = 0; + HealthText = 0; + TopPoint = 0; + BottomPoint = 0; + LeftPoint = 0; + TopOffset = 0; + BottomOffset = 0; + LeftOffset = 0; } CUFProfile(const std::string& name, uint16 frameHeight, uint16 frameWidth, uint8 sortBy, uint8 healthText, uint32 boolOptions, - uint8 unk146, uint8 unk147, uint8 unk148, uint16 unk150, uint16 unk152, uint16 unk154) + uint8 topPoint, uint8 bottomPoint, uint8 leftPoint, uint16 topOffset, uint16 bottomOffset, uint16 leftOffset) : ProfileName(name), BoolOptions((int)boolOptions) { - FrameHeight = frameHeight; - FrameWidth = frameWidth; - SortBy = sortBy; - HealthText = healthText; - Unk146 = unk146; - Unk147 = unk147; - Unk148 = unk148; - Unk150 = unk150; - Unk152 = unk152; - Unk154 = unk154; + FrameHeight = frameHeight; + FrameWidth = frameWidth; + SortBy = sortBy; + HealthText = healthText; + TopPoint = topPoint; + BottomPoint = bottomPoint; + LeftPoint = leftPoint; + TopOffset = topOffset; + BottomOffset = bottomOffset; + LeftOffset = leftOffset; } std::string ProfileName; @@ -270,15 +268,15 @@ struct CUFProfile uint8 SortBy; uint8 HealthText; - // LeftAlign, TopAlight, BottomAllign (unk order) - uint8 Unk146; - uint8 Unk147; - uint8 Unk148; + // LeftAlign, TopAlight, BottomAlign + uint8 TopPoint; + uint8 BottomPoint; + uint8 LeftPoint; - // LeftOffset, TopOffset and BottomOffset (unk order) - uint16 Unk150; - uint16 Unk152; - uint16 Unk154; + // LeftOffset, TopOffset and BottomOffset + uint16 TopOffset; + uint16 BottomOffset; + uint16 LeftOffset; std::bitset<CUF_BOOL_OPTIONS_COUNT> BoolOptions; @@ -311,6 +309,7 @@ enum ActionButtonType ACTION_BUTTON_DROPDOWN = 0x30, ACTION_BUTTON_MACRO = 0x40, ACTION_BUTTON_CMACRO = ACTION_BUTTON_C | ACTION_BUTTON_MACRO, + ACTION_BUTTON_MOUNT = 0x60, ACTION_BUTTON_ITEM = 0x80 }; @@ -1324,7 +1323,6 @@ private: PlayerTalentInfo(PlayerTalentInfo const&); }; - class Player : public Unit, public GridObject<Player> { friend class WorldSession; @@ -1737,8 +1735,9 @@ class Player : public Unit, public GridObject<Player> void AddTimedQuest(uint32 questId) { m_timedquests.insert(questId); } void RemoveTimedQuest(uint32 questId) { m_timedquests.erase(questId); } - void SaveCUFProfile(uint8 id, CUFProfile* profile) { delete _CUFProfiles[id]; _CUFProfiles[id] = profile; } ///> Replaces a CUF profile at position 0-4 - CUFProfile* GetCUFProfile(uint8 id) const { return _CUFProfiles[id]; } ///> Retrieves a CUF profile at position 0-4 + void SaveCUFProfile(uint8 id, std::nullptr_t) { _CUFProfiles[id] = nullptr; } ///> Empties a CUF profile at position 0-4 + void SaveCUFProfile(uint8 id, std::unique_ptr<CUFProfile> profile) { _CUFProfiles[id] = std::move(profile); } ///> Replaces a CUF profile at position 0-4 + CUFProfile* GetCUFProfile(uint8 id) const { return _CUFProfiles[id].get(); } ///> Retrieves a CUF profile at position 0-4 uint8 GetCUFProfilesCount() const { uint8 count = 0; @@ -2522,8 +2521,7 @@ class Player : public Unit, public GridObject<Player> uint8 GetSubGroup() const { return m_group.getSubGroup(); } uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; } void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; } - uint64 GetAuraUpdateMaskForRaid() const { return m_auraRaidUpdateMask; } - void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); } + void RemoveGroupUpdateFlag(uint32 flag) { m_groupUpdateMask &= ~flag; } Player* GetNextRandomRaidMember(float radius); PartyResult CanUninviteFromGroup(ObjectGuid guidMember = ObjectGuid::Empty) const; @@ -2889,7 +2887,6 @@ class Player : public Unit, public GridObject<Player> GroupReference m_originalGroup; Group* m_groupInvite; uint32 m_groupUpdateMask; - uint64 m_auraRaidUpdateMask; bool m_bPassOnGroupLoot; // last used pet number (for BG's) @@ -2912,7 +2909,7 @@ class Player : public Unit, public GridObject<Player> uint8 m_grantableLevels; - CUFProfile* _CUFProfiles[MAX_CUF_PROFILES]; + std::array<std::unique_ptr<CUFProfile>, MAX_CUF_PROFILES> _CUFProfiles = {}; private: // internal common parts for CanStore/StoreItem functions diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 81497029e55..7034f7fbdc5 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -36,7 +36,7 @@ Transport::Transport() : GameObject(), _transportInfo(NULL), _isMoving(true), _pendingStop(false), _triggeredArrivalEvent(false), _triggeredDepartureEvent(false), - _passengerTeleportItr(_passengers.begin()), _delayedAddModel(false) + _passengerTeleportItr(_passengers.begin()), _delayedAddModel(false), _delayedTeleport(false) { m_updateFlag = UPDATEFLAG_TRANSPORT | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_ROTATION; } @@ -231,6 +231,14 @@ void Transport::Update(uint32 diff) sScriptMgr->OnTransportUpdate(this, diff); } +void Transport::DelayedUpdate(uint32 diff) +{ + if (GetKeyFrames().size() <= 1) + return; + + DelayedTeleportTransport(); +} + void Transport::AddPassenger(WorldObject* passenger) { if (!IsInWorld()) @@ -607,36 +615,8 @@ bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, fl if (oldMap->GetId() != newMapid) { - Map* newMap = sMapMgr->CreateBaseMap(newMapid); + _delayedTeleport = true; UnloadStaticPassengers(); - GetMap()->RemoveFromMap<Transport>(this, false); - SetMap(newMap); - - for (_passengerTeleportItr = _passengers.begin(); _passengerTeleportItr != _passengers.end();) - { - WorldObject* obj = (*_passengerTeleportItr++); - - float destX, destY, destZ, destO; - obj->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO); - TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, o); - - switch (obj->GetTypeId()) - { - case TYPEID_PLAYER: - if (!obj->ToPlayer()->TeleportTo(newMapid, destX, destY, destZ, destO, TELE_TO_NOT_LEAVE_TRANSPORT)) - RemovePassenger(obj); - break; - case TYPEID_DYNAMICOBJECT: - obj->AddObjectToRemoveList(); - break; - default: - RemovePassenger(obj); - break; - } - } - - Relocate(x, y, z, o); - GetMap()->AddToMap<Transport>(this); return true; } else @@ -659,6 +639,48 @@ bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, fl } } +void Transport::DelayedTeleportTransport() +{ + if (!_delayedTeleport) + return; + + _delayedTeleport = false; + Map* newMap = sMapMgr->CreateBaseMap(_nextFrame->Node->MapID); + GetMap()->RemoveFromMap<Transport>(this, false); + SetMap(newMap); + + float x = _nextFrame->Node->Loc.X, + y = _nextFrame->Node->Loc.Y, + z = _nextFrame->Node->Loc.Z, + o =_nextFrame->InitialOrientation; + + for (_passengerTeleportItr = _passengers.begin(); _passengerTeleportItr != _passengers.end();) + { + WorldObject* obj = (*_passengerTeleportItr++); + + float destX, destY, destZ, destO; + obj->m_movementInfo.transport.pos.GetPosition(destX, destY, destZ, destO); + TransportBase::CalculatePassengerPosition(destX, destY, destZ, &destO, x, y, z, o); + + switch (obj->GetTypeId()) + { + case TYPEID_PLAYER: + if (!obj->ToPlayer()->TeleportTo(_nextFrame->Node->MapID, destX, destY, destZ, destO, TELE_TO_NOT_LEAVE_TRANSPORT)) + RemovePassenger(obj); + break; + case TYPEID_DYNAMICOBJECT: + obj->AddObjectToRemoveList(); + break; + default: + RemovePassenger(obj); + break; + } + } + + Relocate(x, y, z, o); + GetMap()->AddToMap<Transport>(this); +} + void Transport::UpdatePassengerPositions(PassengerSet& passengers) { for (PassengerSet::iterator itr = passengers.begin(); itr != passengers.end(); ++itr) diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 193e32300c0..d6598a0036c 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -39,6 +39,7 @@ class Transport : public GameObject, public TransportBase void CleanupsBeforeDelete(bool finalCleanup = true) override; void Update(uint32 diff) override; + void DelayedUpdate(uint32 diff); void BuildUpdate(UpdateDataMapType& data_map) override; @@ -103,6 +104,7 @@ class Transport : public GameObject, public TransportBase void MoveToNextWaypoint(); float CalculateSegmentPos(float perc); bool TeleportTransport(uint32 newMapid, float x, float y, float z, float o); + void DelayedTeleportTransport(); void UpdatePassengerPositions(PassengerSet& passengers); void DoEventIfAny(KeyFrame const& node, bool departure); @@ -127,6 +129,7 @@ class Transport : public GameObject, public TransportBase PassengerSet _staticPassengers; bool _delayedAddModel; + bool _delayedTeleport; }; #endif diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 7ae20779fa7..a581e612980 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -6957,15 +6957,11 @@ void Unit::setPowerType(Powers new_powertype) if (ToPlayer()->GetGroup()) ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POWER_TYPE); } - else if (Pet* pet = ToCreature()->ToPet()) + /*else if (Pet* pet = ToCreature()->ToPet()) TODO 6.x { if (pet->isControlled()) - { - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_POWER_TYPE); - } - } + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_POWER_TYPE); + }*/ float powerMultiplier = 1.0f; if (!IsPet()) @@ -11470,11 +11466,7 @@ void Unit::SetHealth(uint32 val) else if (Pet* pet = ToCreature()->ToPet()) { if (pet->isControlled()) - { - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_HP); - } + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_HP); } } @@ -11495,11 +11487,7 @@ void Unit::SetMaxHealth(uint32 val) else if (Pet* pet = ToCreature()->ToPet()) { if (pet->isControlled()) - { - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_HP); - } + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_HP); } if (val < health) @@ -11551,15 +11539,11 @@ void Unit::SetPower(Powers power, int32 val) if (player->GetGroup()) player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_POWER); } - else if (Pet* pet = ToCreature()->ToPet()) + /*else if (Pet* pet = ToCreature()->ToPet()) TODO 6.x { if (pet->isControlled()) - { - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER); - } - } + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER); + }*/ } void Unit::SetMaxPower(Powers power, int32 val) @@ -11577,15 +11561,11 @@ void Unit::SetMaxPower(Powers power, int32 val) if (ToPlayer()->GetGroup()) ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_MAX_POWER); } - else if (Pet* pet = ToCreature()->ToPet()) + /*else if (Pet* pet = ToCreature()->ToPet()) TODO 6.x { if (pet->isControlled()) - { - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER); - } - } + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER); + }*/ if (val < cur_power) SetPower(power, val); @@ -13007,23 +12987,13 @@ void Unit::UpdateAuraForGroup(uint8 slot) if (Player* player = ToPlayer()) { if (player->GetGroup()) - { player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_AURAS); - player->SetAuraUpdateMaskForRaid(slot); - } } else if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsPet()) { Pet* pet = ((Pet*)this); if (pet->isControlled()) - { - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - { - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_AURAS); - pet->SetAuraUpdateMaskForRaid(slot); - } - } + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_AURAS); } } @@ -16401,7 +16371,7 @@ void Unit::Whisper(std::string const& text, Language language, Player* target, b LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex(); WorldPackets::Chat::Chat packet; - packet.Initalize(isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, language, this, target, text, 0, "", locale); + packet.Initialize(isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, language, this, target, text, 0, "", locale); target->SendDirectMessage(packet.Write()); } @@ -16448,7 +16418,7 @@ void Unit::Whisper(uint32 textId, Player* target, bool isBossWhisper /*= false*/ LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex(); WorldPackets::Chat::Chat packet; - packet.Initalize(isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, DB2Manager::GetBroadcastTextValue(bct, locale, getGender()), 0, "", locale); + packet.Initialize(isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, DB2Manager::GetBroadcastTextValue(bct, locale, getGender()), 0, "", locale); target->SendDirectMessage(packet.Write()); } diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index ba247dbd19e..0d6b971ec15 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -1266,8 +1266,12 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) sMapMgr->DoForAllMapsWithMapId(data->mapid, [&itr](Map* map) { auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(*itr); - for (auto itr = creatureBounds.first; itr != creatureBounds.second; ++itr) - itr->second->AddObjectToRemoveList(); + for (auto itr2 = creatureBounds.first; itr2 != creatureBounds.second;) + { + Creature* creature = itr2->second; + ++itr2; + creature->AddObjectToRemoveList(); + } }); } } @@ -1292,11 +1296,16 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) sMapMgr->DoForAllMapsWithMapId(data->mapid, [&itr](Map* map) { auto gameobjectBounds = map->GetGameObjectBySpawnIdStore().equal_range(*itr); - for (auto itr = gameobjectBounds.first; itr != gameobjectBounds.second; ++itr) - itr->second->AddObjectToRemoveList(); + for (auto itr2 = gameobjectBounds.first; itr2 != gameobjectBounds.second;) + { + GameObject* go = itr2->second; + ++itr2; + go->AddObjectToRemoveList(); + } }); } } + if (internal_event_id < 0 || internal_event_id >= int32(mGameEventPoolIds.size())) { TC_LOG_ERROR("gameevent", "GameEventMgr::GameEventUnspawn attempt access to out of range mGameEventPoolIds element %u (size: %zu)", internal_event_id, mGameEventPoolIds.size()); diff --git a/src/server/game/Garrison/Garrison.cpp b/src/server/game/Garrison/Garrison.cpp index 15387d9a9b6..3087de37472 100644 --- a/src/server/game/Garrison/Garrison.cpp +++ b/src/server/game/Garrison/Garrison.cpp @@ -210,6 +210,15 @@ Garrison::Plot* Garrison::GetPlot(uint32 garrPlotInstanceId) return nullptr; } +Garrison::Plot const* Garrison::GetPlot(uint32 garrPlotInstanceId) const +{ + auto itr = _plots.find(garrPlotInstanceId); + if (itr != _plots.end()) + return &itr->second; + + return nullptr; +} + void Garrison::LearnBlueprint(uint32 garrBuildingId) { WorldPackets::Garrison::GarrisonLearnBlueprintResult learnBlueprintResult; @@ -253,33 +262,116 @@ void Garrison::PlaceBuilding(uint32 garrPlotInstanceId, uint32 garrBuildingId) placeBuildingResult.BuildingInfo.TimeBuilt = time(nullptr); Plot* plot = GetPlot(garrPlotInstanceId); + uint32 oldBuildingId = 0; + Map* map = FindMap(); + GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(garrBuildingId); + if (map) + plot->DeleteGameObject(map); - if (Map* map = FindMap()) + if (plot->BuildingInfo.PacketInfo) { - if (!plot->BuildingInfo.Guid.IsEmpty()) - { - if (GameObject* oldBuilding = map->GetGameObject(plot->BuildingInfo.Guid)) - oldBuilding->AddObjectToRemoveList(); - - plot->BuildingInfo.Guid.Clear(); - } + oldBuildingId = plot->BuildingInfo.PacketInfo->GarrBuildingID; + if (sGarrBuildingStore.AssertEntry(oldBuildingId)->Type != building->Type) + plot->ClearBuildingInfo(_owner); + } - plot->BuildingInfo.PacketInfo = placeBuildingResult.BuildingInfo; + plot->SetBuildingInfo(placeBuildingResult.BuildingInfo, _owner); + if (map) if (GameObject* go = plot->CreateGameObject(map, GetFaction())) - { map->AddToMap(go); - GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(garrBuildingId); - _owner->ModifyCurrency(building->CostCurrencyID, -building->CostCurrencyAmount, false, true); - _owner->ModifyMoney(-building->CostMoney, false); - } - else - plot->BuildingInfo.PacketInfo = boost::none; + + _owner->ModifyCurrency(building->CostCurrencyID, -building->CostCurrencyAmount, false, true); + _owner->ModifyMoney(-building->CostMoney * GOLD, false); + + if (oldBuildingId) + { + WorldPackets::Garrison::GarrisonBuildingRemoved buildingRemoved; + buildingRemoved.Result = GARRISON_SUCCESS; + buildingRemoved.GarrPlotInstanceID = garrPlotInstanceId; + buildingRemoved.GarrBuildingID = oldBuildingId; + _owner->SendDirectMessage(buildingRemoved.Write()); } } _owner->SendDirectMessage(placeBuildingResult.Write()); } +void Garrison::CancelBuildingConstruction(uint32 garrPlotInstanceId) +{ + WorldPackets::Garrison::GarrisonBuildingRemoved buildingRemoved; + buildingRemoved.Result = CheckBuildingRemoval(garrPlotInstanceId); + if (buildingRemoved.Result == GARRISON_SUCCESS) + { + Plot* plot = GetPlot(garrPlotInstanceId); + + buildingRemoved.GarrPlotInstanceID = garrPlotInstanceId; + buildingRemoved.GarrBuildingID = plot->BuildingInfo.PacketInfo->GarrBuildingID; + + Map* map = FindMap(); + if (map) + plot->DeleteGameObject(map); + + plot->ClearBuildingInfo(_owner); + _owner->SendDirectMessage(buildingRemoved.Write()); + + GarrBuildingEntry const* constructing = sGarrBuildingStore.AssertEntry(buildingRemoved.GarrBuildingID); + // Refund construction/upgrade cost + _owner->ModifyCurrency(constructing->CostCurrencyID, constructing->CostCurrencyAmount, false, true); + _owner->ModifyMoney(constructing->CostMoney * GOLD, false); + + if (constructing->Level > 1) + { + // Restore previous level building + GarrBuildingEntry const* restored = sGarrisonMgr.GetPreviousLevelBuilding(constructing->Type, constructing->Level); + ASSERT(restored); + + WorldPackets::Garrison::GarrisonPlaceBuildingResult placeBuildingResult; + placeBuildingResult.Result = GARRISON_SUCCESS; + placeBuildingResult.BuildingInfo.GarrPlotInstanceID = garrPlotInstanceId; + placeBuildingResult.BuildingInfo.GarrBuildingID = restored->ID; + placeBuildingResult.BuildingInfo.TimeBuilt = time(nullptr); + placeBuildingResult.BuildingInfo.Active = true; + + plot->SetBuildingInfo(placeBuildingResult.BuildingInfo, _owner); + _owner->SendDirectMessage(placeBuildingResult.Write()); + } + + if (map) + if (GameObject* go = plot->CreateGameObject(map, GetFaction())) + map->AddToMap(go); + } + else + _owner->SendDirectMessage(buildingRemoved.Write()); +} + +void Garrison::AddFollower(uint32 garrFollowerId) +{ + WorldPackets::Garrison::GarrisonAddFollowerResult addFollowerResult; + GarrFollowerEntry const* followerEntry = sGarrFollowerStore.LookupEntry(garrFollowerId); + if (_followers.count(garrFollowerId) || !followerEntry) + { + addFollowerResult.Result = GARRISON_GENERIC_UNKNOWN_ERROR; + _owner->SendDirectMessage(addFollowerResult.Write()); + return; + } + + Follower& follower = _followers[garrFollowerId]; + follower.PacketInfo.DbID = sGarrisonMgr.GenerateFollowerDbId(); + follower.PacketInfo.GarrFollowerID = garrFollowerId; + follower.PacketInfo.Quality = followerEntry->Quality; // TODO: handle magic upgrades + follower.PacketInfo.FollowerLevel = followerEntry->Level; + follower.PacketInfo.ItemLevelWeapon = followerEntry->ItemLevelWeapon; + follower.PacketInfo.ItemLevelArmor = followerEntry->ItemLevelArmor; + follower.PacketInfo.Xp = 0; + follower.PacketInfo.CurrentBuildingID = 0; + follower.PacketInfo.CurrentMissionID = 0; + follower.PacketInfo.AbilityID = sGarrisonMgr.RollFollowerAbilities(followerEntry, follower.PacketInfo.Quality, GetFaction(), true); + follower.PacketInfo.FollowerStatus = 0; + + addFollowerResult.Follower = follower.PacketInfo; + _owner->SendDirectMessage(addFollowerResult.Write()); +} + void Garrison::SendInfo() { WorldPackets::Garrison::GetGarrisonInfoResult garrisonInfo; @@ -295,6 +387,9 @@ void Garrison::SendInfo() garrisonInfo.Buildings.push_back(plot.BuildingInfo.PacketInfo.get_ptr()); } + for (auto const& p : _followers) + garrisonInfo.Followers.push_back(&p.second.PacketInfo); + _owner->SendDirectMessage(garrisonInfo.Write()); } @@ -347,7 +442,8 @@ Map* Garrison::FindMap() const GarrisonError Garrison::CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32 garrBuildingId) const { GarrPlotInstanceEntry const* plotInstance = sGarrPlotInstanceStore.LookupEntry(garrPlotInstanceId); - if (!plotInstance || !_plots.count(garrPlotInstanceId)) + Plot const* plot = GetPlot(garrPlotInstanceId); + if (!plotInstance || !plot) return GARRISON_ERROR_INVALID_PLOT; GarrBuildingEntry const* building = sGarrBuildingStore.LookupEntry(garrBuildingId); @@ -357,9 +453,13 @@ GarrisonError Garrison::CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32 if (!sGarrisonMgr.IsPlotMatchingBuilding(plotInstance->GarrPlotID, garrBuildingId)) return GARRISON_ERROR_INVALID_PLOT_BUILDING; + // Cannot place buldings of higher level than garrison level + if (building->Level > _siteLevel->Level) + return GARRISON_ERROR_INVALID_BUILDINGID; + if (building->Flags & GARRISON_BUILDING_FLAG_NEEDS_PLAN) { - if (_knownBuildings.count(garrBuildingId)) + if (!_knownBuildings.count(garrBuildingId)) return GARRISON_ERROR_BLUEPRINT_NOT_KNOWN; } else // Building is built as a quest reward @@ -373,7 +473,7 @@ GarrisonError Garrison::CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32 { existingBuilding = sGarrBuildingStore.AssertEntry(p.second.BuildingInfo.PacketInfo->GarrBuildingID); if (existingBuilding->Type == building->Type) - if (p.first != garrPlotInstanceId || existingBuilding->Level != building->Level + 1) // check if its an upgrade in same plot + if (p.first != garrPlotInstanceId || existingBuilding->Level + 1 != building->Level) // check if its an upgrade in same plot return GARRISON_ERROR_BUILDING_EXISTS; } } @@ -381,9 +481,29 @@ GarrisonError Garrison::CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32 if (!_owner->HasCurrency(building->CostCurrencyID, building->CostCurrencyAmount)) return GARRISON_ERROR_NOT_ENOUGH_CURRENCY; - if (!_owner->HasEnoughMoney(uint64(building->CostMoney))) + if (!_owner->HasEnoughMoney(uint64(building->CostMoney * GOLD))) return GARRISON_ERROR_NOT_ENOUGH_GOLD; + // New building cannot replace another building currently under construction + if (plot->BuildingInfo.PacketInfo) + if (!plot->BuildingInfo.PacketInfo->Active) + return GARRISON_ERROR_NO_BUILDING; + + return GARRISON_SUCCESS; +} + +GarrisonError Garrison::CheckBuildingRemoval(uint32 garrPlotInstanceId) const +{ + Plot const* plot = GetPlot(garrPlotInstanceId); + if (!plot) + return GARRISON_ERROR_INVALID_PLOT; + + if (!plot->BuildingInfo.PacketInfo) + return GARRISON_ERROR_NO_BUILDING; + + if (plot->BuildingInfo.CanActivate()) + return GARRISON_ERROR_BUILDING_EXISTS; + return GARRISON_SUCCESS; } @@ -395,7 +515,7 @@ GameObject* Garrison::Plot::CreateGameObject(Map* map, GarrisonFactionIndex fact GarrPlotInstanceEntry const* plotInstance = sGarrPlotInstanceStore.AssertEntry(PacketInfo.GarrPlotInstanceID); GarrPlotEntry const* plot = sGarrPlotStore.AssertEntry(plotInstance->GarrPlotID); GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(BuildingInfo.PacketInfo->GarrBuildingID); - if (BuildingInfo.PacketInfo->TimeBuilt + building->BuildDuration <= time(nullptr) && BuildingInfo.PacketInfo->Active) + if (BuildingInfo.PacketInfo->Active) entry = faction == GARRISON_FACTION_INDEX_HORDE ? building->HordeGameObjectID : building->AllianceGameObjectID; else entry = faction == GARRISON_FACTION_INDEX_HORDE ? plot->HordeConstructionGameObjectID : plot->AllianceConstructionGameObjectID; @@ -419,3 +539,47 @@ GameObject* Garrison::Plot::CreateGameObject(Map* map, GarrisonFactionIndex fact BuildingInfo.Guid = go->GetGUID(); return go; } + +void Garrison::Plot::DeleteGameObject(Map* map) +{ + if (BuildingInfo.Guid.IsEmpty()) + return; + + if (GameObject* oldBuilding = map->GetGameObject(BuildingInfo.Guid)) + oldBuilding->Delete(); + + BuildingInfo.Guid.Clear(); +} + +void Garrison::Plot::ClearBuildingInfo(Player* owner) +{ + WorldPackets::Garrison::GarrisonPlotPlaced plotPlaced; + plotPlaced.PlotInfo = &PacketInfo; + owner->SendDirectMessage(plotPlaced.Write()); + + BuildingInfo.PacketInfo = boost::none; +} + +void Garrison::Plot::SetBuildingInfo(WorldPackets::Garrison::GarrisonBuildingInfo const& buildingInfo, Player* owner) +{ + if (!BuildingInfo.PacketInfo) + { + WorldPackets::Garrison::GarrisonPlotRemoved plotRemoved; + plotRemoved.GarrPlotInstanceID = PacketInfo.GarrPlotInstanceID; + owner->SendDirectMessage(plotRemoved.Write()); + } + + BuildingInfo.PacketInfo = buildingInfo; +} + +bool Garrison::Building::CanActivate() const +{ + if (PacketInfo) + { + GarrBuildingEntry const* building = sGarrBuildingStore.AssertEntry(PacketInfo->GarrBuildingID); + if (PacketInfo->TimeBuilt + building->BuildDuration <= time(nullptr)) + return true; + } + + return false; +} diff --git a/src/server/game/Garrison/Garrison.h b/src/server/game/Garrison/Garrison.h index 37712386d0b..be92b9e14f3 100644 --- a/src/server/game/Garrison/Garrison.h +++ b/src/server/game/Garrison/Garrison.h @@ -32,6 +32,21 @@ enum GarrisonBuildingFlags GARRISON_BUILDING_FLAG_NEEDS_PLAN = 0x1 }; +enum GarrisonFollowerFlags +{ + GARRISON_FOLLOWER_FLAG_UNIQUE = 0x1 +}; + +enum GarrisonAbilityFlags +{ + GARRISON_ABILITY_FLAG_TRAIT = 0x01, + GARRISON_ABILITY_CANNOT_ROLL = 0x02, + GARRISON_ABILITY_HORDE_ONLY = 0x04, + GARRISON_ABILITY_ALLIANCE_ONLY = 0x08, + GARRISON_ABILITY_FLAG_CANNOT_REMOVE = 0x10, + GARRISON_ABILITY_FLAG_EXCLUSIVE = 0x20 +}; + enum GarrisonError { GARRISON_SUCCESS = 0, @@ -44,7 +59,9 @@ enum GarrisonError GARRISON_ERROR_BLUEPRINT_NOT_KNOWN = 22, GARRISON_ERROR_BUILDING_EXISTS = 24, GARRISON_ERROR_NOT_ENOUGH_CURRENCY = 46, - GARRISON_ERROR_NOT_ENOUGH_GOLD = 47 + GARRISON_ERROR_NOT_ENOUGH_GOLD = 47, + + GARRISON_GENERIC_UNKNOWN_ERROR = 255 // custom value for packets whose handlers only check if error != 0 }; enum GarrisonFollowerStatus @@ -62,6 +79,8 @@ class Garrison public: struct Building { + bool CanActivate() const; + ObjectGuid Guid; Optional<WorldPackets::Garrison::GarrisonBuildingInfo> PacketInfo; }; @@ -69,6 +88,9 @@ public: struct Plot { GameObject* CreateGameObject(Map* map, GarrisonFactionIndex faction); + void DeleteGameObject(Map* map); + void ClearBuildingInfo(Player* owner); + void SetBuildingInfo(WorldPackets::Garrison::GarrisonBuildingInfo const& buildingInfo, Player* owner); WorldPackets::Garrison::GarrisonPlotInfo PacketInfo; uint32 EmptyGameObjectId = 0; @@ -76,6 +98,11 @@ public: Building BuildingInfo; }; + struct Follower + { + WorldPackets::Garrison::GarrisonFollower PacketInfo; + }; + explicit Garrison(Player* owner); bool LoadFromDB(PreparedQueryResult garrison, PreparedQueryResult blueprints, PreparedQueryResult buildings); @@ -88,12 +115,20 @@ public: void Leave() const; GarrisonFactionIndex GetFaction() const; + + // Plots std::vector<Plot*> GetPlots(); Plot* GetPlot(uint32 garrPlotInstanceId); + Plot const* GetPlot(uint32 garrPlotInstanceId) const; + // Buildings void LearnBlueprint(uint32 garrBuildingId); void UnlearnBlueprint(uint32 garrBuildingId); void PlaceBuilding(uint32 garrPlotInstanceId, uint32 garrBuildingId); + void CancelBuildingConstruction(uint32 garrPlotInstanceId); + + // Followers + void AddFollower(uint32 garrFollowerId); void SendInfo(); void SendRemoteInfo() const; @@ -106,12 +141,14 @@ private: Map* FindMap() const; void InitializePlots(); GarrisonError CheckBuildingPlacement(uint32 garrPlotInstanceId, uint32 garrBuildingId) const; + GarrisonError CheckBuildingRemoval(uint32 garrPlotInstanceId) const; Player* _owner; GarrSiteLevelEntry const* _siteLevel; uint32 _followerActivationsRemainingToday; std::unordered_map<uint32 /*garrPlotInstanceId*/, Plot> _plots; std::unordered_set<uint32 /*garrBuildingId*/> _knownBuildings; + std::unordered_map<uint64 /*dbId*/, Follower> _followers; }; #endif // Garrison_h__ diff --git a/src/server/game/Garrison/GarrisonMgr.cpp b/src/server/game/Garrison/GarrisonMgr.cpp index 4e7266c0855..75f4289c385 100644 --- a/src/server/game/Garrison/GarrisonMgr.cpp +++ b/src/server/game/Garrison/GarrisonMgr.cpp @@ -16,7 +16,10 @@ */ #include "GarrisonMgr.h" +#include "Containers.h" +#include "Garrison.h" #include "ObjectDefines.h" +#include "World.h" void GarrisonMgr::Initialize() { @@ -32,6 +35,26 @@ void GarrisonMgr::Initialize() for (GarrBuildingPlotInstEntry const* buildingPlotInst : sGarrBuildingPlotInstStore) _garrisonBuildingPlotInstances[MAKE_PAIR64(buildingPlotInst->GarrBuildingID, buildingPlotInst->GarrSiteLevelPlotInstID)] = buildingPlotInst->ID; + + for (GarrBuildingEntry const* building : sGarrBuildingStore) + _garrisonBuildingsByType[building->Type].push_back(building); + + for (GarrFollowerXAbilityEntry const* followerAbility : sGarrFollowerXAbilityStore) + { + if (GarrAbilityEntry const* ability = sGarrAbilityStore.LookupEntry(followerAbility->GarrAbilityID)) + { + if (!(ability->Flags & GARRISON_ABILITY_CANNOT_ROLL) && ability->Flags & GARRISON_ABILITY_FLAG_TRAIT) + _garrisonFollowerRandomTraits.insert(ability); + + if (followerAbility->FactionIndex < 2) + { + if (ability->Flags & GARRISON_ABILITY_FLAG_TRAIT) + _garrisonFollowerAbilities[followerAbility->FactionIndex][followerAbility->GarrFollowerID].Traits.insert(ability); + else + _garrisonFollowerAbilities[followerAbility->FactionIndex][followerAbility->GarrFollowerID].Counters.insert(ability); + } + } + } } GarrSiteLevelEntry const* GarrisonMgr::GetGarrSiteLevelEntry(uint32 garrSiteId, uint32 level) const @@ -82,3 +105,167 @@ uint32 GarrisonMgr::GetGarrBuildingPlotInst(uint32 garrBuildingId, uint32 garrSi return 0; } + +GarrBuildingEntry const* GarrisonMgr::GetPreviousLevelBuilding(uint32 buildingType, uint32 currentLevel) const +{ + auto itr = _garrisonBuildingsByType.find(buildingType); + if (itr != _garrisonBuildingsByType.end()) + for (GarrBuildingEntry const* building : itr->second) + if (building->Level == currentLevel - 1) + return building; + + return nullptr; +} + +uint64 GarrisonMgr::GenerateFollowerDbId() +{ + if (_followerDbIdGenerator >= std::numeric_limits<uint64>::max()) + { + TC_LOG_ERROR("misc", "Garrison follower db id overflow! Can't continue, shutting down server. "); + World::StopNow(ERROR_EXIT_CODE); + } + + return _followerDbIdGenerator++; +} + +uint32 const AbilitiesForQuality[][2] = +{ + // Counters, Traits + { 0, 0 }, + { 1, 0 }, + { 1, 1 }, // Uncommon + { 1, 2 }, // Rare + { 2, 3 }, // Epic + { 2, 3 } // Legendary +}; + +std::list<GarrAbilityEntry const*> GarrisonMgr::RollFollowerAbilities(GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const +{ + ASSERT(faction < 2); + + bool hasForcedExclusiveTrait = false; + std::list<GarrAbilityEntry const*> result; + int32 slots[2] = { AbilitiesForQuality[quality][0], AbilitiesForQuality[quality][1] }; + + GarrAbilities const* abilities = nullptr; + auto itr = _garrisonFollowerAbilities[faction].find(follower->ID); + if (itr != _garrisonFollowerAbilities[faction].end()) + abilities = &itr->second; + + std::list<GarrAbilityEntry const*> abilityList, forcedAbilities, traitList, forcedTraits; + if (abilities) + { + for (GarrAbilityEntry const* ability : abilities->Counters) + { + if (ability->Flags & GARRISON_ABILITY_HORDE_ONLY && faction != GARRISON_FACTION_INDEX_HORDE) + continue; + else if (ability->Flags & GARRISON_ABILITY_ALLIANCE_ONLY && faction != GARRISON_FACTION_INDEX_ALLIANCE) + continue; + + if (ability->Flags & GARRISON_ABILITY_FLAG_CANNOT_REMOVE) + forcedAbilities.push_back(ability); + else + abilityList.push_back(ability); + } + + for (GarrAbilityEntry const* ability : abilities->Traits) + { + if (ability->Flags & GARRISON_ABILITY_HORDE_ONLY && faction != GARRISON_FACTION_INDEX_HORDE) + continue; + else if (ability->Flags & GARRISON_ABILITY_ALLIANCE_ONLY && faction != GARRISON_FACTION_INDEX_ALLIANCE) + continue; + + if (ability->Flags & GARRISON_ABILITY_FLAG_CANNOT_REMOVE) + forcedTraits.push_back(ability); + else + traitList.push_back(ability); + } + } + + Trinity::Containers::RandomResizeList(abilityList, std::max<int32>(0, slots[0] - forcedAbilities.size())); + Trinity::Containers::RandomResizeList(traitList, std::max<int32>(0, slots[1] - forcedTraits.size())); + + // Add counters specified in GarrFollowerXAbility.db2 before generic classspec ones on follower creation + if (initial) + { + forcedAbilities.splice(forcedAbilities.end(), abilityList); + forcedTraits.splice(forcedTraits.end(), traitList); + } + + // check if we have a trait from exclusive category + for (GarrAbilityEntry const* ability : forcedTraits) + { + if (ability->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE) + { + hasForcedExclusiveTrait = true; + break; + } + } + + if (slots[0] > forcedAbilities.size() + abilityList.size()) + { + std::list<GarrAbilityEntry const*> classSpecAbilities; // = GetDefaultClassSpecAbilities(follower, faction) + + abilityList.splice(abilityList.end(), classSpecAbilities); + abilityList.sort(); + abilityList.unique(); + + Trinity::Containers::RandomResizeList(abilityList, std::max<int32>(0, slots[0] - forcedAbilities.size())); + } + + if (slots[1] > forcedTraits.size() + traitList.size()) + { + std::list<GarrAbilityEntry const*> genericTraits; + for (GarrAbilityEntry const* ability : _garrisonFollowerRandomTraits) + { + if (ability->Flags & GARRISON_ABILITY_HORDE_ONLY && faction != GARRISON_FACTION_INDEX_HORDE) + continue; + else if (ability->Flags & GARRISON_ABILITY_ALLIANCE_ONLY && faction != GARRISON_FACTION_INDEX_ALLIANCE) + continue; + + // forced exclusive trait exists, skip other ones entirely + if (hasForcedExclusiveTrait && ability->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE) + continue; + + genericTraits.push_back(ability); + } + + genericTraits.splice(genericTraits.begin(), traitList); + // "split" the list into two parts [nonexclusive, exclusive] to make selection later easier + genericTraits.sort([](GarrAbilityEntry const* a1, GarrAbilityEntry const* a2) + { + uint32 e1 = a1->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE; + uint32 e2 = a2->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE; + if (e1 != e2) + return e1 < e2; + + return a1->ID < a2->ID; + }); + genericTraits.unique(); + + std::size_t firstExclusive = 0, total = genericTraits.size(); + for (auto itr = genericTraits.begin(); itr != genericTraits.end(); ++itr, ++firstExclusive) + if ((*itr)->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE) + break; + + while (traitList.size() < std::max<int32>(0, slots[1] - forcedTraits.size()) && !genericTraits.empty()) + { + auto itr = genericTraits.begin(); + std::advance(itr, urand(0, total-- - 1)); + if ((*itr)->Flags & GARRISON_ABILITY_FLAG_EXCLUSIVE) + total = firstExclusive; // selected exclusive trait - no other can be selected now + else + --firstExclusive; + + traitList.push_back(*itr); + genericTraits.erase(itr); + } + } + + result.splice(result.end(), forcedAbilities); + result.splice(result.end(), abilityList); + result.splice(result.end(), forcedTraits); + result.splice(result.end(), traitList); + + return result; +} diff --git a/src/server/game/Garrison/GarrisonMgr.h b/src/server/game/Garrison/GarrisonMgr.h index 1b96f9ca27e..a54606dd9b1 100644 --- a/src/server/game/Garrison/GarrisonMgr.h +++ b/src/server/game/Garrison/GarrisonMgr.h @@ -18,9 +18,14 @@ #ifndef GarrisonMgr_h__ #define GarrisonMgr_h__ +#include "DB2Stores.h" #include <unordered_set> -#include "DB2Stores.h" +struct GarrAbilities +{ + std::unordered_set<GarrAbilityEntry const*> Counters; + std::unordered_set<GarrAbilityEntry const*> Traits; +}; class GarrisonMgr { @@ -38,12 +43,20 @@ public: GameObjectsEntry const* GetPlotGameObject(uint32 mapId, uint32 garrPlotInstanceId) const; bool IsPlotMatchingBuilding(uint32 garrPlotId, uint32 garrBuildingId) const; uint32 GetGarrBuildingPlotInst(uint32 garrBuildingId, uint32 garrSiteLevelPlotInstId) const; + GarrBuildingEntry const* GetPreviousLevelBuilding(uint32 buildingType, uint32 currentLevel) const; + uint64 GenerateFollowerDbId(); + std::list<GarrAbilityEntry const*> RollFollowerAbilities(GarrFollowerEntry const* follower, uint32 quality, uint32 faction, bool initial) const; private: std::unordered_map<uint32 /*garrSiteId*/, std::vector<GarrSiteLevelPlotInstEntry const*>> _garrisonPlotInstBySiteLevel; std::unordered_map<uint32 /*mapId*/, std::unordered_map<uint32 /*garrPlotId*/, GameObjectsEntry const*>> _garrisonPlots; std::unordered_map<uint32 /*garrPlotId*/, std::unordered_set<uint32/*garrBuildingId*/>> _garrisonBuildingsByPlot; std::unordered_map<uint64 /*garrBuildingId | garrSiteLevelPlotInstId << 32*/, uint32 /*garrBuildingPlotInstId*/> _garrisonBuildingPlotInstances; + std::unordered_map<uint32 /*buildingType*/, std::vector<GarrBuildingEntry const*>> _garrisonBuildingsByType; + std::unordered_map<uint32 /*garrFollowerId*/, GarrAbilities> _garrisonFollowerAbilities[2]; + std::unordered_set<GarrAbilityEntry const*> _garrisonFollowerRandomTraits; + + uint64 _followerDbIdGenerator; }; #define sGarrisonMgr GarrisonMgr::Instance() diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index ac87f58af5c..10288cff927 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2242,6 +2242,25 @@ bool ObjectMgr::GetPlayerNameByGUID(ObjectGuid const& guid, std::string& name) return false; } +bool ObjectMgr::GetPlayerNameAndClassByGUID(ObjectGuid const& guid, std::string& name, uint8& _class) +{ + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) + { + name = player->GetName(); + _class = player->getClass(); + return true; + } + + if (CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(guid)) + { + name = characterInfo->Name; + _class = characterInfo->Class; + return true; + } + + return false; +} + uint32 ObjectMgr::GetPlayerTeamByGUID(ObjectGuid const& guid) { if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index dc26e30773c..4277ab74048 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -780,6 +780,7 @@ class ObjectMgr * @return true if player was found, false otherwise */ static bool GetPlayerNameByGUID(ObjectGuid const& guid, std::string& name); + static bool GetPlayerNameAndClassByGUID(ObjectGuid const& guid, std::string& name, uint8& _class); static uint32 GetPlayerTeamByGUID(ObjectGuid const& guid); static uint32 GetPlayerAccountIdByGUID(ObjectGuid const& guid); static uint32 GetPlayerAccountIdByPlayerName(std::string const& name); @@ -1364,7 +1365,7 @@ class ObjectMgr { auto itr = _guidGenerators.find(high); if (itr == _guidGenerators.end()) - itr = _guidGenerators.insert(std::make_pair(high, std::unique_ptr<ObjectGuidGenerator<high>>(new ObjectGuidGenerator<high>()))).first; + itr = _guidGenerators.insert(std::make_pair(high, Trinity::make_unique<ObjectGuidGenerator<high>>())).first; return *itr->second; } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index f359e1eff57..fadf7e1970e 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -21,6 +21,7 @@ #include "WorldPacket.h" #include "WorldSession.h" #include "Player.h" +#include "Pet.h" #include "World.h" #include "ObjectMgr.h" #include "GroupMgr.h" @@ -35,6 +36,7 @@ #include "Util.h" #include "LFGMgr.h" #include "UpdateFieldFlags.h" +#include "PartyPackets.h" Roll::Roll(ObjectGuid _guid, LootItem const& li) : itemGUID(_guid), itemid(li.itemid), itemRandomPropId(li.randomPropertyId), itemRandomSuffix(li.randomSuffix), itemCount(li.count), @@ -55,11 +57,15 @@ Loot* Roll::getLoot() Group::Group() : m_leaderGuid(), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL), m_dungeonDifficulty(DIFFICULTY_NORMAL), m_raidDifficulty(DIFFICULTY_NORMAL_RAID), m_legacyRaidDifficulty(DIFFICULTY_10_N), -m_bgGroup(NULL), m_bfGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(), -m_masterLooterGuid(), m_subGroupsCounts(NULL), m_guid(), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0) +m_bgGroup(nullptr), m_bfGroup(nullptr), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(), +m_masterLooterGuid(), m_subGroupsCounts(nullptr), m_guid(), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0), +m_readyCheckStarted(false), m_readyCheckTimer(0), m_activeMarkers(0) { - for (uint8 i = 0; i < TARGETICONCOUNT; ++i) + for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i) m_targetIcons[i].Clear(); + + for (uint8 i = 0; i < RAID_MARKERS_COUNT; ++i) + m_markers[i] = nullptr; } Group::~Group() @@ -176,7 +182,7 @@ void Group::LoadGroupFromDB(Field* fields) m_looterGuid = ObjectGuid::Create<HighGuid::Player>(fields[2].GetUInt64()); m_lootThreshold = ItemQualities(fields[3].GetUInt8()); - for (uint8 i = 0; i < TARGETICONCOUNT; ++i) + for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i) m_targetIcons[i].SetRawValue(fields[4 + i].GetBinary()); m_groupType = GroupType(fields[12].GetUInt8()); @@ -199,7 +205,7 @@ void Group::LoadMemberFromDB(ObjectGuid::LowType guidLow, uint8 memberFlags, uin member.guid = ObjectGuid::Create<HighGuid::Player>(guidLow); // skip non-existed member - if (!ObjectMgr::GetPlayerNameByGUID(member.guid, member.name)) + if (!ObjectMgr::GetPlayerNameAndClassByGUID(member.guid, member.name, member._class)) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER); stmt->setUInt64(0, guidLow); @@ -207,9 +213,10 @@ void Group::LoadMemberFromDB(ObjectGuid::LowType guidLow, uint8 memberFlags, uin return; } - member.group = subgroup; - member.flags = memberFlags; - member.roles = roles; + member.group = subgroup; + member.flags = memberFlags; + member.roles = roles; + member.readyChecked = false; m_memberSlots.push_back(member); @@ -368,7 +375,7 @@ bool Group::AddMember(Player* player) bool groupFound = false; for (; subGroup < MAX_RAID_SUBGROUPS; ++subGroup) { - if (m_subGroupsCounts[subGroup] < MAXGROUPSIZE) + if (m_subGroupsCounts[subGroup] < MAX_GROUP_SIZE) { groupFound = true; break; @@ -380,11 +387,13 @@ bool Group::AddMember(Player* player) } MemberSlot member; - member.guid = player->GetGUID(); - member.name = player->GetName(); - member.group = subGroup; - member.flags = 0; - member.roles = 0; + member.guid = player->GetGUID(); + member.name = player->GetName(); + member._class = player->getClass(); + member.group = subGroup; + member.flags = 0; + member.roles = 0; + member.readyChecked = false; m_memberSlots.push_back(member); SubGroupCounterIncrease(subGroup); @@ -407,7 +416,7 @@ bool Group::AddMember(Player* player) if (!isRaidGroup()) // reset targetIcons for non-raid-groups { - for (uint8 i = 0; i < TARGETICONCOUNT; ++i) + for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i) m_targetIcons[i].Clear(); } @@ -455,7 +464,11 @@ bool Group::AddMember(Player* player) } } } + player->SetGroupUpdateFlag(GROUP_UPDATE_FULL); + if (Pet* pet = player->GetPet()) + pet->SetGroupUpdateFlag(GROUP_UPDATE_PET_FULL); + UpdatePlayerOutOfRange(player); // quest related GO state dependent from raid membership @@ -552,12 +565,6 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R player->GetSession()->SendPacket(&data); } - // Do we really need to send this opcode? - data.Initialize(SMSG_PARTY_UPDATE, 1+1+1+1+8+4+4+8); - data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0); - data << m_guid << uint32(m_counter) << uint32(0) << uint64(0); - player->GetSession()->SendPacket(&data); - _homebindIfInstance(player); } @@ -644,7 +651,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R } } -void Group::ChangeLeader(ObjectGuid newLeaderGuid) +void Group::ChangeLeader(ObjectGuid newLeaderGuid, int8 partyIndex) { member_witerator slot = _getMemberWSlot(newLeaderGuid); @@ -707,9 +714,10 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid) m_leaderName = newLeader->GetName(); ToggleGroupMemberFlag(slot, MEMBER_FLAG_ASSISTANT, false); - WorldPacket data(SMSG_GROUP_NEW_LEADER, m_leaderName.size()+1); - data << slot->name; - BroadcastPacket(&data, true); + WorldPackets::Party::GroupNewLeader groupNewLeader; + groupNewLeader.Name = m_leaderName; + groupNewLeader.PartyIndex = partyIndex; + BroadcastPacket(groupNewLeader.Write(), true); } void Group::Disband(bool hideDestroy /* = false */) @@ -1491,45 +1499,38 @@ void Group::CountTheRoll(Rolls::iterator rollI) delete roll; } -void Group::SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid) +void Group::SetTargetIcon(uint8 symbol, ObjectGuid target, ObjectGuid changedBy, uint8 partyIndex) { - if (id >= TARGETICONCOUNT) + if (symbol >= TARGET_ICONS_COUNT) return; // clean other icons - if (!targetGuid.IsEmpty()) - for (int i = 0; i < TARGETICONCOUNT; ++i) - if (m_targetIcons[i] == targetGuid) - SetTargetIcon(i, ObjectGuid::Empty, ObjectGuid::Empty); + if (!target.IsEmpty()) + for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i) + if (m_targetIcons[i] == target) + SetTargetIcon(i, ObjectGuid::Empty, changedBy, partyIndex); - m_targetIcons[id] = targetGuid; + m_targetIcons[symbol] = target; - WorldPacket data(SMSG_SEND_RAID_TARGET_UPDATE_SINGLE, (1+8+1+8)); - data << uint8(0); // set targets - data << whoGuid; - data << uint8(id); - data << targetGuid; - BroadcastPacket(&data, true); + WorldPackets::Party::SendRaidTargetUpdateSingle updateSingle; + updateSingle.PartyIndex = partyIndex; + updateSingle.Target = target; + updateSingle.ChangedBy = changedBy; + updateSingle.Symbol = symbol; + BroadcastPacket(updateSingle.Write(), true); } -void Group::SendTargetIconList(WorldSession* session) +void Group::SendTargetIconList(WorldSession* session, int8 partyIndex) { if (!session) return; - WorldPacket data(SMSG_SEND_RAID_TARGET_UPDATE_ALL, (1+TARGETICONCOUNT*9)); - data << uint8(1); // list targets + WorldPackets::Party::SendRaidTargetUpdateAll updateAll; + updateAll.PartyIndex = partyIndex; + for (uint8 i = 0; i < TARGET_ICONS_COUNT; i++) + updateAll.TargetIcons.insert(std::pair<uint8, ObjectGuid>(i, m_targetIcons[i])); - for (uint8 i = 0; i < TARGETICONCOUNT; ++i) - { - if (m_targetIcons[i].IsEmpty()) - continue; - - data << uint8(i); - data << m_targetIcons[i]; - } - - session->SendPacket(&data); + session->SendPacket(updateAll.Write()); } void Group::SendUpdate() @@ -1556,56 +1557,79 @@ void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot) slot = &(*witr); } - WorldPacket data(SMSG_PARTY_UPDATE, (1+1+1+1+1+4+8+4+4+(GetMembersCount()-1)*(13+8+1+1+1+1)+8+1+8+1+1+1+1)); - data << uint8(m_groupType); // group type (flags in 3.3) - data << uint8(slot->group); - data << uint8(slot->flags); - data << uint8(slot->roles); - if (isLFGGroup()) - { - data << uint8(sLFGMgr->GetState(m_guid) == lfg::LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done - data << uint32(sLFGMgr->GetDungeon(m_guid)); - data << uint8(0); // 4.x new - } + WorldPackets::Party::PartyUpdate partyUpdate; - data << m_guid; - data << uint32(m_counter++); // 3.3, value increases every time this packet gets sent - data << uint32(GetMembersCount()-1); - for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) + partyUpdate.PartyType = m_groupType; + partyUpdate.PartyIndex = 0; + partyUpdate.PartyFlags = uint8(IsCreated()); + + partyUpdate.PartyGUID = m_guid; + partyUpdate.LeaderGUID = m_leaderGuid; + + partyUpdate.SequenceNum = m_counter++; // 3.3, value increases every time this packet gets sent + + partyUpdate.MyIndex = -1; + uint8 index = 0; + for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr, ++index) { if (slot->guid == citr->guid) - continue; + partyUpdate.MyIndex = index; Player* member = ObjectAccessor::FindConnectedPlayer(citr->guid); - uint8 onlineState = (member && !member->GetSession()->PlayerLogout()) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; - onlineState = onlineState | ((isBGGroup() || isBFGroup()) ? MEMBER_STATUS_PVP : 0); + WorldPackets::Party::GroupPlayerInfos playerInfos; - data << citr->name; - data << citr->guid; // guid - data << uint8(onlineState); // online-state - data << uint8(citr->group); // groupid - data << uint8(citr->flags); // See enum GroupMemberFlags - data << uint8(citr->roles); // Lfg Roles + playerInfos.GUID = citr->guid; + playerInfos.Name = citr->name; + playerInfos.Class = citr->_class; + + playerInfos.Status = MEMBER_STATUS_OFFLINE; + if (member && member->GetSession() && !member->GetSession()->PlayerLogout()) + playerInfos.Status = MEMBER_STATUS_ONLINE | (isBGGroup() || isBFGroup() ? MEMBER_STATUS_PVP : 0); + + playerInfos.Subgroup = citr->group; // groupid + playerInfos.Flags = citr->flags; // See enum GroupMemberFlags + playerInfos.RolesAssigned = citr->roles; // Lfg Roles + + partyUpdate.PlayerList.push_back(playerInfos); } - data << m_leaderGuid; // leader guid + if (GetMembersCount() > 1) + { + // LootSettings + partyUpdate.LootSettings = boost::in_place(); + partyUpdate.LootSettings->Method = m_lootMethod; + partyUpdate.LootSettings->Threshold = m_lootThreshold; + partyUpdate.LootSettings->LootMaster = m_lootMethod == MASTER_LOOT ? m_masterLooterGuid : ObjectGuid::Empty; + + // Difficulty Settings + partyUpdate.DifficultySettings = boost::in_place(); + partyUpdate.DifficultySettings->DungeonDifficultyID = m_dungeonDifficulty; + partyUpdate.DifficultySettings->RaidDifficultyID = m_raidDifficulty; + partyUpdate.DifficultySettings->LegacyRaidDifficultyID = m_legacyRaidDifficulty; + } - if (GetMembersCount() - 1) + // LfgInfos + if (isLFGGroup()) { - data << uint8(m_lootMethod); // loot method + partyUpdate.LfgInfos = boost::in_place(); - if (m_lootMethod == MASTER_LOOT) - data << m_masterLooterGuid; // master looter guid - else - data << uint64(0); + partyUpdate.LfgInfos->Slot = sLFGMgr->GetDungeon(m_guid); + partyUpdate.LfgInfos->BootCount = 0; // new 6.x + partyUpdate.LfgInfos->Aborted = false; // new 6.x + + partyUpdate.LfgInfos->MyFlags = 0; // new 6.x + partyUpdate.LfgInfos->MyRandomSlot = 0; // new 6.x + + partyUpdate.LfgInfos->MyPartialClear = sLFGMgr->GetState(m_guid) == lfg::LFG_STATE_FINISHED_DUNGEON ? 2 : 0; // FIXME - Dungeon save status? 2 = done + partyUpdate.LfgInfos->MyGearDiff = 0.f; // new 6.x + partyUpdate.LfgInfos->MyFirstReward = false; // new 6.x - data << uint8(m_lootThreshold); // loot threshold - data << uint8(m_dungeonDifficulty); // Dungeon Difficulty - data << uint8(m_raidDifficulty); // Raid Difficulty + partyUpdate.LfgInfos->MyStrangerCount = 0; // new 6.x + partyUpdate.LfgInfos->MyKickVoteCount = 0; // new 6.x } - player->GetSession()->SendPacket(&data); + player->GetSession()->SendPacket(partyUpdate.Write()); } void Group::UpdatePlayerOutOfRange(Player* player) @@ -1613,15 +1637,15 @@ void Group::UpdatePlayerOutOfRange(Player* player) if (!player || !player->IsInWorld()) return; - WorldPacket data; - player->GetSession()->BuildPartyMemberStatsChangedPacket(player, &data); + WorldPackets::Party::PartyMemberStats packet; + packet.Initialize(player); Player* member; for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) { member = itr->GetSource(); if (member && member != player && (!member->IsInMap(player) || !member->IsWithinDist(player, member->GetSightRange(), false))) - member->GetSession()->SendPacket(&data); + member->GetSession()->SendPacket(packet.Write()); } } @@ -1653,32 +1677,6 @@ void Group::BroadcastPacket(WorldPacket const* packet, bool ignorePlayersInBGRai } } -void Group::BroadcastReadyCheck(WorldPacket const* packet) -{ - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) - { - Player* player = itr->GetSource(); - if (player && player->GetSession()) - if (IsLeader(player->GetGUID()) || IsAssistant(player->GetGUID())) - player->GetSession()->SendPacket(packet); - } -} - -void Group::OfflineReadyCheck() -{ - for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) - { - Player* player = ObjectAccessor::FindConnectedPlayer(citr->guid); - if (!player || !player->GetSession()) - { - WorldPacket data(SMSG_READY_CHECK_RESPONSE, 9); - data << citr->guid; - data << uint8(0); - BroadcastReadyCheck(&data); - } - } -} - bool Group::_setMembersGroup(ObjectGuid guid, uint8 group) { member_witerator slot = _getMemberWSlot(guid); @@ -1725,8 +1723,8 @@ void Group::ChangeMembersGroup(ObjectGuid guid, uint8 group) if (slot == m_memberSlots.end()) return; + uint8 prevSubGroup = slot->group; // Abort if the player is already in the target sub group - uint8 prevSubGroup = GetMemberGroup(guid); if (prevSubGroup == group) return; @@ -1758,7 +1756,6 @@ void Group::ChangeMembersGroup(ObjectGuid guid, uint8 group) else { // If player is in BG raid, it is possible that he is also in normal raid - and that normal raid is stored in m_originalGroup reference - prevSubGroup = player->GetOriginalSubGroup(); player->GetOriginalGroupRef().setSubGroup(group); } } @@ -1767,6 +1764,51 @@ void Group::ChangeMembersGroup(ObjectGuid guid, uint8 group) SendUpdate(); } +void Group::SwapMembersGroups(ObjectGuid firstGuid, ObjectGuid secondGuid) +{ + if (!isRaidGroup()) + return; + + member_witerator slots[2]; + slots[0] = _getMemberWSlot(firstGuid); + slots[1] = _getMemberWSlot(secondGuid); + if (slots[0] == m_memberSlots.end() || slots[1] == m_memberSlots.end()) + return; + + if (slots[0]->group == slots[1]->group) + return; + + uint8 tmp = slots[0]->group; + slots[0]->group = slots[1]->group; + slots[1]->group = tmp; + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + for (uint8 i = 0; i < 2; i++) + { + // Preserve new sub group in database for non-raid groups + if (!isBGGroup() && !isBFGroup()) + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_MEMBER_SUBGROUP); + + stmt->setUInt8(0, slots[i]->group); + stmt->setUInt64(1, slots[i]->guid.GetCounter()); + + trans->Append(stmt); + } + + if (Player* player = ObjectAccessor::FindConnectedPlayer(slots[i]->guid)) + { + if (player->GetGroup() == this) + player->GetGroupRef().setSubGroup(slots[i]->group); + else + player->GetOriginalGroupRef().setSubGroup(slots[i]->group); + } + } + CharacterDatabase.CommitTransaction(trans); + + SendUpdate(); +} + // Retrieve the next Round-Roubin player for the group // // No update done if loot method is FFA. @@ -2262,9 +2304,167 @@ void Group::SetLfgRoles(ObjectGuid guid, uint8 roles) SendUpdate(); } +uint8 Group::GetLfgRoles(ObjectGuid guid) +{ + member_witerator slot = _getMemberWSlot(guid); + if (slot == m_memberSlots.end()) + return 0; + + return slot->roles; +} + +void Group::Update(uint32 diff) +{ + UpdateReadyCheck(diff); +} + +void Group::UpdateReadyCheck(uint32 diff) +{ + if (!m_readyCheckStarted) + return; + + m_readyCheckTimer -= diff; + if (m_readyCheckTimer <= 0) + EndReadyCheck(); +} + +void Group::StartReadyCheck(ObjectGuid starterGuid, int8 partyIndex, uint32 duration) +{ + if (m_readyCheckStarted) + return; + + member_witerator slot = _getMemberWSlot(starterGuid); + if (slot == m_memberSlots.end()) + return ; + + m_readyCheckStarted = true; + m_readyCheckTimer = duration; + + SetOfflineMembersReadyChecked(); + + SetMemberReadyChecked(&(*slot)); + + WorldPackets::Party::ReadyCheckStarted readyCheckStarted; + readyCheckStarted.PartyGUID = m_guid; + readyCheckStarted.PartyIndex = partyIndex; + readyCheckStarted.InitiatorGUID = starterGuid; + readyCheckStarted.Duration = duration; + BroadcastPacket(readyCheckStarted.Write(), false); +} + +void Group::EndReadyCheck(void) +{ + if (!m_readyCheckStarted) + return; + + m_readyCheckStarted = false; + m_readyCheckTimer = 0; + + ResetMemberReadyChecked(); + + WorldPackets::Party::ReadyCheckCompleted readyCheckCompleted; + readyCheckCompleted.PartyIndex = 0; + readyCheckCompleted.PartyGUID = m_guid; + BroadcastPacket(readyCheckCompleted.Write(), false); +} + +bool Group::IsReadyCheckCompleted(void) const +{ + for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) + if (!citr->readyChecked) + return false; + return true; +} + +void Group::SetMemberReadyCheck(ObjectGuid guid, bool ready) +{ + if (!m_readyCheckStarted) + return; + + member_witerator slot = _getMemberWSlot(guid); + if (slot != m_memberSlots.end()) + SetMemberReadyCheck(&(*slot), ready); +} + +void Group::SetMemberReadyCheck(MemberSlot* slot, bool ready) +{ + WorldPackets::Party::ReadyCheckResponse response; + response.PartyGUID = m_guid; + response.Player = slot->guid; + response.IsReady = ready; + BroadcastPacket(response.Write(), false); + + SetMemberReadyChecked(slot); +} + +void Group::SetOfflineMembersReadyChecked(void) +{ + for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) + { + Player* player = ObjectAccessor::FindConnectedPlayer(itr->guid); + if (!player || !player->GetSession()) + SetMemberReadyCheck(&(*itr), false); + } +} + +void Group::SetMemberReadyChecked(MemberSlot* slot) +{ + slot->readyChecked = true; + if (IsReadyCheckCompleted()) + EndReadyCheck(); +} + +void Group::ResetMemberReadyChecked(void) +{ + for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) + itr->readyChecked = false; +} + +void Group::AddRaidMarker(uint8 markerId, uint32 mapId, float positionX, float positionY, float positionZ, ObjectGuid transportGuid) +{ + if (markerId >= RAID_MARKERS_COUNT || m_markers[markerId]) + return; + + m_activeMarkers |= (1 << markerId); + m_markers[markerId] = Trinity::make_unique<RaidMarker>(mapId, positionX, positionY, positionZ, transportGuid); + SendRaidMarkersChanged(); +} + +void Group::DeleteRaidMarker(uint8 markerId) +{ + if (markerId > RAID_MARKERS_COUNT) + return; + + for (uint8 i = 0; i < RAID_MARKERS_COUNT; i++) + if (m_markers[i] && (markerId == i || markerId == RAID_MARKERS_COUNT)) + { + m_markers[i] = nullptr; + m_activeMarkers &= ~(1 << i); + } + + SendRaidMarkersChanged(); +} + +void Group::SendRaidMarkersChanged(WorldSession* session, int8 partyIndex) +{ + WorldPackets::Party::RaidMarkersChanged packet; + + packet.PartyIndex = partyIndex; + packet.ActiveMarkers = m_activeMarkers; + + for (uint8 i = 0; i < RAID_MARKERS_COUNT; i++) + if (m_markers[i]) + packet.RaidMarkers.push_back(m_markers[i].get()); + + if (session) + session->SendPacket(packet.Write()); + else + BroadcastPacket(packet.Write(), false); +} + bool Group::IsFull() const { - return isRaidGroup() ? (m_memberSlots.size() >= MAXRAIDSIZE) : (m_memberSlots.size() >= MAXGROUPSIZE); + return isRaidGroup() ? (m_memberSlots.size() >= MAX_RAID_SIZE) : (m_memberSlots.size() >= MAX_GROUP_SIZE); } bool Group::isLFGGroup() const @@ -2371,10 +2571,9 @@ bool Group::SameSubGroup(ObjectGuid guid1, MemberSlot const* slot2) const bool Group::HasFreeSlotSubGroup(uint8 subgroup) const { - return (m_subGroupsCounts && m_subGroupsCounts[subgroup] < MAXGROUPSIZE); + return (m_subGroupsCounts && m_subGroupsCounts[subgroup] < MAX_GROUP_SIZE); } - uint8 Group::GetMemberGroup(ObjectGuid guid) const { member_citerator mslot = _getMemberCSlot(guid); @@ -2522,3 +2721,15 @@ void Group::ToggleGroupMemberFlag(member_witerator slot, uint8 flag, bool apply) slot->flags &= ~flag; } +void Group::SetEveryoneIsAssistant(bool apply) +{ + if (apply) + m_groupType = GroupType(m_groupType | GROUPTYPE_EVERYONE_ASSISTANT); + else + m_groupType = GroupType(m_groupType & ~GROUPTYPE_EVERYONE_ASSISTANT); + + for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) + ToggleGroupMemberFlag(itr, MEMBER_FLAG_ASSISTANT, apply); + + SendUpdate(); +} diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 4154f31a410..e14ca6c976b 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -38,10 +38,14 @@ class WorldSession; struct MapEntry; -#define MAXGROUPSIZE 5 -#define MAXRAIDSIZE 40 -#define MAX_RAID_SUBGROUPS MAXRAIDSIZE/MAXGROUPSIZE -#define TARGETICONCOUNT 8 +#define MAX_GROUP_SIZE 5 +#define MAX_RAID_SIZE 40 +#define MAX_RAID_SUBGROUPS MAX_RAID_SIZE / MAX_GROUP_SIZE + +#define TARGET_ICONS_COUNT 8 +#define RAID_MARKERS_COUNT 8 + +#define READYCHECK_DURATION 35000 enum RollVote { @@ -81,50 +85,59 @@ enum GroupMemberAssignment enum GroupType { - GROUPTYPE_NORMAL = 0x00, - GROUPTYPE_BG = 0x01, - GROUPTYPE_RAID = 0x02, - GROUPTYPE_BGRAID = GROUPTYPE_BG | GROUPTYPE_RAID, // mask - GROUPTYPE_LFG_RESTRICTED = 0x04, // Script_HasLFGRestrictions() - GROUPTYPE_LFG = 0x08, + GROUPTYPE_NORMAL = 0x00, + GROUPTYPE_BG = 0x01, + GROUPTYPE_RAID = 0x02, + GROUPTYPE_BGRAID = GROUPTYPE_BG | GROUPTYPE_RAID, // mask + GROUPTYPE_LFG_RESTRICTED = 0x04, // Script_HasLFGRestrictions() + GROUPTYPE_LFG = 0x08, + GROUPTYPE_EVERYONE_ASSISTANT = 0x40, // Script_IsEveryoneAssistant() (4.x) // 0x10, leave/change group?, I saw this flag when leaving group and after leaving BG while in group // GROUPTYPE_ONE_PERSON_PARTY = 0x20, 4.x Script_IsOnePersonParty() - // GROUPTYPE_EVERYONE_ASSISTANT = 0x40 4.x Script_IsEveryoneAssistant() }; enum GroupUpdateFlags { GROUP_UPDATE_FLAG_NONE = 0x00000000, // nothing - GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint16 (GroupMemberStatusFlag) - GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint32 (HP) - GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint32 (HP) - GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000008, // uint8 (PowerType) - GROUP_UPDATE_FLAG_CUR_POWER = 0x00000010, // int16 (power value) - GROUP_UPDATE_FLAG_MAX_POWER = 0x00000020, // int16 (power value) - GROUP_UPDATE_FLAG_LEVEL = 0x00000040, // uint16 (level value) - GROUP_UPDATE_FLAG_ZONE = 0x00000080, // uint16 (zone id) - GROUP_UPDATE_FLAG_UNK100 = 0x00000100, // int16 (unk) - GROUP_UPDATE_FLAG_POSITION = 0x00000200, // uint16 (x), uint16 (y), uint16 (z) - GROUP_UPDATE_FLAG_AURAS = 0x00000400, // uint8 (unk), uint64 (mask), uint32 (count), for each bit set: uint32 (spell id) + uint16 (AuraFlags) (if has flags Scalable -> 3x int32 (bps)) - GROUP_UPDATE_FLAG_PET_GUID = 0x00000800, // uint64 (pet guid) - GROUP_UPDATE_FLAG_PET_NAME = 0x00001000, // cstring (name, NULL terminated string) - GROUP_UPDATE_FLAG_PET_MODEL_ID = 0x00002000, // uint16 (model id) - GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00004000, // uint32 (HP) - GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00008000, // uint32 (HP) - GROUP_UPDATE_FLAG_PET_POWER_TYPE = 0x00010000, // uint8 (PowerType) - GROUP_UPDATE_FLAG_PET_CUR_POWER = 0x00020000, // uint16 (power value) - GROUP_UPDATE_FLAG_PET_MAX_POWER = 0x00040000, // uint16 (power value) - GROUP_UPDATE_FLAG_PET_AURAS = 0x00080000, // [see GROUP_UPDATE_FLAG_AURAS] - GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00100000, // int32 (vehicle seat id) - GROUP_UPDATE_FLAG_PHASE = 0x00200000, // int32 (unk), uint32 (phase count), for (count) uint16(phaseId) - - GROUP_UPDATE_PET = GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | - GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | - GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER | GROUP_UPDATE_FLAG_PET_AURAS, // all pet flags - GROUP_UPDATE_FULL = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | - GROUP_UPDATE_FLAG_POWER_TYPE | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | - GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | - GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_PET | GROUP_UPDATE_FLAG_PHASE // all known flags, except UNK100 and VEHICLE_SEAT + GROUP_UPDATE_FLAG_UNK704 = 0x00000001, // uint8[2] (unk) + GROUP_UPDATE_FLAG_STATUS = 0x00000002, // uint16 (GroupMemberStatusFlag) + GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000004, // uint8 (PowerType) + GROUP_UPDATE_FLAG_UNK322 = 0x00000008, // uint16 (unk) + GROUP_UPDATE_FLAG_CUR_HP = 0x00000010, // uint32 (HP) + GROUP_UPDATE_FLAG_MAX_HP = 0x00000020, // uint32 (max HP) + GROUP_UPDATE_FLAG_CUR_POWER = 0x00000040, // int16 (power value) + GROUP_UPDATE_FLAG_MAX_POWER = 0x00000080, // int16 (max power value) + GROUP_UPDATE_FLAG_LEVEL = 0x00000100, // uint16 (level value) + GROUP_UPDATE_FLAG_UNK200000 = 0x00000200, // int16 (unk) + GROUP_UPDATE_FLAG_ZONE = 0x00000400, // uint16 (zone id) + GROUP_UPDATE_FLAG_UNK2000000 = 0x00000800, // int16 (unk) + GROUP_UPDATE_FLAG_UNK4000000 = 0x00001000, // int32 (unk) + GROUP_UPDATE_FLAG_POSITION = 0x00002000, // uint16 (x), uint16 (y), uint16 (z) + GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00104000, // int32 (vehicle seat id) + GROUP_UPDATE_FLAG_AURAS = 0x00008000, // uint8 (unk), uint64 (mask), uint32 (count), for each bit set: uint32 (spell id) + uint16 (AuraFlags) (if has flags Scalable -> 3x int32 (bps)) + GROUP_UPDATE_FLAG_PET = 0x00010000, // complex (pet) + GROUP_UPDATE_FLAG_PHASE = 0x00020000, // int32 (unk), uint32 (phase count), for (count) uint16(phaseId) + + GROUP_UPDATE_FULL = GROUP_UPDATE_FLAG_UNK704 | GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_POWER_TYPE | + GROUP_UPDATE_FLAG_UNK322 | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | + GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | + GROUP_UPDATE_FLAG_UNK200000 | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_UNK2000000 | + GROUP_UPDATE_FLAG_UNK4000000 | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_VEHICLE_SEAT | + GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET | GROUP_UPDATE_FLAG_PHASE // all known flags +}; + +enum GroupUpdatePetFlags +{ + GROUP_UPDATE_FLAG_PET_NONE = 0x00000000, // nothing + GROUP_UPDATE_FLAG_PET_GUID = 0x00000001, // ObjectGuid (pet guid) + GROUP_UPDATE_FLAG_PET_NAME = 0x00000002, // cstring (name, NULL terminated string) + GROUP_UPDATE_FLAG_PET_MODEL_ID = 0x00000004, // uint16 (model id) + GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00000008, // uint32 (HP) + GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00000010, // uint32 (max HP) + GROUP_UPDATE_FLAG_PET_AURAS = 0x00000020, // [see GROUP_UPDATE_FLAG_AURAS] + + GROUP_UPDATE_PET_FULL = GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | + GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_AURAS // all pet flags }; class Roll : public LootValidatorRef @@ -160,6 +173,18 @@ struct InstanceGroupBind InstanceGroupBind() : save(NULL), perm(false) { } }; +struct RaidMarker +{ + WorldLocation Location; + ObjectGuid TransportGUID; + + RaidMarker(uint32 mapId, float positionX, float positionY, float positionZ, ObjectGuid transportGuid = ObjectGuid::Empty) + { + Location.WorldRelocate(mapId, positionX, positionY, positionZ); + TransportGUID = transportGuid; + } +}; + /** request member stats checken **/ /// @todo uninvite people that not accepted invite class Group @@ -169,9 +194,11 @@ class Group { ObjectGuid guid; std::string name; + uint8 _class; uint8 group; uint8 flags; uint8 roles; + bool readyChecked; }; typedef std::list<MemberSlot> MemberSlotList; typedef MemberSlotList::const_iterator member_citerator; @@ -197,7 +224,7 @@ class Group bool AddLeaderInvite(Player* player); bool AddMember(Player* player); bool RemoveMember(ObjectGuid guid, const RemoveMethod &method = GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker = ObjectGuid::Empty, const char* reason = NULL); - void ChangeLeader(ObjectGuid guid); + void ChangeLeader(ObjectGuid guid, int8 partyIndex = 0); void SetLootMethod(LootMethod method); void SetLooterGuid(ObjectGuid guid); void SetMasterLooterGuid(ObjectGuid guid); @@ -205,6 +232,31 @@ class Group void SetLootThreshold(ItemQualities threshold); void Disband(bool hideDestroy = false); void SetLfgRoles(ObjectGuid guid, uint8 roles); + uint8 GetLfgRoles(ObjectGuid guid); + void SetEveryoneIsAssistant(bool apply); + + // Update + void Update(uint32 diff); + void UpdateReadyCheck(uint32 diff); + + // Ready check + void StartReadyCheck(ObjectGuid starterGuid, int8 partyIndex, uint32 duration = READYCHECK_DURATION); + void EndReadyCheck(); + + bool IsReadyCheckStarted(void) const { return m_readyCheckStarted; } + bool IsReadyCheckCompleted(void) const; + + void SetOfflineMembersReadyChecked(void); + void SetMemberReadyCheck(ObjectGuid guid, bool ready); + void SetMemberReadyCheck(MemberSlot* slot, bool ready); + + void SetMemberReadyChecked(MemberSlot* slot); + void ResetMemberReadyChecked(void); + + // Raid Markers + void AddRaidMarker(uint8 markerId, uint32 mapId, float positionX, float positionY, float positionZ, ObjectGuid transportGuid = ObjectGuid::Empty); + void DeleteRaidMarker(uint8 markerId); + void SendRaidMarkersChanged(WorldSession* session = nullptr, int8 partyIndex = 0); // properties accessories bool IsFull() const; @@ -254,7 +306,8 @@ class Group GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot, ObjectGuid& errorGuid); void ChangeMembersGroup(ObjectGuid guid, uint8 group); - void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid); + void SwapMembersGroups(ObjectGuid firstGuid, ObjectGuid secondGuid); + void SetTargetIcon(uint8 symbol, ObjectGuid target, ObjectGuid changedBy, uint8 partyIndex); void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag); void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag); @@ -269,7 +322,7 @@ class Group // -no description- //void SendInit(WorldSession* session); - void SendTargetIconList(WorldSession* session); + void SendTargetIconList(WorldSession* session, int8 partyIndex = 0); void SendUpdate(); void SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot = NULL); void UpdatePlayerOutOfRange(Player* player); @@ -290,8 +343,6 @@ class Group void BroadcastPacket(WorldPacket const* packet, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignoredPlayer = ObjectGuid::Empty); void BroadcastAddonMessagePacket(WorldPacket const* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignore = ObjectGuid::Empty); - void BroadcastReadyCheck(WorldPacket const* packet); - void OfflineReadyCheck(); /*********************************************************/ /*** LOOT SYSTEM ***/ @@ -351,7 +402,7 @@ class Group Difficulty m_legacyRaidDifficulty; Battleground* m_bgGroup; Battlefield* m_bfGroup; - ObjectGuid m_targetIcons[TARGETICONCOUNT]; + ObjectGuid m_targetIcons[TARGET_ICONS_COUNT]; LootMethod m_lootMethod; ItemQualities m_lootThreshold; ObjectGuid m_looterGuid; @@ -363,5 +414,13 @@ class Group uint32 m_counter; // used only in SMSG_GROUP_LIST uint32 m_maxEnchantingLevel; uint32 m_dbStoreId; // Represents the ID used in database (Can be reused by other groups if group was disbanded) + + // Ready Check + bool m_readyCheckStarted; + int32 m_readyCheckTimer; + + // Raid markers + std::array<std::unique_ptr<RaidMarker>, RAID_MARKERS_COUNT> m_markers; + uint32 m_activeMarkers; }; #endif diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp index f0c764e7269..7fb239cec48 100644 --- a/src/server/game/Groups/GroupMgr.cpp +++ b/src/server/game/Groups/GroupMgr.cpp @@ -233,3 +233,10 @@ void GroupMgr::LoadGroups() TC_LOG_INFO("server.loading", ">> Loaded %u group-instance saves in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } } + +void GroupMgr::Update(uint32 diff) +{ + for (GroupContainer::iterator itr = GroupStore.begin(); itr != GroupStore.end(); itr++) + if (itr->second) + itr->second->Update(diff); +} diff --git a/src/server/game/Groups/GroupMgr.h b/src/server/game/Groups/GroupMgr.h index 6aafe77432c..2fdd6d978e9 100644 --- a/src/server/game/Groups/GroupMgr.h +++ b/src/server/game/Groups/GroupMgr.h @@ -50,6 +50,8 @@ public: void AddGroup(Group* group); void RemoveGroup(Group* group); + void Update(uint32 diff); + protected: ObjectGuid::LowType NextGroupId; diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index c5812999490..0225c9405ce 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -2466,7 +2466,7 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::strin if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) { WorldPackets::Chat::Chat packet; - packet.Initalize(officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), nullptr, msg); + packet.Initialize(officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), nullptr, msg); WorldPacket const* data = packet.Write(); for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if (Player* player = itr->second->FindConnectedPlayer()) @@ -2481,7 +2481,7 @@ void Guild::BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std:: if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) { WorldPackets::Chat::Chat packet; - packet.Initalize(officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, LANG_ADDON, session->GetPlayer(), nullptr, msg, 0, "", DEFAULT_LOCALE, prefix); + packet.Initialize(officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, LANG_ADDON, session->GetPlayer(), nullptr, msg, 0, "", DEFAULT_LOCALE, prefix); WorldPacket const* data = packet.Write(); for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if (Player* player = itr->second->FindPlayer()) diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index b5550c2c073..b9fd383b19d 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -288,7 +288,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPackets::Chat::Chat packet; - packet.Initalize(ChatMsg(type), Language(lang), sender, nullptr, msg); + packet.Initialize(ChatMsg(type), Language(lang), sender, nullptr, msg); group->BroadcastPacket(packet.Write(), false, group->GetMemberGroup(GetPlayer()->GetGUID())); break; } @@ -320,8 +320,8 @@ void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, } case CHAT_MSG_RAID: { - Group* group = GetPlayer()->GetOriginalGroup(); - if (!group) + Group* group = GetPlayer()->GetGroup(); + if (!group || !group->isRaidGroup() || group->isBGGroup()) return; if (group->IsLeader(GetPlayer()->GetGUID())) @@ -330,7 +330,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPackets::Chat::Chat packet; - packet.Initalize(ChatMsg(type), Language(lang), sender, nullptr, msg); + packet.Initialize(ChatMsg(type), Language(lang), sender, nullptr, msg); group->BroadcastPacket(packet.Write(), false); break; } @@ -344,7 +344,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, WorldPackets::Chat::Chat packet; //in battleground, raid warning is sent only to players in battleground - code is ok - packet.Initalize(CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); + packet.Initialize(CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); group->BroadcastPacket(packet.Write(), false); break; } @@ -381,7 +381,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPackets::Chat::Chat packet; - packet.Initalize(ChatMsg(type), Language(lang), sender, nullptr, msg); + packet.Initialize(ChatMsg(type), Language(lang), sender, nullptr, msg); group->BroadcastPacket(packet.Write(), false); break; } @@ -484,7 +484,7 @@ void WorldSession::HandleChatAddonMessage(ChatMsg type, std::string prefix, std: } WorldPackets::Chat::Chat packet; - packet.Initalize(type, LANG_ADDON, sender, nullptr, text, 0, "", DEFAULT_LOCALE, prefix); + packet.Initialize(type, LANG_ADDON, sender, nullptr, text, 0, "", DEFAULT_LOCALE, prefix); group->BroadcastAddonMessagePacket(packet.Write(), prefix, true, subGroup, sender->GetGUID()); break; } @@ -666,7 +666,7 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData) return; WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_IGNORED, LANG_UNIVERSAL, _player, _player, GetPlayer()->GetName()); + packet.Initialize(CHAT_MSG_IGNORED, LANG_UNIVERSAL, _player, _player, GetPlayer()->GetName()); player->SendDirectMessage(packet.Write()); } diff --git a/src/server/game/Handlers/GarrisonHandler.cpp b/src/server/game/Handlers/GarrisonHandler.cpp index 0b45fb0ab57..54c7f4242fd 100644 --- a/src/server/game/Handlers/GarrisonHandler.cpp +++ b/src/server/game/Handlers/GarrisonHandler.cpp @@ -34,6 +34,15 @@ void WorldSession::HandleGarrisonPurchaseBuilding(WorldPackets::Garrison::Garris garrison->PlaceBuilding(garrisonPurchaseBuilding.PlotInstanceID, garrisonPurchaseBuilding.BuildingID); } +void WorldSession::HandleGarrisonCancelConstruction(WorldPackets::Garrison::GarrisonCancelConstruction& garrisonCancelConstruction) +{ + if (!_player->GetNPCIfCanInteractWith(garrisonCancelConstruction.NpcGUID, UNIT_NPC_FLAG_GARRISON_ARCHITECT)) + return; + + if (Garrison* garrison = _player->GetGarrison()) + garrison->CancelBuildingConstruction(garrisonCancelConstruction.PlotInstanceID); +} + void WorldSession::HandleGarrisonRequestBlueprintAndSpecializationData(WorldPackets::Garrison::GarrisonRequestBlueprintAndSpecializationData& /*garrisonRequestBlueprintAndSpecializationData*/) { if (Garrison* garrison = _player->GetGarrison()) diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 9552c9a0655..4aef42fed8d 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -35,6 +35,7 @@ #include "SpellAuraEffects.h" #include "MiscPackets.h" #include "LootPackets.h" +#include "PartyPackets.h" class Aura; @@ -51,103 +52,59 @@ class Aura; void WorldSession::SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res, uint32 val /* = 0 */) { - WorldPacket data(SMSG_PARTY_COMMAND_RESULT, 4 + member.size() + 1 + 4 + 4 + 8); - data << uint32(operation); - data << member; - data << uint32(res); - data << uint32(val); // LFD cooldown related (used with ERR_PARTY_LFG_BOOT_COOLDOWN_S and ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S) - data << uint64(0); // player who caused error (in some cases). - - SendPacket(&data); -} - -void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) -{ - ObjectGuid crossRealmGuid; // unused - - recvData.read_skip<uint32>(); // Non-zero in cross realm invites - recvData.read_skip<uint32>(); // Always 0 - - crossRealmGuid[2] = recvData.ReadBit(); - crossRealmGuid[7] = recvData.ReadBit(); - - uint8 realmLen = recvData.ReadBits(9); - - crossRealmGuid[3] = recvData.ReadBit(); - - uint8 nameLen = recvData.ReadBits(10); - - crossRealmGuid[5] = recvData.ReadBit(); - crossRealmGuid[4] = recvData.ReadBit(); - crossRealmGuid[6] = recvData.ReadBit(); - crossRealmGuid[0] = recvData.ReadBit(); - crossRealmGuid[1] = recvData.ReadBit(); + WorldPackets::Party::PartyCommandResult packet; - recvData.ReadByteSeq(crossRealmGuid[4]); - recvData.ReadByteSeq(crossRealmGuid[7]); - recvData.ReadByteSeq(crossRealmGuid[6]); + packet.Name = member; + packet.Command = uint8(operation); + packet.Result = uint8(res); + packet.ResultData = val; + packet.ResultGUID = ObjectGuid::Empty; - std::string memberName, realmName; - memberName = recvData.ReadString(nameLen); - realmName = recvData.ReadString(realmLen); // unused - - recvData.ReadByteSeq(crossRealmGuid[1]); - recvData.ReadByteSeq(crossRealmGuid[0]); - recvData.ReadByteSeq(crossRealmGuid[5]); - recvData.ReadByteSeq(crossRealmGuid[3]); - recvData.ReadByteSeq(crossRealmGuid[2]); - - // attempt add selected player - - // cheating - if (!normalizePlayerName(memberName)) - { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); - return; - } + SendPacket(packet.Write()); +} - Player* player = ObjectAccessor::FindPlayerByName(memberName); +void WorldSession::HandlePartyInviteOpcode(WorldPackets::Party::PartyInviteClient& packet) +{ + Player* player = ObjectAccessor::FindPlayerByName(packet.TargetName); // no player if (!player) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); + SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_BAD_PLAYER_NAME_S); return; } // restrict invite to GMs if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->IsGameMaster() && player->IsGameMaster()) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!GetPlayer()->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PLAYER_WRONG_FACTION); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_TARGET_NOT_IN_INSTANCE_S); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetInstanceId() != 0 && player->GetDungeonDifficultyID() != GetPlayer()->GetDungeonDifficultyID()) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_IGNORING_YOU_S); return; } if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID())) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_IGNORING_YOU_S); return; } - ObjectGuid invitedGuid = player->GetGUID(); - Group* group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); @@ -155,67 +112,18 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) Group* group2 = player->GetGroup(); if (group2 && group2->isBGGroup()) group2 = player->GetOriginalGroup(); + // player already in another group or invited if (group2 || player->GetGroupInvite()) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_ALREADY_IN_GROUP_S); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_ALREADY_IN_GROUP_S); if (group2) { // tell the player that they were invited but it failed as they were already in a group - WorldPacket data(SMSG_PARTY_INVITE, 45); - - data.WriteBit(0); - - data.WriteBit(invitedGuid[0]); - data.WriteBit(invitedGuid[3]); - data.WriteBit(invitedGuid[2]); - - data.WriteBit(0); // Inverse already in group - - data.WriteBit(invitedGuid[6]); - data.WriteBit(invitedGuid[5]); - - data.WriteBits(0, 9); // Realm name - - data.WriteBit(invitedGuid[4]); - - data.WriteBits(GetPlayer()->GetName().size(), 7); // Inviter name length - - data.WriteBits(0, 24); // Count 2 - - data.WriteBit(0); - - data.WriteBit(invitedGuid[1]); - data.WriteBit(invitedGuid[7]); - - data.FlushBits(); - - data.WriteByteSeq(invitedGuid[1]); - data.WriteByteSeq(invitedGuid[4]); - - data << int32(getMSTime()); - data << int32(0); - data << int32(0); - - data.WriteByteSeq(invitedGuid[6]); - data.WriteByteSeq(invitedGuid[0]); - data.WriteByteSeq(invitedGuid[2]); - data.WriteByteSeq(invitedGuid[3]); - - // for count2 { int32(0) } - - data.WriteByteSeq(invitedGuid[5]); - - // data.append(realm name); - - data.WriteByteSeq(invitedGuid[7]); - - data.WriteString(GetPlayer()->GetName()); // inviter name - - data << int32(0); - - player->GetSession()->SendPacket(&data); + WorldPackets::Party::PartyInvite partyInvite; + partyInvite.Initialize(GetPlayer(), packet.ProposedRoles, false); + player->GetSession()->SendPacket(partyInvite.Write()); } return; @@ -264,79 +172,21 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) } } - // ok, we do it - WorldPacket data(SMSG_PARTY_INVITE, 45); - - data.WriteBit(0); - - data.WriteBit(invitedGuid[0]); - data.WriteBit(invitedGuid[3]); - data.WriteBit(invitedGuid[2]); - - data.WriteBit(1); // Inverse already in group - - data.WriteBit(invitedGuid[6]); - data.WriteBit(invitedGuid[5]); - - data.WriteBits(0, 9); // Realm name - - data.WriteBit(invitedGuid[4]); - - data.WriteBits(GetPlayer()->GetName().size(), 7); // Inviter name length - - data.WriteBits(0, 24); // Count 2 - - data.WriteBit(0); - - data.WriteBit(invitedGuid[1]); - data.WriteBit(invitedGuid[7]); - - data.FlushBits(); + WorldPackets::Party::PartyInvite partyInvite; + partyInvite.Initialize(GetPlayer(), packet.ProposedRoles, true); + player->GetSession()->SendPacket(partyInvite.Write()); - data.WriteByteSeq(invitedGuid[1]); - data.WriteByteSeq(invitedGuid[4]); - - data << int32(getMSTime()); - data << int32(0); - data << int32(0); - - data.WriteByteSeq(invitedGuid[6]); - data.WriteByteSeq(invitedGuid[0]); - data.WriteByteSeq(invitedGuid[2]); - data.WriteByteSeq(invitedGuid[3]); - - // for count2 { int32(0) } - - data.WriteByteSeq(invitedGuid[5]); - - // data.append(realm name); - - data.WriteByteSeq(invitedGuid[7]); - - data.WriteString(GetPlayer()->GetName()); - - data << int32(0); - - player->GetSession()->SendPacket(&data); - - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PARTY_RESULT_OK); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_PARTY_RESULT_OK); } -void WorldSession::HandleGroupInviteResponseOpcode(WorldPacket& recvData) +void WorldSession::HandlePartyInviteResponseOpcode(WorldPackets::Party::PartyInviteResponse& packet) { - recvData.ReadBit(); // unk always 0 - bool accept = recvData.ReadBit(); - - // Never actually received? - /*if (accept) - recvData.read_skip<uint32>(); // unk*/ - Group* group = GetPlayer()->GetGroupInvite(); if (!group) return; - if (accept) + if (packet.Accept) { // Remove player from invitees in any case group->RemoveInvite(GetPlayer()); @@ -391,28 +241,22 @@ void WorldSession::HandleGroupInviteResponseOpcode(WorldPacket& recvData) return; // report - WorldPacket data(SMSG_GROUP_DECLINE, GetPlayer()->GetName().size()); - data << GetPlayer()->GetName(); - leader->GetSession()->SendPacket(&data); + WorldPackets::Party::GroupDecline decline(GetPlayer()->GetName()); + leader->GetSession()->SendPacket(decline.Write()); } } -void WorldSession::HandleGroupUninviteOpcode(WorldPacket& recvData) +void WorldSession::HandlePartyUninviteOpcode(WorldPackets::Party::PartyUninvite& packet) { - ObjectGuid guid; - std::string reason; - recvData >> guid; - recvData >> reason; - - //can't uninvite yourself - if (guid == GetPlayer()->GetGUID()) + // can't uninvite yourself + if (packet.TargetGUID == GetPlayer()->GetGUID()) { TC_LOG_ERROR("network", "WorldSession::HandleGroupUninviteGuidOpcode: leader %s (%s) tried to uninvite himself from the group.", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str()); return; } - PartyResult res = GetPlayer()->CanUninviteFromGroup(guid); + PartyResult res = GetPlayer()->CanUninviteFromGroup(packet.TargetGUID); if (res != ERR_PARTY_RESULT_OK) { SendPartyResult(PARTY_OP_UNINVITE, "", res); @@ -423,13 +267,13 @@ void WorldSession::HandleGroupUninviteOpcode(WorldPacket& recvData) // grp is checked already above in CanUninviteFromGroup() ASSERT(grp); - if (grp->IsMember(guid)) + if (grp->IsMember(packet.TargetGUID)) { - Player::RemoveFromGroup(grp, guid, GROUP_REMOVEMETHOD_KICK, GetPlayer()->GetGUID(), reason.c_str()); + Player::RemoveFromGroup(grp, packet.TargetGUID, GROUP_REMOVEMETHOD_KICK, GetPlayer()->GetGUID(), packet.Reason.c_str()); return; } - if (Player* player = grp->GetInvited(guid)) + if (Player* player = grp->GetInvited(packet.TargetGUID)) { player->UninviteFromGroup(); return; @@ -438,12 +282,9 @@ void WorldSession::HandleGroupUninviteOpcode(WorldPacket& recvData) SendPartyResult(PARTY_OP_UNINVITE, "", ERR_TARGET_NOT_IN_GROUP_S); } -void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket& recvData) +void WorldSession::HandleSetPartyLeaderOpcode(WorldPackets::Party::SetPartyLeader& packet) { - ObjectGuid guid; - recvData >> guid; - - Player* player = ObjectAccessor::FindConnectedPlayer(guid); + Player* player = ObjectAccessor::FindConnectedPlayer(packet.TargetGUID); Group* group = GetPlayer()->GetGroup(); if (!group || !player) @@ -453,87 +294,35 @@ void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket& recvData) return; // Everything's fine, accepted. - group->ChangeLeader(guid); + group->ChangeLeader(packet.TargetGUID, packet.PartyIndex); group->SendUpdate(); } -void WorldSession::HandleGroupSetRolesOpcode(WorldPacket& recvData) +void WorldSession::HandleSetRoleOpcode(WorldPackets::Party::SetRole& packet) { - uint32 newRole; - ObjectGuid guid1; // Assigner GUID - ObjectGuid guid2; // Target GUID - - guid1 = GetPlayer()->GetGUID(); - - recvData >> newRole; - - guid2[2] = recvData.ReadBit(); - guid2[6] = recvData.ReadBit(); - guid2[3] = recvData.ReadBit(); - guid2[7] = recvData.ReadBit(); - guid2[5] = recvData.ReadBit(); - guid2[1] = recvData.ReadBit(); - guid2[0] = recvData.ReadBit(); - guid2[4] = recvData.ReadBit(); - - recvData.ReadByteSeq(guid2[6]); - recvData.ReadByteSeq(guid2[4]); - recvData.ReadByteSeq(guid2[1]); - recvData.ReadByteSeq(guid2[3]); - recvData.ReadByteSeq(guid2[0]); - recvData.ReadByteSeq(guid2[5]); - recvData.ReadByteSeq(guid2[2]); - recvData.ReadByteSeq(guid2[7]); - - WorldPacket data(SMSG_ROLE_CHANGED_INFORM, 24); - - data.WriteBit(guid1[1]); - data.WriteBit(guid2[0]); - data.WriteBit(guid2[2]); - data.WriteBit(guid2[4]); - data.WriteBit(guid2[7]); - data.WriteBit(guid2[3]); - data.WriteBit(guid1[7]); - data.WriteBit(guid2[5]); - data.WriteBit(guid1[5]); - data.WriteBit(guid1[4]); - data.WriteBit(guid1[3]); - data.WriteBit(guid2[6]); - data.WriteBit(guid1[2]); - data.WriteBit(guid1[6]); - data.WriteBit(guid2[1]); - data.WriteBit(guid1[0]); - - data.WriteByteSeq(guid1[7]); - data.WriteByteSeq(guid2[3]); - data.WriteByteSeq(guid1[6]); - data.WriteByteSeq(guid2[4]); - data.WriteByteSeq(guid2[0]); - data << uint32(newRole); // New Role - data.WriteByteSeq(guid2[6]); - data.WriteByteSeq(guid2[2]); - data.WriteByteSeq(guid1[0]); - data.WriteByteSeq(guid1[4]); - data.WriteByteSeq(guid2[1]); - data.WriteByteSeq(guid1[3]); - data.WriteByteSeq(guid1[5]); - data.WriteByteSeq(guid1[2]); - data.WriteByteSeq(guid2[5]); - data.WriteByteSeq(guid2[7]); - data.WriteByteSeq(guid1[1]); - data << uint32(0); // Old Role - - if (Group* group = GetPlayer()->GetGroup()) + WorldPackets::Party::RoleChangedInform roleChangedInform; + + Group* group = GetPlayer()->GetGroup(); + uint8 oldRole = group ? group->GetLfgRoles(packet.TargetGUID) : 0; + if (oldRole == packet.Role) + return; + + roleChangedInform.PartyIndex = packet.PartyIndex; + roleChangedInform.From = GetPlayer()->GetGUID(); + roleChangedInform.ChangedUnit = packet.TargetGUID; + roleChangedInform.OldRole = oldRole; + roleChangedInform.NewRole = packet.Role; + + if (group) { - /// @todo probably should be sent only if (oldRole != newRole) - group->BroadcastPacket(&data, false); - group->SetLfgRoles(guid2, newRole); + group->BroadcastPacket(roleChangedInform.Write(), false); + group->SetLfgRoles(packet.TargetGUID, packet.Role); } else - SendPacket(&data); + SendPacket(roleChangedInform.Write()); } -void WorldSession::HandleGroupDisbandOpcode(WorldPacket& /*recvData*/) +void WorldSession::HandleLeaveGroupOpcode(WorldPackets::Party::LeaveGroup& /*packet*/) { Group* grp = GetPlayer()->GetGroup(); if (!grp) @@ -554,13 +343,8 @@ void WorldSession::HandleGroupDisbandOpcode(WorldPacket& /*recvData*/) GetPlayer()->RemoveFromGroup(GROUP_REMOVEMETHOD_LEAVE); } -void WorldSession::HandleLootMethodOpcode(WorldPacket& recvData) +void WorldSession::HandleSetLootMethodOpcode(WorldPackets::Party::SetLootMethod& packet) { - uint32 lootMethod; - ObjectGuid lootMaster; - uint32 lootThreshold; - recvData >> lootMethod >> lootMaster >> lootThreshold; - Group* group = GetPlayer()->GetGroup(); if (!group) return; @@ -569,20 +353,20 @@ void WorldSession::HandleLootMethodOpcode(WorldPacket& recvData) if (!group->IsLeader(GetPlayer()->GetGUID())) return; - if (lootMethod > NEED_BEFORE_GREED) + if (packet.LootMethod > NEED_BEFORE_GREED) return; - if (lootThreshold < ITEM_QUALITY_UNCOMMON || lootThreshold > ITEM_QUALITY_ARTIFACT) + if (packet.LootThreshold < ITEM_QUALITY_UNCOMMON || packet.LootThreshold > ITEM_QUALITY_ARTIFACT) return; - if (lootMethod == MASTER_LOOT && !group->IsMember(lootMaster)) + if (packet.LootMethod == MASTER_LOOT && !group->IsMember(packet.LootMasterGUID)) return; /********************/ // everything's fine, do it - group->SetLootMethod((LootMethod)lootMethod); - group->SetMasterLooterGuid(lootMaster); - group->SetLootThreshold((ItemQualities)lootThreshold); + group->SetLootMethod((LootMethod)packet.LootMethod); + group->SetMasterLooterGuid(packet.LootMasterGUID); + group->SetLootThreshold((ItemQualities)packet.LootThreshold); group->SendUpdate(); } @@ -605,28 +389,16 @@ void WorldSession::HandleLootRoll(WorldPackets::Loot::LootRoll& packet) } } -void WorldSession::HandleMinimapPingOpcode(WorldPacket& recvData) +void WorldSession::HandleMinimapPingOpcode(WorldPackets::Party::MinimapPingClient& packet) { - TC_LOG_DEBUG("network", "WORLD: Received MSG_MINIMAP_PING"); - if (!GetPlayer()->GetGroup()) return; - float x, y; - recvData >> x; - recvData >> y; - - //TC_LOG_DEBUG("misc", "Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y); - - /** error handling **/ - /********************/ - - // everything's fine, do it - WorldPacket data(SMSG_MINIMAP_PING, (8+4+4)); - data << GetPlayer()->GetGUID(); - data << float(x); - data << float(y); - GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID()); + WorldPackets::Party::MinimapPing minimapPing; + minimapPing.Sender = GetPlayer()->GetGUID(); + minimapPing.PositionX = packet.PositionX; + minimapPing.PositionY = packet.PositionY; + GetPlayer()->GetGroup()->BroadcastPacket(minimapPing.Write(), true, -1, GetPlayer()->GetGUID()); } void WorldSession::HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet) @@ -643,8 +415,6 @@ void WorldSession::HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& // everything's fine, do it roll = urand(minimum, maximum); - //TC_LOG_DEBUG("misc", "ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll); - WorldPackets::Misc::RandomRoll randomRoll; randomRoll.Min = minimum; randomRoll.Max = maximum; @@ -657,44 +427,31 @@ void WorldSession::HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& SendPacket(randomRoll.Write()); } -void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket& recvData) +void WorldSession::HandleUpdateRaidTargetOpcode(WorldPackets::Party::UpdateRaidTarget& packet) { - TC_LOG_DEBUG("network", "WORLD: Received MSG_RAID_TARGET_UPDATE"); - Group* group = GetPlayer()->GetGroup(); if (!group) return; - uint8 x; - recvData >> x; - - /** error handling **/ - /********************/ - - // everything's fine, do it - if (x == 0xFF) // target icon request - group->SendTargetIconList(this); - else // target icon update + if (packet.Symbol == 0xFF) // target icon request + group->SendTargetIconList(this, packet.PartyIndex); + else // target icon update { if (group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) return; - ObjectGuid guid; - recvData >> guid; - - if (guid.IsPlayer()) + if (packet.Target.IsPlayer()) { - Player* target = ObjectAccessor::FindConnectedPlayer(guid); - + Player* target = ObjectAccessor::FindConnectedPlayer(packet.Target); if (!target || target->IsHostileTo(GetPlayer())) return; } - group->SetTargetIcon(x, _player->GetGUID(), guid); + group->SetTargetIcon(packet.Symbol, packet.Target, GetPlayer()->GetGUID(), packet.PartyIndex); } } -void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket& recvData) +void WorldSession::HandleConvertRaidOpcode(WorldPackets::Party::ConvertRaid& packet) { Group* group = GetPlayer()->GetGroup(); if (!group) @@ -711,71 +468,56 @@ void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket& recvData) SendPartyResult(PARTY_OP_INVITE, "", ERR_PARTY_RESULT_OK); // New 4.x: it is now possible to convert a raid to a group if member count is 5 or less - - bool toRaid; - recvData >> toRaid; - - if (toRaid) + if (packet.Raid) group->ConvertToRaid(); else group->ConvertToGroup(); } -void WorldSession::HandleGroupRequestJoinUpdates(WorldPacket& /*recvData*/) +void WorldSession::HandleRequestPartyJoinUpdates(WorldPackets::Party::RequestPartyJoinUpdates& packet) { Group* group = GetPlayer()->GetGroup(); if (!group) return; - // does some stuff. dunno what. + group->SendTargetIconList(this, packet.PartyIndex); + group->SendRaidMarkersChanged(this, packet.PartyIndex); } -void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket& recvData) +void WorldSession::HandleChangeSubGroupOpcode(WorldPackets::Party::ChangeSubGroup& packet) { // we will get correct pointer for group here, so we don't have to check if group is BG raid Group* group = GetPlayer()->GetGroup(); if (!group) return; - std::string name; - uint8 groupNr; - recvData >> name; - recvData >> groupNr; - - if (groupNr >= MAX_RAID_SUBGROUPS) + if (packet.NewSubGroup >= MAX_RAID_SUBGROUPS) return; ObjectGuid senderGuid = GetPlayer()->GetGUID(); if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid)) return; - if (!group->HasFreeSlotSubGroup(groupNr)) + if (!group->HasFreeSlotSubGroup(packet.NewSubGroup)) return; - Player* movedPlayer = ObjectAccessor::FindConnectedPlayerByName(name); - ObjectGuid guid; - - if (movedPlayer) - guid = movedPlayer->GetGUID(); - else - { - CharacterDatabase.EscapeString(name); - guid = ObjectMgr::GetPlayerGUIDByName(name.c_str()); - } - - group->ChangeMembersGroup(guid, groupNr); + group->ChangeMembersGroup(packet.TargetGUID, packet.NewSubGroup); } -void WorldSession::HandleGroupSwapSubGroupOpcode(WorldPacket& recvData) +void WorldSession::HandleSwapSubGroupsOpcode(WorldPackets::Party::SwapSubGroups& packet) { - std::string unk1; - std::string unk2; + Group* group = GetPlayer()->GetGroup(); + if (!group) + return; - recvData >> unk1; - recvData >> unk2; + ObjectGuid senderGuid = GetPlayer()->GetGUID(); + if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid)) + return; + + group->SwapMembersGroups(packet.FirstTarget, packet.SecondTarget); } -void WorldSession::HandleGroupAssistantLeaderOpcode(WorldPacket& recvData) +void WorldSession::HandleSetAssistantLeaderOpcode(WorldPackets::Party::SetAssistantLeader& packet) { Group* group = GetPlayer()->GetGroup(); if (!group) @@ -784,12 +526,7 @@ void WorldSession::HandleGroupAssistantLeaderOpcode(WorldPacket& recvData) if (!group->IsLeader(GetPlayer()->GetGUID())) return; - ObjectGuid guid; - bool apply; - recvData >> guid; - recvData >> apply; - - group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_ASSISTANT); + group->SetGroupMemberFlag(packet.Target, packet.Apply, MEMBER_FLAG_ASSISTANT); } void WorldSession::HandlePartyAssignmentOpcode(WorldPacket& recvData) @@ -826,509 +563,103 @@ void WorldSession::HandlePartyAssignmentOpcode(WorldPacket& recvData) group->SendUpdate(); } -void WorldSession::HandleRaidReadyCheckOpcode(WorldPacket& recvData) +void WorldSession::HandleDoReadyCheckOpcode(WorldPackets::Party::DoReadyCheck& packet) { Group* group = GetPlayer()->GetGroup(); if (!group) return; - if (recvData.empty()) // request - { - /** error handling **/ - if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) - return; - /********************/ - - // everything's fine, do it - WorldPacket data(SMSG_READY_CHECK_STARTED, 8); - data << GetPlayer()->GetGUID(); - group->BroadcastPacket(&data, false, -1); + /** error handling **/ + if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + return; + /********************/ - group->OfflineReadyCheck(); - } - else // answer - { - uint8 state; - recvData >> state; - - // everything's fine, do it - WorldPacket data(SMSG_READY_CHECK_RESPONSE, 9); - data << GetPlayer()->GetGUID(); - data << uint8(state); - group->BroadcastReadyCheck(&data); - } + // everything's fine, do it + group->StartReadyCheck(GetPlayer()->GetGUID(), packet.PartyIndex); } -void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacket* data) +void WorldSession::HandleReadyCheckResponseOpcode(WorldPackets::Party::ReadyCheckResponseClient& packet) { - uint32 mask = player->GetGroupUpdateFlag(); - - if (mask == GROUP_UPDATE_FLAG_NONE) + Group* group = GetPlayer()->GetGroup(); + if (!group) return; - std::set<uint32> const& phases = player->GetPhases(); - - if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also - mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); - - if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets - mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER); - - data->Initialize(SMSG_PARTY_MEMBER_STATE, 80); // average value - *data << player->GetPackGUID(); - *data << uint32(mask); - - if (mask & GROUP_UPDATE_FLAG_STATUS) - { - uint16 playerStatus = MEMBER_STATUS_ONLINE; - if (player->IsPvP()) - playerStatus |= MEMBER_STATUS_PVP; - - if (!player->IsAlive()) - { - if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) - playerStatus |= MEMBER_STATUS_GHOST; - else - playerStatus |= MEMBER_STATUS_DEAD; - } - - if (player->IsFFAPvP()) - playerStatus |= MEMBER_STATUS_PVP_FFA; - - if (player->isAFK()) - playerStatus |= MEMBER_STATUS_AFK; - - if (player->isDND()) - playerStatus |= MEMBER_STATUS_DND; - - *data << uint16(playerStatus); - } - - if (mask & GROUP_UPDATE_FLAG_CUR_HP) - *data << uint32(player->GetHealth()); - - if (mask & GROUP_UPDATE_FLAG_MAX_HP) - *data << uint32(player->GetMaxHealth()); - - Powers powerType = player->getPowerType(); - if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) - *data << uint8(powerType); - - if (mask & GROUP_UPDATE_FLAG_CUR_POWER) - *data << uint16(player->GetPower(powerType)); - - if (mask & GROUP_UPDATE_FLAG_MAX_POWER) - *data << uint16(player->GetMaxPower(powerType)); - - if (mask & GROUP_UPDATE_FLAG_LEVEL) - *data << uint16(player->getLevel()); - - if (mask & GROUP_UPDATE_FLAG_ZONE) - *data << uint16(player->GetZoneId()); - - if (mask & GROUP_UPDATE_FLAG_UNK100) - *data << uint16(0); - - if (mask & GROUP_UPDATE_FLAG_POSITION) - { - *data << uint16(player->GetPositionX()); - *data << uint16(player->GetPositionY()); - *data << uint16(player->GetPositionZ()); - } - - if (mask & GROUP_UPDATE_FLAG_AURAS) - { - *data << uint8(0); - uint64 auramask = player->GetAuraUpdateMaskForRaid(); - *data << uint64(auramask); - *data << uint32(MAX_AURAS); // count - for (uint32 i = 0; i < MAX_AURAS; ++i) - { - if (auramask & (uint64(1) << i)) - { - AuraApplication const* aurApp = player->GetVisibleAura(i); - if (!aurApp) - { - *data << uint32(0); - *data << uint16(0); - continue; - } - - *data << uint32(aurApp->GetBase()->GetId()); - *data << uint16(aurApp->GetFlags()); - - if (aurApp->GetFlags() & AFLAG_SCALABLE) - { - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) - *data << int32(eff->GetAmount()); - else - *data << int32(0); - } - } - } - } - } - - Pet* pet = player->GetPet(); - if (mask & GROUP_UPDATE_FLAG_PET_GUID) - { - if (pet) - *data << pet->GetGUID(); - else - *data << ObjectGuid::Empty; - } - - if (mask & GROUP_UPDATE_FLAG_PET_NAME) - { - if (pet) - *data << pet->GetName(); - else - *data << uint8(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID) - { - if (pet) - *data << uint16(pet->GetDisplayId()); - else - *data << uint16(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP) - { - if (pet) - *data << uint32(pet->GetHealth()); - else - *data << uint32(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP) - { - if (pet) - *data << uint32(pet->GetMaxHealth()); - else - *data << uint32(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) - { - if (pet) - *data << uint8(pet->getPowerType()); - else - *data << uint8(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER) - { - if (pet) - *data << uint16(pet->GetPower(pet->getPowerType())); - else - *data << uint16(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER) - { - if (pet) - *data << uint16(pet->GetMaxPower(pet->getPowerType())); - else - *data << uint16(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_AURAS) - { - if (pet) - { - *data << uint8(0); - uint64 auramask = pet->GetAuraUpdateMaskForRaid(); - *data << uint64(auramask); - *data << uint32(MAX_AURAS); // count - for (uint32 i = 0; i < MAX_AURAS; ++i) - { - if (auramask & (uint64(1) << i)) - { - AuraApplication const* aurApp = pet->GetVisibleAura(i); - if (!aurApp) - { - *data << uint32(0); - *data << uint16(0); - continue; - } - - *data << uint32(aurApp->GetBase()->GetId()); - *data << uint16(aurApp->GetFlags()); - - if (aurApp->GetFlags() & AFLAG_SCALABLE) - { - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) - *data << int32(eff->GetAmount()); - else - *data << int32(0); - } - } - } - } - } - else - { - *data << uint8(0); - *data << uint64(0); - } - } - - if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT) - { - if (Vehicle* veh = player->GetVehicle()) - *data << uint32(veh->GetVehicleInfo()->SeatID[player->m_movementInfo.transport.seat]); - else - *data << uint32(0); - - } - - if (mask & GROUP_UPDATE_FLAG_PHASE) - { - *data << uint32(phases.empty() ? 8 : 0); - *data << uint32(phases.size()); - for (std::set<uint32>::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) - *data << uint16(*itr); - } + // everything's fine, do it + group->SetMemberReadyCheck(GetPlayer()->GetGUID(), packet.IsReady); } -/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ -void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) +void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPackets::Party::RequestPartyMemberStats& packet) { - ObjectGuid Guid; - recvData >> Guid; + WorldPackets::Party::PartyMemberStats partyMemberStats; - Player* player = ObjectAccessor::FindConnectedPlayer(Guid); + Player* player = ObjectAccessor::FindConnectedPlayer(packet.TargetGUID); if (!player) { - WorldPacket data(SMSG_PARTY_MEMBER_STATE, 3 + 4 + 2); - data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related - data << Guid.WriteAsPacked(); - data << uint32(GROUP_UPDATE_FLAG_STATUS); - data << uint16(MEMBER_STATUS_OFFLINE); - SendPacket(&data); - return; - } - - Pet* pet = player->GetPet(); - Powers powerType = player->getPowerType(); - std::set<uint32> const& phases = player->GetPhases(); - - WorldPacket data(SMSG_PARTY_MEMBER_STATE, 4 + 2 + 2 + 2 + 1 + 2 * 6 + 8 + 1 + 8); - data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related - data << player->GetPackGUID(); - - uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP - | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL - | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS - | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS; - - if (powerType != POWER_MANA) - updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE; - - if (pet) - updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP - | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER; - - if (player->GetVehicle()) - updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; - - if (!phases.empty()) - updateFlags |= GROUP_UPDATE_FLAG_PHASE; - - uint16 playerStatus = MEMBER_STATUS_ONLINE; - if (player->IsPvP()) - playerStatus |= MEMBER_STATUS_PVP; - - if (!player->IsAlive()) - { - if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) - playerStatus |= MEMBER_STATUS_GHOST; - else - playerStatus |= MEMBER_STATUS_DEAD; - } - - if (player->IsFFAPvP()) - playerStatus |= MEMBER_STATUS_PVP_FFA; - - if (player->isAFK()) - playerStatus |= MEMBER_STATUS_AFK; - - if (player->isDND()) - playerStatus |= MEMBER_STATUS_DND; - - data << uint32(updateFlags); - data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS - data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP - data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP - if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE) - data << uint8(powerType); - - data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER - data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER - data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL - data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE - data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION - data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION - data << uint16(player->GetPositionZ()); // GROUP_UPDATE_FLAG_POSITION - - // GROUP_UPDATE_FLAG_AURAS - data << uint8(1); - uint64 auramask = 0; - size_t maskPos = data.wpos(); - data << uint64(auramask); // placeholder - data << uint32(MAX_AURAS); // count - - for (uint8 i = 0; i < MAX_AURAS; ++i) - { - if (AuraApplication const* aurApp = player->GetVisibleAura(i)) - { - auramask |= (uint64(1) << i); - - data << uint32(aurApp->GetBase()->GetId()); - data << uint16(aurApp->GetFlags()); - - if (aurApp->GetFlags() & AFLAG_SCALABLE) - { - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) - data << int32(eff->GetAmount()); - else - data << int32(0); - } - } - } - } - - data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS - - if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID) - data << pet->GetGUID(); - - data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME - data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID - - if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP) - data << uint32(pet->GetHealth()); - - if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP) - data << uint32(pet->GetMaxHealth()); - - if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE) - data << (uint8)pet->getPowerType(); - - if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER) - data << uint16(pet->GetPower(pet->getPowerType())); - - if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER) - data << uint16(pet->GetMaxPower(pet->getPowerType())); - - // GROUP_UPDATE_FLAG_PET_AURAS - uint64 petAuraMask = 0; - data << uint8(1); - maskPos = data.wpos(); - data << uint64(petAuraMask); // placeholder - data << uint32(MAX_AURAS); // count - if (pet) - { - for (uint8 i = 0; i < MAX_AURAS; ++i) - { - if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) - { - petAuraMask |= (uint64(1) << i); - - data << uint32(aurApp->GetBase()->GetId()); - data << uint16(aurApp->GetFlags()); - - if (aurApp->GetFlags() & AFLAG_SCALABLE) - { - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) - data << int32(eff->GetAmount()); - else - data << int32(0); - } - } - } - } - } - - data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS - - if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT) - data << uint32(player->GetVehicle()->GetVehicleInfo()->SeatID[player->m_movementInfo.transport.seat]); - - if (updateFlags & GROUP_UPDATE_FLAG_PHASE) - { - data << uint32(phases.empty() ? 8 : 0); - data << uint32(phases.size()); - for (std::set<uint32>::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) - data << uint16(*itr); + partyMemberStats.MemberStats.GUID = packet.TargetGUID; + partyMemberStats.MemberStats.Status = MEMBER_STATUS_OFFLINE; } + else + partyMemberStats.Initialize(player); - SendPacket(&data); + SendPacket(partyMemberStats.Write()); } -void WorldSession::HandleRequestRaidInfoOpcode(WorldPacket& /*recvData*/) +void WorldSession::HandleRequestRaidInfoOpcode(WorldPackets::Party::RequestRaidInfo& /*packet*/) { // every time the player checks the character screen _player->SendRaidInfo(); } -void WorldSession::HandleOptOutOfLootOpcode(WorldPacket& recvData) +void WorldSession::HandleOptOutOfLootOpcode(WorldPackets::Party::OptOutOfLoot& packet) { - bool passOnLoot; - recvData >> passOnLoot; // 1 always pass, 0 do not pass - // ignore if player not loaded if (!GetPlayer()) // needed because STATUS_AUTHED { - if (passOnLoot) + if (packet.PassOnLoot) TC_LOG_ERROR("network", "CMSG_OPT_OUT_OF_LOOT value<>0 for not-loaded character!"); return; } - GetPlayer()->SetPassOnGroupLoot(passOnLoot != 0); + GetPlayer()->SetPassOnGroupLoot(packet.PassOnLoot); } -void WorldSession::HandleRolePollBeginOpcode(WorldPacket& recvData) +void WorldSession::HandleInitiateRolePoll(WorldPackets::Party::InitiateRolePoll& packet) { Group* group = GetPlayer()->GetGroup(); if (!group) return; - if (recvData.empty()) - { - if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) - return; + if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + return; - ObjectGuid guid = GetPlayer()->GetGUID(); - - WorldPacket data(SMSG_ROLE_POLL_INFORM, 8); - data.WriteBit(guid[1]); - data.WriteBit(guid[5]); - data.WriteBit(guid[7]); - data.WriteBit(guid[3]); - data.WriteBit(guid[2]); - data.WriteBit(guid[4]); - data.WriteBit(guid[0]); - data.WriteBit(guid[6]); - data.WriteByteSeq(guid[4]); - data.WriteByteSeq(guid[7]); - data.WriteByteSeq(guid[0]); - data.WriteByteSeq(guid[5]); - data.WriteByteSeq(guid[1]); - data.WriteByteSeq(guid[6]); - data.WriteByteSeq(guid[2]); - data.WriteByteSeq(guid[3]); - - GetPlayer()->GetGroup()->BroadcastPacket(&data, true); - } + ObjectGuid guid = GetPlayer()->GetGUID(); + + WorldPackets::Party::RolePollInform rolePollInform; + rolePollInform.From = GetPlayer()->GetGUID(); + rolePollInform.PartyIndex = packet.PartyIndex; + group->BroadcastPacket(rolePollInform.Write(), true); +} + +void WorldSession::HandleSetEveryoneIsAssistant(WorldPackets::Party::SetEveryoneIsAssistant& packet) +{ + Group* group = GetPlayer()->GetGroup(); + if (!group) + return; + + if (!group->IsLeader(GetPlayer()->GetGUID())) + return; + + group->SetEveryoneIsAssistant(packet.EveryoneIsAssistant); +} + +void WorldSession::HandleClearRaidMarker(WorldPackets::Party::ClearRaidMarker& packet) +{ + Group* group = GetPlayer()->GetGroup(); + if (!group) + return; + + if (group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + return; + + group->DeleteRaidMarker(packet.MarkerId); } diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index c4d3358a333..4a3866cbb1b 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -86,7 +86,7 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) { if (!sLFGMgr->isOptionEnabled(lfg::LFG_OPTION_ENABLE_DUNGEON_FINDER | lfg::LFG_OPTION_ENABLE_RAID_BROWSER) || (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() && - (GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup()))) + (GetPlayer()->GetGroup()->GetMembersCount() == MAX_GROUP_SIZE || !GetPlayer()->GetGroup()->isLFGGroup()))) { recvData.rfinish(); return; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 025bb45b42b..1715e1643ea 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1213,129 +1213,28 @@ void WorldSession::HandleObjectUpdateRescuedOpcode(WorldPackets::Misc::ObjectUpd _player->m_clientGUIDs.insert(objectUpdateRescued.ObjectGUID); } -void WorldSession::HandleSaveCUFProfiles(WorldPacket& recvPacket) +void WorldSession::HandleSaveCUFProfiles(WorldPackets::Misc::SaveCUFProfiles& packet) { - uint8 count = (uint8)recvPacket.ReadBits(20); - - if (count > MAX_CUF_PROFILES) + if (packet.CUFProfiles.size() > MAX_CUF_PROFILES) { TC_LOG_ERROR("entities.player", "HandleSaveCUFProfiles - %s tried to save more than %i CUF profiles. Hacking attempt?", GetPlayerName().c_str(), MAX_CUF_PROFILES); - recvPacket.rfinish(); return; } - CUFProfile* profiles[MAX_CUF_PROFILES]; - uint8 strlens[MAX_CUF_PROFILES]; - - for (uint8 i = 0; i < count; ++i) - { - profiles[i] = new CUFProfile; - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_SPEC_2 , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_10_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_UNK_157 , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_HEAL_PREDICTION , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_SPEC_1 , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_PVP , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_POWER_BAR , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_15_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_40_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_PETS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_5_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_ONLY_DISPELLABLE_DEBUFFS, recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_2_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_UNK_156 , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_NON_BOSS_DEBUFFS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_MAIN_TANK_AND_ASSIST , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_AGGRO_HIGHLIGHT , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_3_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_BORDER , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_USE_CLASS_COLORS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_UNK_145 , recvPacket.ReadBit()); - strlens[i] = (uint8)recvPacket.ReadBits(8); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_PVE , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_HORIZONTAL_GROUPS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_25_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_KEEP_GROUPS_TOGETHER , recvPacket.ReadBit()); - } - - for (uint8 i = 0; i < count; ++i) - { - recvPacket >> profiles[i]->Unk146; - profiles[i]->ProfileName = recvPacket.ReadString(strlens[i]); - recvPacket >> profiles[i]->Unk152; - recvPacket >> profiles[i]->FrameHeight; - recvPacket >> profiles[i]->FrameWidth; - recvPacket >> profiles[i]->Unk150; - recvPacket >> profiles[i]->HealthText; - recvPacket >> profiles[i]->Unk147; - recvPacket >> profiles[i]->SortBy; - recvPacket >> profiles[i]->Unk154; - recvPacket >> profiles[i]->Unk148; - - GetPlayer()->SaveCUFProfile(i, profiles[i]); - } + for (uint8 i = 0; i < packet.CUFProfiles.size(); ++i) + GetPlayer()->SaveCUFProfile(i, std::move(packet.CUFProfiles[i])); - for (uint8 i = count; i < MAX_CUF_PROFILES; ++i) - GetPlayer()->SaveCUFProfile(i, NULL); + for (uint8 i = packet.CUFProfiles.size(); i < MAX_CUF_PROFILES; ++i) + GetPlayer()->SaveCUFProfile(i, nullptr); } void WorldSession::SendLoadCUFProfiles() { Player* player = GetPlayer(); - uint8 count = player->GetCUFProfilesCount(); + WorldPackets::Misc::LoadCUFProfiles loadCUFProfiles; - ByteBuffer byteBuffer(25 * count); - WorldPacket data(SMSG_LOAD_CUF_PROFILES, 5 * count + 25 * count); - - data.WriteBits(count, 20); - for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i) - { - CUFProfile* profile = player->GetCUFProfile(i); - if (!profile) - continue; - - data.WriteBit(profile->BoolOptions[CUF_UNK_157]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_10_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_5_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_25_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_HEAL_PREDICTION]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_PVE]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_HORIZONTAL_GROUPS]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_40_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_3_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_AGGRO_HIGHLIGHT]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_BORDER]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_2_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_NON_BOSS_DEBUFFS]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_MAIN_TANK_AND_ASSIST]); - data.WriteBit(profile->BoolOptions[CUF_UNK_156]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_SPEC_2]); - data.WriteBit(profile->BoolOptions[CUF_USE_CLASS_COLORS]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_POWER_BAR]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_SPEC_1]); - data.WriteBits(profile->ProfileName.size(), 8); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_ONLY_DISPELLABLE_DEBUFFS]); - data.WriteBit(profile->BoolOptions[CUF_KEEP_GROUPS_TOGETHER]); - data.WriteBit(profile->BoolOptions[CUF_UNK_145]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_15_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_PETS]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_PVP]); - - byteBuffer << uint16(profile->Unk154); - byteBuffer << uint16(profile->FrameHeight); - byteBuffer << uint16(profile->Unk152); - byteBuffer << uint8(profile->Unk147); - byteBuffer << uint16(profile->Unk150); - byteBuffer << uint8(profile->Unk146); - byteBuffer << uint8(profile->HealthText); - byteBuffer << uint8(profile->SortBy); - byteBuffer << uint16(profile->FrameWidth); - byteBuffer << uint8(profile->Unk148); - byteBuffer.WriteString(profile->ProfileName); - } - - data.FlushBits(); - data.append(byteBuffer); - SendPacket(&data); + for (uint8 i = 0; i < MAX_CUF_PROFILES; i++) + loadCUFProfiles.CUFProfiles.push_back(player->GetCUFProfile(i)); + SendPacket(loadCUFProfiles.Write()); } diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 7f1782ea1f0..429d3565052 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -616,8 +616,7 @@ void WorldSession::HandlePetRename(WorldPacket& recvData) pet->SetName(name); - if (pet->GetOwner()->GetGroup()) - pet->GetOwner()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME); + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME); pet->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED); diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 3d2f60929fb..2d3090825da 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -281,8 +281,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& cast) caster = _player; } - // check known spell - if (caster->GetTypeId() == TYPEID_PLAYER && !caster->ToPlayer()->HasActiveSpell(spellInfo->Id)) + // check known spell or raid marker spell (which not requires player to know it) + if (caster->GetTypeId() == TYPEID_PLAYER && !caster->ToPlayer()->HasActiveSpell(spellInfo->Id) && !spellInfo->HasEffect(SPELL_EFFECT_CHANGE_RAID_MARKER)) return; // Check possible spell cast overrides diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 7398da99a06..26a3d38635d 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2600,7 +2600,7 @@ void Map::SendObjectUpdates() while (!_updateObjects.empty()) { Object* obj = *_updateObjects.begin(); - ASSERT(obj && obj->IsInWorld()); + ASSERT(obj->IsInWorld()); _updateObjects.erase(_updateObjects.begin()); obj->BuildUpdate(update_players); } @@ -2616,6 +2616,17 @@ void Map::SendObjectUpdates() void Map::DelayedUpdate(const uint32 t_diff) { + for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();) + { + Transport* transport = *_transportsUpdateIter; + ++_transportsUpdateIter; + + if (!transport->IsInWorld()) + continue; + + transport->DelayedUpdate(t_diff); + } + RemoveAllObjectsInRemoveList(); // Don't unload grids if it's battleground, since we may have manually added GOs, creatures, those doesn't load from DB at grid re-load ! diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index a2faa8cc0a0..fb1ac3cc62d 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -699,7 +699,7 @@ class Map : public GridRefManager<NGridType> { auto itr = _guidGenerators.find(high); if (itr == _guidGenerators.end()) - itr = _guidGenerators.insert(std::make_pair(high, std::unique_ptr<ObjectGuidGenerator<high>>(new ObjectGuidGenerator<high>()))).first; + itr = _guidGenerators.insert(std::make_pair(high, Trinity::make_unique<ObjectGuidGenerator<high>>())).first; return *itr->second; } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index ed004c6174d..03cde264734 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -1113,7 +1113,7 @@ enum SpellEffectName SPELL_EFFECT_REPUTATION = 103, SPELL_EFFECT_SUMMON_OBJECT_SLOT1 = 104, SPELL_EFFECT_SUMMON_OBJECT_SLOT2 = 105, - SPELL_EFFECT_SUMMON_OBJECT_SLOT3 = 106, + SPELL_EFFECT_CHANGE_RAID_MARKER = 106, SPELL_EFFECT_SUMMON_OBJECT_SLOT4 = 107, SPELL_EFFECT_DISPEL_MECHANIC = 108, SPELL_EFFECT_RESURRECT_PET = 109, diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp index 0343e92c506..117891140da 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp @@ -162,12 +162,14 @@ bool OPvPCapturePoint::DelCreature(uint32 type) } auto bounds = m_PvP->GetMap()->GetCreatureBySpawnIdStore().equal_range(spawnId); - for (auto itr = bounds.first; itr != bounds.second; ++itr) + for (auto itr = bounds.first; itr != bounds.second;) { + Creature* c = itr->second; + ++itr; // Don't save respawn time - itr->second->SetRespawnTime(0); - itr->second->RemoveCorpse(); - itr->second->AddObjectToRemoveList(); + c->SetRespawnTime(0); + c->RemoveCorpse(); + c->AddObjectToRemoveList(); } TC_LOG_DEBUG("outdoorpvp", "deleting opvp creature type %u", type); @@ -196,11 +198,13 @@ bool OPvPCapturePoint::DelObject(uint32 type) ObjectGuid::LowType spawnId = m_Objects[type]; auto bounds = m_PvP->GetMap()->GetGameObjectBySpawnIdStore().equal_range(spawnId); - for (auto itr = bounds.first; itr != bounds.second; ++itr) + for (auto itr = bounds.first; itr != bounds.second;) { + GameObject* go = itr->second; + ++itr; // Don't save respawn time - itr->second->SetRespawnTime(0); - itr->second->Delete(); + go->SetRespawnTime(0); + go->Delete(); } sObjectMgr->DeleteGOData(spawnId); diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index 15f378e138a..a82652d2f03 100644 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -225,8 +225,12 @@ void PoolGroup<Creature>::Despawn1Object(uint64 guid) if (!map->Instanceable()) { auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(guid); - for (auto itr = creatureBounds.first; itr != creatureBounds.second; ++itr) - itr->second->AddObjectToRemoveList(); + for (auto itr = creatureBounds.first; itr != creatureBounds.second;) + { + Creature* creature = itr->second; + ++itr; + creature->AddObjectToRemoveList(); + } } } } @@ -243,8 +247,12 @@ void PoolGroup<GameObject>::Despawn1Object(uint64 guid) if (!map->Instanceable()) { auto gameobjectBounds = map->GetGameObjectBySpawnIdStore().equal_range(guid); - for (auto itr = gameobjectBounds.first; itr != gameobjectBounds.second; ++itr) - itr->second->AddObjectToRemoveList(); + for (auto itr = gameobjectBounds.first; itr != gameobjectBounds.second;) + { + GameObject* go = itr->second; + ++itr; + go->AddObjectToRemoveList(); + } } } } diff --git a/src/server/game/Server/Packets/ChannelPackets.cpp b/src/server/game/Server/Packets/ChannelPackets.cpp index 5acb018b46f..c8779052c95 100644 --- a/src/server/game/Server/Packets/ChannelPackets.cpp +++ b/src/server/game/Server/Packets/ChannelPackets.cpp @@ -83,6 +83,49 @@ WorldPacket const* WorldPackets::Channel::ChannelNotifyLeft::Write() return &_worldPacket; } +WorldPacket const* WorldPackets::Channel::UserlistAdd::Write() +{ + _worldPacket << AddedUserGUID; + _worldPacket << uint8(ChannelFlags); + _worldPacket << uint8(UserFlags); + + _worldPacket << uint32(ChannelID); + + _worldPacket.WriteBits(ChannelName.length(), 7); + _worldPacket.FlushBits(); + _worldPacket.WriteString(ChannelName); + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Channel::UserlistRemove::Write() +{ + _worldPacket << RemovedUserGUID; + + _worldPacket << uint8(ChannelFlags); + + _worldPacket << uint32(ChannelID); + + _worldPacket.WriteBits(ChannelName.length(), 7); + _worldPacket.FlushBits(); + _worldPacket.WriteString(ChannelName); + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Channel::UserlistUpdate::Write() +{ + _worldPacket << UpdatedUserGUID; + + _worldPacket << uint8(ChannelFlags); + _worldPacket << uint8(UserFlags); + + _worldPacket << uint32(ChannelID); + + _worldPacket.WriteBits(ChannelName.length(), 7); + _worldPacket.FlushBits(); + _worldPacket.WriteString(ChannelName); + return &_worldPacket; +} + void WorldPackets::Channel::ChannelPlayerCommand::Read() { switch (GetOpcode()) diff --git a/src/server/game/Server/Packets/ChannelPackets.h b/src/server/game/Server/Packets/ChannelPackets.h index ca47c76edc9..8dba1e84677 100644 --- a/src/server/game/Server/Packets/ChannelPackets.h +++ b/src/server/game/Server/Packets/ChannelPackets.h @@ -95,6 +95,56 @@ namespace WorldPackets bool Suspended = false; ///< User Leave - false, On Zone Change - true }; + class UserlistAdd final : public ServerPacket + { + public: + UserlistAdd() : ServerPacket(SMSG_USERLIST_ADD, 30) { } + + WorldPacket const* Write() override; + + ObjectGuid AddedUserGUID; + + uint8 ChannelFlags = CHANNEL_FLAG_NONE; + uint8 UserFlags = MEMBER_FLAG_NONE; + + int32 ChannelID = 0; + + std::string ChannelName; + }; + + class UserlistRemove final : public ServerPacket + { + public: + UserlistRemove() : ServerPacket(SMSG_USERLIST_REMOVE, 30) { } + + WorldPacket const* Write() override; + + ObjectGuid RemovedUserGUID; + + uint8 ChannelFlags = CHANNEL_FLAG_NONE; + + uint32 ChannelID = 0; + + std::string ChannelName; + }; + + class UserlistUpdate final : public ServerPacket + { + public: + UserlistUpdate() : ServerPacket(SMSG_USERLIST_UPDATE, 30) { } + + WorldPacket const* Write() override; + + ObjectGuid UpdatedUserGUID; + + uint8 ChannelFlags = CHANNEL_FLAG_NONE; + uint8 UserFlags = MEMBER_FLAG_NONE; + + int32 ChannelID = 0; + + std::string ChannelName; + }; + class ChannelPlayerCommand final : public ClientPacket { public: diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp index 260770e65fe..e3df4f5a15d 100644 --- a/src/server/game/Server/Packets/ChatPackets.cpp +++ b/src/server/game/Server/Packets/ChatPackets.cpp @@ -92,7 +92,7 @@ void WorldPackets::Chat::ChatMessageEmote::Read() Text = _worldPacket.ReadString(len); } -void WorldPackets::Chat::Chat::Initalize(ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string message, +void WorldPackets::Chat::Chat::Initialize(ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string message, uint32 achievementId /*= 0*/, std::string channelName /*= ""*/, LocaleConstant locale /*= DEFAULT_LOCALE*/, std::string addonPrefix /*= ""*/) { // Clear everything because same packet can be used multiple times diff --git a/src/server/game/Server/Packets/ChatPackets.h b/src/server/game/Server/Packets/ChatPackets.h index 5bc55952168..3bfac840ecc 100644 --- a/src/server/game/Server/Packets/ChatPackets.h +++ b/src/server/game/Server/Packets/ChatPackets.h @@ -151,7 +151,7 @@ namespace WorldPackets public: Chat() : ServerPacket(SMSG_CHAT, 100) { } - void Initalize(ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string message, uint32 achievementId = 0, std::string channelName = "", LocaleConstant locale = DEFAULT_LOCALE, std::string addonPrefix = ""); + void Initialize(ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string message, uint32 achievementId = 0, std::string channelName = "", LocaleConstant locale = DEFAULT_LOCALE, std::string addonPrefix = ""); WorldPacket const* Write() override; uint8 SlashCmd = 0; ///< @see enum ChatMsg diff --git a/src/server/game/Server/Packets/GarrisonPackets.cpp b/src/server/game/Server/Packets/GarrisonPackets.cpp index 09097450486..88374e7ce62 100644 --- a/src/server/game/Server/Packets/GarrisonPackets.cpp +++ b/src/server/game/Server/Packets/GarrisonPackets.cpp @@ -60,8 +60,8 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Garrison::GarrisonFollowe data << uint32(follower.CurrentMissionID); data << uint32(follower.AbilityID.size()); data << uint32(follower.FollowerStatus); - if (!follower.AbilityID.empty()) - data.append(follower.AbilityID.data(), follower.AbilityID.size()); + for (GarrAbilityEntry const* ability : follower.AbilityID) + data << uint32(ability->ID); return data; } @@ -155,12 +155,27 @@ WorldPacket const* WorldPackets::Garrison::GarrisonPlaceBuildingResult::Write() { _worldPacket << uint32(Result); _worldPacket << BuildingInfo; - _worldPacket.WriteBit(Active); + _worldPacket.WriteBit(PlayActivationCinematic); _worldPacket.FlushBits(); return &_worldPacket; } +void WorldPackets::Garrison::GarrisonCancelConstruction::Read() +{ + _worldPacket >> NpcGUID; + _worldPacket >> PlotInstanceID; +} + +WorldPacket const* WorldPackets::Garrison::GarrisonBuildingRemoved::Write() +{ + _worldPacket << uint32(Result); + _worldPacket << uint32(GarrPlotInstanceID); + _worldPacket << uint32(GarrBuildingID); + + return &_worldPacket; +} + WorldPacket const* WorldPackets::Garrison::GarrisonLearnBlueprintResult::Write() { _worldPacket << uint32(Result); @@ -208,3 +223,25 @@ WorldPacket const* WorldPackets::Garrison::GarrisonBuildingLandmarks::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::Garrison::GarrisonPlotPlaced::Write() +{ + _worldPacket << *PlotInfo; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Garrison::GarrisonPlotRemoved::Write() +{ + _worldPacket << uint32(GarrPlotInstanceID); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Garrison::GarrisonAddFollowerResult::Write() +{ + _worldPacket << uint32(Result); + _worldPacket << Follower; + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/GarrisonPackets.h b/src/server/game/Server/Packets/GarrisonPackets.h index c632a5d6103..1bb04c7ba95 100644 --- a/src/server/game/Server/Packets/GarrisonPackets.h +++ b/src/server/game/Server/Packets/GarrisonPackets.h @@ -22,6 +22,7 @@ #include "ObjectGuid.h" #include "Position.h" #include "PacketUtilities.h" +#include "DB2Structure.h" namespace WorldPackets { @@ -74,7 +75,7 @@ namespace WorldPackets uint32 Xp = 0; uint32 CurrentBuildingID = 0; uint32 CurrentMissionID = 0; - std::vector<uint32> AbilityID; + std::list<GarrAbilityEntry const*> AbilityID; uint32 FollowerStatus; }; @@ -102,9 +103,9 @@ namespace WorldPackets uint32 FactionIndex = 0; uint32 NumFollowerActivationsRemaining = 0; std::vector<GarrisonPlotInfo*> Plots; - std::vector<GarrisonBuildingInfo*> Buildings; - std::vector<GarrisonFollower*> Followers; - std::vector<GarrisonMission*> Missions; + std::vector<GarrisonBuildingInfo const*> Buildings; + std::vector<GarrisonFollower const*> Followers; + std::vector<GarrisonMission const*> Missions; std::vector<int32> ArchivedMissions; }; @@ -154,7 +155,30 @@ namespace WorldPackets uint32 Result = 0; GarrisonBuildingInfo BuildingInfo; - bool Active = false; + bool PlayActivationCinematic = false; + }; + + class GarrisonCancelConstruction final : public ClientPacket + { + public: + GarrisonCancelConstruction(WorldPacket&& packet) : ClientPacket(CMSG_GARRISON_CANCEL_CONSTRUCTION, std::move(packet)) { } + + void Read() override; + + ObjectGuid NpcGUID; + uint32 PlotInstanceID = 0; + }; + + class GarrisonBuildingRemoved final : public ServerPacket + { + public: + GarrisonBuildingRemoved() : ServerPacket(SMSG_GARRISON_BUILDING_REMOVED, 4 + 4 + 4) { } + + WorldPacket const* Write() override; + + uint32 Result = 0; + uint32 GarrPlotInstanceID = 0; + uint32 GarrBuildingID = 0; }; class GarrisonLearnBlueprintResult final : public ServerPacket @@ -224,6 +248,37 @@ namespace WorldPackets std::vector<GarrisonBuildingLandmark> Landmarks; }; + + class GarrisonPlotPlaced final : public ServerPacket + { + public: + GarrisonPlotPlaced() : ServerPacket(SMSG_GARRISON_PLOT_PLACED) { } + + WorldPacket const* Write() override; + + GarrisonPlotInfo* PlotInfo = nullptr; + }; + + class GarrisonPlotRemoved final : public ServerPacket + { + public: + GarrisonPlotRemoved() : ServerPacket(SMSG_GARRISON_PLOT_REMOVED, 4) { } + + WorldPacket const* Write() override; + + uint32 GarrPlotInstanceID = 0; + }; + + class GarrisonAddFollowerResult final : public ServerPacket + { + public: + GarrisonAddFollowerResult() : ServerPacket(SMSG_GARRISON_ADD_FOLLOWER_RESULT, 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 5 * 4 + 4) { } + + WorldPacket const* Write() override; + + GarrisonFollower Follower; + uint32 Result = 0; + }; } } diff --git a/src/server/game/Server/Packets/InstancePackets.cpp b/src/server/game/Server/Packets/InstancePackets.cpp index 50b2a66a8b8..db5bdcbd9e8 100644 --- a/src/server/game/Server/Packets/InstancePackets.cpp +++ b/src/server/game/Server/Packets/InstancePackets.cpp @@ -30,3 +30,29 @@ WorldPacket const* WorldPackets::Instance::UpdateInstanceOwnership::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::Instance::InstanceInfo::Write() +{ + _worldPacket << int32(LockList.size()); + + for (InstanceLockInfos const& lockInfos : LockList) + _worldPacket << lockInfos; + + return &_worldPacket; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Instance::InstanceLockInfos const& lockInfos) +{ + data << lockInfos.MapID; + data << lockInfos.DifficultyID; + data << lockInfos.InstanceID; + data << lockInfos.TimeRemaining; + data << lockInfos.CompletedMask; + + data.WriteBit(lockInfos.Locked); + data.WriteBit(lockInfos.Extended); + + data.FlushBits(); + + return data; +} diff --git a/src/server/game/Server/Packets/InstancePackets.h b/src/server/game/Server/Packets/InstancePackets.h index 09f6c1efdcb..e38bcb97462 100644 --- a/src/server/game/Server/Packets/InstancePackets.h +++ b/src/server/game/Server/Packets/InstancePackets.h @@ -46,7 +46,31 @@ namespace WorldPackets int32 IOwnInstance = 0; // Used to control whether "Reset all instances" button appears on the UI - Script_CanShowResetInstances() // but it has been deperecated in favor of simply checking group leader, being inside an instance or using dungeon finder }; + + struct InstanceLockInfos + { + uint64 InstanceID = 0u; + uint32 MapID = 0u; + uint32 DifficultyID = 0u; + int32 TimeRemaining = 0; + uint32 CompletedMask = 0u; + + bool Locked = false; + bool Extended = false; + }; + + class InstanceInfo final : public ServerPacket + { + public: + InstanceInfo() : ServerPacket(SMSG_INSTANCE_INFO, 4) { } + + WorldPacket const* Write() override; + + std::vector<InstanceLockInfos> LockList; + }; } } +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Instance::InstanceLockInfos const& lockInfos); + #endif // InstancePackets_h__ diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index a12ff537050..bbd3fcb2ba7 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -451,3 +451,72 @@ WorldPacket const* WorldPackets::Misc::Dismount::Write() return &_worldPacket; } + +void WorldPackets::Misc::SaveCUFProfiles::Read() +{ + uint32 count; + _worldPacket >> count; + + for (uint8 i = 0; i < count && i < MAX_CUF_PROFILES; i++) + { + std::unique_ptr<CUFProfile> cufProfile = Trinity::make_unique<CUFProfile>(); + + uint8 strLen = _worldPacket.ReadBits(7); + + // Bool Options + for (uint8 option = 0; option < CUF_BOOL_OPTIONS_COUNT; option++) + cufProfile->BoolOptions.set(option, _worldPacket.ReadBit()); + + // Other Options + _worldPacket >> cufProfile->FrameHeight; + _worldPacket >> cufProfile->FrameWidth; + + _worldPacket >> cufProfile->SortBy; + _worldPacket >> cufProfile->HealthText; + + _worldPacket >> cufProfile->TopPoint; + _worldPacket >> cufProfile->BottomPoint; + _worldPacket >> cufProfile->LeftPoint; + + _worldPacket >> cufProfile->TopOffset; + _worldPacket >> cufProfile->BottomOffset; + _worldPacket >> cufProfile->LeftOffset; + + cufProfile->ProfileName = _worldPacket.ReadString(strLen); + + CUFProfiles.push_back(std::move(cufProfile)); + } +} + +WorldPacket const* WorldPackets::Misc::LoadCUFProfiles::Write() +{ + _worldPacket << uint32(CUFProfiles.size()); + + for (CUFProfile const* cufProfile : CUFProfiles) + { + _worldPacket.WriteBits(cufProfile->ProfileName.size(), 7); + + // Bool Options + for (uint8 option = 0; option < CUF_BOOL_OPTIONS_COUNT; option++) + _worldPacket.WriteBit(cufProfile->BoolOptions[option]); + + // Other Options + _worldPacket << cufProfile->FrameHeight; + _worldPacket << cufProfile->FrameWidth; + + _worldPacket << cufProfile->SortBy; + _worldPacket << cufProfile->HealthText; + + _worldPacket << cufProfile->TopPoint; + _worldPacket << cufProfile->BottomPoint; + _worldPacket << cufProfile->LeftPoint; + + _worldPacket << cufProfile->TopOffset; + _worldPacket << cufProfile->BottomOffset; + _worldPacket << cufProfile->LeftOffset; + + _worldPacket.WriteString(cufProfile->ProfileName); + } + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index fda0e44990e..93bac0d208b 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -24,6 +24,7 @@ #include "G3D/Vector3.h" #include "Object.h" #include "Unit.h" +#include "Player.h" #include "Weather.h" namespace WorldPackets @@ -642,6 +643,26 @@ namespace WorldPackets ObjectGuid Guid; }; + + class SaveCUFProfiles final : public ClientPacket + { + public: + SaveCUFProfiles(WorldPacket&& packet) : ClientPacket(CMSG_SAVE_CUF_PROFILES, std::move(packet)) { } + + void Read() override; + + std::vector<std::unique_ptr<CUFProfile>> CUFProfiles; + }; + + class LoadCUFProfiles final : public ServerPacket + { + public: + LoadCUFProfiles() : ServerPacket(SMSG_LOAD_CUF_PROFILES, 20) { } + + WorldPacket const* Write() override; + + std::vector<CUFProfile const*> CUFProfiles; + }; } } diff --git a/src/server/game/Server/Packets/PartyPackets.cpp b/src/server/game/Server/Packets/PartyPackets.cpp new file mode 100644 index 00000000000..9696cb6a3fc --- /dev/null +++ b/src/server/game/Server/Packets/PartyPackets.cpp @@ -0,0 +1,716 @@ +/* + * Copyright (C) 2008-2015 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 "PartyPackets.h" + +#include "Player.h" +#include "Pet.h" +#include "Vehicle.h" +#include "SpellAuras.h" +#include "SpellAuraEffects.h" + +WorldPacket const* WorldPackets::Party::PartyCommandResult::Write() +{ + _worldPacket.WriteBits(Name.size(), 9); + + _worldPacket.WriteBits(Command, 4); + _worldPacket.WriteBits(Result, 6); + + _worldPacket << ResultData; + _worldPacket << ResultGUID; + _worldPacket.WriteString(Name); + + _worldPacket.FlushBits(); + + return &_worldPacket; +} + +void WorldPackets::Party::PartyInviteClient::Read() +{ + uint32 targetNameLen, targetRealmLen; + + _worldPacket >> PartyIndex; + _worldPacket >> ProposedRoles; + _worldPacket >> TargetGUID; + _worldPacket >> TargetCfgRealmID; + + targetNameLen = _worldPacket.ReadBits(9); + targetRealmLen = _worldPacket.ReadBits(9); + + TargetName = _worldPacket.ReadString(targetNameLen); + TargetRealm = _worldPacket.ReadString(targetRealmLen); +} + +WorldPacket const* WorldPackets::Party::PartyInvite::Write() +{ + // Order guessed + _worldPacket.WriteBit(CanAccept); + _worldPacket.WriteBit(MightCRZYou); + _worldPacket.WriteBit(MustBeBNetFriend); + _worldPacket.WriteBit(AllowMultipleRoles); + _worldPacket.WriteBit(IsXRealm); + + _worldPacket.WriteBits(InviterName.size(), 6); + + _worldPacket << InviterGUID; + _worldPacket << InviterBNetAccountId; + + _worldPacket << InviterVirtualRealmAddress; + _worldPacket << Unk1; + + _worldPacket.WriteBit(IsLocal); + _worldPacket.WriteBit(Unk2); + + _worldPacket.FlushBits(); + + _worldPacket.WriteBits(InviterRealmNameActual.size(), 8); + _worldPacket.WriteBits(InviterRealmNameNormalized.size(), 8); + _worldPacket.WriteString(InviterRealmNameActual); + _worldPacket.WriteString(InviterRealmNameNormalized); + + _worldPacket << ProposedRoles; + _worldPacket << int32(LfgSlots.size()); + _worldPacket << LfgCompletedMask; + + _worldPacket.WriteString(InviterName); + + for (int32 LfgSlot : LfgSlots) + _worldPacket << LfgSlot; + + return &_worldPacket; +} + +void WorldPackets::Party::PartyInvite::Initialize(Player* const inviter, int32 proposedRoles, bool canAccept) +{ + CanAccept = canAccept; + + InviterName = inviter->GetName(); + InviterGUID = inviter->GetGUID(); + InviterBNetAccountId = inviter->GetSession()->GetAccountGUID(); + + ProposedRoles = proposedRoles; + + std::string realmName = sObjectMgr->GetRealmName(realmHandle.Index); + + InviterVirtualRealmAddress = GetVirtualRealmAddress(); + InviterRealmNameActual = realmName; + InviterRealmNameNormalized = realmName; +} + +void WorldPackets::Party::PartyInviteResponse::Read() +{ + _worldPacket >> PartyIndex; + + Accept = _worldPacket.ReadBit(); + + bool hasRolesDesired = _worldPacket.ReadBit(); + if (hasRolesDesired) + { + RolesDesired = boost::in_place(); + _worldPacket >> *RolesDesired; + } +} + +void WorldPackets::Party::PartyUninvite::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> TargetGUID; + + uint8 reasonLen = _worldPacket.ReadBits(8); + Reason = _worldPacket.ReadString(reasonLen); +} + +WorldPacket const* WorldPackets::Party::GroupDecline::Write() +{ + _worldPacket.WriteBits(Name.length(), 9); + _worldPacket.FlushBits(); + _worldPacket.WriteString(Name); + + return &_worldPacket; +} + +void WorldPackets::Party::RequestPartyMemberStats::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> TargetGUID; +} + +WorldPacket const* WorldPackets::Party::PartyMemberStats::Write() +{ + _worldPacket.WriteBit(ForEnemy); + + _worldPacket << MemberStats; + + return &_worldPacket; +} + +void WorldPackets::Party::SetPartyLeader::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> TargetGUID; +} + +void WorldPackets::Party::SetRole::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> TargetGUID; + _worldPacket >> Role; +} + +WorldPacket const* WorldPackets::Party::RoleChangedInform::Write() +{ + _worldPacket << PartyIndex; + _worldPacket << From; + _worldPacket << ChangedUnit; + _worldPacket << OldRole; + _worldPacket << NewRole; + + return &_worldPacket; +} + +void WorldPackets::Party::LeaveGroup::Read() +{ + _worldPacket >> PartyIndex; +} + +void WorldPackets::Party::SetLootMethod::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> LootMethod; + _worldPacket >> LootMasterGUID; + _worldPacket >> LootThreshold; +} + +void WorldPackets::Party::MinimapPingClient::Read() +{ + _worldPacket >> PositionX; + _worldPacket >> PositionY; + _worldPacket >> PartyIndex; +} + +WorldPacket const* WorldPackets::Party::MinimapPing::Write() +{ + _worldPacket << Sender; + _worldPacket << PositionX; + _worldPacket << PositionY; + + return &_worldPacket; +} + +void WorldPackets::Party::UpdateRaidTarget::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> Target; + _worldPacket >> Symbol; +} + +WorldPacket const* WorldPackets::Party::SendRaidTargetUpdateSingle::Write() +{ + _worldPacket << PartyIndex; + _worldPacket << Symbol; + _worldPacket << Target; + _worldPacket << ChangedBy; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Party::SendRaidTargetUpdateAll::Write() +{ + _worldPacket << PartyIndex; + + _worldPacket << int32(TargetIcons.size()); + + std::map<uint8, ObjectGuid>::const_iterator itr; + for (itr = TargetIcons.begin(); itr != TargetIcons.end(); itr++) + { + _worldPacket << itr->second; + _worldPacket << itr->first; + } + + return &_worldPacket; +} + +void WorldPackets::Party::ConvertRaid::Read() +{ + Raid = _worldPacket.ReadBit(); +} + +void WorldPackets::Party::RequestPartyJoinUpdates::Read() +{ + _worldPacket >> PartyIndex; +} + +void WorldPackets::Party::SetAssistantLeader::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> Target; + Apply = _worldPacket.ReadBit(); +} + +void WorldPackets::Party::DoReadyCheck::Read() +{ + _worldPacket >> PartyIndex; +} + +WorldPacket const* WorldPackets::Party::ReadyCheckStarted::Write() +{ + _worldPacket << PartyIndex; + _worldPacket << PartyGUID; + _worldPacket << InitiatorGUID; + _worldPacket << Duration; + + return &_worldPacket; +} + +void WorldPackets::Party::ReadyCheckResponseClient::Read() +{ + _worldPacket >> PartyIndex; + IsReady = _worldPacket.ReadBit(); +} + +WorldPacket const* WorldPackets::Party::ReadyCheckResponse::Write() +{ + _worldPacket << PartyGUID; + _worldPacket << Player; + + _worldPacket.WriteBit(IsReady); + + _worldPacket.FlushBits(); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Party::ReadyCheckCompleted::Write() +{ + _worldPacket << PartyIndex; + _worldPacket << PartyGUID; + + return &_worldPacket; +} + +void WorldPackets::Party::OptOutOfLoot::Read() +{ + PassOnLoot = _worldPacket.ReadBit(); +} + +void WorldPackets::Party::InitiateRolePoll::Read() +{ + _worldPacket >> PartyIndex; +} + +WorldPacket const* WorldPackets::Party::RolePollInform::Write() +{ + _worldPacket << PartyIndex; + _worldPacket << From; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Party::GroupNewLeader::Write() +{ + _worldPacket << PartyIndex; + _worldPacket.WriteBits(Name.size(), 6); + _worldPacket.WriteString(Name); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Party::PartyUpdate::Write() +{ + _worldPacket << PartyType; + _worldPacket << PartyIndex; + _worldPacket << PartyFlags; + + _worldPacket << MyIndex; + _worldPacket << PartyGUID; + _worldPacket << SequenceNum; + _worldPacket << LeaderGUID; + + _worldPacket << PlayerList; + + _worldPacket.WriteBit(LfgInfos.is_initialized()); + _worldPacket.WriteBit(LootSettings.is_initialized()); + _worldPacket.WriteBit(DifficultySettings.is_initialized()); + + _worldPacket.FlushBits(); + + if (LfgInfos.is_initialized()) + _worldPacket << *LfgInfos; + + if (LootSettings.is_initialized()) + _worldPacket << *LootSettings; + + if (DifficultySettings.is_initialized()) + _worldPacket << *DifficultySettings; + + return &_worldPacket; +} + +void WorldPackets::Party::SetEveryoneIsAssistant::Read() +{ + _worldPacket >> PartyIndex; + EveryoneIsAssistant = _worldPacket.ReadBit(); +} + +void WorldPackets::Party::ChangeSubGroup::Read() +{ + _worldPacket >> TargetGUID; + _worldPacket >> PartyIndex; + _worldPacket >> NewSubGroup; +} + +void WorldPackets::Party::SwapSubGroups::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> FirstTarget; + _worldPacket >> SecondTarget; +} + +void WorldPackets::Party::ClearRaidMarker::Read() +{ + _worldPacket >> MarkerId; +} + +WorldPacket const* WorldPackets::Party::RaidMarkersChanged::Write() +{ + _worldPacket << PartyIndex; + _worldPacket << ActiveMarkers; + + _worldPacket.WriteBits(RaidMarkers.size(), 4); + _worldPacket.FlushBits(); + + for (RaidMarker* raidMarker : RaidMarkers) + { + _worldPacket << raidMarker->TransportGUID; + _worldPacket << raidMarker->Location.GetMapId(); + _worldPacket << raidMarker->Location.PositionXYZStream(); + } + + return &_worldPacket; +} + +void WorldPackets::Party::PartyMemberStats::Initialize(Player const* player) +{ + ForEnemy = false; + + MemberStats.GUID = player->GetGUID(); + + // Status + MemberStats.Status = MEMBER_STATUS_ONLINE; + + if (player->IsPvP()) + MemberStats.Status |= MEMBER_STATUS_PVP; + + if (!player->IsAlive()) + { + if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + MemberStats.Status |= MEMBER_STATUS_GHOST; + else + MemberStats.Status |= MEMBER_STATUS_DEAD; + } + + if (player->IsFFAPvP()) + MemberStats.Status |= MEMBER_STATUS_PVP_FFA; + + if (player->isAFK()) + MemberStats.Status |= MEMBER_STATUS_AFK; + + if (player->isDND()) + MemberStats.Status |= MEMBER_STATUS_DND; + + // Level + MemberStats.Level = player->getLevel(); + + // Health + MemberStats.CurrentHealth = player->GetHealth(); + MemberStats.MaxHealth = player->GetMaxHealth(); + + // Power + MemberStats.PowerType = player->getPowerType(); + MemberStats.CurrentPower = player->GetPower(player->getPowerType()); + MemberStats.MaxPower = player->GetMaxPower(player->getPowerType()); + + // Position + MemberStats.ZoneID = player->GetZoneId(); + MemberStats.PositionX = int16(player->GetPositionX()); + MemberStats.PositionY = int16(player->GetPositionY()); + MemberStats.PositionZ = int16(player->GetPositionZ()); + + // Unk + MemberStats.Unk322 = 0; // Always 0 + MemberStats.Unk704[0] = 1; // Always 1 + MemberStats.Unk704[1] = 0; // Always 0 + MemberStats.Unk200000 = 0; // Always 0 + + MemberStats.Unk2000000 = 0; + MemberStats.Unk4000000 = 0; + + // Vehicle + if (player->GetVehicle() && player->GetVehicle()->GetVehicleInfo()) + MemberStats.VehicleSeat = player->GetVehicle()->GetVehicleInfo()->SeatID[player->m_movementInfo.transport.seat]; + + // Auras + for (uint8 i = 0; i < MAX_AURAS; ++i) + { + if (AuraApplication const* aurApp = player->GetVisibleAura(i)) + { + WorldPackets::Party::GroupAura aura; + + aura.SpellId = aurApp->GetBase()->GetId(); + aura.EffectMask = aurApp->GetEffectMask(); + aura.Scalings = aurApp->GetFlags(); // ?? + + if (aurApp->GetFlags() & AFLAG_SCALABLE) + { + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + float scale = 0.f; + if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) + scale = float(eff->GetAmount()); + aura.EffectScales.push_back(scale); + } + } + + MemberStats.AuraList.push_back(aura); + } + } + + // Phases + std::set<uint32> const& phases = player->GetPhases(); + MemberStats.Phases.PhaseShiftFlags = 0x08 | (phases.size() ? 0x10 : 0); + MemberStats.Phases.PersonalGUID = ObjectGuid::Empty; + for (uint32 phaseId : phases) + { + WorldPackets::Party::GroupPhase phase; + phase.Id = phaseId; + phase.Flags = 1; + MemberStats.Phases.List.push_back(phase); + } + + // Pet + if (player->GetPet()) + { + Pet* pet = player->GetPet(); + + MemberStats.PetStats = boost::in_place(); + + MemberStats.PetStats->GUID = pet->GetGUID(); + MemberStats.PetStats->Name = pet->GetName(); + MemberStats.PetStats->ModelId = pet->GetDisplayId(); + + MemberStats.PetStats->CurrentHealth = pet->GetHealth(); + MemberStats.PetStats->MaxHealth = pet->GetMaxHealth(); + + for (uint8 i = 0; i < MAX_AURAS; ++i) + { + if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) + { + WorldPackets::Party::GroupAura aura; + + aura.SpellId = aurApp->GetBase()->GetId(); + aura.EffectMask = aurApp->GetEffectMask(); + aura.Scalings = aurApp->GetFlags(); // ?? + + if (aurApp->GetFlags() & AFLAG_SCALABLE) + { + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + float scale = 0.f; + if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) + scale = float(eff->GetAmount()); + aura.EffectScales.push_back(scale); + } + } + + MemberStats.PetStats->AuraList.push_back(aura); + } + } + } +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPhase const& phase) +{ + data << phase.Flags; + data << phase.Id; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPhases const& phases) +{ + data << phases.PhaseShiftFlags; + data << int32(phases.List.size()); + data << phases.PersonalGUID; + + for (WorldPackets::Party::GroupPhase const& phase : phases.List) + data << phase; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupAura const& aura) +{ + data << aura.SpellId; + data << aura.Scalings; + data << aura.EffectMask; + + data << int32(aura.EffectScales.size()); + for (float scale : aura.EffectScales) + data << scale; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, std::vector<WorldPackets::Party::GroupAura> const& auraList) +{ + data << int32(auraList.size()); + for (WorldPackets::Party::GroupAura const& aura : auraList) + data << aura; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPetStats const& petStats) +{ + data << petStats.GUID; + + data << petStats.ModelId; + + data << petStats.CurrentHealth; + data << petStats.MaxHealth; + + data << petStats.AuraList; + + data.WriteBits(petStats.Name.size(), 8); + data.FlushBits(); + data.WriteString(petStats.Name); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupMemberStats const& memberStats) +{ + data << memberStats.GUID; + + for (uint8 i = 0; i < 2; i++) + data << memberStats.Unk704[i]; + + data << memberStats.Status; + + data << memberStats.PowerType; + + data << memberStats.Unk322; + + data << memberStats.CurrentHealth; + data << memberStats.MaxHealth; + + data << memberStats.CurrentPower; + data << memberStats.MaxPower; + + data << memberStats.Level; + + data << memberStats.Unk200000; + + data << memberStats.ZoneID; + + data << memberStats.Unk2000000; + data << memberStats.Unk4000000; + + data << memberStats.PositionX; + data << memberStats.PositionY; + data << memberStats.PositionZ; + + data << memberStats.VehicleSeat; + + data << int32(memberStats.AuraList.size()); + + data << memberStats.Phases; + + for (WorldPackets::Party::GroupAura const& aura : memberStats.AuraList) + data << aura; + + data.WriteBit(memberStats.PetStats.is_initialized()); + data.FlushBits(); + + if (memberStats.PetStats.is_initialized()) + data << *memberStats.PetStats; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, std::vector<WorldPackets::Party::GroupPlayerInfos> const& playerList) +{ + data << int32(playerList.size()); + + for (WorldPackets::Party::GroupPlayerInfos const& playerInfos : playerList) + data << playerInfos; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPlayerInfos const& playerInfos) +{ + data.WriteBits(playerInfos.Name.size(), 6); + data.FlushBits(); + + data << playerInfos.GUID; + data << playerInfos.Status; + data << playerInfos.Subgroup; + data << playerInfos.Flags; + data << playerInfos.RolesAssigned; + data << playerInfos.Class; + + data.WriteString(playerInfos.Name); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupLfgInfos const& lfgInfos) +{ + data << lfgInfos.MyFlags; + data << lfgInfos.Slot; + data << lfgInfos.MyRandomSlot; + data << lfgInfos.MyPartialClear; + data << lfgInfos.MyGearDiff; + data << lfgInfos.MyStrangerCount; + data << lfgInfos.MyKickVoteCount; + data << lfgInfos.BootCount; + + data.WriteBit(lfgInfos.Aborted); + data.WriteBit(lfgInfos.MyFirstReward); + data.FlushBits(); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupLootSettings const& lootSettings) +{ + data << lootSettings.Method; + data << lootSettings.LootMaster; + data << lootSettings.Threshold; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupDifficultySettings const& difficultySettings) +{ + data << difficultySettings.DungeonDifficultyID; + data << difficultySettings.RaidDifficultyID; + data << difficultySettings.LegacyRaidDifficultyID; + + return data; +} diff --git a/src/server/game/Server/Packets/PartyPackets.h b/src/server/game/Server/Packets/PartyPackets.h new file mode 100644 index 00000000000..ed3eed60ef4 --- /dev/null +++ b/src/server/game/Server/Packets/PartyPackets.h @@ -0,0 +1,616 @@ +/* + * Copyright (C) 2008-2015 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 PartyPackets_h__ +#define PartyPackets_h__ + +#include "Packet.h" +#include "ObjectGuid.h" +#include "Group.h" + +namespace WorldPackets +{ + namespace Party + { + class PartyCommandResult final : public ServerPacket + { + public: + PartyCommandResult() : ServerPacket(SMSG_PARTY_COMMAND_RESULT, 23) { } + + WorldPacket const* Write() override; + + std::string Name; + uint8 Command = 0u; + uint8 Result = 0u; + uint32 ResultData = 0u; + ObjectGuid ResultGUID; + }; + + class PartyInviteClient final : public ClientPacket + { + public: + PartyInviteClient(WorldPacket&& packet) : ClientPacket(CMSG_PARTY_INVITE, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + int32 ProposedRoles = 0; + int32 TargetCfgRealmID = 0; + std::string TargetName; + std::string TargetRealm; + ObjectGuid TargetGUID; + }; + + class PartyInvite final : public ServerPacket + { + public: + PartyInvite() : ServerPacket(SMSG_PARTY_INVITE, 55) { } + + WorldPacket const* Write() override; + void Initialize(Player* const inviter, int32 proposedRoles, bool canAccept); + + bool MightCRZYou = false; + bool MustBeBNetFriend = false; + bool AllowMultipleRoles = false; + bool Unk2 = false; + int16 Unk1 = 0; + + bool CanAccept = false; + + // Inviter + ObjectGuid InviterGUID; + ObjectGuid InviterBNetAccountId; + std::string InviterName; + + // Realm + bool IsXRealm = false; + bool IsLocal = true; + uint32 InviterVirtualRealmAddress = 0u; + std::string InviterRealmNameActual; + std::string InviterRealmNameNormalized; + + // Lfg + int32 ProposedRoles = 0; + int32 LfgCompletedMask = 0; + std::vector<int32> LfgSlots; + }; + + class PartyInviteResponse final : public ClientPacket + { + public: + PartyInviteResponse(WorldPacket&& packet) : ClientPacket(CMSG_PARTY_INVITE_RESPONSE, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + bool Accept = false; + Optional<int32> RolesDesired; + }; + + class PartyUninvite final : public ClientPacket + { + public: + PartyUninvite(WorldPacket&& packet) : ClientPacket(CMSG_PARTY_UNINVITE, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + ObjectGuid TargetGUID; + std::string Reason; + }; + + class GroupDecline final : public ServerPacket + { + public: + GroupDecline(std::string const& name) : ServerPacket(SMSG_GROUP_DECLINE, 2 + name.size()), Name(name) { } + + WorldPacket const* Write() override; + + std::string Name; + }; + + class RequestPartyMemberStats final : public ClientPacket + { + public: + RequestPartyMemberStats(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_PARTY_MEMBER_STATS, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + ObjectGuid TargetGUID; + }; + + struct GroupPhase + { + uint16 Flags = 0u; + uint16 Id = 0u; + }; + + struct GroupPhases + { + int32 PhaseShiftFlags = 0; + ObjectGuid PersonalGUID; + std::vector<GroupPhase> List; + }; + + struct GroupAura + { + uint32 SpellId = 0u; + uint8 Scalings = 0; + uint32 EffectMask = 0u; + std::vector<float> EffectScales; + }; + + struct GroupPetStats + { + ObjectGuid GUID; + std::string Name; + int16 ModelId = 0; + + int32 CurrentHealth = 0; + int32 MaxHealth = 0; + + std::vector<GroupAura> AuraList; + }; + + struct GroupMemberStats + { + ObjectGuid GUID; + int16 Level = 0; + int16 Status = 0; + + int32 CurrentHealth = 0; + int32 MaxHealth; + + uint8 PowerType = 0u; + int16 CurrentPower = 0; + int16 MaxPower = 0; + + int16 ZoneID = 0; + int16 PositionX = 0; + int16 PositionY = 0; + int16 PositionZ = 0; + + int32 VehicleSeat = 0; + + GroupPhases Phases; + std::vector<GroupAura> AuraList; + Optional<GroupPetStats> PetStats; + + int16 Unk322 = 0; + int16 Unk200000 = 0; + int16 Unk2000000 = 0; + int32 Unk4000000 = 0; + int8 Unk704[2]; + }; + + class PartyMemberStats final : public ServerPacket + { + public: + PartyMemberStats() : ServerPacket(SMSG_PARTY_MEMBER_STATE, 80) { } + + WorldPacket const* Write() override; + void Initialize(Player const* player); + + GroupMemberStats MemberStats; + bool ForEnemy = false; + }; + + class SetPartyLeader final : public ClientPacket + { + public: + SetPartyLeader(WorldPacket&& packet) : ClientPacket(CMSG_SET_PARTY_LEADER, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + ObjectGuid TargetGUID; + }; + + class SetRole final : public ClientPacket + { + public: + SetRole(WorldPacket&& packet) : ClientPacket(CMSG_SET_ROLE, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + ObjectGuid TargetGUID; + int32 Role = 0; + }; + + class RoleChangedInform final : public ServerPacket + { + public: + RoleChangedInform() : ServerPacket(SMSG_ROLE_CHANGED_INFORM, 41) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + ObjectGuid From; + ObjectGuid ChangedUnit; + int32 OldRole = 0; + int32 NewRole = 0; + }; + + class LeaveGroup final : public ClientPacket + { + public: + LeaveGroup(WorldPacket&& packet) : ClientPacket(CMSG_LEAVE_GROUP, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + }; + + class SetLootMethod final : public ClientPacket + { + public: + SetLootMethod(WorldPacket&& packet) : ClientPacket(CMSG_SET_LOOT_METHOD, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + ObjectGuid LootMasterGUID; + uint8 LootMethod = 0u; + uint32 LootThreshold = 0u; + }; + + class MinimapPingClient final : public ClientPacket + { + public: + MinimapPingClient(WorldPacket&& packet) : ClientPacket(CMSG_MINIMAP_PING, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + float PositionX = 0.f; + float PositionY = 0.f; + }; + + class MinimapPing final : public ServerPacket + { + public: + MinimapPing() : ServerPacket(SMSG_MINIMAP_PING, 24) { } + + WorldPacket const* Write() override; + + ObjectGuid Sender; + float PositionX = 0.f; + float PositionY = 0.f; + }; + + class UpdateRaidTarget final : public ClientPacket + { + public: + UpdateRaidTarget(WorldPacket&& packet) : ClientPacket(CMSG_UPDATE_RAID_TARGET, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + ObjectGuid Target; + int8 Symbol = 0; + }; + + class SendRaidTargetUpdateSingle final : public ServerPacket + { + public: + SendRaidTargetUpdateSingle() : ServerPacket(SMSG_SEND_RAID_TARGET_UPDATE_SINGLE, 34) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + ObjectGuid Target; + ObjectGuid ChangedBy; + int8 Symbol = 0; + }; + + class SendRaidTargetUpdateAll final : public ServerPacket + { + public: + SendRaidTargetUpdateAll() : ServerPacket(SMSG_SEND_RAID_TARGET_UPDATE_ALL, 1 + TARGET_ICONS_COUNT * (1 + 16)) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + std::map<uint8, ObjectGuid> TargetIcons; + }; + + class ConvertRaid final : public ClientPacket + { + public: + ConvertRaid(WorldPacket&& packet) : ClientPacket(CMSG_CONVERT_RAID, std::move(packet)) { } + + void Read() override; + + bool Raid = false; + }; + + class RequestPartyJoinUpdates final : public ClientPacket + { + public: + RequestPartyJoinUpdates(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_PARTY_JOIN_UPDATES, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + }; + + class SetAssistantLeader final : public ClientPacket + { + public: + SetAssistantLeader(WorldPacket&& packet) : ClientPacket(CMSG_SET_ASSISTANT_LEADER, std::move(packet)) { } + + void Read() override; + + ObjectGuid Target; + int8 PartyIndex = 0; + bool Apply = false; + }; + + class DoReadyCheck final : public ClientPacket + { + public: + DoReadyCheck(WorldPacket&& packet) : ClientPacket(CMSG_DO_READY_CHECK, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + }; + + class ReadyCheckStarted final : public ServerPacket + { + public: + ReadyCheckStarted() : ServerPacket(SMSG_READY_CHECK_STARTED, 37) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + ObjectGuid PartyGUID; + ObjectGuid InitiatorGUID; + uint32 Duration = 0u; + }; + + class ReadyCheckResponseClient final : public ClientPacket + { + public: + ReadyCheckResponseClient(WorldPacket&& packet) : ClientPacket(CMSG_READY_CHECK_RESPONSE, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + bool IsReady = false; + }; + + class ReadyCheckResponse final : public ServerPacket + { + public: + ReadyCheckResponse() : ServerPacket(SMSG_READY_CHECK_RESPONSE, 19) { } + + WorldPacket const* Write() override; + + ObjectGuid PartyGUID; + ObjectGuid Player; + bool IsReady = false; + }; + + class ReadyCheckCompleted final : public ServerPacket + { + public: + ReadyCheckCompleted() : ServerPacket(SMSG_READY_CHECK_COMPLETED, 17) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + ObjectGuid PartyGUID; + }; + + class RequestRaidInfo final : public ClientPacket + { + public: + RequestRaidInfo(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_RAID_INFO, std::move(packet)) { } + + void Read() override { } + }; + + class OptOutOfLoot final : public ClientPacket + { + public: + OptOutOfLoot(WorldPacket&& packet) : ClientPacket(CMSG_OPT_OUT_OF_LOOT, std::move(packet)) { } + + void Read() override; + + bool PassOnLoot = false; + }; + + class InitiateRolePoll final : public ClientPacket + { + public: + InitiateRolePoll(WorldPacket&& packet) : ClientPacket(CMSG_INITIATE_ROLE_POLL, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + }; + + class RolePollInform final : public ServerPacket + { + public: + RolePollInform() : ServerPacket(SMSG_ROLE_POLL_INFORM, 17) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + ObjectGuid From; + }; + + class GroupNewLeader final : public ServerPacket + { + public: + GroupNewLeader() : ServerPacket(SMSG_GROUP_NEW_LEADER, 14) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + std::string Name; + }; + + struct GroupPlayerInfos + { + ObjectGuid GUID; + std::string Name; + uint8 Class = 0; + + uint8 Status = 0u; + uint8 Subgroup = 0u; + uint8 Flags = 0u; + uint8 RolesAssigned = 0u; + }; + + struct GroupLfgInfos + { + int32 Slot = 0u; + int8 BootCount = 0; + + bool Aborted = false; + + int32 MyRandomSlot = 0; + uint8 MyFlags = 0u; + uint8 MyPartialClear = 0u; + float MyGearDiff = 0.f; + + int8 MyStrangerCount = 0; + int8 MyKickVoteCount = 0; + + bool MyFirstReward = false; + }; + + struct GroupLootSettings + { + uint8 Method = 0u; + ObjectGuid LootMaster; + uint8 Threshold = 0u; + }; + + struct GroupDifficultySettings + { + uint32 DungeonDifficultyID = 0u; + uint32 RaidDifficultyID = 0u; + uint32 LegacyRaidDifficultyID = 0u; + }; + + class PartyUpdate final : public ServerPacket + { + public: + PartyUpdate() : ServerPacket(SMSG_PARTY_UPDATE, 200) { } + + WorldPacket const* Write() override; + + int8 PartyFlags = 0; + int8 PartyIndex = 0; + int8 PartyType = 0; + + ObjectGuid PartyGUID; + ObjectGuid LeaderGUID; + + int32 MyIndex = 0; + int32 SequenceNum = 0; + + std::vector<GroupPlayerInfos> PlayerList; + + Optional<GroupLfgInfos> LfgInfos; + Optional<GroupLootSettings> LootSettings; + Optional<GroupDifficultySettings> DifficultySettings; + }; + + class SetEveryoneIsAssistant final : public ClientPacket + { + public: + SetEveryoneIsAssistant(WorldPacket&& packet) : ClientPacket(CMSG_SET_EVERYONE_IS_ASSISTANT, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + bool EveryoneIsAssistant = false; + }; + + class ChangeSubGroup final : public ClientPacket + { + public: + ChangeSubGroup(WorldPacket&& packet) : ClientPacket(CMSG_CHANGE_SUB_GROUP, std::move(packet)) { } + + void Read() override; + + ObjectGuid TargetGUID; + int8 PartyIndex = 0; + uint8 NewSubGroup = 0u; + }; + + class SwapSubGroups final : public ClientPacket + { + public: + SwapSubGroups(WorldPacket&& packet) : ClientPacket(CMSG_SWAP_SUB_GROUPS, std::move(packet)) { } + + void Read() override; + + ObjectGuid FirstTarget; + ObjectGuid SecondTarget; + int8 PartyIndex = 0; + }; + + class ClearRaidMarker final : public ClientPacket + { + public: + ClearRaidMarker(WorldPacket&& packet) : ClientPacket(CMSG_CLEAR_RAID_MARKER, std::move(packet)) { } + + void Read() override; + + uint8 MarkerId = 0u; + }; + + class RaidMarkersChanged final : public ServerPacket + { + public: + RaidMarkersChanged() : ServerPacket(SMSG_RAID_MARKERS_CHANGED, 6) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + uint32 ActiveMarkers = 0u; + + std::vector<RaidMarker*> RaidMarkers; + }; + } +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPhase const& phase); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPhases const& phases); + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupAura const& aura); +ByteBuffer& operator<<(ByteBuffer& data, std::vector<WorldPackets::Party::GroupAura> const& auraList); + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPetStats const& petStats); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupMemberStats const& memberStats); + +ByteBuffer& operator<<(ByteBuffer& data, std::vector<WorldPackets::Party::GroupPlayerInfos> const& playerList); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPlayerInfos const& playerInfos); + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupLfgInfos const& lfgInfos); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupLootSettings const& lootSettings); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupDifficultySettings const& difficultySettings); + +#endif // PartyPackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 6efac892cf9..9b30be91ee3 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -33,6 +33,7 @@ #include "Packets/GameObjectPackets.h" #include "Packets/GarrisonPackets.h" #include "Packets/GuildPackets.h" +#include "Packets/PartyPackets.h" #include "Packets/InspectPackets.h" #include "Packets/InstancePackets.h" #include "Packets/ItemPackets.h" @@ -259,7 +260,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_CHALLENGE_MODE_REQUEST_MAP_STATS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_CHANGE_BAG_SLOT_FLAG, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_CHANGE_MONUMENT_APPEARANCE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANGE_SUB_GROUP, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupChangeSubGroupOpcode ); + DEFINE_HANDLER(CMSG_CHANGE_SUB_GROUP, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::ChangeSubGroup, &WorldSession::HandleChangeSubGroupOpcode); DEFINE_HANDLER(CMSG_CHARACTER_RENAME_REQUEST, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharacterRenameRequest, &WorldSession::HandleCharRenameOpcode); DEFINE_HANDLER(CMSG_CHAR_CUSTOMIZE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharCustomize, &WorldSession::HandleCharCustomizeOpcode); DEFINE_HANDLER(CMSG_CHAR_DELETE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharDelete, &WorldSession::HandleCharDeleteOpcode); @@ -315,7 +316,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_CHECK_RAF_EMAIL_ENABLED, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_CHECK_WOW_TOKEN_VETERAN_ELIGIBILITY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_CHOICE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_HANDLER(CMSG_CLEAR_RAID_MARKER, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); + DEFINE_HANDLER(CMSG_CLEAR_RAID_MARKER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::ClearRaidMarker, &WorldSession::HandleClearRaidMarker); DEFINE_HANDLER(CMSG_CLEAR_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::ClearTradeItem, &WorldSession::HandleClearTradeItemOpcode); DEFINE_HANDLER(CMSG_CLIENT_PORT_GRAVEYARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::PortGraveyard, &WorldSession::HandlePortGraveyard); DEFINE_HANDLER(CMSG_CLOSE_INTERACTION, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -331,7 +332,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_COMPLETE_MOVIE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_CONFIRM_RESPEC_WIPE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleConfirmRespecWipeOpcode ); DEFINE_HANDLER(CMSG_CONNECT_TO_FAILED, STATUS_NEVER, PROCESS_INPLACE, WorldPacket, &WorldSession::Handle_EarlyProccess); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CONVERT_RAID, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupRaidConvertOpcode ); + DEFINE_HANDLER(CMSG_CONVERT_RAID, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::ConvertRaid, &WorldSession::HandleConvertRaidOpcode); DEFINE_HANDLER(CMSG_CREATE_CHARACTER, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CreateCharacter, &WorldSession::HandleCharCreateOpcode); DEFINE_HANDLER(CMSG_CREATE_SHIPMENT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_DB_QUERY_BULK, STATUS_AUTHED, PROCESS_INPLACE, WorldPackets::Query::DBQueryBulk, &WorldSession::HandleDBQueryBulk); @@ -357,7 +358,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_DISCARDED_TIME_SYNC_ACKS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_DISMISS_CRITTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissCritter ); DEFINE_HANDLER(CMSG_DO_MASTER_LOOT_ROLL, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_DO_READY_CHECK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckOpcode ); + DEFINE_HANDLER(CMSG_DO_READY_CHECK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::DoReadyCheck, &WorldSession::HandleDoReadyCheckOpcode); DEFINE_HANDLER(CMSG_DUEL_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Duel::DuelResponse, &WorldSession::HandleDuelResponseOpcode); DEFINE_HANDLER(CMSG_EJECT_PASSENGER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Vehicle::EjectPassenger, &WorldSession::HandleEjectPassenger); DEFINE_HANDLER(CMSG_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::EmoteClient, &WorldSession::HandleEmoteOpcode); @@ -370,7 +371,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_GAME_OBJ_REPORT_USE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::GameObject::GameObjReportUse, &WorldSession::HandleGameobjectReportUse); DEFINE_HANDLER(CMSG_GAME_OBJ_USE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::GameObject::GameObjUse, &WorldSession::HandleGameObjectUseOpcode); DEFINE_HANDLER(CMSG_GARRISON_ASSIGN_FOLLOWER_TO_BUILDING, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_HANDLER(CMSG_GARRISON_CANCEL_CONSTRUCTION, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); + DEFINE_HANDLER(CMSG_GARRISON_CANCEL_CONSTRUCTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Garrison::GarrisonCancelConstruction, &WorldSession::HandleGarrisonCancelConstruction); DEFINE_HANDLER(CMSG_GARRISON_CHECK_UPGRADEABLE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_GARRISON_COMPLETE_MISSION, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_GARRISON_GENERATE_RECRUITS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -458,7 +459,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_HEARTH_AND_RESURRECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battleground::HearthAndResurrect, &WorldSession::HandleHearthAndResurrect); DEFINE_HANDLER(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::IgnoreTrade, &WorldSession::HandleIgnoreTradeOpcode); DEFINE_HANDLER(CMSG_INCREASE_CAST_TIME_FOR_SPELL, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_INITIATE_ROLE_POLL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRolePollBeginOpcode); + DEFINE_HANDLER(CMSG_INITIATE_ROLE_POLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::InitiateRolePoll, &WorldSession::HandleInitiateRolePoll); DEFINE_HANDLER(CMSG_INITIATE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::InitiateTrade, &WorldSession::HandleInitiateTradeOpcode); DEFINE_HANDLER(CMSG_INSPECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::Inspect, &WorldSession::HandleInspectOpcode); DEFINE_HANDLER(CMSG_INSPECT_PVP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::InspectPVPRequest, &WorldSession::HandleInspectPVP); @@ -471,7 +472,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_KEYBOUND_OVERRIDE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_LEARN_PET_SPECIALIZATION_GROUP, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_LEARN_TALENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Talent::LearnTalents, &WorldSession::HandleLearnTalentsOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_LEAVE_GROUP, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupDisbandOpcode ); + DEFINE_HANDLER(CMSG_LEAVE_GROUP, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::LeaveGroup, &WorldSession::HandleLeaveGroupOpcode); DEFINE_HANDLER(CMSG_LEAVE_PET_BATTLE_QUEUE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_LFG_LIST_APPLY_TO_GROUP, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_LFG_LIST_CANCEL_APPLICATION, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -514,7 +515,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_MAIL_TAKE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailTakeItem, &WorldSession::HandleMailTakeItem); DEFINE_HANDLER(CMSG_MAIL_TAKE_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailTakeMoney, &WorldSession::HandleMailTakeMoney); DEFINE_OPCODE_HANDLER_OLD(CMSG_MASTER_LOOT_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMasterGiveOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MINIMAP_PING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMinimapPingOpcode ); + DEFINE_HANDLER(CMSG_MINIMAP_PING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::MinimapPingClient, &WorldSession::HandleMinimapPingOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_MISSILE_TRAJECTORY_COLLISION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateProjectilePosition ); DEFINE_HANDLER(CMSG_MOUNT_SET_FAVORITE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOUNT_SPECIAL_ANIM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode ); @@ -590,10 +591,10 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_OPEN_MISSION_NPC, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_OPEN_SHIPMENT_NPC, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_OPEN_TRADESKILL_NPC, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_OPT_OUT_OF_LOOT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOptOutOfLootOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_INVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteResponseOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_UNINVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteOpcode ); + DEFINE_HANDLER(CMSG_OPT_OUT_OF_LOOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::OptOutOfLoot, &WorldSession::HandleOptOutOfLootOpcode); + DEFINE_HANDLER(CMSG_PARTY_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::PartyInviteClient, &WorldSession::HandlePartyInviteOpcode); + DEFINE_HANDLER(CMSG_PARTY_INVITE_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::PartyInviteResponse, &WorldSession::HandlePartyInviteResponseOpcode); + DEFINE_HANDLER(CMSG_PARTY_UNINVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::PartyUninvite, &WorldSession::HandlePartyUninviteOpcode); DEFINE_HANDLER(CMSG_PETITION_BUY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionBuy, &WorldSession::HandlePetitionBuy); DEFINE_HANDLER(CMSG_PETITION_RENAME_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionRenameGuild, &WorldSession::HandlePetitionRenameGuild); DEFINE_HANDLER(CMSG_PETITION_SHOW_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowList, &WorldSession::HandlePetitionShowList); @@ -655,7 +656,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_PUSH_RESULT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult ); DEFINE_HANDLER(CMSG_QUEUED_MESSAGES_END, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_RANDOM_ROLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::RandomRollClient, &WorldSession::HandleRandomRollOpcode); - DEFINE_HANDLER(CMSG_READY_CHECK_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); + DEFINE_HANDLER(CMSG_READY_CHECK_RESPONSE, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::ReadyCheckResponseClient, &WorldSession::HandleReadyCheckResponseOpcode); DEFINE_HANDLER(CMSG_READ_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::ReadItem, &WorldSession::HandleReadItem); DEFINE_HANDLER(CMSG_RECLAIM_CORPSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::ReclaimCorpse, &WorldSession::HandleReclaimCorpse); DEFINE_HANDLER(CMSG_RECRUIT_A_FRIEND, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -676,12 +677,12 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_REQUEST_GUILD_REWARDS_LIST, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Guild::RequestGuildRewardsList, &WorldSession::HandleRequestGuildRewardsList); DEFINE_HANDLER(CMSG_REQUEST_HONOR_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::RequestHonorStats, &WorldSession::HandleRequestHonorStatsOpcode); DEFINE_HANDLER(CMSG_REQUEST_LFG_LIST_BLACKLIST, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PARTY_JOIN_UPDATES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupRequestJoinUpdates); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode); + DEFINE_HANDLER(CMSG_REQUEST_PARTY_JOIN_UPDATES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::RequestPartyJoinUpdates, &WorldSession::HandleRequestPartyJoinUpdates); + DEFINE_HANDLER(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::RequestPartyMemberStats, &WorldSession::HandleRequestPartyMemberStatsOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PET_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode ); DEFINE_HANDLER(CMSG_REQUEST_PLAYED_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::RequestPlayedTime, &WorldSession::HandlePlayedTime); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PVP_REWARDS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestPvpReward ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_RAID_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestRaidInfoOpcode ); + DEFINE_HANDLER(CMSG_REQUEST_RAID_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::RequestRaidInfo, &WorldSession::HandleRequestRaidInfoOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_RATED_BATTLEFIELD_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestRatedBattlefieldInfo); DEFINE_HANDLER(CMSG_REQUEST_RESEARCH_HISTORY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_STABLED_PETS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleListStabledPetsOpcode ); @@ -695,7 +696,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_RESURRECT_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::ResurrectResponse, &WorldSession::HandleResurrectResponse); DEFINE_HANDLER(CMSG_REVERT_MONUMENT_APPEARANCE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_RIDE_VEHICLE_INTERACT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Vehicle::RideVehicleInteract, &WorldSession::HandleRideVehicleInteract); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SAVE_CUF_PROFILES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleSaveCUFProfiles ); + DEFINE_HANDLER(CMSG_SAVE_CUF_PROFILES, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::SaveCUFProfiles, &WorldSession::HandleSaveCUFProfiles); DEFINE_HANDLER(CMSG_SAVE_EQUIPMENT_SET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::EquipmentSet::SaveEquipmentSet, &WorldSession::HandleEquipmentSetSave); DEFINE_HANDLER(CMSG_SAVE_GUILD_EMBLEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::SaveGuildEmblem, &WorldSession::HandleSaveGuildEmblem); DEFINE_HANDLER(CMSG_SCENE_PLAYBACK_CANCELED, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Scenes::ScenePlaybackCanceled, &WorldSession::HandleScenePlaybackCanceled); @@ -716,7 +717,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_SET_ACTIVE_MOVER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Movement::SetActiveMover, &WorldSession::HandleSetActiveMoverOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ACTIVE_VOICE_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveVoiceChannel ); DEFINE_HANDLER(CMSG_SET_ADVANCED_COMBAT_LOGGING, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ASSISTANT_LEADER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupAssistantLeaderOpcode); + DEFINE_HANDLER(CMSG_SET_ASSISTANT_LEADER, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SetAssistantLeader, &WorldSession::HandleSetAssistantLeaderOpcode); DEFINE_HANDLER(CMSG_SET_BACKPACK_AUTOSORT_DISABLED, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_BANK_AUTOSORT_DISABLED, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_BANK_BAG_SLOT_FLAG, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -724,22 +725,22 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_SET_CURRENCY_FLAGS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_DIFFICULTY_ID, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_DUNGEON_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetDungeonDifficulty, &WorldSession::HandleSetDungeonDifficultyOpcode); - DEFINE_HANDLER(CMSG_SET_EVERYONE_IS_ASSISTANT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); + DEFINE_HANDLER(CMSG_SET_EVERYONE_IS_ASSISTANT, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SetEveryoneIsAssistant, &WorldSession::HandleSetEveryoneIsAssistant); DEFINE_HANDLER(CMSG_SET_FACTION_AT_WAR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::SetFactionAtWar, &WorldSession::HandleSetFactionAtWar); DEFINE_HANDLER(CMSG_SET_FACTION_INACTIVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::SetFactionInactive, &WorldSession::HandleSetFactionInactiveOpcode); DEFINE_HANDLER(CMSG_SET_FACTION_NOT_AT_WAR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::SetFactionNotAtWar, &WorldSession::HandleSetFactionNotAtWar); DEFINE_HANDLER(CMSG_SET_INSERT_ITEMS_LEFT_TO_RIGHT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_LFG_BONUS_FACTION_ID, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_LOOT_METHOD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMethodOpcode ); + DEFINE_HANDLER(CMSG_SET_LOOT_METHOD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::SetLootMethod, &WorldSession::HandleSetLootMethodOpcode); DEFINE_HANDLER(CMSG_SET_LOOT_SPECIALIZATION, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PARTY_ASSIGNMENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePartyAssignmentOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PARTY_LEADER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupSetLeaderOpcode ); + DEFINE_HANDLER(CMSG_SET_PARTY_LEADER, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SetPartyLeader, &WorldSession::HandleSetPartyLeaderOpcode); DEFINE_HANDLER(CMSG_SET_PET_SLOT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PLAYER_DECLINED_NAMES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetPlayerDeclinedNames ); DEFINE_HANDLER(CMSG_SET_PREFERRED_CEMETERY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_PVP, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_RAID_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetRaidDifficulty, &WorldSession::HandleSetRaidDifficultyOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ROLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupSetRolesOpcode ); + DEFINE_HANDLER(CMSG_SET_ROLE, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SetRole, &WorldSession::HandleSetRoleOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SAVED_INSTANCE_EXTEND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetSavedInstanceExtend ); DEFINE_HANDLER(CMSG_SET_SELECTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetSelection, &WorldSession::HandleSetSelectionOpcode); DEFINE_HANDLER(CMSG_SET_SHEATHED, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Combat::SetSheathed, &WorldSession::HandleSetSheathedOpcode); @@ -775,7 +776,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_SUSPEND_TOKEN_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SWAP_INV_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SwapInvItem, &WorldSession::HandleSwapInvItemOpcode); DEFINE_HANDLER(CMSG_SWAP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SwapItem, &WorldSession::HandleSwapItem); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SWAP_SUB_GROUPS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupSwapSubGroupOpcode ); + DEFINE_HANDLER(CMSG_SWAP_SUB_GROUPS, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SwapSubGroups, &WorldSession::HandleSwapSubGroupsOpcode); DEFINE_HANDLER(CMSG_SWAP_VOID_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::VoidStorage::SwapVoidItem, &WorldSession::HandleVoidSwapItem); DEFINE_HANDLER(CMSG_TABARD_VENDOR_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleTabardVendorActivateOpcode); DEFINE_HANDLER(CMSG_TALK_TO_GOSSIP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleGossipHelloOpcode); @@ -809,7 +810,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_UPDATE_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::ClientConfig::UserClientUpdateAccountData, &WorldSession::HandleUpdateAccountData); DEFINE_HANDLER(CMSG_UPDATE_CLIENT_SETTINGS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_MISSILE_TRAJECTORY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_RAID_TARGET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidTargetUpdateOpcode ); + DEFINE_HANDLER(CMSG_UPDATE_RAID_TARGET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::UpdateRaidTarget, &WorldSession::HandleUpdateRaidTargetOpcode); DEFINE_HANDLER(CMSG_UPDATE_WOW_TOKEN_AUCTIONABLE_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Token::UpdateListedAuctionableTokens, &WorldSession::HandleUpdateListedAuctionableTokens); DEFINE_HANDLER(CMSG_UPDATE_WOW_TOKEN_COUNT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_UPGRADE_GARRISON, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -1109,12 +1110,12 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_SPEED_SET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_TIME_SET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_TIME_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_ADD_FOLLOWER_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_ADD_FOLLOWER_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_ADD_MISSION_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_ASSIGN_FOLLOWER_TO_BUILDING_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_ACTIVATED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_LANDMARKS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_REMOVED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_BUILDING_SET_ACTIVE_SPECIALIZATION_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_COMPLETE_MISSION_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_CREATE_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); @@ -1134,8 +1135,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_OPEN_MISSION_NPC, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_OPEN_TRADESKILL_NPC, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLACE_BUILDING_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLOT_PLACED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLOT_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLOT_PLACED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_PLOT_REMOVED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_RECALL_PORTAL_LAST_USED_TIME, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_RECALL_PORTAL_USED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_RECRUITMENT_FOLLOWERS_GENERATED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); @@ -1169,10 +1170,10 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_MESSAGE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_POI, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_ACTION_THROTTLED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DECLINE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DESTROYED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_NEW_LEADER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_UNINVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DECLINE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DESTROYED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_NEW_LEADER, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_UNINVITE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DELETED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_EARNED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_MEMBERS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1248,7 +1249,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_START, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_TIMER_START, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_GROUP_SIZE_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_INFO, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_RESET_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_SAVE_CREATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1298,7 +1299,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIVE_REGION_ACCOUNT_RESTORE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIVE_REGION_CHARACTER_COPY_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIVE_REGION_GET_ACCOUNT_CHARACTER_LIST_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_EQUIPMENT_SET, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_SELECTED_TROPHY_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGIN_SET_TIME_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); @@ -1327,7 +1328,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAP_OBJ_EVENTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MASTER_LOOT_CANDIDATE_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MESSAGE_BOX, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIMAP_PING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIMAP_PING, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MIRROR_IMAGE_COMPONENTED_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MIRROR_IMAGE_CREATURE_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MISSILE_CANCEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1431,11 +1432,11 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_SHIPMENT_NPC_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OVERRIDE_LIGHT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAGE_TEXT, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_COMMAND_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_INVITE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_KILL_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAUSE_MIRROR_TIMER, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PENDING_RAID_LOCK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_ALREADY_SIGNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1539,12 +1540,12 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_DIFFICULTY_SET, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_GROUP_ONLY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_INSTANCE_MESSAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_MARKERS_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_MARKERS_CHANGED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RANDOM_ROLL, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RATED_BATTLEFIELD_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_COMPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_STARTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_COMPLETED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_STARTED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_RESULT_FAILED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_RESULT_OK, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REALM_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1573,9 +1574,9 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_TOKEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESURRECT_REQUEST, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESYNC_RUNES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_CHANGED_INFORM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_CHANGED_INFORM, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_CHOSEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_POLL_INFORM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_POLL_INFORM, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RUNE_REGEN_DEBUG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SCENARIO_BOOT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SCENARIO_COMPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1594,8 +1595,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SELL_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_ITEM_PASSIVES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_KNOWN_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_ALL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_SINGLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_ALL, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_SINGLE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_CHARGES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_HISTORY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_UNLEARN_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); @@ -1719,9 +1720,9 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_WEEKLY_SPELL_USAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_WORLD_STATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_WOW_TOKEN_AUCTIONABLE_LIST_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_ADD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_REMOVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_ADD, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_REMOVE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_USE_EQUIPMENT_SET_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_VENDOR_INVENTORY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_VIGNETTE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index da7cbbe8020..d8bad3d4933 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -171,6 +171,9 @@ namespace WorldPackets class ChannelPlayerCommand; class JoinChannel; class LeaveChannel; + class UserlistAdd; + class UserlistRemove; + class UserlistUpdate; } namespace Chat @@ -218,6 +221,7 @@ namespace WorldPackets { class GetGarrisonInfo; class GarrisonPurchaseBuilding; + class GarrisonCancelConstruction; class GarrisonRequestBlueprintAndSpecializationData; class GarrisonGetBuildingLandmarks; } @@ -274,6 +278,11 @@ namespace WorldPackets class RequestHonorStats; } + namespace Instance + { + class InstanceInfo; + } + namespace Item { class AutoEquipItem; @@ -337,6 +346,8 @@ namespace WorldPackets class CompleteCinematic; class NextCinematicCamera; class FarSight; + class LoadCUFProfiles; + class SaveCUFProfiles; } namespace Movement @@ -359,6 +370,47 @@ namespace WorldPackets class TrainerBuySpell; } + namespace Party + { + class PartyCommandResult; + class PartyInviteClient; + class PartyInvite; + class PartyInviteResponse; + class PartyUninvite; + class GroupDecline; + class RequestPartyMemberStats; + class PartyMemberStats; + class SetPartyLeader; + class SetRole; + class RoleChangedInform; + class SetLootMethod; + class LeaveGroup; + class MinimapPingClient; + class MinimapPing; + class UpdateRaidTarget; + class SendRaidTargetUpdateSingle; + class SendRaidTargetUpdateAll; + class ConvertRaid; + class RequestPartyJoinUpdates; + class SetAssistantLeader; + class DoReadyCheck; + class ReadyCheckStarted; + class ReadyCheckResponseClient; + class ReadyCheckResponse; + class ReadyCheckCompleted; + class RequestRaidInfo; + class OptOutOfLoot; + class InitiateRolePoll; + class RolePollInform; + class GroupNewLeader; + class PartyUpdate; + class SetEveryoneIsAssistant; + class ChangeSubGroup; + class SwapSubGroups; + class RaidMarkersChanged; + class ClearRaidMarker; + } + namespace Petition { class DeclinePetition; @@ -854,8 +906,6 @@ class WorldSession void SendNotInArenaTeamPacket(uint8 type); void SendPetitionShowList(ObjectGuid guid); - void BuildPartyMemberStatsChangedPacket(Player* player, WorldPacket* data); - void DoLootRelease(ObjectGuid lguid); // Account mute time @@ -1050,28 +1100,31 @@ class WorldSession void HandleMoveTimeSkippedOpcode(WorldPackets::Movement::MoveTimeSkipped& moveTimeSkipped); void HandleMovementAckMessage(WorldPackets::Movement::MovementAckMessage& movementAck); - void HandleRequestRaidInfoOpcode(WorldPacket& recvData); + void HandleRequestRaidInfoOpcode(WorldPackets::Party::RequestRaidInfo& packet); - void HandleGroupInviteOpcode(WorldPacket& recvPacket); + void HandlePartyInviteOpcode(WorldPackets::Party::PartyInviteClient& packet); //void HandleGroupCancelOpcode(WorldPacket& recvPacket); - void HandleGroupInviteResponseOpcode(WorldPacket& recvPacket); - void HandleGroupUninviteOpcode(WorldPacket& recvPacket); - void HandleGroupSetLeaderOpcode(WorldPacket& recvPacket); - void HandleGroupSetRolesOpcode(WorldPacket& recvData); - void HandleGroupDisbandOpcode(WorldPacket& recvPacket); - void HandleOptOutOfLootOpcode(WorldPacket& recvData); - void HandleLootMethodOpcode(WorldPacket& recvPacket); + void HandlePartyInviteResponseOpcode(WorldPackets::Party::PartyInviteResponse& packet); + void HandlePartyUninviteOpcode(WorldPackets::Party::PartyUninvite& packet); + void HandleSetPartyLeaderOpcode(WorldPackets::Party::SetPartyLeader& packet); + void HandleSetRoleOpcode(WorldPackets::Party::SetRole& packet); + void HandleLeaveGroupOpcode(WorldPackets::Party::LeaveGroup& packet); + void HandleOptOutOfLootOpcode(WorldPackets::Party::OptOutOfLoot& packet); + void HandleSetLootMethodOpcode(WorldPackets::Party::SetLootMethod& packet); void HandleLootRoll(WorldPackets::Loot::LootRoll& packet); - void HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData); - void HandleRaidTargetUpdateOpcode(WorldPacket& recvData); - void HandleRaidReadyCheckOpcode(WorldPacket& recvData); - void HandleGroupRaidConvertOpcode(WorldPacket& recvData); - void HandleGroupRequestJoinUpdates(WorldPacket& recvData); - void HandleGroupChangeSubGroupOpcode(WorldPacket& recvData); - void HandleGroupSwapSubGroupOpcode(WorldPacket& recvData); - void HandleGroupAssistantLeaderOpcode(WorldPacket& recvData); + void HandleRequestPartyMemberStatsOpcode(WorldPackets::Party::RequestPartyMemberStats& packet); + void HandleUpdateRaidTargetOpcode(WorldPackets::Party::UpdateRaidTarget& packet); + void HandleDoReadyCheckOpcode(WorldPackets::Party::DoReadyCheck& packet); + void HandleReadyCheckResponseOpcode(WorldPackets::Party::ReadyCheckResponseClient& packet); + void HandleConvertRaidOpcode(WorldPackets::Party::ConvertRaid& packet); + void HandleRequestPartyJoinUpdates(WorldPackets::Party::RequestPartyJoinUpdates& packet); + void HandleChangeSubGroupOpcode(WorldPackets::Party::ChangeSubGroup& packet); + void HandleSwapSubGroupsOpcode(WorldPackets::Party::SwapSubGroups& packet); + void HandleSetAssistantLeaderOpcode(WorldPackets::Party::SetAssistantLeader& packet); void HandlePartyAssignmentOpcode(WorldPacket& recvData); - void HandleRolePollBeginOpcode(WorldPacket& recvData); + void HandleInitiateRolePoll(WorldPackets::Party::InitiateRolePoll& packet); + void HandleSetEveryoneIsAssistant(WorldPackets::Party::SetEveryoneIsAssistant& packet); + void HandleClearRaidMarker(WorldPackets::Party::ClearRaidMarker& packet); void HandleDeclinePetition(WorldPackets::Petition::DeclinePetition& packet); void HandleOfferPetition(WorldPackets::Petition::OfferPetition& packet); @@ -1336,7 +1389,7 @@ class WorldSession void HandleWardenDataOpcode(WorldPacket& recvData); void HandleWorldTeleportOpcode(WorldPacket& recvData); - void HandleMinimapPingOpcode(WorldPacket& recvData); + void HandleMinimapPingOpcode(WorldPackets::Party::MinimapPingClient& packet); void HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet); void HandleFarSightOpcode(WorldPackets::Misc::FarSight& packet); void HandleSetDungeonDifficultyOpcode(WorldPackets::Misc::SetDungeonDifficulty& setDungeonDifficulty); @@ -1469,12 +1522,13 @@ class WorldSession void HandleRequestWowTokenMarketPrice(WorldPackets::Token::RequestWowTokenMarketPrice& requestWowTokenMarketPrice); // Compact Unit Frames (4.x) - void HandleSaveCUFProfiles(WorldPacket& recvPacket); + void HandleSaveCUFProfiles(WorldPackets::Misc::SaveCUFProfiles& packet); void SendLoadCUFProfiles(); // Garrison void HandleGetGarrisonInfo(WorldPackets::Garrison::GetGarrisonInfo& getGarrisonInfo); void HandleGarrisonPurchaseBuilding(WorldPackets::Garrison::GarrisonPurchaseBuilding& garrisonPurchaseBuilding); + void HandleGarrisonCancelConstruction(WorldPackets::Garrison::GarrisonCancelConstruction& garrisonCancelConstruction); void HandleGarrisonRequestBlueprintAndSpecializationData(WorldPackets::Garrison::GarrisonRequestBlueprintAndSpecializationData& garrisonRequestBlueprintAndSpecializationData); void HandleGarrisonGetBuildingLandmarks(WorldPackets::Garrison::GarrisonGetBuildingLandmarks& garrisonGetBuildingLandmarks); diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 7af7644d924..ec716a0e03d 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -338,6 +338,7 @@ class Spell void EffectApplyGlyph(SpellEffIndex effIndex); void EffectEnchantHeldItem(SpellEffIndex effIndex); void EffectSummonObject(SpellEffIndex effIndex); + void EffectChangeRaidMarker(SpellEffIndex effIndex); void EffectResurrect(SpellEffIndex effIndex); void EffectParry(SpellEffIndex effIndex); void EffectBlock(SpellEffIndex effIndex); @@ -407,6 +408,7 @@ class Spell void EffectDestroyItem(SpellEffIndex effIndex); void EffectLearnGarrisonBuilding(SpellEffIndex effIndex); void EffectCreateGarrison(SpellEffIndex effIndex); + void EffectAddGarrisonFollower(SpellEffIndex effIndex); typedef std::set<Aura*> UsedSpellMods; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 97e82426e9d..faa897d866f 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -180,7 +180,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectReputation, //103 SPELL_EFFECT_REPUTATION &Spell::EffectSummonObject, //104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1 &Spell::EffectSummonObject, //105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2 - &Spell::EffectSummonObject, //106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3 + &Spell::EffectChangeRaidMarker, //106 SPELL_EFFECT_CHANGE_RAID_MARKER &Spell::EffectSummonObject, //107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4 &Spell::EffectDispelMechanic, //108 SPELL_EFFECT_DISPEL_MECHANIC &Spell::EffectResurrectPet, //109 SPELL_EFFECT_RESURRECT_PET @@ -294,7 +294,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectNULL, //217 SPELL_EFFECT_UPGRADE_GARRISON &Spell::EffectNULL, //218 SPELL_EFFECT_218 &Spell::EffectNULL, //219 SPELL_EFFECT_219 - &Spell::EffectNULL, //220 SPELL_EFFECT_ADD_GARRISON_FOLLOWER + &Spell::EffectAddGarrisonFollower, //220 SPELL_EFFECT_ADD_GARRISON_FOLLOWER &Spell::EffectNULL, //221 SPELL_EFFECT_221 &Spell::EffectNULL, //222 SPELL_EFFECT_CREATE_HEIRLOOM_ITEM &Spell::EffectNULL, //223 SPELL_EFFECT_CHANGE_ITEM_BONUSES @@ -2923,7 +2923,7 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/) unitTarget->ToCreature()->AI()->AttackStart(m_caster); } -void Spell::EffectWeaponDmg(SpellEffIndex /*effIndex*/) +void Spell::EffectWeaponDmg(SpellEffIndex effIndex) { if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET) return; @@ -2934,8 +2934,9 @@ void Spell::EffectWeaponDmg(SpellEffIndex /*effIndex*/) // multiple weapon dmg effect workaround // execute only the last weapon damage // and handle all effects at once - for (SpellEffectInfo const* effect : GetEffects()) + for (uint8 index = effIndex + 1; index < MAX_SPELL_EFFECTS; ++index) { + SpellEffectInfo const* effect = GetEffect(index); if (!effect) continue; switch (effect->Effect) @@ -4647,6 +4648,25 @@ void Spell::EffectPullTowards(SpellEffIndex /*effIndex*/) unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ); } +void Spell::EffectChangeRaidMarker(SpellEffIndex /*effIndex*/) +{ + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + + Player* player = m_caster->ToPlayer(); + if (!player || !m_targets.HasDst()) + return; + + Group* group = player->GetGroup(); + if (!group || (group->isRaidGroup() && !group->IsLeader(player->GetGUID()) && !group->IsAssistant(player->GetGUID()))) + return; + + float x, y, z; + destTarget->GetPosition(x, y, z); + + group->AddRaidMarker(damage, player->GetMapId(), x, y, z); +} + void Spell::EffectDispelMechanic(SpellEffIndex /*effIndex*/) { if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) @@ -5825,3 +5845,15 @@ void Spell::EffectCreateGarrison(SpellEffIndex effIndex) unitTarget->ToPlayer()->CreateGarrison(GetEffect(effIndex)->MiscValue); } + +void Spell::EffectAddGarrisonFollower(SpellEffIndex effIndex) +{ + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + if (Garrison* garrison = unitTarget->ToPlayer()->GetGarrison()) + garrison->AddFollower(GetEffect(effIndex)->MiscValue); +} diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 4db7091f971..0bdb36b988f 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -806,7 +806,7 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] = {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 103 SPELL_EFFECT_REPUTATION {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2 - {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 106 SPELL_EFFECT_CHANGE_RAID_MARKER {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 108 SPELL_EFFECT_DISPEL_MECHANIC {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 109 SPELL_EFFECT_SUMMON_DEAD_PET diff --git a/src/server/game/Texts/ChatTextBuilder.h b/src/server/game/Texts/ChatTextBuilder.h index dcee6f08ac3..167680f1cd2 100644 --- a/src/server/game/Texts/ChatTextBuilder.h +++ b/src/server/game/Texts/ChatTextBuilder.h @@ -34,7 +34,7 @@ namespace Trinity { BroadcastTextEntry const* bct = sBroadcastTextStore.LookupEntry(_textId); WorldPackets::Chat::Chat packet; - packet.Initalize(_msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? DB2Manager::GetBroadcastTextValue(bct, locale, _source->getGender()) : "", _achievementId, "", locale); + packet.Initialize(_msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? DB2Manager::GetBroadcastTextValue(bct, locale, _source->getGender()) : "", _achievementId, "", locale); packet.Write(); data = packet.Move(); } @@ -56,7 +56,7 @@ namespace Trinity void operator()(WorldPacket& data, LocaleConstant locale) { WorldPackets::Chat::Chat packet; - packet.Initalize(_msgType, _language, _source, _target, _text, 0, "", locale); + packet.Initialize(_msgType, _language, _source, _target, _text, 0, "", locale); packet.Write(); data = packet.Move(); } diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index 281504b9aaf..c1ea235a3e2 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -37,7 +37,7 @@ class CreatureTextBuilder { std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale); WorldPackets::Chat::Chat packet; - packet.Initalize(_msgType, Language(_language), _source, _target, text, 0, "", locale); + packet.Initialize(_msgType, Language(_language), _source, _target, text, 0, "", locale); packet.Write(); data = packet.Move(); } @@ -62,7 +62,7 @@ class PlayerTextBuilder { std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale); WorldPackets::Chat::Chat packet; - packet.Initalize(_msgType, Language(_language), _talker, _target, text, 0, "", locale); + packet.Initialize(_msgType, Language(_language), _talker, _target, text, 0, "", locale); packet.Write(); data = packet.Move(); } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 9b8c63000fc..d68da8fbc63 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2252,6 +2252,9 @@ void World::Update(uint32 diff) sLFGMgr->Update(diff); RecordTimeDiff("UpdateLFGMgr"); + sGroupMgr->Update(diff); + RecordTimeDiff("GroupMgr"); + // execute callbacks from sql queries that were queued recently ProcessQueryCallbacks(); RecordTimeDiff("ProcessQueryCallbacks"); @@ -2381,7 +2384,7 @@ namespace Trinity while (char* line = ChatHandler::LineFromMessage(text)) { WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); + packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); packet.Write(); dataList.emplace_back(new WorldPacket(packet.Move())); } @@ -2447,7 +2450,7 @@ void World::SendGlobalText(const char* text, WorldSession* self) while (char* line = ChatHandler::LineFromMessage(pos)) { WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); + packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); SendGlobalMessage(packet.Write(), self); } @@ -2481,7 +2484,7 @@ bool World::SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession void World::SendZoneText(uint32 zone, const char* text, WorldSession* self, uint32 team) { WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, text); + packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, text); SendZoneMessage(zone, packet.Write(), self, team); } diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index ecd98595723..7f1a364fd57 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -485,7 +485,7 @@ public: char const* msg = "testtest"; uint8 type = atoi(args); WorldPackets::Chat::Chat packet; - packet.Initalize(ChatMsg(type), LANG_UNIVERSAL, handler->GetSession()->GetPlayer(), handler->GetSession()->GetPlayer(), msg, 0, "chan"); + packet.Initialize(ChatMsg(type), LANG_UNIVERSAL, handler->GetSession()->GetPlayer(), handler->GetSession()->GetPlayer(), msg, 0, "chan"); handler->GetSession()->SendPacket(packet.Write()); return true; } diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index ef52f6ebd95..1af687aef08 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -168,6 +168,8 @@ public: // fill the gameobject data and save to the db object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMask()); + guidLow = object->GetSpawnId(); + // delete the old object and do a clean load from DB with a fresh new GameObject instance. // this is required to avoid weird behavior and memory leaks delete object; diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index f1c4c22527b..38eae92c917 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -25,14 +25,6 @@ #include "ruby_sanctum.h" #include "Player.h" -/* ScriptData -SDName: ruby_sanctum -SDAuthors: Kaelima, Warpten -SD%Complete: 90% -SDComment: Based on Kaelima's initial work (half of it). Corporeality handling is a pure guess, we lack info. -SDCategory: Chamber of Aspects -EndScriptData */ - enum Texts { // Shared @@ -86,6 +78,8 @@ enum Spells // Living Inferno SPELL_BLAZING_AURA = 75885, + SPELL_SPAWN_LIVING_EMBERS = 75880, + SPELL_SUMMON_LIVING_EMBER = 75881, // Halion Controller SPELL_COSMETIC_FIRE_PILLAR = 76006, @@ -142,7 +136,7 @@ enum Events EVENT_CHECK_CORPOREALITY = 14, EVENT_SHADOW_PULSARS_SHOOT = 15, EVENT_TRIGGER_BERSERK = 16, - EVENT_TWILIGHT_MENDING = 17 + EVENT_TWILIGHT_MENDING = 17, }; enum Actions @@ -155,7 +149,13 @@ enum Actions ACTION_MONITOR_CORPOREALITY = 3, // Orb Carrier - ACTION_SHOOT = 4 + ACTION_SHOOT = 4, + + // Living Inferno + ACTION_SUMMON_LIVING_EMBERS = 5, + + // Meteor Flame + ACTION_SUMMON_FLAME = 6 }; enum Phases @@ -173,7 +173,8 @@ enum Misc DATA_MATERIAL_DAMAGE_TAKEN = 2, DATA_STACKS_DISPELLED = 3, DATA_FIGHT_PHASE = 4, - DATA_EVADE_METHOD = 5 + DATA_EVADE_METHOD = 5, + DATA_SPAWNED_FLAMES = 6, }; enum OrbCarrierSeats @@ -702,7 +703,7 @@ class npc_halion_controller : public CreatureScript // The IsInCombat() check is needed because that check should be false when Halion is // not engaged, while it would return true without as UpdateVictim() checks for // combat state. - if (!(_events.IsInPhase(PHASE_INTRO)) && me->IsInCombat() && !UpdateVictim()) + if (!_events.IsInPhase(PHASE_INTRO) && me->IsInCombat() && !UpdateVictim()) { EnterEvadeMode(); return; @@ -893,8 +894,6 @@ class npc_halion_controller : public CreatureScript } }; -typedef npc_halion_controller::npc_halion_controllerAI controllerAI; - class npc_orb_carrier : public CreatureScript { public: @@ -996,7 +995,7 @@ class npc_meteor_strike_initial : public CreatureScript if (!owner) return; - // Let Halion Controller count as summoner + // Let Controller count as summoner if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER))) controller->AI()->JustSummoned(me); @@ -1006,11 +1005,13 @@ class npc_meteor_strike_initial : public CreatureScript if (HalionAI* halionAI = CAST_AI(HalionAI, owner->AI())) { Position const* ownerPos = halionAI->GetMeteorStrikePosition(); + // Adjust randomness between 0 and pi. + float randomAdjustment = frand(static_cast<float>(M_PI / 14), static_cast<float>(13 * M_PI / 14)); float angle[4]; angle[0] = me->GetAngle(ownerPos); - angle[1] = me->GetAngle(ownerPos) - static_cast<float>(M_PI/2); - angle[2] = me->GetAngle(ownerPos) - static_cast<float>(-M_PI/2); - angle[3] = me->GetAngle(ownerPos) - static_cast<float>(M_PI); + angle[1] = angle[0] + randomAdjustment; + angle[2] = angle[0] + static_cast<float>(M_PI); + angle[3] = angle[2] + randomAdjustment; _meteorList.clear(); for (uint8 i = 0; i < 4; i++) @@ -1019,7 +1020,10 @@ class npc_meteor_strike_initial : public CreatureScript me->SetOrientation(angle[i]); Position newPos = me->GetNearPosition(10.0f, 0.0f); // Exact distance if (Creature* meteor = me->SummonCreature(NPC_METEOR_STRIKE_NORTH + i, newPos, TEMPSUMMON_TIMED_DESPAWN, 30000)) + { + meteor->SetOrientation(angle[i]); _meteorList.push_back(meteor); + } } } } @@ -1045,11 +1049,8 @@ class npc_meteor_strike : public CreatureScript struct npc_meteor_strikeAI : public ScriptedAI { npc_meteor_strikeAI(Creature* creature) : ScriptedAI(creature), - _instance(creature->GetInstanceScript()) + _instance(creature->GetInstanceScript()), _spawnCount(0) { - _range = 5.0f; - _spawnCount = 0; - SetCombatMovement(false); } @@ -1070,34 +1071,41 @@ class npc_meteor_strike : public CreatureScript controller->AI()->JustSummoned(me); } - void UpdateAI(uint32 diff) override + void SetData(uint32 dataType, uint32 dataCount) override { - if (_spawnCount > 5) - return; + if (dataType == DATA_SPAWNED_FLAMES) + _spawnCount += dataCount; + } - _events.Update(diff); + uint32 GetData(uint32 dataType) const override + { + if (dataType == DATA_SPAWNED_FLAMES) + return _spawnCount; + return 0; + } + void UpdateAI(uint32 diff) override + { + _events.Update(diff); if (_events.ExecuteEvent() == EVENT_SPAWN_METEOR_FLAME) { - Position pos = me->GetNearPosition( _range, 0.0f); - + Position pos = me->GetNearPosition(5.0f, 0.0f); if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25000)) { if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER))) controller->AI()->JustSummoned(flame); - flame->CastSpell(flame, SPELL_METEOR_STRIKE_FIRE_AURA_2, true); - ++_spawnCount; + flame->SetOrientation(me->GetOrientation()); + + flame->AI()->SetGUID(GetGUID()); + flame->AI()->DoAction(ACTION_SUMMON_FLAME); } - _range += 5.0f; - _events.ScheduleEvent(EVENT_SPAWN_METEOR_FLAME, 800); } } private: InstanceScript* _instance; EventMap _events; - float _range; uint8 _spawnCount; }; @@ -1107,6 +1115,70 @@ class npc_meteor_strike : public CreatureScript } }; +class npc_meteor_strike_flame : public CreatureScript +{ + public: + npc_meteor_strike_flame() : CreatureScript("npc_meteor_strike_flame") { } + + struct npc_meteor_strike_flameAI : public ScriptedAI + { + npc_meteor_strike_flameAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + SetCombatMovement(false); + } + + void SetGUID(ObjectGuid guid, int32 /*id = 0 */) + { + _rootOwnerGuid = guid; + } + + void DoAction(int32 action) override + { + if (action != ACTION_SUMMON_FLAME || _rootOwnerGuid.IsEmpty()) + return; + + me->CastSpell(me, SPELL_METEOR_STRIKE_FIRE_AURA_2, true); + + Creature* meteorStrike = ObjectAccessor::GetCreature(*me, _rootOwnerGuid); + if (!meteorStrike || meteorStrike->AI()->GetData(DATA_SPAWNED_FLAMES) > 5) + return; + + me->SetOrientation(me->GetOrientation() + frand(static_cast<float>(-M_PI / 16), static_cast<float>(M_PI / 16))); + Position pos = me->GetNearPosition(5.0f, 0.0f); + + if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25000)) + { + if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER))) + controller->AI()->JustSummoned(flame); + + flame->AI()->SetGUID(_rootOwnerGuid); + meteorStrike->AI()->SetData(DATA_SPAWNED_FLAMES, 1); + } + } + + void IsSummonedBy(Unit* /*summoner*/) override + { + // Let Halion Controller count as summoner. + if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER))) + controller->AI()->JustSummoned(me); + } + + void UpdateAI(uint32 /*diff*/) override { } + void EnterEvadeMode() override { } + + private: + InstanceScript* _instance; + EventMap _events; + ObjectGuid _rootOwnerGuid = ObjectGuid::Empty; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetRubySanctumAI<npc_meteor_strike_flameAI>(creature); + } +}; + class npc_combustion_consumption : public CreatureScript { public: @@ -1119,26 +1191,23 @@ class npc_combustion_consumption : public CreatureScript { SetCombatMovement(false); - switch (me->GetEntry()) + switch (creature->GetEntry()) { case NPC_COMBUSTION: _explosionSpell = SPELL_FIERY_COMBUSTION_EXPLOSION; _damageSpell = SPELL_COMBUSTION_DAMAGE_AURA; - me->SetPhaseMask(0x01, true); + creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x01, true); break; case NPC_CONSUMPTION: _explosionSpell = SPELL_SOUL_CONSUMPTION_EXPLOSION; _damageSpell = SPELL_CONSUMPTION_DAMAGE_AURA; - me->SetPhaseMask(0x20, true); + creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x20, true); break; default: // Should never happen _explosionSpell = 0; _damageSpell = 0; break; } - - if (IsHeroic()) - me->SetPhaseMask(0x01 | 0x20, true); } void IsSummonedBy(Unit* summoner) override @@ -1160,7 +1229,7 @@ class npc_combustion_consumption : public CreatureScript me->CastCustomSpell(SPELL_SCALE_AURA, SPELLVALUE_AURA_STACK, stackAmount, me); DoCast(me, _damageSpell); - int32 damage = 1200 + (stackAmount * 1290); // Needs more researches. + int32 damage = 1200 + (stackAmount * 1290); // Needs more research. summoner->CastCustomSpell(_explosionSpell, SPELLVALUE_BASE_POINT0, damage, summoner); } @@ -1193,6 +1262,10 @@ class npc_living_inferno : public CreatureScript me->SetInCombatWithZone(); me->CastSpell(me, SPELL_BLAZING_AURA, true); + // SMSG_SPELL_GO for the living ember stuff isn't even sent to the client - Blizzard on drugs. + if (me->GetMap()->GetDifficultyID() == DIFFICULTY_25_HC) + me->CastSpell(me, SPELL_SPAWN_LIVING_EMBERS, true); + if (InstanceScript* instance = me->GetInstanceScript()) if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HALION_CONTROLLER))) controller->AI()->JustSummoned(me); @@ -1210,7 +1283,6 @@ class npc_living_inferno : public CreatureScript } }; -//! Need sniff data class npc_living_ember : public CreatureScript { public: @@ -1738,12 +1810,46 @@ class spell_halion_summon_exit_portals : public SpellScriptLoader } }; +class spell_halion_spawn_living_embers : public SpellScriptLoader +{ + public: + spell_halion_spawn_living_embers() : SpellScriptLoader("spell_halion_spawn_living_embers") { } + + class spell_halion_spawn_living_embers_SpellScript : public SpellScript + { + PrepareSpellScript(spell_halion_spawn_living_embers_SpellScript); + + void SelectMeteorFlames(std::list<WorldObject*>& unitList) + { + if (!unitList.empty()) + Trinity::Containers::RandomResizeList(unitList, 10); + } + + void HandleScript(SpellEffIndex /* effIndex */) + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SUMMON_LIVING_EMBER, true); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_halion_spawn_living_embers_SpellScript::SelectMeteorFlames, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_halion_spawn_living_embers_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_halion_spawn_living_embers_SpellScript(); + } +}; + void AddSC_boss_halion() { new boss_halion(); new boss_twilight_halion(); new npc_halion_controller(); + new npc_meteor_strike_flame(); new npc_meteor_strike_initial(); new npc_meteor_strike(); new npc_combustion_consumption(); @@ -1765,4 +1871,5 @@ void AddSC_boss_halion() new spell_halion_twilight_phasing(); new spell_halion_twilight_cutter(); new spell_halion_clear_debuffs(); + new spell_halion_spawn_living_embers(); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index 9ca88f4fdfa..525ecacd39a 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -482,40 +482,47 @@ class boss_flame_leviathan : public CreatureScript if (action && action <= 4) // Tower destruction, debuff leviathan loot and reduce active tower count { if (me->HasLootMode(LOOT_MODE_DEFAULT | LOOT_MODE_HARD_MODE_1 | LOOT_MODE_HARD_MODE_2 | LOOT_MODE_HARD_MODE_3 | LOOT_MODE_HARD_MODE_4) && ActiveTowersCount == 4) - { me->RemoveLootMode(LOOT_MODE_HARD_MODE_4); - --ActiveTowersCount; - } + if (me->HasLootMode(LOOT_MODE_DEFAULT | LOOT_MODE_HARD_MODE_1 | LOOT_MODE_HARD_MODE_2 | LOOT_MODE_HARD_MODE_3) && ActiveTowersCount == 3) - { me->RemoveLootMode(LOOT_MODE_HARD_MODE_3); - --ActiveTowersCount; - } + if (me->HasLootMode(LOOT_MODE_DEFAULT | LOOT_MODE_HARD_MODE_1 | LOOT_MODE_HARD_MODE_2) && ActiveTowersCount == 2) - { me->RemoveLootMode(LOOT_MODE_HARD_MODE_2); - --ActiveTowersCount; - } + if (me->HasLootMode(LOOT_MODE_DEFAULT | LOOT_MODE_HARD_MODE_1) && ActiveTowersCount == 1) - { me->RemoveLootMode(LOOT_MODE_HARD_MODE_1); - --ActiveTowersCount; - } } switch (action) { case ACTION_TOWER_OF_STORM_DESTROYED: - towerOfStorms = false; + if (towerOfStorms) + { + towerOfStorms = false; + --ActiveTowersCount; + } break; case ACTION_TOWER_OF_FROST_DESTROYED: - towerOfFrost = false; + if (towerOfFrost) + { + towerOfFrost = false; + --ActiveTowersCount; + } break; case ACTION_TOWER_OF_FLAMES_DESTROYED: - towerOfFlames = false; + if (towerOfFlames) + { + towerOfFlames = false; + --ActiveTowersCount; + } break; case ACTION_TOWER_OF_LIFE_DESTROYED: - towerOfLife = false; + if (towerOfLife) + { + towerOfLife = false; + --ActiveTowersCount; + } break; case ACTION_START_HARD_MODE: // Activate hard-mode enable all towers, apply buffs on leviathan ActiveTowers = true; diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index dc9e948966d..e83340bdd84 100644 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -38,6 +38,7 @@ #include <queue> #include <sstream> #include <algorithm> +#include <memory> #include <boost/optional.hpp> #include <boost/utility/in_place_factory.hpp> @@ -164,4 +165,14 @@ struct LocalizedString template <typename T> using Optional = boost::optional<T>; +namespace Trinity +{ + //! std::make_unique implementation (TODO: remove this once C++14 is supported) + template<typename T, typename ...Args> + std::unique_ptr<T> make_unique(Args&& ...args) + { + return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); + } +} + #endif diff --git a/src/server/shared/Database/Implementation/HotfixDatabase.cpp b/src/server/shared/Database/Implementation/HotfixDatabase.cpp index 1afb118a06e..a7043b1d5ff 100644 --- a/src/server/shared/Database/Implementation/HotfixDatabase.cpp +++ b/src/server/shared/Database/Implementation/HotfixDatabase.cpp @@ -52,6 +52,11 @@ void HotfixDatabaseConnection::DoPrepareStatements() "PhaseUseFlags, PhaseID, PhaseGroupID, Type, Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Name FROM gameobjects ORDER BY ID DESC", CONNECTION_SYNCH); PREPARE_LOCALE_STMT(HOTFIX_SEL_GAMEOBJECTS, "SELECT ID, Name_lang FROM gameobjects_locale WHERE locale = ?", CONNECTION_SYNCH); + // GarrAbility.db2 + PrepareStatement(HOTFIX_SEL_GARR_ABILITY, "SELECT ID, Flags, Name, Description, IconFileDataID, OtherFactionGarrAbilityID, " + "GarrAbilityCategoryID FROM garr_ability ORDER BY ID DESC", CONNECTION_SYNCH); + PREPARE_LOCALE_STMT(HOTFIX_SEL_GARR_ABILITY, "SELECT ID, Name_lang, Description_lang FROM garr_ability_locale WHERE locale = ?", CONNECTION_SYNCH); + // GarrBuilding.db2 PrepareStatement(HOTFIX_SEL_GARR_BUILDING, "SELECT ID, HordeGameObjectID, AllianceGameObjectID, Unknown, Type, Level, NameAlliance, NameHorde, Description, " "Tooltip, BuildDuration, CostCurrencyID, CostCurrencyAmount, HordeTexPrefixKitID, AllianceTexPrefixKitID, IconFileDataID, BonusAmount, Flags, " @@ -64,6 +69,20 @@ void HotfixDatabaseConnection::DoPrepareStatements() PrepareStatement(HOTFIX_SEL_GARR_BUILDING_PLOT_INST, "SELECT ID, GarrBuildingID, UiTextureAtlasMemberID, GarrSiteLevelPlotInstID, " "LandmarkOffsetX, LandmarkOffsetY FROM garr_building_plot_inst ORDER BY ID DESC", CONNECTION_SYNCH); + // GarrClassSpec.db2 + PrepareStatement(HOTFIX_SEL_GARR_CLASS_SPEC, "SELECT ID, NameMale, NameFemale, NameGenderless, ClassAtlasID, GarrFollItemSetID " + "FROM garr_class_spec ORDER BY ID DESC", CONNECTION_SYNCH); + PREPARE_LOCALE_STMT(HOTFIX_SEL_GARR_CLASS_SPEC, "SELECT ID, NameMale_lang, NameFemale_lang, NameGenderless_lang FROM garr_class_spec_locale WHERE locale = ?", CONNECTION_SYNCH); + + // GarrFollower.db2 + PrepareStatement(HOTFIX_SEL_GARR_FOLLOWER, "SELECT ID, HordeCreatureID, AllianceCreatureID, HordeUiAnimRaceInfoID, AllianceUiAnimRaceInfoID, Quality, " + "HordeGarrClassSpecID, AllianceGarrClassSpecID, HordeGarrFollItemSetID, AllianceGarrFollItemSetID, Level, ItemLevelWeapon, ItemLevelArmor, Unknown1, Flags, " + "HordeSourceText, AllianceSourceText, Unknown2, Unknown3, HordePortraitIconID, AlliancePortraitIconID FROM garr_follower ORDER BY ID DESC", CONNECTION_SYNCH); + PREPARE_LOCALE_STMT(HOTFIX_SEL_GARR_FOLLOWER, "SELECT ID, HordeSourceText_lang, AllianceSourceText_lang FROM garr_follower_locale WHERE locale = ?", CONNECTION_SYNCH); + + // GarrFollowerXAbility.db2 + PrepareStatement(HOTFIX_SEL_GARR_FOLLOWER_X_ABILITY, "SELECT ID, GarrFollowerID, GarrAbilityID, FactionIndex FROM garr_follower_x_ability ORDER BY ID DESC", CONNECTION_SYNCH); + // GarrPlot.db2 PrepareStatement(HOTFIX_SEL_GARR_PLOT, "SELECT ID, GarrPlotUICategoryID, PlotType, Flags, Name, MinCount, MaxCount, " "AllianceConstructionGameObjectID, HordeConstructionGameObjectID FROM garr_plot ORDER BY ID DESC", CONNECTION_SYNCH); diff --git a/src/server/shared/Database/Implementation/HotfixDatabase.h b/src/server/shared/Database/Implementation/HotfixDatabase.h index 5d5f00dbf9e..4adf555dc2f 100644 --- a/src/server/shared/Database/Implementation/HotfixDatabase.h +++ b/src/server/shared/Database/Implementation/HotfixDatabase.h @@ -57,11 +57,22 @@ enum HotfixDatabaseStatements HOTFIX_SEL_GAMEOBJECTS, HOTFIX_SEL_GAMEOBJECTS_LOCALE, + HOTFIX_SEL_GARR_ABILITY, + HOTFIX_SEL_GARR_ABILITY_LOCALE, + HOTFIX_SEL_GARR_BUILDING, HOTFIX_SEL_GARR_BUILDING_LOCALE, HOTFIX_SEL_GARR_BUILDING_PLOT_INST, + HOTFIX_SEL_GARR_CLASS_SPEC, + HOTFIX_SEL_GARR_CLASS_SPEC_LOCALE, + + HOTFIX_SEL_GARR_FOLLOWER, + HOTFIX_SEL_GARR_FOLLOWER_LOCALE, + + HOTFIX_SEL_GARR_FOLLOWER_X_ABILITY, + HOTFIX_SEL_GARR_PLOT, HOTFIX_SEL_GARR_PLOT_LOCALE, diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index e22a06e635e..5b3782fce55 100644 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -23,6 +23,7 @@ #include "Appender.h" #include "Logger.h" #include "StringFormat.h" +#include "Common.h" #include <boost/asio/io_service.hpp> #include <boost/asio/strand.hpp> @@ -64,7 +65,7 @@ class Log template<typename... Args> inline void outMessage(std::string const& filter, LogLevel const level, const char* fmt, Args const&... args) { - write(std::unique_ptr<LogMessage>(new LogMessage(level, filter, Trinity::StringFormat(fmt, args...)))); + write(Trinity::make_unique<LogMessage>(level, filter, Trinity::StringFormat(fmt, args...))); } template<typename... Args> @@ -73,7 +74,7 @@ class Log if (!ShouldLog("commands.gm", LOG_LEVEL_INFO)) return; - std::unique_ptr<LogMessage> msg(new LogMessage(LOG_LEVEL_INFO, "commands.gm", std::move(Trinity::StringFormat(fmt, args...)))); + std::unique_ptr<LogMessage> msg = Trinity::make_unique<LogMessage>(LOG_LEVEL_INFO, "commands.gm", std::move(Trinity::StringFormat(fmt, args...))); msg->param1 = std::to_string(account); diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 8f85cfdbe83..125f630bb13 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -80,7 +80,7 @@ struct map_liquidHeader namespace MMAP { - char const* MAP_VERSION_MAGIC = "v1.4"; + char const* MAP_VERSION_MAGIC = "v1.5"; TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ } TerrainBuilder::~TerrainBuilder() { } @@ -134,7 +134,7 @@ namespace MMAP bool TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, Spot portion) { char mapFileName[255]; - sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX); + sprintf(mapFileName, "maps/%04u_%02u_%02u.map", mapID, tileY, tileX); FILE* mapFile = fopen(mapFileName, "rb"); if (!mapFile) |