--[[ cable_NS1 -> One connection from north to south cable_NW1_ES1 -> One connection from north to west, and another from east to south cable_NWE8_S8 -> One connection between north, west and east, 8bit single cable from south cable_0 -> The one cable without connection --]] local nodebox_single = { {-0.0625, -0.5, 0.25, 0.0625, -0.375, 0.5}, {-0.125, -0.5, 0.25, 0.125, -0.25, 0.5} } local nodebox_straight = { {-0.0625, -0.5, -0.5, 0.0625, -0.375, 0.5}, {-0.125, -0.5, -0.5, 0.125, -0.25, 0.5} } local nodeboxes_corner = { { {-0.5, -0.5, -0.0625, 0.0625, -0.375, 0.0625}, -- NodeBox1 {-0.0625, -0.5, 0.0625, 0.0625, -0.375, 0.5}, -- NodeBox2 }, { {-0.5, -0.5, -0.125, 0.125, -0.25, 0.125}, -- NodeBox1 {-0.125, -0.5, 0.125, 0.125, -0.25, 0.5}, -- NodeBox2 } } local nodeboxes_jump = { { {-0.5, -0.5, -0.0625, -0.1875, -0.375, 0.0625}, -- NodeBox2 {0.1875, -0.5, -0.0625, 0.5, -0.375, 0.0625}, -- NodeBox3 {-0.3125, -0.1875, -0.0625, 0.3125, -0.0625, 0.0625}, -- NodeBox4 {-0.3125, -0.375, -0.0625, -0.1875, -0.1875, 0.0625}, -- NodeBox5 {0.1875, -0.375, -0.0625, 0.3125, -0.1875, 0.0625}, -- NodeBox6 }, { {-0.5, -0.5, -0.125, -0.1875, -0.25, 0.125}, -- NodeBox2 {0.1875, -0.5, -0.125, 0.5, -0.25, 0.125}, -- NodeBox3 {-0.4375, -0.1875, -0.125, 0.4375, 0.0625, 0.125}, -- NodeBox4 {-0.4375, -0.25, -0.125, -0.1875, -0.1875, 0.125}, -- NodeBox5 {0.1875, -0.25, -0.125, 0.4375, -0.1875, 0.125}, -- NodeBox6 } } local nodeboxes_ccorner = { { {-0.5, -0.5, -0.0625, -0.1875, -0.375, 0.0625}, -- NodeBox1 {-0.0625, -0.5, 0.1875, 0.0625, -0.375, 0.5}, -- NodeBox2 {-0.3125, -0.5, 0.0625, -0.1875, -0.375, 0.3125}, -- NodeBox3 {-0.1875, -0.5, 0.1875, -0.0625, -0.375, 0.3125}, -- NodeBox4 }, { {-0.5, -0.5, -0.125, -0.125, -0.25, 0.125}, -- NodeBox1 {-0.125, -0.5, 0.125, 0.125, -0.25, 0.5}, -- NodeBox2 {-0.375, -0.5, 0.125, -0.125, -0.25, 0.375}, -- NodeBox4 } } local nodeboxes_tri = { { {-0.5, -0.5, -0.0625, 0.5, -0.375, 0.0625}, -- NodeBox1 {-0.0625, -0.5, 0.0625, 0.0625, -0.375, 0.5}, -- NodeBox2 }, { {-0.5, -0.5, -0.125, 0.5, -0.25, 0.125}, -- NodeBox1 {-0.125, -0.5, 0.125, 0.125, -0.25, 0.5}, -- NodeBox2 } } local nodeboxes_cross = { { {-0.5, -0.5, -0.0625, 0.5, -0.375, 0.0625}, -- NodeBox1 {-0.0625, -0.5, 0.0625, 0.0625, -0.375, 0.5}, -- NodeBox2 {-0.0625, -0.5, -0.5, 0.0625, -0.375, -0.0625}, -- NodeBox3 }, { {-0.5, -0.5, -0.125, 0.5, -0.25, 0.125}, -- NodeBox1 {-0.125, -0.5, 0.125, 0.125, -0.25, 0.5}, -- NodeBox2 {-0.125, -0.5, -0.5, 0.125, -0.25, -0.125}, -- NodeBox3 } } local nodebox_disconnected = {-0.125, -0.5, -0.125, 0.125, -0.25, 0.125} local function rotateNodebox(nb,rot) return (math.fmod(rot,4)==0) and {nb[1],nb[2],nb[3],nb[4],nb[5],nb[6]} or (math.fmod(rot,4)==1) and {nb[3],nb[2],-nb[1],nb[6],nb[5],-nb[4]} or (math.fmod(rot,4)==2) and {-nb[1],nb[2],-nb[3],-nb[4],nb[5],-nb[6]} or (math.fmod(rot,4)==3) and {-nb[3],nb[2],nb[1],-nb[6],nb[5],nb[4]} or nb -- Should not happen end local function rotate4dir(conn,r) local function rotate4dirOnce(conn) return math.floor(conn/2) + 8*math.fmod(conn,2) end local x = math.fmod(conn,16) for i=1,r do x = rotate4dirOnce(x) end return (conn - math.fmod(conn,16) + x) end local function constArray(val,size) local t = {} for i=1,size do table.insert(t,val) end return t end --[[ name: the name of the cable nodeboxes: All the rendered nodeboxes connections: A list of connections between NSEW (N=8,E=4,S=2,W=1), +16 when it is 8bit ex: {4+2,16+1} -> ES + W8 nbconn: Which correspond each nodebox correspond to ex: {1,1,2,1} -> nodeboxes 1,2,3 correspond to connection ES, and nodebox 2 correspond to connection W --]] logikraft.cablesnb = {} logikraft.cablesconn = {} logikraft.cablesnbconn = {} local function createCables(name,nodeboxes,connections,nbconn) minetest.register_node("logikraft:cable_"..name, { tiles = { "cable_gray.png", "cable_gray.png", "cable_gray.png", "cable_gray.png", "cable_gray.png", "cable_gray.png", }, drawtype = "nodebox", paramtype = "light", node_box = { type = "fixed", fixed = nodeboxes }, groups = {circuitry = 1,dig_immediate = 3} }) if name == "EW8_N1_S1" then print(dump(connections)) end -- We sort the connections and nbconn local connections2 = table.copy(connections) table.sort(connections2) local perm = table.arrperm(connections,connections2) local nbconn2 = {} for i,v in ipairs(nbconn) do nbconn2[i] = perm[v] end if name == "EW8_N1_S1" then print(dump(connections2)) end logikraft.cablesnb[name] = nodeboxes logikraft.cablesconn[name] = connections2 logikraft.cablesnbconn[name] = nbconn2 end -- cable_NSEW0 for v=1,2 do createCables("NSEW"..tostring((v-1)*7+1),nodeboxes_cross[v],{(v-1)*16+8+4+2+1},constArray(1,#nodeboxes_cross[v])) end --[ -- cable_NW0_SE0 -- cable_NE0_SW0 -- cable_NS0_EW0 for v0=1,2 do for v1=1,2 do local nodeboxes = {} local nbconn = {} for _,nb in ipairs(nodeboxes_ccorner[v0]) do table.insert(nodeboxes, nb) table.insert(nbconn, 1) end for _,nb in ipairs(nodeboxes_ccorner[v1]) do table.insert(nodeboxes, rotateNodebox(nb,2)) table.insert(nbconn, 2) end createCables("NW"..tostring((v0-1)*7+1).."_SE"..tostring((v1-1)*7+1),nodeboxes,{(v0-1)*16+8+1,(v1-1)*16+4+2},nbconn) local nodeboxes = {} local nbconn = {} for _,nb in ipairs(nodeboxes_ccorner[v0]) do table.insert(nodeboxes, rotateNodebox(nb,1)) table.insert(nbconn, 1) end for _,nb in ipairs(nodeboxes_ccorner[v1]) do table.insert(nodeboxes, rotateNodebox(nb,3)) table.insert(nbconn, 2) end createCables("NE"..tostring((v0-1)*7+1).."_SW"..tostring((v1-1)*7+1),nodeboxes,{(v0-1)*16+8+4,(v1-1)*16+2+1},nbconn) local nodeboxes = {} local nbconn = {} table.insert(nodeboxes, nodebox_straight[v0]) table.insert(nbconn, 1) for _,nb in ipairs(nodeboxes_jump[v1]) do table.insert(nodeboxes, rotateNodebox(nb,2)) table.insert(nbconn, 2) end createCables("NS"..tostring((v0-1)*7+1).."_EW"..tostring((v1-1)*7+1),nodeboxes,{(v0-1)*16+8+2,(v1-1)*16+4+1},nbconn) end end -- cable_AB0_C0_D0 -- ("NW","NE","SE","SW") * (/ + C0 + D0 + C0D0) -- cable_AB0_C0_D0 -- ("NS" "EW") * (/ + C0 + D0 + C0D0) for v=1,2 do for v1=0,2 do for v2=0,2 do for r,rn in ipairs({{"NW","E","S"},{"NE","S","W"},{"SE","W","N"},{"SW","N","E"}}) do local nodeboxes = {} local nbconn = {} local connz = {rotate4dir((v-1)*16+8+1,r-1)} for _,nb in ipairs(nodeboxes_corner[v]) do table.insert(nodeboxes, rotateNodebox(nb,r-1)) table.insert(nbconn, 1) end if v1 ~= 0 then table.insert(nodeboxes, rotateNodebox(nodebox_single[v1],r)) table.insert(nbconn, 2) table.insert(connz,rotate4dir((v1-1)*16+4,r-1)) end if v2 ~= 0 then table.insert(nodeboxes, rotateNodebox(nodebox_single[v2],r+1)) table.insert(nbconn, v1==0 and 2 or 3) table.insert(connz,rotate4dir((v2-1)*16+2,r-1)) end createCables( rn[1]..tostring((v-1)*7+1).. (v1~=0 and ("_"..rn[2]..tostring((v1-1)*7+1)) or "").. (v2~=0 and ("_"..rn[3]..tostring((v2-1)*7+1)) or "") ,nodeboxes,connz,nbconn ) end for r,rn in ipairs({{"NS","E","W"},{"EW","N","S"}}) do local nodeboxes = {} local nbconn = {} local connz = {rotate4dir((v-1)*16+8+2,r-1)} table.insert(nodeboxes, rotateNodebox(nodebox_straight[v],r-1)) table.insert(nbconn, 1) if v1 ~= 0 then table.insert(nodeboxes, rotateNodebox(nodebox_single[v1],r)) table.insert(nbconn, 2) table.insert(connz,rotate4dir((v1-1)*16+4,r-1)) end if v2 ~= 0 then table.insert(nodeboxes, rotateNodebox(nodebox_single[v2],r+2)) table.insert(nbconn, v1==0 and 2 or 3) table.insert(connz,rotate4dir((v2-1)*16+1,r-1)) end createCables( rn[1]..tostring((v-1)*7+1).. (v1~=0 and ("_"..rn[2]..tostring((v1-1)*7+1)) or "").. (v2~=0 and ("_"..rn[3]..tostring((v2-1)*7+1)) or ""), nodeboxes,connz,nbconn ) end end end end -- "cable_A0_B0_C0_D0" -- (n s e w ns ...) for v1=0,2 do for v2=0,2 do for v3=0,2 do for v4=0,2 do local nodeboxes = {} local nbconn = {} local name = "" local connz = {} if v1 ~= 0 then table.insert(nodeboxes, rotateNodebox(nodebox_single[v1],0)) table.insert(nbconn, 1) table.insert(connz,(v1-1)*16+8) name = name.."_N"..tostring((v1-1)*7+1) end if v2 ~= 0 then table.insert(nodeboxes, rotateNodebox(nodebox_single[v2],1)) table.insert(nbconn, #nbconn+1) table.insert(connz,(v2-1)*16+4) name = name.."_E"..tostring((v2-1)*7+1) end if v3 ~= 0 then table.insert(nodeboxes, rotateNodebox(nodebox_single[v3],2)) table.insert(nbconn, #nbconn+1) table.insert(connz,(v3-1)*16+2) name = name.."_S"..tostring((v3-1)*7+1) end if v4 ~= 0 then table.insert(nodeboxes, rotateNodebox(nodebox_single[v4],3)) table.insert(nbconn, #nbconn+1) table.insert(connz,(v4-1)*16+1) name = name.."_W"..tostring((v4-1)*7+1) end 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 end end end end -- "cable_ABC0_D0" -- ("NEW","NES","ESW","SWN") * (/ + D0) for v=1,2 do for v1=0,2 do for r,rn in ipairs({{"NEW","S"},{"NES","W"},{"ESW","N"},{"SWN","E"}}) do local nodeboxes = {} local nbconn = {} local connz = {rotate4dir((v-1)*16+8+4+1,r-1)} for _,nb in ipairs(nodeboxes_tri[v]) do table.insert(nodeboxes, rotateNodebox(nb,r-1)) table.insert(nbconn, 1) end if v1 ~= 0 then table.insert(nodeboxes, rotateNodebox(nodebox_single[v1],r+1)) table.insert(nbconn, 2) table.insert(connz,rotate4dir((v1-1)*16+2,r-1)) end createCables( rn[1]..tostring((v-1)*7+1).. (v1~=0 and ("_"..rn[2]..tostring((v1-1)*7+1)) or ""), nodeboxes,connz,nbconn ) end end end --]] logikraft.cablesfromconn = table.invert(logikraft.cablesconn) function logikraft.rotateCable(name,r) local conn = logikraft.cablesconn[name] local newconn = {} for i,v in ipairs(conn) do newconn[i] = rotate4dir(v,r) end table.sort(newconn) return table.getkey1(logikraft.cablesconn,newconn) end function logikraft.connectInCable(name,a,b) local conns = table.copy(logikraft.cablesconn[name]) local cia = logikraft.cablesnbconn[name][a] local cib = logikraft.cablesnbconn[name][b] local conna = conns[cia] local connb = conns[cib] -- If mismatch, v is that of firstly selected cable local v = math.fmod(math.floor(conna/16),2) conns[cia] = math.fmod(conna,16) + math.fmod(connb,16) + v*16 table.remove(conns,cib) table.sort(conns) 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] local conn = conns[cindex] table.remove(conns,cindex) if not (conn == 1 or conn == 2 or conn == 4 or conn == 8 or conn == 17 or conn == 18 or conn == 20 or conn == 24) then -- The connection was more than one-sided, so we recreate the «tips» if math.fmod(math.floor(conn/1),2)==1 then table.insert(conns,conn>=16 and 17 or 1) end if math.fmod(math.floor(conn/2),2)==1 then table.insert(conns,conn>=16 and 18 or 2) end if math.fmod(math.floor(conn/4),2)==1 then table.insert(conns,conn>=16 and 20 or 4) end if math.fmod(math.floor(conn/8),2)==1 then table.insert(conns,conn>=16 and 24 or 8) end end table.sort(conns) return table.getkey1(logikraft.cablesconn,conns) end