DabDaddy6223

crop_farm.lua

Jun 11th, 2026 (edited)
300
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.42 KB | None | 0 0
  1. ----------------------------------------------------------------------------------------------------------------------------
  2. -- TURTLE MUST BE PLACED IN CENTRE OF 9x9 FARM. BY DEFAULT, IT FACES SOUTH. SET face_north TO true IF YOU WANT IT ROTATED --
  3. -- ITEMS WILL BE OUTPUTTED AT THE CENTRE OF THE OPPOSITE WALL TO ITS STARTING FACING DIRECTION -----------------------------
  4. ----------------------------------------------------------------------------------------------------------------------------
  5.  
  6. -- API --------------------------------------------------
  7. FUEL_ITEMS = {"minecraft:coal", "minecraft:charcoal"}
  8. FUEL_SLOT = -1
  9. FUEL_COUNT = 0
  10.  
  11. function hasValue (tab, val)
  12.     for index, value in ipairs(tab) do
  13.         if value == val then
  14.             return true
  15.         end
  16.     end
  17.  
  18.     return false
  19. end
  20.  
  21. function printKeys(tab)
  22.     -- Source - https://stackoverflow.com/a/12674376
  23.     -- Posted by lhf
  24.     -- Retrieved 2026-06-11, License - CC BY-SA 3.0
  25.  
  26.     local keyset={}
  27.     local n=0
  28.  
  29.     for k,v in pairs(tab) do
  30.         n=n+1
  31.         keyset[n]=k
  32.     end
  33.  
  34.     print(textutils.serialise(keyset))
  35. end
  36.  
  37. function turnAround()
  38.     turtle.turnRight()
  39.     turtle.turnRight()
  40. end
  41.  
  42. function findItemInInventory(item_name)
  43.     for i=1,16 do
  44.         local item = turtle.getItemDetail(i)
  45.         if item ~= nil then
  46.             if item["name"] == item_name then
  47.                 return i, item["count"]
  48.             end
  49.         end
  50.     end
  51.  
  52.     return -1, 0
  53. end
  54.  
  55. function itemIsFuel(item_name)
  56.     return hasValue(FUEL_ITEMS, item_name)
  57. end
  58.  
  59. function refuelIfNeeded()
  60.     local level = turtle.getFuelLevel()
  61.     if level == "unlimited" then print("Turtle does not need fuel") return end
  62.  
  63.     if FUEL_COUNT == 0 then
  64.        FUEL_SLOT = -1
  65.     end
  66.    
  67.     if FUEL_SLOT == -1 then
  68.         for i=1,16 do
  69.             local item = turtle.getItemDetail(i)
  70.             if item ~= nil then
  71.                if itemIsFuel(item["name"]) then
  72.                     FUEL_SLOT = i
  73.                     FUEL_COUNT = item["count"]
  74.                end
  75.             end
  76.         end
  77.     end
  78.  
  79.     if FUEL_SLOT ~= -1 then
  80.         turtle.select(FUEL_SLOT)
  81.         if level == 0 then
  82.             turtle.refuel(1)
  83.             FUEL_COUNT = FUEL_COUNT - 1
  84.         end
  85.         return true
  86.     else
  87.         print("No fuel found!")
  88.         return false
  89.     end
  90. end
  91.  
  92. function calculateFacingDirection()
  93.     refuelIfNeeded()
  94.  
  95.     local start_x, _, start_z = gps.locate()
  96.     turtle.forward()
  97.     local end_x, _, end_z = gps.locate()
  98.     turtle.back()
  99.  
  100.     if start_x == end_x then
  101.         -- Moved in Z direction
  102.         local difference = end_z - start_z
  103.         if difference > 0 then
  104.             return "south"
  105.         else
  106.             return "north"
  107.         end
  108.     else
  109.         -- Moved in X direction
  110.         local difference = end_x - start_x
  111.         if difference > 0 then
  112.             return "east"
  113.         else
  114.             return "west"
  115.         end
  116.     end
  117. end
  118.  
  119. function faceTargetDirection(target_direction, current_direction)
  120.     local directions = {
  121.         north = 0,
  122.         east  = 1,
  123.         south = 2,
  124.         west  = 3
  125.     }
  126.  
  127.     local target = directions[target_direction]
  128.     local current = directions[current_direction]
  129.  
  130.     if not target or not current then
  131.         error("Invalid direction")
  132.     end
  133.  
  134.     local difference = (target - current) % 4
  135.  
  136.     if difference == 1 then
  137.         turtle.turnRight()
  138.     elseif difference == 2 then
  139.         turnAround()
  140.     elseif difference == 3 then
  141.         turtle.turnLeft()
  142.     end
  143.     -- difference == 0 means we're already facing the correct direction
  144. end
  145.  
  146. function moveToTargetPosition(pos_x, pos_y, pos_z)
  147.     print("Moving to: " .. pos_x .. ", " .. pos_y .. ", " .. pos_z)
  148.  
  149.     local current_x, current_y, current_z = gps.locate()
  150.     local facing_direction = calculateFacingDirection()
  151.  
  152.     -- Move along X
  153.     if current_x < pos_x then
  154.         faceTargetDirection("east", facing_direction)
  155.  
  156.         while current_x < pos_x do
  157.             turtle.forward()
  158.             current_x = current_x + 1
  159.         end
  160.  
  161.         facing_direction = "east"
  162.     elseif current_x > pos_x then
  163.         faceTargetDirection("west", facing_direction)
  164.  
  165.         while current_x > pos_x do
  166.             turtle.forward()
  167.             current_x = current_x - 1
  168.         end
  169.  
  170.         facing_direction = "west"
  171.     end
  172.  
  173.     -- Move along Z
  174.     if current_z < pos_z then
  175.         faceTargetDirection("south", facing_direction)
  176.  
  177.         while current_z < pos_z do
  178.             turtle.forward()
  179.             current_z = current_z + 1
  180.         end
  181.  
  182.         facing_direction = "south"
  183.     elseif current_z > pos_z then
  184.         faceTargetDirection("north", facing_direction)
  185.  
  186.         while current_z > pos_z do
  187.             turtle.forward()
  188.             current_z = current_z - 1
  189.         end
  190.  
  191.         facing_direction = "north"
  192.     end
  193.  
  194.     -- Move along Y
  195.     while current_y < pos_y do
  196.         turtle.up()
  197.         current_y = current_y + 1
  198.     end
  199.  
  200.     while current_y > pos_y do
  201.         turtle.down()
  202.         current_y = current_y - 1
  203.     end
  204.  
  205.     return facing_direction
  206. end
  207.  
  208. ---------------------------------------------------------
  209.  
  210. SEED_SLOT = -1
  211. SEED_COUNT = 0
  212.  
  213. CROP_CONTROLLER_ID = -1
  214.  
  215. FACING_NORTH = false
  216.  
  217. local function turnLeft()
  218.     if FACING_NORTH then
  219.         turtle.turnRight()
  220.     else
  221.         turtle.turnLeft()
  222.     end
  223. end
  224.  
  225. local function turnRight()
  226.     if FACING_NORTH then
  227.         turtle.turnLeft()
  228.     else
  229.         turtle.turnRight()
  230.     end
  231. end
  232.  
  233. local function moveAndFarm(crop_name)
  234.     if refuelIfNeeded() ~= true then
  235.         return
  236.     end
  237.  
  238.     turtle.forward()
  239.     local exists, block = turtle.inspectDown()
  240.  
  241.     if exists == true then
  242.         if block["name"] == crop_name then
  243.             if block["state"]["age"] == 7 then
  244.                 turtle.digDown()
  245.             end
  246.         end
  247.     end
  248.    
  249.     turtle.suckDown()
  250. end
  251.  
  252. local function moveAndPlant(seed_item)
  253.     if refuelIfNeeded() ~= true then
  254.         rednet.send(CROP_CONTROLLER_ID, "crop_worker_no_fuel")
  255.         return
  256.     end
  257.  
  258.     turtle.forward()
  259.     local exists, block = turtle.inspectDown()
  260.  
  261.     if exists == false then
  262.         if SEED_COUNT == 0 then
  263.             SEED_SLOT = -1
  264.         end
  265.  
  266.         if SEED_SLOT == -1 then
  267.             local seed_slot, seed_count = findItemInInventory(seed_item)
  268.             if seed_slot == -1 then
  269.                 print("No seeds!!!")
  270.                 rednet.send(CROP_CONTROLLER_ID, "crop_worker_no_seeds")
  271.             end
  272.  
  273.             SEED_SLOT = seed_slot
  274.             SEED_COUNT = seed_count
  275.         end
  276.  
  277.         if SEED_SLOT ~= -1 then
  278.             turtle.select(SEED_SLOT)
  279.             turtle.placeDown()
  280.             SEED_COUNT = SEED_COUNT - 1    
  281.         end
  282.     end
  283.  
  284.     turtle.suckDown()
  285. end
  286.  
  287. local function harvest(crop_name)
  288.     -- Move to South edge
  289.     for i=1,4 do
  290.        moveAndFarm(crop_name)
  291.     end
  292.  
  293.     for j=1,2 do
  294.         -- Turn
  295.         turnLeft()
  296.         moveAndFarm(crop_name)
  297.         turnLeft()
  298.  
  299.         -- Move to North edge
  300.         for i=1,8 do
  301.             moveAndFarm(crop_name)
  302.         end
  303.  
  304.         -- Turn
  305.         turnRight()
  306.         moveAndFarm(crop_name)
  307.         turnRight()
  308.  
  309.         -- Move to South edge
  310.         for i=1,8 do
  311.             moveAndFarm(crop_name)
  312.         end
  313.     end
  314.  
  315.     turnRight()
  316.  
  317.     for i=1,8 do
  318.         moveAndFarm(crop_name)
  319.     end
  320.  
  321.     turnRight()
  322.  
  323.     for j=1,2 do
  324.         -- Move to North edge
  325.         for i=1,8 do
  326.             moveAndFarm(crop_name)
  327.         end
  328.  
  329.         -- Turn
  330.         turnRight()
  331.         moveAndFarm(crop_name)
  332.         turnRight()
  333.  
  334.         -- Move to South edge
  335.         for i=1,8 do
  336.             moveAndFarm(crop_name)
  337.         end
  338.  
  339.         -- Turn
  340.         turnLeft()
  341.         moveAndFarm(crop_name)
  342.         turnLeft()
  343.     end
  344.  
  345.     -- Move to North edge
  346.     for i=1,8 do
  347.         moveAndFarm(crop_name)
  348.     end
  349.  
  350.     -- Move back to origin
  351.     turnAround()
  352.  
  353.     for i=1,4 do
  354.         moveAndFarm(crop_name)
  355.     end
  356. end
  357.  
  358. local function plant(seed_name)
  359.     -- Move to South edge
  360.     for i=1,4 do
  361.        moveAndPlant(seed_name)
  362.     end
  363.  
  364.     for j=1,2 do
  365.         -- Turn
  366.         turnLeft()
  367.         moveAndPlant(seed_name)
  368.         turnLeft()
  369.  
  370.         -- Move to North edge
  371.         for i=1,8 do
  372.             moveAndPlant(seed_name)
  373.         end
  374.  
  375.         -- Turn
  376.         turnRight()
  377.         moveAndPlant(seed_name)
  378.         turnRight()
  379.  
  380.         -- Move to South edge
  381.         for i=1,8 do
  382.             moveAndPlant(seed_name)
  383.         end
  384.     end
  385.  
  386.     turnRight()
  387.  
  388.     for i=1,8 do
  389.         moveAndPlant(seed_name)
  390.     end
  391.  
  392.     turnRight()
  393.  
  394.     for j=1,2 do
  395.         -- Move to North edge
  396.         for i=1,8 do
  397.             moveAndPlant(seed_name)
  398.         end
  399.  
  400.         -- Turn
  401.         turnRight()
  402.         moveAndPlant(seed_name)
  403.         turnRight()
  404.  
  405.         -- Move to South edge
  406.         for i=1,8 do
  407.             moveAndPlant(seed_name)
  408.         end
  409.  
  410.         -- Turn
  411.         turnLeft()
  412.         moveAndPlant(seed_name)
  413.         turnLeft()
  414.     end
  415.  
  416.     -- Move to North edge
  417.     for i=1,8 do
  418.         moveAndPlant(seed_name)
  419.     end
  420.  
  421.     -- Dump to chest
  422.     for i=1,16 do
  423.         turtle.select(i)
  424.         local item = turtle.getItemDetail()
  425.         if item ~= nil then
  426.             if itemIsFuel(item["name"]) ~= true then
  427.                 turtle.drop(item["count"])
  428.             end
  429.         end
  430.     end
  431.  
  432.     -- Move back to origin
  433.     turnAround()
  434.  
  435.     for i=1,4 do
  436.         moveAndPlant(seed_name)
  437.     end
  438. end
  439.  
  440. local function main(...)
  441.     local turtle_name, crop_name, seed_name = ...
  442.     print(turtle_name)
  443.     print(crop_name)
  444.     print(seed_name)
  445.  
  446.     if fs.exists("/start_position.txt") == true then
  447.         -- Move towards the intended start position
  448.         local file = fs.open("/start_position.txt", "r")
  449.         local target_x = file.readLine()
  450.         local target_y = file.readLine()
  451.         local target_z = file.readLine()
  452.         local target_facing = file.readLine()
  453.         file.close()
  454.  
  455.         local facing_direction = moveToTargetPosition(tonumber(target_x), tonumber(target_y), tonumber(target_z))
  456.         faceTargetDirection(target_facing, facing_direction)
  457.     else
  458.         local start_x, start_y, start_z = gps.locate()
  459.         local facing_direction = calculateFacingDirection()
  460.  
  461.         local file = fs.open("/start_position.txt", "w")
  462.         file.writeLine(start_x)
  463.         file.writeLine(start_y)
  464.         file.writeLine(start_z)
  465.         file.writeLine(facing_direction)
  466.         file.close()
  467.     end
  468.  
  469.     peripheral.find("modem", rednet.open)
  470.  
  471.     repeat
  472.         local id, message = rednet.receive()
  473.         if message == "crop_controller_ping" then
  474.             CROP_CONTROLLER_ID = id
  475.             rednet.send(CROP_CONTROLLER_ID, "crop_worker_pong")
  476.         end
  477.     until CROP_CONTROLLER_ID ~= -1
  478.  
  479.     print("Connected")
  480.  
  481.     while true do
  482.         local id, message = rednet.receive()
  483.         if id == CROP_CONTROLLER_ID then
  484.             if message == "crop_controller_identify" then
  485.                 rednet.send(CROP_CONTROLLER_ID, turtle_name)
  486.             end
  487.             if message == "crop_controller_harvest" then
  488.                 harvest(crop_name)
  489.                 plant(seed_name)
  490.                 rednet.send(CROP_CONTROLLER_ID, "crop_worker_finished")
  491.             end
  492.         end
  493.     end
  494. end
  495.  
  496. main(...)
Advertisement
Add Comment
Please, Sign In to add comment