diff options
author | Ovahlord <dreadkiller@gmx.de> | 2024-03-13 22:34:49 +0100 |
---|---|---|
committer | Ovahlord <dreadkiller@gmx.de> | 2024-03-13 22:34:49 +0100 |
commit | 4aae7887d014a73d75293b839a829370a8f8a6bb (patch) | |
tree | befde5f92903caaeee88f800a3b757b2cbc823af | |
parent | cfc9cc9ec285e7934f3160047ff87be3c649594f (diff) |
Core/Creatures: added PetSpellDataId and Civilian fields to creature_template, replaced level delta fields with MinLevel and MaxLevel in creature_template_difficulty and backported creature_classlevel_stats from 4.3.4
-rw-r--r-- | sql/updates/world/cata_classic/2024_03_13_01_world.sql | 439 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/WorldDatabase.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 141 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 11 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/CreatureData.h | 31 | ||||
-rw-r--r-- | src/server/game/Entities/Pet/Pet.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 161 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 3 | ||||
-rw-r--r-- | src/server/game/Server/Packets/CombatLogPacketsCommon.cpp | 25 |
9 files changed, 593 insertions, 229 deletions
diff --git a/sql/updates/world/cata_classic/2024_03_13_01_world.sql b/sql/updates/world/cata_classic/2024_03_13_01_world.sql new file mode 100644 index 00000000000..17257aa625f --- /dev/null +++ b/sql/updates/world/cata_classic/2024_03_13_01_world.sql @@ -0,0 +1,439 @@ +UPDATE `creature_template_difficulty` SET `LevelScalingDeltaMax`= 1; +UPDATE `creature_template_difficulty` SET `LevelScalingDeltaMin`= 1; + +ALTER TABLE `creature_template_difficulty` + DROP COLUMN `ContentTuningID`, + CHANGE `LevelScalingDeltaMin` `MinLevel` TINYINT DEFAULT 1 NOT NULL, + CHANGE `LevelScalingDeltaMax` `MaxLevel` TINYINT DEFAULT 1 NOT NULL; + +DROP TABLE IF EXISTS `creature_classlevelstats`; +CREATE TABLE `creature_classlevelstats` ( + `level` tinyint NOT NULL, + `class` tinyint NOT NULL, + `basehp0` int UNSIGNED NOT NULL DEFAULT 1, + `basehp1` int UNSIGNED NOT NULL DEFAULT 1, + `basehp2` int UNSIGNED NOT NULL DEFAULT 1, + `basehp3` int UNSIGNED NOT NULL DEFAULT 1, + `basemana` int UNSIGNED NOT NULL DEFAULT 1, + `basearmor` int UNSIGNED NOT NULL DEFAULT 1, + `attackpower` smallint NOT NULL DEFAULT 0, + `rangedattackpower` smallint NOT NULL DEFAULT 0, + `damage_base` float NOT NULL DEFAULT 0, + `damage_exp1` float NOT NULL DEFAULT 0, + `damage_exp2` float NOT NULL DEFAULT 0, + `damage_exp3` float NOT NULL DEFAULT 0, + `comment` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL, + PRIMARY KEY (`level`, `class`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic; + +INSERT INTO `creature_classlevelstats` (`level`, `class`, `basehp0`, `basehp1`, `basehp2`, `basehp3`, `basemana`, `basearmor`, `attackpower`, `rangedattackpower`, `damage_base`, `damage_exp1`, `damage_exp2`, `damage_exp3`, `comment`) VALUES +(1, 1, 42, 1, 1, 1, 0, 15, 10, 1, 0.0607, 0, 0, 0, NULL), +(1, 2, 41, 1, 1, 1, 60, 13, 1, 1, 0.746, 0, 0, 0, 'armor estimated'), +(1, 4, 42, 1, 1, 1, 0, 6, 24, 1, 0.25, 0, 0, 0, NULL), +(1, 8, 40, 1, 1, 1, 120, 5, 1, 10, 0.4564, 0, 0, 0, NULL), +(2, 1, 55, 1, 1, 1, 0, 16, 10, 1, 0.3603, 0, 0, 0, NULL), +(2, 2, 54, 1, 1, 1, 69, 14, 3, 1, 0.7365, 0, 0, 0, 'armor estimated'), +(2, 4, 55, 1, 1, 1, 0, 18, 26, 1, 0.54, 0, 0, 0, NULL), +(2, 8, 52, 1, 1, 1, 147, 16, 3, 10, 0.4564, 0, 0, 0, NULL), +(3, 1, 71, 1, 1, 1, 0, 41, 11, 1, 0.6976, 0, 0, 0, NULL), +(3, 2, 69, 1, 1, 1, 79, 37, 7, 1, 0.6984, 0, 0, 0, NULL), +(3, 4, 71, 1, 1, 1, 0, 31, 28, 1, 0.74, 0, 0, 0, NULL), +(3, 8, 67, 1, 1, 1, 174, 28, 7, 10, 0.7334, 0, 0, 0, NULL), +(4, 1, 86, 1, 1, 1, 0, 76, 13, 1, 1.0863, 0, 0, 0, NULL), +(4, 2, 83, 1, 1, 1, 104, 67, 18, 1, 1.2138, 0, 0, 0, NULL), +(4, 4, 86, 1, 1, 1, 0, 63, 30, 1, 0.9435, 0, 0, 0, NULL), +(4, 8, 81, 1, 1, 1, 202, 57, 8, 11, 1.1235, 0, 0, 0, NULL), +(5, 1, 102, 1, 1, 1, 0, 120, 17, 1, 1.4422, 0, 0, 0, NULL), +(5, 2, 98, 1, 1, 1, 115, 105, 19, 1, 1.8471, 0, 0, 0, NULL), +(5, 4, 102, 1, 1, 1, 0, 102, 32, 1, 1.5, 0, 0, 0, NULL), +(5, 8, 95, 1, 1, 1, 230, 93, 9, 11, 1.3456, 0, 0, 0, NULL), +(6, 1, 120, 1, 1, 1, 0, 174, 19, 1, 2.1375, 0, 0, 0, NULL), +(6, 2, 115, 1, 1, 1, 126, 150, 24, 1, 2.6006, 0, 0, 0, NULL), +(6, 4, 120, 1, 1, 1, 0, 152, 34, 1, 2.2, 0, 0, 0, NULL), +(6, 8, 111, 1, 1, 1, 259, 139, 10, 11, 1.9557, 0, 0, 0, NULL), +(7, 1, 137, 1, 1, 1, 0, 239, 21, 1, 2.9811, 0, 0, 0, NULL), +(7, 2, 131, 1, 1, 1, 138, 205, 28, 1, 3.5412, 0, 0, 0, NULL), +(7, 4, 137, 1, 1, 1, 0, 212, 36, 1, 3, 0, 0, 0, NULL), +(7, 8, 126, 1, 1, 1, 289, 194, 13, 11, 2.7876, 0, 0, 0, NULL), +(8, 1, 156, 1, 1, 1, 0, 316, 24, 1, 3.485, 0, 0, 0, NULL), +(8, 2, 148, 1, 1, 1, 165, 268, 32, 1, 4.1435, 0, 0, 0, NULL), +(8, 4, 156, 1, 1, 1, 0, 286, 38, 1, 4.3597, 0, 0, 0, NULL), +(8, 8, 143, 1, 1, 1, 319, 265, 15, 11, 3.2334, 0, 0, 0, NULL), +(9, 1, 176, 1, 1, 1, 0, 406, 28, 1, 3.0304, 0, 0, 0, NULL), +(9, 2, 166, 1, 1, 1, 178, 342, 36, 1, 4.7933, 0, 0, 0, NULL), +(9, 4, 176, 1, 1, 1, 0, 363, 40, 1, 4.6993, 0, 0, 0, NULL), +(9, 8, 160, 1, 1, 1, 350, 339, 16, 11, 3.7654, 0, 0, 0, NULL), +(10, 1, 198, 1, 1, 1, 0, 512, 32, 1, 3.2707, 0, 0, 0, NULL), +(10, 2, 186, 1, 1, 1, 191, 426, 38, 1, 5.066, 0, 0, 0, NULL), +(10, 4, 198, 1, 1, 1, 0, 443, 42, 1, 4.8281, 0, 0, 0, NULL), +(10, 8, 178, 1, 1, 1, 382, 423, 17, 12, 4.2456, 0, 0, 0, NULL), +(11, 1, 222, 1, 1, 1, 0, 538, 36, 1, 4.8425, 0, 0, 0, NULL), +(11, 2, 208, 1, 1, 1, 205, 450, 40, 1, 5.3387, 0, 0, 0, NULL), +(11, 4, 222, 1, 1, 1, 0, 488, 44, 1, 5.1609, 0, 0, 0, NULL), +(11, 8, 199, 1, 1, 1, 459, 447, 17, 12, 4.7654, 0, 0, 0, NULL), +(12, 1, 247, 1, 1, 1, 0, 573, 40, 1, 5.603, 0, 0, 0, NULL), +(12, 2, 230, 1, 1, 1, 249, 479, 42, 1, 5.6114, 0, 0, 0, NULL), +(12, 4, 247, 1, 1, 1, 0, 519, 46, 1, 5.6558, 0, 0, 0, NULL), +(12, 8, 219, 1, 1, 1, 537, 475, 18, 12, 5.0345, 0, 0, 0, NULL), +(13, 1, 273, 1, 1, 1, 0, 608, 44, 1, 6.0787, 0, 0, 0, NULL), +(13, 2, 253, 1, 1, 1, 264, 507, 44, 1, 5.8841, 0, 0, 0, NULL), +(13, 4, 273, 1, 1, 1, 0, 553, 48, 1, 6.0221, 0, 0, 0, NULL), +(13, 8, 241, 1, 1, 1, 601, 509, 19, 12, 5.199, 0, 0, 0, NULL), +(14, 1, 300, 1, 1, 1, 0, 642, 50, 1, 6.6101, 0, 0, 0, NULL), +(14, 2, 276, 1, 1, 1, 295, 537, 46, 1, 6.1568, 0, 0, 0, NULL), +(14, 4, 300, 1, 1, 1, 0, 577, 50, 1, 6.6101, 0, 0, 0, NULL), +(14, 8, 263, 1, 1, 1, 710, 523, 21, 12, 5.7241, 0, 0, 0, NULL), +(15, 1, 328, 1, 1, 1, 0, 677, 54, 2, 7.1981, 0, 0, 0, NULL), +(15, 2, 301, 1, 1, 1, 326, 566, 48, 2, 6.8211, 0, 0, 0, NULL), +(15, 4, 328, 1, 1, 1, 0, 612, 54, 2, 7.1981, 0, 0, 0, NULL), +(15, 8, 285, 1, 1, 1, 790, 559, 22, 13, 6.3298, 0, 0, 0, NULL), +(16, 1, 356, 1, 1, 1, 0, 713, 56, 2, 7.7861, 0, 0, 0, NULL), +(16, 2, 325, 1, 1, 1, 357, 596, 52, 2, 7.1374, 0, 0, 0, NULL), +(16, 4, 356, 1, 1, 1, 0, 645, 56, 2, 7.7861, 0, 0, 0, NULL), +(16, 8, 307, 1, 1, 1, 856, 589, 24, 13, 6.6051, 0, 0, 0, NULL), +(17, 1, 386, 1, 1, 1, 0, 748, 60, 2, 8.3741, 0, 0, 0, NULL), +(17, 2, 350, 1, 1, 1, 390, 625, 56, 2, 7.6355, 0, 0, 0, NULL), +(17, 4, 386, 1, 1, 1, 0, 676, 60, 2, 8.3741, 0, 0, 0, NULL), +(17, 8, 330, 1, 1, 1, 938, 617, 26, 13, 7.0485, 0, 0, 0, NULL), +(18, 1, 417, 1, 1, 1, 0, 782, 64, 3, 8.9621, 0, 0, 0, NULL), +(18, 2, 377, 1, 1, 1, 408, 652, 58, 3, 8.1353, 0, 0, 0, NULL), +(18, 4, 417, 1, 1, 1, 0, 706, 64, 3, 8.9621, 0, 0, 0, NULL), +(18, 8, 354, 1, 1, 1, 1020, 643, 27, 13, 7.4083, 0, 0, 0, NULL), +(19, 1, 449, 1, 1, 1, 0, 817, 68, 3, 9.5501, 0, 0, 0, NULL), +(19, 2, 404, 1, 1, 1, 456, 683, 60, 3, 8.6351, 0, 0, 0, NULL), +(19, 4, 449, 1, 1, 1, 0, 738, 68, 3, 9.5501, 0, 0, 0, NULL), +(19, 8, 379, 1, 1, 1, 1118, 674, 28, 13, 7.9334, 0, 0, 0, NULL), +(20, 1, 484, 1, 1, 1, 0, 852, 70, 4, 10.1381, 0, 0, 0, NULL), +(20, 2, 433, 1, 1, 1, 490, 712, 64, 4, 9.0674, 0, 0, 0, NULL), +(20, 4, 484, 1, 1, 1, 0, 769, 70, 4, 10.1381, 0, 0, 0, NULL), +(20, 8, 405, 1, 1, 1, 1202, 701, 30, 14, 8.3382, 0, 0, 0, NULL), +(21, 1, 521, 1, 1, 1, 0, 888, 74, 4, 10.7261, 0, 0, 0, NULL), +(21, 2, 464, 1, 1, 1, 510, 740, 68, 4, 9.3169, 0, 0, 0, NULL), +(21, 4, 521, 1, 1, 1, 0, 801, 74, 4, 10.7261, 0, 0, 0, NULL), +(21, 8, 432, 1, 1, 1, 1272, 729, 32, 14, 8.5517, 0, 0, 0, NULL), +(22, 1, 562, 1, 1, 1, 0, 922, 78, 4, 11.3141, 0, 0, 0, NULL), +(22, 2, 498, 1, 1, 1, 545, 770, 72, 5, 9.7231, 0, 0, 0, NULL), +(22, 4, 562, 1, 1, 1, 0, 833, 78, 4, 11.3141, 0, 0, 0, NULL), +(22, 8, 463, 1, 1, 1, 1357, 759, 34, 14, 8.9102, 0, 0, 0, NULL), +(23, 1, 605, 1, 1, 1, 0, 957, 80, 5, 11.9021, 0, 0, 0, NULL), +(23, 2, 533, 1, 1, 1, 581, 800, 74, 5, 10.0761, 0, 0, 0, NULL), +(23, 4, 605, 1, 1, 1, 0, 863, 80, 5, 11.9021, 0, 0, 0, NULL), +(23, 8, 494, 1, 1, 1, 1443, 786, 35, 14, 9.228, 0, 0, 0, NULL), +(24, 1, 651, 1, 1, 1, 0, 992, 84, 6, 12.4901, 0, 0, 0, NULL), +(24, 2, 571, 1, 1, 1, 618, 829, 78, 6, 10.4619, 0, 0, 0, NULL), +(24, 4, 651, 1, 1, 1, 0, 895, 84, 6, 12.4901, 0, 0, 0, NULL), +(24, 8, 528, 1, 1, 1, 1545, 815, 36, 15, 9.6818, 0, 0, 0, NULL), +(25, 1, 699, 1, 1, 1, 0, 1026, 86, 6, 13.0781, 0, 0, 0, NULL), +(25, 2, 610, 1, 1, 1, 655, 858, 80, 6, 10.8234, 0, 0, 0, NULL), +(25, 4, 699, 1, 1, 1, 0, 926, 86, 6, 13.0781, 0, 0, 0, NULL), +(25, 8, 562, 1, 1, 1, 1633, 843, 37, 15, 10.1014, 0, 0, 0, NULL), +(26, 1, 750, 1, 1, 1, 0, 1061, 90, 7, 13.6661, 0, 0, 0, NULL), +(26, 2, 651, 1, 1, 1, 693, 887, 84, 6, 11.185, 0, 0, 0, NULL), +(26, 4, 750, 1, 1, 1, 0, 957, 90, 7, 13.6661, 0, 0, 0, NULL), +(26, 8, 598, 1, 1, 1, 1707, 871, 39, 15, 10.3246, 0, 0, 0, NULL), +(27, 1, 800, 1, 1, 1, 0, 1097, 92, 7, 14.2541, 0, 0, 0, NULL), +(27, 2, 690, 1, 1, 1, 732, 916, 86, 7, 11.7126, 0, 0, 0, NULL), +(27, 4, 800, 1, 1, 1, 0, 989, 92, 7, 14.2541, 0, 0, 0, NULL), +(27, 8, 633, 1, 1, 1, 1812, 900, 40, 15, 10.804, 0, 0, 0, NULL), +(28, 1, 853, 1, 1, 1, 0, 1130, 96, 8, 14.8421, 0, 0, 0, NULL), +(28, 2, 732, 1, 1, 1, 756, 946, 90, 7, 11.9663, 0, 0, 0, NULL), +(28, 4, 853, 1, 1, 1, 0, 1020, 96, 8, 14.8421, 0, 0, 0, NULL), +(28, 8, 669, 1, 1, 1, 1977, 928, 42, 15, 11.0214, 0, 0, 0, NULL), +(29, 1, 905, 1, 1, 1, 0, 1165, 100, 8, 15.4301, 0, 0, 0, NULL), +(29, 2, 773, 1, 1, 1, 811, 975, 94, 8, 12.352, 0, 0, 0, NULL), +(29, 4, 905, 1, 1, 1, 0, 1051, 100, 8, 15.4301, 0, 0, 0, NULL), +(29, 8, 704, 1, 1, 1, 2068, 957, 44, 16, 11.3608, 0, 0, 0, NULL), +(30, 1, 955, 1, 1, 1, 0, 1200, 102, 9, 16.0181, 0, 0, 0, NULL), +(30, 2, 811, 1, 1, 1, 852, 1004, 94, 8, 13.0007, 0, 0, 0, NULL), +(30, 4, 955, 1, 1, 1, 0, 1082, 102, 9, 16.0181, 0, 0, 0, NULL), +(30, 8, 737, 1, 1, 1, 2175, 984, 44, 16, 11.9607, 0, 0, 0, NULL), +(31, 1, 1006, 1, 1, 1, 0, 1234, 106, 9, 16.6061, 0, 0, 0, NULL), +(31, 2, 850, 1006, 1, 1, 878, 1033, 98, 9, 13.2348, 0, 0, 0, NULL), +(31, 4, 1006, 1, 1, 1, 0, 1113, 106, 9, 16.6061, 0, 0, 0, NULL), +(31, 8, 770, 1, 1, 1, 2253, 1012, 46, 16, 12.16, 0, 0, 0, NULL), +(32, 1, 1057, 1, 1, 1, 0, 1270, 108, 10, 17.1941, 0, 0, 0, NULL), +(32, 2, 888, 1, 1, 1, 935, 1063, 100, 9, 13.6924, 0, 0, 0, NULL), +(32, 4, 1057, 1, 1, 1, 0, 1146, 108, 10, 17.1941, 0, 0, 0, NULL), +(32, 8, 802, 1, 1, 1, 2362, 1042, 47, 16, 12.5746, 0, 0, 0, NULL), +(33, 1, 1110, 1, 1, 1, 0, 1304, 112, 10, 17.7821, 0, 0, 0, NULL), +(33, 2, 928, 1, 1, 1, 963, 1091, 104, 10, 13.9511, 0, 0, 0, NULL), +(33, 4, 1110, 1, 1, 1, 0, 1173, 112, 10, 17.7821, 0, 0, 0, NULL), +(33, 8, 835, 1, 1, 1, 2457, 1065, 49, 17, 12.7966, 0, 0, 0, NULL), +(34, 1, 1163, 1, 1, 1, 0, 1340, 114, 11, 18.3701, 0, 0, 0, NULL), +(34, 2, 967, 1, 1, 1, 1007, 1121, 106, 10, 14.4142, 0, 0, 0, NULL), +(34, 4, 1163, 1, 1, 1, 0, 1208, 114, 11, 18.3701, 0, 0, 0, NULL), +(34, 8, 867, 1, 1, 1, 2553, 1098, 50, 17, 13.2162, 0, 0, 0, NULL), +(35, 1, 1220, 1, 1, 1, 0, 1373, 118, 11, 18.9581, 0, 0, 0, NULL), +(35, 2, 1009, 1, 1, 1, 1067, 1149, 110, 11, 14.7365, 0, 0, 0, NULL), +(35, 4, 1220, 1, 1, 1, 0, 1237, 118, 11, 18.9581, 0, 0, 0, NULL), +(35, 8, 902, 1, 1, 1, 2680, 1124, 52, 17, 13.497, 0, 0, 0, NULL), +(36, 1, 1277, 1, 1, 1, 0, 1480, 120, 12, 19.5461, 0, 0, 0, NULL), +(36, 2, 1050, 1, 1, 1, 1097, 1234, 112, 11, 15.1346, 0, 0, 0, NULL), +(36, 4, 1277, 1, 1, 1, 0, 1349, 120, 12, 19.5461, 0, 0, 0, NULL), +(36, 8, 935, 1, 1, 1, 2763, 1241, 53, 18, 13.8566, 0, 0, 0, NULL), +(37, 1, 1336, 1, 1, 1, 0, 1593, 124, 12, 20.1341, 0, 0, 0, NULL), +(37, 2, 1093, 1, 1, 1, 1142, 1325, 116, 11, 15.5816, 0, 0, 0, NULL), +(37, 4, 1336, 1, 1, 1, 0, 1434, 124, 12, 20.1341, 0, 0, 0, NULL), +(37, 8, 970, 1, 1, 1, 2861, 1300, 54, 18, 14.367, 0, 0, 0, NULL), +(38, 1, 1395, 1, 1, 1, 0, 1709, 128, 13, 20.7221, 0, 0, 0, NULL), +(38, 2, 1135, 1, 1, 1, 1189, 1418, 120, 12, 15.9286, 0, 0, 0, NULL), +(38, 4, 1395, 1, 1, 1, 0, 1538, 128, 13, 20.7221, 0, 0, 0, NULL), +(38, 8, 1004, 1, 1, 1, 2975, 1391, 56, 18, 14.6707, 0, 0, 0, NULL), +(39, 1, 1459, 1, 1, 1, 0, 1834, 132, 13, 21.3101, 0, 0, 0, NULL), +(39, 2, 1180, 1, 1, 1, 1236, 1517, 124, 12, 16.4168, 0, 0, 0, NULL), +(39, 4, 1459, 1, 1, 1, 0, 1649, 132, 13, 21.3101, 0, 0, 0, NULL), +(39, 8, 1040, 1, 1, 1, 3075, 1489, 58, 18, 15.1049, 0, 0, 0, NULL), +(40, 1, 1524, 1, 1, 1, 0, 1964, 136, 14, 21.8981, 0, 0, 0, NULL), +(40, 2, 1226, 1, 1, 1, 1283, 1619, 128, 13, 16.9294, 0, 0, 0, NULL), +(40, 4, 1524, 1, 1, 1, 0, 1764, 136, 14, 21.8981, 0, 0, 0, NULL), +(40, 8, 1077, 1, 1, 1, 3191, 1590, 60, 19, 15.5617, 0, 0, 0, NULL), +(41, 1, 1585, 1, 1, 1, 0, 2101, 142, 15, 22.4861, 0, 0, 0, NULL), +(41, 2, 1268, 1, 1, 1, 1332, 1727, 132, 13, 17.8592, 0, 0, 0, NULL), +(41, 4, 1585, 1, 1, 1, 0, 1886, 142, 15, 22.4861, 0, 0, 0, NULL), +(41, 8, 1110, 1, 1, 1, 3293, 1697, 62, 19, 16.4044, 0, 0, 0, NULL), +(42, 1, 1651, 1, 1, 1, 0, 2246, 152, 15, 23.0741, 0, 0, 0, NULL), +(42, 2, 1321, 1, 1, 1, 1381, 1841, 142, 15, 18.8825, 0, 0, 0, NULL), +(42, 4, 1651, 1, 1, 1, 0, 2015, 152, 15, 23.0741, 0, 0, 0, NULL), +(42, 8, 1156, 1, 1, 1, 3471, 1811, 67, 19, 17.3076, 0, 0, 0, NULL), +(43, 1, 1716, 1, 1, 1, 0, 2397, 162, 16, 23.6621, 0, 0, 0, NULL), +(43, 2, 1373, 1, 1, 1, 1432, 1958, 152, 14, 20.1126, 0, 0, 0, NULL), +(43, 4, 1716, 1, 1, 1, 0, 2148, 162, 16, 23.6621, 0, 0, 0, NULL), +(43, 8, 1201, 1, 1, 1, 3575, 1926, 71, 19, 18.5165, 0, 0, 0, NULL), +(44, 1, 1782, 1, 1, 1, 0, 2557, 174, 16, 24.2501, 0, 0, 0, NULL), +(44, 2, 1426, 1, 1, 1, 1483, 2082, 166, 15, 21.6981, 0, 0, 0, NULL), +(44, 4, 1782, 1, 1, 1, 0, 2303, 174, 16, 24.2501, 0, 0, 0, NULL), +(44, 8, 1247, 1, 1, 1, 3680, 2078, 78, 20, 19.9224, 0, 0, 0, NULL), +(45, 1, 1848, 1, 1, 1, 0, 2725, 184, 17, 24.8381, 0, 0, 0, NULL), +(45, 2, 1478, 1, 1, 1, 1534, 2211, 172, 15, 22.9018, 0, 0, 0, NULL), +(45, 4, 1848, 1, 1, 1, 0, 2436, 184, 17, 24.8381, 0, 0, 0, NULL), +(45, 8, 1294, 1, 1, 1, 3801, 2177, 81, 20, 21.0097, 0, 0, 0, NULL), +(46, 1, 1919, 1, 1, 1, 0, 2780, 188, 17, 25.4261, 0, 0, 0, NULL), +(46, 2, 1535, 1, 1, 1, 1587, 2255, 176, 16, 23.345, 0, 0, 0, NULL), +(46, 4, 1919, 1, 1, 1, 0, 2485, 188, 17, 25.4261, 0, 0, 0, NULL), +(46, 8, 1343, 1, 1, 1, 3923, 2220, 83, 20, 21.4023, 0, 0, 0, NULL), +(47, 1, 1990, 1, 1, 1, 0, 2835, 192, 18, 26.0141, 0, 0, 0, NULL), +(47, 2, 1592, 1, 1, 1, 1640, 2300, 180, 16, 23.9542, 0, 0, 0, NULL), +(47, 4, 1990, 1, 1, 1, 0, 2535, 192, 18, 26.0141, 0, 0, 0, NULL), +(47, 8, 1393, 1, 1, 1, 4031, 2265, 85, 21, 21.9484, 0, 0, 0, NULL), +(48, 1, 2062, 1, 1, 1, 0, 2888, 196, 19, 26.6021, 0, 0, 0, NULL), +(48, 2, 1650, 1, 1, 1, 1695, 2344, 184, 17, 24.401, 0, 0, 0, NULL), +(48, 4, 2062, 1, 1, 1, 0, 2582, 196, 19, 26.6021, 0, 0, 0, NULL), +(48, 8, 1443, 1, 1, 1, 4140, 2307, 87, 21, 22.3444, 0, 0, 0, NULL), +(49, 1, 2138, 1, 1, 1, 0, 2944, 200, 19, 27.1901, 0, 0, 0, NULL), +(49, 2, 1710, 1, 1, 1, 1750, 2389, 188, 17, 24.9975, 0, 0, 0, NULL), +(49, 4, 2138, 1, 1, 1, 0, 2631, 200, 19, 27.1901, 0, 0, 0, NULL), +(49, 8, 1497, 1, 1, 1, 4281, 2349, 89, 21, 22.8788, 0, 0, 0, NULL), +(50, 1, 2215, 1, 1, 1, 0, 2999, 206, 20, 27.7781, 0, 0, 0, NULL), +(50, 2, 1772, 1, 1, 1, 1807, 2432, 194, 18, 25.5204, 0, 0, 0, NULL), +(50, 4, 2215, 1, 1, 1, 0, 2680, 206, 20, 27.7781, 0, 0, 0, NULL), +(50, 8, 1551, 1, 1, 1, 4393, 2393, 91, 22, 23.4508, 0, 0, 0, NULL), +(51, 1, 2292, 1, 1, 1, 0, 3052, 210, 20, 28.3661, 0, 0, 0, NULL), +(51, 2, 1834, 1, 1, 1, 1864, 2477, 198, 19, 26.0047, 0, 0, 0, NULL), +(51, 4, 2292, 1, 1, 1, 0, 2728, 210, 20, 28.3661, 0, 0, 0, NULL), +(51, 8, 1604, 1, 1, 1, 4506, 2437, 93, 22, 23.8815, 0, 0, 0, NULL), +(52, 1, 2371, 1, 1, 1, 0, 3108, 214, 21, 28.9541, 0, 0, 0, NULL), +(52, 2, 1897, 1, 1, 1, 1923, 2522, 202, 19, 26.6877, 0, 0, 0, NULL), +(52, 4, 2371, 1, 1, 1, 0, 2778, 214, 21, 28.9541, 0, 0, 0, NULL), +(52, 8, 1660, 1, 1, 1, 4650, 2481, 95, 22, 24.4958, 0, 0, 0, NULL), +(53, 1, 2453, 1, 1, 1, 0, 3163, 218, 22, 29.5421, 0, 0, 0, NULL), +(53, 2, 1962, 1, 1, 1, 1982, 2566, 206, 20, 27.1912, 0, 0, 0, NULL), +(53, 4, 2453, 1, 1, 1, 0, 2826, 218, 22, 29.5421, 0, 0, 0, NULL), +(53, 8, 1717, 1, 1, 1, 4765, 2524, 97, 23, 24.9442, 0, 0, 0, NULL), +(54, 1, 2533, 1, 1, 1, 0, 3216, 224, 22, 30.1301, 0, 0, 0, NULL), +(54, 2, 2026, 1, 1, 1, 2041, 2610, 210, 20, 27.8506, 0, 0, 0, NULL), +(54, 4, 2533, 1, 1, 1, 0, 2874, 224, 22, 30.1301, 0, 0, 0, NULL), +(54, 8, 1773, 1, 1, 1, 4896, 2567, 99, 23, 25.5368, 0, 0, 0, NULL), +(55, 1, 2614, 1, 1, 1, 0, 3271, 228, 23, 30.7177, 0, 0, 0, NULL), +(55, 2, 2091, 1, 1, 1, 2117, 2654, 214, 21, 28.3834, 0, 0, 0, NULL), +(55, 4, 2614, 1, 1, 1, 0, 2922, 228, 23, 30.7177, 0, 0, 0, NULL), +(55, 8, 1830, 1, 1, 1, 5013, 2609, 101, 23, 26.079, 0, 0, 0, NULL), +(56, 1, 2699, 1, 1, 1, 0, 3327, 234, 23, 31.3057, 0, 0, 0, NULL), +(56, 2, 2159, 1, 1, 1, 2163, 2699, 220, 21, 28.9161, 0, 0, 0, NULL), +(56, 4, 2699, 1, 1, 1, 0, 2972, 234, 23, 31.3057, 0, 0, 0, NULL), +(56, 8, 1889, 1, 1, 1, 5206, 2654, 104, 24, 26.4791, 0, 0, 0, NULL), +(57, 1, 2784, 1, 1, 1, 0, 3380, 238, 24, 31.8937, 42.1353, 0, 0, NULL), +(57, 2, 2227, 1, 1, 1, 2241, 2744, 224, 22, 29.5702, 41.2575, 0, 0, NULL), +(57, 4, 2784, 1, 1, 1, 0, 3020, 238, 24, 31.8937, 42.1353, 0, 0, NULL), +(57, 8, 1949, 1, 1, 1, 5340, 2698, 106, 24, 27.0667, 39.5236, 0, 0, NULL), +(58, 1, 2871, 3989, 1, 1, 0, 3435, 242, 25, 32.4817, 46.9207, 0, 0, NULL), +(58, 2, 2297, 3191, 1, 1, 2289, 2788, 228, 23, 30.1469, 45.5251, 0, 0, NULL), +(58, 4, 2871, 3989, 1, 1, 0, 3068, 242, 25, 32.4817, 46.9207, 0, 0, NULL), +(58, 8, 2010, 2793, 1, 1, 5461, 2740, 107, 24, 27.6972, 43.1021, 0, 0, NULL), +(59, 1, 2961, 4142, 1, 1, 0, 3489, 248, 25, 33.0697, 51.7061, 0, 0, NULL), +(59, 2, 2369, 3314, 1, 1, 2369, 2832, 234, 23, 30.7656, 49.7927, 0, 0, NULL), +(59, 4, 2961, 4142, 1, 1, 0, 3117, 248, 25, 33.0697, 51.7061, 0, 0, NULL), +(59, 8, 2073, 2899, 1, 1, 5598, 2784, 110, 25, 28.1686, 46.5379, 0, 0, NULL), +(60, 1, 3052, 4979, 1, 1, 0, 3791, 252, 26, 33.6577, 56.4915, 0, 0, NULL), +(60, 2, 2442, 3984, 1, 1, 2434, 3075, 238, 24, 31.3842, 54.0603, 0, 0, NULL), +(60, 4, 3052, 4979, 1, 1, 0, 3388, 252, 26, 33.6577, 56.4915, 0, 0, NULL), +(60, 8, 2136, 3484, 1, 1, 5751, 3025, 112, 25, 28.7983, 50.045, 0, 0, NULL), +(61, 1, 3144, 5158, 1, 1, 0, 4091, 258, 28, 34.2457, 61.2769, 0, 0, NULL), +(61, 2, 2515, 4126, 5776, 1, 2486, 3316, 244, 25, 31.9807, 58.3279, 0, 0, NULL), +(61, 4, 3144, 5158, 1, 1, 0, 3655, 258, 28, 34.2457, 61.2769, 0, 0, NULL), +(61, 8, 2201, 3611, 1, 1, 5875, 3263, 115, 25, 29.2976, 53.4807, 0, 0, NULL), +(62, 1, 3237, 5341, 1, 1, 0, 4391, 262, 30, 34.8337, 66.0623, 0, 0, NULL), +(62, 2, 2590, 4274, 1, 1, 2568, 3555, 246, 26, 32.5772, 62.4676, 0, 0, NULL), +(62, 4, 3237, 5341, 1, 1, 0, 3922, 262, 30, 34.8337, 66.0623, 0, 0, NULL), +(62, 8, 2266, 3739, 1, 1, 6015, 3500, 116, 25, 29.7969, 57.2713, 0, 0, NULL), +(63, 1, 3331, 5527, 1, 1, 0, 4691, 268, 32, 35.4217, 70.8477, 0, 0, NULL), +(63, 2, 2665, 4422, 1, 1, 2620, 3795, 252, 26, 33.1737, 66.121, 0, 0, NULL), +(63, 4, 3331, 5527, 1, 1, 0, 4189, 268, 32, 35.4217, 70.8477, 0, 0, NULL), +(63, 8, 2332, 3870, 1, 1, 6156, 3736, 119, 26, 30.2962, 60.577, 0, 0, NULL), +(64, 1, 3427, 5715, 1, 1, 0, 4991, 272, 33, 36.0097, 75.6331, 0, 0, NULL), +(64, 2, 2740, 4572, 1, 1, 2705, 4036, 256, 27, 33.7702, 70.2568, 0, 0, NULL), +(64, 4, 3427, 5715, 1, 1, 0, 4457, 272, 33, 36.0097, 75.6331, 0, 0, NULL), +(64, 8, 2399, 4000, 1, 1, 6299, 3977, 121, 26, 30.7955, 64.3364, 0, 0, NULL), +(65, 1, 3524, 5914, 1, 1, 0, 5291, 278, 35, 36.5977, 80.4185, 0, 0, NULL), +(65, 2, 2819, 4731, 1, 1, 2790, 4275, 262, 29, 34.3667, 74.3252, 0, 0, NULL), +(65, 4, 3524, 5914, 1, 1, 0, 4724, 278, 35, 36.5977, 80.4185, 0, 0, NULL), +(65, 8, 2467, 4140, 4731, 1, 6443, 4214, 124, 26, 31.2948, 68.0244, 0, 0, NULL), +(66, 1, 3635, 6116, 1, 1, 0, 5591, 282, 37, 37.1857, 85.2039, 0, 0, NULL), +(66, 2, 2899, 4892, 6116, 1, 2846, 4515, 266, 29, 34.9632, 78.472, 0, 0, NULL), +(66, 4, 3635, 6116, 1, 1, 0, 5104, 282, 37, 37.1857, 85.2039, 0, 0, NULL), +(66, 8, 2552, 4281, 4892, 1, 6588, 4460, 125, 27, 31.7941, 72.0499, 0, 0, NULL), +(67, 1, 3728, 6326, 1, 1, 0, 5892, 288, 39, 37.7737, 89.9893, 111.174, 0, NULL), +(67, 2, 2982, 5060, 1, 1, 2933, 4755, 272, 31, 35.5597, 82.7944, 110.698, 0, NULL), +(67, 4, 3728, 6326, 1, 1, 0, 5326, 288, 39, 37.7737, 89.9893, 111.174, 0, NULL), +(67, 8, 2610, 4429, 5060, 1, 6749, 4710, 128, 27, 32.2934, 75.9676, 87.7106, 0, NULL), +(68, 1, 3834, 6542, 6986, 1, 0, 6192, 292, 41, 38.3617, 94.7747, 115.224, 0, NULL), +(68, 2, 3067, 5233, 6986, 1, 2991, 4995, 276, 31, 36.1562, 87.2676, 114.869, 0, NULL), +(68, 4, 3834, 6542, 6986, 1, 0, 5527, 292, 41, 38.3617, 94.7747, 115.224, 0, NULL), +(68, 8, 2684, 4580, 5588, 1, 6882, 4928, 130, 27, 32.7927, 79.9198, 96.6868, 0, NULL), +(69, 1, 3942, 6761, 7984, 1, 0, 6492, 298, 43, 38.9497, 99.5601, 119.274, 0, NULL), +(69, 2, 3153, 5409, 7984, 1, 3080, 5235, 282, 32, 36.7527, 91.8915, 119.04, 0, NULL), +(69, 4, 3942, 6761, 7984, 1, 0, 5795, 298, 43, 38.9497, 99.5601, 119.274, 0, NULL), +(69, 8, 2759, 4733, 6387, 1, 7031, 5167, 133, 28, 33.292, 83.8005, 105.591, 0, NULL), +(70, 1, 4050, 6986, 8982, 1, 0, 6792, 304, 44, 39.5377, 104.346, 123.324, 0, NULL), +(70, 2, 3240, 5589, 8982, 1, 3155, 5474, 286, 33, 37.3492, 96.7365, 123.212, 0, NULL), +(70, 4, 4050, 6986, 8982, 1, 0, 6062, 304, 44, 39.5377, 104.346, 123.324, 0, NULL), +(70, 8, 2835, 4890, 7185, 1, 7196, 5404, 135, 28, 33.7913, 87.7526, 114.496, 0, NULL), +(71, 1, 4163, 7181, 9291, 1, 0, 7089, 308, 48, 40.1257, 109.131, 127.374, 0, NULL), +(71, 2, 3330, 5744, 9291, 1, 3231, 5714, 290, 37, 37.9457, 101.004, 127.383, 0, NULL), +(71, 4, 4163, 7181, 9291, 1, 0, 6332, 308, 48, 40.1257, 109.131, 127.374, 0, NULL), +(71, 8, 2914, 5027, 7432, 1, 7332, 5645, 137, 31, 34.2906, 91.7048, 117.829, 0, NULL), +(72, 1, 4278, 7380, 9610, 1, 0, 7387, 314, 53, 40.7137, 113.916, 131.424, 0, NULL), +(72, 2, 3422, 5903, 9610, 1, 3309, 5954, 296, 40, 38.5422, 105.272, 131.092, 0, NULL), +(72, 4, 4278, 7380, 9610, 1, 0, 6602, 314, 53, 40.7137, 113.916, 131.424, 0, NULL), +(72, 8, 2995, 5166, 7688, 1, 7500, 5886, 140, 34, 34.7899, 95.5855, 121.259, 0, NULL), +(73, 1, 4399, 7588, 9940, 19880, 0, 7684, 320, 58, 41.3017, 118.702, 135.474, 0, NULL), +(73, 2, 3519, 6070, 9940, 19880, 3387, 6193, 302, 44, 39.1387, 109.539, 134.908, 0, NULL), +(73, 4, 4399, 7580, 9940, 1, 0, 6872, 320, 58, 41.3017, 118.702, 135.474, 0, NULL), +(73, 8, 3098, 5311, 7952, 1, 7654, 6126, 143, 37, 35.2892, 99.4662, 124.79, 0, NULL), +(74, 1, 4524, 7804, 10282, 1, 0, 7918, 354, 63, 41.8897, 0, 139.524, 0, NULL), +(74, 2, 3619, 6243, 10282, 1, 3466, 7903, 334, 48, 39.7352, 0, 138.836, 0, NULL), +(74, 4, 4524, 1, 10282, 1, 0, 7143, 354, 63, 41.8897, 0, 139.524, 0, NULL), +(74, 8, 3186, 1, 8225, 1, 7809, 6368, 158, 41, 35.7885, 0, 128.423, 0, NULL), +(75, 1, 4652, 8025, 10635, 1, 0, 8219, 392, 68, 42.4777, 0, 143.574, 0, NULL), +(75, 2, 3722, 6420, 10635, 1, 3561, 8204, 370, 53, 40.3317, 0, 142.878, 0, NULL), +(75, 4, 4652, 1, 10635, 1, 0, 7415, 392, 68, 42.4777, 0, 143.574, 0, NULL), +(75, 8, 3256, 5617, 8508, 1, 7981, 6610, 175, 45, 36.2878, 0, 132.162, 0, NULL), +(76, 1, 4781, 8247, 11001, 22002, 0, 8520, 432, 74, 43.0657, 0, 147.624, 0, NULL), +(76, 2, 3825, 6602, 11001, 1, 3643, 8503, 408, 57, 40.9282, 0, 147.038, 0, NULL), +(76, 4, 4781, 1, 11001, 1, 0, 7686, 432, 74, 43.0657, 0, 147.624, 0, NULL), +(76, 8, 3367, 1, 8800, 1, 8139, 6851, 193, 49, 36.7871, 0, 136.01, 0, NULL), +(77, 1, 4916, 8480, 11379, 22758, 0, 8822, 478, 81, 43.6537, 0, 151.674, 0, NULL), +(77, 2, 3933, 6784, 11379, 1, 3725, 8803, 452, 62, 41.5247, 0, 151.319, 0, NULL), +(77, 4, 4916, 1, 11379, 1, 0, 7958, 478, 81, 43.6537, 0, 151.674, 0, NULL), +(77, 8, 3462, 1, 9103, 1, 8313, 7094, 214, 54, 37.2864, 0, 139.97, 0, NULL), +(78, 1, 5052, 8715, 11770, 1, 0, 9124, 528, 88, 44.2417, 0, 155.724, 0, NULL), +(78, 2, 4042, 6972, 11770, 1, 3809, 9104, 500, 68, 42.1212, 0, 155.724, 0, NULL), +(78, 4, 5052, 1, 11770, 1, 0, 8230, 528, 88, 44.2417, 0, 155.724, 0, NULL), +(78, 8, 3558, 1, 9416, 1, 8459, 7335, 236, 58, 37.7857, 0, 144.045, 0, NULL), +(79, 1, 5194, 8960, 12175, 1, 0, 9426, 582, 95, 44.8297, 0, 160.258, 0, NULL), +(79, 2, 4155, 7167, 12175, 1, 3893, 9405, 550, 74, 42.7177, 0, 160.258, 0, NULL), +(79, 4, 5194, 1, 12175, 1, 0, 8503, 582, 95, 44.8297, 0, 160.258, 0, NULL), +(79, 8, 3658, 1, 9740, 1, 8636, 7579, 260, 64, 38.285, 0, 148.239, 0, NULL), +(80, 1, 5342, 9215, 12600, 30951, 0, 9729, 642, 103, 45.4177, 0, 164.924, 197.377, NULL), +(80, 2, 4274, 7373, 12600, 30951, 3994, 9706, 608, 80, 43.3142, 0, 164.924, 195.237, NULL), +(80, 4, 5342, 1, 12600, 30951, 0, 8776, 642, 103, 45.4177, 0, 164.924, 191.179, NULL), +(80, 8, 3739, 1, 10080, 24761, 8814, 7822, 289, 69, 38.7843, 0, 152.412, 183.236, NULL), +(81, 1, 5492, 9474, 13033, 37187, 0, 10033, 708, 112, 46.0057, 0, 168.974, 197.377, NULL), +(81, 2, 4394, 7581, 13033, 37187, 4081, 10007, 670, 86, 43.9107, 0, 169.095, 195.237, NULL), +(81, 4, 5496, 1, 13033, 37187, 0, 9068, 708, 112, 46.0057, 0, 168.974, 191.179, NULL), +(81, 8, 3870, 1, 10486, 29750, 8979, 8102, 304, 74, 39.2836, 0, 157.584, 183.236, NULL), +(82, 1, 5647, 9741, 13481, 44679, 0, 10356, 782, 121, 46.5937, 0, 173.024, 197.377, NULL), +(82, 2, 4518, 7794, 13481, 44679, 4169, 10253, 726, 91, 44.5072, 0, 173.266, 195.237, NULL), +(82, 4, 5647, 1, 13481, 44679, 0, 9348, 782, 121, 46.5937, 0, 173.024, 191.179, NULL), +(82, 8, 3977, 1, 10784, 35743, 9160, 8340, 326, 79, 39.7829, 0, 162.257, 183.236, NULL), +(83, 1, 5808, 10019, 13945, 53681, 0, 10643, 805, 135, 47.1817, 0, 177.074, 197.377, NULL), +(83, 2, 4646, 1, 13945, 53681, 4258, 10643, 783, 98, 45.1037, 0, 177.438, 195.237, NULL), +(83, 4, 5808, 1, 13945, 53681, 0, 9589, 805, 135, 47.1817, 0, 177.074, 191.179, NULL), +(83, 8, 4090, 1, 11156, 42945, 9328, 8505, 343, 84, 40.2822, 0, 167.286, 183.236, NULL), +(84, 1, 5971, 10300, 14409, 64496, 0, 10099, 930, 149, 47.7697, 171.348, 181.124, 197.377, ''), +(84, 2, 4774, 8220, 14409, 64496, 4363, 10893, 840, 105, 45.7002, 156.476, 181.61, 195.237, ''), +(84, 4, 5969, 9780, 14409, 64496, 0, 9830, 828, 149, 47.7697, 171.348, 181.124, 191.179, ''), +(84, 8, 4203, 6906, 11528, 51597, 9512, 8670, 360, 89, 40.7815, 142.154, 172.315, 183.236, ''), +(85, 1, 6141, 10595, 14873, 77490, 0, 10419, 1004, 163, 48.3577, 176.134, 185.174, 197.377, ''), +(85, 2, 4902, 8433, 14873, 77490, 4454, 11213, 897, 112, 46.2967, 160.743, 185.782, 195.237, ''), +(85, 4, 6130, 9980, 14873, 77490, 0, 10071, 851, 163, 48.3577, 176.134, 185.174, 191.179, ''), +(85, 8, 4316, 7051, 11900, 61992, 9697, 8835, 377, 94, 41.2808, 146.035, 177.344, 183.236, ''), +(86, 1, 6306, 10890, 15337, 80195, 0, 10470, 1078, 177, 48.9457, 180.92, 189.224, 217.475, ''), +(86, 2, 5030, 8646, 15337, 80195, 4502, 11533, 954, 119, 46.8932, 165.01, 189.954, 215.339, ''), +(86, 4, 6291, 10180, 15337, 80195, 0, 10312, 874, 177, 48.9457, 180.92, 189.224, 211.376, ''), +(86, 8, 4429, 7196, 12272, 86077, 9873, 9000, 394, 99, 41.7801, 149.915, 182.373, 203.275, ''), +(87, 1, 6472, 11185, 15801, 82994, 0, 10522, 1152, 191, 49.5337, 185.706, 193.274, 217.475, ''), +(87, 2, 5158, 8859, 15801, 82994, 4655, 11853, 1011, 126, 47.4897, 169.277, 194.126, 215.339, ''), +(87, 4, 6452, 10380, 15801, 82994, 0, 10553, 897, 191, 49.5337, 185.706, 193.274, 211.376, ''), +(87, 8, 4542, 7341, 12644, 107596, 10052, 9165, 411, 104, 42.2794, 153.796, 187.402, 203.275, ''), +(88, 1, 6639, 11480, 16265, 85892, 0, 1057, 1226, 205, 50.1217, 190.492, 197.324, 217.475, ''), +(88, 2, 5286, 9072, 16265, 85892, 4735, 12173, 1068, 133, 48.0862, 173.544, 198.298, 215.339, ''), +(88, 4, 6613, 10580, 16265, 85892, 0, 10794, 920, 205, 50.1217, 190.492, 197.324, 211.376, ''), +(88, 8, 4655, 7486, 13016, 68714, 10232, 9330, 428, 109, 42.7787, 157.677, 192.431, 203.275, ''), +(89, 1, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 217.475, NULL), +(89, 2, 1, 1, 1, 107596, 5502, 1, 0, 0, 0, 0, 0, 215.339, NULL), +(89, 4, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 211.376, NULL), +(89, 8, 1, 1, 1, 107596, 10052, 1, 0, 0, 0, 0, 0, 203.275, NULL), +(90, 1, 1, 17672, 17672, 107596, 0, 1, 0, 0, 0, 0, 0, 217.475, NULL), +(90, 2, 1, 1, 1, 107596, 5502, 1, 0, 0, 0, 0, 0, 215.339, NULL), +(90, 4, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 211.376, NULL), +(90, 8, 1, 1, 1, 107596, 10052, 1, 0, 0, 0, 0, 0, 203.275, NULL), +(91, 1, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 217.475, NULL), +(91, 2, 1, 1, 1, 107596, 5502, 1, 0, 0, 0, 0, 0, 215.339, NULL), +(91, 4, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 211.376, NULL), +(91, 8, 1, 1, 1, 107596, 10052, 1, 0, 0, 0, 0, 0, 203.275, NULL), +(92, 1, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 217.475, NULL), +(92, 2, 1, 1, 1, 107596, 5502, 1, 0, 0, 0, 0, 0, 215.339, NULL), +(92, 4, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 211.376, NULL), +(92, 8, 1, 1, 1, 107596, 10052, 1, 0, 0, 0, 0, 0, 203.275, NULL), +(93, 1, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 217.475, NULL), +(93, 2, 1, 1, 1, 107596, 5502, 1, 0, 0, 0, 0, 0, 215.339, NULL), +(93, 4, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 211.376, NULL), +(93, 8, 1, 1, 1, 107596, 10052, 1, 0, 0, 0, 0, 0, 203.275, NULL), +(94, 1, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 217.475, NULL), +(94, 2, 1, 1, 1, 107596, 5502, 1, 0, 0, 0, 0, 0, 215.339, NULL), +(94, 4, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 211.376, NULL), +(94, 8, 1, 1, 1, 107596, 10052, 1, 0, 0, 0, 0, 0, 203.275, NULL), +(95, 1, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 217.475, NULL), +(95, 2, 1, 1, 1, 107596, 5502, 1, 0, 0, 0, 0, 0, 215.339, NULL), +(95, 4, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 211.376, NULL), +(95, 8, 1, 1, 1, 107596, 10052, 1, 0, 0, 0, 0, 0, 203.275, NULL), +(96, 1, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 217.475, NULL), +(96, 2, 1, 1, 1, 107596, 5502, 1, 0, 0, 0, 0, 0, 215.339, NULL), +(96, 4, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 211.376, NULL), +(96, 8, 1, 1, 1, 107596, 10052, 1, 0, 0, 0, 0, 0, 203.275, NULL), +(97, 1, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 217.475, NULL), +(97, 2, 1, 1, 1, 107596, 5502, 1, 0, 0, 0, 0, 0, 215.339, NULL), +(97, 4, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 211.376, NULL), +(97, 8, 1, 1, 1, 107596, 10052, 1, 0, 0, 0, 0, 0, 203.275, NULL), +(98, 1, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 217.475, NULL), +(98, 2, 1, 1, 1, 107596, 5502, 1, 0, 0, 0, 0, 0, 215.339, NULL), +(98, 4, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 211.376, NULL), +(98, 8, 1, 1, 1, 107596, 10052, 1, 0, 0, 0, 0, 0, 203.275, NULL), +(99, 1, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 217.475, NULL), +(99, 2, 1, 1, 1, 107596, 5502, 1, 0, 0, 0, 0, 0, 215.339, NULL), +(99, 4, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 211.376, NULL), +(99, 8, 1, 1, 1, 107596, 10052, 1, 0, 0, 0, 0, 0, 203.275, NULL), +(100, 1, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 217.475, NULL), +(100, 2, 1, 1, 1, 107596, 5502, 1, 0, 0, 0, 0, 0, 215.339, NULL), +(100, 4, 1, 1, 1, 107596, 0, 1, 0, 0, 0, 0, 0, 211.376, NULL), +(100, 8, 1, 1, 1, 107596, 10052, 1, 0, 0, 0, 0, 0, 203.275, NULL); + +ALTER TABLE `creature_template` + ADD COLUMN `Civilian` TINYINT UNSIGNED DEFAULT 0 NOT NULL AFTER `ExperienceModifier`, + ADD COLUMN `PetSpellDataId` INT UNSIGNED DEFAULT 0 NOT NULL AFTER `type`; + +ALTER TABLE `player_classlevelstats` + ADD COLUMN `spi` SMALLINT NOT NULL COMMENT 'spirit' AFTER `inte`; + +ALTER TABLE `player_racestats` + ADD COLUMN `spi` SMALLINT NOT NULL COMMENT 'spirit' AFTER `inte`; diff --git a/src/server/database/Database/Implementation/WorldDatabase.cpp b/src/server/database/Database/Implementation/WorldDatabase.cpp index 2438bc1c1e1..39235e7cb45 100644 --- a/src/server/database/Database/Implementation/WorldDatabase.cpp +++ b/src/server/database/Database/Implementation/WorldDatabase.cpp @@ -62,7 +62,7 @@ void WorldDatabaseConnection::DoPrepareStatements() PrepareStatement(WORLD_SEL_CREATURE_ADDON_BY_GUID, "SELECT guid FROM creature_addon WHERE guid = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, help FROM command", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, KillCredit1, KillCredit2, name, femaleName, subname, TitleAlt, IconName, RequiredExpansion, VignetteID, faction, npcflag, speed_walk, speed_run, scale, Classification, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, unit_flags3, family, trainer_class, type, VehicleId, AIName, MovementType, ctm.HoverInitiallyEnabled, ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, ExperienceModifier, RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, CreatureImmunitiesId, flags_extra, ScriptName, StringId FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ? OR 1 = ?", CONNECTION_SYNCH); + PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, KillCredit1, KillCredit2, name, femaleName, subname, TitleAlt, IconName, RequiredExpansion, VignetteID, faction, npcflag, speed_walk, speed_run, scale, Classification, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, unit_flags3, family, trainer_class, type, PetSpellDataId, VehicleId, AIName, MovementType, ctm.HoverInitiallyEnabled, ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, ExperienceModifier, Civilian, RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, CreatureImmunitiesId, flags_extra, ScriptName, StringId FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ? OR 1 = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_CREATURE_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM creature WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index cc8e3fc7757..60075659717 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -177,6 +177,7 @@ WorldPacket CreatureTemplate::BuildQueryData(LocaleConstant loc, Difficulty diff WorldPackets::Query::CreatureStats& stats = queryTemp.Stats; + stats.Civilian = Civilian; stats.Leader = RacialLeader; stats.Name[0] = Name; @@ -188,6 +189,7 @@ WorldPacket CreatureTemplate::BuildQueryData(LocaleConstant loc, Difficulty diff stats.CreatureType = type; stats.CreatureFamily = family; stats.Classification = uint32(Classification); + stats.PetSpellDataID = PetSpellDataID; for (uint32 i = 0; i < MAX_KILL_CREDIT; ++i) stats.ProxyCreatureID[i] = KillCredit[i]; @@ -251,9 +253,8 @@ CreatureDifficulty const* CreatureTemplate::GetDifficulty(Difficulty difficulty) { DefaultCreatureDifficulty() { - DeltaLevelMin = 0; - DeltaLevelMax = 0; - ContentTuningID = 0; + MinLevel = 1; + MaxLevel = 1; HealthScalingExpansion = 0; HealthModifier = 1.f; ManaModifier = 1.f; @@ -620,17 +621,15 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/, if (updateLevel) SelectLevel(); - else if (!IsGuardian()) + + // Do not update guardian stats here - they are handled in Guardian::InitStatsForLevel() + if (!IsGuardian()) { uint32 previousHealth = GetHealth(); UpdateLevelDependantStats(); // We still re-initialize level dependant stats on entry update if (previousHealth > 0) SetHealth(previousHealth); - } - // Do not update guardian stats here - they are handled in Guardian::InitStatsForLevel() - if (!IsGuardian()) - { SetMeleeDamageSchool(SpellSchools(cInfo->dmgschool)); SetStatFlatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_HOLY])); SetStatFlatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_FIRE])); @@ -1568,25 +1567,23 @@ void Creature::SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDiffic void Creature::SelectLevel() { // Level - ApplyLevelScaling(); - int32 levelWithDelta = m_unitData->ScalingLevelMax + m_unitData->ScalingLevelDelta; - uint8 level = RoundToInterval<int32>(levelWithDelta, 1, STRONG_MAX_LEVEL); - SetLevel(level); - - UpdateLevelDependantStats(); + CreatureDifficulty const* difficulty = GetCreatureDifficulty(); + if (difficulty->MinLevel != difficulty->MaxLevel) + SetLevel(urand(difficulty->MinLevel, difficulty->MaxLevel)); + else + SetLevel(difficulty->MinLevel); } void Creature::UpdateLevelDependantStats() { CreatureTemplate const* cInfo = GetCreatureTemplate(); CreatureClassifications classification = IsPet() ? CreatureClassifications::Normal : cInfo->Classification; - uint8 level = GetLevel(); - CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(level, cInfo->unit_class); + CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(GetLevel(), cInfo->unit_class); // health float healthmod = GetHealthMod(classification); - uint32 basehp = GetMaxHealthByLevel(level); + uint32 basehp = stats->GenerateHealth(m_creatureDifficulty); uint32 health = uint32(basehp * healthmod); SetCreateHealth(health); @@ -1611,7 +1608,7 @@ void Creature::UpdateLevelDependantStats() } // damage - float basedamage = GetBaseDamageForLevel(level); + float basedamage = stats->GenerateBaseDamage(m_creatureDifficulty); float weaponBaseMinDamage = basedamage; float weaponBaseMaxDamage = basedamage * 1.5f; @@ -1628,7 +1625,7 @@ void Creature::UpdateLevelDependantStats() SetStatFlatModifier(UNIT_MOD_ATTACK_POWER, BASE_VALUE, stats->AttackPower); SetStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, stats->RangedAttackPower); - float armor = GetBaseArmorForLevel(level); + float armor = (float)stats->GenerateArmor(m_creatureDifficulty); /// @todo Why is this treated as uint32 when it's a float? SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, armor); } @@ -3008,84 +3005,6 @@ void Creature::UpdateNearbyPlayersInteractions() } } -bool Creature::HasScalableLevels() const -{ - return m_unitData->ContentTuningID != 0; -} - -void Creature::ApplyLevelScaling() -{ - CreatureDifficulty const* creatureDifficulty = GetCreatureDifficulty(); - - if (Optional<ContentTuningLevels> levels = sDB2Manager.GetContentTuningData(creatureDifficulty->ContentTuningID, 0)) - { - SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ScalingLevelMin), levels->MinLevel); - SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ScalingLevelMax), levels->MaxLevel); - } - - int32 mindelta = std::min(creatureDifficulty->DeltaLevelMax, creatureDifficulty->DeltaLevelMin); - int32 maxdelta = std::max(creatureDifficulty->DeltaLevelMax, creatureDifficulty->DeltaLevelMin); - int32 delta = mindelta == maxdelta ? mindelta : irand(mindelta, maxdelta); - - SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ScalingLevelDelta), delta); - SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ContentTuningID), creatureDifficulty->ContentTuningID); -} - -uint64 Creature::GetMaxHealthByLevel(uint8 level) const -{ - CreatureTemplate const* cInfo = GetCreatureTemplate(); - CreatureDifficulty const* creatureDifficulty = GetCreatureDifficulty(); - float baseHealth = sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureHealth, level, creatureDifficulty->GetHealthScalingExpansion(), creatureDifficulty->ContentTuningID, Classes(cInfo->unit_class), 0); - return std::max(baseHealth * creatureDifficulty->HealthModifier, 1.0f); -} - -float Creature::GetHealthMultiplierForTarget(WorldObject const* target) const -{ - if (!HasScalableLevels()) - return 1.0f; - - uint8 levelForTarget = GetLevelForTarget(target); - if (GetLevel() < levelForTarget) - return 1.0f; - - return double(GetMaxHealthByLevel(levelForTarget)) / double(GetCreateHealth()); -} - -float Creature::GetBaseDamageForLevel(uint8 level) const -{ - CreatureTemplate const* cInfo = GetCreatureTemplate(); - CreatureDifficulty const* creatureDifficulty = GetCreatureDifficulty(); - return sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureAutoAttackDps, level, creatureDifficulty->GetHealthScalingExpansion(), creatureDifficulty->ContentTuningID, Classes(cInfo->unit_class), 0); -} - -float Creature::GetDamageMultiplierForTarget(WorldObject const* target) const -{ - if (!HasScalableLevels()) - return 1.0f; - - uint8 levelForTarget = GetLevelForTarget(target); - - return GetBaseDamageForLevel(levelForTarget) / GetBaseDamageForLevel(GetLevel()); -} - -float Creature::GetBaseArmorForLevel(uint8 level) const -{ - CreatureTemplate const* cInfo = GetCreatureTemplate(); - CreatureDifficulty const* creatureDifficulty = GetCreatureDifficulty(); - float baseArmor = sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureArmor, level, creatureDifficulty->GetHealthScalingExpansion(), creatureDifficulty->ContentTuningID, Classes(cInfo->unit_class), 0); - return baseArmor * creatureDifficulty->ArmorModifier; -} - -float Creature::GetArmorMultiplierForTarget(WorldObject const* target) const -{ - if (!HasScalableLevels()) - return 1.0f; - - uint8 levelForTarget = GetLevelForTarget(target); - - return GetBaseArmorForLevel(levelForTarget) / GetBaseArmorForLevel(GetLevel()); -} - uint8 Creature::GetLevelForTarget(WorldObject const* target) const { if (Unit const* unitTarget = target->ToUnit()) @@ -3095,34 +3014,6 @@ uint8 Creature::GetLevelForTarget(WorldObject const* target) const uint8 level = unitTarget->GetLevel() + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF); return RoundToInterval<uint8>(level, 1u, 255u); } - - // If this creature should scale level, adapt level depending of target level - // between UNIT_FIELD_SCALING_LEVEL_MIN and UNIT_FIELD_SCALING_LEVEL_MAX - if (HasScalableLevels()) - { - int32 scalingLevelMin = m_unitData->ScalingLevelMin; - int32 scalingLevelMax = m_unitData->ScalingLevelMax; - int32 scalingLevelDelta = m_unitData->ScalingLevelDelta; - int32 scalingFactionGroup = m_unitData->ScalingFactionGroup; - int32 targetLevel = unitTarget->m_unitData->EffectiveLevel; - if (!targetLevel) - targetLevel = unitTarget->GetLevel(); - - int32 targetLevelDelta = 0; - - if (Player const* playerTarget = target->ToPlayer()) - { - if (scalingFactionGroup && sFactionTemplateStore.AssertEntry(sChrRacesStore.AssertEntry(playerTarget->GetRace())->FactionID)->FactionGroup != scalingFactionGroup) - scalingLevelMin = scalingLevelMax; - - int32 maxCreatureScalingLevel = playerTarget->m_activePlayerData->MaxCreatureScalingLevel; - targetLevelDelta = std::min(maxCreatureScalingLevel > 0 ? maxCreatureScalingLevel - targetLevel : 0, *playerTarget->m_activePlayerData->ScalingPlayerLevelDelta); - } - - int32 levelWithDelta = targetLevel + targetLevelDelta; - int32 level = RoundToInterval(levelWithDelta, scalingLevelMin, scalingLevelMax) + scalingLevelDelta; - return RoundToInterval(level, 1, MAX_LEVEL + 3); - } } return Unit::GetLevelForTarget(target); diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 839abfdd725..a64ba0c02e7 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -187,19 +187,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma void SetInteractionAllowedInCombat(bool interactionAllowed) override; void UpdateNearbyPlayersInteractions() override; - bool HasScalableLevels() const; - void ApplyLevelScaling(); uint8 GetLevelForTarget(WorldObject const* target) const override; - uint64 GetMaxHealthByLevel(uint8 level) const; - float GetHealthMultiplierForTarget(WorldObject const* target) const override; - - float GetBaseDamageForLevel(uint8 level) const; - float GetDamageMultiplierForTarget(WorldObject const* target) const override; - - float GetBaseArmorForLevel(uint8 level) const; - float GetArmorMultiplierForTarget(WorldObject const* target) const override; - bool IsInEvadeMode() const { return HasUnitState(UNIT_STATE_EVADE); } bool IsEvadingAttacks() const { return IsInEvadeMode() || CanNotReachTarget(); } diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h index 1e386ff2da5..31cf963dc69 100644 --- a/src/server/game/Entities/Creature/CreatureData.h +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -436,9 +436,8 @@ struct CreatureModel struct CreatureDifficulty { - int16 DeltaLevelMin; - int16 DeltaLevelMax; - int32 ContentTuningID; + uint8 MinLevel; + uint8 MaxLevel; int32 HealthScalingExpansion; float HealthModifier; float ManaModifier; @@ -507,6 +506,7 @@ struct TC_GAME_API CreatureTemplate CreatureFamily family; // enum CreatureFamily values (optional) uint32 trainer_class; uint32 type; // enum CreatureType values + uint32 PetSpellDataID; int32 resistance[MAX_SPELL_SCHOOL]; uint32 spells[MAX_CREATURE_SPELLS]; uint32 VehicleId; @@ -514,6 +514,7 @@ struct TC_GAME_API CreatureTemplate uint32 MovementType; CreatureMovementData Movement; float ModExperience; + bool Civilian; bool RacialLeader; uint32 movementId; int32 WidgetSetID; @@ -556,11 +557,29 @@ struct TC_GAME_API CreatureTemplate // Defines base stats for creatures (used to calculate HP/mana/armor/attackpower/rangedattackpower/all damage). struct TC_GAME_API CreatureBaseStats { - uint32 BaseMana; - uint32 AttackPower; - uint32 RangedAttackPower; + std::array<uint32, CURRENT_EXPANSION + 1> BaseHealth; + uint32 BaseMana = 0; + uint32 BaseArmor = 0; + uint32 AttackPower = 0; + uint32 RangedAttackPower = 0; + std::array<float, CURRENT_EXPANSION + 1> BaseDamage; // Helpers + + uint32 GenerateHealth(CreatureDifficulty const* difficulty) const { return uint32(ceil(BaseHealth[difficulty->GetHealthScalingExpansion()] * difficulty->HealthModifier)); } + uint32 GenerateMana(CreatureDifficulty const* difficulty) const + { + // Mana can be 0. + if (!BaseMana) + return 0; + + return uint32(ceil(BaseMana * difficulty->ManaModifier)); + } + + uint32 GenerateArmor(CreatureDifficulty const* difficulty) const { return uint32(ceil(BaseArmor * difficulty->ArmorModifier)); } + + float GenerateBaseDamage(CreatureDifficulty const* difficulty) const { return BaseDamage[difficulty->GetHealthScalingExpansion()]; } + static CreatureBaseStats const* GetBaseStats(uint8 level, uint8 unitClass); }; diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index c6966763d9d..2d2cac13da0 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -906,7 +906,10 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) { // remove elite bonuses included in DB values CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(petlevel, cinfo->unit_class); - ApplyLevelScaling(); + float healthmod = GetHealthMod(cinfo->Classification); + uint32 basehp = stats->GenerateHealth(m_creatureDifficulty); + uint32 health = uint32(basehp * healthmod); + uint32 mana = stats->GenerateMana(m_creatureDifficulty); CreatureDifficulty const* creatureDifficulty = GetCreatureDifficulty(); SetCreateHealth(std::max(sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureHealth, petlevel, creatureDifficulty->GetHealthScalingExpansion(), m_unitData->ContentTuningID, Classes(cinfo->unit_class), 0) * creatureDifficulty->HealthModifier * GetHealthMod(cinfo->Classification), 1.0f)); @@ -915,6 +918,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) SetCreateStat(STAT_AGILITY, 22); SetCreateStat(STAT_STAMINA, 25); SetCreateStat(STAT_INTELLECT, 28); + SetCreateStat(STAT_SPIRIT, 27); } // Power @@ -1069,7 +1073,8 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) * should be copied here (or moved to another method or if that function should be called here * or not just for this default case) */ - float basedamage = GetBaseDamageForLevel(petlevel); + CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(petlevel, cinfo->unit_class); + float basedamage = stats->GenerateBaseDamage(m_creatureDifficulty); float weaponBaseMinDamage = basedamage; float weaponBaseMaxDamage = basedamage * 1.5f; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 5aaa3e6e080..eb9c3a9b7c1 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -352,15 +352,15 @@ void ObjectMgr::LoadCreatureTemplates() // "faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, " // 21 22 23 24 // "unit_class, unit_flags, unit_flags2, unit_flags3, " - // 25 26 27 28 29 30 - // "family, trainer_class, type, VehicleId, AIName, MovementType, " - // 31 32 33 34 35 + // 25 26 27 28 29 30 31 + // "family, trainer_class, type, PetSpellDataId, VehicleId, AIName, MovementType, " + // 32 33 34 35 36 // "ctm.HoverInitiallyEnabled, ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, ExperienceModifier, " - // 36 37 38 39 40 - // "RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, " - // 41 42 + // 37 38 39 40 41 42 + // "Civilian, RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, " + // 43 44 // "CreatureImmunitiesId, flags_extra, " - // 43 44 + // 45 46 // "ScriptName, StringId FROM creature_template WHERE entry = ? OR 1 = ?"); WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_TEMPLATE); @@ -429,6 +429,7 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields) creatureTemplate.family = CreatureFamily(fields[25].GetInt32()); creatureTemplate.trainer_class = uint32(fields[26].GetUInt8()); creatureTemplate.type = uint32(fields[27].GetUInt8()); + creatureTemplate.PetSpellDataID = uint32(fields[28].GetUInt32()); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) creatureTemplate.resistance[i] = 0; @@ -436,32 +437,33 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields) for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i) creatureTemplate.spells[i] = 0; - creatureTemplate.VehicleId = fields[28].GetUInt32(); - creatureTemplate.AIName = fields[29].GetString(); - creatureTemplate.MovementType = uint32(fields[30].GetUInt8()); - - if (!fields[31].IsNull()) - creatureTemplate.Movement.HoverInitiallyEnabled = fields[31].GetBool(); + creatureTemplate.VehicleId = fields[29].GetUInt32(); + creatureTemplate.AIName = fields[30].GetString(); + creatureTemplate.MovementType = uint32(fields[31].GetUInt8()); if (!fields[32].IsNull()) - creatureTemplate.Movement.Chase = static_cast<CreatureChaseMovementType>(fields[32].GetUInt8()); + creatureTemplate.Movement.HoverInitiallyEnabled = fields[32].GetBool(); if (!fields[33].IsNull()) - creatureTemplate.Movement.Random = static_cast<CreatureRandomMovementType>(fields[33].GetUInt8()); + creatureTemplate.Movement.Chase = static_cast<CreatureChaseMovementType>(fields[33].GetUInt8()); if (!fields[34].IsNull()) - creatureTemplate.Movement.InteractionPauseTimer = fields[34].GetUInt32(); + creatureTemplate.Movement.Random = static_cast<CreatureRandomMovementType>(fields[34].GetUInt8()); + + if (!fields[35].IsNull()) + creatureTemplate.Movement.InteractionPauseTimer = fields[35].GetUInt32(); - creatureTemplate.ModExperience = fields[35].GetFloat(); - creatureTemplate.RacialLeader = fields[36].GetBool(); - creatureTemplate.movementId = fields[37].GetUInt32(); - creatureTemplate.WidgetSetID = fields[38].GetInt32(); - creatureTemplate.WidgetSetUnitConditionID = fields[39].GetInt32(); - creatureTemplate.RegenHealth = fields[40].GetBool(); - creatureTemplate.CreatureImmunitiesId = fields[41].GetInt32(); - creatureTemplate.flags_extra = fields[42].GetUInt32(); - creatureTemplate.ScriptID = GetScriptId(fields[43].GetString()); - creatureTemplate.StringId = fields[44].GetString(); + creatureTemplate.ModExperience = fields[36].GetFloat(); + creatureTemplate.Civilian = fields[37].GetBool(); + creatureTemplate.RacialLeader = fields[38].GetBool(); + creatureTemplate.movementId = fields[39].GetUInt32(); + creatureTemplate.WidgetSetID = fields[40].GetInt32(); + creatureTemplate.WidgetSetUnitConditionID = fields[41].GetInt32(); + creatureTemplate.RegenHealth = fields[42].GetBool(); + creatureTemplate.CreatureImmunitiesId = fields[43].GetInt32(); + creatureTemplate.flags_extra = fields[44].GetUInt32(); + creatureTemplate.ScriptID = GetScriptId(fields[45].GetString()); + creatureTemplate.StringId = fields[46].GetString(); } void ObjectMgr::LoadCreatureTemplateGossip() @@ -924,13 +926,13 @@ void ObjectMgr::LoadCreatureTemplateDifficulty() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 - QueryResult result = WorldDatabase.Query("SELECT Entry, DifficultyID, LevelScalingDeltaMin, LevelScalingDeltaMax, ContentTuningID, HealthScalingExpansion, " - // 6 7 8 9 10 11 12 + // 0 1 2 3 4 + QueryResult result = WorldDatabase.Query("SELECT Entry, DifficultyID, MinLevel, MaxLevel, HealthScalingExpansion, " + // 5 6 7 8 9 10 11 "HealthModifier, ManaModifier, ArmorModifier, DamageModifier, CreatureDifficultyID, TypeFlags, TypeFlags2, " - // 13 14 15 16 17 + // 12 13 14 15 16 "LootID, PickPocketLootID, SkinLootID, GoldMin, GoldMax," - // 18 19 20 21 22 23 24 25 + // 17 18 19 20 21 22 23 24 "StaticFlags1, StaticFlags2, StaticFlags3, StaticFlags4, StaticFlags5, StaticFlags6, StaticFlags7, StaticFlags8 " "FROM creature_template_difficulty ORDER BY Entry"); @@ -956,30 +958,51 @@ void ObjectMgr::LoadCreatureTemplateDifficulty() } CreatureDifficulty creatureDifficulty; - creatureDifficulty.DeltaLevelMin = fields[2].GetInt16(); - creatureDifficulty.DeltaLevelMax = fields[3].GetInt16(); - creatureDifficulty.ContentTuningID = fields[4].GetInt32(); - creatureDifficulty.HealthScalingExpansion = fields[5].GetInt32(); - creatureDifficulty.HealthModifier = fields[6].GetFloat(); - creatureDifficulty.ManaModifier = fields[7].GetFloat(); - creatureDifficulty.ArmorModifier = fields[8].GetFloat(); - creatureDifficulty.DamageModifier = fields[9].GetFloat(); - creatureDifficulty.CreatureDifficultyID = fields[10].GetInt32(); - creatureDifficulty.TypeFlags = fields[11].GetUInt32(); - creatureDifficulty.TypeFlags2 = fields[12].GetUInt32(); - creatureDifficulty.LootID = fields[13].GetUInt32(); - creatureDifficulty.PickPocketLootID = fields[14].GetUInt32(); - creatureDifficulty.SkinLootID = fields[15].GetUInt32(); - creatureDifficulty.GoldMin = fields[16].GetUInt32(); - creatureDifficulty.GoldMax = fields[17].GetUInt32(); - creatureDifficulty.StaticFlags = CreatureStaticFlagsHolder(CreatureStaticFlags(fields[18].GetUInt32()), CreatureStaticFlags2(fields[19].GetUInt32()), - CreatureStaticFlags3(fields[20].GetUInt32()), CreatureStaticFlags4(fields[21].GetUInt32()), CreatureStaticFlags5(fields[22].GetUInt32()), - CreatureStaticFlags6(fields[23].GetUInt32()), CreatureStaticFlags7(fields[24].GetUInt32()), CreatureStaticFlags8(fields[25].GetUInt32())); + creatureDifficulty.MinLevel = fields[2].GetUInt8(); + creatureDifficulty.MaxLevel = fields[3].GetUInt8(); + creatureDifficulty.HealthScalingExpansion = fields[4].GetInt32(); + creatureDifficulty.HealthModifier = fields[5].GetFloat(); + creatureDifficulty.ManaModifier = fields[6].GetFloat(); + creatureDifficulty.ArmorModifier = fields[7].GetFloat(); + creatureDifficulty.DamageModifier = fields[8].GetFloat(); + creatureDifficulty.CreatureDifficultyID = fields[9].GetInt32(); + creatureDifficulty.TypeFlags = fields[10].GetUInt32(); + creatureDifficulty.TypeFlags2 = fields[11].GetUInt32(); + creatureDifficulty.LootID = fields[12].GetUInt32(); + creatureDifficulty.PickPocketLootID = fields[13].GetUInt32(); + creatureDifficulty.SkinLootID = fields[14].GetUInt32(); + creatureDifficulty.GoldMin = fields[15].GetUInt32(); + creatureDifficulty.GoldMax = fields[16].GetUInt32(); + creatureDifficulty.StaticFlags = CreatureStaticFlagsHolder(CreatureStaticFlags(fields[17].GetUInt32()), CreatureStaticFlags2(fields[18].GetUInt32()), + CreatureStaticFlags3(fields[19].GetUInt32()), CreatureStaticFlags4(fields[20].GetUInt32()), CreatureStaticFlags5(fields[21].GetUInt32()), + CreatureStaticFlags6(fields[22].GetUInt32()), CreatureStaticFlags7(fields[23].GetUInt32()), CreatureStaticFlags8(fields[24].GetUInt32())); // TODO: Check if this still applies creatureDifficulty.DamageModifier *= Creature::GetDamageMod(itr->second.Classification); - if (creatureDifficulty.HealthScalingExpansion < EXPANSION_LEVEL_CURRENT || creatureDifficulty.HealthScalingExpansion >= MAX_EXPANSIONS) + if (creatureDifficulty.MinLevel == 0 || creatureDifficulty.MaxLevel == 0) + { + if (creatureDifficulty.MinLevel == 0) + { + TC_LOG_ERROR("sql.sql", "Table `creature_template_difficulty` lists creature (ID: {}) has MinLevel set to 0 but the allowed minimum is 1. Ignored and set to 1.", entry); + creatureDifficulty.MinLevel = 1; + } + + if (creatureDifficulty.MaxLevel == 0) + { + TC_LOG_ERROR("sql.sql", "Table `creature_template_difficulty` lists creature (ID: {}) has MaxLevel set to 0 but the allowed minimum is 1. Ignored and set to 1.", entry); + creatureDifficulty.MaxLevel = 1; + } + } + + if (creatureDifficulty.MinLevel > creatureDifficulty.MaxLevel) + { + TC_LOG_ERROR("sql.sql", "Table `creature_template_difficulty` lists creature (ID: {}) with a higher MinLevel ({}) than MaxLevel ({}). MaxLevel will be set to MinLevel value.", + entry, creatureDifficulty.MinLevel, creatureDifficulty.MaxLevel); + creatureDifficulty.MinLevel = creatureDifficulty.MaxLevel; + } + + if (creatureDifficulty.HealthScalingExpansion < EXPANSION_LEVEL_CURRENT || creatureDifficulty.HealthScalingExpansion > CURRENT_EXPANSION) { TC_LOG_ERROR("sql.sql", "Table `creature_template_difficulty` lists creature (ID: {}) with invalid `HealthScalingExpansion` {}. Ignored and set to 0.", entry, creatureDifficulty.HealthScalingExpansion); @@ -4169,7 +4192,8 @@ void ObjectMgr::LoadPlayerInfo() uint32 oldMSTime = getMSTime(); - QueryResult raceStatsResult = WorldDatabase.Query("SELECT race, str, agi, sta, inte FROM player_racestats"); + // 0 1 2 3 4 5 6 + QueryResult raceStatsResult = WorldDatabase.Query("SELECT race, str, agi, sta, inte, spi FROM player_racestats"); if (!raceStatsResult) { @@ -4193,8 +4217,8 @@ void ObjectMgr::LoadPlayerInfo() } while (raceStatsResult->NextRow()); - // 0 1 2 3 4 5 - QueryResult result = WorldDatabase.Query("SELECT class, level, str, agi, sta, inte FROM player_classlevelstats"); + // 0 1 2 3 4 5 6 + QueryResult result = WorldDatabase.Query("SELECT class, level, str, agi, sta, inte, spi FROM player_classlevelstats"); if (!result) { @@ -9962,8 +9986,8 @@ CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint8 level, uint8 unit void ObjectMgr::LoadCreatureClassLevelStats() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 - QueryResult result = WorldDatabase.Query("SELECT level, class, basemana, attackpower, rangedattackpower FROM creature_classlevelstats"); + // 0 1 2 3 4 5 6 7 8 9 10 12 13 14 + QueryResult result = WorldDatabase.Query("SELECT level, class, basehp0, basehp1, basehp2, basehp3, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2, damage_exp3 FROM creature_classlevelstats"); if (!result) { @@ -9984,10 +10008,29 @@ void ObjectMgr::LoadCreatureClassLevelStats() CreatureBaseStats stats; - stats.BaseMana = fields[2].GetUInt32(); + for (uint8 i = 0; i <= CURRENT_EXPANSION; ++i) + { + stats.BaseHealth[i] = fields[2 + i].GetUInt32(); + + if (stats.BaseHealth[i] == 0) + { + TC_LOG_ERROR("sql.sql", "Creature base stats for class {}, level {} has invalid zero base HP[{}] - set to 1", Class, Level, i); + stats.BaseHealth[i] = 1; + } + + stats.BaseDamage[i] = fields[10 + i].GetFloat(); + if (stats.BaseDamage[i] < 0.0f) + { + TC_LOG_ERROR("sql.sql", "Creature base stats for class {}, level {} has invalid negative base damage[{}] - set to 0.0", Class, Level, i); + stats.BaseDamage[i] = 0.0f; + } + } + + stats.BaseMana = fields[6].GetUInt32(); + stats.BaseArmor = fields[7].GetUInt32(); - stats.AttackPower = fields[3].GetUInt16(); - stats.RangedAttackPower = fields[4].GetUInt16(); + stats.AttackPower = fields[8].GetUInt16(); + stats.RangedAttackPower = fields[9].GetUInt16(); _creatureBaseStatsStore[MAKE_PAIR16(Level, Class)] = stats; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 08954b5c251..3766d4109e2 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -276,9 +276,10 @@ enum Stats : uint16 STAT_AGILITY = 1, STAT_STAMINA = 2, STAT_INTELLECT = 3, + STAT_SPIRIT = 4 }; -#define MAX_STATS 4 +#define MAX_STATS 5 // EnumUtils: DESCRIBE THIS enum Powers : int8 diff --git a/src/server/game/Server/Packets/CombatLogPacketsCommon.cpp b/src/server/game/Server/Packets/CombatLogPacketsCommon.cpp index e2435ae0660..cb817e72762 100644 --- a/src/server/game/Server/Packets/CombatLogPacketsCommon.cpp +++ b/src/server/game/Server/Packets/CombatLogPacketsCommon.cpp @@ -78,7 +78,6 @@ bool ContentTuningParams::GenerateDataForUnits<Creature, Player>(Creature* attac TargetLevel = target->GetLevel(); Expansion = creatureDifficulty->HealthScalingExpansion; TargetScalingLevelDelta = int8(attacker->m_unitData->ScalingLevelDelta); - TargetContentTuningID = creatureDifficulty->ContentTuningID; return true; } @@ -96,14 +95,13 @@ bool ContentTuningParams::GenerateDataForUnits<Player, Creature>(Player* attacke TargetLevel = target->GetLevel(); Expansion = creatureDifficulty->HealthScalingExpansion; TargetScalingLevelDelta = int8(target->m_unitData->ScalingLevelDelta); - TargetContentTuningID = creatureDifficulty->ContentTuningID; return true; } template<> bool ContentTuningParams::GenerateDataForUnits<Creature, Creature>(Creature* attacker, Creature* target) { - Creature* accessor = target->HasScalableLevels() ? target : attacker; + Creature* accessor = attacker; CreatureTemplate const* creatureTemplate = accessor->GetCreatureTemplate(); CreatureDifficulty const* creatureDifficulty = creatureTemplate->GetDifficulty(accessor->GetMap()->GetDifficultyID()); @@ -113,7 +111,6 @@ bool ContentTuningParams::GenerateDataForUnits<Creature, Creature>(Creature* att TargetLevel = target->GetLevel(); Expansion = creatureDifficulty->HealthScalingExpansion; TargetScalingLevelDelta = int8(accessor->m_unitData->ScalingLevelDelta); - TargetContentTuningID = creatureDifficulty->ContentTuningID; return true; } @@ -121,28 +118,8 @@ template<> bool ContentTuningParams::GenerateDataForUnits<Unit, Unit>(Unit* attacker, Unit* target) { if (Player* playerAttacker = Object::ToPlayer(attacker)) - { if (Player* playerTarget = Object::ToPlayer(target)) return GenerateDataForUnits(playerAttacker, playerTarget); - else if (Creature* creatureTarget = Object::ToCreature(target)) - { - if (creatureTarget->HasScalableLevels()) - return GenerateDataForUnits(playerAttacker, creatureTarget); - } - } - else if (Creature* creatureAttacker = Object::ToCreature(attacker)) - { - if (Player* playerTarget = Object::ToPlayer(target)) - { - if (creatureAttacker->HasScalableLevels()) - return GenerateDataForUnits(creatureAttacker, playerTarget); - } - else if (Creature* creatureTarget = Object::ToCreature(target)) - { - if (creatureAttacker->HasScalableLevels() || creatureTarget->HasScalableLevels()) - return GenerateDataForUnits(creatureAttacker, creatureTarget); - } - } return false; } |