Advertisement
Blackhome

PotatoFarmer

Jun 24th, 2025 (edited)
402
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.54 KB | Gaming | 0 0
  1. -- pastebin get neAN4a60 PotatoFarmer
  2.  
  3. local numberLevels = ...
  4.  
  5. if numberLevels then
  6.     numberLevels = tonumber(numberLevels)
  7. else
  8.     numberLevels = 1
  9. end
  10.  
  11. local turtlePos, direction
  12. local startPos, startDir
  13.  
  14. local Settings = {
  15.     vertDiff = 5
  16. }
  17.  
  18. local function getGPSPosition()
  19.     local x, y, z = gps.locate()
  20.     if not x then print("Error: GPS not available") return nil end
  21.     return {x = math.floor(x), y = math.floor(y), z = math.floor(z)}
  22. end
  23.  
  24. local function negative(vec)
  25.     return {x = -vec.x, y = -vec.y, z = -vec.z}
  26. end
  27.  
  28. local function add(vec1, vec2)
  29.     return {x = vec1.x + vec2.x, y = vec1.y + vec2.y, z = vec1.z + vec2.z}
  30. end
  31. local function sub(vec1, vec2)
  32.     return add(vec1, negative(vec2))
  33. end
  34.  
  35. local function multiply(s, vec)
  36.     return {x = s * vec.x, y = s * vec.y, z = s * vec.z}
  37. end
  38.  
  39. local function getSign(number)
  40.     return number / math.abs(number)
  41. end
  42.  
  43. local function isEqual(vec1, vec2)
  44.     return vec1.x == vec2.x and vec1.y == vec2.y and vec1.z == vec2.z
  45. end
  46.  
  47.  
  48. -- === Basic Movement ===
  49.  
  50. local function moveForward()
  51.     if turtle.forward() then
  52.         turtlePos = add(turtlePos, direction)
  53.         return true
  54.     end
  55.     return false
  56. end
  57. local function moveUp()
  58.     if turtle.up() then
  59.         turtlePos.y = turtlePos.y + 1
  60.         return true
  61.     end
  62.     return false
  63. end
  64.  
  65. local function moveDown()
  66.     if turtle.down() then
  67.         turtlePos.y = turtlePos.y - 1
  68.         return true
  69.     end
  70.     return false
  71. end
  72.  
  73.  
  74. -- === Basic Turning ===
  75.  
  76. local function turnInDirection(dir)
  77.     if not direction then return end
  78.     if dir == "left" then
  79.         turtle.turnLeft()
  80.         direction = {x = direction.z, y = 0, z = -direction.x}
  81.     elseif dir == "right" then
  82.         turtle.turnRight()
  83.         direction = {x = -direction.z, y = 0, z = direction.x}
  84.     elseif dir == "around" then
  85.         turtle.turnLeft()
  86.         turtle.turnLeft()
  87.         direction = {x = -direction.x, y = 0, z = -direction.z}
  88.     end
  89. end
  90.  
  91. local function getTurnDirection(from, to)
  92.     local function vectorsEqual(a, b)
  93.         return a.x == b.x and a.z == b.z
  94.     end
  95.  
  96.     if vectorsEqual(from, to) then return nil end
  97.     local left  = {x = from.z, y = 0, z = -from.x}
  98.     local right = {x = -from.z, y = 0, z = from.x}
  99.     local back  = {x = -from.x, y = 0, z = -from.z}
  100.     if vectorsEqual(to, left) then
  101.         return "left"
  102.     elseif vectorsEqual(to, right) then
  103.         return "right"
  104.     elseif vectorsEqual(to, back) then
  105.         return "around"
  106.     else
  107.         error("Invalid target direction")
  108.     end
  109. end
  110.  
  111. local function getDirection()
  112.     local pos1 = getGPSPosition()
  113.     if not pos1 then error("GPS failure, cannot get direction") end
  114.  
  115.     for i = 1, 4 do
  116.         if turtle.forward() then
  117.             local pos2 = getGPSPosition()
  118.             if not pos2 then error("GPS failure after move") end
  119.             -- turtlePos = pos2
  120.             -- Richtung berechnen
  121.             direction = sub(pos2, pos1)
  122.  
  123.             -- zurück zur ursprünglichen Position
  124.             turnInDirection("around")
  125.             moveForward()
  126.  
  127.             -- Sicherheitsprüfung
  128.             local posBack = getGPSPosition()
  129.             if not isEqual(pos1, posBack) then
  130.                 error("Warnung: Position hat sich beim Rückweg verschoben!")
  131.                 turtlePos = posBack -- explizit wieder auf GPS setzen
  132.             else
  133.                 turtlePos = pos1
  134.             end
  135.  
  136.             turnInDirection("around")
  137.             return
  138.         else
  139.             turtle.turnLeft()
  140.         end
  141.     end
  142.  
  143.     error("Unable to move forward in any direction for direction detection")
  144. end
  145.  
  146.  
  147. -- === Positioning ===
  148.  
  149. local function goToLift()
  150.     local coord = add(startPos, startDir)
  151.  
  152.     local deltaX = coord.x - turtlePos.x
  153.     local deltaZ = coord.z - turtlePos.z
  154.  
  155.     local dirX = startDir.x
  156.     local dirZ = startDir.z
  157.  
  158.     local function moveToEqualX()
  159.         while not (deltaX == 0) do
  160.             turnInDirection(getTurnDirection(direction, {x = getSign(deltaX), y = 0, z = 0}))
  161.             moveForward()
  162.             deltaX = coord.x - turtlePos.x
  163.         end
  164.     end
  165.  
  166.     local function moveToEqualZ()
  167.         while not (deltaZ == 0) do
  168.             turnInDirection(getTurnDirection(direction, {x = 0, y = 0, z = getSign(deltaZ)}))
  169.             moveForward()
  170.             deltaZ = coord.z - turtlePos.z
  171.         end
  172.     end
  173.  
  174.     if dirX == 0 then
  175.         moveToEqualX()
  176.         moveToEqualZ()
  177.     elseif dirZ == 0 then
  178.         moveToEqualZ()
  179.         moveToEqualX()
  180.     end
  181. end
  182.  
  183. local function goToPos(coord)
  184.     local deltaX = coord.x - turtlePos.x
  185.     local deltaY = coord.y - turtlePos.y
  186.     local deltaZ = coord.z - turtlePos.z
  187.  
  188.     local dirX = startDir.x
  189.     local dirZ = startDir.z
  190.  
  191.     local function moveToEqualX()
  192.         while not (deltaX == 0) do
  193.             turnInDirection(getTurnDirection(direction, {x = getSign(deltaX), y = 0, z = 0}))
  194.             moveForward()
  195.             deltaX = coord.x - turtlePos.x
  196.         end
  197.     end
  198.  
  199.     local function moveToEqualZ()
  200.         while not (deltaZ == 0) do
  201.             turnInDirection(getTurnDirection(direction, {x = 0, y = 0, z = getSign(deltaZ)}))
  202.             moveForward()
  203.             deltaZ = coord.z - turtlePos.z
  204.         end
  205.     end
  206.  
  207.     local function moveToEqualY()
  208.         while not (deltaY == 0) do
  209.             if deltaY > 0 then
  210.                 moveUp()
  211.             elseif deltaY < 0 then
  212.                 moveDown()
  213.             end
  214.             deltaY = coord.y - turtlePos.y
  215.         end
  216.     end
  217.  
  218.     if not (deltaY == 0) then
  219.         goToLift()
  220.         moveToEqualY()
  221.         deltaX = coord.x - turtlePos.x
  222.         deltaZ = coord.z - turtlePos.z
  223.     end
  224.     if dirX == 0 then
  225.         moveToEqualZ()
  226.         moveToEqualX()
  227.     elseif dirZ == 0 then
  228.         moveToEqualX()
  229.         moveToEqualZ()
  230.     end
  231. end
  232.  
  233.  
  234. -- === Tasks ===
  235.  
  236. local function isPotato(item)
  237.     if not item or not item.name then return false end
  238.     return item.name == "minecraft:potatoes" or item.name == "minecraft:potato"
  239. end
  240.  
  241. local function getAge(item)
  242.     return item.state and item.state.age or nil
  243. end
  244.  
  245. local function getPotatoCount()
  246.     local numPotatoes = 0
  247.     for i = 1, 16 do
  248.         local item = turtle.getItemDetail(i)
  249.        
  250.         if isPotato(item) then
  251.             numPotatoes = numPotatoes + turtle.getItemCount(i)
  252.         end
  253.     end
  254.     return numPotatoes
  255. end
  256.  
  257. local function selectPotatoSlot()
  258.     for i = 1, 16 do
  259.         local item = turtle.getItemDetail(i)
  260.        
  261.         if isPotato(item) then
  262.             turtle.select(i)
  263.             return true
  264.         end
  265.     end
  266.     return false
  267. end
  268.  
  269. local function harvestAndPlantPotato()
  270.     local success, item = turtle.inspectDown()
  271.  
  272.     if (not success) or (isPotato(item) and getAge(item) == 7) then
  273.         turtle.digDown()
  274.         selectPotatoSlot()
  275.         turtle.placeDown()
  276.     end
  277. end
  278.  
  279. local function harvestField()
  280.     -- Get in position
  281.     goToLift()
  282.     turnInDirection(getTurnDirection(direction, startDir))
  283.     moveUp()
  284.     local cntRow = 1
  285.     local notFinished = true
  286.  
  287.     local function turnToNextRow(turnDir)
  288.         turnInDirection(turnDir)
  289.         if not moveForward() then
  290.             return false
  291.         end
  292.         if cntRow % 6 == 3 then
  293.             if not moveForward() then
  294.                 return false
  295.             end
  296.         end
  297.         turnInDirection(turnDir)
  298.         return true
  299.     end
  300.  
  301.     while true do
  302.         -- Move forward till wall then turn next row
  303.         if isEqual(direction, startDir) then
  304.             if not moveForward() then
  305.                 if not turnToNextRow("right") then
  306.                     -- stops at last harvested block, does not go back
  307.                     break
  308.                 else
  309.                     cntRow = cntRow + 1
  310.                 end
  311.             end
  312.         -- Move forward till distance of 2 in start directional coordinate to startPos
  313.         else
  314.             local testCoord = add(turtlePos, multiply(2, direction))
  315.             local condition1 = (not (startDir.x == 0)) and (testCoord.x == startPos.x)
  316.             local condition2 = (not (startDir.z == 0)) and (testCoord.z == startPos.z)
  317.  
  318.             if condition1 or condition2 then
  319.                 if not turnToNextRow("left") then
  320.                     -- stops at last harvested block, does not go back
  321.                     break
  322.                 else
  323.                     cntRow = cntRow + 1
  324.                 end
  325.             else
  326.                 moveForward()
  327.             end
  328.         end
  329.         -- harvest block below
  330.         harvestAndPlantPotato()
  331.     end
  332. end
  333.  
  334. -- === Inventory Management ===
  335.  
  336. local function dumpInventoryKeepPotatoes()
  337.     local success, chest = turtle.inspect()
  338.     while not (success and chest.name == "minecraft:chest") do
  339.         print("No chest found. Pls place one in front.")
  340.         print("Press enter to continue.")
  341.         read()
  342.         success, chest = turtle.inspect()
  343.     end
  344.  
  345.     local potatoesKept = 0
  346.  
  347.     for slot = 1, 16 do
  348.         local item = turtle.getItemDetail(slot)
  349.         if item then
  350.             turtle.select(slot)
  351.             if isPotato(item) and potatoesKept < 10 then
  352.                 local keep = math.min(item.count, 10 - potatoesKept)
  353.                 local drop = item.count - keep
  354.                 if drop > 0 then
  355.                     turtle.drop(drop)
  356.                 end
  357.                 potatoesKept = potatoesKept + keep
  358.             else
  359.                 turtle.drop()
  360.             end
  361.         end
  362.     end
  363.  
  364.     turtle.select(1)
  365. end
  366.  
  367. local function turtleNeedsFuel()
  368.     local fuelLevel = turtle.getFuelLevel()
  369.  
  370.     if fuelLevel < 1000 then
  371.         if not isEqual(startPos, turtlePos) then
  372.             goToPos(startPos)
  373.         end
  374.         print("Turtle needs more fuel")
  375.         return true
  376.     end
  377.     return false
  378. end
  379.  
  380.  
  381. -- === Initialization ===
  382.  
  383. local function saveStartingParameters()
  384.     local parameterList = {pos = turtlePos, dir = direction, numLevels = numberLevels}
  385.  
  386.     local file = fs.open("startingParameters.txt", "w")
  387.     file.write(textutils.serialize(parameterList))
  388.     file.close()
  389. end
  390.  
  391. local function loadStartingParameters()
  392.     if not fs.exists("startingParameters.txt") then return false end
  393.  
  394.     local file = fs.open("startingParameters.txt", "r")
  395.     local data = textutils.unserialize(file.readAll())
  396.  
  397.     file.close()
  398.  
  399.     startPos = data.pos
  400.     startDir = data.dir
  401.     numberLevels = data.numLevels
  402.     return true
  403. end
  404.  
  405. local function initProgram()
  406.     turtlePos = getGPSPosition()
  407.     if not turtlePos then error("GPS failure, cannot run the program") end
  408.    
  409.     getDirection()
  410.  
  411.     if not loadStartingParameters() then
  412.         startPos = turtlePos
  413.         startDir = direction
  414.         saveStartingParameters()
  415.     end
  416. end
  417.  
  418.  
  419.  
  420. local function main()
  421.     local cnt = 0
  422.     while true do
  423.         if turtleNeedsFuel() then
  424.             return
  425.         end
  426.         local level = cnt % numberLevels
  427.         local posLift = add(startPos, startDir)
  428.         local vecUp = {x = 0, y = Settings.vertDiff * level, z = 0}
  429.  
  430.         local posNextField = add(posLift, vecUp)
  431.  
  432.         -- Go to field and harvest it
  433.         goToPos(posNextField)
  434.         harvestField()
  435.  
  436.         -- Go to start and dump inventory
  437.         if cnt % 2 == 1 then
  438.             goToPos(startPos)
  439.             turnInDirection(getTurnDirection(direction, negative(startDir)))
  440.             dumpInventoryKeepPotatoes()
  441.         end
  442.         cnt = cnt + 1
  443.     end
  444. end
  445.  
  446.  
  447.  
  448.  
  449. initProgram()
  450. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement