Browse Source

Extract common logic for saving items to a save file

This was duplicated for saving from the menu and transitioning to a new level
pull/3586/head
ephphatha 5 years ago committed by Anders Jenbo
parent
commit
84302c45f3
  1. 62
      Source/loadsave.cpp

62
Source/loadsave.cpp

@ -1503,6 +1503,41 @@ void SavePortal(SaveHelper *file, int i)
file->WriteLE<uint32_t>(pPortal->setlvl ? 1 : 0);
}
/**
* @brief Saves items on the current dungeon floor
* @param file interface to the save file
* @return a map converting from runtime item indexes to the relative position in the save file, used by SaveDroppedItemLocations
* @see SaveDroppedItemLocations
*/
std::unordered_map<uint8_t, uint8_t> SaveDroppedItems(SaveHelper &file)
{
// Vanilla Diablo/Hellfire initialise the ActiveItems and AvailableItems arrays based on saved data, so write valid values for compatibility
for (int i = 0; i < MAXITEMS; i++)
file.WriteLE<int8_t>(i); // Strictly speaking everything from ActiveItemCount onwards is unused but no harm writing non-zero values here.
for (int i = 0; i < MAXITEMS; i++)
file.WriteLE<int8_t>((i + ActiveItemCount) % MAXITEMS);
std::unordered_map<uint8_t, uint8_t> itemIndexes = { { 0, 0 } };
for (int i = 0; i < ActiveItemCount; i++) {
itemIndexes[ActiveItems[i] + 1] = i + 1;
SaveItem(file, Items[ActiveItems[i]]);
}
return itemIndexes;
}
/**
* @brief Saves the position of dropped items (in dItem)
* @param file interface to the save file
* @param indexMap a map converting from runtime item indexes to the relative position in the save file
*/
void SaveDroppedItemLocations(SaveHelper &file, const std::unordered_map<uint8_t, uint8_t> &itemIndexes)
{
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
file.WriteLE<int8_t>(itemIndexes.at(dItem[i][j]));
}
}
const int DiabloItemSaveSize = 368;
const int HellfireItemSaveSize = 372;
@ -2016,12 +2051,8 @@ void SaveGameData()
SaveLighting(&file, &VisionList[i]);
}
for (int itemId : ActiveItems)
file.WriteLE<int8_t>(itemId);
for (int itemId : AvailableItems)
file.WriteLE<int8_t>(itemId);
for (int i = 0; i < ActiveItemCount; i++)
SaveItem(file, Items[ActiveItems[i]]);
auto itemIndexes = SaveDroppedItems(file);
for (bool uniqueItemFlag : UniqueItemFlags)
file.WriteLE<uint8_t>(uniqueItemFlag ? 1 : 0);
@ -2037,10 +2068,8 @@ void SaveGameData()
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
file.WriteLE<int8_t>(dPlayer[i][j]);
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
file.WriteLE<int8_t>(dItem[i][j]);
}
SaveDroppedItemLocations(file, itemIndexes);
if (leveltype != DTYPE_TOWN) {
for (int j = 0; j < MAXDUNY; j++) {
@ -2128,22 +2157,13 @@ void SaveLevel()
SaveObject(file, Objects[ActiveObjects[i]]);
}
for (int itemId : ActiveItems)
file.WriteLE<int8_t>(itemId);
for (int itemId : AvailableItems)
file.WriteLE<int8_t>(itemId);
for (int i = 0; i < ActiveItemCount; i++)
SaveItem(file, Items[ActiveItems[i]]);
auto itemIndexes = SaveDroppedItems(file);
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
file.WriteLE<uint8_t>(static_cast<uint8_t>(dFlags[i][j] & DungeonFlag::SavedFlags));
}
for (int j = 0; j < MAXDUNY; j++) {
for (int i = 0; i < MAXDUNX; i++) // NOLINT(modernize-loop-convert)
file.WriteLE<int8_t>(dItem[i][j]);
}
SaveDroppedItemLocations(file, itemIndexes);
if (leveltype != DTYPE_TOWN) {
for (int j = 0; j < MAXDUNY; j++) {

Loading…
Cancel
Save