470 lines
15 KiB
Lua
470 lines
15 KiB
Lua
--[[
|
|
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])
|
|
print(dump(connsa))
|
|
print(dump(connsb))
|
|
local cia = logikraft.cablesnbconn[namea][a]
|
|
local cib = logikraft.cablesnbconn[nameb][b]
|
|
local cia2 = logikraft.connFromDir(namea,dira)
|
|
local cib2 = logikraft.connFromDir(nameb,math.fmod(dira+2,4))
|
|
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 (cia ~= 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,math.fmod(dira+2,4))
|
|
elseif (cib ~= 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
|
|
|
|
function logikraft.resizeInCable(name,a)
|
|
local conns = table.copy(logikraft.cablesconn[name])
|
|
local cindex = logikraft.cablesnbconn[name][a]
|
|
|
|
conns[cindex] = (conns[cindex] >= 16) and (conns[cindex] - 16) or (conns[cindex] + 16)
|
|
|
|
table.sort(conns)
|
|
return table.getkey1(logikraft.cablesconn,conns)
|
|
end |