Browse Source

Remove #defines in player.h and add constexpr where applicable (#4896)

* Change defines to constexpr int in player.h

* Add const or constexpr to player.h/cpp where applicable

* Update tests with changed names of player constatns

* remove unecessary variable
pull/4881/merge
Mikołaj Piróg 4 years ago committed by GitHub
parent
commit
dda0b96ea5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      Source/DiabloUI/diabloui.cpp
  2. 2
      Source/controls/plrctrls.cpp
  3. 16
      Source/dvlnet/base_protocol.h
  4. 10
      Source/inv.cpp
  5. 24
      Source/items.cpp
  6. 12
      Source/loadsave.cpp
  7. 2
      Source/missiles.cpp
  8. 4
      Source/msg.cpp
  9. 2
      Source/multi.cpp
  10. 8
      Source/objects.cpp
  11. 10
      Source/pack.cpp
  12. 8
      Source/pack.h
  13. 4
      Source/panels/charpanel.cpp
  14. 4
      Source/pfile.cpp
  15. 36
      Source/player.cpp
  16. 43
      Source/player.h
  17. 4
      Source/qol/xpbar.cpp
  18. 4
      Source/stores.cpp
  19. 8
      test/inv_test.cpp
  20. 6
      test/player_test.cpp
  21. 8
      test/writehero_test.cpp

4
Source/DiabloUI/diabloui.cpp

@ -627,9 +627,9 @@ bool UiValidPlayerName(string_view name)
if (name.empty())
return false;
// Currently only allow saving PLR_NAME_LEN bytes as a player name, so if the name is too long we'd have to truncate it.
// Currently only allow saving PlayerNameLength bytes as a player name, so if the name is too long we'd have to truncate it.
// That said the input buffer is only 16 bytes long...
if (name.size() > PLR_NAME_LEN)
if (name.size() > PlayerNameLength)
return false;
if (name.find_first_of(",<>%&\\\"?*#/: ") != name.npos)

2
Source/controls/plrctrls.cpp

@ -1666,7 +1666,7 @@ void plrctrls_after_game_logic()
void UseBeltItem(int type)
{
for (int i = 0; i < MAXBELTITEMS; i++) {
for (int i = 0; i < MaxBeltItems; i++) {
Item &item = MyPlayer->SpdList[i];
if (item.isEmpty()) {
continue;

16
Source/dvlnet/base_protocol.h

@ -292,16 +292,15 @@ template <class P>
void base_protocol<P>::recv_decrypted(packet &pkt, endpoint_t sender)
{
if (pkt.Source() == PLR_BROADCAST && pkt.Destination() == PLR_MASTER && pkt.Type() == PT_INFO_REPLY) {
constexpr size_t sizePlayerName = (sizeof(char) * PLR_NAME_LEN);
size_t neededSize = sizeof(GameData) + (sizePlayerName * MAX_PLRS);
size_t neededSize = sizeof(GameData) + (PlayerNameLength * MAX_PLRS);
if (pkt.Info().size() < neededSize)
return;
const GameData *gameData = (const GameData *)pkt.Info().data();
std::vector<std::string> playerNames;
for (size_t i = 0; i < MAX_PLRS; i++) {
std::string playerName;
const char *playerNamePointer = (const char *)(pkt.Info().data() + sizeof(GameData) + (i * sizePlayerName));
playerName.append(playerNamePointer, strnlen(playerNamePointer, PLR_NAME_LEN));
const char *playerNamePointer = (const char *)(pkt.Info().data() + sizeof(GameData) + (i * PlayerNameLength));
playerName.append(playerNamePointer, strnlen(playerNamePointer, PlayerNameLength));
if (!playerName.empty())
playerNames.push_back(playerName);
}
@ -324,17 +323,16 @@ void base_protocol<P>::recv_ingame(packet &pkt, endpoint_t sender)
} else if (pkt.Type() == PT_INFO_REQUEST) {
if ((plr_self != PLR_BROADCAST) && (get_master() == plr_self)) {
buffer_t buf;
constexpr size_t sizePlayerName = (sizeof(char) * PLR_NAME_LEN);
buf.resize(game_init_info.size() + (sizePlayerName * MAX_PLRS) + gamename.size());
buf.resize(game_init_info.size() + (PlayerNameLength * MAX_PLRS) + gamename.size());
std::memcpy(buf.data(), &game_init_info[0], game_init_info.size());
for (size_t i = 0; i < MAX_PLRS; i++) {
if (Players[i].plractive) {
std::memcpy(buf.data() + game_init_info.size() + (i * sizePlayerName), &Players[i]._pName, sizePlayerName);
std::memcpy(buf.data() + game_init_info.size() + (i * PlayerNameLength), &Players[i]._pName, PlayerNameLength);
} else {
std::memset(buf.data() + game_init_info.size() + (i * sizePlayerName), '\0', sizePlayerName);
std::memset(buf.data() + game_init_info.size() + (i * PlayerNameLength), '\0', PlayerNameLength);
}
}
std::memcpy(buf.data() + game_init_info.size() + (sizePlayerName * MAX_PLRS), &gamename[0], gamename.size());
std::memcpy(buf.data() + game_init_info.size() + (PlayerNameLength * MAX_PLRS), &gamename[0], gamename.size());
auto reply = pktfty->make_packet<PT_INFO_REPLY>(PLR_BROADCAST,
PLR_MASTER,
buf);

10
Source/inv.cpp

@ -370,7 +370,7 @@ void CheckInvPaste(Player &player, Point cursorPosition)
} else {
int yy = std::max(INV_ROW_SLOT_SIZE * ((ii / INV_ROW_SLOT_SIZE) - ((itemSize.height - 1) / 2)), 0);
for (int j = 0; j < itemSize.height; j++) {
if (yy >= NUM_INV_GRID_ELEM)
if (yy >= InventoryGridCells)
return;
int xx = std::max((ii % INV_ROW_SLOT_SIZE) - ((itemSize.width - 1) / 2), 0);
for (int i = 0; i < itemSize.width; i++) {
@ -1147,7 +1147,7 @@ void DrawInv(const Surface &out)
}
}
for (int i = 0; i < NUM_INV_GRID_ELEM; i++) {
for (int i = 0; i < InventoryGridCells; i++) {
if (myPlayer.InvGrid[i] != 0) {
InvDrawSlotBack(
out,
@ -1156,7 +1156,7 @@ void DrawInv(const Surface &out)
}
}
for (int j = 0; j < NUM_INV_GRID_ELEM; j++) {
for (int j = 0; j < InventoryGridCells; j++) {
if (myPlayer.InvGrid[j] > 0) { // first slot of an item
int ii = myPlayer.InvGrid[j] - 1;
int cursId = myPlayer.InvList[ii]._iCurs + CURSOR_FIRSTITEM;
@ -1193,7 +1193,7 @@ void DrawInvBelt(const Surface &out)
Player &myPlayer = *MyPlayer;
for (int i = 0; i < MAXBELTITEMS; i++) {
for (int i = 0; i < MaxBeltItems; i++) {
if (myPlayer.SpdList[i].isEmpty()) {
continue;
}
@ -1358,7 +1358,7 @@ bool AutoPlaceItemInInventorySlot(Player &player, int slotIndex, const Item &ite
Size itemSize = GetInventorySize(item);
for (int j = 0; j < itemSize.height; j++) {
if (yy >= NUM_INV_GRID_ELEM) {
if (yy >= InventoryGridCells) {
return false;
}
int xx = (slotIndex > 0) ? (slotIndex % 10) : 0;

24
Source/items.cpp

@ -2550,9 +2550,9 @@ void CalcPlrItemVals(Player &player, bool loadgfx)
lr = 0;
}
player._pMagResist = clamp(mr, 0, MAXRESIST);
player._pFireResist = clamp(fr, 0, MAXRESIST);
player._pLghtResist = clamp(lr, 0, MAXRESIST);
player._pMagResist = clamp(mr, 0, MaxResistance);
player._pFireResist = clamp(fr, 0, MaxResistance);
player._pLghtResist = clamp(lr, 0, MaxResistance);
if (player._pClass == HeroClass::Warrior) {
vadd *= 2;
@ -3534,28 +3534,28 @@ bool DoOil(Player &player, int cii)
return fmt::format(fmt::runtime(_("armor class: {:d}")), item._iAC);
case IPL_FIRERES:
case IPL_FIRERES_CURSE:
if (item._iPLFR < MAXRESIST)
if (item._iPLFR < MaxResistance)
return fmt::format(fmt::runtime(_("Resist Fire: {:+d}%")), item._iPLFR);
else
return fmt::format(fmt::runtime(_("Resist Fire: {:+d}% MAX")), MAXRESIST);
return fmt::format(fmt::runtime(_("Resist Fire: {:+d}% MAX")), MaxResistance);
case IPL_LIGHTRES:
case IPL_LIGHTRES_CURSE:
if (item._iPLLR < MAXRESIST)
if (item._iPLLR < MaxResistance)
return fmt::format(fmt::runtime(_("Resist Lightning: {:+d}%")), item._iPLLR);
else
return fmt::format(fmt::runtime(_("Resist Lightning: {:+d}% MAX")), MAXRESIST);
return fmt::format(fmt::runtime(_("Resist Lightning: {:+d}% MAX")), MaxResistance);
case IPL_MAGICRES:
case IPL_MAGICRES_CURSE:
if (item._iPLMR < MAXRESIST)
if (item._iPLMR < MaxResistance)
return fmt::format(fmt::runtime(_("Resist Magic: {:+d}%")), item._iPLMR);
else
return fmt::format(fmt::runtime(_("Resist Magic: {:+d}% MAX")), MAXRESIST);
return fmt::format(fmt::runtime(_("Resist Magic: {:+d}% MAX")), MaxResistance);
case IPL_ALLRES:
case IPL_ALLRES_CURSE:
if (item._iPLFR < MAXRESIST)
if (item._iPLFR < MaxResistance)
return fmt::format(fmt::runtime(_("Resist All: {:+d}%")), item._iPLFR);
else
return fmt::format(fmt::runtime(_("Resist All: {:+d}% MAX")), MAXRESIST);
return fmt::format(fmt::runtime(_("Resist All: {:+d}% MAX")), MaxResistance);
case IPL_SPLLVLADD:
if (item._iSplLvlAdd > 0)
return fmt::format(fmt::runtime(ngettext("spells are increased {:d} level", "spells are increased {:d} levels", item._iSplLvlAdd)), item._iSplLvlAdd);
@ -3941,7 +3941,7 @@ void UseItem(int pnum, item_misc_id mid, spell_id spl)
break;
case IMISC_BOOK:
player._pMemSpells |= GetSpellBitmask(spl);
if (player._pSplLvl[spl] < MAX_SPELL_LEVEL)
if (player._pSplLvl[spl] < MaxSpellLevel)
player._pSplLvl[spl]++;
if (HasNoneOf(player._pIFlags, ItemSpecialEffect::NoMana)) {
player._pMana += spelldata[spl].sManaCost << 6;

12
Source/loadsave.cpp

@ -395,7 +395,7 @@ void LoadPlayer(LoadHelper &file, Player &player)
player._pLightRad = file.NextLE<int8_t>();
player._pLvlChanging = file.NextBool8();
file.NextBytes(player._pName, PLR_NAME_LEN);
file.NextBytes(player._pName, PlayerNameLength);
player._pClass = static_cast<HeroClass>(file.NextLE<int8_t>());
file.Skip(3); // Alignment
player._pStrength = file.NextLE<int32_t>();
@ -1155,7 +1155,7 @@ void SavePlayer(SaveHelper &file, const Player &player)
file.WriteLE<int8_t>(player._pLightRad);
file.WriteLE<uint8_t>(player._pLvlChanging ? 1 : 0);
file.WriteBytes(player._pName, PLR_NAME_LEN);
file.WriteBytes(player._pName, PlayerNameLength);
file.WriteLE<int8_t>(static_cast<int8_t>(player._pClass));
file.Skip(3); // Alignment
file.WriteLE<int32_t>(player._pStrength);
@ -1937,8 +1937,8 @@ void LoadHeroItems(Player &player)
gbIsHellfireSaveGame = file.NextBool8();
LoadMatchingItems(file, NUM_INVLOC, player.InvBody);
LoadMatchingItems(file, NUM_INV_GRID_ELEM, player.InvList);
LoadMatchingItems(file, MAXBELTITEMS, player.SpdList);
LoadMatchingItems(file, InventoryGridCells, player.InvList);
LoadMatchingItems(file, MaxBeltItems, player.SpdList);
gbIsHellfireSaveGame = gbIsHellfire;
}
@ -1986,7 +1986,7 @@ void LoadStash()
void RemoveEmptyInventory(Player &player)
{
for (int i = NUM_INV_GRID_ELEM; i > 0; i--) {
for (int i = InventoryGridCells; i > 0; i--) {
int8_t idx = player.InvGrid[i - 1];
if (idx > 0 && player.InvList[idx - 1].isEmpty()) {
player.RemoveInvItem(idx - 1);
@ -2197,7 +2197,7 @@ void LoadGame(bool firstflag)
void SaveHeroItems(MpqWriter &saveWriter, Player &player)
{
size_t itemCount = static_cast<size_t>(NUM_INVLOC) + NUM_INV_GRID_ELEM + MAXBELTITEMS;
size_t itemCount = static_cast<size_t>(NUM_INVLOC) + InventoryGridCells + MaxBeltItems;
SaveHelper file(saveWriter, "heroitems", itemCount * (gbIsHellfire ? HellfireItemSaveSize : DiabloItemSaveSize) + sizeof(uint8_t));
file.WriteLE<uint8_t>(gbIsHellfire ? 1 : 0);

2
Source/missiles.cpp

@ -1229,7 +1229,7 @@ void AddStealPotions(Missile &missile, const AddMissileParameter & /*parameter*/
Player &player = Players[abs(pnum) - 1];
bool hasPlayedSFX = false;
for (int si = 0; si < MAXBELTITEMS; si++) {
for (int si = 0; si < MaxBeltItems; si++) {
int ii = -1;
if (player.SpdList[si]._itype == ItemType::Misc) {
if (GenerateRnd(2) == 0)

4
Source/msg.cpp

@ -1747,7 +1747,7 @@ DWORD OnPlayerLevel(const TCmd *pCmd, int pnum)
if (gbBufferMsgs == 1)
SendPacket(pnum, &message, sizeof(message));
else if (message.wParam1 <= MAXCHARLEVEL && pnum != MyPlayerId)
else if (message.wParam1 <= MaxCharacterLevel && pnum != MyPlayerId)
Players[pnum]._pLevel = static_cast<int8_t>(message.wParam1);
return sizeof(message);
@ -2001,7 +2001,7 @@ DWORD OnCheatExperience(const TCmd *pCmd, int pnum) // NOLINT(misc-unused-parame
#ifdef _DEBUG
if (gbBufferMsgs == 1)
SendPacket(pnum, pCmd, sizeof(*pCmd));
else if (Players[pnum]._pLevel < MAXCHARLEVEL) {
else if (Players[pnum]._pLevel < MaxCharacterLevel) {
Players[pnum]._pExperience = Players[pnum]._pNextExper;
if (*sgOptions.Gameplay.experienceBar) {
force_redraw = 255;

2
Source/multi.cpp

@ -139,7 +139,7 @@ void NetReceivePlayerData(TPkt *pkt)
bool IsNetPlayerValid(const Player &player)
{
return player._pLevel >= 1
&& player._pLevel <= MAXCHARLEVEL
&& player._pLevel <= MaxCharacterLevel
&& static_cast<uint8_t>(player._pClass) < enum_size<HeroClass>::value
&& player.plrlevel < NUMLEVELS
&& player.pDifficulty <= DIFF_LAST

8
Source/objects.cpp

@ -2213,7 +2213,7 @@ void OperateBook(int pnum, Object &book)
if (setlvlnum == SL_BONECHAMB) {
player._pMemSpells |= GetSpellBitmask(SPL_GUARDIAN);
if (player._pSplLvl[SPL_GUARDIAN] < MAX_SPELL_LEVEL)
if (player._pSplLvl[SPL_GUARDIAN] < MaxSpellLevel)
player._pSplLvl[SPL_GUARDIAN]++;
Quests[Q_SCHAMB]._qactive = QUEST_DONE;
PlaySfxLoc(IS_QUESTDN, book.position);
@ -2758,7 +2758,7 @@ void OperateShrineEnchanted(Player &player)
spell = 1;
for (int j = SPL_FIREBOLT; j < maxSpells; j++) { // BUGFIX: < MAX_SPELLS, there is no spell with MAX_SPELLS index (fixed)
if ((player._pMemSpells & spell) != 0) {
if (player._pSplLvl[j] < MAX_SPELL_LEVEL)
if (player._pSplLvl[j] < MaxSpellLevel)
player._pSplLvl[j]++;
}
spell *= 2;
@ -2801,9 +2801,9 @@ void OperateShrineCostOfWisdom(Player &player, spell_id spellId, diablo_message
player._pMemSpells |= GetSpellBitmask(spellId);
if (player._pSplLvl[spellId] < MAX_SPELL_LEVEL)
if (player._pSplLvl[spellId] < MaxSpellLevel)
player._pSplLvl[spellId]++;
if (player._pSplLvl[spellId] < MAX_SPELL_LEVEL)
if (player._pSplLvl[spellId] < MaxSpellLevel)
player._pSplLvl[spellId]++;
uint32_t t = player._pMaxManaBase / 10;

10
Source/pack.cpp

@ -121,10 +121,10 @@ void PackPlayer(PlayerPack *pPack, const Player &player, bool manashield, bool n
PackItem(pPack->InvList[i], item, isHellfire);
}
for (int i = 0; i < NUM_INV_GRID_ELEM; i++)
for (int i = 0; i < InventoryGridCells; i++)
pPack->InvGrid[i] = player.InvGrid[i];
for (int i = 0; i < MAXBELTITEMS; i++) {
for (int i = 0; i < MaxBeltItems; i++) {
const Item &item = player.SpdList[i];
bool isHellfire = netSync ? ((item.dwBuff & CF_HELLFIRE) != 0) : gbIsHellfire;
PackItem(pPack->SpdList[i], item, isHellfire);
@ -206,7 +206,7 @@ bool UnPackPlayer(const PlayerPack *pPack, Player &player, bool netSync)
}
auto heroClass = static_cast<HeroClass>(pPack->pClass);
if (pPack->pLevel > MAXCHARLEVEL || pPack->pLevel < 1) {
if (pPack->pLevel > MaxCharacterLevel || pPack->pLevel < 1) {
return false;
}
uint32_t difficulty = SDL_SwapLE32(pPack->pDifficulty);
@ -270,12 +270,12 @@ bool UnPackPlayer(const PlayerPack *pPack, Player &player, bool netSync)
UnPackItem(packedItem, player.InvList[i], isHellfire);
}
for (int i = 0; i < NUM_INV_GRID_ELEM; i++)
for (int i = 0; i < InventoryGridCells; i++)
player.InvGrid[i] = pPack->InvGrid[i];
VerifyGoldSeeds(player);
for (int i = 0; i < MAXBELTITEMS; i++) {
for (int i = 0; i < MaxBeltItems; i++) {
auto packedItem = pPack->SpdList[i];
bool isHellfire = netSync ? ((packedItem.dwBuff & CF_HELLFIRE) != 0) : (pPack->bIsHellfire != 0);
UnPackItem(packedItem, player.SpdList[i], isHellfire);

8
Source/pack.h

@ -38,7 +38,7 @@ struct PlayerPack {
uint8_t py;
uint8_t targx;
uint8_t targy;
char pName[PLR_NAME_LEN];
char pName[PlayerNameLength];
uint8_t pClass;
uint8_t pBaseStr;
uint8_t pBaseMag;
@ -55,10 +55,10 @@ struct PlayerPack {
int8_t pSplLvl[37]; // Should be MAX_SPELLS but set to 37 to make save games compatible
uint64_t pMemSpells;
ItemPack InvBody[NUM_INVLOC];
ItemPack InvList[NUM_INV_GRID_ELEM];
int8_t InvGrid[NUM_INV_GRID_ELEM];
ItemPack InvList[InventoryGridCells];
int8_t InvGrid[InventoryGridCells];
uint8_t _pNumInv;
ItemPack SpdList[MAXBELTITEMS];
ItemPack SpdList[MaxBeltItems];
int8_t pTownWarps;
int8_t pDungMsgs;
int8_t pLvlLoad;

4
Source/panels/charpanel.cpp

@ -105,7 +105,7 @@ StyledText GetResistInfo(int8_t resist)
style = UiFlags::ColorWhite;
else if (resist < 0)
style = UiFlags::ColorRed;
else if (resist >= MAXRESIST)
else if (resist >= MaxResistance)
style = UiFlags::ColorWhitegold;
return { style, fmt::format("{:d}%", resist) };
@ -137,7 +137,7 @@ PanelEntry panelEntries[] = {
} },
{ N_("Next level"), { TopRightLabelX, 80 }, 99, 198,
[]() {
if (MyPlayer->_pLevel == MAXCHARLEVEL) {
if (MyPlayer->_pLevel == MaxCharacterLevel) {
return StyledText { UiFlags::ColorWhitegold, std::string(_("None")) };
}
int spacing = ((MyPlayer->_pNextExper >= 1000000000) ? 0 : 1);

4
Source/pfile.cpp

@ -35,7 +35,7 @@ bool gbValidSaveFile;
namespace {
/** List of character names for the character selection screen. */
char hero_names[MAX_CHARACTERS][PLR_NAME_LEN];
char hero_names[MAX_CHARACTERS][PlayerNameLength];
std::string GetSavePath(uint32_t saveNum, std::string savePrefix = "")
{
@ -420,7 +420,7 @@ bool pfile_ui_save_create(_uiheroinfo *heroinfo)
Player &player = Players[0];
CreatePlayer(player, heroinfo->heroclass);
CopyUtf8(player._pName, heroinfo->name, PLR_NAME_LEN);
CopyUtf8(player._pName, heroinfo->name, PlayerNameLength);
PackPlayer(&pkplr, player, true, false);
EncodeHero(saveWriter, &pkplr);
Game2UiPlayer(player, heroinfo, false);

36
Source/player.cpp

@ -47,16 +47,16 @@ Player Players[MAX_PLRS];
bool MyPlayerIsDead;
/** Specifies the X-coordinate delta from the player start location in Tristram. */
int8_t plrxoff[9] = { 0, 2, 0, 2, 1, 0, 1, 2, 1 };
constexpr int8_t plrxoff[9] = { 0, 2, 0, 2, 1, 0, 1, 2, 1 };
/** Specifies the Y-coordinate delta from the player start location in Tristram. */
int8_t plryoff[9] = { 0, 2, 2, 0, 1, 1, 0, 1, 2 };
constexpr int8_t plryoff[9] = { 0, 2, 2, 0, 1, 1, 0, 1, 2 };
/** Specifies the X-coordinate delta from a player, used for instance when casting resurrect. */
int8_t plrxoff2[9] = { 0, 1, 0, 1, 2, 0, 1, 2, 2 };
constexpr int8_t plrxoff2[9] = { 0, 1, 0, 1, 2, 0, 1, 2, 2 };
/** Specifies the Y-coordinate delta from a player, used for instance when casting resurrect. */
int8_t plryoff2[9] = { 0, 0, 1, 1, 0, 2, 2, 1, 2 };
constexpr int8_t plryoff2[9] = { 0, 0, 1, 1, 0, 2, 2, 1, 2 };
/** Maps from player_class to starting stat in strength. */
int StrengthTbl[enum_size<HeroClass>::value] = {
constexpr int StrengthTbl[enum_size<HeroClass>::value] = {
30,
20,
15,
@ -65,7 +65,7 @@ int StrengthTbl[enum_size<HeroClass>::value] = {
40,
};
/** Maps from player_class to starting stat in magic. */
int MagicTbl[enum_size<HeroClass>::value] = {
constexpr int MagicTbl[enum_size<HeroClass>::value] = {
// clang-format off
10,
15,
@ -76,7 +76,7 @@ int MagicTbl[enum_size<HeroClass>::value] = {
// clang-format on
};
/** Maps from player_class to starting stat in dexterity. */
int DexterityTbl[enum_size<HeroClass>::value] = {
constexpr int DexterityTbl[enum_size<HeroClass>::value] = {
20,
30,
15,
@ -85,7 +85,7 @@ int DexterityTbl[enum_size<HeroClass>::value] = {
20,
};
/** Maps from player_class to starting stat in vitality. */
int VitalityTbl[enum_size<HeroClass>::value] = {
constexpr int VitalityTbl[enum_size<HeroClass>::value] = {
25,
20,
20,
@ -94,7 +94,7 @@ int VitalityTbl[enum_size<HeroClass>::value] = {
25,
};
/** Specifies the chance to block bonus of each player class.*/
int BlockBonuses[enum_size<HeroClass>::value] = {
constexpr int BlockBonuses[enum_size<HeroClass>::value] = {
30,
20,
10,
@ -104,7 +104,7 @@ int BlockBonuses[enum_size<HeroClass>::value] = {
};
/** Specifies the experience point limit of each level. */
uint32_t ExpLvlsTbl[MAXCHARLEVEL + 1] = {
constexpr uint32_t ExpLvlsTbl[MaxCharacterLevel + 1] = {
0,
2000,
4620,
@ -171,7 +171,7 @@ struct DirectionSettings {
};
/** Specifies the frame of each animation for which an action is triggered, for each player class. */
const int8_t PlrGFXAnimLens[enum_size<HeroClass>::value][11] = {
constexpr int8_t PlrGFXAnimLens[enum_size<HeroClass>::value][11] = {
{ 10, 16, 8, 2, 20, 20, 6, 20, 8, 9, 14 },
{ 8, 18, 8, 4, 20, 16, 7, 20, 8, 10, 12 },
{ 8, 16, 8, 6, 20, 12, 8, 20, 8, 12, 8 },
@ -180,7 +180,7 @@ const int8_t PlrGFXAnimLens[enum_size<HeroClass>::value][11] = {
{ 10, 16, 8, 2, 20, 20, 6, 20, 8, 9, 14 },
};
/** Maps from player class to player velocity. */
int PWVel[enum_size<HeroClass>::value][3] = {
constexpr int PWVel[enum_size<HeroClass>::value][3] = {
{ 2048, 1024, 512 },
{ 2048, 1024, 512 },
{ 2048, 1024, 512 },
@ -255,7 +255,7 @@ void WalkSideways(int pnum, const DirectionSettings &walkParams)
player.position.temp = player.position.future;
}
_sfx_id herosounds[enum_size<HeroClass>::value][enum_size<HeroSpeech>::value] = {
constexpr _sfx_id herosounds[enum_size<HeroClass>::value][enum_size<HeroSpeech>::value] = {
// clang-format off
{ PS_WARR1, PS_WARR2, PS_WARR3, PS_WARR4, PS_WARR5, PS_WARR6, PS_WARR7, PS_WARR8, PS_WARR9, PS_WARR10, PS_WARR11, PS_WARR12, PS_WARR13, PS_WARR14, PS_WARR15, PS_WARR16, PS_WARR17, PS_WARR18, PS_WARR19, PS_WARR20, PS_WARR21, PS_WARR22, PS_WARR23, PS_WARR24, PS_WARR25, PS_WARR26, PS_WARR27, PS_WARR28, PS_WARR29, PS_WARR30, PS_WARR31, PS_WARR32, PS_WARR33, PS_WARR34, PS_WARR35, PS_WARR36, PS_WARR37, PS_WARR38, PS_WARR39, PS_WARR40, PS_WARR41, PS_WARR42, PS_WARR43, PS_WARR44, PS_WARR45, PS_WARR46, PS_WARR47, PS_WARR48, PS_WARR49, PS_WARR50, PS_WARR51, PS_WARR52, PS_WARR53, PS_WARR54, PS_WARR55, PS_WARR56, PS_WARR57, PS_WARR58, PS_WARR59, PS_WARR60, PS_WARR61, PS_WARR62, PS_WARR63, PS_WARR64, PS_WARR65, PS_WARR66, PS_WARR67, PS_WARR68, PS_WARR69, PS_WARR70, PS_WARR71, PS_WARR72, PS_WARR73, PS_WARR74, PS_WARR75, PS_WARR76, PS_WARR77, PS_WARR78, PS_WARR79, PS_WARR80, PS_WARR81, PS_WARR82, PS_WARR83, PS_WARR84, PS_WARR85, PS_WARR86, PS_WARR87, PS_WARR88, PS_WARR89, PS_WARR90, PS_WARR91, PS_WARR92, PS_WARR93, PS_WARR94, PS_WARR95, PS_WARR96B, PS_WARR97, PS_WARR98, PS_WARR99, PS_WARR100, PS_WARR101, PS_WARR102, PS_DEAD },
{ PS_ROGUE1, PS_ROGUE2, PS_ROGUE3, PS_ROGUE4, PS_ROGUE5, PS_ROGUE6, PS_ROGUE7, PS_ROGUE8, PS_ROGUE9, PS_ROGUE10, PS_ROGUE11, PS_ROGUE12, PS_ROGUE13, PS_ROGUE14, PS_ROGUE15, PS_ROGUE16, PS_ROGUE17, PS_ROGUE18, PS_ROGUE19, PS_ROGUE20, PS_ROGUE21, PS_ROGUE22, PS_ROGUE23, PS_ROGUE24, PS_ROGUE25, PS_ROGUE26, PS_ROGUE27, PS_ROGUE28, PS_ROGUE29, PS_ROGUE30, PS_ROGUE31, PS_ROGUE32, PS_ROGUE33, PS_ROGUE34, PS_ROGUE35, PS_ROGUE36, PS_ROGUE37, PS_ROGUE38, PS_ROGUE39, PS_ROGUE40, PS_ROGUE41, PS_ROGUE42, PS_ROGUE43, PS_ROGUE44, PS_ROGUE45, PS_ROGUE46, PS_ROGUE47, PS_ROGUE48, PS_ROGUE49, PS_ROGUE50, PS_ROGUE51, PS_ROGUE52, PS_ROGUE53, PS_ROGUE54, PS_ROGUE55, PS_ROGUE56, PS_ROGUE57, PS_ROGUE58, PS_ROGUE59, PS_ROGUE60, PS_ROGUE61, PS_ROGUE62, PS_ROGUE63, PS_ROGUE64, PS_ROGUE65, PS_ROGUE66, PS_ROGUE67, PS_ROGUE68, PS_ROGUE69, PS_ROGUE70, PS_ROGUE71, PS_ROGUE72, PS_ROGUE73, PS_ROGUE74, PS_ROGUE75, PS_ROGUE76, PS_ROGUE77, PS_ROGUE78, PS_ROGUE79, PS_ROGUE80, PS_ROGUE81, PS_ROGUE82, PS_ROGUE83, PS_ROGUE84, PS_ROGUE85, PS_ROGUE86, PS_ROGUE87, PS_ROGUE88, PS_ROGUE89, PS_ROGUE90, PS_ROGUE91, PS_ROGUE92, PS_ROGUE93, PS_ROGUE94, PS_ROGUE95, PS_ROGUE96, PS_ROGUE97, PS_ROGUE98, PS_ROGUE99, PS_ROGUE100, PS_ROGUE101, PS_ROGUE102, PS_ROGUE71 },
@ -1778,8 +1778,8 @@ void ValidatePlayer()
}
Player &myPlayer = *MyPlayer;
if (myPlayer._pLevel > MAXCHARLEVEL)
myPlayer._pLevel = MAXCHARLEVEL;
if (myPlayer._pLevel > MaxCharacterLevel)
myPlayer._pLevel = MaxCharacterLevel;
if (myPlayer._pExperience > myPlayer._pNextExper) {
myPlayer._pExperience = myPlayer._pNextExper;
if (*sgOptions.Gameplay.experienceBar) {
@ -1820,8 +1820,8 @@ void ValidatePlayer()
for (int b = SPL_FIREBOLT; b < MAX_SPELLS; b++) {
if (GetSpellBookLevel((spell_id)b) != -1) {
msk |= GetSpellBitmask(b);
if (myPlayer._pSplLvl[b] > MAX_SPELL_LEVEL)
myPlayer._pSplLvl[b] = MAX_SPELL_LEVEL;
if (myPlayer._pSplLvl[b] > MaxSpellLevel)
myPlayer._pSplLvl[b] = MaxSpellLevel;
}
}
@ -2680,7 +2680,7 @@ void AddPlrExperience(Player &player, int lvl, int exp)
// Prevent power leveling
if (gbIsMultiplayer) {
const uint32_t clampedPlayerLevel = clamp(static_cast<int>(player._pLevel), 1, MAXCHARLEVEL);
const uint32_t clampedPlayerLevel = clamp(static_cast<int>(player._pLevel), 1, MaxCharacterLevel);
// 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.

43
Source/player.h

@ -28,13 +28,12 @@
namespace devilution {
// number of inventory grid cells
#define NUM_INV_GRID_ELEM 40
#define MAXBELTITEMS 8
#define MAXRESIST 75
#define MAXCHARLEVEL 50
#define MAX_SPELL_LEVEL 15
#define PLR_NAME_LEN 32
constexpr int InventoryGridCells = 40;
constexpr int MaxBeltItems = 8;
constexpr int MaxResistance = 75;
constexpr int MaxCharacterLevel = 50;
constexpr int MaxSpellLevel = 15;
constexpr int PlayerNameLength = 32;
constexpr size_t NumHotkeys = 12;
constexpr int BaseHitChance = 50;
@ -261,7 +260,7 @@ struct Player {
bool _pInvincible;
int8_t _pLightRad;
bool _pLvlChanging; // True when the player is transitioning between levels
char _pName[PLR_NAME_LEN];
char _pName[PlayerNameLength];
HeroClass _pClass;
int _pStrength;
int _pBaseStr;
@ -314,10 +313,10 @@ struct Player {
int8_t _pDFrames;
int8_t _pBFrames;
Item InvBody[NUM_INVLOC];
Item InvList[NUM_INV_GRID_ELEM];
Item InvList[InventoryGridCells];
int _pNumInv;
int8_t InvGrid[NUM_INV_GRID_ELEM];
Item SpdList[MAXBELTITEMS];
int8_t InvGrid[InventoryGridCells];
Item SpdList[MaxBeltItems];
Item HoldItem;
int _pIMinDam;
int _pIMaxDam;
@ -394,7 +393,7 @@ struct Player {
return mostValuableItem;
};
const Item *mostValuableItem = getMostValuableItem(SpdList, SpdList + MAXBELTITEMS);
const Item *mostValuableItem = getMostValuableItem(SpdList, SpdList + MaxBeltItems);
mostValuableItem = getMostValuableItem(InvBody, InvBody + inv_body_loc::NUM_INVLOC, mostValuableItem);
mostValuableItem = getMostValuableItem(InvList, InvList + _pNumInv, mostValuableItem);
@ -744,7 +743,7 @@ extern DVL_API_FOR_TEST int MyPlayerId;
extern DVL_API_FOR_TEST Player *MyPlayer;
extern DVL_API_FOR_TEST Player Players[MAX_PLRS];
extern bool MyPlayerIsDead;
extern int BlockBonuses[enum_size<HeroClass>::value];
extern const int BlockBonuses[enum_size<HeroClass>::value];
void LoadPlrGFX(Player &player, player_graphic graphic);
void InitPlayerGFX(Player &player);
@ -815,14 +814,14 @@ void PlayDungMsgs();
/* data */
extern int8_t plrxoff[9];
extern int8_t plryoff[9];
extern int8_t plrxoff2[9];
extern int8_t plryoff2[9];
extern int StrengthTbl[enum_size<HeroClass>::value];
extern int MagicTbl[enum_size<HeroClass>::value];
extern int DexterityTbl[enum_size<HeroClass>::value];
extern int VitalityTbl[enum_size<HeroClass>::value];
extern uint32_t ExpLvlsTbl[MAXCHARLEVEL + 1];
extern const int8_t plrxoff[9];
extern const int8_t plryoff[9];
extern const int8_t plrxoff2[9];
extern const int8_t plryoff2[9];
extern const int StrengthTbl[enum_size<HeroClass>::value];
extern const int MagicTbl[enum_size<HeroClass>::value];
extern const int DexterityTbl[enum_size<HeroClass>::value];
extern const int VitalityTbl[enum_size<HeroClass>::value];
extern const uint32_t ExpLvlsTbl[MaxCharacterLevel + 1];
} // namespace devilution

4
Source/qol/xpbar.cpp

@ -80,7 +80,7 @@ void DrawXPBar(const Surface &out)
const int8_t charLevel = player._pLevel;
if (charLevel == MAXCHARLEVEL) {
if (charLevel == MaxCharacterLevel) {
// Draw a nice golden bar for max level characters.
DrawBar(out, position, BarWidth, GoldGradient);
@ -126,7 +126,7 @@ bool CheckXPBarInfo()
AddPanelString(fmt::format(fmt::runtime(_("Level {:d}")), charLevel));
if (charLevel == MAXCHARLEVEL) {
if (charLevel == MaxCharacterLevel) {
// Show a maximum level indicator for max level players.
InfoColor = UiFlags::ColorWhitegold;

4
Source/stores.cpp

@ -568,7 +568,7 @@ void StartSmithSell()
}
}
for (int i = 0; i < MAXBELTITEMS; i++) {
for (int i = 0; i < MaxBeltItems; i++) {
if (storenumh >= 48)
break;
if (SmithSellOk(-(i + 1))) {
@ -836,7 +836,7 @@ void StartWitchSell()
}
}
for (int i = 0; i < MAXBELTITEMS; i++) {
for (int i = 0; i < MaxBeltItems; i++) {
if (storenumh >= 48)
break;
if (!myPlayer.SpdList[i].isEmpty() && WitchSellOk(-(i + 1))) {

8
test/inv_test.cpp

@ -20,7 +20,7 @@ void set_up_scroll(Item &item, spell_id spell)
/* Clear the inventory of MyPlayerId. */
void clear_inventory()
{
for (int i = 0; i < NUM_INV_GRID_ELEM; i++) {
for (int i = 0; i < InventoryGridCells; i++) {
MyPlayer->InvList[i] = {};
MyPlayer->InvGrid[i] = 0;
}
@ -46,7 +46,7 @@ TEST(Inv, UseScroll_from_belt)
TEST(Inv, UseScroll_from_inventory_invalid_conditions)
{
// Empty the belt to prevent using a scroll from the belt
for (int i = 0; i < MAXBELTITEMS; i++) {
for (int i = 0; i < MaxBeltItems; i++) {
MyPlayer->SpdList[i].clear();
}
@ -181,7 +181,7 @@ TEST(Inv, RemoveInvItem_other_item)
TEST(Inv, RemoveSpdBarItem)
{
// Clear the belt
for (int i = 0; i < MAXBELTITEMS; i++) {
for (int i = 0; i < MaxBeltItems; i++) {
MyPlayer->SpdList[i].clear();
}
// Put an item in the belt: | x | x | item | x | x | x | x | x |
@ -212,7 +212,7 @@ TEST(Inv, RemoveCurrentSpellScroll_inventory)
TEST(Inv, RemoveCurrentSpellScroll_belt)
{
// Clear the belt
for (int i = 0; i < MAXBELTITEMS; i++) {
for (int i = 0; i < MaxBeltItems; i++) {
MyPlayer->SpdList[i].clear();
}
// Put a firebolt scroll into the belt

6
test/player_test.cpp

@ -91,10 +91,10 @@ TEST(Player, PM_DoGotHit)
static void AssertPlayer(Player &player)
{
ASSERT_EQ(Count8(player._pSplLvl, 64), 0);
ASSERT_EQ(Count8(player.InvGrid, NUM_INV_GRID_ELEM), 1);
ASSERT_EQ(Count8(player.InvGrid, InventoryGridCells), 1);
ASSERT_EQ(CountItems(player.InvBody, NUM_INVLOC), 1);
ASSERT_EQ(CountItems(player.InvList, NUM_INV_GRID_ELEM), 1);
ASSERT_EQ(CountItems(player.SpdList, MAXBELTITEMS), 2);
ASSERT_EQ(CountItems(player.InvList, InventoryGridCells), 1);
ASSERT_EQ(CountItems(player.SpdList, MaxBeltItems), 2);
ASSERT_EQ(CountItems(&player.HoldItem, 1), 0);
ASSERT_EQ(player.position.tile.x, 0);

8
test/writehero_test.cpp

@ -180,7 +180,7 @@ static void PackPlayerTest(PlayerPack *pPack)
pPack->InvList[i].idx = -1;
for (auto i = 0; i < 7; i++)
pPack->InvBody[i].idx = -1;
for (auto i = 0; i < MAXBELTITEMS; i++)
for (auto i = 0; i < MaxBeltItems; i++)
PackItemFullRejuv(pPack->SpdList + i, i);
for (auto i = 1; i < 37; i++) {
if (spelldat_vanilla[i] != -1) {
@ -217,10 +217,10 @@ static void PackPlayerTest(PlayerPack *pPack)
static void AssertPlayer(Player &player)
{
ASSERT_EQ(Count8(player._pSplLvl, 64), 23);
ASSERT_EQ(Count8(player.InvGrid, NUM_INV_GRID_ELEM), 9);
ASSERT_EQ(Count8(player.InvGrid, InventoryGridCells), 9);
ASSERT_EQ(CountItems(player.InvBody, NUM_INVLOC), 6);
ASSERT_EQ(CountItems(player.InvList, NUM_INV_GRID_ELEM), 2);
ASSERT_EQ(CountItems(player.SpdList, MAXBELTITEMS), 8);
ASSERT_EQ(CountItems(player.InvList, InventoryGridCells), 2);
ASSERT_EQ(CountItems(player.SpdList, MaxBeltItems), 8);
ASSERT_EQ(CountItems(&player.HoldItem, 1), 0);
ASSERT_EQ(player.position.tile.x, 75);

Loading…
Cancel
Save