Browse Source

Extract common logic for loading items from a save

This was duplicated for loading a save from the menu and transitioning to a new level
pull/3586/head
ephphatha 5 years ago committed by Anders Jenbo
parent
commit
71e39dda6f
  1. 6
      Source/items.cpp
  2. 67
      Source/loadsave.cpp

6
Source/items.cpp

@ -42,6 +42,12 @@ namespace devilution {
Item Items[MAXITEMS + 1];
int ActiveItems[MAXITEMS];
int ActiveItemCount;
/**
* @brief Contains indexes of empty spaces in Items.
*
* This array effectively duplicates ActiveItems due to differences in implementation to other fixed buffers.
* Eventually this can be removed and Items can be treated the same as how Missiles are tracked
*/
int AvailableItems[MAXITEMS];
bool ShowUniqueItemInfoBox;
CornerStoneStruct CornerStone;

67
Source/loadsave.cpp

@ -885,6 +885,46 @@ 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<uint8_t, uint8_t> LoadDroppedItems(LoadHelper &file)
{
std::unordered_map<uint8_t, uint8_t> 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<uint8_t>() + 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<size_t>(ActiveItemCount)); // Skip loading the rest of ActiveItems and AvailableItems, the indices are initialised below based on the number of active items
for (int i = 0; i < MAXITEMS; i++) {
if (i < ActiveItemCount)
LoadItem(file, Items[i]);
// Initialise the ActiveItems and AvailableItems arrays so the existing logic for dropping items can stay unchanged
ActiveItems[i] = i;
AvailableItems[i] = (i + ActiveItemCount) % MAXITEMS;
}
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()
{
for (int i = ActiveItemCount; i > 0; i--) {
@ -1788,12 +1828,8 @@ void LoadGame(bool firstflag)
LoadLighting(&file, &VisionList[i]);
}
for (int &itemId : ActiveItems)
itemId = file.NextLE<int8_t>();
for (int &itemId : AvailableItems)
itemId = file.NextLE<int8_t>();
for (int i = 0; i < ActiveItemCount; i++)
LoadItem(file, Items[ActiveItems[i]]);
auto itemIndexes = LoadDroppedItems(file);
for (bool &uniqueItemFlag : UniqueItemFlags)
uniqueItemFlag = file.NextBool8();
@ -1809,10 +1845,8 @@ void LoadGame(bool firstflag)
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dPlayer[i][j] = file.NextLE<int8_t>();
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dItem[i][j] = file.NextLE<int8_t>();
}
LoadDroppedItemLocations(file, itemIndexes);
if (leveltype != DTYPE_TOWN) {
for (int j = 0; j < MAXDUNY; j++) {
@ -2177,21 +2211,14 @@ void LoadLevel()
}
}
for (int &itemId : ActiveItems)
itemId = file.NextLE<int8_t>();
for (int &itemId : AvailableItems)
itemId = file.NextLE<int8_t>();
for (int i = 0; i < ActiveItemCount; i++)
LoadItem(file, Items[ActiveItems[i]]);
auto itemIndexes = 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<DungeonFlag>(file.NextLE<uint8_t>()) & DungeonFlag::LoadedFlags;
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
dItem[i][j] = file.NextLE<int8_t>();
}
LoadDroppedItemLocations(file, itemIndexes);
if (leveltype != DTYPE_TOWN) {
for (int j = 0; j < MAXDUNY; j++) {

Loading…
Cancel
Save