conv2.lua 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. conv2 = conv2 or {}
  2. conv2.modpath = minetest.get_modpath("converter")
  3. local BUFFER_SIZE = tech.converter.buffer
  4. local ENERGY_AMOUNT = tech.converter.power
  5. -- First key is voltage from. Second key is voltage to.
  6. -- Note that we never have 'from' and 'to' be the same voltage tier.
  7. local efficiency = {
  8. lv = {
  9. lv = 1.0,
  10. mv = 0.7,
  11. hv = 0.1,
  12. },
  13. mv = {
  14. lv = 0.9,
  15. mv = 1.0,
  16. hv = 0.7,
  17. },
  18. hv = {
  19. lv = 0.7,
  20. mv = 0.9,
  21. hv = 1.0,
  22. },
  23. }
  24. conv2.get_config_data =
  25. function(pos, side) -- side should be p1 or p2.
  26. local meta = minetest.get_meta(pos)
  27. local owner = meta:get_string("owner")
  28. local inv = meta:get_inventory()
  29. local cfg = inv:get_stack("config", 1)
  30. if cfg:get_count() == 1 and cfg:get_name() == "cfg:dev" then
  31. local meta1 = cfg:get_meta()
  32. local pos1 = minetest.string_to_pos(meta1:get_string(side))
  33. if pos1 then
  34. if vector.distance(pos, pos1) < 1.01 then
  35. local node = minetest.get_node(pos1)
  36. local nmeta = minetest.get_meta(pos1)
  37. local nowner = nmeta:get_string("owner")
  38. if string.find(node.name, "^stat2:") and owner == nowner then
  39. local tier = string.sub(node.name, 7)
  40. -- Return success, pos, tier, owner.
  41. return true, pos1, tier, nowner
  42. end
  43. end
  44. end
  45. end
  46. return false
  47. end
  48. conv2.on_energy_put =
  49. function(pos, energy, tier)
  50. -- Can only put energy into machine if it comes from the input side.
  51. local gooda, posa, tiera, owna = conv2.get_config_data(pos, "p1")
  52. if not gooda then
  53. return energy
  54. end
  55. if tier ~= tiera then
  56. return energy
  57. end
  58. local meta = minetest.get_meta(pos)
  59. local inv = meta:get_inventory()
  60. local stack = inv:get_stack("buffer", 1)
  61. local chg, max = stack:get_count(), BUFFER_SIZE
  62. local canfit = max - chg
  63. if canfit < 0 then canfit = 0 end
  64. local toput = energy
  65. if toput > canfit then
  66. toput = canfit
  67. end
  68. local total = chg + toput
  69. inv:set_stack("buffer", 1, "atomic:energy " .. total)
  70. energy = energy - toput
  71. conv2.trigger_update(pos)
  72. return energy
  73. end
  74. conv2.compose_formspec =
  75. function(pos)
  76. local formspec =
  77. "size[8,4]" ..
  78. default.gui_bg ..
  79. default.gui_bg_img ..
  80. default.gui_slots ..
  81. "label[2,0.5;Config]" ..
  82. "list[context;config;2,1;1,1]" ..
  83. "label[5,0.5;Energy]" ..
  84. "list[context;buffer;5,1;1,1]" ..
  85. "list[current_player;main;0,3;8,1;]" ..
  86. "listring[context;config]" ..
  87. "listring[current_player;main]" ..
  88. default.get_hotbar_bg(0, 3)
  89. return formspec
  90. end
  91. conv2.compose_infotext =
  92. function(pos, tiera, tierb, invalidconfig, keeprunning)
  93. local active = "Standby"
  94. if keeprunning then
  95. active = "Active"
  96. end
  97. local infotext = "Voltage Transformer (" .. active .. ")\n" ..
  98. "Configuration: "
  99. if invalidconfig then
  100. infotext = infotext .. "Invalid/Unknown"
  101. else
  102. --print(tiera)
  103. --print(tierb)
  104. infotext = infotext .. string.upper(tiera) .. " -> " .. string.upper(tierb) .. "\n" ..
  105. "Efficiency: " .. math.floor(efficiency[tiera][tierb] * 100) .. "%"
  106. end
  107. return infotext
  108. end
  109. conv2.trigger_update =
  110. function(pos)
  111. local timer = minetest.get_node_timer(pos)
  112. -- Restart timer even if already running.
  113. timer:start(1.0)
  114. end
  115. conv2.on_punch =
  116. function(pos, node, puncher, pointed_thing)
  117. conv2.trigger_update(pos)
  118. end
  119. conv2.can_dig =
  120. function(pos, player)
  121. local meta = minetest.get_meta(pos)
  122. local inv = meta:get_inventory()
  123. return inv:is_empty("config")
  124. end
  125. conv2.on_timer =
  126. function(pos, elapsed)
  127. --minetest.chat_send_player("MustTest", "# Server: On Timer! " .. minetest.get_gametime())
  128. local keeprunning = false
  129. local meta = minetest.get_meta(pos)
  130. local inv = meta:get_inventory()
  131. local owner = meta:get_string("owner")
  132. local needflush = false
  133. local invalidconfig = false
  134. local putgood = false
  135. local getgood = false
  136. local gooda, posa, tiera, owna = conv2.get_config_data(pos, "p1")
  137. local goodb, posb, tierb, ownb = conv2.get_config_data(pos, "p2")
  138. if not gooda or not goodb then
  139. invalidconfig = true
  140. goto the_end
  141. end
  142. -- Tiers cannot be same.
  143. if tiera == tierb then
  144. invalidconfig = true
  145. goto the_end
  146. end
  147. -- Check if we need to discharge energy.
  148. do -- Scoped local variable to prevent problems with goto.
  149. local curstack = inv:get_stack("buffer", 1)
  150. if curstack:get_count() >= BUFFER_SIZE then
  151. needflush = true
  152. end
  153. end
  154. -- Draw energy from network above only if not needing a flush.
  155. if not needflush then
  156. local toget = ENERGY_AMOUNT
  157. local energy = net2.get_energy(posa, owna, toget, tiera)
  158. local estack = ItemStack("atomic:energy " .. energy)
  159. inv:add_item("buffer", estack)
  160. if energy >= toget then
  161. getgood = true -- We were able to get wanted amount of energy.
  162. end
  163. end
  164. -- Discharge energy into network below.
  165. if needflush then
  166. -- There should be at least BUFFER_SIZE energy in inventory.
  167. local total_energy = inv:get_stack("buffer", 1)
  168. local eff = efficiency[tiera][tierb]
  169. local amount_to_send = math.floor(total_energy:get_count() * eff)
  170. local amount_not_sent = net2.put_energy(posb, ownb, amount_to_send, tierb)
  171. -- 3 possible cases.
  172. if amount_not_sent == amount_to_send then
  173. -- No energy could be stored in the network.
  174. -- Don't change energy buffered.
  175. elseif amount_not_sent == 0 then
  176. -- All energy sent was stored in the network.
  177. inv:set_stack("buffer", 1, ItemStack(""))
  178. putgood = true
  179. else
  180. -- Energy was only partially stored.
  181. assert(amount_not_sent < amount_to_send)
  182. assert(amount_not_sent > 0)
  183. local amount_sent = (amount_to_send - amount_not_sent)
  184. -- print((7000*100)/(0.7*100))
  185. local full_cost = math.floor((amount_sent*100)/(eff*100))
  186. assert(total_energy:get_count() > full_cost)
  187. local energy_remaining = total_energy:take_item(full_cost)
  188. inv:set_stack("buffer", 1, energy_remaining)
  189. end
  190. end
  191. ::the_end::
  192. -- Determine if we should enter sleep mode, or keep running.
  193. if getgood or putgood then
  194. keeprunning = true
  195. end
  196. if invalidconfig then
  197. keeprunning = false
  198. end
  199. meta:set_string("infotext", conv2.compose_infotext(pos, tiera, tierb, invalidconfig, keeprunning))
  200. if keeprunning then
  201. minetest.get_node_timer(pos):start(1.0)
  202. else
  203. minetest.get_node_timer(pos):start(math.random(1, 60*3))
  204. end
  205. end
  206. conv2.on_construct =
  207. function(pos)
  208. end
  209. conv2.after_place_node =
  210. function(pos, placer, itemstack, pointed_thing)
  211. local meta = minetest.get_meta(pos)
  212. local node = minetest.get_node(pos)
  213. local owner = placer:get_player_name()
  214. local inv = meta:get_inventory()
  215. meta:set_string("owner", owner)
  216. meta:set_string("nodename", node.name)
  217. inv:set_size("buffer", 1)
  218. inv:set_size("config", 1)
  219. net2.clear_caches(pos, owner, "lv")
  220. net2.clear_caches(pos, owner, "mv")
  221. net2.clear_caches(pos, owner, "hv")
  222. meta:set_string("formspec", conv2.compose_formspec(pos))
  223. meta:set_string("infotext", conv2.compose_infotext(pos, "", "", true, false))
  224. nodestore.add_node(pos)
  225. local timer = minetest.get_node_timer(pos)
  226. timer:start(1.0)
  227. end
  228. conv2.on_blast =
  229. function(pos)
  230. local drops = {}
  231. default.get_inventory_drops(pos, "config", drops)
  232. drops[#drops+1] = "conv2:converter"
  233. minetest.remove_node(pos)
  234. return drops
  235. end
  236. conv2.allow_metadata_inventory_put =
  237. function(pos, listname, index, stack, player)
  238. if minetest.test_protection(pos, player:get_player_name()) then
  239. return 0
  240. end
  241. if listname == "config" and stack:get_name() == "cfg:dev" then
  242. return stack:get_count()
  243. end
  244. return 0
  245. end
  246. conv2.allow_metadata_inventory_move =
  247. function(pos, from_list, from_index, to_list, to_index, count, player)
  248. return 0
  249. end
  250. conv2.allow_metadata_inventory_take =
  251. function(pos, listname, index, stack, player)
  252. if minetest.test_protection(pos, player:get_player_name()) then
  253. return 0
  254. end
  255. if listname == "config" then
  256. return stack:get_count()
  257. end
  258. return 0
  259. end
  260. conv2.on_metadata_inventory_move =
  261. function(pos)
  262. conv2.trigger_update(pos)
  263. end
  264. conv2.on_metadata_inventory_put =
  265. function(pos)
  266. conv2.trigger_update(pos)
  267. end
  268. conv2.on_metadata_inventory_take =
  269. function(pos, listname, index, stack, player)
  270. conv2.trigger_update(pos)
  271. end
  272. conv2.on_destruct =
  273. function(pos)
  274. local meta = minetest.get_meta(pos)
  275. local owner = meta:get_string("owner")
  276. net2.clear_caches(pos, owner, "lv")
  277. net2.clear_caches(pos, owner, "mv")
  278. net2.clear_caches(pos, owner, "hv")
  279. nodestore.del_node(pos)
  280. end
  281. if not conv2.run_once then
  282. minetest.register_node(":conv2:converter", {
  283. description = "Voltage Transformer\n\nThis machine requires a WR Config Device to configure it.\nThe configurator should point to adjacent cable boxes.",
  284. tiles = {
  285. "converter_top.png", "converter_top.png",
  286. "converter_side.png", "converter_side.png",
  287. "converter_side.png", "converter_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 = "conv2:converter",
  294. on_energy_put = function(...)
  295. return conv2.on_energy_put(...) end,
  296. on_rotate = function(...)
  297. return screwdriver.rotate_simple(...) end,
  298. allow_metadata_inventory_put = function(...)
  299. return conv2.allow_metadata_inventory_put(...) end,
  300. allow_metadata_inventory_move = function(...)
  301. return conv2.allow_metadata_inventory_move(...) end,
  302. allow_metadata_inventory_take = function(...)
  303. return conv2.allow_metadata_inventory_take(...) end,
  304. on_metadata_inventory_move = function(...)
  305. return conv2.on_metadata_inventory_move(...) end,
  306. on_metadata_inventory_put = function(...)
  307. return conv2.on_metadata_inventory_put(...) end,
  308. on_metadata_inventory_take = function(...)
  309. return conv2.on_metadata_inventory_take(...) end,
  310. on_punch = function(...)
  311. return conv2.on_punch(...) end,
  312. can_dig = function(...)
  313. return conv2.can_dig(...) end,
  314. on_timer = function(...)
  315. return conv2.on_timer(...) end,
  316. on_construct = function(...)
  317. return conv2.on_construct(...) end,
  318. on_destruct = function(...)
  319. return conv2.on_destruct(...) end,
  320. on_blast = function(...)
  321. return conv2.on_blast(...) end,
  322. after_place_node = function(...)
  323. return conv2.after_place_node(...) end,
  324. })
  325. local c = "conv2:core"
  326. local f = conv2.modpath .. "/conv2.lua"
  327. reload.register_file(c, f, false)
  328. conv2.run_once = true
  329. end