diff --git a/Source/items.cpp b/Source/items.cpp index 0877b60c7..8425b08b1 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -2694,7 +2694,7 @@ void CalcPlrItemVals(Player &player, bool loadgfx) player._pIAC += player._pLevel * 2; } - int gfxNum = static_cast(animWeaponId) | static_cast(animArmorId); + const uint8_t gfxNum = static_cast(animWeaponId) | static_cast(animArmorId); if (player._pgfxnum != gfxNum && loadgfx) { player._pgfxnum = gfxNum; ResetPlayerGFX(player); diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index f0f8a7e08..680f04cf2 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -146,8 +146,7 @@ public: template TDesired NextLENarrow(TSource modifier = 0) { - static_assert(std::numeric_limits::min() < std::numeric_limits::min()); - static_assert(std::numeric_limits::max() > std::numeric_limits::max()); + static_assert(sizeof(TSource) > sizeof(TDesired), "Can only narrow to a smaller type"); TSource value = SwapLE(Next()) + modifier; return static_cast(clamp(value, std::numeric_limits::min(), std::numeric_limits::max())); } @@ -346,7 +345,7 @@ void LoadPlayer(LoadHelper &file, Player &player) file.Skip(4); // Skip offset and velocity player._pdir = static_cast(file.NextLE()); file.Skip(4); // Unused - player._pgfxnum = file.NextLE(); + player._pgfxnum = file.NextLENarrow(); file.Skip(); // Skip pointer pData player.AnimInfo = {}; player.AnimInfo.ticksPerFrame = file.NextLENarrow(1); @@ -1116,7 +1115,7 @@ void SavePlayer(SaveHelper &file, const Player &player) file.WriteLE(velocity.deltaY); file.WriteLE(static_cast(player._pdir)); file.Skip(4); // Unused - file.WriteLE(player._pgfxnum); + file.WriteLE(player._pgfxnum); file.Skip(4); // Skip pointer _pAnimData file.WriteLE(std::max(0, player.AnimInfo.ticksPerFrame - 1)); file.WriteLE(player.AnimInfo.tickCounterOfCurrentFrame); diff --git a/Source/msg.cpp b/Source/msg.cpp index 86ef5978a..d373ad5e6 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -2090,7 +2090,7 @@ size_t OnPlayerJoinLevel(const TCmd *pCmd, size_t pnum) if ((player._pHitPoints >> 6) > 0) { StartStand(player, Direction::South); } else { - player._pgfxnum &= ~0xF; + player._pgfxnum &= ~0xFU; player._pmode = PM_DEATH; NewPlrAnim(player, player_graphic::Death, Direction::South); player.AnimInfo.currentFrame = player.AnimInfo.numberOfFrames - 2; diff --git a/Source/multi.cpp b/Source/multi.cpp index d4802a514..a0c96ee01 100644 --- a/Source/multi.cpp +++ b/Source/multi.cpp @@ -839,7 +839,7 @@ void recv_plrinfo(int pnum, const TCmdPlrInfoHdr &header, bool recv) return; } - player._pgfxnum &= ~0xF; + player._pgfxnum &= ~0xFU; player._pmode = PM_DEATH; NewPlrAnim(player, player_graphic::Death, Direction::South); player.AnimInfo.currentFrame = player.AnimInfo.numberOfFrames - 2; diff --git a/Source/player.cpp b/Source/player.cpp index 442ef2519..e43bdfae0 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -2293,7 +2293,7 @@ void InitPlayerGFX(Player &player) ResetPlayerGFX(player); if (player._pHitPoints >> 6 == 0) { - player._pgfxnum &= ~0xF; + player._pgfxnum &= ~0xFU; LoadPlrGFX(player, player_graphic::Death); return; } @@ -2354,8 +2354,8 @@ void SetPlrAnims(Player &player) } player._pSFNum = PlrGFXAnimLens[static_cast(pc)][10]; - auto gn = static_cast(player._pgfxnum & 0xF); - int armorGraphicIndex = player._pgfxnum & ~0xF; + auto gn = static_cast(player._pgfxnum & 0xFU); + int armorGraphicIndex = player._pgfxnum & ~0xFU; if (pc == HeroClass::Warrior) { if (gn == PlayerWeaponGraphic::Bow) { if (leveltype != DTYPE_TOWN) { @@ -2570,7 +2570,7 @@ void CreatePlayer(Player &player, HeroClass c) animWeaponId = PlayerWeaponGraphic::Staff; break; } - player._pgfxnum = static_cast(animWeaponId); + player._pgfxnum = static_cast(animWeaponId); for (bool &levelVisited : player._pLvlVisited) { levelVisited = false; @@ -2745,7 +2745,7 @@ void InitPlayer(Player &player, bool firstTime) player.AnimInfo.currentFrame = GenerateRnd(player._pNFrames - 1); player.AnimInfo.tickCounterOfCurrentFrame = GenerateRnd(3); } else { - player._pgfxnum &= ~0xF; + player._pgfxnum &= ~0xFU; player._pmode = PM_DEATH; NewPlrAnim(player, player_graphic::Death, Direction::South); player.AnimInfo.currentFrame = player.AnimInfo.numberOfFrames - 2; @@ -2955,7 +2955,7 @@ StartPlayerKill(Player &player, int earflag) if (player._pgfxnum != 0) { if (diablolevel || earflag != 0) - player._pgfxnum &= ~0xF; + player._pgfxnum &= ~0xFU; else player._pgfxnum = 0; ResetPlayerGFX(player); diff --git a/Source/player.h b/Source/player.h index 041a9f3cb..a1bb2cbc4 100644 --- a/Source/player.h +++ b/Source/player.h @@ -220,6 +220,53 @@ struct Player { Player(Player &&) noexcept = default; Player &operator=(Player &&) noexcept = default; + char _pName[PlayerNameLength]; + Item InvBody[NUM_INVLOC]; + Item InvList[InventoryGridCells]; + Item SpdList[MaxBeltItems]; + Item HoldItem; + + int _plid; + int _pvid; + + int _pNumInv; + int _pStrength; + int _pBaseStr; + int _pMagic; + int _pBaseMag; + int _pDexterity; + int _pBaseDex; + int _pVitality; + int _pBaseVit; + int _pStatPts; + int _pDamageMod; + int _pBaseToBlk; + int _pHPBase; + int _pMaxHPBase; + int _pHitPoints; + int _pMaxHP; + int _pHPPer; + int _pManaBase; + int _pMaxManaBase; + int _pMana; + int _pMaxMana; + int _pManaPer; + int _pIMinDam; + int _pIMaxDam; + int _pIAC; + int _pIBonusDam; + int _pIBonusToHit; + int _pIBonusAC; + int _pIBonusDamMod; + int _pIGetHit; + int _pISplDur; + int _pIEnAc; + int _pIFMinDam; + int _pIFMaxDam; + int _pILMinDam; + int _pILMaxDam; + uint32_t _pExperience; + uint32_t _pNextExper; PLR_MODE _pmode; int8_t walkpath[MaxPathLength]; bool plractive; @@ -228,11 +275,8 @@ struct Player { int destParam2; int destParam3; int destParam4; - uint8_t plrlevel; - bool plrIsOnSetLevel; - ActorPosition position; - Direction _pdir; // Direction faced by player (direction enum) - int _pgfxnum; // Bitmask indicating what variant of the sprite the player is using. Lower byte define weapon (PlayerWeaponGraphic) and higher values define armour (starting with PlayerArmorGraphic) + int _pGold; + /** * @brief Contains Information for current Animation */ @@ -245,103 +289,72 @@ struct Player { * @brief Contains the progress to next game tick when previewCelSprite was set */ float progressToNextGameTickWhenPreviewWasSet; - int _plid; - int _pvid; - /* @brief next queued spell */ + /** @brief Bitmask using item_special_effect */ + ItemSpecialEffect _pIFlags; + /** + * @brief Contains Data (Sprites) for the different Animations + */ + std::array::value> AnimationData; + int8_t _pNFrames; + int8_t _pWFrames; + int8_t _pAFrames; + int8_t _pAFNum; + int8_t _pSFrames; + int8_t _pSFNum; + int8_t _pHFrames; + int8_t _pDFrames; + int8_t _pBFrames; + int8_t InvGrid[InventoryGridCells]; + + uint8_t plrlevel; + bool plrIsOnSetLevel; + ActorPosition position; + Direction _pdir; // Direction faced by player (direction enum) + HeroClass _pClass; + int8_t _pLevel; + int8_t _pMaxLvl; + uint8_t _pgfxnum; // Bitmask indicating what variant of the sprite the player is using. The 3 lower bits define weapon (PlayerWeaponGraphic) and the higher bits define armour (starting with PlayerArmorGraphic) + int8_t _pISplLvlAdd; + /** @brief Specifies whether players are in non-PvP mode. */ + bool friendlyMode = true; + + /** @brief The next queued spell */ SpellCastInfo queuedSpell; - /* @brief the spell that is currently casted */ + /** @brief The spell that is currently being cast */ SpellCastInfo executedSpell; spell_id _pTSpell; spell_id _pRSpell; spell_type _pRSplType; spell_id _pSBkSpell; int8_t _pSplLvl[64]; - uint64_t _pMemSpells; // Bitmask of learned spells - uint64_t _pAblSpells; // Bitmask of abilities - uint64_t _pScrlSpells; // Bitmask of spells available via scrolls + /** @brief Bitmask of staff spell */ + uint64_t _pISpells; + /** @brief Bitmask of learned spells */ + uint64_t _pMemSpells; + /** @brief Bitmask of abilities */ + uint64_t _pAblSpells; + /** @brief Bitmask of spells available via scrolls */ + uint64_t _pScrlSpells; SpellFlag _pSpellFlags; spell_id _pSplHotKey[NumHotkeys]; spell_type _pSplTHotKey[NumHotkeys]; bool _pBlockFlag; bool _pInvincible; int8_t _pLightRad; - bool _pLvlChanging; // True when the player is transitioning between levels - char _pName[PlayerNameLength]; - HeroClass _pClass; - int _pStrength; - int _pBaseStr; - int _pMagic; - int _pBaseMag; - int _pDexterity; - int _pBaseDex; - int _pVitality; - int _pBaseVit; - int _pStatPts; - int _pDamageMod; - int _pBaseToBlk; - int _pHPBase; - int _pMaxHPBase; - int _pHitPoints; - int _pMaxHP; - int _pHPPer; - int _pManaBase; - int _pMaxManaBase; - int _pMana; - int _pMaxMana; - int _pManaPer; - int8_t _pLevel; - int8_t _pMaxLvl; - uint32_t _pExperience; - uint32_t _pNextExper; + /** @brief True when the player is transitioning between levels */ + bool _pLvlChanging; + int8_t _pArmorClass; int8_t _pMagResist; int8_t _pFireResist; int8_t _pLghtResist; - int _pGold; bool _pInfraFlag; /** Player's direction when ending movement. Also used for casting direction of SPL_FIREWALL. */ Direction tempDirection; bool _pLvlVisited[NUMLEVELS]; bool _pSLvlVisited[NUMLEVELS]; // only 10 used - /** - * @brief Contains Data (Sprites) for the different Animations - */ - std::array::value> AnimationData; - int8_t _pNFrames; - int8_t _pWFrames; - int8_t _pAFrames; - int8_t _pAFNum; - int8_t _pSFrames; - int8_t _pSFNum; - int8_t _pHFrames; - int8_t _pDFrames; - int8_t _pBFrames; - Item InvBody[NUM_INVLOC]; - Item InvList[InventoryGridCells]; - int _pNumInv; - int8_t InvGrid[InventoryGridCells]; - Item SpdList[MaxBeltItems]; - Item HoldItem; - int _pIMinDam; - int _pIMaxDam; - int _pIAC; - int _pIBonusDam; - int _pIBonusToHit; - int _pIBonusAC; - int _pIBonusDamMod; - /** Bitmask of staff spell */ - uint64_t _pISpells; - /** Bitmask using item_special_effect */ - ItemSpecialEffect _pIFlags; - int _pIGetHit; - int8_t _pISplLvlAdd; - int _pISplDur; - int _pIEnAc; - int _pIFMinDam; - int _pIFMaxDam; - int _pILMinDam; - int _pILMaxDam; + item_misc_id _pOilType; uint8_t pTownWarps; uint8_t pDungMsgs; @@ -350,12 +363,10 @@ struct Player { bool pManaShield; uint8_t pDungMsgs2; bool pOriginalCathedral; - uint16_t wReflections; uint8_t pDiabloKillLevel; + uint16_t wReflections; _difficulty pDifficulty; ItemSpecialEffectHf pDamAcFlags; - /** @brief Specifies whether players are in non-PvP mode. */ - bool friendlyMode = true; void CalcScrolls();