From f7f978665841beeb6cda0cd8bd560ef307ad7ad8 Mon Sep 17 00:00:00 2001 From: Robin Date: Tue, 24 Aug 2021 13:08:24 +0200 Subject: [PATCH] items: add BUGFIX, reset item get records when resetting items (#2691) * items: add BUGFIX, reset item get records when resetting items The item get record array tracks items being recently looted in an effort to prevent the same item from being looted more than once. Prior to this commit, the item get record array (and corresponding item get record array length) variables were not cleared when creating a new game. Therefore, the item get record array of a previous game could remain in between games and prevent an item from being looted (if it was looted in a previous), even if it was never looted in the current game. In practice this almost never shows up, since each item get record is valid for a total of 6 seconds before being cleared. So, you would either have to save a game, quickly loot an item, when load the game and try to loot the same item before 6 seconds pass. OR, you could use the demo replay functionality to run test cases, and speed up execution to run e.g. 10'000'000 logic ticks per second. Both would exhibit the bug and prevent the item from being looted. This commit fixes such issues by explicitly clearing the item get record array and item get record array length variables whenever items are initialized. --- Source/items.cpp | 17 +++++++++++++++++ Source/items.h | 1 + 2 files changed, 18 insertions(+) diff --git a/Source/items.cpp b/Source/items.cpp index 649998c80..1627f8b74 100644 --- a/Source/items.cpp +++ b/Source/items.cpp @@ -127,8 +127,13 @@ enum class PlayerArmorGraphic : uint8_t { // clang-format on }; ItemStruct curruitem; + +/** Holds item get records, tracking items being recently looted. This is in an effort to prevent items being picked up more than once. */ ItemGetRecordStruct itemrecord[MAXITEMS]; + bool itemhold[3][3]; + +/** Specifies the number of active item get records. */ int gnNumGetRecords; int OilLevels[] = { 1, 10, 1, 10, 4, 1, 5, 17, 1, 10 }; @@ -2628,6 +2633,9 @@ void InitItems() } ShowUniqueItemInfoBox = false; + + // BUGFIX: item get records not reset when resetting items (fixed). + initItemGetRecords(); } void CalcPlrItemVals(int playerId, bool loadgfx) @@ -4964,4 +4972,13 @@ void ItemStruct::SetNewAnimation(bool showAnimation) } } +/** + * @brief Resets item get records. + */ +void initItemGetRecords() +{ + memset(itemrecord, 0, sizeof(itemrecord)); + gnNumGetRecords = 0; +} + } // namespace devilution diff --git a/Source/items.h b/Source/items.h index 03b1ce392..a29838e0e 100644 --- a/Source/items.h +++ b/Source/items.h @@ -466,6 +466,7 @@ void CreateMagicWeapon(Point position, int imisc, int icurs, bool sendmsg, bool bool GetItemRecord(int nSeed, uint16_t wCI, int nIndex); void SetItemRecord(int nSeed, uint16_t wCI, int nIndex); void PutItemRecord(int nSeed, uint16_t wCI, int nIndex); +void initItemGetRecords(); #ifdef _DEBUG std::string DebugSpawnItem(std::string itemName, bool unique);