diff --git a/Source/player.cpp b/Source/player.cpp index 6f82103ce..37321007f 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -2430,8 +2430,7 @@ void NextPlrLevel(Player &player) } else { player._pStatPts += 5; } - - player._pNextExper = ExpLvlsTbl[player._pLevel]; + player._pNextExper = ExpLvlsTbl[std::min(player._pLevel, MaxCharacterLevel - 1)]; int hp = PlayersData[static_cast(player._pClass)].lvlUpLife; @@ -2466,17 +2465,11 @@ void NextPlrLevel(Player &player) void AddPlrExperience(Player &player, int lvl, int exp) { - if (&player != MyPlayer) { - return; - } - - // exit function early if player is unable to gain more experience by checking final index of ExpLvlsTbl - int expLvlsTblSize = sizeof(ExpLvlsTbl) / sizeof(ExpLvlsTbl[0]); - if (player._pExperience >= ExpLvlsTbl[expLvlsTblSize - 1]) { + if (&player != MyPlayer || player._pHitPoints <= 0) return; - } - if (player._pHitPoints <= 0) { + if (player._pLevel >= MaxCharacterLevel) { + player._pLevel = MaxCharacterLevel; return; } @@ -2492,25 +2485,18 @@ void AddPlrExperience(Player &player, int lvl, int exp) clampedExp = std::min({ clampedExp, /* level 0-5: */ ExpLvlsTbl[clampedPlayerLevel] / 20U, /* level 6-50: */ 200U * clampedPlayerLevel }); } - constexpr uint32_t MaxExperience = 2000000000U; + const uint32_t MaxExperience = ExpLvlsTbl[MaxCharacterLevel - 1]; - // Overflow is only possible if a kill grants more than (2^32-1 - MaxExperience) XP in one go, which doesn't happen in normal gameplay + // Overflow is only possible if a kill grants more than (2^32-1 - MaxExperience) XP in one go, which doesn't happen in normal gameplay. Clamp to experience required to reach max level player._pExperience = std::min(player._pExperience + clampedExp, MaxExperience); if (*sgOptions.Gameplay.experienceBar) { RedrawEverything(); } - /* set player level to MaxCharacterLevel if the experience value for MaxCharacterLevel is reached, which exits the function early - and does not call NextPlrLevel(), which is responsible for giving Attribute points and Life/Mana on level up */ - if (player._pExperience >= ExpLvlsTbl[MaxCharacterLevel - 1]) { - player._pLevel = MaxCharacterLevel; - return; - } - // Increase player level if applicable - int newLvl = 0; - while (player._pExperience >= ExpLvlsTbl[newLvl]) { + int newLvl = player._pLevel; + while (newLvl < MaxCharacterLevel && player._pExperience >= ExpLvlsTbl[newLvl]) { newLvl++; } if (newLvl != player._pLevel) { @@ -2601,7 +2587,7 @@ void InitPlayer(Player &player, bool firstTime) SpellID s = PlayersData[static_cast(player._pClass)].skill; player._pAblSpells = GetSpellBitmask(s); - player._pNextExper = ExpLvlsTbl[player._pLevel]; + player._pNextExper = ExpLvlsTbl[std::min(player._pLevel, MaxCharacterLevel - 1)]; player._pInvincible = false; if (&player == MyPlayer) { diff --git a/Source/playerdat.cpp b/Source/playerdat.cpp index c44569231..05d2a67f7 100644 --- a/Source/playerdat.cpp +++ b/Source/playerdat.cpp @@ -14,7 +14,7 @@ namespace devilution { /** Specifies the experience point limit of each level. */ -const uint32_t ExpLvlsTbl[MaxCharacterLevel + 1] = { +const uint32_t ExpLvlsTbl[MaxCharacterLevel] = { 0, 2000, 4620, @@ -64,8 +64,7 @@ const uint32_t ExpLvlsTbl[MaxCharacterLevel + 1] = { 733825617, 892680222, 1082908612, - 1310707109, - 1583495809 + 1310707109 }; const _sfx_id herosounds[enum_size::value][enum_size::value] = { diff --git a/Source/playerdat.hpp b/Source/playerdat.hpp index 5492686ab..95b847f8d 100644 --- a/Source/playerdat.hpp +++ b/Source/playerdat.hpp @@ -132,7 +132,7 @@ struct PlayerAnimData { }; extern const _sfx_id herosounds[enum_size::value][enum_size::value]; -extern const uint32_t ExpLvlsTbl[MaxCharacterLevel + 1]; +extern const uint32_t ExpLvlsTbl[MaxCharacterLevel]; extern const PlayerData PlayersData[]; extern const PlayerSpriteData PlayersSpriteData[]; extern const PlayerAnimData PlayersAnimData[]; diff --git a/test/writehero_test.cpp b/test/writehero_test.cpp index 837286f48..8c85da624 100644 --- a/test/writehero_test.cpp +++ b/test/writehero_test.cpp @@ -327,7 +327,7 @@ void AssertPlayer(Player &player) ASSERT_EQ(player._pMaxHP, 16640); ASSERT_EQ(player._pMana, 14624); ASSERT_EQ(player._pMaxMana, 14624); - ASSERT_EQ(player._pNextExper, 1583495809); + ASSERT_EQ(player._pNextExper, 1310707109); ASSERT_EQ(player._pMagResist, 75); ASSERT_EQ(player._pFireResist, 16); ASSERT_EQ(player._pLghtResist, 75);