workshop.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. if not minetest.global_exists("workshop") then workshop = {} end
  2. workshop.modpath = minetest.get_modpath("machines")
  3. -- Localize for performance.
  4. local math_random = math.random
  5. local BUFFER_SIZE = tech.workshop.buffer
  6. local ENERGY_AMOUNT = tech.workshop.power
  7. local REPAIR_RATE = tech.workshop.repair
  8. workshop.compose_formspec =
  9. function(pos)
  10. local formspec =
  11. "size[8,7.75]" ..
  12. default.gui_bg ..
  13. default.gui_bg_img ..
  14. default.gui_slots ..
  15. "label[1.0,0.5;Upgrade]" ..
  16. "list[context;upg;1.0,1;1,1]" ..
  17. "label[3.5,0.5;Energy Buffer]" ..
  18. "list[context;buffer;3.5,1;1,1]" ..
  19. "label[6.0,0.5;Tool Repair]" ..
  20. "list[context;main;6.0,1;1,1]" ..
  21. "list[current_player;main;0,3.5;8,1;]" ..
  22. "list[current_player;main;0,4.75;8,3;8]" ..
  23. "listring[context;main]" ..
  24. "listring[current_player;main]" ..
  25. default.get_hotbar_bg(0, 3.5)
  26. return formspec
  27. end
  28. workshop.on_receive_fields =
  29. function(pos, formname, fields, sender)
  30. end
  31. workshop.compose_infotext =
  32. function(pos)
  33. local meta = minetest.get_meta(pos)
  34. local state = "Standby"
  35. local eups = 0
  36. if meta:get_int("active") == 1 then
  37. state = "Active"
  38. eups = ENERGY_AMOUNT
  39. end
  40. local infotext = "LV Tool Repair Shop (" .. state .. ")\n" ..
  41. "Demand: " .. eups .. " EU Per/Sec"
  42. return infotext
  43. end
  44. workshop.trigger_update =
  45. function(pos)
  46. local timer = minetest.get_node_timer(pos)
  47. -- Restart timer even if already running.
  48. timer:start(1.0)
  49. end
  50. workshop.on_punch =
  51. function(pos, node, puncher, pointed_thing)
  52. workshop.trigger_update(pos)
  53. local meta = minetest.get_meta(pos)
  54. local inv = meta:get_inventory()
  55. inv:set_size("upg", 1)
  56. end
  57. workshop.can_dig =
  58. function(pos, player)
  59. local meta = minetest.get_meta(pos)
  60. local inv = meta:get_inventory()
  61. return inv:is_empty("main") and inv:is_empty("upg")
  62. end
  63. workshop.on_timer =
  64. function(pos, elapsed)
  65. --minetest.chat_send_all("# Server: Elapsed time is " .. elapsed .. "!")
  66. local keeprunning = false
  67. local meta = minetest.get_meta(pos)
  68. local inv = meta:get_inventory()
  69. local the_tool -- Set to tool's itemstack if we have one.
  70. local got_energy = false
  71. local energy_gotten = 0
  72. -- Assuming we can keep running unless someone says otherwise.
  73. keeprunning = true
  74. do
  75. local tool = inv:get_stack("main", 1)
  76. if tool:get_count() == 1 and tool:get_stack_max() == 1 then
  77. local name = tool:get_name()
  78. local def = minetest.registered_tools[name]
  79. if def and not def.wear_represents then -- Wear cannot be anything but default.
  80. local wear = tool:get_wear()
  81. if wear == 0 then
  82. -- Tool fully repaired.
  83. -- (Or, it could be something that looks like a tool but doesn't implement wear.)
  84. keeprunning = false
  85. goto cancel
  86. else
  87. -- We got a tool and it needs repair.
  88. the_tool = tool
  89. end
  90. else
  91. -- Unknown item.
  92. keeprunning = false
  93. goto cancel
  94. end
  95. else
  96. -- No tool.
  97. keeprunning = false
  98. goto cancel
  99. end
  100. end
  101. -- Consume energy (but only if there is a tool to charge).
  102. if the_tool then
  103. local energy = inv:get_stack("buffer", 1)
  104. if energy:get_count() >= ENERGY_AMOUNT then
  105. energy:set_count(energy:get_count() - ENERGY_AMOUNT)
  106. inv:set_stack("buffer", 1, energy)
  107. -- We have enough energy.
  108. energy_gotten = ENERGY_AMOUNT
  109. got_energy = true
  110. else
  111. -- Try to get energy from network.
  112. local owner = meta:get_string("owner")
  113. local gotten = net2.get_energy(pos, owner, BUFFER_SIZE, "lv")
  114. if gotten >= ENERGY_AMOUNT then
  115. energy = ItemStack("atomic:energy " .. (energy:get_count() + gotten))
  116. inv:set_stack("buffer", 1, energy)
  117. -- Wait for next iteration before repairing again.
  118. goto cancel
  119. end
  120. -- Not enough energy!
  121. keeprunning = false
  122. goto cancel
  123. end
  124. end
  125. -- Repair the tool.
  126. if the_tool and got_energy then
  127. local wear = the_tool:get_wear()
  128. wear = wear - REPAIR_RATE
  129. if wear < 0 then
  130. wear = 0
  131. end
  132. the_tool:set_wear(wear)
  133. inv:set_stack("main", 1, the_tool)
  134. end
  135. -- Jump here if something prevents machine from working.
  136. ::cancel::
  137. -- Determine mode (active or sleep) and set timer accordingly.
  138. if keeprunning then
  139. minetest.get_node_timer(pos):start(1.0)
  140. meta:set_int("active", 1)
  141. else
  142. -- Slow down timer during sleep periods to reduce load.
  143. minetest.get_node_timer(pos):start(math_random(1, 3*60))
  144. meta:set_int("active", 0)
  145. end
  146. -- Update infotext.
  147. meta:set_string("formspec", workshop.compose_formspec(pos))
  148. meta:set_string("infotext", workshop.compose_infotext(pos))
  149. end
  150. workshop.on_construct =
  151. function(pos)
  152. end
  153. workshop.after_place_node =
  154. function(pos, placer, itemstack, pointed_thing)
  155. local meta = minetest.get_meta(pos)
  156. local node = minetest.get_node(pos)
  157. local owner = placer:get_player_name()
  158. local inv = meta:get_inventory()
  159. meta:set_string("owner", owner)
  160. meta:set_string("nodename", node.name)
  161. inv:set_size("buffer", 1)
  162. inv:set_size("main", 1)
  163. inv:set_size("upg", 1)
  164. net2.clear_caches(pos, owner, "lv")
  165. meta:set_string("formspec", workshop.compose_formspec(pos))
  166. meta:set_string("infotext", workshop.compose_infotext(pos))
  167. nodestore.add_node(pos)
  168. local timer = minetest.get_node_timer(pos)
  169. timer:start(1.0)
  170. end
  171. workshop.on_blast =
  172. function(pos)
  173. local drops = {}
  174. drops[#drops+1] = "workshop:workshop"
  175. default.get_inventory_drops(pos, "main", drops)
  176. minetest.remove_node(pos)
  177. return drops
  178. end
  179. workshop.has_public_access =
  180. function(pos)
  181. local meta = minetest.get_meta(pos)
  182. local inv = meta:get_inventory()
  183. -- There is only 1 upgrade slot.
  184. local s1 = inv:get_stack("upg", 1)
  185. if s1 and s1:get_count() > 0 then
  186. if minetest.get_item_group(s1:get_name(), "chest") > 0 then
  187. return true
  188. end
  189. end
  190. end
  191. workshop.allow_metadata_inventory_put =
  192. function(pos, listname, index, stack, player)
  193. local pname = player:get_player_name()
  194. local public = workshop.has_public_access(pos)
  195. local protected = false
  196. if minetest.test_protection(pos, pname) then
  197. protected = true
  198. end
  199. if listname == "main" and (not protected or public) then
  200. local def = minetest.registered_items[stack:get_name()]
  201. if def and not def.wear_represents then
  202. -- Only if wear amount represents the default usage.
  203. return 1
  204. end
  205. elseif listname == "upg" and not protected then
  206. if minetest.get_item_group(stack:get_name(), "chest") > 0 then
  207. return stack:get_count()
  208. -- Note: battery and CLU don't do anything for this machine at this time.
  209. elseif stack:get_name() == "battery:battery" then
  210. return stack:get_count()
  211. elseif stack:get_name() == "techcrafts:control_logic_unit" then
  212. return stack:get_count()
  213. end
  214. end
  215. return 0
  216. end
  217. workshop.allow_metadata_inventory_move =
  218. function(pos, from_list, from_index, to_list, to_index, count, player)
  219. local pname = player:get_player_name()
  220. local public = workshop.has_public_access(pos)
  221. local protected = false
  222. if minetest.test_protection(pos, pname) then
  223. protected = true
  224. end
  225. if (from_list == "upg" or to_list == "upg") and protected then
  226. -- Don't permit public users to mess with the upgrades.
  227. return 0
  228. end
  229. if not protected or public then
  230. -- Can't touch the output energy buffer.
  231. if from_list == "buffer" or to_list == "buffer" then
  232. return 0
  233. end
  234. if from_list == to_list then
  235. return count
  236. end
  237. end
  238. return 0
  239. end
  240. workshop.allow_metadata_inventory_take =
  241. function(pos, listname, index, stack, player)
  242. local pname = player:get_player_name()
  243. local public = workshop.has_public_access(pos)
  244. local protected = false
  245. if minetest.test_protection(pos, pname) then
  246. protected = true
  247. end
  248. if listname == "main" and (not protected or public) then
  249. return stack:get_count()
  250. elseif listname == "upg" and not protected then
  251. return stack:get_count()
  252. end
  253. return 0
  254. end
  255. workshop.on_metadata_inventory_move =
  256. function(pos)
  257. workshop.trigger_update(pos)
  258. end
  259. workshop.on_metadata_inventory_put =
  260. function(pos)
  261. workshop.trigger_update(pos)
  262. end
  263. workshop.on_metadata_inventory_take =
  264. function(pos, listname, index, stack, player)
  265. workshop.trigger_update(pos)
  266. end
  267. workshop.on_destruct =
  268. function(pos)
  269. local meta = minetest.get_meta(pos)
  270. net2.clear_caches(pos, meta:get_string("owner"), "lv")
  271. nodestore.del_node(pos)
  272. end
  273. if not workshop.run_once then
  274. minetest.register_node(":workshop:workshop", {
  275. description = "LV Tool Repair Shop\n\nRepairs tools.\nConnects to a power-network.",
  276. tiles = {
  277. "workshop_top.png",
  278. "workshop_bottom.png",
  279. "workshop_side.png",
  280. "workshop_side.png",
  281. "workshop_side.png",
  282. "workshop_side.png",
  283. },
  284. groups = utility.dig_groups("machine"),
  285. paramtype2 = "facedir",
  286. is_ground_content = false,
  287. sounds = default.node_sound_metal_defaults(),
  288. drop = "workshop:workshop",
  289. on_rotate = function(...)
  290. return screwdriver.rotate_simple(...) end,
  291. allow_metadata_inventory_put = function(...)
  292. return workshop.allow_metadata_inventory_put(...) end,
  293. allow_metadata_inventory_move = function(...)
  294. return workshop.allow_metadata_inventory_move(...) end,
  295. allow_metadata_inventory_take = function(...)
  296. return workshop.allow_metadata_inventory_take(...) end,
  297. on_metadata_inventory_move = function(...)
  298. return workshop.on_metadata_inventory_move(...) end,
  299. on_metadata_inventory_put = function(...)
  300. return workshop.on_metadata_inventory_put(...) end,
  301. on_metadata_inventory_take = function(...)
  302. return workshop.on_metadata_inventory_take(...) end,
  303. on_punch = function(...)
  304. return workshop.on_punch(...) end,
  305. can_dig = function(...)
  306. return workshop.can_dig(...) end,
  307. on_timer = function(...)
  308. return workshop.on_timer(...) end,
  309. on_construct = function(...)
  310. return workshop.on_construct(...) end,
  311. on_destruct = function(...)
  312. return workshop.on_destruct(...) end,
  313. on_blast = function(...)
  314. return workshop.on_blast(...) end,
  315. after_place_node = function(...)
  316. return workshop.after_place_node(...) end,
  317. on_receive_fields = function(...)
  318. return workshop.on_receive_fields(...) end,
  319. })
  320. ---[[
  321. minetest.register_craft({
  322. output = 'workshop:workshop',
  323. recipe = {
  324. {'group:wood', 'default:diamond', 'group:wood'},
  325. {'anvil:anvil', 'techcrafts:machine_casing', 'techcrafts:carbon_cloth'},
  326. {'default:obsidian', 'techcrafts:control_logic_unit', 'cobble_furnace:inactive'},
  327. }
  328. })
  329. --]]
  330. local c = "workshop:core"
  331. local f = workshop.modpath .. "/workshop.lua"
  332. reload.register_file(c, f, false)
  333. workshop.run_once = true
  334. end