Browse Source

Replace ExpLvlsTbl global with helper function

pull/6504/head
ephphatha 3 years ago committed by Anders Jenbo
parent
commit
486f5ca3e8
  1. 15
      Source/player.cpp
  2. 11
      Source/playerdat.cpp
  3. 2
      Source/playerdat.hpp
  4. 10
      Source/qol/xpbar.cpp

15
Source/player.cpp

@ -2308,7 +2308,7 @@ void CreatePlayer(Player &player, HeroClass c)
player._pMaxManaBase = player._pMana;
player._pExperience = 0;
player._pNextExper = ExpLvlsTbl[1];
player._pNextExper = GetNextExperienceThresholdForLevel(player._pLevel);
player._pArmorClass = 0;
player._pLightRad = 10;
player._pInfraFlag = false;
@ -2397,7 +2397,7 @@ void NextPlrLevel(Player &player)
} else {
player._pStatPts += 5;
}
player._pNextExper = ExpLvlsTbl[std::min<int8_t>(player._pLevel, MaxCharacterLevel - 1)];
player._pNextExper = GetNextExperienceThresholdForLevel(player._pLevel);
int hp = PlayersData[static_cast<size_t>(player._pClass)].lvlLife;
@ -2447,14 +2447,15 @@ void AddPlrExperience(Player &player, int lvl, int exp)
// Prevent power leveling
if (gbIsMultiplayer) {
const uint32_t clampedPlayerLevel = std::clamp(static_cast<int>(player._pLevel), 1, MaxCharacterLevel);
// Use a minimum of 1 so level 0 characters can still gain experience
const uint32_t clampedPlayerLevel = static_cast<uint32_t>(std::max(static_cast<int>(player._pLevel), 1));
// for low level characters experience gain is capped to 1/20 of current levels xp
// for high level characters experience gain is capped to 200 * current level - this is a smaller value than 1/20 of the exp needed for the next level after level 5.
clampedExp = std::min({ clampedExp, /* level 0-5: */ ExpLvlsTbl[clampedPlayerLevel] / 20U, /* level 6-50: */ 200U * clampedPlayerLevel });
clampedExp = std::min({ clampedExp, /* level 1-5: */ GetNextExperienceThresholdForLevel(clampedPlayerLevel) / 20U, /* level 6-50: */ 200U * clampedPlayerLevel });
}
const uint32_t MaxExperience = ExpLvlsTbl[MaxCharacterLevel - 1];
const uint32_t MaxExperience = GetNextExperienceThresholdForLevel(MaxCharacterLevel);
// 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);
@ -2465,7 +2466,7 @@ void AddPlrExperience(Player &player, int lvl, int exp)
// Increase player level if applicable
int newLvl = player._pLevel;
while (newLvl < MaxCharacterLevel && player._pExperience >= ExpLvlsTbl[newLvl]) {
while (newLvl < MaxCharacterLevel && player._pExperience >= GetNextExperienceThresholdForLevel(newLvl)) {
newLvl++;
}
if (newLvl != player._pLevel) {
@ -2547,7 +2548,7 @@ void InitPlayer(Player &player, bool firstTime)
SpellID s = PlayersData[static_cast<size_t>(player._pClass)].skill;
player._pAblSpells = GetSpellBitmask(s);
player._pNextExper = ExpLvlsTbl[std::min<int8_t>(player._pLevel, MaxCharacterLevel - 1)];
player._pNextExper = GetNextExperienceThresholdForLevel(player._pLevel);
player._pInvincible = false;
if (&player == MyPlayer) {

11
Source/playerdat.cpp

@ -6,6 +6,8 @@
#include "playerdat.hpp"
#include <algorithm>
#include <array>
#include <cstdint>
#include "items.h"
@ -15,8 +17,9 @@
namespace devilution {
namespace {
/** Specifies the experience point limit of each level. */
const uint32_t ExpLvlsTbl[MaxCharacterLevel] = {
const std::array<uint32_t, MaxCharacterLevel> ExpLvlsTbl {
0,
2000,
4620,
@ -68,6 +71,12 @@ const uint32_t ExpLvlsTbl[MaxCharacterLevel] = {
1082908612,
1310707109
};
} // namespace
uint32_t GetNextExperienceThresholdForLevel(int level)
{
return ExpLvlsTbl[std::clamp(level, 0, static_cast<int>(ExpLvlsTbl.size()) - 1)];
}
const _sfx_id herosounds[enum_size<HeroClass>::value][enum_size<HeroSpeech>::value] = {
// clang-format off

2
Source/playerdat.hpp

@ -136,7 +136,7 @@ struct PlayerAnimData {
};
extern const _sfx_id herosounds[enum_size<HeroClass>::value][enum_size<HeroSpeech>::value];
extern const uint32_t ExpLvlsTbl[MaxCharacterLevel];
uint32_t GetNextExperienceThresholdForLevel(int level);
extern const PlayerData PlayersData[];
extern const PlayerSpriteData PlayersSpriteData[];
extern const PlayerAnimData PlayersAnimData[];

10
Source/qol/xpbar.cpp

@ -85,12 +85,12 @@ void DrawXPBar(const Surface &out)
return;
}
const uint64_t prevXp = ExpLvlsTbl[charLevel - 1];
const uint64_t prevXp = GetNextExperienceThresholdForLevel(charLevel - 1);
if (player._pExperience < prevXp)
return;
uint64_t prevXpDelta1 = player._pExperience - prevXp;
uint64_t prevXpDelta = ExpLvlsTbl[charLevel] - prevXp;
uint64_t prevXpDelta = GetNextExperienceThresholdForLevel(charLevel) - prevXp;
uint64_t fullBar = BarWidth * prevXpDelta1 / prevXpDelta;
// Figure out how much to fill the last pixel of the XP bar, to make it gradually appear with gained XP
@ -128,7 +128,7 @@ bool CheckXPBarInfo()
// Show a maximum level indicator for max level players.
InfoColor = UiFlags::ColorWhitegold;
AddPanelString(fmt::format(fmt::runtime(_("Experience: {:s}")), FormatInteger(ExpLvlsTbl[charLevel - 1])));
AddPanelString(fmt::format(fmt::runtime(_("Experience: {:s}")), FormatInteger(GetNextExperienceThresholdForLevel(charLevel - 1))));
AddPanelString(_("Maximum Level"));
return true;
@ -137,8 +137,8 @@ bool CheckXPBarInfo()
InfoColor = UiFlags::ColorWhite;
AddPanelString(fmt::format(fmt::runtime(_("Experience: {:s}")), FormatInteger(player._pExperience)));
AddPanelString(fmt::format(fmt::runtime(_("Next Level: {:s}")), FormatInteger(ExpLvlsTbl[charLevel])));
AddPanelString(fmt::format(fmt::runtime(_("{:s} to Level {:d}")), FormatInteger(ExpLvlsTbl[charLevel] - player._pExperience), charLevel + 1));
AddPanelString(fmt::format(fmt::runtime(_("Next Level: {:s}")), FormatInteger(GetNextExperienceThresholdForLevel(charLevel))));
AddPanelString(fmt::format(fmt::runtime(_("{:s} to Level {:d}")), FormatInteger(GetNextExperienceThresholdForLevel(charLevel) - player._pExperience), charLevel + 1));
return true;
}

Loading…
Cancel
Save