cnc.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. -- Technic CNC v1.0 by kpoppel
  2. -- Based on the NonCubic Blocks MOD v1.4 by yves_de_beck
  3. -- Idea:
  4. -- Somehow have a tabbed/paged panel if the number of shapes should expand
  5. -- beyond what is available in the panel today.
  6. -- I could imagine some form of API allowing modders to come with their own node
  7. -- box definitions and easily stuff it in the this machine for production.
  8. local S = technic_cnc.getter
  9. local allow_metadata_inventory_put
  10. local allow_metadata_inventory_take
  11. local allow_metadata_inventory_move
  12. local can_dig
  13. local desc_tr = S("CNC Machine")
  14. if technic_cnc.use_technic then
  15. minetest.register_craft({
  16. output = 'technic:cnc',
  17. recipe = {
  18. {'default:glass', 'technic:diamond_drill_head', 'default:glass'},
  19. {'technic:control_logic_unit', 'technic:machine_casing', 'basic_materials:motor'},
  20. {'technic:carbon_steel_ingot', 'technic:lv_cable', 'technic:carbon_steel_ingot'},
  21. },
  22. })
  23. allow_metadata_inventory_put = technic.machine_inventory_put
  24. allow_metadata_inventory_take = technic.machine_inventory_take
  25. allow_metadata_inventory_move = technic.machine_inventory_move
  26. can_dig = technic.machine_can_dig
  27. desc_tr = S("%s CNC Machine"):format("LV")
  28. else
  29. minetest.register_craft({
  30. output = 'technic:cnc',
  31. recipe = {
  32. {'default:glass', 'default:diamond', 'default:glass'},
  33. {'basic_materials:ic', 'default:steelblock', 'basic_materials:motor'},
  34. {'default:steel_ingot', 'default:mese', 'default:steel_ingot'},
  35. },
  36. })
  37. allow_metadata_inventory_put = function(pos, listname, index, stack, player)
  38. if minetest.is_protected(pos, player:get_player_name()) then
  39. return 0
  40. end
  41. return stack:get_count()
  42. end
  43. allow_metadata_inventory_take = function(pos, listname, index, stack, player)
  44. if minetest.is_protected(pos, player:get_player_name()) then
  45. return 0
  46. end
  47. return stack:get_count()
  48. end
  49. allow_metadata_inventory_move = function(pos, from_list, from_index,
  50. to_list, to_index, count, player)
  51. if minetest.is_protected(pos, player:get_player_name()) then
  52. return 0
  53. end
  54. return count
  55. end
  56. can_dig = function(pos, player)
  57. if player and minetest.is_protected(pos, player:get_player_name()) then return false end
  58. local meta = minetest.get_meta(pos);
  59. local inv = meta:get_inventory()
  60. return inv:is_empty("dst")
  61. and inv:is_empty("src")
  62. and default.can_interact_with_node(player, pos)
  63. end
  64. end
  65. local onesize_products = {
  66. slope = 2,
  67. slope_edge = 1,
  68. slope_inner_edge = 1,
  69. pyramid = 2,
  70. spike = 1,
  71. cylinder = 2,
  72. oblate_spheroid = 1,
  73. sphere = 1,
  74. stick = 8,
  75. slope_upsdown = 2,
  76. slope_edge_upsdown = 1,
  77. slope_inner_edge_upsdown = 1,
  78. cylinder_horizontal = 2,
  79. slope_lying = 2,
  80. onecurvededge = 1,
  81. twocurvededge = 1,
  82. }
  83. local twosize_products = {
  84. element_straight = 2,
  85. element_end = 2,
  86. element_cross = 1,
  87. element_t = 1,
  88. element_edge = 2,
  89. }
  90. local cnc_formspec =
  91. "size[9,11;]"..
  92. "label[1,0;"..S("Choose Milling Program:").."]"..
  93. "image_button[1,0.5;1,1;technic_cnc_slope.png;slope; ]"..
  94. "image_button[2,0.5;1,1;technic_cnc_slope_edge.png;slope_edge; ]"..
  95. "image_button[3,0.5;1,1;technic_cnc_slope_inner_edge.png;slope_inner_edge; ]"..
  96. "image_button[4,0.5;1,1;technic_cnc_pyramid.png;pyramid; ]"..
  97. "image_button[5,0.5;1,1;technic_cnc_spike.png;spike; ]"..
  98. "image_button[6,0.5;1,1;technic_cnc_cylinder.png;cylinder; ]"..
  99. "image_button[7,0.5;1,1;technic_cnc_oblate_spheroid.png;oblate_spheroid; ]"..
  100. "image_button[8,0.5;1,1;technic_cnc_stick.png;stick; ]"..
  101. "image_button[1,1.5;1,1;technic_cnc_slope_upsdwn.png;slope_upsdown; ]"..
  102. "image_button[2,1.5;1,1;technic_cnc_slope_edge_upsdwn.png;slope_edge_upsdown; ]"..
  103. "image_button[3,1.5;1,1;technic_cnc_slope_inner_edge_upsdwn.png;slope_inner_edge_upsdown; ]"..
  104. "image_button[4,1.5;1,1;technic_cnc_cylinder_horizontal.png;cylinder_horizontal; ]"..
  105. "image_button[5,1.5;1,1;technic_cnc_sphere.png;sphere; ]"..
  106. "image_button[1,2.5;1,1;technic_cnc_slope_lying.png;slope_lying; ]"..
  107. "image_button[2,2.5;1,1;technic_cnc_onecurvededge.png;onecurvededge; ]"..
  108. "image_button[3,2.5;1,1;technic_cnc_twocurvededge.png;twocurvededge; ]"..
  109. "label[1,3.5;"..S("Slim Elements half / normal height:").."]"..
  110. "image_button[1,4;1,0.5;technic_cnc_full.png;full; ]"..
  111. "image_button[1,4.5;1,0.5;technic_cnc_half.png;half; ]"..
  112. "image_button[2,4;1,1;technic_cnc_element_straight.png;element_straight; ]"..
  113. "image_button[3,4;1,1;technic_cnc_element_end.png;element_end; ]"..
  114. "image_button[4,4;1,1;technic_cnc_element_cross.png;element_cross; ]"..
  115. "image_button[5,4;1,1;technic_cnc_element_t.png;element_t; ]"..
  116. "image_button[6,4;1,1;technic_cnc_element_edge.png;element_edge; ]"..
  117. "label[0, 5.5;"..S("In:").."]"..
  118. "list[current_name;src;0.5,5.5;1,1;]"..
  119. "label[4, 5.5;"..S("Out:").."]"..
  120. "list[current_name;dst;5,5.5;4,1;]"..
  121. "list[current_player;main;0,7;8,4;]"..
  122. "listring[current_name;dst]"..
  123. "listring[current_player;main]"..
  124. "listring[current_name;src]"..
  125. "listring[current_player;main]"
  126. -- The form handler is declared here because we need it in both the inactive and active modes
  127. -- in order to be able to change programs wile it is running.
  128. local function form_handler(pos, formname, fields, sender)
  129. local meta = minetest.get_meta(pos)
  130. -- REGISTER MILLING PROGRAMS AND OUTPUTS:
  131. ------------------------------------------
  132. -- Program for half/full size
  133. if fields["full"] then
  134. meta:set_int("size", 1)
  135. return
  136. end
  137. if fields["half"] then
  138. meta:set_int("size", 2)
  139. return
  140. end
  141. -- Resolve the node name and the number of items to make
  142. local inv = meta:get_inventory()
  143. local inputstack = inv:get_stack("src", 1)
  144. local inputname = inputstack:get_name()
  145. local multiplier = 0
  146. local size = meta:get_int("size")
  147. if size < 1 then size = 1 end
  148. for k, _ in pairs(fields) do
  149. -- Set a multipier for the half/full size capable blocks
  150. if twosize_products[k] ~= nil then
  151. multiplier = size * twosize_products[k]
  152. else
  153. multiplier = onesize_products[k]
  154. end
  155. if onesize_products[k] ~= nil or twosize_products[k] ~= nil then
  156. meta:set_float( "cnc_multiplier", multiplier)
  157. meta:set_string("cnc_user", sender:get_player_name())
  158. end
  159. if onesize_products[k] ~= nil or (twosize_products[k] ~= nil and size==2) then
  160. meta:set_string("cnc_product", inputname .. "_technic_cnc_" .. k)
  161. --print(inputname .. "_technic_cnc_" .. k)
  162. break
  163. end
  164. if twosize_products[k] ~= nil and size==1 then
  165. meta:set_string("cnc_product", inputname .. "_technic_cnc_" .. k .. "_double")
  166. --print(inputname .. "_technic_cnc_" .. k .. "_double")
  167. break
  168. end
  169. end
  170. if not technic_cnc.use_technic then
  171. local result = meta:get_string("cnc_product")
  172. if not inv:is_empty("src")
  173. and minetest.registered_nodes[result]
  174. and inv:room_for_item("dst", result) then
  175. local srcstack = inv:get_stack("src", 1)
  176. srcstack:take_item()
  177. inv:set_stack("src", 1, srcstack)
  178. inv:add_item("dst", result.." "..meta:get_int("cnc_multiplier"))
  179. end
  180. end
  181. end
  182. -- Action code performing the transformation
  183. local run = function(pos, node)
  184. local meta = minetest.get_meta(pos)
  185. local inv = meta:get_inventory()
  186. local eu_input = meta:get_int("LV_EU_input")
  187. local machine_name = desc_tr
  188. local machine_node = "technic:cnc"
  189. local demand = 450
  190. local result = meta:get_string("cnc_product")
  191. if inv:is_empty("src") or
  192. (not minetest.registered_nodes[result]) or
  193. (not inv:room_for_item("dst", result)) then
  194. technic.swap_node(pos, machine_node)
  195. meta:set_string("infotext", S("%s Idle"):format(machine_name))
  196. meta:set_string("cnc_product", "")
  197. meta:set_int("LV_EU_demand", 0)
  198. return
  199. end
  200. if eu_input < demand then
  201. technic.swap_node(pos, machine_node)
  202. meta:set_string("infotext", S("%s Unpowered"):format(machine_name))
  203. elseif eu_input >= demand then
  204. technic.swap_node(pos, machine_node.."_active")
  205. meta:set_string("infotext", S("%s Active"):format(machine_name))
  206. meta:set_int("src_time", meta:get_int("src_time") + 1)
  207. if meta:get_int("src_time") >= 3 then -- 3 ticks per output
  208. meta:set_int("src_time", 0)
  209. local srcstack = inv:get_stack("src", 1)
  210. srcstack:take_item()
  211. inv:set_stack("src", 1, srcstack)
  212. inv:add_item("dst", result.." "..meta:get_int("cnc_multiplier"))
  213. end
  214. end
  215. meta:set_int("LV_EU_demand", demand)
  216. end
  217. -- The actual block inactive state
  218. minetest.register_node(":technic:cnc", {
  219. description = desc_tr,
  220. tiles = {"technic_cnc_top.png", "technic_cnc_bottom.png", "technic_cnc_side.png",
  221. "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front.png"},
  222. groups = {cracky=2, technic_machine=1, technic_lv=1},
  223. connect_sides = {"bottom", "back", "left", "right"},
  224. paramtype2 = "facedir",
  225. legacy_facedir_simple = true,
  226. on_construct = function(pos)
  227. local meta = minetest.get_meta(pos)
  228. meta:set_string("infotext", desc_tr)
  229. meta:set_float("technic_power_machine", 1)
  230. meta:set_string("formspec", cnc_formspec)
  231. local inv = meta:get_inventory()
  232. inv:set_size("src", 1)
  233. inv:set_size("dst", 4)
  234. end,
  235. can_dig = can_dig,
  236. allow_metadata_inventory_put = allow_metadata_inventory_put,
  237. allow_metadata_inventory_take = allow_metadata_inventory_take,
  238. allow_metadata_inventory_move = allow_metadata_inventory_move,
  239. on_receive_fields = form_handler,
  240. technic_run = technic_cnc.use_technic and run,
  241. })
  242. -- Active state block
  243. if technic_cnc.use_technic then
  244. minetest.register_node(":technic:cnc_active", {
  245. description = desc_tr,
  246. tiles = {"technic_cnc_top_active.png", "technic_cnc_bottom.png", "technic_cnc_side.png",
  247. "technic_cnc_side.png", "technic_cnc_side.png", "technic_cnc_front_active.png"},
  248. groups = {cracky=2, technic_machine=1, technic_lv=1, not_in_creative_inventory=1},
  249. connect_sides = {"bottom", "back", "left", "right"},
  250. paramtype2 = "facedir",
  251. drop = "technic:cnc",
  252. legacy_facedir_simple = true,
  253. can_dig = can_dig,
  254. allow_metadata_inventory_put = allow_metadata_inventory_put,
  255. allow_metadata_inventory_take = allow_metadata_inventory_take,
  256. allow_metadata_inventory_move = allow_metadata_inventory_move,
  257. on_receive_fields = form_handler,
  258. technic_run = run,
  259. technic_disabled_machine_name = "technic:cnc",
  260. })
  261. technic.register_machine("LV", "technic:cnc", technic.receiver)
  262. technic.register_machine("LV", "technic:cnc_active", technic.receiver)
  263. else
  264. minetest.register_alias("technic:cnc_active", "technic:cnc")
  265. end