Fix metadata loss and. Improve placement for some corner cases.
This commit is contained in:
parent
b73bbd323e
commit
334f0a5065
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue