aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/base/characters_database.sql3
-rw-r--r--sql/updates/characters/master/2018_04_28_00_characters.sql803
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp2
-rw-r--r--src/server/game/DataStores/DBCEnums.h36
-rw-r--r--src/server/game/Entities/Item/Item.cpp71
-rw-r--r--src/server/game/Entities/Item/Item.h7
-rw-r--r--src/server/game/Entities/Player/Player.cpp7
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp4
8 files changed, 891 insertions, 42 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql
index 9e08c4a4a31..1084311bc84 100644
--- a/sql/base/characters_database.sql
+++ b/sql/base/characters_database.sql
@@ -3562,7 +3562,8 @@ INSERT INTO `updates` VALUES
('2018_02_03_00_characters.sql','73E9BFD848D7A22F2A7DD89CF64E30E3A8689512','ARCHIVED','2018-02-03 23:52:42',0),
('2018_02_08_00_characters.sql','75FA162A9B85D678B26F972371265F1EC2C75187','ARCHIVED','2018-02-08 22:23:28',0),
('2018_02_19_00_characters.sql','75A0FFAFD0633921708DB0F72F9CC9796ACB960B','RELEASED','2018-02-19 22:33:32',117),
-('2018_03_04_00_characters.sql','2A4CD2EE2547E718490706FADC78BF36F0DED8D6','RELEASED','2018-03-04 18:15:24',0);
+('2018_03_04_00_characters.sql','2A4CD2EE2547E718490706FADC78BF36F0DED8D6','RELEASED','2018-03-04 18:15:24',0),
+('2018_04_28_00_characters.sql','CBD0FDC0F32DE3F456F7CE3D9CAD6933CD6A50F5','RELEASED','2018-04-28 12:44:09',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/characters/master/2018_04_28_00_characters.sql b/sql/updates/characters/master/2018_04_28_00_characters.sql
new file mode 100644
index 00000000000..a6a61dd3ab2
--- /dev/null
+++ b/sql/updates/characters/master/2018_04_28_00_characters.sql
@@ -0,0 +1,803 @@
+-- Setup temporary table with list of fixed-scaling item bonuses, and their scaling limits
+DROP TABLE IF EXISTS `tmp_scale_data`;
+CREATE TEMPORARY TABLE `tmp_scale_data` (
+ `BonusListID` int(10) unsigned NOT NULL,
+ `MinLevel` int(10) unsigned NOT NULL,
+ `MaxLevel` int(10) unsigned NOT NULL,
+ PRIMARY KEY (`BonusListID`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+INSERT INTO `tmp_scale_data` (`BonusListID`, `MinLevel`, `MaxLevel`) VALUES
+(615,1,110),
+(645,1,110),
+(656,1,110),
+(664,98,110),
+(692,1,110),
+(767,98,110),
+(768,98,110),
+(1723,0,110),
+(1724,0,110),
+(1725,0,110),
+(1729,0,110),
+(1730,0,110),
+(1731,0,110),
+(1732,98,110),
+(1733,98,110),
+(1734,0,110),
+(1735,0,110),
+(1736,0,110),
+(1737,0,110),
+(1738,0,110),
+(1739,0,110),
+(1740,0,110),
+(1741,0,110),
+(1788,0,110),
+(1789,0,110),
+(1790,0,110),
+(1791,0,110),
+(1792,0,110),
+(1793,0,110),
+(1794,98,110),
+(1795,0,110),
+(1796,0,110),
+(1812,98,110),
+(3342,98,110),
+(3380,0,110),
+(3387,1,100),
+(3388,1,100),
+(3389,1,100),
+(3398,0,110),
+(3448,0,110),
+(3502,1,110),
+(3578,1,110),
+(3585,1,110),
+(3589,1,110),
+(3590,1,110),
+(3596,1,110),
+(3621,1,110),
+(3622,1,110),
+(3623,1,110),
+(3624,1,110),
+(3625,1,110),
+(3626,1,110),
+(3627,1,110),
+(3628,1,110),
+(3631,0,120),
+(3633,10,60),
+(3634,10,60),
+(3635,10,60),
+(3636,10,60),
+(3637,10,60),
+(3638,10,60),
+(3639,10,60),
+(3640,10,60),
+(3641,15,60),
+(3642,15,60),
+(3643,15,60),
+(3644,20,60),
+(3645,20,60),
+(3646,20,60),
+(3647,25,60),
+(3648,25,60),
+(3649,25,60),
+(3650,30,60),
+(3651,30,60),
+(3652,40,60),
+(3653,35,60),
+(3654,35,60),
+(3655,30,60),
+(3656,35,60),
+(3657,40,60),
+(3658,40,60),
+(3659,40,60),
+(3660,40,60),
+(3661,40,60),
+(3662,40,60),
+(3663,40,60),
+(3664,40,60),
+(3665,40,60),
+(3666,40,60),
+(3667,40,60),
+(3668,5,20),
+(3669,4,20),
+(3670,5,20),
+(3671,4,20),
+(3672,5,20),
+(3673,4,20),
+(3674,5,20),
+(3675,5,20),
+(3676,5,20),
+(3677,5,20),
+(3678,5,20),
+(3679,58,80),
+(3680,60,80),
+(3681,62,80),
+(3682,65,80),
+(3683,67,80),
+(3684,67,80),
+(3685,58,80),
+(3686,58,80),
+(3687,61,80),
+(3688,63,80),
+(3689,64,80),
+(3690,66,80),
+(3691,67,80),
+(3692,67,80),
+(3693,80,90),
+(3694,80,90),
+(3695,82,90),
+(3696,83,90),
+(3697,84,90),
+(3698,80,90),
+(3699,81,90),
+(3700,81,90),
+(3701,82,90),
+(3702,83,90),
+(3703,84,90),
+(3704,85,90),
+(3705,90,100),
+(3706,90,100),
+(3707,94,100),
+(3708,92,100),
+(3709,96,100),
+(3710,98,100),
+(3711,90,100),
+(3712,10,60),
+(3713,10,60),
+(3714,10,60),
+(3715,10,60),
+(3716,10,60),
+(3717,10,60),
+(3718,10,60),
+(3719,10,60),
+(3720,15,60),
+(3721,15,60),
+(3722,15,60),
+(3723,20,60),
+(3724,20,60),
+(3725,20,60),
+(3726,25,60),
+(3727,25,60),
+(3728,25,60),
+(3729,30,60),
+(3730,30,60),
+(3731,40,60),
+(3732,35,60),
+(3733,35,60),
+(3734,30,60),
+(3735,35,60),
+(3736,40,60),
+(3737,40,60),
+(3738,40,60),
+(3739,40,60),
+(3740,40,60),
+(3741,40,60),
+(3742,40,60),
+(3743,40,60),
+(3744,40,60),
+(3745,40,60),
+(3746,40,60),
+(3747,5,20),
+(3748,4,20),
+(3749,5,20),
+(3750,4,20),
+(3751,5,20),
+(3752,4,20),
+(3753,5,20),
+(3754,5,20),
+(3755,5,20),
+(3756,5,20),
+(3757,5,20),
+(3758,58,80),
+(3759,60,80),
+(3760,62,80),
+(3761,65,80),
+(3762,67,80),
+(3763,67,80),
+(3764,58,80),
+(3765,58,80),
+(3766,61,80),
+(3767,63,80),
+(3768,64,80),
+(3769,66,80),
+(3770,67,80),
+(3771,67,80),
+(3772,80,90),
+(3773,80,90),
+(3774,82,90),
+(3775,83,90),
+(3776,84,90),
+(3777,85,90),
+(3778,81,90),
+(3779,81,90),
+(3780,82,90),
+(3781,83,90),
+(3782,84,90),
+(3783,85,90),
+(3784,90,100),
+(3785,90,100),
+(3786,94,100),
+(3787,92,100),
+(3788,96,100),
+(3789,98,100),
+(3790,90,100),
+(3791,64,80),
+(3792,64,80),
+(3793,5,20),
+(3794,4,20),
+(3795,5,20),
+(3796,4,20),
+(3797,5,20),
+(3798,4,20),
+(3799,0,120),
+(3800,5,20),
+(3801,5,20),
+(3802,5,20),
+(3803,5,20),
+(3804,67,80),
+(3805,84,90),
+(3806,83,90),
+(3807,0,120),
+(3808,0,120),
+(3809,0,120),
+(3810,0,120),
+(3811,0,120),
+(3812,0,120),
+(3813,0,120),
+(3814,0,120),
+(3815,0,120),
+(3816,0,120),
+(3817,0,120),
+(3818,0,120),
+(3819,0,120),
+(3820,85,90),
+(3821,85,90),
+(3823,40,60),
+(3828,0,120),
+(3829,0,120),
+(3830,0,120),
+(3831,0,120),
+(3832,0,120),
+(3833,0,120),
+(3834,0,120),
+(3835,0,120),
+(3836,0,120),
+(3837,0,120),
+(3838,0,120),
+(3839,0,120),
+(3840,0,120),
+(3841,0,120),
+(3842,0,120),
+(3843,0,120),
+(3844,0,120),
+(3845,0,120),
+(3846,0,120),
+(3847,0,120),
+(3848,0,120),
+(3849,0,120),
+(3850,0,120),
+(3851,0,120),
+(3852,0,120),
+(3853,0,120),
+(3854,0,120),
+(3855,0,120),
+(3856,0,120),
+(3857,0,120),
+(3858,0,120),
+(3859,0,120),
+(3860,0,120),
+(3861,0,120),
+(3862,0,120),
+(3863,0,120),
+(3864,0,120),
+(3865,0,120),
+(3866,0,120),
+(3867,0,120),
+(3868,0,120),
+(3869,0,120),
+(3870,0,120),
+(3871,0,120),
+(3872,0,120),
+(3873,0,120),
+(3874,0,120),
+(3875,0,120),
+(3876,0,120),
+(3877,0,120),
+(3878,0,120),
+(3879,0,120),
+(3880,0,120),
+(3881,0,120),
+(3882,0,120),
+(3883,0,120),
+(3884,0,120),
+(3885,0,120),
+(3886,0,120),
+(3887,0,120),
+(3888,0,120),
+(3889,0,120),
+(3890,0,120),
+(3891,0,120),
+(3892,0,120),
+(3893,0,120),
+(3894,0,120),
+(3895,0,120),
+(3896,0,120),
+(3897,0,120),
+(3898,0,120),
+(3899,0,120),
+(3900,0,120),
+(3901,0,120),
+(3902,0,120),
+(3903,0,120),
+(3904,0,120),
+(3905,0,120),
+(3906,0,120),
+(3907,0,120),
+(3908,0,120),
+(3909,0,120),
+(3910,0,120),
+(3911,0,120),
+(3912,0,120),
+(3913,0,120),
+(3914,0,120),
+(3915,0,120),
+(3916,0,120),
+(3917,0,120),
+(3918,0,120),
+(3919,0,120),
+(3920,0,120),
+(3921,0,120),
+(3922,0,120),
+(3923,0,120),
+(3924,0,120),
+(3925,0,120),
+(3926,0,120),
+(3927,0,120),
+(3928,0,120),
+(3929,0,120),
+(3930,0,120),
+(3931,0,120),
+(3932,0,120),
+(3933,0,120),
+(3934,0,120),
+(3935,0,120),
+(3936,0,120),
+(3937,0,120),
+(3938,0,120),
+(3939,0,120),
+(3940,0,120),
+(3941,0,120),
+(3942,0,120),
+(3943,0,120),
+(3944,0,120),
+(3945,0,120),
+(3946,0,120),
+(3947,0,120),
+(3948,0,120),
+(3949,0,120),
+(3950,0,120),
+(3951,0,120),
+(3952,0,120),
+(3953,0,120),
+(3954,0,120),
+(3955,0,120),
+(3956,0,120),
+(3957,0,120),
+(3958,0,120),
+(3959,0,120),
+(3960,0,120),
+(3961,0,120),
+(3962,0,120),
+(3963,0,120),
+(3964,0,120),
+(3965,0,120),
+(3966,0,120),
+(3967,0,120),
+(3968,0,120),
+(3969,0,120),
+(3970,0,120),
+(3971,0,120),
+(3972,0,120),
+(3973,0,120),
+(3974,0,120),
+(3975,0,120),
+(3976,0,120),
+(3977,0,120),
+(3978,0,120),
+(3979,0,120),
+(3980,0,120),
+(3981,0,120),
+(3982,0,120),
+(3998,20,60),
+(3999,47,60),
+(4000,47,60),
+(4001,47,60),
+(4002,20,60),
+(4003,20,60),
+(4004,15,60),
+(4005,15,60),
+(4006,15,60),
+(4007,36,60),
+(4008,36,60),
+(4009,36,60),
+(4010,42,60),
+(4011,42,60),
+(4012,42,60),
+(4013,39,60),
+(4014,39,60),
+(4015,39,60),
+(4016,24,60),
+(4017,24,60),
+(4018,24,60),
+(4019,55,60),
+(4020,55,60),
+(4021,55,60),
+(4022,34,60),
+(4023,34,60),
+(4024,34,60),
+(4025,30,60),
+(4026,30,60),
+(4027,30,60),
+(4028,32,60),
+(4029,32,60),
+(4030,32,60),
+(4031,15,60),
+(4032,15,60),
+(4033,15,60),
+(4034,35,60),
+(4035,35,60),
+(4036,35,60),
+(4037,30,60),
+(4038,30,60),
+(4039,30,60),
+(4040,26,60),
+(4041,26,60),
+(4042,28,60),
+(4043,28,60),
+(4044,28,60),
+(4045,38,60),
+(4046,38,60),
+(4047,38,60),
+(4048,17,60),
+(4049,17,60),
+(4050,17,60),
+(4051,46,60),
+(4052,46,60),
+(4053,46,60),
+(4054,26,60),
+(4055,42,60),
+(4056,42,60),
+(4057,42,60),
+(4058,20,60),
+(4059,20,60),
+(4060,20,60),
+(4061,50,60),
+(4062,50,60),
+(4063,50,60),
+(4064,40,60),
+(4065,40,60),
+(4066,40,60),
+(4067,17,60),
+(4068,17,60),
+(4069,17,60),
+(4070,44,60),
+(4071,44,60),
+(4072,44,60),
+(4074,63,80),
+(4075,63,80),
+(4076,58,80),
+(4077,58,80),
+(4079,68,80),
+(4080,68,80),
+(4082,62,80),
+(4083,62,80),
+(4085,64,80),
+(4086,64,80),
+(4088,65,80),
+(4089,65,80),
+(4090,67,80),
+(4091,67,80),
+(4092,68,80),
+(4093,68,80),
+(4094,68,80),
+(4095,68,80),
+(4096,59,80),
+(4097,59,80),
+(4098,67,80),
+(4099,67,80),
+(4100,67,80),
+(4101,67,80),
+(4102,67,80),
+(4103,67,80),
+(4104,60,80),
+(4105,60,80),
+(4106,67,80),
+(4107,67,80),
+(4108,61,80),
+(4109,61,80),
+(4110,61,80),
+(4111,61,80),
+(4112,60,80),
+(4113,60,80),
+(4114,62,80),
+(4115,62,80),
+(4116,64,80),
+(4117,64,80),
+(4118,67,80),
+(4119,67,80),
+(4120,70,80),
+(4121,70,80),
+(4122,65,80),
+(4123,65,80),
+(4124,70,80),
+(4125,70,80),
+(4126,68,80),
+(4127,68,80),
+(4128,70,80),
+(4129,70,80),
+(4130,59,80),
+(4131,59,80),
+(4132,67,80),
+(4133,67,80),
+(4134,63,80),
+(4135,63,80),
+(4136,68,80),
+(4137,68,80),
+(4138,58,80),
+(4139,58,80),
+(4140,67,80),
+(4141,67,80),
+(4142,80,90),
+(4143,80,90),
+(4144,0,120),
+(4145,0,120),
+(4146,84,90),
+(4147,84,90),
+(4148,84,90),
+(4149,84,90),
+(4150,0,120),
+(4151,0,120),
+(4152,84,90),
+(4153,84,90),
+(4154,81,90),
+(4155,81,90),
+(4156,81,90),
+(4157,81,90),
+(4158,80,90),
+(4159,80,90),
+(4160,0,120),
+(4161,0,120),
+(4162,80,90),
+(4163,80,90),
+(4164,80,90),
+(4165,80,90),
+(4166,83,90),
+(4167,83,90),
+(4168,82,90),
+(4169,82,90),
+(4170,82,90),
+(4171,82,90),
+(4172,83,90),
+(4173,83,90),
+(4174,80,90),
+(4175,80,90),
+(4176,80,90),
+(4177,80,90),
+(4178,94,100),
+(4179,94,100),
+(4180,90,100),
+(4181,90,100),
+(4182,100,100),
+(4183,100,100),
+(4184,92,100),
+(4185,92,100),
+(4186,100,100),
+(4187,100,100),
+(4188,97,100),
+(4189,97,100),
+(4190,100,100),
+(4191,100,100),
+(4192,100,100),
+(4193,100,100),
+(4194,0,120),
+(4195,0,120),
+(4196,0,120),
+(4197,0,120),
+(4198,0,120),
+(4199,0,120),
+(4200,0,120),
+(4201,0,120),
+(4202,0,120),
+(4204,0,120),
+(4205,82,90),
+(4206,84,90),
+(4207,83,90),
+(4208,67,80),
+(4209,81,90),
+(4210,80,90),
+(4211,85,90),
+(4212,85,90),
+(4214,0,120),
+(4215,0,120),
+(4216,0,120),
+(4217,0,120),
+(4218,0,120),
+(4219,0,120),
+(4220,0,120),
+(4221,0,120),
+(4222,0,120),
+(4223,0,120),
+(4224,0,120),
+(4225,0,120),
+(4226,0,120),
+(4227,0,120),
+(4228,0,120),
+(4229,0,120),
+(4233,80,90),
+(4234,80,90),
+(4235,80,90),
+(4236,0,120),
+(4237,0,120),
+(4238,90,100),
+(4239,80,90),
+(4240,0,120),
+(4241,80,90),
+(4242,58,80),
+(4243,58,80),
+(4244,1,60),
+(4246,0,120),
+(4247,0,120),
+(4248,0,120),
+(4249,0,120),
+(4250,0,120),
+(4251,0,120),
+(4252,0,120),
+(4253,0,120),
+(4254,0,120),
+(4255,0,120),
+(4256,0,120),
+(4257,0,120),
+(4258,0,120),
+(4259,0,120),
+(4260,0,120),
+(4261,0,120),
+(4262,0,120),
+(4263,0,120),
+(4264,0,120),
+(4265,0,120),
+(4266,0,120),
+(4267,0,120),
+(4268,0,120),
+(4269,0,120),
+(4270,0,120),
+(4271,0,120),
+(4272,0,120),
+(4273,0,120),
+(4274,0,120),
+(4275,0,120),
+(4276,0,120),
+(4277,0,120),
+(4278,0,120),
+(4279,0,120),
+(4280,0,120),
+(4281,0,120),
+(4282,0,120),
+(4283,0,120),
+(4284,0,120),
+(4285,0,120),
+(4286,0,120),
+(4287,0,120),
+(4288,0,120),
+(4289,0,120),
+(4290,0,120),
+(4291,0,120),
+(4292,0,120),
+(4293,0,120),
+(4294,0,120),
+(4295,0,120),
+(4296,0,120),
+(4297,0,120),
+(4298,0,120),
+(4299,0,120),
+(4300,0,120),
+(4301,0,120),
+(4302,0,120),
+(4303,0,120),
+(4304,0,120),
+(4305,0,120),
+(4306,0,120),
+(4307,0,120),
+(4308,0,120),
+(4309,0,120),
+(4310,0,120),
+(4311,0,120),
+(4312,0,120),
+(4313,0,120),
+(4314,0,120),
+(4315,0,120),
+(4316,0,120),
+(4317,0,120),
+(4318,90,100),
+(4319,90,100),
+(4320,90,100),
+(4321,92,100),
+(4322,92,100),
+(4323,92,100),
+(4324,98,100),
+(4325,98,100),
+(4326,98,100),
+(4327,90,100),
+(4328,90,100),
+(4329,90,100),
+(4330,96,100),
+(4331,96,100),
+(4332,96,100),
+(4333,94,100),
+(4334,94,100),
+(4335,94,100),
+(4336,90,100),
+(4337,90,100),
+(4338,90,100),
+(4493,0,120),
+(4503,0,120),
+(4738,0,120),
+(4739,0,120),
+(4740,0,120),
+(4741,94,100),
+(4742,90,100),
+(4743,100,100),
+(4744,92,100),
+(4745,100,100),
+(4746,90,100),
+(4747,97,100),
+(4748,100,100),
+(4749,100,100),
+(4750,0,120),
+(4751,0,120),
+(4752,0,120),
+(4753,0,120),
+(4754,0,120),
+(4755,0,120),
+(4756,0,120),
+(4757,0,120),
+(4758,0,120),
+(4759,0,120),
+(4760,0,120),
+(4761,0,120),
+(4762,0,120),
+(4763,0,120),
+(4764,0,120),
+(4765,0,120),
+(4766,0,120),
+(4767,0,120),
+(4768,0,120),
+(4769,0,120),
+(4770,0,120),
+(4771,0,120),
+(4772,0,120),
+(4773,0,120),
+(4774,0,120);
+
+-- Set fixedScalingLevel to current character level, constrained by DB2 limits in tmp_scale_data
+-- If item has no owner, it defaults character level to 1
+-- Items that already have scale data are not modified
+
+UPDATE character_void_storage vs
+ INNER JOIN tmp_scale_data s ON FIND_IN_SET(s.BonusListID, REPLACE(vs.bonusListIDs, ' ', ','))
+ LEFT JOIN characters c ON c.guid = vs.playerGuid
+ SET fixedScalingLevel = LEAST(GREATEST(IFNULL(c.level, 1), s.MinLevel), s.MaxLevel)
+ WHERE fixedScalingLevel = 0;
+
+UPDATE item_instance_modifiers SET fixedScalingLevel = (SELECT LEAST(GREATEST(IFNULL(c.level, 1), s.MinLevel), s.MaxLevel)
+ FROM tmp_scale_data s
+ INNER JOIN item_instance i ON FIND_IN_SET(s.BonusListID, REPLACE(i.bonusListIDs, ' ', ','))
+ LEFT JOIN characters c ON c.guid = i.owner_guid
+ WHERE i.guid = itemGuid) WHERE fixedScalingLevel = 0;
+
+INSERT IGNORE INTO item_instance_modifiers (itemGuid, fixedScalingLevel)
+ SELECT i.guid, LEAST(GREATEST(IFNULL(c.level, 1), s.MinLevel), s.MaxLevel)
+ FROM tmp_scale_data s
+ INNER JOIN item_instance i ON FIND_IN_SET(s.BonusListID, REPLACE(i.bonusListIDs, ' ', ','))
+ LEFT JOIN characters c ON c.guid = i.owner_guid;
+
+DROP TABLE `tmp_scale_data`;
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index cc0f56a3ce4..3c9cebc3950 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -704,7 +704,7 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPackets::AuctionHouse::Aucti
if (quality != 0xffffffff && proto->GetQuality() != quality)
continue;
- if (levelmin != 0 && (proto->GetBaseRequiredLevel() < levelmin || (levelmax != 0 && proto->GetBaseRequiredLevel() > levelmax)))
+ if (levelmin != 0 && (item->GetRequiredLevel() < levelmin || (levelmax != 0 && item->GetRequiredLevel() > levelmax)))
continue;
if (usable && player->CanUseItem(item) != EQUIP_ERR_OK)
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 92b8d0128c4..7807bb5538e 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -714,24 +714,24 @@ enum ItemExtendedCostFlags
enum ItemBonusType
{
- ITEM_BONUS_ITEM_LEVEL = 1,
- ITEM_BONUS_STAT = 2,
- ITEM_BONUS_QUALITY = 3,
- ITEM_BONUS_DESCRIPTION = 4,
- ITEM_BONUS_SUFFIX = 5,
- ITEM_BONUS_SOCKET = 6,
- ITEM_BONUS_APPEARANCE = 7,
- ITEM_BONUS_REQUIRED_LEVEL = 8,
- ITEM_BONUS_DISPLAY_TOAST_METHOD = 9,
- ITEM_BONUS_REPAIR_COST_MULTIPLIER = 10,
- ITEM_BONUS_SCALING_STAT_DISTRIBUTION = 11,
- ITEM_BONUS_DISENCHANT_LOOT_ID = 12,
- ITEM_BONUS_SCALING_STAT_DISTRIBUTION_2 = 13,
- ITEM_BONUS_ITEM_LEVEL_CAN_INCREASE = 14, // Displays a + next to item level indicating it can warforge
- ITEM_BONUS_RANDOM_ENCHANTMENT = 15, // Responsible for showing "<Random additional stats>" or "+%d Rank Random Minor Trait" in the tooltip before item is obtained
- ITEM_BONUS_BONDING = 16,
- ITEM_BONUS_RELIC_TYPE = 17,
- ITEM_BONUS_OVERRIDE_REQUIRED_LEVEL = 18
+ ITEM_BONUS_ITEM_LEVEL = 1,
+ ITEM_BONUS_STAT = 2,
+ ITEM_BONUS_QUALITY = 3,
+ ITEM_BONUS_DESCRIPTION = 4,
+ ITEM_BONUS_SUFFIX = 5,
+ ITEM_BONUS_SOCKET = 6,
+ ITEM_BONUS_APPEARANCE = 7,
+ ITEM_BONUS_REQUIRED_LEVEL = 8,
+ ITEM_BONUS_DISPLAY_TOAST_METHOD = 9,
+ ITEM_BONUS_REPAIR_COST_MULTIPLIER = 10,
+ ITEM_BONUS_SCALING_STAT_DISTRIBUTION = 11,
+ ITEM_BONUS_DISENCHANT_LOOT_ID = 12,
+ ITEM_BONUS_SCALING_STAT_DISTRIBUTION_FIXED = 13,
+ ITEM_BONUS_ITEM_LEVEL_CAN_INCREASE = 14, // Displays a + next to item level indicating it can warforge
+ ITEM_BONUS_RANDOM_ENCHANTMENT = 15, // Responsible for showing "<Random additional stats>" or "+%d Rank Random Minor Trait" in the tooltip before item is obtained
+ ITEM_BONUS_BONDING = 16,
+ ITEM_BONUS_RELIC_TYPE = 17,
+ ITEM_BONUS_OVERRIDE_REQUIRED_LEVEL = 18
};
enum ItemLimitCategoryMode
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 6f2526de7de..71bc71f9430 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -684,18 +684,6 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
SetUInt32Value(ITEM_FIELD_FLAGS, itemFlags);
- _LoadIntoDataField(fields[8].GetString(), ITEM_FIELD_ENCHANTMENT, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET);
- m_randomEnchantment.Type = ItemRandomEnchantmentType(fields[9].GetUInt8());
- m_randomEnchantment.Id = fields[10].GetUInt32();
- if (m_randomEnchantment.Type == ItemRandomEnchantmentType::Property)
- SetUInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, m_randomEnchantment.Id);
- else if (m_randomEnchantment.Type == ItemRandomEnchantmentType::Suffix)
- {
- SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, -int32(m_randomEnchantment.Id));
- // recalculate suffix factor
- UpdateItemSuffixFactor();
- }
-
uint32 durability = fields[11].GetUInt16();
SetUInt32Value(ITEM_FIELD_DURABILITY, durability);
// update max durability (and durability) if need
@@ -771,6 +759,19 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
SetModifier(ITEM_MODIFIER_SCALING_STAT_DISTRIBUTION_FIXED_LEVEL, fields[43].GetUInt32());
SetModifier(ITEM_MODIFIER_ARTIFACT_KNOWLEDGE_LEVEL, fields[44].GetUInt32());
+ // Enchants must be loaded after all other bonus/scaling data
+ _LoadIntoDataField(fields[8].GetString(), ITEM_FIELD_ENCHANTMENT, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET);
+ m_randomEnchantment.Type = ItemRandomEnchantmentType(fields[9].GetUInt8());
+ m_randomEnchantment.Id = fields[10].GetUInt32();
+ if (m_randomEnchantment.Type == ItemRandomEnchantmentType::Property)
+ SetUInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, m_randomEnchantment.Id);
+ else if (m_randomEnchantment.Type == ItemRandomEnchantmentType::Suffix)
+ {
+ SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, -int32(m_randomEnchantment.Id));
+ // recalculate suffix factor
+ UpdateItemSuffixFactor();
+ }
+
// Remove bind flag for items vs BIND_NONE set
if (IsSoulBound() && GetBonding() == BIND_NONE)
{
@@ -892,7 +893,7 @@ ItemTemplate const* Item::GetTemplate() const
return sObjectMgr->GetItemTemplate(GetEntry());
}
-Player* Item::GetOwner()const
+Player* Item::GetOwner() const
{
return ObjectAccessor::FindPlayer(GetOwnerGUID());
}
@@ -947,7 +948,15 @@ void Item::SetItemRandomProperties(ItemRandomEnchantmentId const& randomPropId)
void Item::UpdateItemSuffixFactor()
{
- uint32 suffixFactor = GenerateEnchSuffixFactor(GetEntry());
+ if (!GetTemplate()->GetRandomSuffix())
+ return;
+
+ uint32 suffixFactor = 0;
+ if (Player* owner = GetOwner())
+ suffixFactor = GetRandomPropertyPoints(GetItemLevel(owner), GetQuality(), GetTemplate()->GetInventoryType(), GetTemplate()->GetSubClass());
+ else
+ suffixFactor = GenerateEnchSuffixFactor(GetEntry());
+
if (GetItemSuffixFactor() == suffixFactor)
return;
SetUInt32Value(ITEM_FIELD_PROPERTY_SEED, suffixFactor);
@@ -2555,6 +2564,33 @@ void Item::GiveArtifactXp(uint64 amount, Item* sourceItem, uint32 artifactCatego
SetState(ITEM_CHANGED, owner);
}
+void Item::SetFixedLevel(uint8 level)
+{
+ if (!_bonusData.HasFixedLevel || GetModifier(ITEM_MODIFIER_SCALING_STAT_DISTRIBUTION_FIXED_LEVEL))
+ return;
+
+ if (ScalingStatDistributionEntry const* ssd = sScalingStatDistributionStore.LookupEntry(_bonusData.ScalingStatDistribution))
+ {
+ level = std::min(std::max(int32(level), ssd->MinLevel), ssd->MaxLevel);
+
+ if (SandboxScalingEntry const* sandbox = sSandboxScalingStore.LookupEntry(_bonusData.SandboxScalingId))
+ if ((sandbox->Flags & 2 || sandbox->MinLevel || sandbox->MaxLevel) && !(sandbox->Flags & 4))
+ level = std::min(std::max(int32(level), sandbox->MinLevel), sandbox->MaxLevel);
+
+ SetModifier(ITEM_MODIFIER_SCALING_STAT_DISTRIBUTION_FIXED_LEVEL, level);
+ }
+}
+
+int32 Item::GetRequiredLevel() const
+{
+ if (_bonusData.RequiredLevelOverride)
+ return _bonusData.RequiredLevelOverride;
+ else if (_bonusData.HasFixedLevel)
+ return GetModifier(ITEM_MODIFIER_SCALING_STAT_DISTRIBUTION_FIXED_LEVEL);
+ else
+ return _bonusData.RequiredLevel;
+}
+
void BonusData::Initialize(ItemTemplate const* proto)
{
Quality = proto->GetQuality();
@@ -2588,6 +2624,8 @@ void BonusData::Initialize(ItemTemplate const* proto)
SandboxScalingId = 0;
RelicType = -1;
HasItemLevelBonus = false;
+ HasFixedLevel = false;
+ RequiredLevelOverride = 0;
_state.AppearanceModPriority = std::numeric_limits<int32>::max();
_state.ScalingStatDistributionPriority = std::numeric_limits<int32>::max();
@@ -2667,12 +2705,13 @@ void BonusData::AddBonus(uint32 type, int32 const (&values)[3])
RepairCostMultiplier *= static_cast<float>(values[0]) * 0.01f;
break;
case ITEM_BONUS_SCALING_STAT_DISTRIBUTION:
- case ITEM_BONUS_SCALING_STAT_DISTRIBUTION_2:
+ case ITEM_BONUS_SCALING_STAT_DISTRIBUTION_FIXED:
if (values[1] < _state.ScalingStatDistributionPriority)
{
ScalingStatDistribution = static_cast<uint32>(values[0]);
SandboxScalingId = static_cast<uint32>(values[2]);
_state.ScalingStatDistributionPriority = values[1];
+ HasFixedLevel = type == ITEM_BONUS_SCALING_STAT_DISTRIBUTION_FIXED;
}
break;
case ITEM_BONUS_BONDING:
@@ -2682,7 +2721,7 @@ void BonusData::AddBonus(uint32 type, int32 const (&values)[3])
RelicType = values[0];
break;
case ITEM_BONUS_OVERRIDE_REQUIRED_LEVEL:
- RequiredLevel = values[0];
+ RequiredLevelOverride = values[0];
break;
}
}
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index ed3abe13c50..d795983b4ed 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -92,7 +92,9 @@ struct BonusData
int32 GemRelicType[MAX_ITEM_PROTO_SOCKETS];
uint16 GemRelicRankBonus[MAX_ITEM_PROTO_SOCKETS];
int32 RelicType;
+ int32 RequiredLevelOverride;
bool HasItemLevelBonus;
+ bool HasFixedLevel;
void Initialize(ItemTemplate const* proto);
void Initialize(WorldPackets::Item::ItemInstance const& itemInstance);
@@ -142,7 +144,7 @@ class TC_GAME_API Item : public Object
ObjectGuid GetOwnerGUID() const { return GetGuidValue(ITEM_FIELD_OWNER); }
void SetOwnerGUID(ObjectGuid guid) { SetGuidValue(ITEM_FIELD_OWNER, guid); }
- Player* GetOwner()const;
+ Player* GetOwner() const;
ItemBondingType GetBonding() const { return _bonusData.Bonding; }
void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_SOULBOUND, val); }
@@ -264,7 +266,7 @@ class TC_GAME_API Item : public Object
uint32 GetItemLevel(Player const* owner) const;
static uint32 GetItemLevel(ItemTemplate const* itemTemplate, BonusData const& bonusData, uint32 level, uint32 fixedLevel, uint32 upgradeId,
uint32 minItemLevel, uint32 minItemLevelCutoff, uint32 maxItemLevel, bool pvpBonus);
- int32 GetRequiredLevel() const { return _bonusData.RequiredLevel; }
+ int32 GetRequiredLevel() const;
int32 GetItemStatType(uint32 index) const { ASSERT(index < MAX_ITEM_PROTO_STATS); return _bonusData.ItemStatType[index]; }
int32 GetItemStatValue(uint32 index, Player const* owner) const;
SocketColor GetSocketColor(uint32 index) const { ASSERT(index < MAX_ITEM_PROTO_SOCKETS); return SocketColor(_bonusData.SocketColor[index]); }
@@ -278,6 +280,7 @@ class TC_GAME_API Item : public Object
uint32 GetScalingStatDistribution() const { return _bonusData.ScalingStatDistribution; }
ItemDisenchantLootEntry const* GetDisenchantLoot(Player const* owner) const;
static ItemDisenchantLootEntry const* GetDisenchantLoot(ItemTemplate const* itemTemplate, uint32 quality, uint32 itemLevel);
+ void SetFixedLevel(uint8 level);
// Item Refund system
void SetNotRefundable(Player* owner, bool changestate = true, SQLTransaction* trans = nullptr, bool addToCollection = true);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 531b3bb16a0..d02a812bbb8 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -11570,6 +11570,9 @@ InventoryResult Player::CanUseItem(Item* pItem, bool not_loading) const
if (pItem->IsBindedNotWith(this))
return EQUIP_ERR_NOT_OWNER;
+ if (getLevel() < pItem->GetRequiredLevel())
+ return EQUIP_ERR_CANT_EQUIP_LEVEL_I;
+
InventoryResult res = CanUseItem(pProto);
if (res != EQUIP_ERR_OK)
return res;
@@ -11744,7 +11747,6 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat
UpdateCriteria(CRITERIA_TYPE_OWN_ITEM, itemId, 1);
item->SetFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_NEW_ITEM);
- item->SetItemRandomProperties(randomPropertyId);
if (uint32 upgradeID = sDB2Manager.GetRulesetItemUpgrade(itemId))
item->SetModifier(ITEM_MODIFIER_UPGRADE_ID, upgradeID);
@@ -11755,6 +11757,9 @@ Item* Player::StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool updat
item = StoreItem(pos, item, update);
+ item->SetFixedLevel(getLevel());
+ item->SetItemRandomProperties(randomPropertyId);
+
if (allowedLooters.size() > 1 && item->GetTemplate()->GetMaxStackSize() == 1 && item->IsSoulBound())
{
item->SetSoulboundTradeable(allowedLooters);
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index ce83e861e6d..0ba24d95ac9 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -529,9 +529,7 @@ void WorldSession::HandleBuybackItem(WorldPackets::Item::BuyBackItem& packet)
{
_player->ModifyMoney(-(int32)price);
_player->RemoveItemFromBuyBackSlot(packet.Slot, false);
- _player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
- _player->UpdateCriteria(CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount());
- _player->StoreItem(dest, pItem, true);
+ _player->MoveItemToInventory(dest, pItem, true);
}
else
_player->SendEquipError(msg, pItem, NULL);