tube_test.lua 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. --[[
  2. Tube Library 2
  3. ==============
  4. Copyright (C) 2017-2020 Joachim Stolberg
  5. LGPLv2.1+
  6. See LICENSE.txt for more information
  7. tube_test.lua
  8. THIS FILE IS ONLY FOR TESTING PURPOSES
  9. ]]--
  10. -- for lazy programmers
  11. local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
  12. local S2P = minetest.string_to_pos
  13. local M = minetest.get_meta
  14. -- Marker entities for debugging purposes
  15. local function debug_info(pos, text)
  16. local marker = minetest.add_entity(pos, "tubelib2:marker_cube")
  17. if marker ~= nil then
  18. if text == "add" then
  19. marker:set_nametag_attributes({color = "#FF0000", text = "add__________"})
  20. elseif text == "del" then
  21. marker:set_nametag_attributes({color = "#00FF00", text = "_____del_____"})
  22. elseif text == "noc" then
  23. marker:set_nametag_attributes({color = "#0000FF", text = "__________noc"})
  24. end
  25. minetest.after(6, marker.remove, marker)
  26. end
  27. end
  28. minetest.register_entity(":tubelib2:marker_cube", {
  29. initial_properties = {
  30. visual = "cube",
  31. textures = {
  32. "tubelib2_marker_cube.png",
  33. "tubelib2_marker_cube.png",
  34. "tubelib2_marker_cube.png",
  35. "tubelib2_marker_cube.png",
  36. "tubelib2_marker_cube.png",
  37. "tubelib2_marker_cube.png",
  38. },
  39. physical = false,
  40. visual_size = {x = 1.1, y = 1.1},
  41. collisionbox = {-0.55,-0.55,-0.55, 0.55,0.55,0.55},
  42. glow = 8,
  43. },
  44. on_punch = function(self)
  45. self.object:remove()
  46. end,
  47. })
  48. -- Test tubes
  49. local Tube = tubelib2.Tube:new({
  50. -- North, East, South, West, Down, Up
  51. -- dirs_to_check = {1,2,3,4}, -- horizontal only
  52. -- dirs_to_check = {5,6}, -- vertical only
  53. dirs_to_check = {1,2,3,4,5,6},
  54. max_tube_length = 10,
  55. show_infotext = true,
  56. primary_node_names = {"tubelib2:tubeS", "tubelib2:tubeA"},
  57. secondary_node_names = {"default:chest", "default:chest_open",
  58. "tubelib2:source", "tubelib2:junction", "tubelib2:teleporter"},
  59. after_place_tube = function(pos, param2, tube_type, num_tubes, tbl)
  60. minetest.swap_node(pos, {name = "tubelib2:tube"..tube_type, param2 = param2})
  61. end,
  62. --debug_info = debug_info,
  63. })
  64. Tube:set_valid_sides("tubelib2:source", {"F"})
  65. Tube:set_valid_sides("tubelib2:teleporter", {"F"})
  66. Tube:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir)
  67. local sdir = tubelib2.dir_to_string(out_dir)
  68. if not peer_pos then
  69. print(P2S(pos).." to the "..sdir..": Not connected")
  70. elseif Tube:is_secondary_node(peer_pos) then
  71. local node = minetest.get_node(peer_pos)
  72. print(P2S(pos).." to the "..sdir..": Connected with "..node.name.." at "..P2S(peer_pos).."/"..peer_in_dir)
  73. else
  74. print(P2S(pos).." to the "..sdir..": Connected with "..P2S(peer_pos).."/"..peer_in_dir)
  75. for i, pos, node in Tube:get_tube_line(pos, out_dir) do
  76. print("walk", P2S(pos), node.name)
  77. end
  78. end
  79. end)
  80. minetest.register_node("tubelib2:tubeS", {
  81. description = "Tubelib2 Test tube",
  82. tiles = { -- Top, base, right, left, front, back
  83. "tubelib2_tube.png",
  84. "tubelib2_tube.png",
  85. "tubelib2_tube.png",
  86. "tubelib2_tube.png",
  87. "tubelib2_hole.png",
  88. "tubelib2_hole.png",
  89. },
  90. after_place_node = function(pos, placer, itemstack, pointed_thing)
  91. --local t = minetest.get_us_time()
  92. if not Tube:after_place_tube(pos, placer, pointed_thing) then
  93. minetest.remove_node(pos)
  94. return true
  95. end
  96. --print("place time", minetest.get_us_time() - t)
  97. return false
  98. end,
  99. after_dig_node = function(pos, oldnode, oldmetadata, digger)
  100. Tube:after_dig_tube(pos, oldnode, oldmetadata)
  101. end,
  102. paramtype2 = "facedir", -- important!
  103. drawtype = "nodebox",
  104. node_box = {
  105. type = "fixed",
  106. fixed = {
  107. {-2/8, -2/8, -4/8, 2/8, 2/8, 4/8},
  108. },
  109. },
  110. on_rotate = screwdriver.disallow, -- important!
  111. paramtype = "light",
  112. sunlight_propagates = true,
  113. is_ground_content = false,
  114. groups = {crumbly = 3, cracky = 3, snappy = 3},
  115. sounds = default.node_sound_glass_defaults(),
  116. })
  117. minetest.register_node("tubelib2:tubeA", {
  118. description = "Tubelib2 Test tube",
  119. tiles = { -- Top, base, right, left, front, back
  120. "tubelib2_tube.png",
  121. "tubelib2_hole.png",
  122. "tubelib2_tube.png",
  123. "tubelib2_tube.png",
  124. "tubelib2_tube.png",
  125. "tubelib2_hole.png",
  126. },
  127. after_dig_node = function(pos, oldnode, oldmetadata, digger)
  128. Tube:after_dig_tube(pos, oldnode, oldmetadata)
  129. end,
  130. paramtype2 = "facedir", -- important!
  131. drawtype = "nodebox",
  132. node_box = {
  133. type = "fixed",
  134. fixed = {
  135. {-2/8, -4/8, -2/8, 2/8, 2/8, 2/8},
  136. {-2/8, -2/8, -4/8, 2/8, 2/8, -2/8},
  137. },
  138. },
  139. on_rotate = screwdriver.disallow, -- important!
  140. paramtype = "light",
  141. sunlight_propagates = true,
  142. is_ground_content = false,
  143. groups = {crumbly = 3, cracky = 3, snappy = 3, not_in_creative_inventory=1},
  144. sounds = default.node_sound_glass_defaults(),
  145. drop = "tubelib2:tubeS",
  146. })
  147. local function push_item(pos)
  148. local tube_dir = M(pos):get_int("tube_dir")
  149. local dest_pos, dest_dir = Tube:get_connected_node_pos(pos, tube_dir)
  150. local dest_node = minetest.get_node(dest_pos)
  151. local on_push_item = minetest.registered_nodes[dest_node.name].on_push_item
  152. --print("on_timer: dest_pos="..S(dest_pos).." dest_dir="..dest_dir)
  153. local inv = minetest.get_inventory({type="node", pos=dest_pos})
  154. local stack = ItemStack("default:dirt")
  155. if on_push_item then
  156. return on_push_item(dest_pos, dest_dir, stack)
  157. elseif inv then
  158. local leftover = inv:add_item("main", stack)
  159. if leftover:get_count() == 0 then
  160. return true
  161. end
  162. elseif dest_node.name == "air" then
  163. minetest.add_item(dest_pos, stack)
  164. return true
  165. end
  166. return false
  167. end
  168. minetest.register_node("tubelib2:source", {
  169. description = "Tubelib2 Item Source",
  170. tiles = {
  171. -- up, down, right, left, back, front
  172. 'tubelib2_source.png',
  173. 'tubelib2_source.png',
  174. 'tubelib2_source.png',
  175. 'tubelib2_source.png',
  176. 'tubelib2_source.png',
  177. 'tubelib2_conn.png',
  178. },
  179. after_place_node = function(pos, placer)
  180. local tube_dir = ((minetest.dir_to_facedir(placer:get_look_dir()) + 2) % 4) + 1
  181. M(pos):set_int("tube_dir", tube_dir)
  182. Tube:after_place_node(pos, {tube_dir})
  183. minetest.get_node_timer(pos):start(2)
  184. end,
  185. after_dig_node = function(pos, oldnode, oldmetadata, digger)
  186. local tube_dir = tonumber(oldmetadata.fields.tube_dir or 0)
  187. Tube:after_dig_node(pos, {tube_dir})
  188. end,
  189. on_timer = function(pos, elapsed)
  190. if not push_item(pos) then
  191. print("push_item error")
  192. end
  193. return true
  194. end,
  195. paramtype2 = "facedir", -- important!
  196. on_rotate = screwdriver.disallow, -- important!
  197. paramtype = "light",
  198. sunlight_propagates = true,
  199. is_ground_content = false,
  200. groups = {crumbly = 3, cracky = 3, snappy = 3},
  201. sounds = default.node_sound_glass_defaults(),
  202. })
  203. -- Can't be used for item transport (hyperloop test node)
  204. minetest.register_node("tubelib2:junction", {
  205. description = "Tubelib2 Junction",
  206. tiles = {
  207. 'tubelib2_conn.png',
  208. },
  209. after_place_node = function(pos, placer, itemstack, pointed_thing)
  210. local meta = minetest.get_meta(pos)
  211. meta:set_string("infotext", "Position "..P2S(pos))
  212. Tube:after_place_node(pos)
  213. end,
  214. after_dig_node = function(pos, oldnode, oldmetadata, digger)
  215. Tube:after_dig_node(pos)
  216. end,
  217. paramtype2 = "facedir", -- important!
  218. on_rotate = screwdriver.disallow, -- important!
  219. paramtype = "light",
  220. sunlight_propagates = true,
  221. is_ground_content = false,
  222. groups = {crumbly = 3, cracky = 3, snappy = 3},
  223. sounds = default.node_sound_glass_defaults(),
  224. })
  225. -------------------------------------------------------------------------------
  226. -- Teleporter
  227. -------------------------------------------------------------------------------
  228. local pairingList = {}
  229. local sFormspec = "size[7.5,3]"..
  230. "field[0.5,1;7,1;channel;Enter channel string;]" ..
  231. "button_exit[2,2;3,1;exit;Save]"
  232. local function store_connection(pos, peer_pos)
  233. local meta = M(pos)
  234. meta:set_string("peer_pos", P2S(peer_pos))
  235. meta:set_string("channel", "")
  236. meta:set_string("formspec", "")
  237. meta:set_string("infotext", "Connected with "..P2S(peer_pos))
  238. end
  239. local function prepare_pairing(pos)
  240. local meta = M(pos)
  241. meta:set_string("peer_pos", "")
  242. meta:set_string("channel", "")
  243. meta:set_string("formspec", sFormspec)
  244. meta:set_string("infotext", "Pairing is missing")
  245. end
  246. local function pairing(pos, channel)
  247. if pairingList[channel] and not vector.equals(pos, pairingList[channel]) then
  248. -- store peer position on both nodes
  249. local peer_pos = pairingList[channel]
  250. store_connection(pos, peer_pos)
  251. store_connection(peer_pos, pos)
  252. pairingList[channel] = nil
  253. return true
  254. else
  255. pairingList[channel] = pos
  256. prepare_pairing(pos)
  257. return false
  258. end
  259. end
  260. local function stop_pairing(pos, oldmetadata)
  261. -- unpair peer node
  262. if oldmetadata and oldmetadata.fields then
  263. if oldmetadata.fields.peer_pos then
  264. local peer_pos = S2P(oldmetadata.fields.peer_pos)
  265. prepare_pairing(peer_pos)
  266. elseif oldmetadata.fields.channel then
  267. pairingList[oldmetadata.fields.channel] = nil
  268. end
  269. end
  270. end
  271. minetest.register_node("tubelib2:teleporter", {
  272. description = "Tubelib2 Teleporter",
  273. tiles = {
  274. -- up, down, right, left, back, front
  275. 'tubelib2_tele.png',
  276. 'tubelib2_tele.png',
  277. 'tubelib2_tele.png',
  278. 'tubelib2_tele.png',
  279. 'tubelib2_tele.png',
  280. 'tubelib2_conn.png',
  281. },
  282. after_place_node = function(pos, placer)
  283. -- the tube_dir calculation depends on the player look-dir and the hole side of the node
  284. local tube_dir = ((minetest.dir_to_facedir(placer:get_look_dir()) + 2) % 4) + 1
  285. M(pos):set_int("tube_dir", tube_dir)
  286. Tube:after_place_node(pos, {tube_dir})
  287. prepare_pairing(pos)
  288. end,
  289. on_receive_fields = function(pos, formname, fields, player)
  290. if fields.channel ~= nil then
  291. pairing(pos, fields.channel)
  292. end
  293. end,
  294. on_push_item = function(pos, dir, item)
  295. local tube_dir = M(pos):get_int("tube_dir")
  296. if dir == tubelib2.Turn180Deg[tube_dir] then
  297. local s = M(pos):get_string("peer_pos")
  298. if s and s ~= "" then
  299. push_item(S2P(s))
  300. return true
  301. end
  302. end
  303. end,
  304. after_dig_node = function(pos, oldnode, oldmetadata, digger)
  305. stop_pairing(pos, oldmetadata)
  306. local tube_dir = tonumber(oldmetadata.fields.tube_dir or 0)
  307. Tube:after_dig_node(pos, {tube_dir})
  308. end,
  309. paramtype2 = "facedir", -- important!
  310. on_rotate = screwdriver.disallow, -- important!
  311. paramtype = "light",
  312. sunlight_propagates = true,
  313. is_ground_content = false,
  314. groups = {crumbly = 3, cracky = 3, snappy = 3},
  315. sounds = default.node_sound_glass_defaults(),
  316. })
  317. -------------------------------------------------------------------------------
  318. -- Tool
  319. -------------------------------------------------------------------------------
  320. local function read_param2(pos, player)
  321. local node = minetest.get_node(pos)
  322. local dir1, dir2, num_tubes = Tube:decode_param2(pos, node.param2)
  323. minetest.chat_send_player(player:get_player_name(), "[Tubelib2] pos="..P2S(pos)..", dir1="..dir1..", dir2="..dir2..", num_tubes="..num_tubes)
  324. end
  325. local function remove_tube(itemstack, placer, pointed_thing)
  326. if pointed_thing.type == "node" then
  327. local pos = pointed_thing.under
  328. if placer:get_player_control().sneak then
  329. read_param2(pos, placer)
  330. else
  331. Tube:tool_remove_tube(pos, "default_break_glass")
  332. end
  333. else
  334. local dir = (minetest.dir_to_facedir(placer:get_look_dir()) % 4) + 1
  335. minetest.chat_send_player(placer:get_player_name(),
  336. "[Tool Help] dir="..dir.."\n"..
  337. " left: remove node\n"..
  338. " right: repair tube line\n")
  339. end
  340. end
  341. --local function walk(itemstack, placer, pointed_thing)
  342. -- if pointed_thing.type == "node" then
  343. -- local pos = pointed_thing.under
  344. -- local dir = (minetest.dir_to_facedir(placer:get_look_dir()) % 4) + 1
  345. -- local t = minetest.get_us_time()
  346. -- local pos1, outdir1, pos2, outdir2, cnt = Tube:walk(pos, dir)
  347. -- t = minetest.get_us_time() - t
  348. -- print("time", t)
  349. -- if pos1 then
  350. -- local s = "[Tubelib2] pos1="..P2S(pos1)..", outdir1="..outdir1..", pos2="..P2S(pos2)..", outdir2="..outdir2..", cnt="..cnt
  351. -- minetest.chat_send_player(placer:get_player_name(), s)
  352. -- end
  353. -- else
  354. -- local dir = (minetest.dir_to_facedir(placer:get_look_dir()) % 4) + 1
  355. -- minetest.chat_send_player(placer:get_player_name(),
  356. -- "[Tool Help] dir="..dir.."\n"..
  357. -- " left: remove node\n"..
  358. -- " right: repair tube line\n")
  359. -- end
  360. --end
  361. local function repair_tube(itemstack, placer, pointed_thing)
  362. if pointed_thing.type == "node" then
  363. local pos = pointed_thing.under
  364. local _, _, fpos1, fpos2, _, _, cnt1, cnt2 = Tube:tool_repair_tube(pos)
  365. local length = cnt1 + cnt2
  366. local s = "Tube from " .. P2S(fpos1) .. " to " .. P2S(fpos2) .. ". Lenght = " .. length
  367. minetest.chat_send_player(placer:get_player_name(), s)
  368. if length > Tube.max_tube_length then
  369. local s = string.char(0x1b) .. "(c@#ff0000)" .. "Tube length error!"
  370. minetest.chat_send_player(placer:get_player_name(), s)
  371. end
  372. minetest.sound_play("carts_cart_new", {
  373. pos = pos,
  374. gain = 1,
  375. max_hear_distance = 5})
  376. else
  377. local dir = (minetest.dir_to_facedir(placer:get_look_dir()) % 4) + 1
  378. minetest.chat_send_player(placer:get_player_name(),
  379. "[Tool Help] dir="..dir.."\n"..
  380. " left: remove node\n"..
  381. " right: repair tube line\n")
  382. end
  383. end
  384. -- Tool for tube workers to crack a protected tube line
  385. minetest.register_node("tubelib2:tool", {
  386. description = "Tubelib2 Tool",
  387. inventory_image = "tubelib2_tool.png",
  388. wield_image = "tubelib2_tool.png",
  389. use_texture_alpha = true,
  390. groups = {cracky=1, book=1},
  391. on_use = remove_tube,
  392. on_place = repair_tube,
  393. node_placement_prediction = "",
  394. stack_max = 1,
  395. })