Blackhome

StorageTurtle

Jun 5th, 2025 (edited)
445
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 64.58 KB | None | 0 0
  1.     --   pastebin get bSBgdCDF StorageTurtle
  2.  
  3.     local TASK_FILE = "task_list.txt"
  4.     local STATUS_FILE = "status.txt"
  5.  
  6.     TaskStatus = {
  7.         getTask = 0,
  8.         accepted = 1,
  9.         inProgress = 2,
  10.         finished = 3,
  11.         completing = 4,
  12.         joiningQueue = 5,
  13.         waiting = 6,
  14.         refuelNeeded = 7,
  15.         refueling = 8,
  16.         noTask = 9
  17.     }
  18.  
  19.     local DISK_NAMES = {
  20.         incoming = "Incoming Task",
  21.         user = "User Task",
  22.         outgoing = "Outgoing Task",
  23.         finished = "Finished Task",
  24.         settings = "Settings",
  25.         storage = "Data Storage",
  26.         init = "Turtle Initializing"
  27.     }
  28.  
  29.         -- === Initializing Variables ===
  30.     local orientation, direction, modulo, yModulo
  31.     local finishCoord, outputCoord, refuelCoord
  32.     local directionVectors
  33.  
  34.     local leftBeltCoord, rightBeltCoord
  35.  
  36.     local facingVec
  37.     local turtlePos
  38.  
  39.  
  40.         -- === Utility ===
  41.     local function readInitData()
  42.         local localPath = "init.txt"
  43.         local initFile
  44.  
  45.         -- Prüfe, ob bereits eine lokale Init-Datei existiert
  46.         if fs.exists(localPath) then
  47.             initFile = fs.open(localPath, "r")
  48.         else
  49.             -- Wenn nicht vorhanden, von Init-Disk lesen
  50.             local initDiskPath
  51.             for _, side in ipairs(peripheral.getNames()) do
  52.                 if peripheral.getType(side) == "drive" then
  53.                     local disk = peripheral.wrap(side)
  54.                     if disk.getDiskLabel() == "Turtle Initializing" then
  55.                         initDiskPath = disk.getMountPath()
  56.                         break
  57.                     end
  58.                 end
  59.             end
  60.             if not initDiskPath then error("Init disk not found") end
  61.  
  62.             local diskFilePath = fs.combine(initDiskPath, "init.txt")
  63.             if not fs.exists(diskFilePath) then
  64.                 error("init.txt not found on disk")
  65.             end
  66.  
  67.             -- Lese Daten von Disk
  68.             initFile = fs.open(diskFilePath, "r")
  69.  
  70.             -- Speichere eine Kopie lokal
  71.             local diskData = initFile.readAll()
  72.             initFile.close()
  73.             initFile = fs.open(localPath, "w")
  74.             initFile.write(diskData)
  75.             initFile.close()
  76.  
  77.             -- Öffne neu zum Parsen
  78.             initFile = fs.open(localPath, "r")
  79.         end
  80.  
  81.         -- Parse Inhalte
  82.         local orientation = initFile.readLine():match("orientation=(%a+)")
  83.         local direction = tonumber(initFile.readLine():match("direction=(%-?%d+)"))
  84.         local modulo = tonumber(initFile.readLine():match("modulo=(%d+)"))
  85.         local yModulo = tonumber(initFile.readLine():match("yModulo=(%d+)"))
  86.  
  87.         local x1 = tonumber(initFile.readLine():match("finish_x=(%-?%d+)"))
  88.         local y1 = tonumber(initFile.readLine():match("finish_y=(%-?%d+)"))
  89.         local z1 = tonumber(initFile.readLine():match("finish_z=(%-?%d+)"))
  90.  
  91.         local x2 = tonumber(initFile.readLine():match("output_x=(%-?%d+)"))
  92.         local y2 = tonumber(initFile.readLine():match("output_y=(%-?%d+)"))
  93.         local z2 = tonumber(initFile.readLine():match("output_z=(%-?%d+)"))
  94.  
  95.         local x3 = tonumber(initFile.readLine():match("refuel_x=(%-?%d+)"))
  96.         local y3 = tonumber(initFile.readLine():match("refuel_y=(%-?%d+)"))
  97.         local z3 = tonumber(initFile.readLine():match("refuel_z=(%-?%d+)"))
  98.  
  99.  
  100.         local finishPos = {x = x1, y = y1, z = z1}
  101.         local outputPos = {x = x2, y = y2, z = z2}
  102.         local refuelPos = {x = x3, y = y3, z = z3}
  103.  
  104.         initFile.close()
  105.  
  106.         return orientation, direction, modulo, yModulo, finishPos, outputPos, refuelPos
  107.     end
  108.  
  109.     local function getDiskByLabel(label)
  110.         for _, side in ipairs(peripheral.getNames()) do
  111.             if peripheral.getType(side) == "drive" then
  112.                 local disk = peripheral.wrap(side)
  113.                 if disk.getDiskLabel() == label then
  114.                     return disk, disk.getMountPath()
  115.                 end
  116.             end
  117.         end
  118.         return nil, nil
  119.     end
  120.  
  121.     local function isDiskOnSide(label, turtleSide)
  122.         for _, side in ipairs(peripheral.getNames()) do
  123.             if side == turtleSide then
  124.                 if peripheral.getType(side) == "drive" then
  125.                     local disk = peripheral.wrap(side)
  126.                     if disk.getDiskLabel() == label then
  127.                         return true
  128.                     end
  129.                 end
  130.             end
  131.         end
  132.         return false
  133.     end
  134.  
  135.     local function getDirectionVectors(orientation, direction)
  136.         if orientation == "x" then
  137.             return {
  138.                 forward = {x = direction, y = 0, z = 0},
  139.                 backward = {x = -direction, y = 0, z = 0},
  140.                 right   = {x = 0, y = 0, z = direction},
  141.                 left   = {x = 0, y = 0, z = -direction},
  142.                 up      = {x = 0, y = 1, z = 0},
  143.                 down      = {x = 0, y = -1, z = 0}
  144.             }
  145.         elseif orientation == "z" then
  146.             return {
  147.                 forward = {x = 0, y = 0, z = direction},
  148.                 backward = {x = 0, y = 0, z = -direction},
  149.                 right   = {x = -direction, y = 0, z = 0},
  150.                 left   = {x = direction, y = 0, z = 0},
  151.                 up      = {x = 0, y = 1, z = 0},
  152.                 down      = {x = 0, y = -1, z = 0}
  153.             }
  154.         else
  155.             error("Invalid orientation")
  156.         end
  157.     end
  158.  
  159.     local function get_GPS_Position()
  160.         local x, y, z = gps.locate()
  161.         if not x then print("Error: GPS not available") return nil end
  162.         return {x = math.floor(x), y = math.floor(y), z = math.floor(z)}
  163.     end
  164.  
  165.     local function add(pos, delta)
  166.         return {
  167.             x = pos.x + delta.x,
  168.             y = pos.y + delta.y,
  169.             z = pos.z + delta.z
  170.         }
  171.     end
  172.  
  173.     local function equalCoords(coord1, coord2)
  174.         return coord1.x == coord2.x and coord1.y == coord2.y and coord1.z == coord2.z
  175.     end
  176.  
  177.     local function substract(pos, delta)
  178.         return {
  179.             x = pos.x - delta.x,
  180.             y = pos.y - delta.y,
  181.             z = pos.z - delta.z
  182.         }
  183.     end
  184.  
  185.     local function getLeftBeltCoordinate(endBlockCoord, dir, orient)
  186.         local leftBeltCoord = add(endBlockCoord, dir)
  187.         if orient == "x" then
  188.             leftBeltCoord.z = 0
  189.         else
  190.             leftBeltCoord.x = 0
  191.         end
  192.         return leftBeltCoord
  193.     end
  194.  
  195.     local function isTurtleBlock(data)
  196.         return data and type(data.name) == "string" and data.name:match("computercraft:turtle")
  197.     end
  198.  
  199.  
  200.     -- === Task Readings + Writings ===
  201.    
  202.     local function getTaskList(path)
  203.         if not fs.exists(path) then return {} end
  204.         local file = fs.open(path, "r")
  205.         local data = textutils.unserialize(file.readAll())
  206.         file.close()
  207.         return data or {}
  208.     end
  209.  
  210.     local function saveTaskList(path, taskList)
  211.         local file = fs.open(path, "w")
  212.         file.write(textutils.serialize(taskList))
  213.         file.close()
  214.     end
  215.  
  216.     local function addTaskToList(path, task)
  217.         local tasks = getTaskList(path)
  218.         table.insert(tasks, task)
  219.         saveTaskList(path, tasks)
  220.     end
  221.  
  222.  
  223.     local function load_status()
  224.         local path = STATUS_FILE
  225.         local file
  226.  
  227.         if fs.exists(path) then
  228.             file = fs.open(path, "r")
  229.         else
  230.             file = fs.open(path, "w")
  231.             file.writeLine("status=" .. tostring(TaskStatus.noTask))
  232.             return TaskStatus.noTask
  233.         end
  234.         local status = tonumber(file.readLine():match("status=(%-?%d+)"))
  235.         file.close()
  236.  
  237.         return status
  238.  
  239.     end
  240.  
  241.     local function save_status(status)
  242.         local path = STATUS_FILE
  243.         local file = fs.open(path, "w")
  244.         file.writeLine("status=" .. tostring(status))
  245.         file.close()
  246.     end
  247.  
  248.  
  249.     -- === Facing and Rotation Management ===
  250.  
  251.     local function turnInDirection(dir)
  252.         if not facingVec then return end
  253.         if dir == "left" then
  254.             turtle.turnLeft()
  255.             facingVec = {x = facingVec.z, y = 0, z = -facingVec.x}
  256.         elseif dir == "right" then
  257.             turtle.turnRight()
  258.             facingVec = {x = -facingVec.z, y = 0, z = facingVec.x}
  259.         elseif dir == "around" then
  260.             turtle.turnLeft()
  261.             turtle.turnLeft()
  262.             facingVec = {x = -facingVec.x, y = 0, z = -facingVec.z}
  263.         end
  264.     end
  265.  
  266.     local function getTurnDirection(from, to)
  267.         local function vectorsEqual(a, b)
  268.             return a.x == b.x and a.z == b.z
  269.         end
  270.  
  271.         if vectorsEqual(from, to) then return nil end
  272.         local left  = {x = from.z, y = 0, z = -from.x}
  273.         local right = {x = -from.z, y = 0, z = from.x}
  274.         local back  = {x = -from.x, y = 0, z = -from.z}
  275.         if vectorsEqual(to, left) then
  276.             return "left"
  277.         elseif vectorsEqual(to, right) then
  278.             return "right"
  279.         elseif vectorsEqual(to, back) then
  280.             return "around"
  281.         else
  282.             error("Invalid target direction")
  283.         end
  284.     end
  285.  
  286.     local function turnAbsolutDirection(dir)
  287.         if not facingVec then return end
  288.  
  289.         local turnDirection = getTurnDirection(facingVec, dir)
  290.  
  291.         if turnDirection then
  292.             turnInDirection(turnDirection)
  293.         end
  294.  
  295.     end
  296.  
  297.     -- === Basic Movement ===
  298.  
  299.     local function moveUp()
  300.         local bMove = turtle.up()
  301.         turtlePos = get_GPS_Position()
  302.         return bMove
  303.     end
  304.  
  305.     local function moveDown()
  306.         local bMove = turtle.down()
  307.         turtlePos = get_GPS_Position()
  308.         return bMove
  309.     end
  310.  
  311.     local function moveForward()
  312.         if not turtlePos then
  313.             turtlePos = get_GPS_Position()
  314.         end
  315.         local bMove = turtle.forward()
  316.         local pos = get_GPS_Position()
  317.         facingVec = substract(pos, turtlePos)
  318.         turtlePos = pos
  319.         return bMove
  320.     end
  321.  
  322.     --- === Coords Utillity ===
  323.    
  324.     -- gets value on axis relativ to orientation (LR = left right, FB = forward backward)
  325.     local function getOrientatedAxisValues(coord)
  326.         local axis_LR = 0
  327.         local axis_FB = 0
  328.         if orientation == "x" then
  329.             axis_LR = coord.z
  330.             axis_FB = coord.x
  331.         else
  332.             axis_LR = coord.x
  333.             axis_FB = coord.z
  334.         end
  335.         return axis_LR, axis_FB
  336.     end
  337.  
  338.     -- === check Bounds ===
  339.  
  340.     -- checked if turtle is in bounds of storage system or infront of it
  341.     local function isCoordInBounds(coord)
  342.         --print("Coord: (" .. tostring(coord.x) .. ", " .. tostring(coord.y) .. ", " .. tostring(coord.z) .. ")")
  343.         if orientation == "x" then
  344.             local beltDistance = leftBeltCoord.x - coord.x
  345.             print("target_x: " .. tostring(coord.x) .. "  belt_x: " .. tostring(leftBeltCoord.x))
  346.             print(beltDistance)
  347.             if beltDistance == 0 then return true end
  348.             if beltDistance == math.abs(beltDistance) * directionVectors.forward.x then
  349.                 return false
  350.             end
  351.         else
  352.             local beltDistance = leftBeltCoord.z - coord.z
  353.             print("target_z: " .. tostring(coord.z) .. "  belt_x: " .. tostring(leftBeltCoord.z))
  354.             print(beltDistance)
  355.             if beltDistance == 0 then return true end
  356.             if beltDistance == math.abs(beltDistance) * directionVectors.forward.z then
  357.                 return false
  358.             end
  359.         end
  360.         return true
  361.     end
  362.  
  363.     -- check if turtle is on belt (either left or right)
  364.     local function isCoordOnBelt(coord)
  365.         local coord_LR, coord_FB = getOrientatedAxisValues(coord)
  366.  
  367.         if not (coord_FB == leftBeltCoord.x + leftBeltCoord.z) then
  368.             print("LR: " .. tostring(coord_FB))
  369.             print("Add: " .. tostring(leftBeltCoord.x + leftBeltCoord.z))
  370.             return false
  371.         end
  372.  
  373.         if not (coord.y == rightBeltCoord.y or coord.y == leftBeltCoord.y) then
  374.             print("LR_Y: " .. tostring(coord_FB))
  375.             print("BeltHeight: " .. tostring(rightBeltCoord.y) .. ", " .. tostring(leftBeltCoord.y))
  376.             return false
  377.         end
  378.         return true
  379.     end
  380.  
  381.     -- check if coord is in lift up or lift down
  382.     local function isCoordOnLift(coord)
  383.         local added = add(leftBeltCoord, directionVectors.forward)
  384.         local add_LR, add_FB = getOrientatedAxisValues(added)
  385.         local c_LR, c_FB = getOrientatedAxisValues(coord)
  386.  
  387.         if not (c_FB == add_FB) then
  388.             return false
  389.         end
  390.         if ((c_LR + 1) % 8 == modulo) or ((c_LR - 1) % 8 == modulo) then
  391.             return true
  392.         end
  393.         return false
  394.     end
  395.  
  396.     -- check if coord is on a section
  397.     local function isCoordOnSection(coord)
  398.         local coord_LR, coord_FB = getOrientatedAxisValues(coord)
  399.  
  400.         if (coord_LR % 8 == modulo and coord.y % 7 == yModulo and isCoordInBounds(coord)) then
  401.             return true
  402.         end
  403.         return false
  404.     end
  405.  
  406.     -- check if coord is on the side of a vertical chest row
  407.     local function isCoordOnChestRow(coord)
  408.         print("Checking for row")
  409.         local c_LR, c_FB = getOrientatedAxisValues(coord)
  410.         local belt_LR, belt_FB = getOrientatedAxisValues(leftBeltCoord)
  411.  
  412.         if not (((c_LR + 1) % 8 == modulo) or ((c_LR - 1) % 8 == modulo)) then
  413.             return false
  414.         end
  415.         if isCoordInBounds(coord) and (math.abs(c_FB - belt_FB) > 1) then
  416.             return true
  417.         end
  418.         return false
  419.     end
  420.  
  421.     -- check if coord is on an exit section
  422.     local function isCoordOnExitSection(coord)
  423.         local coord_LR, coord_FB = getOrientatedAxisValues(coord)
  424.  
  425.         local exitModulo = (yModulo - 1 > 0) and (yModulo - 1) or (yModulo - 1 + 7)
  426.  
  427.  
  428.         if (coord_LR % 8 == modulo and coord.y % 7 == exitModulo and isCoordInBounds(coord)) then
  429.             return true
  430.         end
  431.         return false
  432.     end
  433.  
  434.     -- check if coord can be reached in the storage system
  435.     local function isConnected(coord)
  436.         if not isCoordInBounds(coord) then return true end
  437.         if isCoordOnBelt(coord) then return true end
  438.         if isCoordOnLift(coord) then return true end
  439.         if isCoordOnSection(coord) then return true end
  440.         if isCoordOnChestRow(coord) then return true end
  441.         if isCoordOnExitSection(coord) then return true end
  442.         return false
  443.     end
  444.  
  445.  
  446.     -- determines direction of turtle and moves one block if necessary
  447.     local function getFacingValue(turtleState)
  448.         if not facingVec then
  449.             local downSuccess, downData = turtle.inspectDown()
  450.            
  451.             -- turn till facing input task disk drive (on backward side of block where turtle receives task)
  452.             if downSuccess and downData.name == "computercraft:disk_drive" then
  453.                 local cnt = 0
  454.                 while cnt < 4 do
  455.                     local frontSuccess, frontData = turtle.inspect()
  456.                     if frontSuccess and frontData.name == "computercraft:disk_drive" then
  457.                         facingVec = directionVectors.backward
  458.                         return true
  459.                     end
  460.                     turtle.turnRight()
  461.                     cnt = cnt + 1
  462.                 end
  463.             end
  464.  
  465.             if not moveForward() then
  466.  
  467.                 -- get correct Facing from joining queue
  468.                 local level = 0
  469.                 if turtleState == TaskStatus.joiningQueue then
  470.                     if turtlePos.x == finishCoord.x and turtlePos.z == finishCoord.z then
  471.                         level = turtlePos.y - finishCoord.y
  472.  
  473.                         while true do
  474.                             local success, data = turtle.inspect()
  475.                             if not (success and isTurtleBlock(data)) then
  476.                                 while not moveForward() do sleep(0.5) end
  477.  
  478.                                 local addedCoord = add(finishCoord, directionVectors.backward)
  479.                                 if turtlePos.x == addedCoord.x and turtlePos.z == addedCoord.z then
  480.                                     print("Set waiting status")
  481.                                     read()
  482.                                     turtleState = TaskStatus.waiting
  483.                                     save_status(TaskStatus.waiting)
  484.                                     break
  485.                                 else
  486.                                     print("Set no Task status")
  487.                                     save_status(TaskStatus.noTask)
  488.                                     return true
  489.                                 end
  490.                             else
  491.                                 while not moveUp() do sleep(0.5) end
  492.                                 level = level + 1
  493.                             end
  494.                         end
  495.                     else
  496.                         turtleState = TaskStatus.noTask
  497.                         save_status(TaskStatus.noTask)
  498.                     end
  499.                 end
  500.  
  501.                 -- get correct position in queue (only when queue is not walled)
  502.                 if turtleState == TaskStatus.waiting then
  503.                     local posQueueEntry = add(finishCoord, directionVectors.backward)
  504.  
  505.                     local cnt = 0
  506.  
  507.                     while cnt < 4 do
  508.                         local success, data = turtle.inspect()
  509.                         if success and (not data.name:match("computercraft:")) then
  510.                             local level = turtlePos.y - finishCoord.y
  511.                             if turtlePos.x == posQueueEntry.x and turtlePos.z == posQueueEntry.z then
  512.                                 if level % 2 == 0 then
  513.                                     turtle.turnRight()
  514.                                     turtle.turnRight()
  515.                                 end
  516.                             else
  517.                                 if level % 2 == 1 then
  518.                                     turtle.turnRight()
  519.                                     turtle.turnRight()
  520.                                 end
  521.                             end
  522.                             return true
  523.                         end
  524.                         turtle.turnRight()
  525.                         cnt = cnt + 1
  526.                     end
  527.                     return true
  528.                 end
  529.  
  530.  
  531.                
  532.  
  533.                 local turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  534.                 local LR_axis, FB_axis = getOrientatedAxisValues(directionVectors.right)
  535.  
  536.                 -- check if turtle is infront of storage chest
  537.                 if (turtle_LR_coord + LR_axis) % 8 == modulo then
  538.                     local success, data = turtle.inspect()
  539.                     if success and data.name == "minecraft:chest" then
  540.                         facingVec = directionVectors.left
  541.                         return true
  542.                     end
  543.                 elseif (turtle_LR_coord - LR_axis) % 8 == modulo then
  544.                     local success, data = turtle.inspect()
  545.                     if success and data.name == "minecraft:chest" then
  546.                         facingVec = directionVectors.right
  547.                         return true
  548.                     end
  549.                 end
  550.  
  551.                 -- turns 360° and trys to move to get directional vector
  552.                 local cnt = 0
  553.                 local bForward = false
  554.                 while not bForward and cnt < 4 do
  555.                     turtle.turnLeft()
  556.                     bForward = moveForward()
  557.                     cnt = cnt + 1
  558.                 end
  559.                 if not bForward then
  560.                     return false
  561.                 else
  562.                     if not isConnected(turtlePos) then
  563.                         turnInDirection("around")
  564.                         while not moveForward() do sleep(0.5) end
  565.                     end
  566.                 end
  567.  
  568.             else
  569.                 if turtleState == TaskStatus.joiningQueue then
  570.                     local addedCoord = add(finishCoord, directionVectors.backward)
  571.                     if not (turtlePos.x == addedCoord.x and turtlePos.z == addedCoord.z) then
  572.                         turtleState = TaskStatus.noTask
  573.                         save_status(TaskStatus.noTask)
  574.                     end
  575.                 end
  576.                 if not isConnected(turtlePos) then
  577.                     turnInDirection("around")
  578.                     while not moveForward() do sleep(0.5) end
  579.                 end
  580.             end
  581.  
  582.  
  583.         end
  584.         return true
  585.     end
  586.  
  587.  
  588.     -- === Inventory Management ===
  589.  
  590.     -- gets specified item in given amount from chest
  591.     local function suckSpecificItem(itemName, count, strDir)
  592.         local chest = peripheral.wrap(strDir)
  593.         if not chest or not chest.list then
  594.             return false
  595.         end
  596.    
  597.         local chestItems = chest.list()
  598.         local foundSlots = {}
  599.         local totalAvailable = 0
  600.    
  601.         -- 1. Scanne Kiste nach dem gewünschten Item
  602.         for slot, item in pairs(chestItems) do
  603.             if item.name == itemName then
  604.                 table.insert(foundSlots, {slot = slot, count = item.count})
  605.                 totalAvailable = totalAvailable + item.count
  606.             end
  607.         end
  608.    
  609.         if totalAvailable < count then
  610.             return false
  611.         end
  612.    
  613.         -- 2. Finde freien Slot in der Turtle für gecachtes Item
  614.         local cachedItemSlot = nil
  615.         for i = 1, 16 do
  616.             if turtle.getItemCount(i) == 0 then
  617.                 cachedItemSlot = i
  618.                 break
  619.             end
  620.         end
  621.    
  622.         if not cachedItemSlot then
  623.             print("Kein freier Slot zum Zwischenspeichern des Kisten-Items.")
  624.             return false
  625.         end
  626.    
  627.         turtle.select(cachedItemSlot)
  628.         local cachedItem = nil
  629.    
  630.         local list = chest.list()
  631.         if list[1] and list[1].name ~= itemName then
  632.             if strDir == "front" then
  633.                 if turtle.suck(64) then
  634.                     cachedItem = turtle.getItemDetail(cachedItemSlot)
  635.                 end
  636.             elseif strDir == "top" then
  637.                 if turtle.suckUp(64) then
  638.                     cachedItem = turtle.getItemDetail(cachedItemSlot)
  639.                 end
  640.             elseif strDir == "bottom" then
  641.                 if turtle.suckDown(64) then
  642.                     cachedItem = turtle.getItemDetail(cachedItemSlot)
  643.                 end
  644.             end
  645.         end
  646.    
  647.         -- 3. Erstes gewünschtes Item in Slot 1 schieben
  648.         local nextSlotIndex = 1
  649.         if not chest.getItemDetail(1) then
  650.             local nextSource = foundSlots[nextSlotIndex]
  651.             chest.pushItems(strDir, nextSource.slot, nextSource.count, 1)
  652.             nextSlotIndex = nextSlotIndex + 1
  653.         elseif (chest.getItemDetail(1) and chest.getItemDetail(1).name == itemName) then
  654.             nextSlotIndex = nextSlotIndex + 1
  655.         end
  656.    
  657.         -- 4. Gecachtes Item zurückgeben
  658.         if cachedItem then
  659.             turtle.select(cachedItemSlot)
  660.             if strDir == "front" then
  661.                 turtle.drop() -- Kiste verteilt es automatisch auf einen freien Slot ≠ 1
  662.             elseif strDir == "top" then
  663.                 turtle.dropUp() -- Kiste verteilt es automatisch auf einen freien Slot ≠ 1
  664.             elseif strDir == "bottom" then
  665.                 turtle.dropDown() -- Kiste verteilt es automatisch auf einen freien Slot ≠ 1
  666.             end
  667.         end
  668.    
  669.         -- 5. Zielitems absaugen
  670.         local collected = 0
  671.         turtle.select(cachedItemSlot) -- Wiederverwenden für Einsammeln
  672.         while collected < count do
  673.             local remaining = count - collected
  674.             local slot1Item = chest.getItemDetail(1)
  675.             local pullCount = math.min(slot1Item.count, remaining)
  676.            
  677.             if strDir == "front" then
  678.                 if turtle.suck(pullCount) then
  679.                     collected = collected + pullCount
  680.                 end
  681.             elseif strDir == "top" then
  682.                 if turtle.suckUp(pullCount) then
  683.                     collected = collected + pullCount
  684.                 end
  685.             elseif strDir == "bottom" then
  686.                 if turtle.suckDown(pullCount) then
  687.                     collected = collected + pullCount
  688.                 end
  689.             end
  690.  
  691.            
  692.    
  693.             if collected < count and nextSlotIndex <= #foundSlots then
  694.                 local nextSource = foundSlots[nextSlotIndex]
  695.                 chest.pushItems(strDir, nextSource.slot, nextSource.count, 1)
  696.                 nextSlotIndex = nextSlotIndex + 1
  697.             end
  698.         end
  699.    
  700.         return true
  701.     end
  702.  
  703.     -- selects slot with item in turtle inventory
  704.     local function selectItem(itemName)
  705.         for i = 1, 16 do
  706.             if turtle.getItemCount(i) > 0 then
  707.                 local data = turtle.getItemDetail(i)
  708.                 if data and data.name == itemName then
  709.                     turtle.select(i)
  710.                     return true
  711.                 end
  712.             end
  713.         end
  714.         return false
  715.     end
  716.  
  717.     -- drops of inventory, if specified only items with itemName
  718.     local function dropOffInventory(itemName)
  719.         for i = 1, 16 do
  720.             if turtle.getItemCount(i) > 0 then
  721.                 if itemName then
  722.                     local data = turtle.getItemDetail(i)
  723.                     if data.name == itemName then
  724.                         turtle.select(i)
  725.                         turtle.drop()
  726.                     end
  727.                 else
  728.                     turtle.select(i)
  729.                     turtle.drop()
  730.                 end
  731.             end
  732.         end
  733.     end
  734.  
  735.     -- === System Movement ===
  736.  
  737.     -- returns LR Position of Section in which the target is located
  738.     local function findSectionPos_LR(targetPos)
  739.         local target_LR_coord, target_FB_coord = getOrientatedAxisValues(targetPos)
  740.  
  741.         local targetModulo = target_LR_coord % 8
  742.         local distanceToSection = targetModulo - modulo
  743.        
  744.         if distanceToSection > 4 then
  745.             distanceToSection = distanceToSection - 8
  746.         elseif distanceToSection < -4 then
  747.             distanceToSection = distanceToSection + 8
  748.         elseif math.abs(distanceToSection) == 4 then
  749.             print("Error: Targetposition out of bounds")
  750.             return nil
  751.         end
  752.        
  753.         local try_LR_coord1 = math.abs(distanceToSection) + target_LR_coord
  754.         local try_LR_coord2 = -math.abs(distanceToSection) + target_LR_coord
  755.  
  756.         if try_LR_coord1 % 8 == modulo then
  757.             return try_LR_coord1
  758.         elseif try_LR_coord2 % 8 == modulo then
  759.             return try_LR_coord2
  760.         else
  761.             print("Error: Can't find correct Section")
  762.             return nil
  763.         end
  764.     end
  765.  
  766.     local function getSectionHeight(targetPos)
  767.         local target_yModulo = targetPos.y % 7
  768.         local difference = target_yModulo - yModulo
  769.         if difference < 0 then
  770.             difference = difference + 7
  771.         end
  772.         return targetPos.y - difference
  773.     end
  774.  
  775.     -- returns LR Position of belt exit + direction it needs to face there
  776.     local function getBeltExitLocation(targetPos)
  777.         local target_LR_coord, target_FB_coord = getOrientatedAxisValues(targetPos)
  778.         if isCoordInBounds(targetPos) then
  779.             local exitCoord = findSectionPos_LR(targetPos)
  780.             if exitCoord then
  781.                 return exitCoord, directionVectors.forward
  782.             else
  783.                 print("Error: No exit Coords found")
  784.                 return nil, nil
  785.             end
  786.         else
  787.             return target_LR_coord, directionVectors.backward
  788.         end
  789.     end
  790.  
  791.     -- moves from left belt to right belt or the other way around
  792.     local function switchBelts()
  793.         local turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  794.         local dir_Right, otherDir = getOrientatedAxisValues(directionVectors.right)
  795.  
  796.         local dir_Left = -dir_Right
  797.  
  798.         if turtlePos.y == rightBeltCoord.y then
  799.             -- moves to elevator left of section way to go down
  800.             if not ((turtle_LR_coord + dir_Right) % 8 == modulo) then
  801.                 turnAbsolutDirection(directionVectors.right)
  802.             end
  803.             while not ((turtle_LR_coord + dir_Right) % 8 == modulo) do
  804.                 while not moveForward() do sleep(0.5) end
  805.                 turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  806.             end
  807.             turnAbsolutDirection(directionVectors.forward)
  808.             while not moveForward() do sleep(0.5) end
  809.  
  810.             while not moveDown() do sleep(0.5) end
  811.             turnAbsolutDirection(directionVectors.backward)
  812.  
  813.             while not moveForward() do sleep(0.5) end
  814.             turnAbsolutDirection(directionVectors.left)
  815.         else
  816.             -- moves to elevator right of section way to go up
  817.             if not ((turtle_LR_coord + dir_Left) % 8 == modulo) then
  818.                 turnAbsolutDirection(directionVectors.left)
  819.             end
  820.             while not ((turtle_LR_coord + dir_Left) % 8 == modulo) do
  821.                 while not moveForward() do sleep(0.5) end
  822.                 turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  823.             end
  824.             turnAbsolutDirection(directionVectors.forward)
  825.             while not moveForward() do sleep(0.5) end
  826.  
  827.             while not moveUp() do sleep(0.5) end
  828.             turnAbsolutDirection(directionVectors.backward)
  829.  
  830.             while not moveForward() do sleep(0.5) end
  831.             turnAbsolutDirection(directionVectors.right)
  832.         end
  833.     end
  834.  
  835.     -- moves from lift down to lift up or the other way around
  836.     local function switchLifts()
  837.         print("Switch lift")
  838.  
  839.         local bLiftDown = false
  840.         local pos_section_LR, pos_section_FB = getOrientatedAxisValues(add(turtlePos, directionVectors.right))
  841.  
  842.         local taboo1 = yModulo - 1
  843.         local taboo2 = yModulo - 1 + 7
  844.         local tabooCondition = (turtlePos.y % 7 == yModulo) or (turtlePos.y % 7  == taboo1) or (turtlePos.y % 7  == taboo2)
  845.         local condition2 = (turtlePos.y % 2 == 0)
  846.  
  847.         if pos_section_LR % 8 == modulo then
  848.             bLiftDown = true
  849.         end
  850.  
  851.         if bLiftDown then
  852.             while condition2 or tabooCondition do
  853.                 while not moveDown() do sleep(0.5) end
  854.                 condition2 = (turtlePos.y % 2 == 0)
  855.                 tabooCondition = (turtlePos.y % 7 == yModulo) or (turtlePos.y % 7  == taboo1) or (turtlePos.y % 7  == taboo2)
  856.             end
  857.             turnAbsolutDirection(directionVectors.right)
  858.             while not moveForward() do sleep(0.5) end
  859.             while not moveForward() do sleep(0.5) end
  860.         else
  861.             while (not condition2) or tabooCondition do
  862.                 while not moveUp() do sleep(0.5) end
  863.                 condition2 = (turtlePos.y % 2 == 0)
  864.                 tabooCondition = (turtlePos.y % 7 == yModulo) or (turtlePos.y % 7  == taboo1) or (turtlePos.y % 7  == taboo2)
  865.             end
  866.             turnAbsolutDirection(directionVectors.left)
  867.             while not moveForward() do sleep(0.5) end
  868.             while not moveForward() do sleep(0.5) end
  869.         end
  870.     end
  871.  
  872.     -- adapts position to join closest belt, switches to other one if necessary
  873.     local function joinBeltFromOutside(targetPos)
  874.         if isCoordInBounds(turtlePos) then
  875.             print("Error: Turtle is already in bounds")
  876.             return false
  877.         end
  878.         local turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  879.         local target_LR_coord, target_FB_coord = getOrientatedAxisValues(targetPos)
  880.  
  881.         local beltHeight = leftBeltCoord.y
  882.         local bRightBelt = false
  883.         if orientation == "x" then
  884.             if (target_LR_coord - turtle_LR_coord) / directionVectors.right.z > 0 then
  885.                 beltHeight = rightBeltCoord.y
  886.                 bRightBelt = true
  887.             end
  888.         elseif orientation == "z" then
  889.             if (target_LR_coord - turtle_LR_coord) / directionVectors.right.x > 0 then
  890.                 beltHeight = rightBeltCoord.y
  891.                 bRightBelt = true
  892.             end
  893.         end
  894.  
  895.         turnAbsolutDirection(directionVectors.forward)
  896.  
  897.         if turtlePos.y > leftBeltCoord.y then
  898.             while turtlePos.y > beltHeight do
  899.                 if not moveDown() then sleep(0.5) end
  900.             end
  901.         else
  902.             while turtlePos.y < beltHeight do
  903.                 if not moveUp()  then sleep(0.5) end
  904.             end
  905.         end
  906.         while not isCoordInBounds(turtlePos) do
  907.             if not moveForward() then sleep(0.5) end
  908.         end
  909.         if bRightBelt then
  910.             turnAbsolutDirection(directionVectors.right)
  911.         else
  912.             turnAbsolutDirection(directionVectors.left)
  913.         end
  914.         return true
  915.     end
  916.  
  917.     -- moves along the belt til exit + exiting it
  918.     local function useAndExitBelt(targetPos)
  919.         local turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  920.         local target_LR_coord, target_FB_coord = getOrientatedAxisValues(targetPos)
  921.  
  922.         if not isCoordOnBelt(turtlePos) then
  923.             print("Error: Turtle is not on Belt.")
  924.             return false
  925.         end
  926.  
  927.         local beltHeight = leftBeltCoord.y
  928.         local bGoingRight = false
  929.         if orientation == "x" then
  930.             if (target_LR_coord - turtle_LR_coord) / directionVectors.right.z > 0 then
  931.                 beltHeight = rightBeltCoord.y
  932.                 bGoingRight = true
  933.             end
  934.         elseif orientation == "z" then
  935.             if (target_LR_coord - turtle_LR_coord) / directionVectors.right.x > 0 then
  936.                 beltHeight = rightBeltCoord.y
  937.                 bGoingRight = true
  938.             end
  939.         end
  940.  
  941.         if not (turtlePos.y == beltHeight) then
  942.             switchBelts()
  943.         end
  944.         if bGoingRight then
  945.             turnAbsolutDirection(directionVectors.right)
  946.         else
  947.             turnAbsolutDirection(directionVectors.left)
  948.         end
  949.  
  950.         local exit_LR, exitVec = getBeltExitLocation(targetPos)
  951.         if not exit_LR then
  952.             print("Error: Can't find exit.")
  953.             return false
  954.         end
  955.  
  956.         while not (turtle_LR_coord == exit_LR) do
  957.             while not moveForward() do sleep(0.5) end
  958.             turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  959.         end
  960.  
  961.         if equalCoords(targetPos, finishCoord) then
  962.             if turtlePos.y == leftBeltCoord.y + 1 then
  963.                 switchBelts()
  964.                 useAndExitBelt(targetPos)
  965.                 return true
  966.             end
  967.         end
  968.        
  969.         turnAbsolutDirection(exitVec)
  970.         while not moveForward() do sleep(0.5) end
  971.  
  972.         return true
  973.     end
  974.  
  975.     -- moves along lift and exits it. Turns in right direction afterward
  976.     local function useAndExitLift(targetPos)
  977.         local bExitToBelt = false
  978.         local bTargetInBounds = isCoordInBounds(targetPos)
  979.  
  980.         local bLiftDown = false
  981.         local pos_section_LR, otherValue = getOrientatedAxisValues(add(turtlePos, directionVectors.right))
  982.  
  983.         local section_LR, otherValue1 = getOrientatedAxisValues(add(turtlePos, directionVectors.left))
  984.  
  985.         if pos_section_LR % 8 == modulo then
  986.             section_LR = pos_section_LR
  987.             bLiftDown = true
  988.         end
  989.  
  990.         if not isCoordOnLift(turtlePos) then
  991.             print("Error: Turtle is not on Lift.")
  992.             return false
  993.         end
  994.  
  995.         if not (findSectionPos_LR(targetPos) == section_LR) then
  996.             print("Exit to belt")
  997.             bExitToBelt = true
  998.         end
  999.  
  1000.         if not bTargetInBounds then
  1001.             bExitToBelt = true
  1002.         end
  1003.  
  1004.         if not bExitToBelt then
  1005.             -- exit to storage section
  1006.             local sectionHeight = getSectionHeight(targetPos)
  1007.             while sectionHeight > turtlePos.y do
  1008.                 if bLiftDown then
  1009.                     switchLifts()
  1010.                     bLiftDown = false
  1011.                 else
  1012.                     while not moveUp() do sleep(0.5) end
  1013.                 end
  1014.             end
  1015.             while sectionHeight < turtlePos.y do
  1016.                 if not bLiftDown then
  1017.                     switchLifts()
  1018.                     bLiftDown = true
  1019.                 else
  1020.                     while not moveDown() do sleep(0.5) end
  1021.                 end
  1022.             end
  1023.             if bLiftDown then
  1024.                 turnAbsolutDirection(directionVectors.right)
  1025.             else
  1026.                 turnAbsolutDirection(directionVectors.left)
  1027.             end
  1028.             while not moveForward() do sleep(0.5) end
  1029.             turnAbsolutDirection(directionVectors.forward)
  1030.         else
  1031.             -- exit to belt
  1032.             local exitHeight = leftBeltCoord.y
  1033.  
  1034.             local turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  1035.             local target_LR_coord, target_FB_coord = getOrientatedAxisValues(targetPos)
  1036.  
  1037.             local step_right_LR, step_right_FB = getOrientatedAxisValues(directionVectors.right)
  1038.  
  1039.             local distance = target_LR_coord - turtle_LR_coord
  1040.  
  1041.             if distance == step_right_LR * math.abs(distance) then
  1042.                 exitHeight = leftBeltCoord.y + 1
  1043.             end
  1044.  
  1045.             while not (exitHeight == turtlePos.y) do
  1046.                 while exitHeight > turtlePos.y do
  1047.                     if bLiftDown then
  1048.                         switchLifts()
  1049.                         bLiftDown = false
  1050.                        
  1051.                         -- calculates new direction and targetBelt again in case the direction changed
  1052.                         distance = target_LR_coord - turtle_LR_coord
  1053.  
  1054.                         if distance == step_right_LR * math.abs(distance) then
  1055.                             exitHeight = leftBeltCoord.y + 1
  1056.                         end
  1057.                     else
  1058.                         while not moveUp() do sleep(0.5) end
  1059.                     end
  1060.                 end
  1061.                 while exitHeight < turtlePos.y do
  1062.                     if not bLiftDown then
  1063.                         switchLifts()
  1064.                         bLiftDown = true
  1065.                        
  1066.                         -- calculates new direction and targetBelt again in case the direction changed
  1067.                         distance = target_LR_coord - turtle_LR_coord
  1068.  
  1069.                         if distance == step_right_LR * math.abs(distance) then
  1070.                             exitHeight = leftBeltCoord.y + 1
  1071.                         end
  1072.                     else
  1073.                         while not moveDown() do sleep(0.5) end
  1074.                     end
  1075.                 end
  1076.             end
  1077.  
  1078.             turnAbsolutDirection(directionVectors.backward)
  1079.             while not moveForward() do sleep(0.5) end
  1080.             if turtlePos.y == beltHeight1 then
  1081.                 turnAbsolutDirection(directionVectors.left)
  1082.             elseif turtlePos.y == beltHeight2 then
  1083.                 turnAbsolutDirection(directionVectors.right)
  1084.             end
  1085.         end
  1086.  
  1087.     end
  1088.  
  1089.     -- moves along section and exits at targetPos if possible otherwise exits directly.
  1090.     local function useAndExitSection(targetPos)
  1091.         local turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  1092.         local target_LR_coord, target_FB_coord = getOrientatedAxisValues(targetPos)
  1093.  
  1094.         local step_forward_LR, step_forward_FB = getOrientatedAxisValues(directionVectors.forward)
  1095.         local step_right_LR, step_right_FB = getOrientatedAxisValues(directionVectors.right)
  1096.  
  1097.         local belt_LR, belt_FB = getOrientatedAxisValues(leftBeltCoord)
  1098.  
  1099.         if not isCoordOnSection(turtlePos) then
  1100.             print("Error: Turtle is not on Section.")
  1101.             return false
  1102.         end
  1103.  
  1104.         turnAbsolutDirection(directionVectors.forward)
  1105.  
  1106.  
  1107.         local difference = target_FB_coord - turtle_FB_coord
  1108.  
  1109.         -- exits belt at closest point to the left
  1110.         local function takeNextLeft()
  1111.             while math.abs(turtle_FB_coord - belt_FB) < 2 do
  1112.                 while not moveForward() do sleep(0.5) end
  1113.                 turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  1114.             end
  1115.             turnAbsolutDirection(directionVectors.left)
  1116.             while not moveForward() do sleep(0.5) end
  1117.         end
  1118.  
  1119.         if not (difference == step_forward_FB * math.abs(difference)) then
  1120.             takeNextLeft()
  1121.             return true
  1122.         elseif not(getSectionHeight(targetPos) == turtlePos.y) then
  1123.             takeNextLeft()
  1124.             return true
  1125.         elseif math.abs(target_LR_coord - turtle_LR_coord) > 1 then
  1126.             takeNextLeft()
  1127.             return true
  1128.         end
  1129.  
  1130.         while not (target_FB_coord == turtle_FB_coord) do
  1131.             while not moveForward() do sleep(0.5) end
  1132.             turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  1133.         end
  1134.  
  1135.         if turtle_LR_coord + step_right_LR == target_LR_coord then
  1136.             turnAbsolutDirection(directionVectors.right)
  1137.         elseif turtle_LR_coord - step_right_LR == target_LR_coord then
  1138.             turnAbsolutDirection(directionVectors.left)
  1139.         end
  1140.  
  1141.         while not moveForward() do sleep(0.5) end
  1142.     end
  1143.  
  1144.     -- climbs chest row up till target or exit
  1145.     local function useAndExitChestRow(targetPos)
  1146.         local turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  1147.         local step_right_LR, step_right_FB = getOrientatedAxisValues(directionVectors.right)
  1148.  
  1149.         local exitModulo = (yModulo - 1 > 0) and (yModulo - 1) or (yModulo - 1 + 7)
  1150.  
  1151.         if not isCoordOnChestRow(turtlePos) then
  1152.             print("Error: Turtle is not on chest row.")
  1153.             return false
  1154.         end
  1155.  
  1156.         while not (turtlePos.y % 7 == exitModulo) do
  1157.             while not moveUp() do sleep(0.5) end
  1158.  
  1159.             if equalCoords(turtlePos, targetPos) then
  1160.                 return true
  1161.             end
  1162.         end
  1163.  
  1164.         if (turtle_LR_coord + step_right_LR) % 8 == modulo then
  1165.             turnAbsolutDirection(directionVectors.right)
  1166.         elseif (turtle_LR_coord - step_right_LR) % 8 == modulo then
  1167.             turnAbsolutDirection(directionVectors.left)
  1168.         else
  1169.             print("Error: Turtle on wrong Position")
  1170.             return false
  1171.         end
  1172.  
  1173.         while not moveForward() do sleep(0.5) end
  1174.         turnAbsolutDirection(directionVectors.backward)
  1175.         return true
  1176.     end
  1177.  
  1178.     -- Moves till the end of the exit section and enters lift
  1179.     local function useAndExitExitSection(targetPos)
  1180.         local turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  1181.         local target_LR_coord, target_FB_coord = getOrientatedAxisValues(targetPos)
  1182.  
  1183.         local step_right_LR, step_right_FB = getOrientatedAxisValues(directionVectors.right)
  1184.  
  1185.         local belt_LR_coord, belt_FB_coord = getOrientatedAxisValues(leftBeltCoord)
  1186.  
  1187.         if not isCoordOnExitSection(turtlePos) then
  1188.             print("Error: Turtle is not on exit section.")
  1189.             return false
  1190.         end
  1191.  
  1192.         turnAbsolutDirection(directionVectors.backward)
  1193.        
  1194.         while math.abs(turtle_FB_coord - belt_FB_coord) > 1 do
  1195.             while not moveForward() do sleep(0.5) end
  1196.             turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  1197.         end
  1198.        
  1199.         local target_section_LR = findSectionPos_LR(targetPos)
  1200.        
  1201.         local exitLiftHeight = leftBeltCoord.y
  1202.        
  1203.         if target_section_LR == turtle_LR_coord then
  1204.             exitLiftHeight = getSectionHeight(targetPos)
  1205.         end
  1206.  
  1207.         local distance = target_LR_coord - turtle_LR_coord
  1208.         if distance == step_right_LR * math.abs(distance) then
  1209.             exitLiftHeight = leftBeltCoord.y + 1
  1210.         elseif distance == -step_right_LR * math.abs(distance) then
  1211.             exitLiftHeight = leftBeltCoord.y
  1212.         elseif distance == 0 then
  1213.             if turtlePos.y > leftBeltCoord.y + 1 then
  1214.                 exitLiftHeight = leftBeltCoord.y + 1
  1215.             elseif turtlePos.y < leftBeltCoord.y then
  1216.                 exitLiftHeight = leftBeltCoord.y
  1217.             else
  1218.                 while not moveForward() do sleep(0.5) end
  1219.                 if turtlePos.y == leftBeltCoord.y then
  1220.                     turnAbsolutDirection(directionVectors.left)
  1221.                 else
  1222.                     turnAbsolutDirection(directionVectors.right)
  1223.                 end
  1224.                 return true
  1225.             end
  1226.         end
  1227.        
  1228.         if turtlePos.y >= exitLiftHeight then
  1229.             turnAbsolutDirection(directionVectors.left)
  1230.             while not moveForward() do sleep(0.5) end
  1231.             return true
  1232.         else
  1233.             turnAbsolutDirection(directionVectors.right)
  1234.             while not moveForward() do sleep(0.5) end
  1235.             return true
  1236.         end
  1237.  
  1238.     end
  1239.  
  1240.     -- reaches target from beltexit if it is out of bounds
  1241.     local function reachOutsideTarget(targetPos)
  1242.         local turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  1243.         local target_LR_coord, target_FB_coord = getOrientatedAxisValues(targetPos)
  1244.  
  1245.         while not (turtle_FB_coord == target_FB_coord) do
  1246.             while not moveForward() do sleep(0.5) end
  1247.             turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  1248.         end
  1249.  
  1250.         while turtlePos.y > targetPos.y do
  1251.             while not moveDown() do sleep(0.5) end
  1252.         end
  1253.         while turtlePos.y < targetPos.y do
  1254.             while not moveUp() do sleep(0.5) end
  1255.         end
  1256.  
  1257.         return true
  1258.     end
  1259.  
  1260.  
  1261.     -- === Turtle States ===
  1262.  
  1263.     -- Returns the coords where task starts
  1264.     local function getTaskStartCoords()
  1265.         local tasks = getTaskList("task_list.txt")
  1266.        
  1267.         if #tasks == 0 then
  1268.             return nil
  1269.         end
  1270.  
  1271.         local task = table.remove(tasks, 1)
  1272.  
  1273.         if task.taskType == "create_chests" then
  1274.             local taskPos = {x = task.x, y = task.y, z = task.z}
  1275.  
  1276.             local taskPos_LR, taskPos_FB = getOrientatedAxisValues(taskPos)
  1277.             local right_LR, right_FB = getOrientatedAxisValues(directionVectors.right)
  1278.  
  1279.             if (taskPos_LR + 2 * right_LR) % 8 == modulo then
  1280.                 return add(taskPos, directionVectors.right)
  1281.             elseif (taskPos_LR - 2 * right_LR) % 8 == modulo then
  1282.                 return add(taskPos, directionVectors.left)
  1283.             else
  1284.                 return nil
  1285.             end
  1286.         elseif task.taskType == "store_items" or task.taskType == "get_items" then
  1287.             local taskPos = task.chestCoord
  1288.  
  1289.             local taskPos_LR, taskPos_FB = getOrientatedAxisValues(taskPos)
  1290.             local right_LR, right_FB = getOrientatedAxisValues(directionVectors.right)
  1291.  
  1292.             if (taskPos_LR + 2 * right_LR) % 8 == modulo then
  1293.                 return add(taskPos, directionVectors.right)
  1294.             elseif (taskPos_LR - 2 * right_LR) % 8 == modulo then
  1295.                 return add(taskPos, directionVectors.left)
  1296.             else
  1297.                 return nil
  1298.             end
  1299.         end
  1300.  
  1301.         return nil
  1302.     end
  1303.  
  1304.     -- accept task from outgoing tasks saves status to accepted or goToPrep when finished
  1305.     local function acceptTask()
  1306.         print("\nWait for task")
  1307.         local disk, outgoingPath = getDiskByLabel(DISK_NAMES.outgoing)
  1308.         local saveState = TaskStatus.noTask
  1309.         local task
  1310.  
  1311.         if not disk then return nil end
  1312.        
  1313.         while true do
  1314.             local fullPath = fs.combine(outgoingPath, "task_list.txt")
  1315.  
  1316.             local tasks = getTaskList("task_list.txt")
  1317.             local bLocal = true
  1318.             if #tasks == 0 then
  1319.                 tasks = getTaskList(fullPath)
  1320.                 bLocal = false
  1321.             end
  1322.             if #tasks == 0 then
  1323.                 sleep(0.5)
  1324.             else
  1325.                
  1326.                 task = table.remove(tasks, 1)
  1327.                 print("Got task " .. task.taskType)
  1328.  
  1329.                 if not bLocal then
  1330.                     -- Save remaining tasks back
  1331.                     local file = fs.open(fullPath, "w")
  1332.                     file.write(textutils.serialize(tasks))
  1333.                     file.close()
  1334.  
  1335.                     addTaskToList("task_list.txt", task)
  1336.                 end
  1337.  
  1338.                 if task.taskType == "create_chests" then
  1339.                     print("Looking for chests in chest")
  1340.                     turnAbsolutDirection(directionVectors.right)
  1341.  
  1342.                     local first1, first2 = true, true
  1343.                     while true do
  1344.                         local success, data = turtle.inspect()
  1345.                         if not (success and data.name == "minecraft:chest") then
  1346.                             if first1 then
  1347.                                 print("No chest found, waiting for placed chest.")
  1348.                                 first1 = false
  1349.                             end
  1350.                             sleep(0.5)
  1351.                         else
  1352.                             if not suckSpecificItem("minecraft:chest", 100, "front") then
  1353.                                 if first2 then
  1354.                                     print("Not enough chests found, waiting for 100 chests in chest inventory")
  1355.                                     first2 = false
  1356.                                 end
  1357.                                 sleep(0.5)
  1358.                             else
  1359.                                 saveState = TaskStatus.accepted
  1360.                                 break
  1361.                             end
  1362.                         end
  1363.                     end
  1364.                 elseif task.taskType == "store_items" then
  1365.                     if task.itemCount > 1 then
  1366.                         print("Looking for " .. tostring(task.itemCount) .. task.itemDisplayName .. "s in Chest above")
  1367.                     else
  1368.                         print("Looking for ".. tostring(task.itemCount) .. task.itemDisplayName .. " in Chest above")
  1369.                     end
  1370.                     local first1, first2 = true, true
  1371.                     while true do
  1372.                         local success, data = turtle.inspectUp()
  1373.                         if not (success and data.name == "minecraft:chest") then
  1374.                             if first1 then
  1375.                                 print("No chest found above, waiting for placed chest.")
  1376.                                 first1 = false
  1377.                             end
  1378.                             sleep(0.5)
  1379.                         end
  1380.                         if not suckSpecificItem(task.itemName, task.itemCount, "top") then
  1381.                             if first2 then
  1382.                                 local str1 = "Not enough " .. task.itemDisplayName .. "s found, waiting for " .. tostring(task.itemCount)
  1383.                                 local str2 = " " .. task.itemDisplayName .. "s in chest inventory."
  1384.                                 print(str1 .. str2)
  1385.                                 first2 = false
  1386.                             end
  1387.                             sleep(0.5)
  1388.                         else
  1389.                             saveState = TaskStatus.accepted
  1390.                             break
  1391.                         end
  1392.                     end
  1393.                 elseif task.taskType == "get_items" then
  1394.                     saveState = TaskStatus.accepted
  1395.                 elseif task.taskType == "check_inventory" then
  1396.                     print("Tasks of type " .. task.taskType .. " can not be accepted at the moment.")
  1397.                     return false
  1398.                 else
  1399.                     print("Wrong task type.")
  1400.                     return false
  1401.                 end
  1402.  
  1403.                 break
  1404.             end
  1405.         end
  1406.         turnAbsolutDirection(directionVectors.forward)
  1407.         while not moveForward() do sleep(0.5) end
  1408.        
  1409.         if saveState == TaskStatus.accepted then
  1410.             print("Accepted Task " .. task.taskType)
  1411.         end
  1412.         save_status(saveState)
  1413.         return true
  1414.     end
  1415.  
  1416.     -- moves turtle along systemways to given target
  1417.     local function goToCoord(targetPos)
  1418.         if not targetPos then
  1419.             print(textutils.serialize(targetPos))
  1420.             print("\nNo coreect target position given.")
  1421.             return false
  1422.         end
  1423.         print("\nGo to Coord (" .. tostring(targetPos.x) .. ", " .. tostring(targetPos.y) .. ", " .. tostring(targetPos.z) .. ")")
  1424.         if equalCoords(targetPos, turtlePos) then
  1425.             print("target reached")
  1426.             return true
  1427.         end
  1428.  
  1429.         local startPos = turtlePos
  1430.  
  1431.         local beltDistance = 0
  1432.         local bTurtleInBounds = isCoordInBounds(turtlePos)
  1433.         local bTargetInBounds = isCoordInBounds(targetPos)
  1434.  
  1435.         local beltPos
  1436.  
  1437.         local turtle_LR_coord, turtle_FB_coord = getOrientatedAxisValues(turtlePos)
  1438.         local target_LR_coord, target_FB_coord = getOrientatedAxisValues(targetPos)
  1439.  
  1440.         if not bTurtleInBounds then
  1441.             -- turtle outside Storage System
  1442.             print("try joining belt")
  1443.             joinBeltFromOutside(targetPos)
  1444.             print("belt joined")
  1445.         end
  1446.  
  1447.         if isCoordOnBelt(turtlePos) then
  1448.             -- turtle on Belt
  1449.             print("use belt")
  1450.             useAndExitBelt(targetPos)
  1451.             print("exited belt")
  1452.             if not bTargetInBounds then
  1453.                 reachOutsideTarget(targetPos)
  1454.                 if equalCoords(targetPos, turtlePos) then
  1455.                     print("target reached")
  1456.                     return true
  1457.                 end
  1458.             end
  1459.  
  1460.             local sectionHeight = getSectionHeight(targetPos)
  1461.             print("Reaching Section at: " .. tostring(sectionHeight))
  1462.             if not (turtlePos.y == sectionHeight) then
  1463.                 if turtlePos.y > sectionHeight then
  1464.                     turnAbsolutDirection(directionVectors.left)
  1465.                     while not moveForward() do sleep(0.5) end
  1466.                 end
  1467.                 if turtlePos.y < sectionHeight then
  1468.                     turnAbsolutDirection(directionVectors.right)
  1469.                     while not moveForward() do sleep(0.5) end
  1470.                 end
  1471.             end
  1472.         end
  1473.  
  1474.         if isCoordOnLift(turtlePos) then
  1475.             print("Using Lift")
  1476.             useAndExitLift(targetPos)
  1477.         end
  1478.  
  1479.  
  1480.         if isCoordOnSection(turtlePos) then
  1481.             print("Using Section")
  1482.             useAndExitSection(targetPos)
  1483.         end
  1484.  
  1485.         if isCoordOnChestRow(turtlePos) then
  1486.             print("Using chest row")
  1487.             useAndExitChestRow(targetPos)
  1488.         end
  1489.  
  1490.         if isCoordOnExitSection(turtlePos) then
  1491.             print("Using exit section")
  1492.             useAndExitExitSection(targetPos)
  1493.         end
  1494.  
  1495.         if equalCoords(startPos, turtlePos) then
  1496.             return false
  1497.         end
  1498.         return goToCoord(targetPos)
  1499.     end
  1500.    
  1501.     -- completes the task and saves status to finished or goToAfterWork
  1502.     local function doTaskWork()
  1503.         print("\n Starting with task")
  1504.         local tasks = getTaskList("task_list.txt")
  1505.        
  1506.         if #tasks == 0 then
  1507.             return nil
  1508.         end
  1509.  
  1510.         local task = table.remove(tasks, 1)
  1511.  
  1512.         if task.taskType == "create_chests" then
  1513.             -- places a row of chests (y=5, delta_x(z) = 10) and goes back to top of first five chests
  1514.             local function placeChestRow()
  1515.                 local cnt = 0
  1516.                 while cnt < 10 do
  1517.                     local cnt1 = 0
  1518.                     while cnt1 < 5 do
  1519.                         while not moveUp() do sleep(0.5) end
  1520.                         if not selectItem("minecraft:chest") then return false end
  1521.                         if not turtle.placeDown() then return false end
  1522.                         cnt1 = cnt1 + 1
  1523.                     end
  1524.                     if not (cnt == 9) then
  1525.                         while not moveForward() do sleep(0.5) end
  1526.                         while cnt1 > 0 do
  1527.                             while not moveDown() do sleep(0.5) end
  1528.                             cnt1 = cnt1 - 1
  1529.                         end
  1530.                     end
  1531.                     cnt = cnt + 1
  1532.                 end
  1533.                 turnInDirection("around")
  1534.                 while cnt > 1 do
  1535.                     while not moveForward() do sleep(0.5) end
  1536.                     cnt = cnt - 1
  1537.                 end
  1538.                 return true
  1539.             end
  1540.  
  1541.  
  1542.             local pos_LR, pos_FB = getOrientatedAxisValues(add(turtlePos, directionVectors.right))
  1543.  
  1544.             local endTurnDirection = directionVectors.left
  1545.            
  1546.             if pos_LR % 8 == modulo then
  1547.                 endTurnDirection = directionVectors.right
  1548.             end
  1549.  
  1550.  
  1551.             while not moveForward() do sleep(0.5) end
  1552.             while not moveForward() do sleep(0.5) end
  1553.  
  1554.             turnAbsolutDirection(directionVectors.forward)
  1555.             if not placeChestRow() then return false end
  1556.            
  1557.             turnAbsolutDirection(endTurnDirection)
  1558.             while not moveForward() do sleep(0.5) end
  1559.  
  1560.             local cnt = 5
  1561.             while cnt > 0 do
  1562.                 while not moveDown() do sleep(0.5) end
  1563.                 cnt = cnt - 1
  1564.             end
  1565.  
  1566.             turnAbsolutDirection(directionVectors.forward)
  1567.             if not placeChestRow() then return false end
  1568.            
  1569.             turnAbsolutDirection(endTurnDirection)
  1570.             while not moveForward() do sleep(0.5) end
  1571.        
  1572.         elseif task.taskType == "store_items" then
  1573.             local success, data = turtle.inspect()
  1574.             if success and data.name == "minecraft:chest" then
  1575.                 dropOffInventory(task.itemName)
  1576.             else
  1577.                 print("Error: No Chest found")
  1578.                 return false
  1579.             end
  1580.         elseif task.taskType == "get_items" then
  1581.             local success, data = turtle.inspect()
  1582.             if success and data.name == "minecraft:chest" then
  1583.                 if not suckSpecificItem(task.itemName, task.itemCount, "front") then
  1584.                     print("Error: Not enough items found")
  1585.                 end
  1586.             else
  1587.                 print("Error: No Chest found")
  1588.             end
  1589.             if not goToCoord(outputCoord) then
  1590.                 error("Can't reach output chest", 0)
  1591.             end
  1592.             dropOffInventory(task.itemName)
  1593.             turnAbsolutDirection(directionVectors.left)
  1594.             while not moveForward() do sleep(0.5) end
  1595.             turnAbsolutDirection(directionVectors.forward)
  1596.         end
  1597.  
  1598.         save_status(TaskStatus.finished)
  1599.         return true
  1600.     end
  1601.  
  1602.     -- Copys task to finished disk and deletes local one
  1603.     local function completeTask()
  1604.         local localTaskList = getTaskList("task_list.txt")
  1605.  
  1606.         local task = table.remove(localTaskList, 1)
  1607.         local index = 1
  1608.  
  1609.         print("Finish task " .. task.taskType .. " with ID " .. tostring(task.taskId))
  1610.        
  1611.         -- add finished Task
  1612.         local disk, path = getDiskByLabel(DISK_NAMES.finished)
  1613.         local finishedPath = fs.combine(path, "task_list.txt")
  1614.        
  1615.         addTaskToList(finishedPath, task)
  1616.  
  1617.         -- delete local (override)
  1618.         saveTaskList("task_list.txt", localTaskList)
  1619.  
  1620.         save_status(TaskStatus.joiningQueue)
  1621.         return true
  1622.     end
  1623.  
  1624.     -- === Queue Handling ===
  1625.  
  1626.     -- joins in queue
  1627.     local function joinQueue()
  1628.         print("\nEntering queue...")
  1629.         local level = 0
  1630.         if turtlePos.x == finishCoord.x and turtlePos.z == finishCoord.z then
  1631.             level = turtlePos.y - finishCoord.y
  1632.         else
  1633.             return false
  1634.         end
  1635.         turnAbsolutDirection(directionVectors.backward)
  1636.  
  1637.         while true do
  1638.             local success, data = turtle.inspect()
  1639.             if not (success and isTurtleBlock(data)) then
  1640.                 while not moveForward() do sleep(0.5) end
  1641.                 if level % 2 == 0 then
  1642.                     turnAbsolutDirection(directionVectors.right)
  1643.                 else
  1644.                     turnAbsolutDirection(directionVectors.left)
  1645.                 end
  1646.                 break
  1647.             else
  1648.                 while not moveUp() do sleep(0.5) end
  1649.                 level = level + 1
  1650.             end
  1651.         end
  1652.         save_status(TaskStatus.waiting)
  1653.     end
  1654.  
  1655.     -- moves along queue till reaching outgoing task disk drive
  1656.     local function queueForTask()
  1657.         print("\nQueue for task")
  1658.         local bFirst = true
  1659.         while true do
  1660.             local success, data = turtle.inspectDown()
  1661.             if success and data.name == "computercraft:disk_drive" then
  1662.                 print("Exiting Queue")
  1663.                 break
  1664.             end
  1665.             if bFirst then
  1666.                 success, data = turtle.inspect()
  1667.                 if success and (not isTurtleBlock(data)) then
  1668.                     while not moveDown() do sleep(0.5) end
  1669.                     turnInDirection("around")
  1670.                 end
  1671.                 bFirst = false
  1672.             end
  1673.             if not moveForward() then
  1674.                 sleep(0.5)
  1675.             else
  1676.                 success, data = turtle.inspectDown()
  1677.                 if success and data.name == "computercraft:disk_drive" then
  1678.                     print("Exiting Queue")
  1679.                     break
  1680.                 end
  1681.                 success, data = turtle.inspect()
  1682.                 if success and (not isTurtleBlock(data)) then
  1683.                     while not moveDown() do sleep(0.5) end
  1684.                     turnInDirection("around")
  1685.                 end
  1686.             end
  1687.         end
  1688.         save_status(TaskStatus.getTask)
  1689.         return true
  1690.     end
  1691.  
  1692.     local function turtleNeedsFuel()
  1693.         local fuelLevel = turtle.getFuelLevel()
  1694.  
  1695.         if fuelLevel < 2000 then
  1696.             print("Turtle needs more fuel")
  1697.             return true
  1698.         end
  1699.         return false
  1700.     end
  1701.  
  1702.     local function main()
  1703.         if load_status() == TaskStatus.refueling then
  1704.             if turtleNeedsFuel() then
  1705.                 return
  1706.             end
  1707.             if isDiskOnSide(DISK_NAMES.init, "bottom") then
  1708.                 save_status(TaskStatus.noTask)
  1709.             else
  1710.                 return
  1711.             end
  1712.         end
  1713.  
  1714.         if not getFacingValue(load_status()) then
  1715.             return
  1716.         end
  1717.  
  1718.         while true do
  1719.             local status = load_status()
  1720.             if status == TaskStatus.refueling then
  1721.                 if turtleNeedsFuel() then
  1722.                     return
  1723.                 end
  1724.                 if isDiskOnSide(DISK_NAMES.init, "bottom") then
  1725.                     save_status(TaskStatus.noTask)
  1726.                 else
  1727.                     return
  1728.                 end
  1729.             end
  1730.  
  1731.  
  1732.             if status == TaskStatus.getTask then
  1733.                 if turtleNeedsFuel() then
  1734.                     save_status(TaskStatus.refuelNeeded)
  1735.                 elseif not acceptTask() then
  1736.                     return
  1737.                 end
  1738.             elseif status == TaskStatus.accepted then
  1739.                 if goToCoord(getTaskStartCoords())then
  1740.                     save_status(TaskStatus.inProgress)
  1741.                 end
  1742.             elseif status == TaskStatus.inProgress then
  1743.                 if not doTaskWork() then return end
  1744.             elseif status == TaskStatus.finished then
  1745.                 if goToCoord(finishCoord) then              -- done
  1746.                     save_status(TaskStatus.completing)
  1747.                 end
  1748.             elseif status == TaskStatus.completing then
  1749.                 completeTask()
  1750.             elseif status == TaskStatus.joiningQueue then
  1751.                 joinQueue()                 -- done
  1752.             elseif status == TaskStatus.waiting then
  1753.                 queueForTask()              -- done
  1754.             elseif status == TaskStatus.refuelNeeded then
  1755.                 if goToCoord(refuelCoord) then              -- done
  1756.                     save_status(TaskStatus.refueling)
  1757.                 end
  1758.             else
  1759.                 if goToCoord(finishCoord) then              -- done
  1760.                     save_status(TaskStatus.joiningQueue)
  1761.                 end
  1762.             end
  1763.         end
  1764.     end
  1765.  
  1766.         -- === Initializing System ===
  1767.     orientation, direction, modulo, yModulo, finishCoord, outputCoord, refuelCoord = readInitData()
  1768.     directionVectors = getDirectionVectors(orientation, direction)
  1769.  
  1770.     finishCoord = add(finishCoord, directionVectors.up)
  1771.     outputCoord = add(outputCoord, directionVectors.forward)
  1772.     refuelCoord = add(add(refuelCoord, directionVectors.forward), directionVectors.forward)
  1773.  
  1774.     leftBeltCoord = getLeftBeltCoordinate(finishCoord, directionVectors.forward, orientation)
  1775.     rightBeltCoord = add(leftBeltCoord, directionVectors.up)
  1776.  
  1777.     facingVec = nil
  1778.     turtlePos = get_GPS_Position()
  1779.  
  1780.     main()
Advertisement
Add Comment
Please, Sign In to add comment