diff options
author | Lars Müller <34514239+appgurueu@users.noreply.github.com> | 2021-02-21 20:02:23 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-21 20:02:23 +0100 |
commit | 051e4c2b00a30c496b5545a6f0b01c9a14e937a4 (patch) | |
tree | 760607f2f8033c1c066fa313a73555ee941b00ee /src | |
parent | c12e9cdcba6b4183de6df4fd05f61a06f804642c (diff) | |
download | minetest-051e4c2b00a30c496b5545a6f0b01c9a14e937a4.tar.gz minetest-051e4c2b00a30c496b5545a6f0b01c9a14e937a4.tar.bz2 minetest-051e4c2b00a30c496b5545a6f0b01c9a14e937a4.zip |
Fix wrong reported item counts for inventory actions using Shift-Move (#10930)
Diffstat (limited to 'src')
-rw-r--r-- | src/inventorymanager.cpp | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/src/inventorymanager.cpp b/src/inventorymanager.cpp index 635bd2e4b..554708e8e 100644 --- a/src/inventorymanager.cpp +++ b/src/inventorymanager.cpp @@ -301,6 +301,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame if (!list_to->getItem(dest_i).empty()) { to_i = dest_i; apply(mgr, player, gamedef); + assert(move_count <= count); count -= move_count; } } @@ -352,10 +353,12 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame bool allow_swap = !list_to->itemFits(to_i, src_item, &restitem) && restitem.count == src_item.count && !caused_by_move_somewhere; + move_count = src_item.count - restitem.count; // Shift-click: Cannot fill this stack, proceed with next slot - if (caused_by_move_somewhere && restitem.count == src_item.count) + if (caused_by_move_somewhere && move_count == 0) { return; + } if (allow_swap) { // Swap will affect the entire stack if it can performed. @@ -384,9 +387,16 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame src_can_take_count = dst_can_put_count = 0; } else { // Take from one inventory, put into another + int src_item_count = src_item.count; + if (caused_by_move_somewhere) + // When moving somewhere: temporarily use the actual movable stack + // size to ensure correct callback execution. + src_item.count = move_count; dst_can_put_count = allowPut(src_item, player); src_can_take_count = allowTake(src_item, player); - + if (caused_by_move_somewhere) + // Reset source item count + src_item.count = src_item_count; bool swap_expected = allow_swap; allow_swap = allow_swap && (src_can_take_count == -1 || src_can_take_count >= src_item.count) @@ -416,12 +426,17 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame count = src_can_take_count; if (dst_can_put_count != -1 && count > dst_can_put_count) count = dst_can_put_count; + /* Limit according to source item count */ if (count > list_from->getItem(from_i).count) count = list_from->getItem(from_i).count; /* If no items will be moved, don't go further */ if (count == 0) { + if (caused_by_move_somewhere) + // Set move count to zero, as no items have been moved + move_count = 0; + // Undo client prediction. See 'clientApply' if (from_inv.type == InventoryLocation::PLAYER) list_from->setModified(); @@ -438,6 +453,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame <<" list=\""<<to_list<<"\"" <<" i="<<to_i <<std::endl; + return; } @@ -455,6 +471,8 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame bool did_swap = false; move_count = list_from->moveItem(from_i, list_to, to_i, count, allow_swap, &did_swap); + if (caused_by_move_somewhere) + count = old_count; assert(allow_swap == did_swap); // If source is infinite, reset it's stack @@ -503,8 +521,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame << std::endl; // If we are inside the move somewhere loop, we don't need to report - // anything if nothing happened (perhaps we don't need to report - // anything for caused_by_move_somewhere == true, but this way its safer) + // anything if nothing happened if (caused_by_move_somewhere && move_count == 0) return; @@ -558,7 +575,15 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame } mgr->setInventoryModified(from_inv); } else { + int src_item_count = src_item.count; + if (caused_by_move_somewhere) + // When moving somewhere: temporarily use the actual movable stack + // size to ensure correct callback execution. + src_item.count = move_count; onPutAndOnTake(src_item, player); + if (caused_by_move_somewhere) + // Reset source item count + src_item.count = src_item_count; if (did_swap) { // Item is now placed in source list src_item = list_from->getItem(from_i); |