Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- +--------------------------------------------------------+
- -- | |
- -- | Wool Image Printer |
- -- | |
- -- +--------------------------------------------------------+
- local version = "Version 1.0.0"
- -- By Jeffrey Alexander, aka Bomb Bloke.
- -- Loads GIF or paintutils images and has a turtle construct them.
- -- http://www.computercraft.info/forums2/index.php?/topic/28727-cc164-wool-image-printer/
- -- ----------------------------------------------------------
- -- Variable Declarations
- -- ----------------------------------------------------------
- local fileName = ...
- local wool, node, pos, slots, img, starty, startNode = {}, {}, {}, {}
- local facing = {"north","east","south","west"}
- local amounts = {[0] = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
- local names = {[0] = "White", "Orange", "Magenta", "Light Blue", "Yellow", "Lime", "Pink", "Gray", "Light Gray", "Cyan", "Purple", "Blue", "Brown", "Green", "Red", "Black"}
- local blocks = {["minecraft:wool"] = true, ["minecraft:stained_hardened_clay"] = true, ["minecraft:stained_glass"] = true, ["minecraft:stained_glass_pane"] = true, ["minecraft:concrete"] = true}
- for i = 0, 15 do wool[2^i] = i end
- -- ----------------------------------------------------------
- -- Function Declarations
- -- ----------------------------------------------------------
- -- Accepts strings representing compass-facings to turn the turtle.
- local function faceDirection(targetdirection)
- local tardir = 1
- for i=1,4 do if targetdirection == facing[i] then tardir = i end end
- if tardir < pos.direction then
- if tardir == 1 and pos.direction == 4 then
- while not turtle.turnRight() do end
- else
- for i=1,pos.direction-tardir do while not turtle.turnLeft() do end end
- end
- elseif tardir > pos.direction then
- if tardir == 4 and pos.direction == 1 then
- while not turtle.turnLeft() do end
- else
- for i=1,tardir-pos.direction do while not turtle.turnRight() do end end
- end
- end
- pos.direction = tardir
- end
- -- Move ahead a block, keeping track of the turtle's position.
- local function forward(amount)
- if not amount then amount = 1 end
- while not turtle.forward() do
- turtle.dig()
- turtle.attack()
- end
- if pos.direction == 1 then pos.z = pos.z - amount
- elseif pos.direction == 2 then pos.x = pos.x + amount
- elseif pos.direction == 3 then pos.z = pos.z + amount
- else pos.x = pos.x - amount end
- end
- -- Same again but non-destructive.
- local function safeForward(amount)
- if not amount then amount = 1 end
- for i = 1, amount do repeat until turtle.forward() end
- if pos.direction == 1 then pos.z = pos.z - amount
- elseif pos.direction == 2 then pos.x = pos.x + amount
- elseif pos.direction == 3 then pos.z = pos.z + amount
- else pos.x = pos.x - amount end
- end
- local function turn(tardir)
- if tardir == "left" then
- while not turtle.turnLeft() do end
- pos.direction = pos.direction - 1
- if pos.direction < 1 then pos.direction = 4 end
- elseif tardir == "right" then
- while not turtle.turnRight() do end
- pos.direction = pos.direction + 1
- if pos.direction > 4 then pos.direction = 1 end
- end
- end
- -- Travel to a co-ordinate.
- local function goToPos(target,digger)
- while (pos.x ~= node[target][1]) or (pos.y ~= node[target][2]) or (pos.z ~= node[target][3]) do
- if pos.y > node[target][2] then
- if digger then
- while not turtle.down() do
- turtle.digDown()
- turtle.attackDown()
- end
- pos.y = pos.y - 1
- elseif turtle.down() then pos.y = pos.y - 1 end
- elseif pos.y < node[target][2] then
- if digger then
- while not turtle.up() do
- turtle.digUp()
- turtle.attackUp()
- end
- pos.y = pos.y + 1
- elseif turtle.up() then pos.y = pos.y + 1 end
- end
- if pos.x > node[target][1] then
- if pos.direction ~= 4 then faceDirection("west") end
- if digger then forward() elseif turtle.forward() then pos.x = pos.x - 1 end
- elseif pos.x < node[target][1] then
- if pos.direction ~= 2 then faceDirection("east") end
- if digger then forward() elseif turtle.forward() then pos.x = pos.x + 1 end
- end
- if pos.z > node[target][3] then
- if pos.direction ~= 1 then faceDirection("north") end
- if digger then forward() elseif turtle.forward() then pos.z = pos.z - 1 end
- elseif pos.z < node[target][3] then
- if pos.direction ~= 3 then faceDirection("south") end
- if digger then forward() elseif turtle.forward() then pos.z = pos.z + 1 end
- end
- end
- faceDirection(node[target][4])
- end
- local function getSlotName(slotNum)
- local data = turtle.getItemDetail(slotNum)
- if not data then return nil else return data.name end
- end
- local function mapSlots()
- slots = {}
- for i = 1, 16 do
- local data = turtle.getItemDetail(i)
- if data and blocks[data.name] then slots[data.damage] = i end
- end
- end
- -- ----------------------------------------------------------
- -- Initialisation
- -- ----------------------------------------------------------
- term.clear()
- term.setCursorPos(1, 1)
- if fs.exists("progress.txt") then
- print("Build already in progress; resume? ")
- if read():lower():sub(1, 1) == "y" then
- local file = fs.open("progress.txt", "r")
- local data = textutils.unserialise(file.readAll())
- file.close()
- fileName, starty, startNode = data[1], data[2], data[3]
- end
- print()
- end
- if not fs.exists(fileName) then
- if fs.exists(fileName .. ".nfp") then
- fileName = fileName .. ".nfp"
- elseif fs.exists(fileName .. ".gif") then
- fileName = fileName .. ".gif"
- else error("Can't find the specified image file.") end
- end
- if fileName:lower():sub(-4) == ".gif" then
- if not bbpack then
- if not (fs.exists("bbpack") or fs.exists(shell.resolve("bbpack"))) then
- shell.run("pastebin get cUYTGbpb bbpack")
- os.loadAPI(shell.resolve("bbpack"))
- else os.loadAPI(fs.exists("bbpack") and "bbpack" or shell.resolve("bbpack")) end
- end
- if not GIF then
- if not (fs.exists("GIF") or fs.exists(shell.resolve("GIF"))) then
- shell.run("pastebin get 5uk9uRjC GIF")
- os.loadAPI(shell.resolve("GIF"))
- else os.loadAPI(fs.exists("GIF") and "GIF" or shell.resolve("GIF")) end
- end
- img = GIF.toPaintutils(GIF.loadGIF(fileName))
- else
- img = paintutils.loadImage(fileName)
- end
- -- Strip any empty rows from the bottom of the image:
- for y = #img, 1, -1 do
- local row, found = img[y], false
- for x = 1, #row do if row[x] > 0 then
- found = true
- break
- end end
- if found then break else img[y] = nil end
- end
- -- Strip any empty columns from the right of the image:
- for y = 1, #img do
- local row = img[y]
- for x = #row, 1, -1 do if row[x] > 0 then
- break
- else
- row[x] = nil
- end end
- end
- if not startNode then
- for y = 1, #img do
- local row = img[y]
- for x = 1, #row do
- local thisCol = wool[row[x]]
- if thisCol then amounts[thisCol] = amounts[thisCol] + 1 end
- end
- end
- local flip = false
- print("Requirements:")
- for i = 0, 15 do if amounts[i] > 0 then
- write(names[i] .. ": " .. amounts[i])
- if flip then
- print()
- else
- local x, y = term.getCursorPos()
- term.setCursorPos(20, y)
- end
- flip = not flip
- end end
- print()
- if not flip then print() end
- write("Proceed? ")
- if read():lower():sub(1, 1) ~= "y" then return end
- starty = 1
- print()
- end
- -- ----------------------------------------------------------
- -- Determine Position
- -- ----------------------------------------------------------
- -- Ping the GPS servers until I get a valid reading:
- if peripheral.find("modem") then
- local tempx, tempy, tempz
- while tempx == nil or tempy == nil or tempz == nil do
- tempx, tempy, tempz = gps.locate(5)
- sleep(5)
- end
- while not turtle.forward() do while not turtle.turnLeft() do end end
- pos.x,pos.y,pos.z = gps.locate(5)
- if pos.x < tempx then pos.direction = 4
- elseif pos.x > tempx then pos.direction = 2
- elseif pos.z < tempz then pos.direction = 1
- else pos.direction = 3 end
- repeat until turtle.back()
- pos.x,pos.y,pos.z = gps.locate(5)
- print("I'm at "..pos.x..","..pos.y..","..pos.z..", I have "..turtle.getFuelLevel().." fuel, and I'm facing "..facing[pos.direction]..".")
- else
- pos.x,pos.y,pos.z,pos.direction = 0, 0, 0, 1
- print("I have "..turtle.getFuelLevel().." fuel, but I don't know where I am. If I have to be restarted, manually place me back at my initial position first.")
- end
- print()
- mapSlots()
- node[1] = startNode or {pos.x, pos.y, pos.z, facing[pos.direction]}
- if pos.y > node[1][2] then
- node[2] = {node[1][1], pos.y, node[1][3], facing[pos.direction]}
- goToPos(2)
- goToPos(1)
- end
- -- ----------------------------------------------------------
- -- Primary Work Loop
- -- ----------------------------------------------------------
- for y = starty, #img do
- local file = fs.open("progress.txt", "w")
- file.write(textutils.serialise({fileName, y, node[1]}))
- file.close()
- local thisRow = img[#img - y + 1]
- if y + #thisRow + 10 > turtle.getFuelLevel() then
- print("Low of energy. Please provide fuel items.")
- goToPos(1)
- repeat
- os.pullEvent("turtle_inventory")
- for i = 1, 16 do
- local slot = getSlotName(i)
- if slot and not blocks[slot] then
- turtle.select(i)
- turtle.refuel()
- end
- end
- until turtle.getFuelLevel() > y + #thisRow + 10
- end
- node[2] = {node[1][1], node[1][2] + y, node[1][3], node[1][4]}
- goToPos(2)
- for x = 1, #thisRow do
- safeForward()
- local thisCol = wool[thisRow[x]]
- if thisCol and not turtle.detectDown() then
- if not slots[thisCol] or turtle.getItemCount(slots[thisCol]) == 0 then
- mapSlots()
- if not slots[thisCol] or turtle.getItemCount(slots[thisCol]) == 0 then
- print("Out of " .. names[thisCol] .. "!")
- node[3] = {pos.x, pos.y, pos.z, node[1][4]}
- goToPos(2)
- goToPos(1)
- repeat
- os.pullEvent("turtle_inventory")
- mapSlots()
- until slots[thisCol] and turtle.getItemCount(slots[thisCol]) > 0
- goToPos(2)
- goToPos(3)
- end
- end
- turtle.select(slots[thisCol])
- turtle.placeDown()
- end
- end
- goToPos(2)
- end
- goToPos(1)
- print("Done!")
- fs.delete("progress.txt")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement