Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local function Key2Coords(k)
- local i = k:find(",")
- local j = k:find(",",(i or -1) +1)
- if not i or not j then
- return nil
- end
- local v = {}
- v.x = tonumber(k:sub(1,i-1))
- v.y = tonumber(k:sub(i+1,j-1))
- v.z = tonumber(k:sub(j+1,-1))
- return v,v.x,v.y,v.z
- end
- local function Coords2Key(x,y,z)
- if type(x) == "table" then
- z = x.z
- y = x.y
- x = x.x
- end
- return tostring(x) .. "," ..
- tostring(y) .. "," ..
- tostring(z)
- end
- local function LoadSchematic(filename)
- local f = fs.open(filename,"r")
- if not f then
- return {}
- end
- local data = textutils.unserialize(
- f.readAll()
- )
- f.close()
- return data or {}
- end
- local function SaveSchematic(filename,schematic)
- local f = fs.open(filename,"w")
- f.write(textutils.serialize(schematic))
- f.close()
- end
- local function Go(n)
- for i=1,(n or 1) do
- while not turtle.forward() do
- print("Unable to move forward")
- sleep(1)
- end
- end
- end
- function CreateSchematic(width,
- height,
- depth,
- filename)
- if not width or
- not height or
- not depth then
- print("Usage:")
- print("CreateSchematic(x,y,z,filename)")
- print("x,y,z are the dimensions")
- print(" turtle is placed on top of")
- print(" the NW corner of the 3D region")
- print("filename is the name of the file")
- print("to be created by the scan")
- return
- end
- local schematic = LoadSchematic(filename)
- if schematic.complete then
- error("File already exists")
- end
- for y = height,1,-1 do
- for x = 1,width do
- for z = 1,depth do
- local s,data = turtle.inspectDown()
- if s then
- if turtle.digDown() then
- local t = {}
- t.name = data.name
- t.half = data.state.half
- t.facing = data.state.facing
- local k = Coords2Key(x,y,z)
- schematic[k] = t
- SaveSchematic(filename,schematic)
- end
- end
- if z < depth then
- Go(1)
- end
- end --end for z
- --turn around and go back
- turtle.turnRight()
- turtle.turnRight()
- Go(depth-1)
- if x < width then
- --move to next column
- turtle.turnLeft()
- Go(1)
- turtle.turnLeft()
- else
- turtle.turnRight()
- Go(width-1)
- turtle.turnRight()
- end
- end --end for x
- while not turtle.down() do
- print("Can't move down")
- sleep(1)
- end
- end --end for y
- schematic.complete = true
- SaveSchematic(filename,schematic)
- print("Done!")
- end
- function PostProcessSchematic(filename)
- local schematic = LoadSchematic(filename)
- if not schematic.complete then
- error("Invalid schematic file")
- end
- local mats = {}
- local size = {x=1,y=1,z=1}
- --local layers = {}
- for k,v in pairs(schematic) do
- if type(k) == "string" then
- local pos = Key2Coords(k)
- if pos and v.name then
- --update mats table
- if not mats[v.name] then
- mats[v.name] =
- {
- qty = 0,
- stateData = not not
- --(v.half or v.facing)
- v.facing
- }
- end
- mats[v.name].qty =
- mats[v.name].qty + 1
- ----update layers table
- --if not layers[v.pos.y] then
- -- layers[v.pos.y] = {}
- --end
- --update size
- for dir,_ in pairs(size) do
- --dir = "x", "y", or "z"
- if size[dir] < pos[dir] then
- size[dir] = pos[dir]
- end
- end
- end --end if key is a position
- end --end if type == string
- end --end for
- --convert mats set into sorted array
- local materials = {}
- local i = 1
- for k,v in pairs(mats) do
- materials[i] = v
- materials[i].name = k
- i = i + 1
- end
- table.sort(materials,
- function(a,b)
- if a.stateData ~= b.stateData then
- return b.stateData
- end
- return a.name < b.name
- end)
- schematic.materials = materials
- schematic.size = size
- SaveSchematic(filename,schematic)
- end
- local function PlaceBlock(blockdata)
- --find item with same name
- local selected
- while not selected do
- for i=1,16 do
- local details = turtle.getItemDetail(i)
- if details and details.name == blockdata.name then
- turtle.select(i)
- selected = true
- end
- end
- if not selected then
- print("Out of: " .. blockdata.name)
- sleep(5)
- end
- end
- --place the block
- while not turtle.placeDown() do
- print("Can't place block")
- sleep(1)
- end
- --is the block facing the right way?
- if blockdata.facing then
- local s,x = turtle.inspectDown()
- if not s then --something is messing with us
- return
- end
- if blockdata.facing and
- blockdata.facing ~= x.state.facing then
- --spin in place
- for i=1,4 do
- turtle.turnRight()
- if x and x.state and
- blockdata.facing ~= x.state.facing then
- turtle.digDown()
- while not turtle.placeDown() do
- print("Can't place block")
- sleep(1)
- end
- end
- s,x = turtle.inspectDown()
- end
- end
- end
- end
- function Build(filename)
- local schematic = LoadSchematic(filename)
- if not schematic.materials then
- PostProcessSchematic(filename)
- end
- local size = schematic.size
- local width = size.x
- local height = size.y
- local depth = size.z
- for y = 1,height do
- --move up to new level
- while not turtle.up() do
- print("Can't move up")
- sleep(1)
- end
- for x = 1,width do
- for z = 1,depth do
- local k = Coords2Key(x,y,z)
- local blockdata = schematic[k]
- if blockdata then
- PlaceBlock(blockdata)
- end
- if z < depth then
- Go(1)
- end
- end --end for z
- --turn around and go back
- turtle.turnRight()
- turtle.turnRight()
- Go(depth-1)
- if x < width then
- --move to next column
- turtle.turnLeft()
- Go(1)
- turtle.turnLeft()
- else
- turtle.turnRight()
- Go(width-1)
- turtle.turnRight()
- end
- end --end for x
- end --end for y
- print("Done!")
- turtle.select(1)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement