conv2.lua 9.9 KB

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