diff --git a/data/sql/updates/db_characters/2026_05_16_00.sql b/data/sql/updates/db_characters/2026_05_16_00.sql new file mode 100644 index 000000000..42b764ae7 --- /dev/null +++ b/data/sql/updates/db_characters/2026_05_16_00.sql @@ -0,0 +1,4 @@ +-- DB update 2026_05_15_00 -> 2026_05_16_00 +-- +ALTER TABLE characters +ADD COLUMN max_level_earned TINYINT(3) UNSIGNED NOT NULL DEFAULT 1; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0d8d08f01..953ad2f09 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2474,6 +2474,16 @@ void Player::GiveLevel(uint8 level) SetLevel(level); + // Set max level earned + CharacterDatabase.Execute( + "UPDATE characters " + "SET max_level_earned = GREATEST(max_level_earned, {}, {})" + "WHERE guid = {}", + oldLevel, + level, + GetGUID().GetCounter() + ); + UpdateSkillsForLevel(); // save base values (bonuses already included in stored stats diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index 843d1118e..05dfb351a 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -2385,7 +2385,27 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; } - if (GetLevel() < proto->RequiredLevel) + QueryResult levelQuery = CharacterDatabase.Query( + "SELECT max_level_earned FROM characters " + "WHERE guid = {}", + GetGUID().GetCounter() + ); + + uint8 maxLevelEarned = 0; + + if (levelQuery) + { + maxLevelEarned = levelQuery->Fetch()[0].Get(); + } + + uint8 currentLevel = GetLevel(); + + if (maxLevelEarned < currentLevel) + { + maxLevelEarned = currentLevel; + } + + if (maxLevelEarned < proto->RequiredLevel) { return EQUIP_ERR_CANT_EQUIP_LEVEL_I; }