inventory.lua 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. -- Returns nil if there's no leftovers
  2. -- Otherwise returns a countlist of leftovers
  3. local add_count_list = function(inv, listname, count_list)
  4. local leftover_list
  5. for item, count in pairs(count_list) do
  6. local stack_max = ItemStack(item):get_stack_max()
  7. while count > 0 do
  8. local to_add = math.min(count, stack_max)
  9. local leftover = inv:add_item(listname, ItemStack({name=item, count=to_add}))
  10. local leftover_count = leftover:get_count()
  11. if leftover_count > 0 then
  12. leftover_list = leftover_list or {}
  13. leftover_list[item] = (leftover_list[item] or 0) + leftover_count + count
  14. break
  15. end
  16. count = count - to_add
  17. end
  18. end
  19. return leftover_list
  20. end
  21. -- Attempts to add the items in count_list to the inventory.
  22. -- Returns a count list containing the items that couldn't be added.
  23. simplecrafting_lib.add_items = function(inv, listname, count_list)
  24. return add_count_list(inv, listname, count_list) or {}
  25. end
  26. -- Attempts to add the items in count_list to the inventory.
  27. -- If it succeeds, returns true.
  28. -- If it fails, the inventory is not modified and returns false.
  29. simplecrafting_lib.add_items_if_room = function(inv, listname, count_list)
  30. local old_list = inv:get_list(listname) -- record current inventory
  31. if not add_count_list(inv, listname, count_list) then
  32. inv:set_list(listname, old_list) -- reset inventory
  33. return false
  34. end
  35. return true
  36. end
  37. -- Returns true if there's room in the inventory for all of the items in the count list,
  38. -- false otherwise.
  39. --This should return true when there is space for more items, broken right now.
  40. simplecrafting_lib.room_for_items = function(inv, listname, count_list)
  41. local old_list = inv:get_list(listname) -- record current inventory
  42. local result = add_count_list(inv, listname, count_list)
  43. inv:set_list(listname, old_list) -- reset inventory
  44. return result ~= nil
  45. end
  46. -- removes the items in the count_list (formatted as per recipe standards)
  47. -- from the inventory. Returns true on success, false on failure. Does not
  48. -- affect the inventory on failure (removal is atomic)
  49. simplecrafting_lib.remove_items = function(inv, listname, count_list)
  50. local old_list = inv:get_list(listname) -- record current inventory
  51. for item, count in pairs(count_list) do
  52. while count > 0 do
  53. -- We need to do this loop because we may be wanting to remove more items than
  54. -- a single stack of that item can hold.
  55. -- https://github.com/minetest/minetest/issues/8883
  56. local stack_to_remove = ItemStack({name=item, count=count})
  57. stack_to_remove:set_count(math.min(count, stack_to_remove:get_stack_max()))
  58. local removed = inv:remove_item(listname, stack_to_remove)
  59. if removed:is_empty() then
  60. -- ran out of things to take. Reset the inventory and return false
  61. inv:set_list(listname, old_list)
  62. return false
  63. end
  64. count = count - removed:get_count()
  65. end
  66. end
  67. return true
  68. end
  69. -- Drops the contents of a count_list at the given location in the world
  70. simplecrafting_lib.drop_items = function(pos, count_list)
  71. for item, count in pairs(count_list) do
  72. local stack_max = ItemStack(item):get_stack_max()
  73. while count > 0 do
  74. local to_add = math.min(count, stack_max)
  75. minetest.add_item(pos, ItemStack({name=item, count=to_add}))
  76. count = count - to_add
  77. end
  78. end
  79. end