From 5fa0dfbc28506ea57a34ec62ddb46d61d582c3f4 Mon Sep 17 00:00:00 2001 From: ephphatha Date: Mon, 3 Jan 2022 13:15:18 +1100 Subject: [PATCH] Skip loading item locations from file It's safer and easier to rebuild this as we load each item. --- Source/loadsave.cpp | 53 +++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index 479e90fbf..61a71b93e 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -102,9 +102,9 @@ public: } template - constexpr void Skip() + constexpr void Skip(size_t count = 1) { - Skip(sizeof(T)); + Skip(sizeof(T) * count); } void Skip(size_t size) @@ -889,40 +889,29 @@ void LoadMatchingItems(LoadHelper &file, const int n, Item *pItem) /** * @brief Loads items on the current dungeon floor * @param file interface to the save file - * @return a map converting from item indexes as recorded in the save file to the appropriate Items array index, used by LoadDroppedItemLocations - * @see LoadDroppedItemLocations */ -std::unordered_map LoadDroppedItems(LoadHelper &file) +void LoadDroppedItems(LoadHelper &file) { - std::unordered_map itemIndexes = { { 0, 0 } }; - for (uint8_t i = 0; i < ActiveItemCount; i++) { - // Load the current item indexes to remap dItem values as needed. - itemIndexes[file.NextLE() + 1] = i + 1; // adding 1 as dItem values use 0 for no item, and index + 1 for the actual item ID - } - file.Skip(MAXITEMS * 2 - static_cast(ActiveItemCount)); // Skip loading the rest of ActiveItems and AvailableItems, the indices are initialised below based on the number of active items + // Skip loading ActiveItems and AvailableItems, the indices are initialised below based on the number of active items + file.Skip(MAXITEMS * 2); + + // Clear dItem so we can populate valid drop locations + memset(dItem, 0, sizeof(dItem)); for (uint8_t i = 0; i < MAXITEMS; i++) { - if (i < ActiveItemCount) + if (i < ActiveItemCount) { LoadItem(file, Items[i]); + const Item &item = Items[i]; + if (!item.isEmpty()) { + // Loaded a valid item, populate its location in the lookup table with the offset in the Items array + dItem[item.position.x][item.position.y] = static_cast(i + 1); + } + } + // Initialise ActiveItems to reflect the order the items were loaded from the file ActiveItems[i] = i; } - - return itemIndexes; -} - -/** - * @brief Helper to initialise dItem based on runtime item indexes - * @param file interface to the save file - * @param indexMap a map converting from save file item indexes to the appropriate Items array index - */ -void LoadDroppedItemLocations(LoadHelper &file, const std::unordered_map &indexMap) -{ - for (int j = 0; j < MAXDUNY; j++) { - for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert) - dItem[i][j] = indexMap.at(file.NextLE()); - } } void RemoveEmptyLevelItems() @@ -1862,7 +1851,7 @@ void LoadGame(bool firstflag) LoadLighting(&file, &VisionList[i]); } - auto itemIndexes = LoadDroppedItems(file); + LoadDroppedItems(file); for (bool &uniqueItemFlag : UniqueItemFlags) uniqueItemFlag = file.NextBool8(); @@ -1880,7 +1869,8 @@ void LoadGame(bool firstflag) dPlayer[i][j] = file.NextLE(); } - LoadDroppedItemLocations(file, itemIndexes); + // skip dItem indexes, this gets populated in LoadDroppedItems + file.Skip(MAXDUNX * MAXDUNY); if (leveltype != DTYPE_TOWN) { for (int j = 0; j < MAXDUNY; j++) { @@ -2230,14 +2220,15 @@ void LoadLevel() } } - auto itemIndexes = LoadDroppedItems(file); + LoadDroppedItems(file); for (int j = 0; j < MAXDUNY; j++) { for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert) dFlags[i][j] = static_cast(file.NextLE()) & DungeonFlag::LoadedFlags; } - LoadDroppedItemLocations(file, itemIndexes); + // skip dItem indexes, this gets populated in LoadDroppedItems + file.Skip(MAXDUNX * MAXDUNY); if (leveltype != DTYPE_TOWN) { for (int j = 0; j < MAXDUNY; j++) {