init.lua 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. -- internationalization boilerplate
  2. local MP = minetest.get_modpath(minetest.get_current_modname())
  3. local S, NS = dofile(MP.."/intllib.lua")
  4. local crafting_bench = {}
  5. minetest.register_alias("castle:workbench", "crafting_bench:workbench")
  6. local usage_help = S("The inventory on the left is for raw materials, the inventory on the right holds finished products. The crafting grid in the center defines what recipe this workbench will make use of; place raw materials into it in the crafting pattern corresponding to what you want to build.")
  7. if minetest.get_modpath("hopper") and hopper ~= nil and hopper.add_container ~= nil then
  8. usage_help = usage_help .. "\n\n" .. S("This workbench is compatible with hoppers. Hoppers will insert into the raw material inventory and remove items from the finished goods inventory.")
  9. end
  10. local crafting_rate = minetest.settings:get("crafting_bench_crafting_rate")
  11. if crafting_rate == nil then crafting_rate = 5 end
  12. minetest.register_node("crafting_bench:workbench",{
  13. description = S("Workbench"),
  14. _doc_items_longdesc = string.format(S("A workbench that does work for you. Set a crafting recipe and provide raw materials and items will magically craft themselves once every %i seconds."), crafting_rate),
  15. _doc_items_usagehelp = usage_help,
  16. tiles = {
  17. "crafting_bench_workbench_top.png",
  18. "crafting_bench_workbench_bottom.png",
  19. "crafting_bench_workbench_side.png",
  20. "crafting_bench_workbench_side.png",
  21. "crafting_bench_workbench_back.png",
  22. "crafting_bench_workbench_front.png"
  23. },
  24. paramtype2 = "facedir",
  25. paramtype = "light",
  26. groups = {choppy=2,oddly_breakable_by_hand=2,flammable=2},
  27. sounds = default.node_sound_wood_defaults(),
  28. on_construct = function ( pos )
  29. local meta = minetest.get_meta( pos )
  30. meta:set_string( 'infotext', S('Workbench'))
  31. local inv = meta:get_inventory()
  32. inv:set_size( 'src', 2 * 4 )
  33. inv:set_size( 'rec', 3 * 3 )
  34. inv:set_size( 'dst', 1 * 4 )
  35. meta:set_string( 'formspec',
  36. 'size[10,10;]' ..
  37. default.gui_bg ..
  38. default.gui_bg_img ..
  39. default.gui_slots ..
  40. 'label[1,0;'..S('Source Material')..']' ..
  41. 'list[context;src;1,1;2,4;]' ..
  42. 'label[4,0;'..S('Recipe to Use')..']' ..
  43. 'list[context;rec;4,1;3,3;]' ..
  44. 'label[7.5,0;'..S('Craft Output')..']' ..
  45. 'list[context;dst;8,1;1,4;]' ..
  46. 'list[current_player;main;1,6;8,4;]'..
  47. 'listring[current_player;main]'..
  48. 'listring[context;src]'..
  49. 'listring[current_player;main]'..
  50. 'listring[context;rec]'..
  51. 'listring[current_player;main]'..
  52. 'listring[context;dst]')
  53. end,
  54. can_dig = function(pos,player)
  55. local meta = minetest.get_meta(pos);
  56. local inv = meta:get_inventory()
  57. return inv:is_empty("main")
  58. end,
  59. on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
  60. minetest.log("action", S("@1 moves stuff in workbench at @2", player:get_player_name(), minetest.pos_to_string(pos)))
  61. end,
  62. on_metadata_inventory_put = function(pos, listname, index, stack, player)
  63. minetest.log("action", S("@1 moves stuff to workbench at @2", player:get_player_name(), minetest.pos_to_string(pos)))
  64. end,
  65. on_metadata_inventory_take = function(pos, listname, index, stack, player)
  66. minetest.log("action", S("@1 takes stuff from workbench at @2", player:get_player_name(), minetest.pos_to_string(pos)))
  67. end,
  68. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  69. if minetest.is_protected(pos, player:get_player_name()) then
  70. return 0
  71. end
  72. return stack:get_count()
  73. end,
  74. allow_metadata_inventory_take = function(pos, listname, index, stack, player)
  75. if minetest.is_protected(pos, player:get_player_name()) then
  76. return 0
  77. end
  78. return stack:get_count()
  79. end,
  80. allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
  81. if minetest.is_protected(pos, player:get_player_name()) then
  82. return 0
  83. end
  84. return (to_list == 'src' or to_list == 'rec' or to_list == 'dst' and from_list == 'src' or from_list == 'rec' or from_list == 'dst') and count or 0
  85. end,
  86. })
  87. local get_recipe = function ( inv )
  88. local result, needed, input
  89. needed = inv:get_list( 'rec' )
  90. result, input = minetest.get_craft_result( {
  91. method = 'normal',
  92. width = 3,
  93. items = needed
  94. })
  95. local totalneed = {}
  96. if result.item:is_empty() then
  97. result = nil
  98. else
  99. result = result.item
  100. for _, item in ipairs( needed ) do
  101. if item ~= nil and not item:is_empty() and not inv:contains_item( 'src', item ) then
  102. result = nil
  103. break
  104. end
  105. if item ~= nil and not item:is_empty() then
  106. if totalneed[item:get_name()] == nil then
  107. totalneed[item:get_name()] = 1
  108. else
  109. totalneed[item:get_name()] = totalneed[item:get_name()] + 1
  110. end
  111. end
  112. end
  113. for name, number in pairs( totalneed ) do
  114. local totallist = inv:get_list( 'src' )
  115. for i, srcitem in pairs( totallist ) do
  116. if srcitem:get_name() == name then
  117. local taken = srcitem:take_item( number )
  118. number = number - taken:get_count()
  119. totallist[i] = srcitem
  120. end
  121. if number <= 0 then
  122. break
  123. end
  124. end
  125. if number > 0 then
  126. result = nil
  127. break
  128. end
  129. end
  130. end
  131. return needed, input, result
  132. end
  133. minetest.register_abm( {
  134. nodenames = {'crafting_bench:workbench'},
  135. label = 'autocrafting table',
  136. interval = crafting_rate,
  137. chance = 1,
  138. action = function ( pos, node )
  139. local meta = minetest.get_meta( pos )
  140. local inv = meta:get_inventory()
  141. local result, newinput, needed
  142. if not inv:is_empty( 'src' ) then
  143. -- Check for a valid recipe and sufficient resources to craft it
  144. needed, newinput, result = get_recipe( inv )
  145. if result ~= nil and inv:room_for_item( 'dst', result ) then
  146. inv:add_item( 'dst', result )
  147. for i, item in pairs( needed ) do
  148. if item ~= nil and item ~= '' then
  149. inv:remove_item( 'src', ItemStack( item ) )
  150. end
  151. if newinput[i] ~= nil and not newinput[i]:is_empty() then
  152. inv:add_item( 'src', newinput[i] )
  153. end
  154. end
  155. end
  156. end
  157. end
  158. } )
  159. local function has_locked_chest_privilege(meta, player)
  160. if player:get_player_name() ~= meta:get_string("owner") then
  161. return false
  162. end
  163. return true
  164. end
  165. minetest.register_craft({
  166. output = "crafting_bench:workbench",
  167. recipe = {
  168. {"default:steel_ingot","default:steel_ingot","default:steel_ingot"},
  169. {"default:wood", "default:wood","default:steel_ingot"},
  170. {"default:tree", "default:tree","default:steel_ingot"},
  171. }
  172. })
  173. -- Hopper compatibility
  174. if minetest.get_modpath("hopper") and hopper ~= nil and hopper.add_container ~= nil then
  175. hopper:add_container({
  176. {"top", "crafting_bench:workbench", "dst"},
  177. {"side", "crafting_bench:workbench", "src"},
  178. {"bottom", "crafting_bench:workbench", "src"},
  179. })
  180. end