Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 27 additions & 16 deletions Source/inv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
#include <SDL3/SDL_keyboard.h>
#include <SDL3/SDL_rect.h>
#else
#include <SDL.h>

Check warning on line 16 in Source/inv.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/inv.cpp:16:1 [misc-include-cleaner]

included header SDL.h is not used directly
#endif

#include <fmt/format.h>

Check warning on line 19 in Source/inv.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/inv.cpp:19:1 [misc-include-cleaner]

included header format.h is not used directly

#include "DiabloUI/ui_flags.hpp"
#include "controls/control_mode.hpp"
Expand All @@ -29,26 +29,26 @@
#include "engine/render/clx_render.hpp"
#include "engine/render/text_render.hpp"
#include "engine/size.hpp"
#include "hwcursor.hpp"

Check warning on line 32 in Source/inv.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/inv.cpp:32:1 [misc-include-cleaner]

included header hwcursor.hpp is not used directly
#include "inv_iterators.hpp"

Check warning on line 33 in Source/inv.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/inv.cpp:33:1 [misc-include-cleaner]

included header inv_iterators.hpp is not used directly
#include "levels/tile_properties.hpp"
#include "levels/town.h"
#include "minitext.h"
#include "options.h"
#include "panels/ui_panels.hpp"
#include "player.h"
#include "plrmsg.h"

Check warning on line 40 in Source/inv.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/inv.cpp:40:1 [misc-include-cleaner]

included header plrmsg.h is not used directly
#include "qol/stash.h"
#include "stores.h"
#include "towners.h"
#include "utils/display.h"

Check warning on line 44 in Source/inv.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/inv.cpp:44:1 [misc-include-cleaner]

included header towners.h is not used directly
#include "utils/format_int.hpp"
#include "utils/is_of.hpp"
#include "utils/language.h"
#include "utils/sdl_geometry.h"
#include "utils/str_cat.hpp"
#include "utils/utf8.hpp"

Check warning on line 51 in Source/inv.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/inv.cpp:51:1 [misc-include-cleaner]

included header utf8.hpp is not used directly
namespace devilution {

bool invflag;
Expand Down Expand Up @@ -76,7 +76,7 @@
* @endcode
*/
const Rectangle InvRect[] = {
// clang-format off

Check warning on line 79 in Source/inv.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/inv.cpp:79:7 [misc-include-cleaner]

no header providing "devilution::Rectangle" is directly included
//{ X, Y }, { W, H }
{ { 132, 2 }, { 58, 59 } }, // helmet
{ { 47, 177 }, { 28, 29 } }, // left ring
Expand Down Expand Up @@ -152,10 +152,10 @@
const int pitch = 10;
for (int y = 0; y < itemSize.height; y++) {
const int rowGridIndex = invGridIndex + pitch * y;
for (int x = 0; x < itemSize.width; x++) {

Check warning on line 155 in Source/inv.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/inv.cpp:155:43 [readability-math-missing-parentheses]

'*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations
if (x == 0 && y == itemSize.height - 1)
player.InvGrid[rowGridIndex + x] = invListIndex;
else

Check warning on line 158 in Source/inv.cpp

View workflow job for this annotation

GitHub Actions / tidy-check

Source/inv.cpp:158:40 [bugprone-narrowing-conversions]

narrowing conversion from 'int' to signed type 'int8_t' (aka 'signed char') is implementation-defined
player.InvGrid[rowGridIndex + x] = -invListIndex; // use negative index to denote it's occupied but it's not the top-left cell.
}
}
Expand Down Expand Up @@ -1565,29 +1565,39 @@
CalcPlrInv(player, player._pmode != PM_DEATH);
}

void CheckInvSwap(Player &player, const Item &item, int invGridIndex)
bool CheckInvSwap(Player &player, const Item &item, int invGridIndex)
{
Size itemSize = GetInventorySize(item);

const int pitch = 10;
const int invListIndex = [&]() -> int {
for (int y = 0; y < itemSize.height; y++) {
const int rowGridIndex = invGridIndex + pitch * y;
for (int x = 0; x < itemSize.width; x++) {
const int gridIndex = rowGridIndex + x;
if (player.InvGrid[gridIndex] != 0)
return std::abs(player.InvGrid[gridIndex]);
if (invGridIndex + itemSize.width - 1 + pitch * (itemSize.height - 1) >= InventoryGridCells)
return false;

int invListIndex = 0;
for (int y = 0; y < itemSize.height; y++) {
int rowGridIndex = invGridIndex + pitch * y;
for (int x = 0; x < itemSize.width; x++) {
int gridIndex = rowGridIndex + x;
if (player.InvGrid[gridIndex] != 0) {
int existingItem = std::abs(player.InvGrid[gridIndex]);
if (!invListIndex) {
invListIndex = existingItem;
} else if (invListIndex != existingItem) {
// More than one item exists where we want to place the new item
return false;
}
}
}
player._pNumInv++;
return player._pNumInv;
}();
}

if (invListIndex < player._pNumInv) {
for (int8_t &itemIndex : player.InvGrid) {
if (itemIndex == invListIndex)
itemIndex = 0;
if (itemIndex == -invListIndex)
if (!invListIndex) {
// The inventory is empty where we want to place the new item. Allocate a new spot.
player._pNumInv++;
invListIndex = player._pNumInv;
} else {
// Remove the old location of the existing item
for (int8_t& itemIndex : player.InvGrid) {
if (std::abs(itemIndex) == invListIndex)
itemIndex = 0;
}
}
Expand All @@ -1605,6 +1615,7 @@
}

CalcPlrInv(player, true);
return true;
}

void CheckInvRemove(Player &player, int invGridIndex)
Expand Down
2 changes: 1 addition & 1 deletion Source/inv.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ int AddGoldToInventory(Player &player, int value);
bool GoldAutoPlace(Player &player, Item &goldStack);
void CheckInvSwap(Player &player, inv_body_loc bLoc);
void inv_update_rem_item(Player &player, inv_body_loc iv);
void CheckInvSwap(Player &player, const Item &item, int invGridIndex);
bool CheckInvSwap(Player &player, const Item &item, int invGridIndex);
void CheckInvRemove(Player &player, int invGridIndex);
void TransferItemToStash(Player &player, int location);
void CheckInvItem(bool isShiftHeld = false, bool isCtrlHeld = false);
Expand Down
5 changes: 4 additions & 1 deletion Source/msg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2172,7 +2172,10 @@ size_t OnChangeInventoryItems(const TCmdChItem &message, Player &player)
} else if (&player != MyPlayer && IsItemAvailable(static_cast<_item_indexes>(Swap16LE(message.def.wIndx)))) {
Item item {};
RecreateItem(player, message, item);
CheckInvSwap(player, item, message.bLoc);
if (!CheckInvSwap(player, item, message.bLoc)) {
// item is larger than 1x1, and it occupies invalid inventory slots
return sizeof(message);
}
}

return sizeof(message);
Expand Down
Loading