Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- pastebin get Bfmm8YH2 Turtle Tasks
- AM = require("AM")
- SE = require("SE")
- TT = {}
- TT.Task = {}
- local function setTaskStatus(status)
- TT.Task.status = status
- SDM.TURTLE.saveTurtleTask(TT.Task)
- end
- local function finishTask()
- while true do
- local fList = SDM.getFinishedTask()
- if fList and #textutils.serialize(fList) > 2 then
- sleep(0.5)
- else
- SDM.setFinishedTask(TT.Task)
- TT.Task = {}
- SDM.TURTLE.saveTurtleTask({})
- return
- end
- end
- end
- local function isCoordLeftSection(coord)
- local initData = SDM.TURTLE.loadInitData()
- local chestSection = POS.getSection(coord)
- local d1 = (coord[POS.beltDir] - chestSection) * initData.dirTopBelt[POS.beltDir]
- if d1 > 0 then return false end
- return true
- end
- local function getItemCount(itemName)
- local num = 0
- for cnt=1, 16 do
- if turtle.getItemCount(cnt) > 0 then
- local item = turtle.getItemDetail(cnt)
- if not itemName or (item and item.name == itemName) then
- num = num + turtle.getItemCount(cnt)
- end
- end
- end
- return num
- end
- local function compactChestInventory(strDir)
- local chest = peripheral.wrap(strDir)
- local function getLastIndex(oldLast)
- local chestList = chest.list()
- for i=oldLast, 1, -1 do if chestList[i] then return i end end
- return 1
- end
- local lastIdx = getLastIndex(54)
- for i = 1, 54 do
- if i > lastIdx then break end
- local itemI = chest.getItemDetail(i, true)
- if not itemI or (itemI and itemI.count < itemI.maxCount) then
- for j = i + 1, 54 do
- if j > lastIdx then break end
- local itemJ = chest.getItemDetail(j, true)
- if (not itemI and itemJ) or (itemJ and itemJ.name == itemI.name) then
- chest.pushItems(strDir, j, itemJ.count, i)
- itemI = chest.getItemDetail(i, true)
- if not itemI or itemI.count == itemI.maxCount then
- break
- end
- end
- end
- lastIdx = getLastIndex(lastIdx)
- end
- end
- end
- local function getChestSingleItem()
- local chest = peripheral.wrap("front")
- local actualItem = {
- name = "", dName = "itemDName",
- stackSize = 64, number = 0
- }
- for i=1, 54 do
- local item = chest.getItemDetail(i, true)
- local itemD = SE.getItemInfo(item)
- if itemD and actualItem.name == "" then
- actualItem = itemD
- elseif itemD then
- if itemD.name == actualItem.name then
- actualItem.number = actualItem.number + itemD.number
- else
- return false, nil
- end
- end
- end
- if actualItem.name == "" then
- return true, nil
- end
- return true, actualItem
- end
- local function calcChestPos()
- local initData = SDM.TURTLE.loadInitData()
- local num = getItemCount()
- local yCoord = -num % 5
- local dirBeltCoord = 1
- if num <= 50 then
- dirBeltCoord = 0
- else
- num = num - 50
- end
- local dirSecCoord = math.floor(-((-num + 1) / 5))
- local pos = {x=dirBeltCoord, y=yCoord, z=dirSecCoord}
- if isCoordLeftSection(TT.Task.coords) then
- return {
- [POS.beltDir] = TT.Task.coords[POS.beltDir] + dirBeltCoord * initData.dirBottomBelt[POS.beltDir],
- ["y"] = TT.Task.coords["y"] + yCoord,
- [POS.sectionDir] = TT.Task.coords[POS.sectionDir] + dirSecCoord * initData.dirSection[POS.sectionDir]
- }
- else
- return {
- [POS.beltDir] = TT.Task.coords[POS.beltDir] + dirBeltCoord * initData.dirTopBelt[POS.beltDir],
- ["y"] = TT.Task.coords["y"] + yCoord,
- [POS.sectionDir] = TT.Task.coords[POS.sectionDir] + dirSecCoord * initData.dirSection[POS.sectionDir]
- }
- end
- end
- local function goToUncheckedChest(chest)
- local initData = SDM.TURTLE.loadInitData()
- if chest.checkState < 2 then
- local targChestCoord = {x=chest.coords.x,y=chest.coords.y,z=chest.coords.z}
- if isCoordLeftSection(targChestCoord) then
- targChestCoord = CVF.add(targChestCoord, initData.dirTopBelt)
- else
- targChestCoord = CVF.add(targChestCoord, initData.dirBottomBelt)
- end
- while not AM.goToCoord(targChestCoord) do
- while not POS.get_GPS_Position() do sleep(1) end
- end
- setTaskStatus(2)
- return true
- end
- return false
- end
- local function checkSingleChest(chest)
- local initData = SDM.TURTLE.loadInitData()
- if chest.checkState == 0 then
- local targChestCoord = {x=chest.coords.x,y=chest.coords.y,z=chest.coords.z}
- if isCoordLeftSection(targChestCoord) then
- targChestCoord = CVF.add(targChestCoord, initData.dirTopBelt)
- BM.turnInDirection("LEFT")
- else
- targChestCoord = CVF.add(targChestCoord, initData.dirBottomBelt)
- BM.turnInDirection("RIGHT")
- end
- if not CVF.equalCoords(targChestCoord, POS.position) then
- setTaskStatus(1)
- else
- local suc, item = getChestSingleItem()
- if suc then
- if item then
- chest.item = item
- end
- chest.checkState = 2
- SDM.TURTLE.saveTurtleTask(TT.Task)
- else
- chest.checkState = 1
- SDM.TURTLE.saveTurtleTask(TT.Task)
- while turtle.suck() do end
- setTaskStatus(3)
- end
- end
- return true
- end
- if chest.checkState == 1 then
- while turtle.suck() do end
- if getItemCount() == 0 then
- chest.checkState = 2
- SDM.TURTLE.saveTurtleTask(TT.Task)
- setTaskStatus(2)
- else
- setTaskStatus(3)
- end
- return true
- end
- return false
- end
- local function dropOfItems(dir)
- local fktInspect = {
- ["front"] = turtle.inspect,
- ["top"] = turtle.inspectUp,
- ["bottom"] = turtle.inspectDown
- }
- local fktDrop = {
- ["front"] = turtle.drop,
- ["top"] = turtle.dropUp,
- ["bottom"] = turtle.dropDown
- }
- local suc, block = fktInspect[dir]()
- if not suc or block.name ~= "minecraft:chest" then return false end
- local chest = peripheral.wrap(dir)
- for cnt=1, 16 do
- local item = turtle.getItemDetail(cnt, true)
- local itemD = SE.getItemInfo(item)
- if itemD then
- turtle.select(cnt)
- fktDrop[dir]()
- end
- end
- if getItemCount() == 0 then return true end
- return false
- end
- local function pullItems(dir, num)
- local fktInspect = {
- ["front"] = turtle.inspect,
- ["top"] = turtle.inspectUp,
- ["bottom"] = turtle.inspectDown
- }
- local fktSuck = {
- ["front"] = turtle.suck,
- ["top"] = turtle.suckUp,
- ["bottom"] = turtle.suckDown
- }
- local suc, block = fktInspect[dir]()
- if not suc or block.name ~= "minecraft:chest" then return false end
- end
- local function selectItem(itemName)
- for i=1, 16 do
- if turtle.getItemCount(i) > 0 then
- local item = turtle.getItemDetail(i)
- if item.name == itemName then
- turtle.select(i)
- return true
- end
- end
- end
- return false
- end
- local function compactInventory()
- for i = 1, 16 do
- local itemI = turtle.getItemDetail(i)
- if itemI and itemI.count < 64 then
- for j = i + 1, 16 do
- local itemJ = turtle.getItemDetail(j)
- if itemJ and itemJ.name == itemI.name then
- turtle.select(j)
- turtle.transferTo(i)
- -- Aktuellen Slot updaten
- itemI = turtle.getItemDetail(i)
- if not itemI or itemI.count == 64 then
- break
- end
- end
- end
- end
- end
- turtle.select(1) -- zum Standard zurückkehren
- end
- local function suckSpecificItem(itemName, count, strDir)
- local chest = peripheral.wrap(strDir)
- if not chest or not chest.list then
- return false
- end
- local chestItems = chest.list()
- local foundSlots = {}
- local totalAvailable = 0
- -- 1. Scans chest for requested Item
- for slot, itemA in pairs(chestItems) do
- local item = chest.getItemDetail(slot, true)
- local itemD = SE.getItemInfo(item)
- if itemD and itemD.name == itemName then
- table.insert(foundSlots, {slot = slot, count = itemD.number})
- totalAvailable = totalAvailable + itemD.number
- chestItems[slot].name = itemD.name
- end
- end
- if count > totalAvailable then return false end
- count = math.min(totalAvailable, count)
- if count == 0 then
- return false
- end
- -- 2. Looks for available Slot for cached item
- local cachedItemSlot = nil
- for i = 1, 16 do
- if turtle.getItemCount(i) == 0 then
- cachedItemSlot = i
- break
- end
- end
- if not cachedItemSlot then
- print("Kein freier Slot zum Zwischenspeichern des Kisten-Items.")
- return false
- end
- turtle.select(cachedItemSlot)
- local cachedItem = nil
- fktSuck = {
- ["front"] = turtle.suck,
- ["top"] = turtle.suckUp,
- ["bottom"] = turtle.suckDown
- }
- fktDrop = {
- ["front"] = turtle.drop,
- ["top"] = turtle.dropUp,
- ["bottom"] = turtle.dropDown
- }
- suck = fktSuck[strDir] or fktSuck["front"]
- drop = fktDrop[strDir] or fktDrop["front"]
- if chestItems[1] and chestItems[1].name ~= itemName then
- if suck(64) then
- cachedItem = turtle.getItemDetail(cachedItemSlot)
- end
- end
- -- 3. Moves first requested item to slot 1
- local nextSlotIndex = 1
- if not chest.getItemDetail(1) then
- local nextSource = foundSlots[nextSlotIndex]
- chest.pushItems(strDir, nextSource.slot, nextSource.count, 1)
- nextSlotIndex = nextSlotIndex + 1
- elseif (chest.getItemDetail(1) and SE.getItemInfo(chest.getItemDetail(1, true)).name == itemName) then
- nextSlotIndex = nextSlotIndex + 1
- end
- -- 4. Returns cached item (returns to first available chest slot ≠1)
- if cachedItem then
- turtle.select(cachedItemSlot)
- drop()
- end
- -- 5. Pulls requested items
- local collected = 0
- turtle.select(cachedItemSlot)
- while collected < count do
- local remaining = count - collected
- local slot1Item = chest.getItemDetail(1)
- local pullCount = math.min(slot1Item.count, remaining)
- if suck(pullCount) then
- collected = collected + pullCount
- end
- if collected < count and nextSlotIndex <= #foundSlots then
- local nextSource = foundSlots[nextSlotIndex]
- chest.pushItems(strDir, nextSource.slot, nextSource.count, 1)
- nextSlotIndex = nextSlotIndex + 1
- end
- end
- return true
- end
- function TT.getTask()
- local initData = SDM.TURTLE.loadInitData()
- local taskOutputCoord = initData.diskOutCoord
- taskOutputCoord.y = taskOutputCoord.y + 1
- local task = SDM.TURTLE.loadTurtleTask()
- if CVF.equalCoords(POS.position, taskOutputCoord) then
- if task and #textutils.serialize(task) == 2 then
- SDM.TURTLE.getNextOutgoingTask()
- task = SDM.TURTLE.loadTurtleTask()
- else
- local tasksOut = SDM.getOutgoingTasks()
- if tasksOut and #textutils.serialize(tasksOut) > 2 then
- local firstTask = table.remove(tasksOut, 1)
- if firstTask.id == task.id then
- SDM.setOutgoingTasks(tasks)
- end
- end
- TT.Task = task
- return true
- end
- end
- if task and #textutils.serialize(task) > 2 then
- TT.Task = task
- return true
- end
- return false
- end
- local bProgress = true
- function TT.doIncomingTask()
- local initData = SDM.TURTLE.loadInitData()
- if TT.Task.status == 1 then
- if suckSpecificItem(TT.Task.info.name, TT.Task.info.number, "top") then
- setTaskStatus(2)
- bProgress = true
- else
- if bProgress then
- if SDM.TURTLE.update_SE() then
- os.reboot()
- else
- print("Waiting for more items in chest above.")
- bProgress = false
- end
- end
- sleep(1)
- end
- elseif TT.Task.status == 2 then
- local targChestCoord = {x=TT.Task.coords.x,y=TT.Task.coords.y,z=TT.Task.coords.z}
- if isCoordLeftSection(targChestCoord) then
- targChestCoord = CVF.add(targChestCoord, initData.dirTopBelt)
- else
- targChestCoord = CVF.add(targChestCoord, initData.dirBottomBelt)
- end
- while not AM.goToCoord(targChestCoord) do
- while not POS.get_GPS_Position() do sleep(1) end
- end
- setTaskStatus(3)
- end
- if TT.Task.status == 3 then
- local targChestCoord = {x=TT.Task.coords.x,y=TT.Task.coords.y,z=TT.Task.coords.z}
- if isCoordLeftSection(targChestCoord) then
- targChestCoord = CVF.add(targChestCoord, initData.dirTopBelt)
- BM.turnInDirection("LEFT")
- else
- targChestCoord = CVF.add(targChestCoord, initData.dirBottomBelt)
- BM.turnInDirection("RIGHT")
- end
- if not CVF.equalCoords(targChestCoord, POS.position) then
- setTaskStatus(2)
- else
- if not dropOfItems("front") then
- compactChestInventory("front")
- if not dropOfItems("front") then
- setTaskStatus(4)
- else
- setTaskStatus(5)
- end
- else
- setTaskStatus(5)
- end
- end
- end
- if TT.Task.status == 4 then
- local targChestCoord = {x=initData.chestOutCoord.x,y=initData.chestOutCoord.y-1,z=initData.chestOutCoord.z}
- while not AM.goToCoord(targChestCoord) do
- while not POS.get_GPS_Position() do sleep(1) end
- end
- while not dropOfItems("top") do sleep(1) end
- setTaskStatus(5)
- end
- if TT.Task.status == 5 then
- local finishCoord = initData.diskFinishCoord
- finishCoord.y = initData.diskFinishCoord.y + 1
- while not AM.goToCoord(finishCoord) do
- while not POS.get_GPS_Position() do sleep(1) end
- end
- finishTask()
- AM.joinQueue()
- AM.queueForTask()
- end
- if TT.Task and #textutils.serialize(TT.Task) > 2 then
- return TT.doIncomingTask()
- end
- return true
- end
- function TT.doOutgoingTask()
- local initData = SDM.TURTLE.loadInitData()
- if TT.Task.status == 1 then
- local targChestCoord = {x=TT.Task.coords.x,y=TT.Task.coords.y,z=TT.Task.coords.z}
- if isCoordLeftSection(targChestCoord) then
- targChestCoord = CVF.add(targChestCoord, initData.dirTopBelt)
- else
- targChestCoord = CVF.add(targChestCoord, initData.dirBottomBelt)
- end
- while not AM.goToCoord(targChestCoord) do
- while not POS.get_GPS_Position() do sleep(1) end
- end
- setTaskStatus(2)
- elseif TT.Task.status == 2 then
- local targChestCoord = {x=TT.Task.coords.x,y=TT.Task.coords.y,z=TT.Task.coords.z}
- if isCoordLeftSection(targChestCoord) then
- targChestCoord = CVF.add(targChestCoord, initData.dirTopBelt)
- BM.turnInDirection("LEFT")
- else
- targChestCoord = CVF.add(targChestCoord, initData.dirBottomBelt)
- BM.turnInDirection("RIGHT")
- end
- if not CVF.equalCoords(targChestCoord, POS.position) then
- setTaskStatus(2)
- else
- if not suckSpecificItem(TT.Task.info.name, TT.Task.info.number, "front") then
- setTaskStatus(4)
- else
- setTaskStatus(3)
- end
- end
- elseif TT.Task.status == 3 then
- local targChestCoord = {x=initData.chestOutCoord.x,y=initData.chestOutCoord.y-1,z=initData.chestOutCoord.z}
- while not AM.goToCoord(targChestCoord) do
- while not POS.get_GPS_Position() do sleep(1) end
- end
- while not dropOfItems("top") do sleep(1) end
- setTaskStatus(4)
- elseif TT.Task.status == 4 then
- local finishCoord = initData.diskFinishCoord
- finishCoord.y = initData.diskFinishCoord.y + 1
- while not AM.goToCoord(finishCoord) do
- while not POS.get_GPS_Position() do sleep(1) end
- end
- finishTask()
- AM.joinQueue()
- AM.queueForTask()
- end
- if TT.Task and #textutils.serialize(TT.Task) > 2 then
- return TT.doOutgoingTask()
- end
- return true
- end
- function TT.doCreateChest()
- local initData = SDM.TURTLE.loadInitData()
- if TT.Task.status == 1 then
- BM.turnInDirection("RIGHT")
- if suckSpecificItem("minecraft:chest", 100, "front") then
- print("Succeeded")
- setTaskStatus(2)
- bProgress = true
- else
- if bProgress then
- print("Waiting for more chests in chest infront.")
- bProgress = false
- end
- sleep(1)
- end
- elseif TT.Task.status == 2 then
- local targChestCoord = {x=TT.Task.coords.x,y=TT.Task.coords.y,z=TT.Task.coords.z}
- if isCoordLeftSection(targChestCoord) then
- targChestCoord = CVF.add(targChestCoord, initData.dirTopBelt)
- else
- targChestCoord = CVF.add(targChestCoord, initData.dirBottomBelt)
- end
- while not AM.goToCoord(targChestCoord) do
- while not POS.get_GPS_Position() do sleep(1) end
- end
- if isCoordLeftSection(targChestCoord) then
- BM.turnInDirection("LEFT")
- else
- BM.turnInDirection("RIGHT")
- end
- setTaskStatus(3)
- elseif TT.Task.status == 3 then
- while getItemCount("minecraft:chest") > 0 do
- local targChestCoord = calcChestPos()
- AM.reachChestPlacementCoord(targChestCoord)
- selectItem("minecraft:chest")
- while not turtle.placeDown() do sleep(0.5) end
- end
- if getItemCount("minecraft:chest") == 0 then
- local targChestCoord = {x=TT.Task.coords.x,y=TT.Task.coords.y + 4,z=TT.Task.coords.z}
- AM.reachChestPlacementCoord(targChestCoord)
- if isCoordLeftSection(targChestCoord) then
- BM.turnInDirection("RIGHT")
- else
- BM.turnInDirection("LEFT")
- end
- while not BM.forward() do sleep(0.1) end
- while not BM.down() do sleep(0.1) end
- setTaskStatus(4)
- end
- elseif TT.Task.status == 4 then
- local finishCoord = initData.diskFinishCoord
- finishCoord.y = initData.diskFinishCoord.y + 1
- while not AM.goToCoord(finishCoord) do
- while not POS.get_GPS_Position() do sleep(1) end
- end
- finishTask()
- AM.joinQueue()
- AM.queueForTask()
- end
- if TT.Task and #textutils.serialize(TT.Task) > 2 then
- return TT.doCreateChest()
- end
- return true
- end
- function TT.doCheckChests()
- local initData = SDM.TURTLE.loadInitData()
- local chests = TT.Task.chests
- if TT.Task.status == 1 then
- print("GOTO Chest")
- for _, chest in ipairs(chests) do
- if goToUncheckedChest(chest) then break end
- end
- elseif TT.Task.status == 2 then
- print("CHECK Chest")
- local bCheckedAll = true
- for _, chest in ipairs(chests) do
- if checkSingleChest(chest) then break end
- end
- for _, chest in ipairs(chests) do
- bCheckedAll = bCheckedAll and chest.checkState == 2
- end
- if bCheckedAll then
- setTaskStatus(4)
- end
- elseif TT.Task.status == 3 then
- print("DROP Items")
- local targChestCoord = {x=initData.chestOutCoord.x,y=initData.chestOutCoord.y-1,z=initData.chestOutCoord.z}
- while not AM.goToCoord(targChestCoord) do
- while not POS.get_GPS_Position() do sleep(1) end
- end
- while not dropOfItems("top") do sleep(1) end
- setTaskStatus(1)
- elseif TT.Task.status == 4 then
- print("FINISH")
- local finishCoord = initData.diskFinishCoord
- finishCoord.y = initData.diskFinishCoord.y + 1
- while not AM.goToCoord(finishCoord) do
- while not POS.get_GPS_Position() do sleep(1) end
- end
- finishTask()
- AM.joinQueue()
- AM.queueForTask()
- end
- if TT.Task and #textutils.serialize(TT.Task) > 2 then
- return TT.doCheckChests()
- end
- return true
- end
- return TT
Advertisement
Add Comment
Please, Sign In to add comment