craft.lua 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. -- internationalization boilerplate
  2. local MP = minetest.get_modpath(minetest.get_current_modname())
  3. local S, NS = dofile(MP.."/intllib.lua")
  4. -- A convenienence function that attempts to do a generic crafting operation.
  5. -- "request_stack" is an item stack that it is assumed the player has removed from a set of possible outputs, it is assumed that the contents of request_stack will be added to the destination inventory as a result of an existing inventory transfer and it will be deducted from the craft result.
  6. -- source_inv, source_listname are where the raw materials will be taken from
  7. -- destination_inv, destination_listname are where the crafting outputs will be placed.
  8. -- player_or_pos is either a player object or a pos table. This is used for logging purposes and as a place to put output in the event that destination_inv can't hold it all.
  9. simplecrafting_lib.craft_stack = function(crafting_type, request_stack, source_inv, source_listname, destination_inv, destination_listname, player_or_pos)
  10. local player
  11. local pos
  12. if type(player_or_pos) == "userdata" then
  13. player = player_or_pos
  14. elseif type(player_or_pos) == "table" then
  15. pos = player_or_pos
  16. end
  17. local craft_result = simplecrafting_lib.get_crafting_result(crafting_type, source_inv:get_list(source_listname), request_stack)
  18. if craft_result then
  19. if simplecrafting_lib.remove_items(source_inv, source_listname, craft_result.input) then
  20. -- We've successfully paid for this craft's output.
  21. -- log it
  22. if player then
  23. minetest.log("action", player:get_player_name() .. " crafts " .. craft_result.output:to_string())
  24. elseif pos then
  25. minetest.log("action", craft_result.output:to_string() .. " was crafted at " .. minetest.pos_to_string(pos))
  26. else
  27. minetest.log("action", craft_result.output:to_string() .. "was crafted somewhere by someone.")
  28. end
  29. local total_output = simplecrafting_lib.count_list_add(
  30. -- subtract the amount of output that the player's getting anyway (due to having taken it from the inventory of outputs)
  31. {[craft_result.output:get_name()]=craft_result.output:get_count() - request_stack:get_count()},
  32. craft_result.returns)
  33. -- stuff the output in the target inventory, or the player's inventory if it doesn't fit, finally dropping anything that doesn't fit at the player's location
  34. local leftover = simplecrafting_lib.add_items(destination_inv, destination_listname, total_output)
  35. simplecrafting_lib.execute_post_craft(crafting_type, craft_result, request_stack, source_inv, source_listname, destination_inv, destination_listname)
  36. if player then
  37. leftover = simplecrafting_lib.add_items(player:get_inventory(), "main", leftover)
  38. simplecrafting_lib.drop_items(player:getpos(), leftover)
  39. elseif pos then
  40. simplecrafting_lib.drop_items(pos, leftover)
  41. else
  42. local still_has_leftovers = false
  43. for item, count in pairs(leftover) do
  44. still_has_leftovers = true
  45. break
  46. end
  47. if still_has_leftovers then
  48. minetest.log("error", "After crafting " .. craft_result.output:to_string() ..
  49. " some output items could not be placed into an inventory or dropped in world, and were lost.")
  50. end
  51. end
  52. return true
  53. end
  54. end
  55. return false
  56. end