Fix metadata loss and. Improve placement for some corner cases.

This commit is contained in:
Andrey Kozlovskiy 2019-10-19 13:51:05 +03:00
parent b73bbd323e
commit 334f0a5065
1 changed files with 31 additions and 25 deletions

View File

@ -317,6 +317,8 @@ can be one of the source lists.
If destination list position is already occupied with some other item
then function tries to move it to the source lists if possible.
Warning!!! Moving oversized stacks is undefined and can lead to item loss!
Arguments:
inv: minetest inventory reference
src_lists: names of source lists
@ -328,44 +330,48 @@ function unified_inventory.move_match(inv, src_lists, dst_list, match_table, amo
local moved_positions = {}
for item, pos_set in pairs(match_table) do
local stack_max = ItemStack(item):get_stack_max()
local needed = {}
local remained = {}
local stack = ItemStack(item)
local stack_max = stack:get_stack_max()
local bounded_amount = math.min(stack_max, amount)
local pos_count = 0;
for _ in pairs(pos_set) do
pos_count = pos_count + 1
end
local total = ItemStack{
name = item,
count = bounded_amount * pos_count
}
local removed = unified_inventory.remove_item(inv, src_lists, total)
local current = ItemStack(removed)
current:set_count(bounded_amount)
-- Pass 1: Remove stacks needed for craft
stack:set_count(bounded_amount)
for pos in pairs(pos_set) do
needed[pos] = unified_inventory.remove_item(inv, src_lists, stack)
end
-- Pass 2: Remove remainder to free up positions
stack:set_count(stack_max)
for pos in pairs(pos_set) do
remained[pos] = unified_inventory.remove_item(inv, src_lists, stack)
end
-- Pass 3: Move only needed stacks
for pos, current in pairs(needed) do
local occupied = inv:get_stack(dst_list, pos)
inv:set_stack(dst_list, pos, current)
repeat
if not occupied:is_empty() then
local leftover = unified_inventory.add_item(inv, src_lists, occupied)
if not occupied:is_empty() then
local leftover = unified_inventory.add_item(inv, src_lists, occupied)
if not leftover:is_empty() then
inv:set_stack(dst_list, pos, leftover)
break
end
if not leftover:is_empty() then
inv:set_stack(dst_list, pos, leftover)
unified_inventory.add_item(inv, src_lists, current)
end
removed:take_item(bounded_amount)
until true
end
moved_positions[pos] = true
end
unified_inventory.add_item(inv, src_lists, removed)
-- Pass 4: Re-add remainder stacks
for _, current in pairs(remained) do
unified_inventory.add_item(inv, src_lists, current)
end
end
unified_inventory.swap_items(inv, dst_list, src_lists, moved_positions)