Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- TODO:
- 1. handle not having saplings in the chest
- 2. make persistance better
- 3. minimum clearing interval
- --]]
- math.sign = math.sign or function(x)
- return x < 0 and -1 or x > 0 and 1 or 0
- end
- table.shallowCopy = function(t)
- local t2 = {}
- for k,v in pairs(t) do
- t2[k] = v
- end
- return t2
- end
- function printMessage(line)
- term.clear()
- print(line)
- end
- function printSleep(line)
- printMessage(line)
- sleep(1)
- term.clear()
- end
- local currentPosition = {
- x = -4;
- y = 0;
- z = 4;
- }
- local currentDirection = 4
- local persisted = false
- local currentSlot = nil
- local woodWhitelist = {
- 'minecraft:oak_log',
- 'minecraft:spruce_log',
- 'minecraft:birch_log',
- 'minecraft:jungle_log',
- 'minecraft:acacia_log',
- 'minecraft:dark_oak_log'
- }
- local saplingWhitelist = {
- 'minecraft:oak_sapling',
- 'minecraft:spruce_sapling',
- 'minecraft:birtch_sapling',
- 'minecraft:jungle_sapling',
- 'minecraft:acacia_sapling',
- 'minecraft:dark_oak_sapling'
- }
- local fuelWhitelist = {
- 'minecraft:coal',
- 'minecraft:charcoal'
- }
- local fuelStorageDirection = 1
- local saplingStorageDirection = 3
- local fuelSlot = 16
- local minFuelToStart = 16
- local minFuelToContinue = 2
- function readData(name)
- if fs.exists('/data/'..name) then
- local handle = fs.open('/data/'..name, 'r')
- local stuff = handle.readAll()
- handle.close()
- return textutils.unserialize(stuff)
- end
- return
- end
- function writeData(name, data)
- if not fs.exists('/data') then
- fs.makeDir('/data')
- end
- local handle = fs.open('/data/'..name, 'w')
- handle.write(textutils.serialize(data))
- handle.close()
- end
- function loadData()
- local loadedPosition = readData('position')
- local loadedDirection = readData('direction')
- if (loadedPosition ~= nil) or (loadedDirection ~= nil) then
- currentPosition = loadedPosition or currentPosition
- currentDirection = loadedDirection or currentDirection
- persisted = true
- end
- end
- function updatePosition(deltaX, deltaY, deltaZ)
- currentPosition.x = currentPosition.x + deltaX
- currentPosition.y = currentPosition.y + deltaY
- currentPosition.z = currentPosition.z + deltaZ
- writeData('position', currentPosition)
- end
- function updateDirection(deltaD)
- currentDirection = (currentDirection + deltaD - 1) % 4 + 1
- writeData('direction', currentDirection)
- end
- function directionToXZ(direction)
- return {
- x = (direction- 2) * (direction% 2),
- z = (direction- 3) * ((direction+ 1) % 2)
- }
- end
- function moveForward(steps, force)
- steps = steps or 1
- for i = 1, steps do
- handleFuel()
- if force == true then
- while turtle.detect() do
- turtle.dig()
- end
- end
- moved = turtle.forward()
- if moved == true then
- deltaXZ = directionToXZ(currentDirection)
- updatePosition(deltaXZ.x, 0, deltaXZ.z)
- else
- printSleep('turtle is stuck, please remove the block in front')
- i = i - 1
- end
- end
- end
- function moveUp(steps, force)
- steps = steps or 1
- for i = 1, steps do
- handleFuel()
- if force == true then
- while turtle.detectUp() do
- turtle.digUp()
- end
- end
- moved = turtle.up()
- if moved == true then
- updatePosition(0, 1, 0)
- else
- printSleep('turtle is stuck, please remove the block above')
- i = i - 1
- end
- end
- end
- function moveDown(steps, force)
- steps = steps or 1
- for i = 1, steps do
- handleFuel()
- if force == true then
- while turtle.detectDown() do
- turtle.digDown()
- end
- end
- moved = turtle.down()
- if moved == true then
- updatePosition(0, -1, 0)
- else
- printSleep('turtle is stuck, please remove the block below')
- i = i - 1
- end
- end
- end
- function moveBack(steps, force, maintaintDirection)
- steps = steps or 1
- for i = 1, steps do
- handleFuel()
- moved = turtle.back()
- if moved == true then
- deltaXZ = directionToXZ(currentDirection)
- updatePosition(-deltaXZ.x, 0, -deltaXZ.z)
- else
- if force == true then
- turnAround()
- moveForward(steps - i + 1, true)
- if maintaintDirection == true then
- turnAround()
- end
- return
- else
- printSleep('turtle is stuck, please remove the block behind')
- i = i - 1
- end
- end
- end
- end
- function turnLeft()
- turtle.turnLeft()
- updateDirection(1)
- end
- function turnRight()
- turtle.turnRight()
- updateDirection(-1)
- end
- function turnAround()
- turnRight()
- turnRight()
- end
- function turnTo(direction)
- if direction == nil or direction == currentDirection then
- return
- end
- local deltaDir = currentDirection - direction
- local temp = (currentDirection % 4) - (direction % 4)
- if math.abs(temp) < math.abs(deltaDir) then
- deltaDir = temp
- end
- if deltaDir < 0 then
- for i = 1, -deltaDir do
- turnLeft()
- end
- elseif deltaDir > 0 then
- for i = 1, deltaDir do
- turnRight()
- end
- end
- end
- function turnToXAxis(preferedSign)
- if currentDirection == 4 then
- if preferedSign == -1 then
- turnLeft()
- else
- turnRight()
- end
- elseif currentDirection == 2 then
- if preferedSign == -1 then
- turnRight()
- else
- turnLeft()
- end
- end
- end
- function turnToZAxis(preferedSign)
- if currentDirection == 1 then
- if preferedSign == -1 then
- turnLeft()
- else
- turnRight()
- end
- elseif currentDirection == 3 then
- if preferedSign == -1 then
- turnRight()
- else
- turnLeft()
- end
- end
- end
- function moveOnXAxis(delta, force, maintaintDirection)
- if delta == 0 or delta == nil then
- return
- end
- local startDir = currentDirection
- local distance = math.abs(delta)
- local sign = math.sign(delta)
- turnToXAxis(sign)
- local currentSign = (currentDirection == 3) and 1 or -1
- if sign * currentSign == 1 then
- moveForward(distance, force)
- else
- moveBack(distance, force, false)
- end
- if maintainDirection then
- turnTo(startDir)
- end
- end
- function moveOnYAxis(delta, force)
- if delta == 0 or delta == nil then
- return
- end
- local distance = math.abs(delta)
- local sign = math.sign(delta)
- if sign == 1 then
- moveUp(distance, force)
- else
- moveDown(distance, force)
- end
- end
- function moveOnZAxis(delta, force, maintaintDirection)
- if delta == 0 or delta == nil then
- return
- end
- local startDir = currentDirection
- local distance = math.abs(delta)
- local sign = math.sign(delta)
- turnToZAxis(sign)
- local currentSign = (currentDirection == 4) and 1 or -1
- if sign * currentSign == 1 then
- moveForward(distance, force)
- else
- moveBack(distance, force, false)
- end
- if maintainDirection then
- turnTo(startDir)
- end
- end
- function moveToX(x, force, maintaintDirection)
- if x == nil then
- return
- end
- local delta = x - currentPosition.x
- moveOnXAxis(delta, force, maintainDirection)
- end
- function moveToY(y, force)
- if y == nil then
- return
- end
- local delta = y - currentPosition.y
- moveOnYAxis(delta, force, maintainDirection)
- end
- function moveToZ(z, force, maintaintDirection)
- if z == nil then
- return
- end
- local delta = z - currentPosition.z
- moveOnZAxis(delta, force, maintainDirection)
- end
- function moveTo(x, y, z, force, maintaintDirection)
- local startDir = currentDirection
- if currentPosition.y < 0 then
- moveToY(y, force)
- if math.abs(currentPosition.x) > math.abs(currentPosition.z) then
- moveToX(x, force, false)
- moveToZ(z, force, false)
- else
- moveToZ(z, force, false)
- moveToX(x, force, false)
- end
- else
- if math.abs(currentPosition.x) > math.abs(currentPosition.z) then
- moveToX(x, force, false)
- moveToZ(z, force, false)
- else
- moveToZ(z, force, false)
- moveToX(x, force, false)
- end
- moveToY(y, force)
- end
- if maintainDirection == true then
- turnTo(startDir)
- end
- end
- function digForward()
- turtle.dig()
- moveForward(1, true)
- end
- function digUp()
- turtle.digUp()
- moveUp(1, true)
- end
- function digDown()
- turtle.digDown()
- moveDown(1, true)
- end
- function select(slot)
- if slot == nil then
- return
- end
- turtle.select(slot)
- currentSlot = slot
- end
- function hasEmptySlots(number)
- number = number or 1
- local empty = 0
- for i = 1, 16 do
- if turtle.getItemDetail(i) == nil then
- empty = empty + 1
- if empty >= number then
- return true
- end
- end
- end
- return false
- end
- function handleFuel()
- local fuel = turtle.getFuelLevel()
- if fuel == 0 then
- local previousSlot = currentSlot
- select(fuelSlot)
- while not turtle.refuel(1) do
- printSleep('turtle is out of fuel, please add some fuel to slot '..fuelSlot)
- end
- select(previousSlot)
- end
- end
- function handleResources(returnBack)
- local previousSlot = currentSlot
- if (selectSapling() == false) or
- (hasEmptySlots(2) == false) or
- (isFuel(getItemName(fuelSlot)) == false) or
- (turtle.getItemCount(fuelSlot) < minFuelToContinue) then
- restock(returnBack)
- end
- select(previousSlot)
- end
- function isWood(name)
- for i = 1, #woodWhitelist do
- if (name == woodWhitelist [i]) then
- return true
- end
- end
- return false
- end
- function isSapling(name)
- for i = 1, #saplingWhitelist do
- if (name == saplingWhitelist [i]) then
- return true
- end
- end
- return false
- end
- function isFuel(name)
- for i = 1, #fuelWhitelist do
- if (name == fuelWhitelist[i]) then
- return true
- end
- end
- return false
- end
- function getItemName(slot)
- if slot == nil then
- return nil
- end
- local detail = turtle.getItemDetail(slot)
- return detail and detail.name or nil
- end
- function selectSapling()
- local holdingSapling = isSapling(getItemName(currentSlot))
- if holdingSapling == false then
- for i = 1, 15 do
- if i ~= currentSlot then
- local foundSapling = isSapling(getItemName(i))
- if foundSapling == true then
- select(i)
- return true
- end
- end
- end
- return false
- end
- return true
- end
- function selectWood()
- local holdingWood = isWood(getItemName(currentSlot))
- if holdingWood == false then
- for i = 1, 15 do
- if i ~= currentSlot then
- local foundWood = isWood(getItemName(i))
- if foundWood == true then
- select(i)
- return true
- end
- end
- end
- return false
- end
- return true
- end
- function dropUnwanted(drop)
- drop = drop or turtle.dropDown
- for i = 1, 16 do
- local name = getItemName(i)
- if (name ~= nil) and (isSapling(name) == false) and (isFuel(name) == false) then
- select(i)
- drop()
- end
- end
- end
- function dropSaplings(drop)
- drop = drop or turtle.drop
- for i = 1, 16 do
- local name = getItemName(i)
- if isSapling(name) == true then
- select(i)
- drop()
- end
- end
- end
- function getSaplings()
- turnTo(saplingStorageDirection)
- dropSaplings(turtle.drop)
- select(1)
- while not turtle.suck(9 * 4) do
- printSleep('missing saplings. to continue, please put saplings in the chest')
- end
- end
- function getFuel()
- while true do
- local name = getItemName(fuelSlot)
- if (name == nil) or (isFuel(name) == true) then
- break
- else
- printMessage('fuel slot('..fuelSlot..') is clogged, please remove all items from slot '..fuelSlot)
- end
- end
- hasAmount = turtle.getItemCount(fuelSlot)
- if hasAmount < 64 then
- turnTo(fuelStorageDirection)
- select(fuelSlot)
- while true do
- turtle.suck(64 - hasAmount)
- hasAmount = turtle.getItemCount(fuelSlot)
- if hasAmount >= minFuelToStart then
- break
- else
- printSleep('missing '..(minFuelToStart - hasAmount)..' fuel. to continue, please put fuel in the chest')
- end
- end
- end
- end
- function restock(returnBack)
- local previousPosition = table.shallowCopy(currentPosition)
- local previousDirection = currentDirection
- moveTo(0, -4, 0, true, false)
- dropUnwanted(turtle.dropDown)
- getSaplings()
- getFuel()
- if returnBack == true then
- moveTo(previousPosition.x, previousPosition.y, previousPosition.z)
- turnTo(previousDirection)
- end
- end
- function placeSapling()
- if selectSapling() == true then
- turtle.place()
- end
- end
- function cutTree()
- local _, data = turtle.inspect()
- if isWood(data.name) then
- selectWood()
- digForward(true)
- local deltaY = 0
- while true do
- _, data = turtle.inspectUp()
- if isWood(data.name) then
- digUp()
- deltaY = deltaY + 1
- else
- break
- end
- end
- for i = 1, deltaY do
- moveDown(1, true)
- end
- moveBack(1)
- end
- end
- function processSpace()
- handleResources(true)
- turtle.suck()
- cutTree()
- placeSapling()
- end
- function processRow(length)
- for i = 1, length-1 do
- processSpace()
- turnRight()
- moveForward()
- turnLeft()
- end
- processSpace()
- end
- function persist()
- loadData()
- if persisted == true then
- printMessage('turtle successfully persisted')
- if ((math.abs(currentPosition.x) == 5) or (math.abs(currentPosition.z) == 5)) then
- if turtle.detectUp() == false then
- moveUp()
- end
- while true do
- local _, data = turtle.inspectUp()
- if isWood(data.name) then
- digUp()
- else
- break
- end
- end
- end
- handleResources(false)
- moveTo(-4, 0, 4, true)
- turnTo(4)
- end
- end
- function main()
- persist()
- while true do
- processRow(9)
- turnRight()
- end
- end
- main()
Add Comment
Please, Sign In to add comment