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 0000000..50185fb Binary files /dev/null and b/textures/linker_activated.png differ