Browse Source

Sort inventory (#7040)

pull/7042/head
Eric Robinson 2 years ago committed by GitHub
parent
commit
0d68aed1f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 17
      Source/diablo.cpp
  2. 66
      Source/inv.cpp
  3. 5
      Source/inv.h

17
Source/diablo.cpp

@ -42,6 +42,7 @@
#include "help.h"
#include "hwcursor.hpp"
#include "init.h"
#include "inv.h"
#include "levels/drlg_l1.h"
#include "levels/drlg_l2.h"
#include "levels/drlg_l3.h"
@ -1954,6 +1955,14 @@ void InitKeymapActions()
[] {
ToggleChatLog();
});
sgOptions.Keymapper.AddAction(
"SortInv",
N_("Sort Inventory"),
N_("Sorts the inventory."),
'R',
[] {
ReorganizeInventory(*MyPlayer);
});
#ifdef _DEBUG
sgOptions.Keymapper.AddAction(
"OpenConsole",
@ -2423,6 +2432,14 @@ void InitPadmapActions()
},
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
"SortInv",
N_("Sort Inventory"),
N_("Sorts the inventory."),
ControllerButton_NONE,
[] {
ReorganizeInventory(*MyPlayer);
});
sgOptions.Padmapper.AddAction(
"ChatLog",
N_("Chat Log"),

66
Source/inv.cpp

@ -1362,6 +1362,72 @@ bool AutoPlaceItemInInventory(Player &player, const Item &item, bool persistItem
app_fatal(StrCat("Unknown item size: ", itemSize.width, "x", itemSize.height));
}
std::vector<int> SortItemsBySize(Player &player)
{
std::vector<std::pair<Size, int>> itemSizes; // Pair of item size and its index in InvList
itemSizes.reserve(player._pNumInv); // Reserves space for the number of items in the player's inventory
for (int i = 0; i < player._pNumInv; i++) {
Size size = GetInventorySize(player.InvList[i]);
itemSizes.emplace_back(size, i);
}
// Sort items by height first, then by width
std::sort(itemSizes.begin(), itemSizes.end(), [](const auto &a, const auto &b) {
if (a.first.height == b.first.height) return a.first.width > b.first.width;
return a.first.height > b.first.height;
});
// Extract sorted indices
std::vector<int> sortedIndices;
sortedIndices.reserve(itemSizes.size()); // Pre-allocate the necessary capacity
for (const auto &itemSize : itemSizes) {
sortedIndices.push_back(itemSize.second);
}
return sortedIndices;
}
void ReorganizeInventory(Player &player)
{
// Sort items by size
std::vector<int> sortedIndices = SortItemsBySize(player);
// Temporary storage for items and a copy of InvGrid
std::vector<Item> tempStorage(player._pNumInv);
std::array<int8_t, 40> originalInvGrid; // Declare an array for InvGrid copy
std::copy(std::begin(player.InvGrid), std::end(player.InvGrid), std::begin(originalInvGrid)); // Copy InvGrid to originalInvGrid
// Move items to temporary storage and clear inventory slots
for (int i = 0; i < player._pNumInv; ++i) {
tempStorage[i] = player.InvList[i];
player.InvList[i] = {};
}
player._pNumInv = 0; // Reset inventory count
std::fill(std::begin(player.InvGrid), std::end(player.InvGrid), 0); // Clear InvGrid
// Attempt to place items back, now from the temp storage
bool reorganizationFailed = false;
for (int index : sortedIndices) {
Item &item = tempStorage[index];
if (!AutoPlaceItemInInventory(player, item, true, false)) {
reorganizationFailed = true;
break;
}
}
// If reorganization failed, restore items and InvGrid from tempStorage and originalInvGrid
if (reorganizationFailed) {
for (Item &item : tempStorage) {
if (!item.isEmpty()) {
player.InvList[player._pNumInv++] = item;
}
}
std::copy(std::begin(originalInvGrid), std::end(originalInvGrid), std::begin(player.InvGrid)); // Restore InvGrid
}
}
int RoomForGold()
{
int amount = 0;

5
Source/inv.h

@ -165,6 +165,11 @@ bool AutoPlaceItemInInventory(Player &player, const Item &item, bool persistItem
*/
bool AutoPlaceItemInBelt(Player &player, const Item &item, bool persistItem = false, bool sendNetworkMessage = false);
/**
* @brief Sort player inventory.
*/
void ReorganizeInventory(Player &player);
/**
* @brief Calculate the maximum aditional gold that may fit in the user's inventory
*/

Loading…
Cancel
Save