From c044a3c1cabda2f5f61fee9e746dba5caa427085 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sun, 28 Apr 2024 19:45:09 +0200 Subject: [PATCH] Client: fix unknown texture upon shift-move to full inventory list (#14586) Fixes a regression caused by 4245a760 'moveItemSomewhere' attempted to add a leftover stack to an empty stack, resulting in an empty name with non-0 ItemStack count. --- src/inventory.cpp | 5 +++-- src/unittest/test_moveaction.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/inventory.cpp b/src/inventory.cpp index 65bbe0390..3c132c718 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -758,8 +758,9 @@ void InventoryList::moveItemSomewhere(u32 i, InventoryList *dest, u32 count) if (!leftover.empty()) { // Add the remaining part back to the source item - ItemStack &source = getItem(i); - source.add(leftover.count); // do NOT use addItem to allow oversized stacks! + // do NOT use addItem to allow oversized stacks! + leftover.add(getItem(i).count); + changeItem(i, leftover); } } diff --git a/src/unittest/test_moveaction.cpp b/src/unittest/test_moveaction.cpp index 0720ba267..966cea8c7 100644 --- a/src/unittest/test_moveaction.cpp +++ b/src/unittest/test_moveaction.cpp @@ -34,6 +34,7 @@ public: void testMove(ServerActiveObject *obj, IGameDef *gamedef); void testMoveFillStack(ServerActiveObject *obj, IGameDef *gamedef); void testMoveSomewhere(ServerActiveObject *obj, IGameDef *gamedef); + void testMoveSomewherePartial(ServerActiveObject *obj, IGameDef *gamedef); void testMoveUnallowed(ServerActiveObject *obj, IGameDef *gamedef); void testMovePartial(ServerActiveObject *obj, IGameDef *gamedef); @@ -71,6 +72,7 @@ void TestMoveAction::runTests(IGameDef *gamedef) TEST(testMove, &obj, gamedef); TEST(testMoveFillStack, &obj, gamedef); TEST(testMoveSomewhere, &obj, gamedef); + TEST(testMoveSomewherePartial, &obj, gamedef); TEST(testMoveUnallowed, &obj, gamedef); TEST(testMovePartial, &obj, gamedef); @@ -143,9 +145,31 @@ void TestMoveAction::testMoveSomewhere(ServerActiveObject *obj, IGameDef *gamede UASSERT(inv.p2.getList("main")->getItem(0).getItemString() == "default:brick 10"); UASSERT(inv.p2.getList("main")->getItem(1).getItemString() == "default:stone 36"); + // Partially moved UASSERT(inv.p2.getList("main")->getItem(2).getItemString() == "default:stone 99"); } +void TestMoveAction::testMoveSomewherePartial(ServerActiveObject *obj, IGameDef *gamedef) +{ + // "Fail" because the destination list is full. + MockInventoryManager inv(gamedef); + + InventoryList *src = inv.p1.addList("main", 3); + src->addItem(0, parse_itemstack("default:brick 10")); + src->changeItem(1, parse_itemstack("default:stone 111")); // oversized + + InventoryList *dst = inv.p2.addList("main", 1); + dst->addItem(0, parse_itemstack("default:stone 98")); + + // No free slots to fit + apply_action("MoveSomewhere 10 player:p1 main 0 player:p2 main", &inv, obj, gamedef); + UASSERT(inv.p1.getList("main")->getItem(0).getItemString() == "default:brick 10"); + + // Only 1 item fits + apply_action("MoveSomewhere 111 player:p1 main 1 player:p2 main", &inv, obj, gamedef); + UASSERT(inv.p1.getList("main")->getItem(1).getItemString() == "default:stone 110"); +} + void TestMoveAction::testMoveUnallowed(ServerActiveObject *obj, IGameDef *gamedef) { MockInventoryManager inv(gamedef);