From efa51993e3df37d85c6928d502b0da1c7befa36f Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Wed, 21 Jun 2023 19:49:07 +0200 Subject: [PATCH] Split network player sync and hero save file --- Source/msg.cpp | 64 ++++++------ Source/msg.h | 2 + Source/multi.cpp | 14 +-- Source/pack.cpp | 217 +++++++++++++++++++++++++++++----------- Source/pack.h | 51 ++++++++-- Source/pfile.cpp | 26 ++--- test/writehero_test.cpp | 6 +- 7 files changed, 250 insertions(+), 130 deletions(-) diff --git a/Source/msg.cpp b/Source/msg.cpp index 85f9c7fe1..31834dc02 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -970,19 +970,6 @@ bool IsPItemValid(const TCmdPItem &message) return IsItemAvailable(static_cast<_item_indexes>(SDL_SwapLE16(message.def.wIndx))); } -void PrepareItemForNetwork(const Item &item, TItem &messageItem) -{ - messageItem.bId = item._iIdentified ? 1 : 0; - messageItem.bDur = item._iDurability; - messageItem.bMDur = item._iMaxDur; - messageItem.bCh = item._iCharges; - messageItem.bMCh = item._iMaxCharges; - messageItem.wValue = SDL_SwapLE16(item._ivalue); - messageItem.wToHit = SDL_SwapLE16(item._iPLToHit); - messageItem.wMaxDam = SDL_SwapLE16(item._iMaxDam); - messageItem.dwBuff = SDL_SwapLE32(item.dwBuff); -} - void PrepareEarForNetwork(const Item &item, TEar &ear) { ear.bCursval = item._ivalue | ((item._iCurs - ICURS_EAR_SORCERER) << 6); @@ -1025,25 +1012,6 @@ void PrepareItemForNetwork(const Item &item, TCmdChItem &message) PrepareItemForNetwork(item, message.item); } -void RecreateItem(const Player &player, const TItem &messageItem, Item &item) -{ - const uint32_t dwBuff = SDL_SwapLE32(messageItem.dwBuff); - RecreateItem(player, item, - static_cast<_item_indexes>(SDL_SwapLE16(messageItem.wIndx)), SDL_SwapLE16(messageItem.wCI), - SDL_SwapLE32(messageItem.dwSeed), SDL_SwapLE16(messageItem.wValue), (dwBuff & CF_HELLFIRE) != 0); - if (messageItem.bId != 0) - item._iIdentified = true; - item._iMaxDur = messageItem.bMDur; - item._iDurability = ClampDurability(item, messageItem.bDur); - item._iMaxCharges = clamp(messageItem.bMCh, 0, item._iMaxCharges); - item._iCharges = clamp(messageItem.bCh, 0, item._iMaxCharges); - if (gbIsHellfire) { - item._iPLToHit = ClampToHit(item, SDL_SwapLE16(messageItem.wToHit)); - item._iMaxDam = ClampMaxDam(item, SDL_SwapLE16(messageItem.wMaxDam)); - } - item.dwBuff = dwBuff; -} - void RecreateItem(const Player &player, const TCmdPItem &message, Item &item) { if (message.def.wIndx == SDL_SwapLE16(IDI_EAR)) @@ -2359,6 +2327,38 @@ size_t OnOpenGrave(const TCmd *pCmd) } // namespace +void PrepareItemForNetwork(const Item &item, TItem &messageItem) +{ + messageItem.bId = item._iIdentified ? 1 : 0; + messageItem.bDur = item._iDurability; + messageItem.bMDur = item._iMaxDur; + messageItem.bCh = item._iCharges; + messageItem.bMCh = item._iMaxCharges; + messageItem.wValue = SDL_SwapLE16(item._ivalue); + messageItem.wToHit = SDL_SwapLE16(item._iPLToHit); + messageItem.wMaxDam = SDL_SwapLE16(item._iMaxDam); + messageItem.dwBuff = SDL_SwapLE32(item.dwBuff); +} + +void RecreateItem(const Player &player, const TItem &messageItem, Item &item) +{ + const uint32_t dwBuff = SDL_SwapLE32(messageItem.dwBuff); + RecreateItem(player, item, + static_cast<_item_indexes>(SDL_SwapLE16(messageItem.wIndx)), SDL_SwapLE16(messageItem.wCI), + SDL_SwapLE32(messageItem.dwSeed), SDL_SwapLE16(messageItem.wValue), (dwBuff & CF_HELLFIRE) != 0); + if (messageItem.bId != 0) + item._iIdentified = true; + item._iMaxDur = messageItem.bMDur; + item._iDurability = ClampDurability(item, messageItem.bDur); + item._iMaxCharges = clamp(messageItem.bMCh, 0, item._iMaxCharges); + item._iCharges = clamp(messageItem.bCh, 0, item._iMaxCharges); + if (gbIsHellfire) { + item._iPLToHit = ClampToHit(item, SDL_SwapLE16(messageItem.wToHit)); + item._iMaxDam = ClampMaxDam(item, SDL_SwapLE16(messageItem.wMaxDam)); + } + item.dwBuff = dwBuff; +} + void ClearLastSentPlayerCmd() { lastSentPlayerCmd = {}; diff --git a/Source/msg.h b/Source/msg.h index 06ed60734..cdfaaaf6b 100644 --- a/Source/msg.h +++ b/Source/msg.h @@ -720,6 +720,8 @@ struct TBuffer { extern uint8_t gbBufferMsgs; extern int dwRecCount; +void PrepareItemForNetwork(const Item &item, TItem &messageItem); +void RecreateItem(const Player &player, const TItem &messageItem, Item &item); void msg_send_drop_pkt(int pnum, int reason); bool msg_wait_resync(); void run_delta_info(); diff --git a/Source/multi.cpp b/Source/multi.cpp index 1f2f5513a..05ae8f148 100644 --- a/Source/multi.cpp +++ b/Source/multi.cpp @@ -349,12 +349,10 @@ void ProcessTmsgs() void SendPlayerInfo(int pnum, _cmd_id cmd) { - PlayerPack pPack; + PlayerNetPack packed; Player &myPlayer = *MyPlayer; - PackPlayer(&pPack, myPlayer, true, true); - pPack.friendlyMode = myPlayer.friendlyMode ? 1 : 0; - pPack.isOnSetLevel = myPlayer.plrIsOnSetLevel; - multi_send_zero_packet(pnum, cmd, reinterpret_cast(&pPack), sizeof(PlayerPack)); + PackNetPlayer(packed, myPlayer); + multi_send_zero_packet(pnum, cmd, reinterpret_cast(&packed), sizeof(PlayerNetPack)); } void SetupLocalPositions() @@ -803,7 +801,7 @@ bool NetInit(bool bSinglePlayer) void recv_plrinfo(int pnum, const TCmdPlrInfoHdr &header, bool recv) { - static PlayerPack PackedPlayerBuffer[MAX_PLRS]; + static PlayerNetPack PackedPlayerBuffer[MAX_PLRS]; assert(pnum >= 0 && pnum < MAX_PLRS); Player &player = Players[pnum]; @@ -831,11 +829,9 @@ void recv_plrinfo(int pnum, const TCmdPlrInfoHdr &header, bool recv) sgwPackPlrOffsetTbl[pnum] = 0; PlayerLeftMsg(pnum, false); - if (!UnPackPlayer(&packedPlayer, player, true)) { + if (!UnPackNetPlayer(packedPlayer, player)) { return; } - player.friendlyMode = packedPlayer.friendlyMode != 0; - player.plrIsOnSetLevel = packedPlayer.isOnSetLevel != 0; if (!recv) { return; diff --git a/Source/pack.cpp b/Source/pack.cpp index 70ff9a2e3..d70f242c9 100644 --- a/Source/pack.cpp +++ b/Source/pack.cpp @@ -78,7 +78,7 @@ void PackItem(ItemPack &packedItem, const Item &item, bool isHellfire) } } -void PackPlayer(PlayerPack *pPack, const Player &player, bool manashield, bool netSync) +void PackPlayer(PlayerPack *pPack, const Player &player) { memset(pPack, 0, sizeof(*pPack)); pPack->destAction = player.destAction; @@ -114,14 +114,14 @@ void PackPlayer(PlayerPack *pPack, const Player &player, bool manashield, bool n for (int i = 0; i < NUM_INVLOC; i++) { const Item &item = player.InvBody[i]; - bool isHellfire = netSync ? ((item.dwBuff & CF_HELLFIRE) != 0) : gbIsHellfire; + bool isHellfire = gbIsHellfire; PackItem(pPack->InvBody[i], item, isHellfire); } pPack->_pNumInv = player._pNumInv; for (int i = 0; i < pPack->_pNumInv; i++) { const Item &item = player.InvList[i]; - bool isHellfire = netSync ? ((item.dwBuff & CF_HELLFIRE) != 0) : gbIsHellfire; + bool isHellfire = gbIsHellfire; PackItem(pPack->InvList[i], item, isHellfire); } @@ -130,7 +130,7 @@ void PackPlayer(PlayerPack *pPack, const Player &player, bool manashield, bool n for (int i = 0; i < MaxBeltItems; i++) { const Item &item = player.SpdList[i]; - bool isHellfire = netSync ? ((item.dwBuff & CF_HELLFIRE) != 0) : gbIsHellfire; + bool isHellfire = gbIsHellfire; PackItem(pPack->SpdList[i], item, isHellfire); } @@ -139,11 +139,53 @@ void PackPlayer(PlayerPack *pPack, const Player &player, bool manashield, bool n pPack->pDamAcFlags = SDL_SwapLE32(static_cast(player.pDamAcFlags)); pPack->pDiabloKillLevel = SDL_SwapLE32(player.pDiabloKillLevel); pPack->bIsHellfire = gbIsHellfire ? 1 : 0; + pPack->pManaShield = 0; +} + +void PackNetPlayer(PlayerNetPack &packed, const Player &player) +{ + packed.plrlevel = player.plrlevel; + packed.px = player.position.tile.x; + packed.py = player.position.tile.y; + strcpy(packed.pName, player._pName); + packed.pClass = static_cast(player._pClass); + packed.pBaseStr = player._pBaseStr; + packed.pBaseMag = player._pBaseMag; + packed.pBaseDex = player._pBaseDex; + packed.pBaseVit = player._pBaseVit; + packed.pLevel = player._pLevel; + packed.pStatPts = player._pStatPts; + packed.pExperience = SDL_SwapLE32(player._pExperience); + packed.pGold = SDL_SwapLE32(player._pGold); + packed.pHPBase = SDL_SwapLE32(player._pHPBase); + packed.pMaxHPBase = SDL_SwapLE32(player._pMaxHPBase); + packed.pManaBase = SDL_SwapLE32(player._pManaBase); + packed.pMaxManaBase = SDL_SwapLE32(player._pMaxManaBase); + packed.pMemSpells = SDL_SwapLE64(player._pMemSpells); + + for (int i = 0; i < MAX_SPELLS; i++) + packed.pSplLvl[i] = player._pSplLvl[i]; + + for (int i = 0; i < NUM_INVLOC; i++) + PrepareItemForNetwork(player.InvBody[i], packed.InvBody[i]); + + packed._pNumInv = player._pNumInv; + for (int i = 0; i < packed._pNumInv; i++) + PrepareItemForNetwork(player.InvList[i], packed.InvList[i]); - if (!gbIsMultiplayer || manashield) - pPack->pManaShield = SDL_SwapLE32(player.pManaShield); - else - pPack->pManaShield = 0; + for (int i = 0; i < InventoryGridCells; i++) + packed.InvGrid[i] = player.InvGrid[i]; + + for (int i = 0; i < MaxBeltItems; i++) + PrepareItemForNetwork(player.SpdList[i], packed.SpdList[i]); + + packed.wReflections = SDL_SwapLE16(player.wReflections); + packed.pDifficulty = player.pDifficulty; + packed.pDamAcFlags = player.pDamAcFlags; + packed.pDiabloKillLevel = player.pDiabloKillLevel; + packed.pManaShield = player.pManaShield; + packed.friendlyMode = player.friendlyMode ? 1 : 0; + packed.isOnSetLevel = player.plrIsOnSetLevel; } void UnPackItem(const ItemPack &packedItem, const Player &player, Item &item, bool isHellfire) @@ -207,38 +249,21 @@ void UnPackItem(const ItemPack &packedItem, const Player &player, Item &item, bo } } -bool UnPackPlayer(const PlayerPack *pPack, Player &player, bool netSync) +void UnPackPlayer(const PlayerPack *pPack, Player &player) { Point position { pPack->px, pPack->py }; - if (!InDungeonBounds(position)) { - return false; - } - - uint8_t dungeonLevel = pPack->plrlevel; - if (dungeonLevel >= NUMLEVELS) { - return false; - } - - if (pPack->pClass >= enum_size::value) { - return false; - } - auto heroClass = static_cast(pPack->pClass); - - if (pPack->pLevel > MaxCharacterLevel || pPack->pLevel < 1) { - return false; - } - uint32_t difficulty = SDL_SwapLE32(pPack->pDifficulty); - if (difficulty > DIFF_LAST) { - return false; - } - - player._pLevel = pPack->pLevel; + player = {}; + player._pLevel = clamp(pPack->pLevel, 1, MaxCharacterLevel); + player._pMaxHPBase = SDL_SwapLE32(pPack->pMaxHPBase); + player._pHPBase = SDL_SwapLE32(pPack->pHPBase); + player._pMaxHP = player._pMaxHPBase; + player._pHitPoints = player._pHPBase; player.position.tile = position; player.position.future = position; - player.setLevel(dungeonLevel); + player.setLevel(pPack->plrlevel); - player._pClass = heroClass; + player._pClass = static_cast(clamp(pPack->pClass, 0, enum_size::value - 1)); ClrPlrPath(player); player.destAction = ACTION_NONE; @@ -259,12 +284,9 @@ bool UnPackPlayer(const PlayerPack *pPack, Player &player, bool netSync) player._pStatPts = pPack->pStatPts; player._pExperience = SDL_SwapLE32(pPack->pExperience); player._pGold = SDL_SwapLE32(pPack->pGold); - player._pMaxHPBase = SDL_SwapLE32(pPack->pMaxHPBase); - player._pHPBase = SDL_SwapLE32(pPack->pHPBase); player._pBaseToBlk = PlayersData[static_cast(player._pClass)].blockBonus; - if (!netSync) - if ((int)(player._pHPBase & 0xFFFFFFC0) < 64) - player._pHPBase = 64; + if ((int)(player._pHPBase & 0xFFFFFFC0) < 64) + player._pHPBase = 64; player._pMaxManaBase = SDL_SwapLE32(pPack->pMaxManaBase); player._pManaBase = SDL_SwapLE32(pPack->pManaBase); @@ -275,41 +297,120 @@ bool UnPackPlayer(const PlayerPack *pPack, Player &player, bool netSync) for (int i = 37; i < 47; i++) player._pSplLvl[i] = pPack->pSplLvl2[i - 37]; - for (int i = 0; i < NUM_INVLOC; i++) { - auto packedItem = pPack->InvBody[i]; - bool isHellfire = netSync ? ((packedItem.dwBuff & CF_HELLFIRE) != 0) : (pPack->bIsHellfire != 0); - UnPackItem(packedItem, player, player.InvBody[i], isHellfire); - } + bool isHellfire = pPack->bIsHellfire != 0; + + for (int i = 0; i < NUM_INVLOC; i++) + UnPackItem(pPack->InvBody[i], player, player.InvBody[i], isHellfire); player._pNumInv = pPack->_pNumInv; - for (int i = 0; i < player._pNumInv; i++) { - auto packedItem = pPack->InvList[i]; - bool isHellfire = netSync ? ((packedItem.dwBuff & CF_HELLFIRE) != 0) : (pPack->bIsHellfire != 0); - UnPackItem(packedItem, player, player.InvList[i], isHellfire); - } + for (int i = 0; i < player._pNumInv; i++) + UnPackItem(pPack->InvList[i], player, player.InvList[i], isHellfire); for (int i = 0; i < InventoryGridCells; i++) player.InvGrid[i] = pPack->InvGrid[i]; VerifyGoldSeeds(player); - 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, player.SpdList[i], isHellfire); - } + for (int i = 0; i < MaxBeltItems; i++) + UnPackItem(pPack->SpdList[i], player, player.SpdList[i], isHellfire); CalcPlrInv(player, false); player.wReflections = SDL_SwapLE16(pPack->wReflections); + player.pDiabloKillLevel = SDL_SwapLE32(pPack->pDiabloKillLevel); + player.pBattleNet = pPack->pBattleNet != 0; + player.pManaShield = false; + uint32_t difficulty = SDL_SwapLE32(pPack->pDifficulty); + player.pDifficulty = static_cast<_difficulty>(clamp(difficulty, 0, DIFF_LAST)); + player.pDamAcFlags = static_cast(SDL_SwapLE32(static_cast(pPack->pDamAcFlags))); +} + +bool UnPackNetPlayer(const PlayerNetPack &packed, Player &player) +{ + Point position { packed.px, packed.py }; + if (!InDungeonBounds(position)) { + return false; + } + + uint8_t dungeonLevel = packed.plrlevel; + if (dungeonLevel >= NUMLEVELS) { + return false; + } + + if (packed.pClass >= enum_size::value) { + return false; + } + + if (packed.pLevel > MaxCharacterLevel || packed.pLevel < 1) { + return false; + } + uint8_t difficulty = packed.pDifficulty; + if (difficulty > DIFF_LAST) { + return false; + } + + player._pLevel = packed.pLevel; + + player.position.tile = position; + player.position.future = position; + player.setLevel(dungeonLevel); + + player._pClass = static_cast(packed.pClass); + + ClrPlrPath(player); + player.destAction = ACTION_NONE; + + strcpy(player._pName, packed.pName); + + InitPlayer(player, true); + + player._pBaseStr = packed.pBaseStr; + player._pStrength = packed.pBaseStr; + player._pBaseMag = packed.pBaseMag; + player._pMagic = packed.pBaseMag; + player._pBaseDex = packed.pBaseDex; + player._pDexterity = packed.pBaseDex; + player._pBaseVit = packed.pBaseVit; + player._pVitality = packed.pBaseVit; + + player._pStatPts = packed.pStatPts; + player._pExperience = SDL_SwapLE32(packed.pExperience); + player._pGold = SDL_SwapLE32(packed.pGold); + player._pMaxHPBase = SDL_SwapLE32(packed.pMaxHPBase); + player._pHPBase = SDL_SwapLE32(packed.pHPBase); + player._pBaseToBlk = PlayersData[static_cast(player._pClass)].blockBonus; + + player._pMaxManaBase = SDL_SwapLE32(packed.pMaxManaBase); + player._pManaBase = SDL_SwapLE32(packed.pManaBase); + player._pMemSpells = SDL_SwapLE64(packed.pMemSpells); + + for (int i = 0; i < MAX_SPELLS; i++) + player._pSplLvl[i] = packed.pSplLvl[i]; + + for (int i = 0; i < NUM_INVLOC; i++) + RecreateItem(player, packed.InvBody[i], player.InvBody[i]); + + player._pNumInv = packed._pNumInv; + for (int i = 0; i < player._pNumInv; i++) + RecreateItem(player, packed.InvList[i], player.InvList[i]); + + for (int i = 0; i < InventoryGridCells; i++) + player.InvGrid[i] = packed.InvGrid[i]; + + for (int i = 0; i < MaxBeltItems; i++) + RecreateItem(player, packed.SpdList[i], player.SpdList[i]); + + CalcPlrInv(player, false); + player.wReflections = SDL_SwapLE16(packed.wReflections); player.pTownWarps = 0; player.pDungMsgs = 0; player.pDungMsgs2 = 0; player.pLvlLoad = 0; - player.pDiabloKillLevel = SDL_SwapLE32(pPack->pDiabloKillLevel); - player.pBattleNet = pPack->pBattleNet != 0; - player.pManaShield = pPack->pManaShield != 0; + player.pDiabloKillLevel = packed.pDiabloKillLevel; + player.pManaShield = packed.pManaShield != 0; player.pDifficulty = static_cast<_difficulty>(difficulty); - player.pDamAcFlags = static_cast(SDL_SwapLE32(static_cast(pPack->pDamAcFlags))); + player.pDamAcFlags = packed.pDamAcFlags; + player.friendlyMode = packed.friendlyMode != 0; + player.plrIsOnSetLevel = packed.isOnSetLevel != 0; return true; } diff --git a/Source/pack.h b/Source/pack.h index d515a0d16..6c43254fd 100644 --- a/Source/pack.h +++ b/Source/pack.h @@ -9,6 +9,7 @@ #include "inv.h" #include "items.h" +#include "msg.h" #include "player.h" namespace devilution { @@ -24,7 +25,7 @@ struct ItemPack { uint8_t bCh; uint8_t bMCh; uint16_t wValue; - int32_t dwBuff; + uint32_t dwBuff; }; struct PlayerPack { @@ -67,24 +68,56 @@ struct PlayerPack { uint8_t pDungMsgs2; /** The format the charater is in, 0: Diablo, 1: Hellfire */ int8_t bIsHellfire; - int8_t bReserved; // For future use + uint8_t reserved; // For future use uint16_t wReflections; - int16_t wReserved2; // For future use + uint8_t reserved2[2]; // For future use uint8_t pSplLvl2[10]; // Hellfire spells int16_t wReserved8; // For future use uint32_t pDiabloKillLevel; uint32_t pDifficulty; - uint32_t pDamAcFlags; // `ItemSpecialEffectHf` is 1 byte but this is 4 bytes. - /**@brief Only used in multiplayer sync (SendPlayerInfo/recv_plrinfo). Never used in save games (single- or multiplayer). */ + uint32_t pDamAcFlags; // `ItemSpecialEffectHf` is 1 byte but this is 4 bytes. + uint8_t reserved3[20]; // For future use +}; + +struct PlayerNetPack { + uint8_t plrlevel; + uint8_t px; + uint8_t py; + char pName[PlayerNameLength]; + uint8_t pClass; + uint8_t pBaseStr; + uint8_t pBaseMag; + uint8_t pBaseDex; + uint8_t pBaseVit; + int8_t pLevel; + uint8_t pStatPts; + uint32_t pExperience; + int32_t pGold; + int32_t pHPBase; + int32_t pMaxHPBase; + int32_t pManaBase; + int32_t pMaxManaBase; + uint8_t pSplLvl[MAX_SPELLS]; + uint64_t pMemSpells; + TItem InvBody[NUM_INVLOC]; + TItem InvList[InventoryGridCells]; + int8_t InvGrid[InventoryGridCells]; + uint8_t _pNumInv; + TItem SpdList[MaxBeltItems]; + uint8_t pManaShield; + uint16_t wReflections; + uint8_t pDiabloKillLevel; + uint8_t pDifficulty; + ItemSpecialEffectHf pDamAcFlags; uint8_t friendlyMode; - /**@brief Only used in multiplayer sync (SendPlayerInfo/recv_plrinfo). Never used in save games (single- or multiplayer). */ uint8_t isOnSetLevel; - uint8_t dwReserved[18]; // For future use }; #pragma pack(pop) -void PackPlayer(PlayerPack *pPack, const Player &player, bool manashield, bool netSync); -bool UnPackPlayer(const PlayerPack *pPack, Player &player, bool netSync); +void PackPlayer(PlayerPack *pPack, const Player &player); +void UnPackPlayer(const PlayerPack *pPack, Player &player); +void PackNetPlayer(PlayerNetPack &packed, const Player &player); +bool UnPackNetPlayer(const PlayerNetPack &packed, Player &player); /** * @brief Save the attributes needed to recreate this item into an ItemPack struct diff --git a/Source/pfile.cpp b/Source/pfile.cpp index afe4909f6..0d8692467 100644 --- a/Source/pfile.cpp +++ b/Source/pfile.cpp @@ -482,7 +482,7 @@ void pfile_write_hero(SaveWriter &saveWriter, bool writeGameData) PlayerPack pkplr; Player &myPlayer = *MyPlayer; - PackPlayer(&pkplr, myPlayer, !gbIsMultiplayer, false); + PackPlayer(&pkplr, myPlayer); EncodeHero(saveWriter, &pkplr); if (!gbVanilla) { SaveHotkeys(saveWriter, myPlayer); @@ -643,16 +643,13 @@ bool pfile_ui_set_hero_infos(bool (*uiAddHeroInfo)(_uiheroinfo *)) Player &player = Players[0]; - player = {}; + UnPackPlayer(&pkplr, player); + LoadHeroItems(player); + RemoveEmptyInventory(player); + CalcPlrInv(player, false); - if (UnPackPlayer(&pkplr, player, false)) { - LoadHeroItems(player); - RemoveEmptyInventory(player); - CalcPlrInv(player, false); - - Game2UiPlayer(player, &uihero, hasSaveGame); - uiAddHeroInfo(&uihero); - } + Game2UiPlayer(player, &uihero, hasSaveGame); + uiAddHeroInfo(&uihero); } } } @@ -696,7 +693,7 @@ bool pfile_ui_save_create(_uiheroinfo *heroinfo) Player &player = Players[0]; CreatePlayer(player, heroinfo->heroclass); CopyUtf8(player._pName, heroinfo->name, PlayerNameLength); - PackPlayer(&pkplr, player, true, false); + PackPlayer(&pkplr, player); EncodeHero(saveWriter, &pkplr); Game2UiPlayer(player, heroinfo, false); if (!gbVanilla) { @@ -719,8 +716,6 @@ bool pfile_delete_save(_uiheroinfo *heroInfo) void pfile_read_player_from_save(uint32_t saveNum, Player &player) { - player = {}; - PlayerPack pkplr; { std::optional archive = OpenSaveArchive(saveNum); @@ -734,10 +729,7 @@ void pfile_read_player_from_save(uint32_t saveNum, Player &player) pkplr.bIsHellfire = gbIsHellfireSaveGame ? 1 : 0; } - if (!UnPackPlayer(&pkplr, player, false)) { - return; - } - + UnPackPlayer(&pkplr, player); LoadHeroItems(player); RemoveEmptyInventory(player); CalcPlrInv(player, false); diff --git a/test/writehero_test.cpp b/test/writehero_test.cpp index bf45b267c..927984bc1 100644 --- a/test/writehero_test.cpp +++ b/test/writehero_test.cpp @@ -53,8 +53,6 @@ void SwapLE(PlayerPack &player) SwapLE(item); } player.wReflections = SDL_SwapLE16(player.wReflections); - player.wReserved2 = SDL_SwapLE16(player.wReserved2); - player.wReserved8 = SDL_SwapLE16(player.wReserved8); player.pDiabloKillLevel = SDL_SwapLE32(player.pDiabloKillLevel); player.pDifficulty = SDL_SwapLE32(player.pDifficulty); player.pDamAcFlags = SDL_SwapLE32(player.pDamAcFlags); @@ -377,15 +375,13 @@ TEST(Writehero, pfile_write_hero) Players.resize(1); MyPlayerId = 0; MyPlayer = &Players[MyPlayerId]; - *MyPlayer = {}; _uiheroinfo info {}; - strcpy(info.name, "TestPlayer"); info.heroclass = HeroClass::Rogue; pfile_ui_save_create(&info); PlayerPack pks; PackPlayerTest(&pks); - UnPackPlayer(&pks, *MyPlayer, true); + UnPackPlayer(&pks, *MyPlayer); AssertPlayer(Players[0]); pfile_write_hero();