Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local delay = 180
- local price = 32
- local activities = {
- CHEST_IDLE = 1,
- CHEST_OUT = 2,
- CHEST_IN = 3,
- TRANSIT_IN_HORIZONTAL = 4,
- TRANSIT_IN_VERTICAL = 5,
- TRANSIT_OUT = 6, -- entering the farming area
- TRANSIT_IN = 7, -- leaving the farming area
- NEXT_OUT_HORIZONTAL = 8,
- NEXT_OUT_VERTICAL = 9,
- NEXT_IN_HORIZONTAL = 10,
- CROP_OUT = 11, -- in the farming area, heading away from entry
- CROP_SWITCH = 12, -- in the farming area, heading toward entry
- CROP_IN = 13,
- TRANSIT_IN_SWITCH = 14
- }
- local directions = {
- OUT_TRANSIT = 0,
- OUT_CROP = 1,
- IN_TRANSIT = 2,
- IN_CROP = 3
- }
- local state
- local function loadState()
- local h = fs.open("cane.state", "r")
- if h then
- state = textutils.unserialise(h.readAll())
- h.close()
- else
- state = {
- activity = activities.CHEST_IDLE,
- direction = directions.OUT_CROP,
- startFuel = turtle.getFuelLevel()
- }
- end
- end
- local function saveState()
- local h = fs.open("cane.state", "w")
- if h then
- h.write(textutils.serialise(state))
- h.close()
- end
- end
- local function turnTo(direction)
- local difference = direction - state.direction
- if math.abs(difference) >= 3 then
- difference = (difference - 2 * (difference / math.abs(difference))) * -1
- end
- if difference > 0 then
- for i = 1, difference do
- turtle.turnLeft()
- state.direction = (state.direction + 1) % 4
- saveState()
- end
- elseif difference < 0 then
- for i = 1, math.abs(difference) do
- turtle.turnRight()
- state.direction = (state.direction - 1) % 4
- saveState()
- end
- end
- end
- local function setActivity(activity)
- if not activity then error('act') end
- state.activity = activity
- saveState()
- end
- -- depart from the idle chest location
- function chestOut()
- print("Starting harvest...")
- setActivity(activities.CHEST_OUT)
- turnTo(directions.OUT_TRANSIT)
- while true do
- local okay, block = turtle.inspectDown()
- if okay and block and block.name == "minecraft:planks" and block.state.variant == "birch" then
- break
- end
- if not turtle.forward() then
- error("WARNING! Failed to find tunnel start.")
- end
- end
- return nextHorizontalOut()
- end
- function enterCrop()
- setActivity(activities.TRANSIT_OUT)
- turnTo(directions.OUT_CROP)
- while true do
- local okay, block = turtle.inspect()
- if okay and block and block.name == "minecraft:reeds" then
- -- there are reeds in front of us, we're in a farming zone now
- return cropOut()
- else
- okay, block = turtle.inspectDown()
- if not okay or (okay and block and block.name == "minecraft:reeds") then
- -- there is no block or there are reeds below us, we're farming now
- return cropOut()
- end
- end
- if not turtle.forward() then
- error("WARNING! Failed to enter farming area.")
- end
- end
- end
- local function crop(isIn)
- local keepRunning = true
- while keepRunning do
- local okay, block = turtle.inspect()
- if okay and block then
- if block.name == "minecraft:reeds" then
- -- there are reeds in front of us
- turtle.dig()
- else
- -- there is another block, we need to stop
- keepRunning = false
- end
- end
- okay, block = turtle.inspectDown()
- if okay and block then
- if block.name == "minecraft:reeds" then
- -- there are reeds below us
- turtle.digDown()
- elseif isIn then
- -- there is another block, we must be in the exit
- keepRunning = false
- end
- end
- if keepRunning and not turtle.forward() then
- error("WARNING! Failed to move through the farm area (probably low fuel).")
- end
- end
- end
- function cropOut()
- setActivity(activities.CROP_OUT)
- turnTo(directions.OUT_CROP)
- crop()
- return cropSwitch()
- end
- function cropSwitch()
- setActivity(activities.CROP_SWITCH)
- turnTo(directions.OUT_TRANSIT)
- local okay, block = turtle.inspect()
- if okay and block then
- if block.name ~= "minecraft:reeds" then
- -- there is another block, we are in cropIn
- return cropIn()
- else
- turtle.dig()
- end
- end
- -- there is air in front of us, we can safely move forward
- turtle.forward()
- return cropIn()
- end
- function cropIn()
- setActivity(activities.CROP_IN)
- turnTo(directions.IN_CROP)
- crop(true)
- return exitSwitch()
- end
- function exitSwitch()
- setActivity(activities.TRANSIT_IN_SWITCH)
- turnTo(directions.IN_CROP)
- local okay, block = turtle.inspect()
- if not okay then
- -- we're already at the exit
- return exitCrop()
- end
- turnTo(directions.IN_TRANSIT)
- turtle.dig()
- turtle.forward()
- return exitCrop()
- end
- function exitCrop()
- setActivity(activities.TRANSIT_IN)
- turnTo(directions.IN_CROP)
- while true do
- local okay, block = turtle.inspect()
- if okay and block then
- -- this is the exit, we don't start any new tasks, simply let nextHorizontal takeover again
- return
- end
- if not turtle.forward() then
- error("WARNING! Failed to exit farming area.")
- end
- end
- end
- function nextHorizontalOut()
- state.nextHorizontal = "out"
- setActivity(activities.NEXT_OUT_HORIZONTAL)
- while true do
- turnTo(directions.OUT_CROP)
- local okay, block = turtle.inspect()
- if not okay then
- -- this is air and hence an entry, enter it
- enterCrop()
- setActivity(activities.NEXT_OUT_HORIZONTAL)
- end
- turnTo(directions.OUT_TRANSIT)
- -- there wasn't an entry or we've been through it, move along and try again
- local okay, block = turtle.inspect()
- if okay and block then
- -- there is a block in front of us, this is the last hoziontal, try going up
- return nextVerticalOut(false)
- end
- if not turtle.forward() then
- error("WARNING! Failed to move to next horizontal entry.")
- end
- end
- end
- function nextHorizontalIn()
- state.nextHorizontal = "in"
- setActivity(activities.NEXT_IN_HORIZONTAL)
- while true do
- turnTo(directions.OUT_CROP)
- local okay, block = turtle.inspect()
- if not okay then
- -- this is air and hence an entry, enter it
- enterCrop()
- setActivity(activities.NEXT_IN_HORIZONTAL)
- end
- turnTo(directions.IN_TRANSIT)
- -- there wasn't an entry, move along and try again
- local okay, block = turtle.inspect()
- if okay and block then
- -- there is a block in front of us, this is the last hoziontal, try going up
- return nextVerticalOut(true)
- end
- if not turtle.forward() then
- error("WARNING! Failed to move to next horizontal entry.")
- end
- end
- end
- function nextVerticalOut(horizontalOut)
- setActivity(activities.NEXT_OUT_VERTICAL)
- turnTo(directions.OUT_CROP)
- while true do
- local okay, block = turtle.inspectUp()
- if okay and block then
- -- there is a block in above us, this is the last vertical, go home
- return verticalIn()
- end
- if not turtle.up() then
- error("WARNING! Failed to move to next vertical entry.")
- end
- local okay, block = turtle.inspect()
- if not okay then
- -- this is air and hence an entry, do next horizonatal
- if horizontalOut then
- return nextHorizontalOut()
- else
- return nextHorizontalIn()
- end
- end
- end
- end
- function verticalIn()
- setActivity(activities.TRANSIT_IN_VERTICAL)
- turnTo(directions.IN_TRANSIT)
- while true do
- local okay, block = turtle.inspectDown()
- if okay and block then
- -- there is a block in below us, this is the last vertical, start horizontal
- return horizontalIn()
- end
- if not turtle.down() then
- error("WARNING! Failed to move to vertically home.")
- end
- end
- end
- function horizontalIn()
- setActivity(activities.TRANSIT_IN_HORIZONTAL)
- turnTo(directions.IN_TRANSIT)
- while true do
- local okay, block = turtle.inspectDown()
- if okay and block and block.name == "minecraft:planks" and block.state.variant == "birch" then
- -- the home plank is right below us, return to the chest
- return chestIn()
- end
- if not turtle.forward() then
- error("WARNING! Failed to move to horizontally home.")
- end
- end
- end
- function chestIn()
- -- at this point it is assumed that we are right above the plank block
- setActivity(activities.CHEST_IN)
- turnTo(directions.IN_TRANSIT)
- while true do
- local okay, block = turtle.inspectDown()
- if okay and block and block.name == "minecraft:wool" and block.state.color == "white" then
- break
- end
- if not turtle.forward() then
- error("WARNING! Failed to return to chest.")
- end
- end
- return chestIdle()
- end
- function chestIdle()
- setActivity(activities.CHEST_IDLE)
- turnTo(directions.OUT_CROP)
- local count = 0
- for i = 1, 16 do
- count = count + turtle.getItemCount(i)
- turtle.select(i)
- turtle.drop()
- end
- print("Harvested " .. count .. " cane.")
- print(string.format("Value: $%.2f", (count / 64) * price))
- print("Fuel consumption: " .. state.startFuel - turtle.getFuelLevel())
- end
- function resume()
- print("Resuming...")
- loadState()
- local funcs = {
- [activities.CHEST_IDLE] = chestIdle;
- [activities.CHEST_OUT] = chestOut;
- [activities.CHEST_IN] = chestIn;
- [activities.TRANSIT_IN_HORIZONTAL] = horizontalIn;
- [activities.TRANSIT_IN_VERTICAL] = verticalIn;
- [activities.TRANSIT_OUT] = enterCrop;
- [activities.TRANSIT_IN] = exitCrop;
- [activities.NEXT_OUT_HORIZONTAL] = nextHorizontalOut;
- [activities.NEXT_OUT_VERTICAL] = nextVerticalOut;
- [activities.NEXT_IN_HORIZONTAL] = nextHorizontalIn;
- [activities.CROP_OUT] = cropOut;
- [activities.CROP_SWITCH] = cropSwitch;
- [activities.CROP_IN] = cropIn;
- [activities.TRANSIT_IN_SWITCH] = exitSwitch;
- }
- funcs[state.activity]()
- if state.activity ~= activities.CHEST_IDLE then
- if state.nextHorizontal == "in" then
- return nextHorizontalIn()
- else
- return nextHorizontalOut()
- end
- end
- end
- resume()
- while true do
- sleep(delay)
- print("Starting fresh...")
- state.startFuel = turtle.getFuelLevel()
- saveState()
- chestOut()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement