Advertisement
Oeed

Melon Farm

Jul 27th, 2016
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.48 KB | None | 0 0
  1. local delay = 0
  2. local price = 16
  3. local startsEven = false
  4. local WHEREIS_CHANNEL = 420
  5.  
  6. local DIRECTION_CALIBRATION_BLOCK = "minecraft:sandstone"
  7. local CROP_START_VARIANT = {
  8.     [true] = "smooth_granite",
  9.     [false] = "smooth_andesite"
  10. }
  11. local CROP_END_VARIANT = {
  12.     [true] = "smooth_andesite",
  13.     [false] = "smooth_granite"
  14. }
  15. local CROP_SWITCH_VARIANT = {
  16.     [true] = "andesite",
  17.     [false] = "granite"
  18. }
  19. local TRANSIT_VERTICAL_ENTER_VARIANT = "smooth_diorite"
  20. local MELON_BLOCK = "minecraft:melon_block"
  21. local CHEST_BLOCK = "minecraft:chest"
  22. local STONE_BLOCK = "minecraft:stone"
  23.  
  24. local activities = {
  25.     CHEST_LEAVE = 1, -- spin until sandstone, note as even direction. go forward one then CROP_FIRST.
  26.     CROP_FIRST = 2, -- go along the crops until a wall
  27.     CROP_SWITCH = 3, -- switch row until left is ditorite
  28.     CROP_SECOND = 4, -- go along crops until granite (odd), andesite (even)
  29.     TRANSIT_HORIZONTAL = 5, -- go toward chest until below is andesite (CROP_FIRST) or above is ditorite (turn and foward, then TRANSIT_VERTICAL_UP)
  30.     TRANSIT_VERTICAL_UP = 6, -- go up until front is plank, rotate twice, switch odd/even then CROP_FIRST. otherwise, if above is blocked then
  31.     TRANSIT_VERTICAL_UP_START = 7, -- go up one block to clear the previous level
  32.     TRANSIT_VERTICAL_DOWN = 8, -- go down until blocked, then CHEST_RETURN
  33.     CHEST_RETURN = 9, -- check below if chest, if so drop everything, else spin to not even direction and repeat
  34.     CHEST_DROP = 10, -- check below if chest, if so drop everything, else spin to not even direction and repeat
  35. }
  36.  
  37. local directions = {
  38.     CROP_TOWARD = 0,
  39.     CHEST_TOWARD = 1,
  40.     CROP_AWAY = 2,
  41.     CHEST_AWAY = 3
  42. }
  43.  
  44. -- fix the modem bug
  45. if not peripheral.find("modem") then
  46.     -- first find an empty slot
  47.     for i = 1, 16 do
  48.         if turtle.getItemCount(i) == 0 then
  49.             turtle.select(i)
  50.             break
  51.         elseif i == 16 then
  52.             turtle.select(i)
  53.             turtle.drop()
  54.         end
  55.     end
  56.     turtle.equipLeft()
  57.     turtle.equipLeft()
  58.     turtle.equipRight()
  59.     turtle.equipRight()
  60. end
  61.  
  62. local state
  63. local function loadState()
  64.     local h = fs.open("melon.state", "r")
  65.     if h then
  66.         state = textutils.unserialise(h.readAll())
  67.         h.close()
  68.     else
  69.         state = {
  70.             activity = activities.CHEST_LEAVE,
  71.             direction = directions.CROP_TOWARD,
  72.             isEven = startsEven,
  73.             startFuel = turtle.getFuelLevel()
  74.         }
  75.     end
  76. end
  77.  
  78. local function saveState()
  79.     local h = fs.open("melon.state", "w")
  80.     if h then
  81.         h.write(textutils.serialise(state))
  82.         h.close()
  83.     end
  84. end
  85.  
  86. local function turnTo(direction)
  87.     local difference = direction - state.direction
  88.     if math.abs(difference) >= 3 then
  89.         difference = (difference - 2 * (difference / math.abs(difference))) * -1
  90.     end
  91.     if difference > 0 then
  92.         for i = 1, difference do
  93.             turtle.turnLeft()
  94.             state.direction = (state.direction + 1) % 4
  95.             saveState()
  96.         end
  97.     elseif difference < 0 then
  98.         for i = 1, math.abs(difference) do
  99.             turtle.turnRight()
  100.             state.direction = (state.direction - 1) % 4
  101.             saveState()
  102.         end
  103.     end
  104. end
  105.  
  106. local function setActivity(activity)
  107.     if not activity then error('act') end
  108.     state.activity = activity
  109.     saveState()
  110. end
  111.  
  112. local funcs = {}
  113.  
  114. local function activity(activity)
  115.     setActivity(activity)
  116.     return funcs[activity]()
  117. end
  118.  
  119. funcs[activities.CHEST_LEAVE] = function()
  120.     turnTo(directions.CROP_TOWARD)
  121.     turtle.forward()
  122.     return activity(activities.CROP_FIRST)
  123. end
  124.  
  125. local function crop()
  126.     while true do
  127.         local isBlock, block = turtle.inspectDown()
  128.         if isBlock and block.name == MELON_BLOCK then
  129.             -- there's a melon below us, break it and til the ground
  130.             turtle.digDown()
  131.             turtle.digDown()
  132.         elseif isBlock and block.name == STONE_BLOCK and block.state.variant == CROP_END_VARIANT[state.isEven] then
  133.             -- we're at the end block, TRANSIT_HORIZONTAL
  134.             return activity(activities.TRANSIT_HORIZONTAL)
  135.         end
  136.         if turtle.inspect() then
  137.             -- there's a block in front of us, CROP_SWITCH
  138.             return activity(activities.CROP_SWITCH)
  139.         else
  140.             turtle.forward()
  141.         end
  142.     end
  143. end
  144.  
  145. funcs[activities.CROP_FIRST] = function()
  146.     print("Collecting crop row #1...")
  147.     turnTo(directions.CROP_TOWARD)
  148.     return crop()
  149. end
  150.  
  151. funcs[activities.CROP_SWITCH] = function()
  152.     print("Switching crop row...")
  153.     while true do
  154.         turnTo(directions.CROP_TOWARD)
  155.         local isBlock, block = turtle.inspect()
  156.         if isBlock and block.name == STONE_BLOCK and block.state.variant == CROP_SWITCH_VARIANT[state.isEven] then
  157.             -- we're at the block where the next row starts, CROP_SECOND
  158.             return activity(activities.CROP_SECOND)
  159.         else
  160.             turnTo(state.isEven and directions.CHEST_TOWARD or directions.CHEST_AWAY)
  161.             turtle.forward()
  162.         end
  163.     end
  164. end
  165.  
  166. funcs[activities.CROP_SECOND] = function()
  167.     print("Collecting crop row #2...")
  168.     turnTo(directions.CROP_AWAY)
  169.     return crop()
  170. end
  171.  
  172. funcs[activities.TRANSIT_HORIZONTAL] = function()
  173.     print("Travelling horizontally to next crop...")
  174.     turnTo(state.isEven and directions.CHEST_TOWARD or directions.CHEST_AWAY)
  175.     while true do
  176.         local isBlock, block = turtle.inspectDown()
  177.         if isBlock and block.name == STONE_BLOCK and block.state.variant == CROP_START_VARIANT[state.isEven] then
  178.             -- we're at the block where the next crop starts, CROP_FIRST
  179.             return activity(activities.CROP_FIRST)
  180.         else
  181.             local isBlockAbove, blockAbove = turtle.inspectUp()
  182.             if isBlockAbove and blockAbove.name == STONE_BLOCK and blockAbove.state.variant == TRANSIT_VERTICAL_ENTER_VARIANT then
  183.                 -- we're at the end of the row, TRANSIT_VERTICAL_UP
  184.                 turnTo(directions.CROP_AWAY)
  185.                 turtle.forward()
  186.                 return activity(activities.TRANSIT_VERTICAL_UP_START)
  187.             else
  188.                 turtle.forward()
  189.             end
  190.         end
  191.     end
  192. end
  193.  
  194. funcs[activities.TRANSIT_VERTICAL_UP_START] = function()
  195.     -- we need to do this because otherwise if it reloads just after it moves into this spot it'll stay on the same level
  196.     print("Leaving previous layer...")
  197.     turtle.up()
  198.     return activity(activities.TRANSIT_VERTICAL_UP)
  199. end
  200.  
  201. funcs[activities.TRANSIT_VERTICAL_UP] = function()
  202.     print("Travelling vertically to next crop layer...")
  203.     turnTo(directions.CROP_TOWARD)
  204.     while true do
  205.         local isBlock, block = turtle.inspect()
  206.         if not isBlock then
  207.             -- we've arrived at the new level, CROP_FIRST
  208.             state.isEven = not state.isEven
  209.             return activity(activities.CROP_FIRST)
  210.         else
  211.             if turtle.inspectUp() then
  212.                 -- there's a block in the way, so we're at the maximum available layer, TRANSIT_VERTICAL_DOWN
  213.                 return activity(activities.TRANSIT_VERTICAL_DOWN)
  214.             else
  215.                 turtle.up()
  216.             end
  217.         end
  218.     end
  219. end
  220.  
  221. funcs[activities.TRANSIT_VERTICAL_DOWN] = function()
  222.     print("Travelling vertically back to the starting layer...")
  223.     while true do
  224.         local isBlock, block = turtle.inspectDown()
  225.         if isBlock then
  226.             -- we've arrived at the chest layer
  227.             state.isEven = false
  228.             if block.name == CHEST_BLOCK then
  229.                 -- we're right above the chest, CROP_DROP
  230.                 return activity(activities.CHEST_DROP)
  231.             else
  232.                 -- we need to move along to the chest
  233.                 return activity(activities.CHEST_RETURN)
  234.             end
  235.         else
  236.             turtle.down()
  237.         end
  238.     end
  239. end
  240.  
  241. funcs[activities.CHEST_RETURN] = function()
  242.     print("Travelling horizontally back to the chest...")
  243.     turnTo(startsEven and directions.CHEST_AWAY or directions.CHEST_TOWARD)
  244.     while true do
  245.         local isBlock, block = turtle.inspectDown()
  246.         if isBlock and block.name == CHEST_BLOCK then
  247.             -- we're right above the chest, CROP_DROP
  248.             return activity(activities.CHEST_DROP)
  249.         else
  250.             turtle.forward()
  251.         end
  252.     end
  253. end
  254.  
  255. funcs[activities.CHEST_DROP] = function()
  256.     print("Dropping the crop in the chest...")
  257.     local count = 0
  258.     for i = 1, 16 do
  259.         count = count + turtle.getItemCount(i)
  260.         turtle.select(i)
  261.         turtle.dropDown()
  262.     end
  263.     print("Harvested " .. count .. " melon.")
  264.     print(string.format("Value: $%.2f", (count / 64) * price))
  265.     print("Fuel consumption: " .. state.startFuel - turtle.getFuelLevel())
  266.     return
  267. end
  268.  
  269. -- depart from the idle chest location
  270. function resume()
  271.     print("Resuming...")
  272.     loadState()
  273.     activity(state.activity)
  274. end
  275.  
  276. parallel.waitForAll(function()
  277.     resume()
  278.     while true do
  279.         sleep(delay)
  280.         print("Starting fresh...")
  281.         state.startFuel = turtle.getFuelLevel()
  282.         state.isEven = startsEven
  283.         saveState()
  284.         activity(activities.CHEST_LEAVE)
  285.     end
  286. end, function()
  287.     local modem = peripheral.find("modem")
  288.     modem.open(WHEREIS_CHANNEL)
  289.     while true do
  290.         local event, side, channel, replyChannel, message = os.pullEvent("modem_message")
  291.         if channel == WHEREIS_CHANNEL and message == "WHEREIS" then
  292.             modem.transmit(replyChannel, channel, {os.getComputerID(), os.getComputerLabel(), gps.locate()})
  293.         end
  294.     end
  295. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement