HandieAndy

planter

Jul 18th, 2020
280
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- pastebin get -f REyTTip0 planter.lua
  2.  
  3. local ms = require("movescript")
  4. local robot = require("robot")
  5. local component = require("component")
  6. local sides = require("sides")
  7. local ic = component.inventory_controller
  8. local geolyzer = component.geolyzer
  9.  
  10. -- The list of names of all blocks that crops may be planted on.
  11. local PLANTABLE_BLOCKS = {
  12.   "minecraft:dirt",
  13.   "minecraft:grass",
  14.   "biomesoplenty:dirt",
  15.   "biomesoplenty:grass"
  16. }
  17.  
  18. local PICKAXE_NAME = "pickaxe"
  19. local HOE_NAME = "mattock"
  20.  
  21. local DISPLACEMENT = -1 -- Displacement == 0 means we're on the first row of the field.
  22.  
  23. local function equipNothing()
  24.   for i = 1, robot.inventorySize() do
  25.     if robot.count(i) == 0 then
  26.       robot.select(i)
  27.       ic.equip()
  28.       return true
  29.     end
  30.   end
  31.   return false
  32. end
  33.  
  34. local function dropAllExcept(names)
  35.   for i = 1, robot.inventorySize() do
  36.     local stack = ic.getStackInInternalSlot(i)
  37.     if stack ~= nil then
  38.       local shouldDrop = true
  39.       for _, acceptableName in ipairs(names) do
  40.         if string.find(stack.name, acceptableName) then
  41.           shouldDrop = false
  42.         end
  43.       end
  44.       if shouldDrop then
  45.         robot.select(i)
  46.         robot.dropDown()
  47.       end
  48.     end
  49.   end
  50. end
  51.  
  52. local function equipItemOrWait(name, cropName)
  53.   -- First, ensure that nothing is equipped.
  54.   repeat
  55.     local success = equipNothing()
  56.     if not success then
  57.       dropAllExcept({PICKAXE_NAME, HOE_NAME, cropName})
  58.     end
  59.   until success
  60.   -- Then try and select the item until we succeed.
  61.   repeat
  62.     local success = ms.selectItem(name)
  63.     if not success then
  64.       print("Please add more " .. name .. ", then press enter.")
  65.       io.read()
  66.     end
  67.   until success
  68.   ic.equip()
  69. end
  70.  
  71. local function ensureEnoughEnergy()
  72.   if ms.getEnergyRatio() < 0.05 then
  73.     while ms.getEnergyRatio() < 0.5 do
  74.       print("Energy low! Sleeping for a while.")
  75.       os.sleep(60)
  76.     end
  77.   end
  78. end
  79.  
  80. -- Moves from the current position to the next planting spot (just above grass).
  81. -- Returns false if no spot could be found.
  82. local function goToNextSpot(cropName)
  83.   ensureEnoughEnergy()
  84.   equipItemOrWait(PICKAXE_NAME, cropName)
  85.   -- Go up to try and get around an obstacle, or give up if we can't.
  86.   while robot.detect() do
  87.     if not robot.up() then return false end
  88.   end
  89.   ms.exec("F")
  90.   DISPLACEMENT = DISPLACEMENT + 1
  91.   local grassFound = false
  92.   while true do
  93.     local blocking, desc = robot.detectDown()
  94.     -- If we hit a liquid, quit right away.
  95.     if not blocking and desc == "liquid" then return false end
  96.     if blocking then -- There is something blocking the robot's path.
  97.       -- If the block below us is something passable or an entity, keep swinging until it's gone.
  98.       if desc == "passable" or desc == "entity" then
  99.         repeat
  100.           ms.exec("Sd")
  101.         until not robot.detectDown()
  102.       end
  103.       if desc == "solid" then
  104.         local blockData = geolyzer.analyze(sides.bottom)
  105.         -- If for some reason we can't analyze the block, quit.
  106.         if blockData == nil then return false end
  107.         for _, plantableBlockName in ipairs(PLANTABLE_BLOCKS) do
  108.           if blockData.name == plantableBlockName then
  109.             ms.exec("U")
  110.             return true
  111.           end
  112.         end
  113.         -- If we reached a solid block that's not plantable, quit and return false.
  114.         if not grassFound then return false end
  115.       end
  116.     else -- The robot is free to move down.
  117.       ms.exec("D")
  118.     end
  119.   end
  120. end
  121.  
  122. local function plantSpot(cropName)
  123.   repeat
  124.     equipItemOrWait(HOE_NAME, cropName)
  125.     robot.useDown()
  126.     equipItemOrWait(cropName, cropName)
  127.     local success = robot.useDown()
  128.   until success
  129. end
  130.  
  131. local function plantUnboundedLength(width, cropName)
  132.   for col = 1, width do
  133.     -- Go as far as possible in this column.
  134.     repeat
  135.       local success = goToNextSpot(cropName)
  136.       if success then
  137.         plantSpot(cropName)
  138.       end
  139.     until not success
  140.     -- We've reached the end. Go all the way back, then go into the next column.
  141.     ms.exec("RR")
  142.     while DISPLACEMENT ~= 0 do
  143.       while not robot.detectDown() do
  144.         ms.exec("D")
  145.       end
  146.       while robot.detect() do
  147.         ms.exec("U")
  148.       end
  149.       ms.exec("F")
  150.       DISPLACEMENT = DISPLACEMENT - 1
  151.     end
  152.     ms.exec("L")
  153.     print("Completed column " .. col .. " of " .. width)
  154.     if col ~= width then
  155.       goToNextSpot(cropName)
  156.       plantSpot(cropName)
  157.       DISPLACEMENT = 0 -- Reset our global displacement tracker before going on the next run.
  158.     end
  159.     ms.exec("L")
  160.   end
  161. end
  162.  
  163. local function plantArea(length, width, cropName)
  164.   goToNextSpot(cropName)
  165.   plantSpot(cropName)
  166.   ms.exec("R")
  167.   for row = 1, length do
  168.     for col = 1, width - 1 do
  169.       goToNextSpot(cropName)
  170.       plantSpot(cropName)
  171.     end
  172.     if row % 2 == 1 then
  173.       ms.exec("L")
  174.     else
  175.       ms.exec("R")
  176.     end
  177.     if row ~= length then
  178.       goToNextSpot(cropName)
  179.       plantSpot(cropName)
  180.     end
  181.     if row % 2 == 1 then
  182.       ms.exec("L")
  183.     else
  184.       ms.exec("R")
  185.     end
  186.     print("Completed row " .. row .. " of " .. length)
  187.   end
  188. end
  189.  
  190.  
  191. if ic == nil then error("Missing inventory controller component.") end
  192. if geolyzer == nil then error("Missing geolyzer component.") end
  193.  
  194. local arg = {...}
  195.  
  196. local length = tonumber(arg[1])
  197. local width = tonumber(arg[2])
  198. local cropName = arg[3]
  199. if not length or not width or not cropName then
  200.   error("Invalid args.")
  201. end
  202.  
  203. if length < 0 and width > 0 then
  204.   print("Planting area " .. width .. " blocks wide, with unbounded length, with " .. cropName)
  205.   plantUnboundedLength(width, cropName)
  206.   return
  207. end
  208.  
  209. print("Planting an area " .. length .. " by " .. width .. " with " .. cropName .. ".")
  210. plantArea(length, width, cropName)
Add Comment
Please, Sign In to add comment