Browse Source

Skip loading item locations from file

It's safer and easier to rebuild this as we load each item.
pull/3895/head
ephphatha 4 years ago committed by Anders Jenbo
parent
commit
5fa0dfbc28
  1. 53
      Source/loadsave.cpp

53
Source/loadsave.cpp

@ -102,9 +102,9 @@ public:
} }
template <typename T> template <typename T>
constexpr void Skip() constexpr void Skip(size_t count = 1)
{ {
Skip(sizeof(T)); Skip(sizeof(T) * count);
} }
void Skip(size_t size) 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 * @brief Loads items on the current dungeon floor
* @param file interface to the save file * @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<uint8_t, uint8_t> LoadDroppedItems(LoadHelper &file) void LoadDroppedItems(LoadHelper &file)
{ {
std::unordered_map<uint8_t, uint8_t> itemIndexes = { { 0, 0 } }; // Skip loading ActiveItems and AvailableItems, the indices are initialised below based on the number of active items
for (uint8_t i = 0; i < ActiveItemCount; i++) { file.Skip<uint8_t>(MAXITEMS * 2);
// Load the current item indexes to remap dItem values as needed.
itemIndexes[file.NextLE<uint8_t>() + 1] = i + 1; // adding 1 as dItem values use 0 for no item, and index + 1 for the actual item ID // Clear dItem so we can populate valid drop locations
} memset(dItem, 0, sizeof(dItem));
file.Skip(MAXITEMS * 2 - static_cast<size_t>(ActiveItemCount)); // Skip loading the rest of ActiveItems and AvailableItems, the indices are initialised below based on the number of active items
for (uint8_t i = 0; i < MAXITEMS; i++) { for (uint8_t i = 0; i < MAXITEMS; i++) {
if (i < ActiveItemCount) if (i < ActiveItemCount) {
LoadItem(file, Items[i]); 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<int8_t>(i + 1);
}
}
// Initialise ActiveItems to reflect the order the items were loaded from the file // Initialise ActiveItems to reflect the order the items were loaded from the file
ActiveItems[i] = i; 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<uint8_t, uint8_t> &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<uint8_t>());
}
} }
void RemoveEmptyLevelItems() void RemoveEmptyLevelItems()
@ -1862,7 +1851,7 @@ void LoadGame(bool firstflag)
LoadLighting(&file, &VisionList[i]); LoadLighting(&file, &VisionList[i]);
} }
auto itemIndexes = LoadDroppedItems(file); LoadDroppedItems(file);
for (bool &uniqueItemFlag : UniqueItemFlags) for (bool &uniqueItemFlag : UniqueItemFlags)
uniqueItemFlag = file.NextBool8(); uniqueItemFlag = file.NextBool8();
@ -1880,7 +1869,8 @@ void LoadGame(bool firstflag)
dPlayer[i][j] = file.NextLE<int8_t>(); dPlayer[i][j] = file.NextLE<int8_t>();
} }
LoadDroppedItemLocations(file, itemIndexes); // skip dItem indexes, this gets populated in LoadDroppedItems
file.Skip<uint8_t>(MAXDUNX * MAXDUNY);
if (leveltype != DTYPE_TOWN) { if (leveltype != DTYPE_TOWN) {
for (int j = 0; j < MAXDUNY; j++) { 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 j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert) for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dFlags[i][j] = static_cast<DungeonFlag>(file.NextLE<uint8_t>()) & DungeonFlag::LoadedFlags; dFlags[i][j] = static_cast<DungeonFlag>(file.NextLE<uint8_t>()) & DungeonFlag::LoadedFlags;
} }
LoadDroppedItemLocations(file, itemIndexes); // skip dItem indexes, this gets populated in LoadDroppedItems
file.Skip<uint8_t>(MAXDUNX * MAXDUNY);
if (leveltype != DTYPE_TOWN) { if (leveltype != DTYPE_TOWN) {
for (int j = 0; j < MAXDUNY; j++) { for (int j = 0; j < MAXDUNY; j++) {

Loading…
Cancel
Save