Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- pastebin get -f REyTTip0 planter.lua
- local ms = require("movescript")
- local robot = require("robot")
- local component = require("component")
- local sides = require("sides")
- local ic = component.inventory_controller
- local geolyzer = component.geolyzer
- -- The list of names of all blocks that crops may be planted on.
- local PLANTABLE_BLOCKS = {
- "minecraft:dirt",
- "minecraft:grass",
- "biomesoplenty:dirt",
- "biomesoplenty:grass"
- }
- local PICKAXE_NAME = "pickaxe"
- local HOE_NAME = "mattock"
- local DISPLACEMENT = -1 -- Displacement == 0 means we're on the first row of the field.
- local function equipNothing()
- for i = 1, robot.inventorySize() do
- if robot.count(i) == 0 then
- robot.select(i)
- ic.equip()
- return true
- end
- end
- return false
- end
- local function dropAllExcept(names)
- for i = 1, robot.inventorySize() do
- local stack = ic.getStackInInternalSlot(i)
- if stack ~= nil then
- local shouldDrop = true
- for _, acceptableName in ipairs(names) do
- if string.find(stack.name, acceptableName) then
- shouldDrop = false
- end
- end
- if shouldDrop then
- robot.select(i)
- robot.dropDown()
- end
- end
- end
- end
- local function equipItemOrWait(name, cropName)
- -- First, ensure that nothing is equipped.
- repeat
- local success = equipNothing()
- if not success then
- dropAllExcept({PICKAXE_NAME, HOE_NAME, cropName})
- end
- until success
- -- Then try and select the item until we succeed.
- repeat
- local success = ms.selectItem(name)
- if not success then
- print("Please add more " .. name .. ", then press enter.")
- io.read()
- end
- until success
- ic.equip()
- end
- local function ensureEnoughEnergy()
- if ms.getEnergyRatio() < 0.05 then
- while ms.getEnergyRatio() < 0.5 do
- print("Energy low! Sleeping for a while.")
- os.sleep(60)
- end
- end
- end
- -- Moves from the current position to the next planting spot (just above grass).
- -- Returns false if no spot could be found.
- local function goToNextSpot(cropName)
- ensureEnoughEnergy()
- equipItemOrWait(PICKAXE_NAME, cropName)
- -- Go up to try and get around an obstacle, or give up if we can't.
- while robot.detect() do
- if not robot.up() then return false end
- end
- ms.exec("F")
- DISPLACEMENT = DISPLACEMENT + 1
- local grassFound = false
- while true do
- local blocking, desc = robot.detectDown()
- -- If we hit a liquid, quit right away.
- if not blocking and desc == "liquid" then return false end
- if blocking then -- There is something blocking the robot's path.
- -- If the block below us is something passable or an entity, keep swinging until it's gone.
- if desc == "passable" or desc == "entity" then
- repeat
- ms.exec("Sd")
- until not robot.detectDown()
- end
- if desc == "solid" then
- local blockData = geolyzer.analyze(sides.bottom)
- -- If for some reason we can't analyze the block, quit.
- if blockData == nil then return false end
- for _, plantableBlockName in ipairs(PLANTABLE_BLOCKS) do
- if blockData.name == plantableBlockName then
- ms.exec("U")
- return true
- end
- end
- -- If we reached a solid block that's not plantable, quit and return false.
- if not grassFound then return false end
- end
- else -- The robot is free to move down.
- ms.exec("D")
- end
- end
- end
- local function plantSpot(cropName)
- repeat
- equipItemOrWait(HOE_NAME, cropName)
- robot.useDown()
- equipItemOrWait(cropName, cropName)
- local success = robot.useDown()
- until success
- end
- local function plantUnboundedLength(width, cropName)
- for col = 1, width do
- -- Go as far as possible in this column.
- repeat
- local success = goToNextSpot(cropName)
- if success then
- plantSpot(cropName)
- end
- until not success
- -- We've reached the end. Go all the way back, then go into the next column.
- ms.exec("RR")
- while DISPLACEMENT ~= 0 do
- while not robot.detectDown() do
- ms.exec("D")
- end
- while robot.detect() do
- ms.exec("U")
- end
- ms.exec("F")
- DISPLACEMENT = DISPLACEMENT - 1
- end
- ms.exec("L")
- print("Completed column " .. col .. " of " .. width)
- if col ~= width then
- goToNextSpot(cropName)
- plantSpot(cropName)
- DISPLACEMENT = 0 -- Reset our global displacement tracker before going on the next run.
- end
- ms.exec("L")
- end
- end
- local function plantArea(length, width, cropName)
- goToNextSpot(cropName)
- plantSpot(cropName)
- ms.exec("R")
- for row = 1, length do
- for col = 1, width - 1 do
- goToNextSpot(cropName)
- plantSpot(cropName)
- end
- if row % 2 == 1 then
- ms.exec("L")
- else
- ms.exec("R")
- end
- if row ~= length then
- goToNextSpot(cropName)
- plantSpot(cropName)
- end
- if row % 2 == 1 then
- ms.exec("L")
- else
- ms.exec("R")
- end
- print("Completed row " .. row .. " of " .. length)
- end
- end
- if ic == nil then error("Missing inventory controller component.") end
- if geolyzer == nil then error("Missing geolyzer component.") end
- local arg = {...}
- local length = tonumber(arg[1])
- local width = tonumber(arg[2])
- local cropName = arg[3]
- if not length or not width or not cropName then
- error("Invalid args.")
- end
- if length < 0 and width > 0 then
- print("Planting area " .. width .. " blocks wide, with unbounded length, with " .. cropName)
- plantUnboundedLength(width, cropName)
- return
- end
- print("Planting an area " .. length .. " by " .. width .. " with " .. cropName .. ".")
- plantArea(length, width, cropName)
Add Comment
Please, Sign In to add comment