charger.lua 10 KB

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