Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---------------
- -- BY UPZONE --
- ---------------
- os.loadAPI("builder\\apis\\Colors")
- os.loadAPI("builder\\apis\\Paint")
- os.loadAPI("builder\\apis\\Turtle")
- os.loadAPI("builder\\apis\\Inventory")
- os.loadAPI("builder\\apis\\Button")
- -- arguments
- local args = {...}
- local templatePath = args[1]
- local width = nil
- local height = nil
- local inventoryFields = {}
- local layers = {}
- local totalLayers = nil
- local colorCount = {}
- -- used for path finding
- local currentX = 1
- local currentY = 1
- local front = 0
- local back = 1
- local right = 2
- local left = 3
- local facing = front
- -- validate
- term.clear()
- term.setCursorPos(1, 1)
- if args[1] == nil or not fs.exists(args[1]) then
- print("Usage: Builder <template path>")
- return
- end
- -- functions
- function loadTemplate(path)
- -- read template
- f = fs.open(path, "r")
- content = f.readAll()
- f.close()
- -- iterator function
- splits = content:gmatch("([^\:]*)\:?")
- width = tonumber(splits())
- height = tonumber(splits())
- -- which inventory slot has which color
- idx = 0
- for c in splits():gmatch(".") do
- idx = idx + 1
- if c ~= Colors.black then
- if inventoryFields[c] == nil then
- inventoryFields[c] = {}
- end
- table.insert(inventoryFields[c], idx)
- end
- end
- -- rebuild layers
- idx = 0
- for c in splits():gmatch(".") do
- idx = idx + 1
- -- layer
- curLayer = math.floor(idx/(width * height)) + 1
- if idx % (width * height) == 0 then
- curLayer = curLayer - 1
- end
- if layers[curLayer] == nil then
- layers[curLayer] = {}
- end
- -- index on current layer
- layerIdx = idx % (width * height)
- if layerIdx == 0 then
- layerIdx = (width * height)
- end
- -- coordinate x on this layer
- layerX = layerIdx % width
- if layerX == 0 then
- layerX = width
- end
- -- coordinate y on this layer
- layerY = math.ceil(layerIdx / width)
- if layerY == 0 then
- layerY = height
- end
- table.insert(layers[curLayer], { layerX, layerY, c, false })
- -- keep track of colors
- if colorCount[c] == nil then
- colorCount[c] = 0
- end
- colorCount[c] = colorCount[c] + 1
- end
- totalLayers = table.getn(layers)
- end
- function selectBlock(l, x, y)
- -- current layer
- layer = layers[l]
- -- get color for coordinate on this layer
- color = nil
- for k, v in ipairs(layer) do
- if v[1] == x and v[2] == y then
- color = v[3]
- break
- end
- end
- -- ignore black (empty) fields
- if color == Colors.black then
- return false
- end
- if color == nil then
- error("No color found for corrdinate x: " .. x .. "/y: " .. y)
- end
- -- get inventory slots associated with this color
- slots = nil
- for k, v in pairs(inventoryFields) do
- if color == k then
- slots = v
- end
- end
- if slots == nil then
- error("No inventory slots found for this color! Adjust the template accordingly")
- end
- while Inventory.getItemCount(slots) == 0 do
- print("")
- print("Run out of items! Please restock one of the following slots:")
- for i, v in pairs(slots) do
- term.write(v .. " ")
- end
- print("")
- print("Waiting for 5 seconds to check again ...")
- sleep(5)
- end
- -- select an inventory slot of this color which has items
- slot = nil
- for k, v in pairs(slots) do
- if turtle.getItemCount(v) > 0 then
- slot = v
- break
- end
- end
- if slot == nil then
- error("No slot with items found for this color!")
- end
- turtle.select(slot)
- return true
- end
- function getDistance(x1, y1, x2, y2)
- -- get distance between two points
- xDistance = math.abs(x1 - x2)
- yDistance = math.abs(y1 - y2)
- return xDistance + yDistance
- end
- function turnRight()
- turtle.turnRight()
- -- keep track of turtle orientation for pathfinding
- if facing == front then
- facing = right
- elseif facing == right then
- facing = back
- elseif facing == back then
- facing = left
- elseif facing == left then
- facing = front
- end
- end
- function turnLeft()
- turtle.turnLeft()
- -- keep track of turtle orientation for pathfinding
- if facing == front then
- facing = left
- elseif facing == left then
- facing = back
- elseif facing == back then
- facing = right
- elseif facing == right then
- facing = front
- end
- end
- function moveForward()
- Turtle.moveForward()
- -- keep track of turtle orientation for pathfinding
- if facing == front then
- currentX = currentX + 1
- elseif facing == left then
- currentY = currentY - 1
- elseif facing == back then
- currentX = currentX - 1
- elseif facing == right then
- currentY = currentY + 1
- end
- end
- function gotoX(x)
- if x < currentX then
- if facing == front then
- turnRight()
- turnRight()
- elseif facing == left then
- turnLeft()
- elseif facing == right then
- turnRight()
- end
- while x < currentX do
- moveForward()
- end
- elseif x > currentX then
- if facing == back then
- turnRight()
- turnRight()
- elseif facing == left then
- turnRight()
- elseif facing == right then
- turnLeft()
- end
- while x > currentX do
- moveForward()
- end
- end
- end
- function gotoY(y)
- if y < currentY then
- if facing == front then
- turnLeft()
- elseif facing == right then
- turnRight()
- turnRight()
- elseif facing == back then
- turnRight()
- end
- while y < currentY do
- moveForward()
- end
- elseif y > currentY then
- if facing == front then
- turnRight()
- elseif facing == left then
- turnLeft()
- turnLeft()
- elseif facing == back then
- turnLeft()
- end
- while y > currentY do
- moveForward()
- end
- end
- end
- function goto(x, y)
- gotoX(x)
- gotoY(y)
- end
- function placeClosestBlock(l, blocksToIgnore)
- local closestDistance = nil
- local closestSpot = nil
- for k, v in ipairs(layers[l]) do
- -- spot has not been placed yet
- if not v[4] then
- -- color is not one to ignore
- local ignore = false
- for s, t in pairs(blocksToIgnore) do
- if v[3] == t then
- ignore = true
- break
- end
- end
- if not ignore then
- -- check distance
- local distance = getDistance(currentX, currentY, v[1], v[2])
- if closestDistance == nil or distance < closestDistance then
- closestDistance = distance
- closestSpot = k
- if closestDistance == 1 then
- break
- end
- end
- end
- end
- end
- if closestSpot ~= nil then
- layers[l][closestSpot][4] = true
- local x = layers[l][closestSpot][1]
- local y = layers[l][closestSpot][2]
- goto(x, y)
- local placeBlock = selectBlock(l, x, y)
- if placeBlock then
- Turtle.placeDown()
- end
- return true
- else
- return false
- end
- end
- function startMain()
- for l = 1, totalLayers do
- print("Starting layer " .. l)
- Turtle.moveUp()
- -- place all blocks except black and yellow
- while placeClosestBlock(l, {Colors.black, Colors.yellow}) do end
- -- place yellow blocks
- while placeClosestBlock(l, {Colors.white, Colors.orange, Colors.magenta, Colors.lightBlue, Colors.lime, Colors.pink, Colors.pink, Colors.gray, Colors.lightGray, Colors.cyan, Colors.purple, Colors.blue, Colors.brown, Colors.green, Colors.red, Colors.black}) do end
- end
- end
- -- initializing
- loadTemplate(templatePath)
- print("Prepare your inventory slots defined by the template like so: ")
- print("")
- btnStart = Button.create("Start", 32, 10, 7, 3, startMain, Colors.white, Colors.red, Colors.white, Colors.lime)
- btnStart:draw()
- while true do
- idx = 3
- for i, k in pairs(inventoryFields) do
- idx = idx + 1
- term.setCursorPos(2, idx)
- Paint.pixel(2, idx, " ", Colors.black, i)
- term.setCursorPos(4, idx)
- term.write("= Slot(s): ")
- for j, h in pairs(k) do
- term.write(h .. " ")
- end
- Inventory.itemCountStatus(colorCount[i], k)
- end
- timeout = os.startTimer(3)
- event = {os.pullEvent()}
- if event[1] == "mouse_click" and btnStart:intersects(event[3], event[4]) then
- btnStart:raiseOnClick()
- break
- end
- sleep(0)
- end
- -- finish
- goto(1, 1)
- print("Builder finished!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement