init.lua 6.6 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. drawtype = "normal",
  29. on_construct = function ( pos )
  30. local meta = minetest.get_meta( pos )
  31. meta:set_string( 'formspec',
  32. 'size[10,10;]' ..
  33. default.gui_bg ..
  34. default.gui_bg_img ..
  35. default.gui_slots ..
  36. 'label[1,0;'..S('Source Material')..']' ..
  37. 'list[context;src;1,1;2,4;]' ..
  38. 'label[4,0;'..S('Recipe to Use')..']' ..
  39. 'list[context;rec;4,1;3,3;]' ..
  40. 'label[7.5,0;'..S('Craft Output')..']' ..
  41. 'list[context;dst;8,1;1,4;]' ..
  42. 'list[current_player;main;1,6;8,4;]'..
  43. 'listring[current_player;main]'..
  44. 'listring[context;src]'..
  45. 'listring[current_player;main]'..
  46. 'listring[context;rec]'..
  47. 'listring[current_player;main]'..
  48. 'listring[context;dst]')
  49. meta:set_string( 'infotext', S('Workbench'))
  50. local inv = meta:get_inventory()
  51. inv:set_size( 'src', 2 * 4 )
  52. inv:set_size( 'rec', 3 * 3 )
  53. inv:set_size( 'dst', 1 * 4 )
  54. end,
  55. can_dig = function(pos,player)
  56. local meta = minetest.get_meta(pos);
  57. local inv = meta:get_inventory()
  58. return inv:is_empty("main")
  59. end,
  60. on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
  61. minetest.log("action", S("@1 moves stuff in workbench at @2", player:get_player_name(), minetest.pos_to_string(pos)))
  62. end,
  63. on_metadata_inventory_put = function(pos, listname, index, stack, player)
  64. minetest.log("action", S("@1 moves stuff to workbench at @2", player:get_player_name(), minetest.pos_to_string(pos)))
  65. end,
  66. on_metadata_inventory_take = function(pos, listname, index, stack, player)
  67. minetest.log("action", S("@1 takes stuff from workbench at @2", player:get_player_name(), minetest.pos_to_string(pos)))
  68. end,
  69. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  70. if minetest.is_protected(pos, player:get_player_name()) then
  71. return 0
  72. end
  73. return stack:get_count()
  74. end,
  75. allow_metadata_inventory_take = function(pos, listname, index, stack, player)
  76. if minetest.is_protected(pos, player:get_player_name()) then
  77. return 0
  78. end
  79. return stack:get_count()
  80. end,
  81. allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
  82. if minetest.is_protected(pos, player:get_player_name()) then
  83. return 0
  84. end
  85. 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
  86. end,
  87. })
  88. local get_recipe = function ( inv )
  89. local result, needed, input
  90. needed = inv:get_list( 'rec' )
  91. result, input = minetest.get_craft_result( {
  92. method = 'normal',
  93. width = 3,
  94. items = needed
  95. })
  96. local totalneed = {}
  97. if result.item:is_empty() then
  98. result = nil
  99. else
  100. result = result.item
  101. for _, item in ipairs( needed ) do
  102. if item ~= nil and not item:is_empty() and not inv:contains_item( 'src', item ) then
  103. result = nil
  104. break
  105. end
  106. if item ~= nil and not item:is_empty() then
  107. if totalneed[item:get_name()] == nil then
  108. totalneed[item:get_name()] = 1
  109. else
  110. totalneed[item:get_name()] = totalneed[item:get_name()] + 1
  111. end
  112. end
  113. end
  114. for name, number in pairs( totalneed ) do
  115. local totallist = inv:get_list( 'src' )
  116. for i, srcitem in pairs( totallist ) do
  117. if srcitem:get_name() == name then
  118. local taken = srcitem:take_item( number )
  119. number = number - taken:get_count()
  120. totallist[i] = srcitem
  121. end
  122. if number <= 0 then
  123. break
  124. end
  125. end
  126. if number > 0 then
  127. result = nil
  128. break
  129. end
  130. end
  131. end
  132. return needed, input, result
  133. end
  134. minetest.register_abm( {
  135. nodenames = { 'crafting_bench:workbench' },
  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