2020-09-04 16:20:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
function get_node_from_pins(pins)
|
|
|
|
local t = "mesecons_extrawires:tjunction_off"
|
|
|
|
local c = "mesecons_extrawires:corner_off"
|
|
|
|
local w = "mesecons_insulated:insulated_off"
|
|
|
|
local a = "air"
|
|
|
|
local x = "mesecons_morewires:xjunction_off"
|
|
|
|
|
|
|
|
-- {left,up,right,down node_name, rotation}
|
|
|
|
local list = {
|
|
|
|
-- empty
|
|
|
|
{0,0,0,0,a,0},
|
|
|
|
|
|
|
|
-- wire
|
|
|
|
{1,0,1,0,w,0},
|
|
|
|
{0,1,0,1,w,1},
|
|
|
|
|
|
|
|
-- corner
|
|
|
|
{1,0,0,1,c,0},
|
|
|
|
{1,1,0,0,c,1},
|
|
|
|
{0,1,1,0,c,2},
|
|
|
|
{0,0,1,1,c,3},
|
|
|
|
|
|
|
|
-- tjunction
|
|
|
|
{1,0,1,1,t,0},
|
|
|
|
{1,1,0,1,t,1},
|
|
|
|
{1,1,1,0,t,2},
|
|
|
|
{0,1,1,1,t,3},
|
|
|
|
|
|
|
|
-- xjunction
|
|
|
|
{1,1,1,1,x,0},
|
|
|
|
|
|
|
|
-- starting wire
|
|
|
|
{1,0,0,0,w,0},
|
|
|
|
{0,1,0,0,w,1},
|
|
|
|
{0,0,1,0,w,0},
|
|
|
|
{0,0,0,1,w,1},
|
|
|
|
}
|
|
|
|
|
|
|
|
local node_name = "air"
|
|
|
|
local rotate = 0
|
|
|
|
for _,v in ipairs(list) do
|
|
|
|
if (pins[1] == v[1]) and
|
|
|
|
(pins[2] == v[2]) and
|
|
|
|
(pins[3] == v[3]) and
|
|
|
|
(pins[4] == v[4]) then
|
|
|
|
|
|
|
|
node_name = v[5]
|
|
|
|
rotate = v[6]
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
return { name = node_name, param2 = rotate }
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function get_pins_from_pos(pos,type)
|
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
|
|
|
|
local rs = {}
|
|
|
|
if type == "input" then
|
|
|
|
rs = mesecon.get_any_inputrules(node)
|
|
|
|
elseif type == "output" then
|
|
|
|
rs = mesecon.get_any_outputrules(node)
|
|
|
|
else
|
|
|
|
rs = mesecon.get_any_rules(node)
|
|
|
|
end
|
|
|
|
if rs == nil then
|
|
|
|
rs = {}
|
|
|
|
else
|
|
|
|
rs = mesecon.flattenrules (rs)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- Filter only y=0
|
|
|
|
local list = {}
|
|
|
|
for _,v in pairs(rs) do
|
|
|
|
if v.y == 0 then
|
|
|
|
if v.x ~= 0 and v.z == 0 then
|
|
|
|
table.insert(list,v)
|
|
|
|
end
|
|
|
|
if v.z ~= 0 and v.x == 0 then
|
|
|
|
table.insert(list,v)
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- constructiong pin structure
|
|
|
|
|
|
|
|
local pins = {0,0,0,0}
|
|
|
|
for _,v in pairs(list) do
|
|
|
|
if v.x == 1 then pins[3] = 1 end
|
|
|
|
if v.x == -1 then pins[1] = 1 end
|
|
|
|
if v.z == 1 then pins[2] = 1 end
|
|
|
|
if v.z == -1 then pins[4] = 1 end
|
|
|
|
end
|
|
|
|
return pins
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-01-05 13:20:08 +01:00
|
|
|
function dir_to_inx(d)
|
2020-09-04 16:20:32 +02:00
|
|
|
if d.x == 1 then return 3 end
|
|
|
|
if d.x == -1 then return 1 end
|
|
|
|
if d.z == 1 then return 2 end
|
|
|
|
if d.z == -1 then return 4 end
|
|
|
|
return 1
|
|
|
|
end
|
|
|
|
|
|
|
|
function get_pin_from_direction(direction)
|
|
|
|
return dir_to_inx(direction)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function neighbours_pins(pos)
|
|
|
|
local npins = {0,0,0,0}
|
|
|
|
for _,ix in ipairs({1,-1}) do
|
|
|
|
|
|
|
|
local shift = { x=ix,y=0,z=0 }
|
|
|
|
local neigh = vector.add(pos,shift)
|
|
|
|
|
|
|
|
local pins = get_pins_from_pos(neigh)
|
|
|
|
npins[ dir_to_inx( shift) ] = pins [ dir_to_inx( vector.multiply(shift,-1) ) ]
|
|
|
|
end
|
|
|
|
for _,iz in ipairs({1,-1}) do
|
|
|
|
|
|
|
|
local shift = { x=0,y=0,z=iz }
|
|
|
|
local neigh = vector.add(pos,shift)
|
|
|
|
|
|
|
|
local pins = get_pins_from_pos(neigh)
|
|
|
|
npins[ dir_to_inx( shift) ] = pins [ dir_to_inx( vector.multiply(shift,-1) ) ]
|
|
|
|
end
|
|
|
|
return npins
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function pins_and(pins1,pins2)
|
|
|
|
local pout = {}
|
|
|
|
for i=1,4,1 do
|
|
|
|
pout[i] = pins1[i] * pins2[i]
|
|
|
|
end
|
|
|
|
return pout
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function start_node(pos,direction)
|
|
|
|
|
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
local name = node.name
|
|
|
|
|
|
|
|
-- Only wires changed
|
|
|
|
local list = {
|
|
|
|
"mesecons_insulated:insulated_off","mesecons_insulated:insulated_on",
|
|
|
|
"mesecons_extrawires:corner_off","mesecons_extrawires:corner_on",
|
|
|
|
"mesecons_extrawires:tjunction_off", "mesecons_extrawires:tjunction_on",
|
|
|
|
"air"
|
|
|
|
}
|
|
|
|
|
|
|
|
if not is_in_list(list,name) then return end
|
|
|
|
|
|
|
|
|
|
|
|
local npins = neighbours_pins(pos)
|
|
|
|
local mypins = get_pins_from_pos(pos)
|
|
|
|
local compins = pins_and(npins,mypins)
|
|
|
|
|
|
|
|
-- adding wire
|
|
|
|
|
|
|
|
if direction.x == 1 then
|
|
|
|
compins[3] = 1
|
|
|
|
end
|
|
|
|
if direction.x == -1 then
|
|
|
|
compins[1] = 1
|
|
|
|
end
|
|
|
|
|
|
|
|
if direction.z == 1 then
|
|
|
|
compins[2] = 1
|
|
|
|
end
|
|
|
|
if direction.z == -1 then
|
|
|
|
compins[4] = 1
|
|
|
|
end
|
|
|
|
|
|
|
|
--merge_wire(pos,direction)
|
|
|
|
local new_node = get_node_from_pins(compins)
|
|
|
|
|
|
|
|
--minetest.set_node(pos,new_node)
|
|
|
|
mesecons_autotools.set_node(pos,new_node,"start_node")
|
|
|
|
end
|
|
|
|
|
|
|
|
local function end_node(pos,direction)
|
|
|
|
--merge_wire(pos, vector.multiply(direction, -1))
|
|
|
|
start_node(pos, vector.multiply(direction,-1))
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function middle_node(pos, direction)
|
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
local name = node.name
|
|
|
|
local param2 = node.param2
|
|
|
|
|
|
|
|
--minetest.set_node(pos,{name = "default:dirt"})
|
|
|
|
--if true then return end
|
|
|
|
|
|
|
|
if name ~= "mesecons_insulated:insulated_off" and
|
|
|
|
name ~= "mesecons_insulated:insulated_on" and
|
|
|
|
name ~= "air" then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
-- do crossing
|
|
|
|
if name == "air" then
|
|
|
|
local prm2 = 0
|
|
|
|
if direction.z ~= 0 then
|
|
|
|
prm2 = 1
|
|
|
|
end
|
|
|
|
if direction.x ~= 0 then
|
|
|
|
prm2 = 0
|
|
|
|
end
|
|
|
|
--minetest.set_node(pos, { name ="mesecons_insulated:insulated_off", param2= 1 } )
|
|
|
|
mesecons_autotools.set_node(pos,
|
|
|
|
{name ="mesecons_insulated:insulated_off", param2= prm2 },
|
|
|
|
"middle_node")
|
|
|
|
|
|
|
|
else
|
|
|
|
-- if nothing to do
|
|
|
|
if (direction.x ~= 0 ) and
|
|
|
|
( param2 == 0 or param2 == 2 ) then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if (direction.z ~= 0 ) and
|
|
|
|
(param2 == 1 or param2 == 3 ) then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
--minetest.set_node(pos,{ name ="mesecons_extrawires:crossover_off" } )
|
|
|
|
mesecons_autotools.set_node(pos,
|
|
|
|
{ name ="mesecons_extrawires:crossover_off" },
|
|
|
|
"middle_node")
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function create_straight_wire_n(pos,direction,size)
|
|
|
|
local current = pos
|
|
|
|
|
|
|
|
-- first
|
|
|
|
start_node(current,direction)
|
|
|
|
current = vector.add(current,direction)
|
|
|
|
|
|
|
|
-- middle
|
|
|
|
for i = 2, size-1, 1 do
|
|
|
|
middle_node(current,direction)
|
|
|
|
current = vector.add(current,direction)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
-- last
|
|
|
|
end_node(current,direction)
|
|
|
|
end
|
|
|
|
|
|
|
|
local function distance_taxi_metric(pos1,pos2)
|
|
|
|
local x1 = pos1.x
|
|
|
|
local x2 = pos2.x
|
|
|
|
|
|
|
|
local dx = math.abs(x2-x1)
|
|
|
|
|
|
|
|
local z1 = pos1.z
|
|
|
|
local z2 = pos2.z
|
|
|
|
|
|
|
|
local dz = math.abs(z2-z1)
|
|
|
|
|
|
|
|
return dz+dx+1
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function create_straight_wire(pos1,pos2)
|
|
|
|
|
|
|
|
-- Check if straight line
|
|
|
|
if pos1.y ~= pos2.y then return end
|
|
|
|
if (pos1.x ~= pos2.x ) and (pos1.z ~= pos2.z) then return end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Compute direction
|
|
|
|
local direction = { x =0,y=0,z=0}
|
|
|
|
if pos1.x == pos2.x then
|
|
|
|
if pos1.z < pos2.z then
|
|
|
|
direction.z = 1
|
|
|
|
else
|
|
|
|
direction.z = -1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if pos1.z == pos2.z then
|
|
|
|
if pos1.x < pos2.x then
|
|
|
|
direction.x = 1
|
|
|
|
else
|
|
|
|
direction.x = -1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- Compute size
|
|
|
|
local size = distance_taxi_metric(pos1,pos2)
|
|
|
|
|
|
|
|
|
|
|
|
create_straight_wire_n(pos1,direction,size)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function hop_pos(pos,pin)
|
|
|
|
local new_pos = { x = pos.x, y = pos.y, z = pos.z }
|
|
|
|
|
|
|
|
if pin == 1 then
|
|
|
|
new_pos.x = pos.x - 1
|
|
|
|
end
|
|
|
|
if pin == 2 then
|
|
|
|
new_pos.z = pos.z + 1
|
|
|
|
end
|
|
|
|
if pin == 3 then
|
|
|
|
new_pos.x = pos.x + 1
|
|
|
|
end
|
|
|
|
if pin == 4 then
|
|
|
|
new_pos.z = pos.z -1
|
|
|
|
end
|
|
|
|
|
|
|
|
return new_pos
|
|
|
|
end
|
|
|
|
|
|
|
|
function flip_pin(pin)
|
|
|
|
if pin == 1 then return 3 end
|
|
|
|
if pin == 2 then return 4 end
|
|
|
|
if pin == 3 then return 1 end
|
|
|
|
if pin == 4 then return 2 end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- TODO: refactor
|
|
|
|
function hop_pin(pin)
|
|
|
|
if pin == 1 then return 3 end
|
|
|
|
if pin == 2 then return 4 end
|
|
|
|
if pin == 3 then return 1 end
|
|
|
|
if pin == 4 then return 2 end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function delete(p,pin)
|
|
|
|
local node = minetest.get_node(p)
|
|
|
|
local name = node.name
|
|
|
|
|
|
|
|
if name == "mesecons_insulated:insulated_off" or
|
|
|
|
name == "mesecons_insulated:insulated_on" or
|
|
|
|
name == "mesecons_extrawires:corner_off" or
|
|
|
|
name == "mesecons_extrawires:corner_on"
|
|
|
|
then
|
|
|
|
|
|
|
|
-- continue deleting
|
|
|
|
local node_pins = get_pins_from_pos(p)
|
|
|
|
|
|
|
|
-- not connected to anything
|
|
|
|
if node_pins[pin] == 0 then return end
|
|
|
|
|
|
|
|
node_pins[pin] = 0
|
|
|
|
for i=1,4,1 do
|
|
|
|
if node_pins[i] == 1 then
|
|
|
|
--minetest.set_node(p,{name="air"})
|
|
|
|
mesecons_autotools.set_node(p,{name="air"},"delete")
|
|
|
|
delete(hop_pos(p,i),hop_pin(i))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
elseif name == "mesecons_extrawires:crossover_off" or
|
|
|
|
name == "mesecons_extrawires:crossover_on" or
|
|
|
|
name == "mesecons_extrawires:crossover_10" or
|
|
|
|
name == "mesecons_extrawires:crossover_01" then
|
|
|
|
|
|
|
|
-- continue deleting
|
|
|
|
|
|
|
|
local node_pins = get_pins_from_pos(p)
|
|
|
|
node_pins[pin] = 0
|
|
|
|
node_pins[hop_pin(pin)] = 0
|
|
|
|
|
|
|
|
local new_node = get_node_from_pins(node_pins)
|
|
|
|
-- minetest.set_node(p,new_node)
|
|
|
|
mesecons_autotools.set_node(p,new_node,"delete_crossover")
|
|
|
|
delete(hop_pos(p,hop_pin(pin)),pin)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
elseif name == "mesecons_extrawires:tjunction_off" or
|
|
|
|
name == "mesecons_extrawires:tjunction_on" or
|
|
|
|
name == "mesecons_morewires:xjunction_off" or
|
|
|
|
name == "mesecons_morewires:xjunction_on" then
|
|
|
|
|
|
|
|
-- end of wire
|
|
|
|
|
|
|
|
local node_pins = get_pins_from_pos(p)
|
|
|
|
|
|
|
|
-- not connected to anything
|
|
|
|
if node_pins[pin] == 0 then return end
|
|
|
|
|
|
|
|
node_pins[pin] = 0
|
|
|
|
local new_node = get_node_from_pins(node_pins)
|
|
|
|
--minetest.set_node(p,new_node)
|
|
|
|
mesecons_autotools.set_node(p,new_node,"delete_end")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
-- do nothing (other blocks)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function delete_node(pos)
|
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
|
|
|
|
local pins = get_pins_from_pos(pos)
|
|
|
|
|
|
|
|
--minetest.set_node(pos,{name="air"})
|
|
|
|
mesecons_autotools.set_node(pos,{name="air"},"delete")
|
|
|
|
|
|
|
|
for i=1,4,1 do
|
|
|
|
if pins[i] == 1 then
|
|
|
|
delete(hop_pos(pos,i),hop_pin(i))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|