mesecons_x/mesecons_autowire/auto_wire.lua
2020-07-19 02:09:39 +02:00

260 lines
5.7 KiB
Lua

mesecons_autowire.pos1 = nil
mesecons_autowire.pos2 = nil
-- a bit of a weld (TODO: fix that)
function is_circuit_element(pos)
local node = minetest.get_node(pos)
local name = node.name
local m = string.match(name,"^mesecons_")
if m ~= nil then
return true
else
return false
end
end
local function put_node(pos,node)
minetest.set_node(pos,node)
mesecon.on_placenode(pos,node)
end
function get_neigh_pins(p)
return {
u = get_pins_sticky( { x=p.x, y=p.y, z=p.z+1 } ).d,
d = get_pins_sticky( { x=p.x, y=p.y, z=p.z-1 } ).u,
l = get_pins_sticky( { x=p.x-1, y=p.y, z=p.z } ).r,
r = get_pins_sticky( { x=p.x+1, y=p.y, z=p.z } ).l
}
end
local map2 = {
{{"mesecons_insulated:insulated_off",1}, {u=1,d=0,l=0,r=0}},
{{"mesecons_insulated:insulated_off",1}, {u=0,d=1,l=0,r=0}},
{{"mesecons_insulated:insulated_off",0}, {u=0,d=0,l=1,r=0}},
{{"mesecons_insulated:insulated_off",0}, {u=0,d=0,l=0,r=1}},
}
function pins_to_wire(pins)
for _,v in ipairs(mesecons_autowire.map) do
local p = v[2]
local name = v[1][1]
local param2 = v[1][2]
if( eq_pins(p,pins) ) then
return { name = name, param2 = param2 }
end
end
for _,v in ipairs(map2) do
local p = v[2]
local name = v[1][1]
local param2 = v[1][2]
if( eq_pins(p,pins) ) then
return { name = name, param2 = param2 }
end
end
return {name ="air" }
end
function merge(pos,direc)
local node = minetest.get_node(pos)
local name = node.name
local param2 = node.param2
if( (not is_wire(pos)) and (not (name == "air") )) then return end
-- exception (dont change)
if ( name == "mesecons_extrawires:crossover_off" ) or
( name == "mesecons_extrawires:crossover_on") or
( name == "mesecons_extrawires:crossover_10") or
( name == "mesecons_extrawires:crossover_01")
then
return
end
-- end of exception
local pins = and_pins(get_pins(pos),get_neigh_pins(pos))
local final_pins = or_pins(pins, direc_to_pin(direc))
local node = pins_to_wire(final_pins)
put_node(pos,node)
end
function merge_start(pos,direction_from)
merge(pos,direction_from)
end
function merge_end(pos,direction_from)
if( direction_from == "u" ) then
merge(pos,"d")
elseif( direction_from == "d" ) then
merge(pos,"u")
elseif( direction_from == "l" ) then
merge(pos,"r")
elseif( direction_from == "r" ) then
merge(pos,"l")
end
end
function jump(pos,direc)
local node = minetest.get_node(pos)
local name = node.name
local param2 = node.param2
if( name == "mesecons_insulated:insulated_off" or name == "mesecons_insulated:insulated_on" ) then
if( direc == "u" or direc == "d" ) then
if( param2 == 0 or param2 == 2 ) then
put_node(pos, {name ="mesecons_extrawires:crossover_off"});
elseif ( param2 == 1 or param2 == 3) then
--nothing
end
elseif( direc == "l" or direc == "r" ) then
if( param2 == 0 or param2 == 2 ) then
--nothing
elseif ( param2 == 1 or param2 == 3) then
put_node(pos, {name ="mesecons_extrawires:crossover_off"});
end
end
end
if( name == "air" ) then
if( direc == "u" or direc == "d" ) then
put_node(pos, {name ="mesecons_insulated:insulated_off",param2=1});
elseif( direc == "l" or direc == "r" ) then
put_node(pos, {name ="mesecons_insulated:insulated_off",param2=0});
end
end
end
function next_pos(pos,direc)
local p = pos
if( direc == "u" ) then
p.z = p.z + 1
elseif( direc == "d" ) then
p.z = p.z - 1
elseif( direc == "l" ) then
p.x = p.x -1
elseif( direc == "r" ) then
p.x = p.x + 1
end
return p
end
function eq_pos(p1,p2)
if( (p1.x==p2.x) and (p1.y==p2.y) and (p1.z==p2.z) ) then
return true
else
return false
end
end
function make_wire(p1,p2,direc)
local current = p1
merge_start(current,direc)
current = next_pos(current,direc)
while(not eq_pos(current,p2)) do
jump(current,direc)
current = next_pos(current,direc)
end
merge_end(current,direc)
end
function do_work()
if(not mesecons_autowire.pos1 ) then
return false
end
if(not mesecons_autowire.pos2 ) then
return false
end
local pos1 = mesecons_autowire.pos1
local pos2 = mesecons_autowire.pos2
if( pos1.y~=pos2.y) then
return false
end
if( (pos1.x==pos2.x) and (pos1.z==pos2.z) ) then
return false
end
if( (pos1.x~=pos2.x) and (pos1.z~=pos2.z) ) then
return false
end
local direc = ""
if( pos1.z == pos2.z ) then
if( pos1.x < pos2.x ) then
direc = "r"
else
direc = "l"
end
elseif( pos1.x == pos2.x ) then
if( pos1.z < pos2.z ) then
direc = "u"
else
direc = "d"
end
end
if( direc == "" ) then return end
make_wire(pos1,pos2,direc)
return true
end
minetest.register_craftitem("mesecons_autowire:wire", {
description = "Tool Autowire",
inventory_image = "tool_autowire.png",
stack_max = 1,
groups = { tool =1 },
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then return end
local node_pos = pointed_thing.under
if( is_circuit_element(node_pos) ) then
mesecons_autowire.pos1 = node_pos
else
mesecons_autowire.pos1 = pointed_thing.above
end
end,
on_place = function(itemstack, user, pointed_thing)
if not pointed_thing then return end
if pointed_thing.type ~= "node" then return end
local node_pos = pointed_thing.under
if( is_circuit_element(node_pos) ) then
mesecons_autowire.pos2 = node_pos
else
mesecons_autowire.pos2 = pointed_thing.above
end
if (do_work()) then
mesecons_autowire.pos1 = mesecons_autowire.pos2
mesecons_autowire.pos2 = nil
end
end
})