farming turtle scrits -- Turtle farm by JackMacWindows -- -- This is a simple farming script for ComputerCraft turtles. To use, simply -- place a tilling turtle on top of a farming region, place a wired modem -- connected to a chest next to the turtle, and run this script. -- -- Features: -- * Fully automatic field tending -- * Automatic tilling and planting to reduce setup time -- * Zero configuration to start a basic farm -- * Boundaries are automatically detected, so no need to calculate size farming turtle scrits How to get it? farming turtle scrits -- * Non-rectangular and non-flat fields supported -- * Recovery after being unloaded -- * Automatic unloading and refueling from one or more chests -- -- To create a farm, create a complete boundary around the dirt or grass area -- that you want the farm to be inside. Then add water to ensure the field stays -- fully watered. The field may be any height - the turtle will automatically -- move up or down to continue farming. The field may also be non-rectangular, -- but it will not detect single holes in a straight line going across the field. -- (e.g. if a boundary is at (100, 0) to (100, 100), the boundary may not have a farming turtle scrits How to dowload it? farming turtle scrits -- hole taken out at (100, 25) to (100, 50).) -- -- The turtle dispenses items when it reaches the origin point, which is the -- place where the turtle was when the farm was started. This point must have a -- modem next to it, with one or more chests placed next to that modem. The -- program will prompt you to set this up if not present. (Make sure to right- -- click the modem to turn it red and enable it.) Whenever the turtle returns to -- this point, it will dispense all items except one stack of seeds and one stack -- of fuel. If either of these stacks are not present, it will pick them up from -- the chests. farming turtle scrits How to dowload it? farming turtle scrits -- -- Farms may have multiple different types of crops, and the turtle will attempt -- to replace them with the same type of seed. However, these will have to be -- planted beforehand - when planting the first crops, it will use whatever -- seeds are found in the chest or turtle first. -- -- If you'd like to add custom modded crops, scroll down to the "add your own -- here" sections, and fill out the templates for the blocks and items you want. -- -- If you need any help, you may ask on the ComputerCraft Discord server at farming turtle scrits How to get it for free? farming turtle scrits -- https://discord.computercraft.cc. -- MIT License -- -- Copyright (c) 2022 JackMacWindows -- -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal -- in the Software without restriction, including without limitation the rights -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell farming turtle scrits How to dowload it? farming turtle scrits -- copies of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: -- -- The above copyright notice and this permission notice shall be included in all -- copies or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER farming turtle scrits PasteShr farming turtle scrits -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -- SOFTWARE. local x, y, z = 0, 0, 0 local direction = 0 local invertDirection = false -- Ground blocks that are part of the farm local groundBlocks = { farming turtle scrits PasteShr farming turtle scrits ["minecraft:dirt"] = true, ["minecraft:grass_block"] = true, ["minecraft:farmland"] = true, ["minecraft:water"] = true, ["minecraft:flowing_water"] = true, -- add your own here: --[":"] = true, } -- Blocks that are crops, with their maximum ages farming turtle scrits How to dowload it? farming turtle scrits local cropBlocks = { ["minecraft:wheat"] = 7, ["minecraft:carrots"] = 7, ["minecraft:potatoes"] = 7, ["minecraft:beetroots"] = 3, -- add your own here: --[":"] = , } -- Mappings of crop blocks to seed items farming turtle scrits How to get it? farming turtle scrits local seeds = { ["minecraft:wheat"] = "minecraft:wheat_seeds", ["minecraft:carrots"] = "minecraft:carrot", ["minecraft:potatoes"] = "minecraft:potato", ["minecraft:beetroots"] = "minecraft:beetroot_seeds", -- add your own here: --[":"] = ":", } -- Fuel types to pull from a chest if no fuel is in the inventory farming turtle scrits How to get it for free? farming turtle scrits local fuels = { ["minecraft:coal"] = true, ["minecraft:charcoal"] = true, ["minecraft:lava_bucket"] = true, -- add your own here: --[":"] = true, } local seedItems = {} for k, v in pairs(seeds) do seedItems[v] = k end farming turtle scrits PasteShr farming turtle scrits local function writePos() local file = fs.open("jackmacwindows.farm-state.txt", "w") file.writeLine(x) file.writeLine(y) file.writeLine(z) file.writeLine(direction) file.writeLine(invertDirection and "true" or "false") file.close() end farming turtle scrits How to use it? farming turtle scrits local function refuel() if turtle.getFuelLevel() == "unlimited" or turtle.getFuelLevel() == turtle.getFuelLimit() then return end for i = 1, 16 do if turtle.getItemCount(i) > 0 then turtle.select(i) turtle.refuel(turtle.getItemCount() - 1) if turtle.getFuelLevel() == turtle.getFuelLimit() then return true end end end farming turtle scrits How to use it? farming turtle scrits if turtle.getFuelLevel() > 0 then return true else return false, "Out of fuel" end end local function forward() local ok, err = turtle.forward() if ok then if direction == 0 then x = x + 1 elseif direction == 1 then z = z + 1 elseif direction == 2 then x = x - 1 farming turtle scrits PasteShr farming turtle scrits else z = z - 1 end writePos() return true elseif err:match "[Ff]uel" then ok, err = refuel() if ok then return forward() else return ok, err end else return false, err end end farming turtle scrits How to get it for free? farming turtle scrits local function back() local ok, err = turtle.back() if ok then if direction == 0 then x = x - 1 elseif direction == 1 then z = z - 1 elseif direction == 2 then x = x + 1 else z = z + 1 end writePos() return true elseif err:match "[Ff]uel" then farming turtle scrits PasteShr farming turtle scrits ok, err = refuel() if ok then return forward() else return ok, err end else return false, err end end local function up() local ok, err = turtle.up() if ok then y = y + 1 farming turtle scrits How to use it? farming turtle scrits writePos() return true elseif err:match "[Ff]uel" then ok, err = refuel() if ok then return forward() else return ok, err end else return false, err end end local function down() farming turtle scrits How to get it? farming turtle scrits local ok, err = turtle.down() if ok then y = y - 1 writePos() return true elseif err:match "[Ff]uel" then ok, err = refuel() if ok then return forward() else return ok, err end else return false, err end farming turtle scrits How to use it? farming turtle scrits end local function left() local ok, err = turtle.turnLeft() if ok then direction = (direction - 1) % 4 writePos() return true else return false, err end end farming turtle scrits How to use it? farming turtle scrits local function right() local ok, err = turtle.turnRight() if ok then direction = (direction + 1) % 4 writePos() return true else return false, err end end farming turtle scrits PasteShr farming turtle scrits local function panic(msg) term.clear() term.setCursorPos(1, 1) term.setTextColor(colors.red) print("An unrecoverable error occured while farming:", msg, "\nPlease hold Ctrl+T to stop the program, then solve the issue described above, run 'rm jackmacwindows.farm-state.txt', and return the turtle to the start position. Don't forget to label the turtle before breaking it.") if peripheral.find("modem") then peripheral.find("modem", rednet.open) rednet.broadcast(msg, "jackmacwindows.farming-error") end local speaker = peripheral.find("speaker") farming turtle scrits How to get it? farming turtle scrits if speaker then while true do speaker.playNote("bit", 3, 12) sleep(1) end else while true do os.pullEvent() end end end local function check(ok, msg) if not ok then panic(msg) end end farming turtle scrits PasteShr farming turtle scrits local function tryForward() local ok, err, found, block repeat found, block = turtle.inspect() if found then if groundBlocks[block.name] or cropBlocks[block.name] then ok, err = up() if not ok then return ok, err end else return false, "Out of bounds" end end farming turtle scrits How to get it for free? farming turtle scrits until not found ok, err = forward() if not ok then return ok, err end local lastY = y repeat found, block = turtle.inspectDown() if not found then ok, err = down() if not ok then return ok, err end end farming turtle scrits How to use it? farming turtle scrits until found if groundBlocks[block.name] then ok, err = up() if not ok then return ok, err end turtle.digDown() elseif not cropBlocks[block.name] then while y < lastY do ok, err = up() if not ok then return ok, err end end farming turtle scrits How to use it? farming turtle scrits ok, err = back() if not ok then return ok, err end return false, "Out of bounds" end return true end local function selectItem(item) local lut = {} if type(item) == "table" then farming turtle scrits How to use it? farming turtle scrits if item[1] then for _, v in ipairs(item) do lut[v] = true end else lut = item end else lut[item] = true end local lastEmpty for i = 1, 16 do local info = turtle.getItemDetail(i) if info and lut[info.name] then turtle.select(i) return true, i elseif not info and not lastEmpty then lastEmpty = i end farming turtle scrits How to get it? farming turtle scrits end return false, lastEmpty end local function handleCrop() local found, block = turtle.inspectDown() if not found then if selectItem(seedItems) then turtle.placeDown() end elseif block.state.age == cropBlocks[block.name] then local seed = seeds[block.name] farming turtle scrits PasteShr farming turtle scrits turtle.select(1) turtle.digDown() turtle.suckDown() local item = turtle.getItemDetail() if (not item or item.name ~= seed) and not selectItem(seed) then return end turtle.placeDown() end end local function exchangeItems() farming turtle scrits How to get it for free? farming turtle scrits local inventory, fuel, seed = {}, nil, nil for i = 1, 16 do turtle.select(i) local item = turtle.getItemDetail(i) if item then if not seed and seedItems[item.name] then seed = {slot = i, name = item.name, count = item.count, limit = turtle.getItemSpace(i)} elseif not turtle.refuel(0) then inventory[item.name] = inventory[item.name] or {} inventory[item.name][i] = item.count farming turtle scrits How to use it? farming turtle scrits elseif not fuel then fuel = {slot = i, name = item.name, count = item.count, limit = turtle.getItemSpace(i)} end end end local modem = peripheral.find("modem", function(_, v) return not v.isWireless() end) local tries = 0 while not modem and tries < 4 do tries = tries + 1 check(left()) farming turtle scrits How to get it? farming turtle scrits modem = peripheral.find("modem", function(_, v) return not v.isWireless() end) end if not modem then panic("Could not find modem!") end local name = modem.getNameLocal() for _, chest in ipairs{peripheral.find("minecraft:chest")} do local items = chest.list() for i = 1, chest.size() do if items[i] then local item = items[i].name if inventory[item] then farming turtle scrits How to get it for free? farming turtle scrits for slot, count in pairs(inventory[item]) do local d = chest.pullItems(name, slot, count, i) if d == 0 then break end if count - d <= 0 then inventory[item][slot] = nil else inventory[item][slot] = count - d end end if not next(inventory[item]) then inventory[item] = nil end elseif fuel and fuel.count < fuel.limit and item == fuel.name then local d = chest.pushItems(name, i, fuel.limit - fuel.count, fuel.slot) fuel.count = fuel.count + d farming turtle scrits How to dowload it? farming turtle scrits elseif seed and seed.count < seed.limit and item == seed.name then local d = chest.pushItems(name, i, seed.limit - seed.count, seed.slot) seed.count = seed.count + d end end if not next(inventory) then break end end if not next(inventory) then break end end if next(inventory) then farming turtle scrits How to get it? farming turtle scrits for _, chest in ipairs{peripheral.find("minecraft:chest")} do local items = chest.list() for i = 1, chest.size() do if not items[i] then local item, list = next(inventory) for slot, count in pairs(list) do local d = chest.pullItems(name, slot, count, i) if d == 0 then break end if count - d <= 0 then list[slot] = nil else list[slot] = count - d end farming turtle scrits How to get it for free? farming turtle scrits end if not next(list) then inventory[item] = nil end end if not next(inventory) then break end end if not next(inventory) then break end end end if not fuel or not seed then for _, chest in ipairs{peripheral.find("minecraft:chest")} do farming turtle scrits PasteShr farming turtle scrits local items = chest.list() for i = 1, chest.size() do if items[i] and ((fuel and items[i].name == fuel.name and fuel.count < fuel.limit) or (not fuel and fuels[items[i].name])) then local d = chest.pushItems(name, i, fuel and fuel.count - fuel.limit, 16) if fuel then fuel.count = fuel.count + d else fuel = {name = items[i].name, count = d, limit = turtle.getItemSpace(16)} end end if items[i] and ((seed and items[i].name == seed.name and seed.count < seed.limit) or (not seed and seedItems[items[i].name])) then local d = chest.pushItems(name, i, seed and seed.count - seed.limit, 1) if seed then seed.count = seed.count + d farming turtle scrits How to get it for free? farming turtle scrits else seed = {name = items[i].name, count = d, limit = turtle.getItemSpace(1)} end end if (fuel and fuel.count >= fuel.limit) and (seed and seed.count >= seed.limit) then break end end if (fuel and fuel.count >= fuel.limit) and (seed and seed.count >= seed.limit) then break end end end end if fs.exists("jackmacwindows.farm-state.txt") then farming turtle scrits How to use it? farming turtle scrits local file = fs.open("jackmacwindows.farm-state.txt", "r") x, y, z, direction = tonumber(file.readLine()), tonumber(file.readLine()), tonumber(file.readLine()), tonumber(file.readLine()) invertDirection = file.readLine() == "true" file.close() -- check if we were on a boundary block first local found, block, ok, err, boundary local lastY = y repeat found, block = turtle.inspectDown() if not found then check(down()) end farming turtle scrits PasteShr farming turtle scrits until found if groundBlocks[block.name] then check(up()) turtle.digDown() elseif not cropBlocks[block.name] then if y == lastY then lastY = lastY + 1 end while y < lastY do check(up()) end while not back() do check(up()) end boundary = true end farming turtle scrits How to get it? farming turtle scrits if direction == 1 or direction == 3 then -- we were in the middle of a rotation, finish that before continuing local mv = (direction == 0) == invertDirection and left or right if boundary then check(mv()) check(mv()) check(tryForward()) invertDirection = not invertDirection mv = mv == left and right or left writePos() farming turtle scrits PasteShr farming turtle scrits end check(mv()) handleCrop() if x == 0 and z == 0 then while y > 0 do check(down()) end while y < 0 do check(up()) end exchangeItems() end end elseif not peripheral.find("minecraft:chest") or not peripheral.find("modem", function(_, m) return not m.isWireless() end) then farming turtle scrits How to get it for free? farming turtle scrits print[[ Please move the turtle to the starting position next to a modem with a chest. The expected setup is the turtle next to a wired modem block, with a chest next to that modem block. This program cannot run until placed correctly. ]] return else exchangeItems() end local ok, err while true do farming turtle scrits How to get it for free? farming turtle scrits ok, err = tryForward() if not ok then if err == "Out of bounds" then local mv = (direction == 0) == invertDirection and left or right check(mv()) ok, err = tryForward() if not ok then if err == "Out of bounds" then check(mv()) check(mv()) farming turtle scrits How to get it for free? farming turtle scrits check(tryForward()) invertDirection = not invertDirection mv = mv == left and right or left writePos() else panic(err) end end check(mv()) else panic(err) end end handleCrop() farming turtle scrits How to dowload it? farming turtle scrits if x == 0 and z == 0 then while y > 0 do check(down()) end while y < 0 do check(up()) end exchangeItems() elseif peripheral.find("modem") then x, y, z = 0, 0, 0 exchangeItems() end if turtle.getFuelLevel() < 100 then refuel() end end farming turtle scrits How to get it? farming turtle scrits farming turtle scrits