conv2.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  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. --minetest.chat_send_player("MustTest", "# Server: On Timer! " .. minetest.get_gametime())
  132. local keeprunning = false
  133. local meta = minetest.get_meta(pos)
  134. local inv = meta:get_inventory()
  135. local owner = meta:get_string("owner")
  136. local needflush = false
  137. local invalidconfig = false
  138. local putgood = false
  139. local getgood = false
  140. local gooda, posa, tiera, owna = conv2.get_config_data(pos, "p1")
  141. local goodb, posb, tierb, ownb = conv2.get_config_data(pos, "p2")
  142. if not gooda or not goodb then
  143. invalidconfig = true
  144. goto the_end
  145. end
  146. -- Tiers cannot be same.
  147. if tiera == tierb then
  148. invalidconfig = true
  149. goto the_end
  150. end
  151. -- Check if we need to discharge energy.
  152. do -- Scoped local variable to prevent problems with goto.
  153. local curstack = inv:get_stack("buffer", 1)
  154. if curstack:get_count() >= BUFFER_SIZE then
  155. needflush = true
  156. end
  157. end
  158. -- Draw energy from network above only if not needing a flush.
  159. if not needflush then
  160. local toget = ENERGY_AMOUNT
  161. local energy = net2.get_energy(posa, owna, toget, tiera)
  162. local estack = ItemStack("atomic:energy " .. energy)
  163. inv:add_item("buffer", estack)
  164. if energy >= toget then
  165. getgood = true -- We were able to get wanted amount of energy.
  166. end
  167. end
  168. -- Discharge energy into network below.
  169. if needflush then
  170. -- There should be at least BUFFER_SIZE energy in inventory.
  171. local total_energy = inv:get_stack("buffer", 1)
  172. local eff = efficiency[tiera][tierb]
  173. local amount_to_send = math_floor(total_energy:get_count() * eff)
  174. local amount_not_sent = net2.put_energy(posb, ownb, amount_to_send, tierb)
  175. -- 3 possible cases.
  176. if amount_not_sent == amount_to_send then
  177. -- No energy could be stored in the network.
  178. -- Don't change energy buffered.
  179. elseif amount_not_sent == 0 then
  180. -- All energy sent was stored in the network.
  181. inv:set_stack("buffer", 1, ItemStack(""))
  182. putgood = true
  183. else
  184. -- Energy was only partially stored.
  185. assert(amount_not_sent < amount_to_send)
  186. assert(amount_not_sent > 0)
  187. local amount_sent = (amount_to_send - amount_not_sent)
  188. -- print((7000*100)/(0.7*100))
  189. local full_cost = math_floor((amount_sent*100)/(eff*100))
  190. assert(total_energy:get_count() >= full_cost)
  191. total_energy:take_item(full_cost)
  192. inv:set_stack("buffer", 1, total_energy)
  193. end
  194. end
  195. ::the_end::
  196. -- Determine if we should enter sleep mode, or keep running.
  197. if getgood or putgood then
  198. keeprunning = true
  199. end
  200. if invalidconfig then
  201. keeprunning = false
  202. end
  203. meta:set_string("infotext", conv2.compose_infotext(pos, tiera, tierb, invalidconfig, keeprunning))
  204. if keeprunning then
  205. minetest.get_node_timer(pos):start(1.0)
  206. else
  207. minetest.get_node_timer(pos):start(math_random(1, 60*3))
  208. end
  209. end
  210. conv2.on_construct =
  211. function(pos)
  212. end
  213. conv2.after_place_node =
  214. function(pos, placer, itemstack, pointed_thing)
  215. local meta = minetest.get_meta(pos)
  216. local node = minetest.get_node(pos)
  217. local owner = placer:get_player_name()
  218. local inv = meta:get_inventory()
  219. meta:set_string("owner", owner)
  220. meta:set_string("nodename", node.name)
  221. inv:set_size("buffer", 1)
  222. inv:set_size("config", 1)
  223. net2.clear_caches(pos, owner, "lv")
  224. net2.clear_caches(pos, owner, "mv")
  225. net2.clear_caches(pos, owner, "hv")
  226. meta:set_string("formspec", conv2.compose_formspec(pos))
  227. meta:set_string("infotext", conv2.compose_infotext(pos, "", "", true, false))
  228. nodestore.add_node(pos)
  229. local timer = minetest.get_node_timer(pos)
  230. timer:start(1.0)
  231. end
  232. conv2.on_blast =
  233. function(pos)
  234. local drops = {}
  235. default.get_inventory_drops(pos, "config", drops)
  236. drops[#drops+1] = "conv2:converter"
  237. minetest.remove_node(pos)
  238. return drops
  239. end
  240. conv2.allow_metadata_inventory_put =
  241. function(pos, listname, index, stack, player)
  242. if minetest.test_protection(pos, player:get_player_name()) then
  243. return 0
  244. end
  245. if listname == "config" and stack:get_name() == "cfg:dev" then
  246. return stack:get_count()
  247. end
  248. return 0
  249. end
  250. conv2.allow_metadata_inventory_move =
  251. function(pos, from_list, from_index, to_list, to_index, count, player)
  252. return 0
  253. end
  254. conv2.allow_metadata_inventory_take =
  255. function(pos, listname, index, stack, player)
  256. if minetest.test_protection(pos, player:get_player_name()) then
  257. return 0
  258. end
  259. if listname == "config" then
  260. return stack:get_count()
  261. end
  262. return 0
  263. end
  264. conv2.on_metadata_inventory_move =
  265. function(pos)
  266. conv2.trigger_update(pos)
  267. end
  268. conv2.on_metadata_inventory_put =
  269. function(pos)
  270. conv2.trigger_update(pos)
  271. end
  272. conv2.on_metadata_inventory_take =
  273. function(pos, listname, index, stack, player)
  274. conv2.trigger_update(pos)
  275. end
  276. conv2.on_destruct =
  277. function(pos)
  278. local meta = minetest.get_meta(pos)
  279. local owner = meta:get_string("owner")
  280. net2.clear_caches(pos, owner, "lv")
  281. net2.clear_caches(pos, owner, "mv")
  282. net2.clear_caches(pos, owner, "hv")
  283. nodestore.del_node(pos)
  284. end
  285. if not conv2.run_once then
  286. minetest.register_node(":conv2:converter", {
  287. description = "Voltage Transformer\n\nThis machine requires a WR Config Device to configure it.\nThe configurator should point to adjacent cable boxes.",
  288. tiles = {
  289. "converter_top.png", "converter_top.png",
  290. "converter_side.png", "converter_side.png",
  291. "converter_side.png", "converter_side.png",
  292. },
  293. groups = utility.dig_groups("machine"),
  294. paramtype2 = "facedir",
  295. is_ground_content = false,
  296. sounds = default.node_sound_metal_defaults(),
  297. drop = "conv2:converter",
  298. on_energy_put = function(...)
  299. return conv2.on_energy_put(...) end,
  300. on_rotate = function(...)
  301. return screwdriver.rotate_simple(...) end,
  302. allow_metadata_inventory_put = function(...)
  303. return conv2.allow_metadata_inventory_put(...) end,
  304. allow_metadata_inventory_move = function(...)
  305. return conv2.allow_metadata_inventory_move(...) end,
  306. allow_metadata_inventory_take = function(...)
  307. return conv2.allow_metadata_inventory_take(...) end,
  308. on_metadata_inventory_move = function(...)
  309. return conv2.on_metadata_inventory_move(...) end,
  310. on_metadata_inventory_put = function(...)
  311. return conv2.on_metadata_inventory_put(...) end,
  312. on_metadata_inventory_take = function(...)
  313. return conv2.on_metadata_inventory_take(...) end,
  314. on_punch = function(...)
  315. return conv2.on_punch(...) end,
  316. can_dig = function(...)
  317. return conv2.can_dig(...) end,
  318. on_timer = function(...)
  319. return conv2.on_timer(...) end,
  320. on_construct = function(...)
  321. return conv2.on_construct(...) end,
  322. on_destruct = function(...)
  323. return conv2.on_destruct(...) end,
  324. on_blast = function(...)
  325. return conv2.on_blast(...) end,
  326. after_place_node = function(...)
  327. return conv2.after_place_node(...) end,
  328. })
  329. local c = "conv2:core"
  330. local f = conv2.modpath .. "/conv2.lua"
  331. reload.register_file(c, f, false)
  332. conv2.run_once = true
  333. end