function is_in_selection(sel,p) local pos = {} pos[1] = sel.pos1 pos[2] = sel.pos2 if pos[1] == nil then return false end if pos[2] == nil then return false end local xmax = math.max(pos[1].x, pos[2].x) local xmin = math.min(pos[1].x, pos[2].x) local ymax = math.max(pos[1].y, pos[2].y) local ymin = math.min(pos[1].y, pos[2].y) local zmax = math.max(pos[1].z, pos[2].z) local zmin = math.min(pos[1].z, pos[2].z) local x = p.x local y = p.y local z = p.z if (xmin<=p.x) and (p.x<=xmax) and (ymin<=p.y) and (p.y<=ymax) and (zmin<=p.z) and (p.z<=zmax) then return true end return false end function is_in_layer(sel,p) local pos = {} pos[1] = sel.pos1 pos[2] = sel.pos2 local ymax = math.max(pos[1].y, pos[2].y) local ymin = math.min(pos[1].y, pos[2].y) if (p.y > ymax) or (p.y< ymin) then return false end return true end function is_in_tube(sel,p) if is_in_selection(sel,p) then return false end if not is_in_layer(sel,p) then return false end local pos = {} pos[1] = sel.pos1 pos[2] = sel.pos2 local xmax = math.max(pos[1].x, pos[2].x) local xmin = math.min(pos[1].x, pos[2].x) local ymax = math.max(pos[1].y, pos[2].y) local ymin = math.min(pos[1].y, pos[2].y) local zmax = math.max(pos[1].z, pos[2].z) local zmin = math.min(pos[1].z, pos[2].z) local x = p.x local y = p.y local z = p.z if (xmin <=x ) and (x<=xmax) then return true end if (zmin <=z) and (z<=zmax) then return true end return false end --[[ function is_in_wings(sel,p) if is_in_selection(sel,p) then return false end if not is_in_layer(sel,p) then return false end if is_in_tube(sel,p) then return false end return true end ]]-- function front_wall_tube(sel,p) local pos = {} pos[1] = sel.pos1 pos[2] = sel.pos2 local xmax = math.max(pos[1].x, pos[2].x) local xmin = math.min(pos[1].x, pos[2].x) local ymax = math.max(pos[1].y, pos[2].y) local ymin = math.min(pos[1].y, pos[2].y) local zmax = math.max(pos[1].z, pos[2].z) local zmin = math.min(pos[1].z, pos[2].z) local x = p.x local y = p.y local z = p.z local new_sel = {} local new_pos1 = vector.new(pos[1]) local new_pos2 = vector.new(pos[2]) local direction = {} if (xmin<=x) and (x<=xmax) then if (z > zmax) then direction.x = 0 direction.y = 0 direction.z = 1 new_pos1.z = zmax new_pos2.z = zmax else direction.x = 0 direction.y = 0 direction.z = -1 new_pos1.z = zmin new_pos2.z = zmin end end if (zmin<=z) and (z<=zmax) then if( x > xmax) then direction.x = 1 direction.y = 0 direction.z = 0 new_pos1.x = xmax new_pos2.x = xmax else direction.x = -1 direction.y = 0 direction.z = 0 new_pos1.x = xmin new_pos2.x = xmin end end new_sel.pos1 = new_pos1 new_sel.pos2 = new_pos2 return new_sel,direction end function tunel_direction(sel,pos) local wall,dir = front_wall_tube(sel,pos) return dir end function tunel_front_wall(sel,pos) local wall,dir = front_wall_tube(sel,pos) return wall end function is_dir_vertical(direction) if direction.z ~= 0 then return true end return false end function is_look_vertical(rad) local dir = radians_to_direction_looking_forward(rad) return is_dir_vertical(dir) end --[[ function is_dir_horizontal(direction) if direction.x ~= then return true end return false end ]]-- function front_wall_by_direction(sel,direction) local pos = {} pos[1] = sel.pos1 pos[2] = sel.pos2 local xmax = math.max(pos[1].x, pos[2].x) local xmin = math.min(pos[1].x, pos[2].x) local ymax = math.max(pos[1].y, pos[2].y) local ymin = math.min(pos[1].y, pos[2].y) local zmax = math.max(pos[1].z, pos[2].z) local zmin = math.min(pos[1].z, pos[2].z) local new_sel = {} local new_pos1 = vector.new(pos[1]) local new_pos2 = vector.new(pos[2]) if direction.x == 1 then new_pos1.x = xmax new_pos2.x = xmax end if direction.x == -1 then new_pos1.x = xmin new_pos2.x = xmin end if direction.z == 1 then new_pos1.z = zmax new_pos2.z = zmax end if direction.z == -1 then new_pos1.z = zmin new_pos2.z = zmin end if direction.y == 1 then new_pos1.y = ymax new_pos2.y = ymax end if direction.y == -1 then new_pos1.y = ymin new_pos2.y = ymin end new_sel.pos1 = new_pos1 new_sel.pos2 = new_pos2 return new_sel end --[[ function get_wing_cords(sel,p) local zero = {x =0,z=0} local cord if is_in_selection(sel,p) then return zero end if not is_in_layer(sel,p) then return zero end local pos = {} pos[1] = sel.pos1 pos[2] = sel.pos2 local xmax = math.max(pos[1].x, pos[2].x) local xmin = math.min(pos[1].x, pos[2].x) local ymax = math.max(pos[1].y, pos[2].y) local ymin = math.min(pos[1].y, pos[2].y) local zmax = math.max(pos[1].z, pos[2].z) local zmin = math.min(pos[1].z, pos[2].z) local x = p.x local y = p.y local z = p.z if (x>xmax) and (z>zmax) then cord = { x = 1, z = 1} end if (xzmax) then cord = {x = -1 , z = 1} end if (zxmax) then cord = { x = 1 , z = -1 } end if (z < zmin) and (x < xmin) then cord = { x -1 ,z = -1 } end return cord end ]]-- --[[ function front_wall_wing(sel,p,rad) local cord = get_wing_cords(sel,p) local wall_dir wall_dir.y = 0 if cord.x == 1 and cord.z == 1 then if is_look_vertical(rad) then wall_dir = {x=1,z=0} else wall_dir = {x=0,z=1} end end if cord.x == -1 and cord.z == 1 then if is_look_vertical(rad) then wall_dir = {x=-1,z=0} else wall_dir = {x=0,z=1} end end if cord.x == 1 and cord.z == -1 then if is_look_vertical(rad) then wall_dir = {x=1,z=0} else wall_dir = {x=0,z=-1} end end if cord.x == -1 and cord.z == -1 then if is_look_vertical(rad) then wall_dir = {x=-1,z=0} else wall_dir = {x=0,z=-1} end end local wall = front_wall_by_direction(wall_dir) return wall,wall_dir end ]]-- function distance_to_selection(sel,p,direction) local dist = 0 local pos = {} pos[1] = sel.pos1 pos[2] = sel.pos2 if not is_in_layer(sel,p) then return dist end --local direction = tunel_direction(sel,p) local xmax = math.max(pos[1].x, pos[2].x) local xmin = math.min(pos[1].x, pos[2].x) local ymax = math.max(pos[1].y, pos[2].y) local ymin = math.min(pos[1].y, pos[2].y) local zmax = math.max(pos[1].z, pos[2].z) local zmin = math.min(pos[1].z, pos[2].z) if direction.x ~= 0 then if direction.x == 1 then dist = math.abs(p.x - xmax) elseif direction.x == -1 then dist = math.abs(xmin-p.x) end elseif direction.z ~= 0 then if direction.z == 1 then dist = math.abs(p.z - zmax) elseif direction.z == -1 then dist = math.abs(zmin - p.z) end end return dist + 1 end --[[ function direction_to_pins(direction) local pin = {0,0,0,0} if direction.x == -1 then pin[1] = 1 end if direction.x == 1 then pin[3] = 1 end if direction.z == 1 then pin[2] = 1 end if direction.z == -1 then pin[4] == 1 end return pin end ]]-- function direction_to_pin(direction) if direction.x == -1 then return 1 end if direction.x == 1 then return 3 end if direction.z == 1 then return 2 end if direction.z == -1 then return 4 end end function pos_to_connect(wall,direction) local list = {} iterate_selection(wall.pos1,wall.pos2, function(pos) local pins = get_pins_from_pos(pos) local dpin = direction_to_pin(direction) if pins[dpin] == 1 then table.insert(list,pos) end end) return list end function _is_block_type(pos,direction) local node = minetest.get_node(pos) local name = node.name if name == "air" then return "buildable" end if name == "mesecons_insulated:insulated_off" or name == "mesecons_insulated:insulated_on" then local param2 = node.param2 local pin = direction_to_pin(direction) if (param2==0 or param2==2) and (pin==2 or pin==4) then return "buildable" end if (param2==1 or param2==3) and (pin==1 or pin==3) then return "buildable" end return "last" end local pos_pins = get_pins_from_pos(pos) local dir_pin = flip_pin(direction_to_pin(direction)) if pos_pins[dir_pin] ==1 then return "last" end return "cancel" end function is_block_type(pos,direction) local res = _is_block_type(pos,direction) local node = minetest.get_node(pos) local name = node.name return res end function is_block_cancel(pos,direction) if is_block_type(pos,direction) == "cancel" then return true else return false end end function is_block_last(pos,direction) if is_block_type(pos,direction) == "last" then return true else return false end end function is_block_buildable(pos,direction) if is_block_type(pos,direction) == "buildable" then return true else return false end end function _can_build_wire(pos,direction,size) local current = { x=pos.x , y =pos.y, z=pos.z} local flag = false for i=1,size,1 do if is_block_cancel(current,direction) then return false end if is_block_last(current,direction) then return true end current = vector.add(current,direction) end return flag end function can_build_wire(pos,direction,size) return _can_build_wire(pos,direction,size) end function add_wire(pos,direction) local node = minetest.get_node(pos) local name = node.name if name == "air" then local pins = get_pins_from_pos(pos) local dpin = direction_to_pin(direction) pins[dpin] = 1 pins[flip_pin(dpin)] = 1 local nnode = get_node_from_pins(pins) --minetest.set_node(pos,nnode) mesecons_autotools.set_node(pos,nnode,"add_wire") else local nnode = { name = "mesecons_extrawires:crossover_off" } --minetest.set_node(pos, nnode) mesecons_autotools.set_node(pos,nnode,"add_wire") end end --[[ not used function add_last_wire(pos,direction) local pins = get_pins_from_pos(pos) local dpin = direction_to_pin(direction) pins[flip_pin(dpin)] = 1 local node = get_node_from_pins(pins) minetest.set_node(pos,node) end ]]-- function build_wire_inside(pos,direction,size) local current = { x=pos.x , y =pos.y, z=pos.z} if not can_build_wire(pos,direction,size) then return end for i=1,size,1 do if is_block_cancel(current,direction) then return elseif is_block_buildable(current,direction) then add_wire(current,direction) elseif is_block_last(current,direction) then break end current = vector.add(current,direction) end end function create_wires_inside_selection(sel,wall,direction) local size = size_by_direction(sel.pos1,sel.pos2,direction) local back_direction = vector.multiply(direction,-1) iterate_selection(wall.pos1,wall.pos2,function(pos) build_wire_inside(pos,back_direction,size) end) end function create_bundle_straight_wire(sel,pos) local pos1 = sel.pos1 local pos2 = sel.pos2 if not is_in_tube(sel,pos) then return false end local wall,direction = front_wall_tube(sel,pos) local distance = distance_to_selection(sel,pos,direction) if is_one_block(pos1,pos2) or is_empty_selection(pos1,pos2) or is_tower_selection(pos1,pos2) then iterate_selection(sel.pos1, sel.pos2, function(pos) create_straight_wire_n(pos,direction,distance) end) else create_wires_inside_selection(sel,wall,direction) local wire_list = pos_to_connect(wall,direction) iterate_list(wire_list,function(pos) create_straight_wire_n(pos,direction,distance) end) end return true end