From 3d9944921f5af34290e0598acfb9567d760886db Mon Sep 17 00:00:00 2001 From: Samy Avrillon Date: Sat, 18 May 2024 20:06:53 +0200 Subject: [PATCH] Rewrite of the linker --- blocks/cable.lua | 81 +++++++++++++++++++++++++++--- items.lua | 92 +++++++++++++++++++++++++++------- textures/linker_activated.png | Bin 0 -> 4652 bytes 3 files changed, 148 insertions(+), 25 deletions(-) create mode 100644 textures/linker_activated.png diff --git a/blocks/cable.lua b/blocks/cable.lua index 3bdeece..3e0ba85 100644 --- a/blocks/cable.lua +++ b/blocks/cable.lua @@ -294,14 +294,11 @@ for v4=0,2 do table.insert(connz,(v4-1)*16+1) name = name.."_W"..tostring((v4-1)*7+1) end - if name == "" then - table.insert(nodeboxes, nodebox_disconnected) - table.insert(nbconn, 1) - table.insert(connz,(v1-1)*16+0) -- special case of no connection - name = "_zero" + if name ~= "" then + -- Else there is no connection, we don't have to create a cable + createCables(string.sub(name,2,-1),nodeboxes,connz,nbconn) end - createCables(string.sub(name,2,-1),nodeboxes,connz,nbconn) end end @@ -364,6 +361,78 @@ function logikraft.connectInCable(name,a,b) return table.getkey1(logikraft.cablesconn,conns) end +function logikraft.connFromDir(name,dir) + local conns = logikraft.cablesconn[name] + local dir8 = math.pow(2,dir) + for i,c in ipairs(conns) + do + if (math.fmod(c,2*dir8) - dir8 >= 0) + then return i + end + end + return nil +end + +--[[ + Returns {newcablea,newcableb} if the two cables are contiguous + Returns nil otherwise +--]] +function logikraft.connectContiguousCable(namea,posa,a,nameb,posb,b) + local dira = (posa.y == posb.y) and ( + (posa.z + 1 == posb.z and posa.x == posb.x and 3) or + (posa.x + 1 == posb.x and posa.z == posb.z and 2) or + (posa.z - 1 == posb.z and posa.x == posb.x and 1) or + (posa.x - 1 == posb.x and posa.z == posb.z and 0) or + nil) or nil + if dira == nil + then return nil + end + + local connsa = table.copy(logikraft.cablesconn[namea]) + local connsb = table.copy(logikraft.cablesconn[nameb]) + local cia = logikraft.cablesnbconn[namea][a] + local cib = logikraft.cablesnbconn[nameb][b] + local cia2 = logikraft.connFromDir(namea,dira) + local cib2 = logikraft.connFromDir(nameb,3 - dira) + print(dira) + print(cia) + print(cia2) + print(cib) + print(cib2) + + + -- (nba == nil) -> Need to add dira to the a + -- (a == nba) -> Already connected + -- (a ~= nba) -> Need to connect a and nbas + if (cia2 == nil) + then + connsa[cia] = connsa[cia] + math.pow(2,dira) + elseif (a ~= cia2) + then + -- We take the v size of selected cable + local v = math.fmod(math.floor(connsa[cia]/16),2) + connsa[cia] = math.fmod(connsa[cia],16) + math.fmod(connsa[cia2],16) + v*16 + table.remove(connsa,cia2) + end + + if (cib2 == nil) + then + connsb[cib] = connsb[cib] + math.pow(2,3-dira) + elseif (b ~= cib2) + then + -- We take the v size of selected cable + local v = math.fmod(math.floor(connsb[cib]/16),2) + connsb[cib] = math.fmod(connsb[cib],16) + math.fmod(connsb[cib2],16) + v*16 + table.remove(connsb,cib2) + end + + + table.sort(connsa) + table.sort(connsb) + return {table.getkey1(logikraft.cablesconn,connsa),table.getkey1(logikraft.cablesconn,connsb)} + +end + function logikraft.disconnectInCable(name,a) local conns = table.copy(logikraft.cablesconn[name]) local cindex = logikraft.cablesnbconn[name][a] diff --git a/items.lua b/items.lua index 6781253..77da851 100644 --- a/items.lua +++ b/items.lua @@ -16,28 +16,79 @@ minetest.register_craftitem("logikraft:linker", { description = "The linker", inventory_image = "linker.png", on_place = function(itemstack, user, pointed_thing) + local meta = itemstack:get_meta() local node = minetest.get_node(pointed_thing.under) - if not string.startsWith(node.name,"logikraft:cable_") - then return itemstack - end - - local index = logikraft.lookingAtNbIndex(user,pointed_thing.under) - - -- We check if we clicked the last selected node - local meta = minetest.get_meta(pointed_thing.under) - if meta:get_int("logikraft:last_selected_nb") ~= 0 + if meta:get_int("logikraft:selected_nb") ~= 0 then - -- We connect - local firsti = meta:get_int("logikraft:last_selected_nb") - local new = logikraft.connectInCable(string.without(node.name,"logikraft:cable_"),firsti,index) - minetest.swap_node(pointed_thing.under, {name = "logikraft:cable_" .. new}) - - -- We destroy the saved selected nb - meta:set_int("logikraft:last_selected_nb",0) + local selectednb = meta:get_int("logikraft:selected_nb") + local selectedx = meta:get_int("logikraft:selected_x") + local selectedy = meta:get_int("logikraft:selected_y") + local selectedz = meta:get_int("logikraft:selected_z") + local selectedpos = {x = selectedx, y = selectedy, z = selectedz} + if string.startsWith(node.name,"logikraft:cable_") + then + if selectedx == pointed_thing.under.x and selectedy == pointed_thing.under.y and selectedz == pointed_thing.under.z + then + local thisnb = logikraft.lookingAtNbIndex(user,pointed_thing.under) + if(selectednb ~= thisnb) + then + local new = logikraft.connectInCable(string.without(node.name,"logikraft:cable_"),selectednb,thisnb) + minetest.swap_node(pointed_thing.under, {name = "logikraft:cable_" .. new}) + end + meta:set_int("logikraft:selected_nb",0) + meta:set_string("inventory_image","linker.png") + else + local thisnb = logikraft.lookingAtNbIndex(user,pointed_thing.under) + local new = logikraft.connectContiguousCable( + string.without(node.name,"logikraft:cable_"),selectedpos,selectednb, + string.without(minetest.get_node(pointed_thing.under).name,"logikraft:cable_"),pointed_thing.under,thisnb) + if new + then + minetest.swap_node(selectedpos, {name = "logikraft:cable_" .. new[1]}) + minetest.swap_node(pointed_thing.under, {name = "logikraft:cable_" .. new[2]}) + meta:set_int("logikraft:selected_nb",0) + meta:set_string("inventory_image","linker.png") + else + minetest.chat_send_all("Les cables sont trop loins l'un de l'autre :/") + end + end + else + local node_def = minetest.registered_nodes[minetest.get_node(pointed_thing.above).name] + if not node_def or not node_def.buildable_to then + -- Then we cannot build here + return itemstack + end + minetest.add_node(pointed_thing.above, {name = "logikraft:cable_NSEW1"}) + meta:set_int("logikraft:selected_nb",0) + meta:set_string("inventory_image","linker.png") + end else - -- We save the selected nb - meta:set_int("logikraft:last_selected_nb",index) + if string.startsWith(node.name,"logikraft:cable_") + then + -- If we are looking at a cable we activate and store data + meta:set_int("logikraft:selected_nb",logikraft.lookingAtNbIndex(user,pointed_thing.under)) + meta:set_int("logikraft:selected_x",pointed_thing.under.x) + meta:set_int("logikraft:selected_y",pointed_thing.under.y) + meta:set_int("logikraft:selected_z",pointed_thing.under.z) + meta:set_string("inventory_image","linker_activated.png") + else + -- Else we place a cable + local node_def = minetest.registered_nodes[minetest.get_node(pointed_thing.above).name] + if not node_def or not node_def.buildable_to then + -- Then we cannot build here + return itemstack + end + minetest.add_node(pointed_thing.above, {name = "logikraft:cable_NSEW1"}) + end end + + return itemstack + end, + on_secondary_use = function(itemstack, user, pointed_thing) + -- Looking at nothing -> we dispose of the data + local meta = itemstack:get_meta() + meta:set_int("logikraft:selected_nb",0) + meta:set_string("inventory_image","linker.png") return itemstack end }) @@ -53,7 +104,10 @@ minetest.register_craftitem("logikraft:unlinker", { local index = logikraft.lookingAtNbIndex(user,pointed_thing.under) local new = logikraft.disconnectInCable(string.without(node.name,"logikraft:cable_"),index) - minetest.swap_node(pointed_thing.under, {name = "logikraft:cable_" .. new}) + if new + then minetest.swap_node(pointed_thing.under, {name = "logikraft:cable_" .. new}) + else minetest.remove_node(pointed_thing.under) + end return itemstack end diff --git a/textures/linker_activated.png b/textures/linker_activated.png new file mode 100644 index 0000000000000000000000000000000000000000..50185fb72f4a8fb796a487f6ffe0c6b10715b63e GIT binary patch literal 4652 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 literal 0 HcmV?d00001