Advertisement
Oeed

Cane Harvester

Jul 10th, 2016
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.57 KB | None | 0 0
  1. local delay = 180
  2. local price = 32
  3.  
  4. local activities = {
  5.     CHEST_IDLE = 1,
  6.     CHEST_OUT = 2,
  7.     CHEST_IN = 3,
  8.     TRANSIT_IN_HORIZONTAL = 4,
  9.     TRANSIT_IN_VERTICAL = 5,
  10.     TRANSIT_OUT = 6, -- entering the farming area
  11.     TRANSIT_IN = 7, -- leaving the farming area
  12.     NEXT_OUT_HORIZONTAL = 8,
  13.     NEXT_OUT_VERTICAL = 9,
  14.     NEXT_IN_HORIZONTAL = 10,
  15.     CROP_OUT = 11, -- in the farming area, heading away from entry
  16.     CROP_SWITCH = 12, -- in the farming area, heading toward entry
  17.     CROP_IN = 13,
  18.     TRANSIT_IN_SWITCH = 14
  19. }
  20.  
  21. local directions = {
  22.     OUT_TRANSIT = 0,
  23.     OUT_CROP = 1,
  24.     IN_TRANSIT = 2,
  25.     IN_CROP = 3
  26. }
  27.  
  28. local state
  29. local function loadState()
  30.     local h = fs.open("cane.state", "r")
  31.     if h then
  32.         state = textutils.unserialise(h.readAll())
  33.         h.close()
  34.     else
  35.         state = {
  36.             activity = activities.CHEST_IDLE,
  37.             direction = directions.OUT_CROP,
  38.             startFuel = turtle.getFuelLevel()
  39.         }
  40.     end
  41. end
  42.  
  43. local function saveState()
  44.     local h = fs.open("cane.state", "w")
  45.     if h then
  46.         h.write(textutils.serialise(state))
  47.         h.close()
  48.     end
  49. end
  50.  
  51. local function turnTo(direction)
  52.     local difference = direction - state.direction
  53.     if math.abs(difference) >= 3 then
  54.         difference = (difference - 2 * (difference / math.abs(difference))) * -1
  55.     end
  56.     if difference > 0 then
  57.         for i = 1, difference do
  58.             turtle.turnLeft()
  59.             state.direction = (state.direction + 1) % 4
  60.             saveState()
  61.         end
  62.     elseif difference < 0 then
  63.         for i = 1, math.abs(difference) do
  64.             turtle.turnRight()
  65.             state.direction = (state.direction - 1) % 4
  66.             saveState()
  67.         end
  68.     end
  69. end
  70.  
  71. local function setActivity(activity)
  72.     if not activity then error('act') end
  73.     state.activity = activity
  74.     saveState()
  75. end
  76.  
  77. -- depart from the idle chest location
  78. function chestOut()
  79.     print("Starting harvest...")
  80.     setActivity(activities.CHEST_OUT)
  81.     turnTo(directions.OUT_TRANSIT)
  82.     while true do
  83.         local okay, block = turtle.inspectDown()
  84.         if okay and block and block.name == "minecraft:planks" and block.state.variant == "birch" then
  85.             break
  86.         end
  87.         if not turtle.forward() then
  88.             error("WARNING! Failed to find tunnel start.")
  89.         end
  90.     end
  91.     return nextHorizontalOut()
  92. end
  93.  
  94. function enterCrop()
  95.     setActivity(activities.TRANSIT_OUT)
  96.     turnTo(directions.OUT_CROP)
  97.     while true do
  98.         local okay, block = turtle.inspect()
  99.         if okay and block and block.name == "minecraft:reeds" then
  100.             -- there are reeds in front of us, we're in a farming zone now
  101.             return cropOut()
  102.         else
  103.             okay, block = turtle.inspectDown()
  104.             if not okay or (okay and block and block.name == "minecraft:reeds") then
  105.                 -- there is no block or there are reeds below us, we're farming now
  106.                 return cropOut()
  107.             end
  108.         end
  109.         if not turtle.forward() then
  110.             error("WARNING! Failed to enter farming area.")
  111.         end
  112.     end
  113. end
  114.  
  115. local function crop(isIn)
  116.     local keepRunning = true
  117.     while keepRunning do
  118.         local okay, block = turtle.inspect()
  119.         if okay and block then
  120.             if block.name == "minecraft:reeds" then
  121.                 -- there are reeds in front of us
  122.                 turtle.dig()
  123.             else
  124.                 -- there is another block, we need to stop
  125.                 keepRunning = false
  126.             end
  127.         end
  128.         okay, block = turtle.inspectDown()
  129.         if okay and block then
  130.             if block.name == "minecraft:reeds" then
  131.                 -- there are reeds below us
  132.                 turtle.digDown()
  133.             elseif isIn then
  134.                 -- there is another block, we must be in the exit
  135.                 keepRunning = false
  136.             end
  137.         end
  138.         if keepRunning and not turtle.forward() then
  139.             error("WARNING! Failed to move through the farm area (probably low fuel).")
  140.         end
  141.     end
  142. end
  143.  
  144. function cropOut()
  145.     setActivity(activities.CROP_OUT)
  146.     turnTo(directions.OUT_CROP)
  147.     crop()
  148.     return cropSwitch()
  149. end
  150.  
  151. function cropSwitch()
  152.     setActivity(activities.CROP_SWITCH)
  153.     turnTo(directions.OUT_TRANSIT)
  154.     local okay, block = turtle.inspect()
  155.     if okay and block then
  156.         if block.name ~= "minecraft:reeds" then
  157.             -- there is another block, we are in cropIn
  158.             return cropIn()
  159.         else
  160.             turtle.dig()
  161.         end
  162.     end
  163.     -- there is air in front of us, we can safely move forward
  164.     turtle.forward()
  165.     return cropIn()
  166. end
  167.  
  168. function cropIn()
  169.     setActivity(activities.CROP_IN)
  170.     turnTo(directions.IN_CROP)
  171.     crop(true)
  172.     return exitSwitch()
  173. end
  174.  
  175. function exitSwitch()
  176.     setActivity(activities.TRANSIT_IN_SWITCH)
  177.     turnTo(directions.IN_CROP)
  178.     local okay, block = turtle.inspect()
  179.     if not okay then
  180.         -- we're already at the exit
  181.         return exitCrop()
  182.     end
  183.     turnTo(directions.IN_TRANSIT)
  184.     turtle.dig()
  185.     turtle.forward()
  186.     return exitCrop()
  187. end
  188.  
  189. function exitCrop()
  190.     setActivity(activities.TRANSIT_IN)
  191.     turnTo(directions.IN_CROP)
  192.     while true do
  193.         local okay, block = turtle.inspect()
  194.         if okay and block then
  195.             -- this is the exit, we don't start any new tasks, simply let nextHorizontal takeover again
  196.             return
  197.         end
  198.         if not turtle.forward() then
  199.             error("WARNING! Failed to exit farming area.")
  200.         end
  201.     end
  202. end
  203.  
  204. function nextHorizontalOut()
  205.     state.nextHorizontal = "out"
  206.     setActivity(activities.NEXT_OUT_HORIZONTAL)
  207.     while true do
  208.         turnTo(directions.OUT_CROP)
  209.         local okay, block = turtle.inspect()
  210.         if not okay then
  211.             -- this is air and hence an entry, enter it
  212.             enterCrop()
  213.             setActivity(activities.NEXT_OUT_HORIZONTAL)
  214.         end
  215.         turnTo(directions.OUT_TRANSIT)
  216.         -- there wasn't an entry or we've been through it, move along and try again
  217.         local okay, block = turtle.inspect()
  218.         if okay and block then
  219.             -- there is a block in front of us, this is the last hoziontal, try going up
  220.             return nextVerticalOut(false)
  221.         end
  222.         if not turtle.forward() then
  223.             error("WARNING! Failed to move to next horizontal entry.")
  224.         end
  225.     end
  226. end
  227.  
  228. function nextHorizontalIn()
  229.     state.nextHorizontal = "in"
  230.     setActivity(activities.NEXT_IN_HORIZONTAL)
  231.     while true do
  232.         turnTo(directions.OUT_CROP)
  233.         local okay, block = turtle.inspect()
  234.         if not okay then
  235.             -- this is air and hence an entry, enter it
  236.             enterCrop()
  237.             setActivity(activities.NEXT_IN_HORIZONTAL)
  238.         end
  239.         turnTo(directions.IN_TRANSIT)
  240.         -- there wasn't an entry, move along and try again
  241.         local okay, block = turtle.inspect()
  242.         if okay and block then
  243.             -- there is a block in front of us, this is the last hoziontal, try going up
  244.             return nextVerticalOut(true)
  245.         end
  246.         if not turtle.forward() then
  247.             error("WARNING! Failed to move to next horizontal entry.")
  248.         end
  249.     end
  250. end
  251.  
  252. function nextVerticalOut(horizontalOut)
  253.     setActivity(activities.NEXT_OUT_VERTICAL)
  254.     turnTo(directions.OUT_CROP)
  255.     while true do
  256.         local okay, block = turtle.inspectUp()
  257.         if okay and block then
  258.             -- there is a block in above us, this is the last vertical, go home
  259.             return verticalIn()
  260.         end
  261.         if not turtle.up() then
  262.             error("WARNING! Failed to move to next vertical entry.")
  263.         end
  264.         local okay, block = turtle.inspect()
  265.         if not okay then
  266.             -- this is air and hence an entry, do next horizonatal
  267.             if horizontalOut then
  268.                 return nextHorizontalOut()
  269.             else
  270.                 return nextHorizontalIn()
  271.             end
  272.         end
  273.     end
  274. end
  275.  
  276. function verticalIn()
  277.     setActivity(activities.TRANSIT_IN_VERTICAL)
  278.     turnTo(directions.IN_TRANSIT)
  279.     while true do
  280.         local okay, block = turtle.inspectDown()
  281.         if okay and block then
  282.             -- there is a block in below us, this is the last vertical, start horizontal
  283.             return horizontalIn()
  284.         end
  285.         if not turtle.down() then
  286.             error("WARNING! Failed to move to vertically home.")
  287.         end
  288.     end
  289. end
  290.  
  291. function horizontalIn()
  292.     setActivity(activities.TRANSIT_IN_HORIZONTAL)
  293.     turnTo(directions.IN_TRANSIT)
  294.     while true do
  295.         local okay, block = turtle.inspectDown()
  296.         if okay and block and block.name == "minecraft:planks" and block.state.variant == "birch" then
  297.             -- the home plank is right below us, return to the chest
  298.             return chestIn()
  299.         end
  300.         if not turtle.forward() then
  301.             error("WARNING! Failed to move to horizontally home.")
  302.         end
  303.     end
  304. end
  305.  
  306. function chestIn()
  307.     -- at this point it is assumed that we are right above the plank block
  308.     setActivity(activities.CHEST_IN)
  309.     turnTo(directions.IN_TRANSIT)
  310.     while true do
  311.         local okay, block = turtle.inspectDown()
  312.         if okay and block and block.name == "minecraft:wool" and block.state.color == "white" then
  313.             break
  314.         end
  315.         if not turtle.forward() then
  316.             error("WARNING! Failed to return to chest.")
  317.         end
  318.     end
  319.     return chestIdle()
  320. end
  321.  
  322. function chestIdle()
  323.     setActivity(activities.CHEST_IDLE)
  324.     turnTo(directions.OUT_CROP)
  325.     local count = 0
  326.     for i = 1, 16 do
  327.         count = count + turtle.getItemCount(i)
  328.         turtle.select(i)
  329.         turtle.drop()
  330.     end
  331.     print("Harvested " .. count .. " cane.")
  332.     print(string.format("Value: $%.2f", (count / 64) * price))
  333.     print("Fuel consumption: " .. state.startFuel - turtle.getFuelLevel())
  334. end
  335.  
  336. function resume()
  337.     print("Resuming...")
  338.     loadState()
  339.     local funcs = {
  340.         [activities.CHEST_IDLE] = chestIdle;
  341.         [activities.CHEST_OUT] = chestOut;
  342.         [activities.CHEST_IN] = chestIn;
  343.         [activities.TRANSIT_IN_HORIZONTAL] = horizontalIn;
  344.         [activities.TRANSIT_IN_VERTICAL] = verticalIn;
  345.         [activities.TRANSIT_OUT] = enterCrop;
  346.         [activities.TRANSIT_IN] = exitCrop;
  347.         [activities.NEXT_OUT_HORIZONTAL] = nextHorizontalOut;
  348.         [activities.NEXT_OUT_VERTICAL] = nextVerticalOut;
  349.         [activities.NEXT_IN_HORIZONTAL] = nextHorizontalIn;
  350.         [activities.CROP_OUT] = cropOut;
  351.         [activities.CROP_SWITCH] = cropSwitch;
  352.         [activities.CROP_IN] = cropIn;
  353.         [activities.TRANSIT_IN_SWITCH] = exitSwitch;
  354.     }
  355.     funcs[state.activity]()
  356.     if state.activity ~= activities.CHEST_IDLE then
  357.         if state.nextHorizontal == "in" then
  358.             return nextHorizontalIn()
  359.         else
  360.             return nextHorizontalOut()
  361.         end
  362.     end
  363. end
  364.  
  365. resume()
  366. while true do
  367.     sleep(delay)
  368.     print("Starting fresh...")
  369.     state.startFuel = turtle.getFuelLevel()
  370.     saveState()
  371.     chestOut()
  372. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement