Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
local turtlePos, direction local startPos, startDir local function getGPSPosition() local x, y, z = gps.locate() if not x then print("Error: GPS not available") return nil end return {x = math.floor(x), y = math.floor(y), z = math.floor(z)} end local function negative(vec) return {x = -vec.x, y = -vec.y, z = -vec.z} end local function add(vec1, vec2) return {x = vec1.x + vec2.x, y = vec1.y + vec2.y, z = vec1.z + vec2.z} end local function sub(vec1, vec2) return add(vec1, negative(vec2)) end local function multiply(s, vec) return {x = s * vec.x, y = s * vec.y, z = s * vec.z} end local function getSign(number) return number / math.abs(number) end local function isEqual(vec1, vec2) return vec1.x == vec2.x and vec1.y == vec2.y and vec1.z == vec2.z end -- === Basic Movement === local function moveForward() if turtle.forward() then turtlePos = add(turtlePos, direction) return true end return false end local function moveUp() if turtle.up() then turtlePos.y = turtlePos.y + 1 return true end return false end local function moveDown() if turtle.down() then turtlePos.y = turtlePos.y - 1 return true end return false end local function forceMoveForward() while not moveForward() do turtle.dig() end end local function forceMoveUp() while not moveUp() do turtle.digUp() end end local function forceMoveDown() while not moveDown() do turtle.digDown() end end -- === Basic Turning === local function turnInDirection(dir) if not direction then return end if dir == "left" then turtle.turnLeft() direction = {x = direction.z, y = 0, z = -direction.x} elseif dir == "right" then turtle.turnRight() direction = {x = -direction.z, y = 0, z = direction.x} elseif dir == "around" then turtle.turnLeft() turtle.turnLeft() direction = {x = -direction.x, y = 0, z = -direction.z} end end local function getTurnDirection(from, to) local function vectorsEqual(a, b) return a.x == b.x and a.z == b.z end if vectorsEqual(from, to) then return nil end local left = {x = from.z, y = 0, z = -from.x} local right = {x = -from.z, y = 0, z = from.x} local back = {x = -from.x, y = 0, z = -from.z} if vectorsEqual(to, left) then return "left" elseif vectorsEqual(to, right) then return "right" elseif vectorsEqual(to, back) then return "around" else error("Invalid target direction") end end local function getDirection() local pos1 = getGPSPosition() if not pos1 then error("GPS failure, cannot get direction") end for i = 1, 4 do if turtle.forward() then local pos2 = getGPSPosition() if not pos2 then error("GPS failure after move") end -- turtlePos = pos2 -- Richtung berechnen direction = sub(pos2, pos1) -- zurück zur ursprünglichen Position turnInDirection("around") forceMoveForward() -- Sicherheitsprüfung local posBack = getGPSPosition() if not isEqual(pos1, posBack) then error("Warnung: Position hat sich beim Rückweg verschoben!") turtlePos = posBack -- explizit wieder auf GPS setzen else turtlePos = pos1 end turnInDirection("around") return else turtle.turnLeft() end end error("Unable to move forward in any direction for direction detection") end -- === Positioning === local function goToPos(coord) local deltaX = coord.x - turtlePos.x local deltaY = coord.y - turtlePos.y local deltaZ = coord.z - turtlePos.z local dirX = startDir.x local dirZ = startDir.z local function moveToEqualX() while not (deltaX == 0) do turnInDirection(getTurnDirection(direction, {x = getSign(deltaX), y = 0, z = 0})) forceMoveForward() deltaX = coord.x - turtlePos.x end end local function moveToEqualZ() while not (deltaZ == 0) do turnInDirection(getTurnDirection(direction, {x = 0, y = 0, z = getSign(deltaZ)})) forceMoveForward() deltaZ = coord.z - turtlePos.z end end local function moveToEqualY() while not (deltaY == 0) do if deltaY > 0 then forceMoveUp() elseif deltaY < 0 then forceMoveDown() end deltaY = coord.y - turtlePos.y end end if dirX == 0 then moveToEqualZ() moveToEqualX() elseif dirZ == 0 then moveToEqualX() moveToEqualZ() end if not (deltaY == 0) then moveToEqualY() deltaX = coord.x - turtlePos.x deltaZ = coord.z - turtlePos.z end end ------------------------- Startpos adapten local function goToStartOfTree() startTreePos = add(startPos, multiply(7, startDir)) goToPos(startTreePos) turnInDirection(getTurnDirection(direction, startDir)) end -- === Tasks === local function isSapling(item) if not item or not item.name then return false end local saplingSuffix = "pale_oak_sapling" return item.name:match(":.*" .. saplingSuffix .. "$") ~= nil end local function isBoneMeal(item) if not item or not item.name then return false end return item.name == "minecraft:bone_meal" end local function isLog(item) if not item or not item.name then return false end local logSuffix = "_log" return item.name:match(":.*" .. logSuffix .. "$") ~= nil end local function getBoneMealCount() local num = 0 for i = 1, 16 do local item = turtle.getItemDetail(i) if isBoneMeal(item) then num = num + turtle.getItemCount(i) end end return num end local function getSaplingCount() local num = 0 for i = 1, 16 do local item = turtle.getItemDetail(i) if isSapling(item) then num = num + turtle.getItemCount(i) end end return num end local function selectSaplingSlot() for i = 1, 16 do local item = turtle.getItemDetail(i) if isSapling(item) then turtle.select(i) return true end end return false end local function selectBoneMealSlot() for i = 1, 16 do local item = turtle.getItemDetail(i) if isBoneMeal(item) then turtle.select(i) return true end end return false end local function plantSapling() if not selectSaplingSlot() then return false end if not turtle.place() then return false end return true end local function plantAllSaplings() local function plantSaplingDown() if not selectSaplingSlot() then return false end if not turtle.placeDown() then suc, item = turtle.inspectDown() if suc and isSapling(item) then return true end return false end return true end goToStartOfTree() forceMoveUp() suc, item = turtle.inspect() if suc and isLog(item) then goToStartOfTree() return false end local returnValue = true forceMoveForward() returnValue = returnValue and plantSaplingDown() forceMoveForward() returnValue = returnValue and plantSaplingDown() turnInDirection("right") forceMoveForward() turnInDirection("right") returnValue = returnValue and plantSaplingDown() forceMoveForward() returnValue = returnValue and plantSaplingDown() goToStartOfTree() return returnValue end local function fellTillLeaves_GetTurnDir(cnt) local sucUp, itemUp = turtle.inspectUp() local sucFor, itemFor = turtle.inspect() local topTurnDir = "left" while (not (sucUp or itemUp.name == "minecraft:pale_oak_leaves")) and cnt < 20 do if sucFor and isLog(itemFor.name) then turtle.dig() end forceMoveUp() sucUp, itemUp = turtle.inspectUp() sucFor, itemFor = turtle.inspect() cnt = cnt + 1 end if (not (sucFor or itemFor.name == "minecraft:pale_oak_leaves") and cnt < 20) then topTurnDir = "right" forceMoveForward() sucUp, itemUp = turtle.inspectUp() while (not (sucUp or itemUp.name == "minecraft:pale_oak_leaves")) and cnt < 20 do forceMoveUp() sucUp, itemUp = turtle.inspectUp() cnt = cnt + 1 end end return topTurnDir end local function fellAtPos(startFellPos) goToPos(startFellPos) turnInDirection(getTurnDirection(direction, startDir)) local cnt = turtlePos.y - startFellPos.y local topTurnDir = fellTillLeaves_GetTurnDir(cnt) cnt = turtlePos.y - startFellPos.y turnInDirection("right") forceMoveForward() turnInDirection(topTurnDir) topTurnDir = fellTillLeaves_GetTurnDir(cnt) if topTurnDir == "right" then turnInDirection("around") end while turtlePos.y > startFellPos.y do local sucFor, itemFor = turtle.inspect() if sucFor and isLog(itemFor.name) then turtle.dig() end forceMoveDown() end end local function fellTree() local forwDir = startDir turnInDirection("left") local leftDir = direction local diffRight = negative(multiply(2, leftDir)) local diffFor = multiply(2, forwDir) local startFellPos1 = add(negative(forwDir),add(turtlePos, multiply(2, leftDir))) local startFellPos2 = add(startFellPos1, diffRight) local startFellPos3 = add(startFellPos2, diffRight) local startFellPos4 = add(startFellPos3, diffFor) local startFellPos5 = add(startFellPos2, diffFor) local startFellPos6 = add(startFellPos1, diffFor) local startFellPos7 = add(startFellPos6, diffFor) local startFellPos8 = add(startFellPos5, diffFor) local startFellPos9 = add(startFellPos4, diffFor) fellAtPos(startFellPos1) fellAtPos(startFellPos2) fellAtPos(startFellPos3) fellAtPos(startFellPos4) fellAtPos(startFellPos5) fellAtPos(startFellPos6) fellAtPos(startFellPos7) fellAtPos(startFellPos8) fellAtPos(startFellPos9) goToStartOfTree() end -- === Inventory Management === 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 -- Keep saplings local function dumpInventoryKeepSaplings(n) local success, chest = turtle.inspect() while not (success and chest.name == "minecraft:chest") do print("No chest found. Pls place one in front.") print("Press enter to continue.") read() success, chest = turtle.inspect() end local saplingsKept = 0 for slot = 1, 16 do local item = turtle.getItemDetail(slot) if item then turtle.select(slot) if isSapling(item) and saplingsKept < n then local keep = math.min(item.count, n - saplingsKept) local drop = item.count - keep if drop > 0 then turtle.drop(drop) end saplingsKept = saplingsKept + keep elseif not isBoneMeal(item) then turtle.drop() end end end turtle.select(1) end local function turtleNeedsFuel() local fuelLevel = turtle.getFuelLevel() if fuelLevel < 1000 then if not isEqual(startPos, turtlePos) then diffX = math.abs(startPos.x - turtlePos.x) diffY = math.abs(startPos.y - turtlePos.y) diffZ = math.abs(startPos.z - turtlePos.z) if not (fuelLevel < diffX + diffY + diffZ +5) then goToPos(startPos) end end print("Turtle needs more fuel") return true end return false end -- gets specified item in given amount (min(available, requested)) from chest 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. Scanne Kiste nach dem gewünschten Item for slot, item in pairs(chestItems) do if item.name == itemName then table.insert(foundSlots, {slot = slot, count = item.count}) totalAvailable = totalAvailable + item.count end end count = math.min(totalAvailable, count) if count == 0 then return false end -- 2. Finde freien Slot in der Turtle für gecachtes 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 local list = chest.list() if list[1] and list[1].name ~= itemName then if strDir == "front" then if turtle.suck(64) then cachedItem = turtle.getItemDetail(cachedItemSlot) end elseif strDir == "top" then if turtle.suckUp(64) then cachedItem = turtle.getItemDetail(cachedItemSlot) end elseif strDir == "bottom" then if turtle.suckDown(64) then cachedItem = turtle.getItemDetail(cachedItemSlot) end end end -- 3. Erstes gewünschtes Item in Slot 1 schieben 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 chest.getItemDetail(1).name == itemName) then nextSlotIndex = nextSlotIndex + 1 end -- 4. Gecachtes Item zurückgeben if cachedItem then turtle.select(cachedItemSlot) if strDir == "front" then turtle.drop() -- Kiste verteilt es automatisch auf einen freien Slot ≠ 1 elseif strDir == "top" then turtle.dropUp() -- Kiste verteilt es automatisch auf einen freien Slot ≠ 1 elseif strDir == "bottom" then turtle.dropDown() -- Kiste verteilt es automatisch auf einen freien Slot ≠ 1 end end -- 5. Zielitems absaugen local collected = 0 turtle.select(cachedItemSlot) -- Wiederverwenden für Einsammeln while collected < count do local remaining = count - collected local slot1Item = chest.getItemDetail(1) local pullCount = math.min(slot1Item.count, remaining) if strDir == "front" then if turtle.suck(pullCount) then collected = collected + pullCount end elseif strDir == "top" then if turtle.suckUp(pullCount) then collected = collected + pullCount end elseif strDir == "bottom" then if turtle.suckDown(pullCount) then collected = collected + pullCount end 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 local function processAndStockInventory() goToPos(startPos) turnInDirection(getTurnDirection(direction, negative(startDir))) dumpInventoryKeepSaplings(64) if getSaplingCount() < 8 then suckSpecificItem("minecraft:pale_oak_sapling", 64 - getSaplingCount(), "bottom") bFirst = true while getSaplingCount() < 8 do if bFirst then print("Waiting for new Saplings!") bFirst = false end if not suckSpecificItem("minecraft:pale_oak_sapling", 64 - getSaplingCount(), "bottom") then sleep(5) end end end if getBoneMealCount() < 64 then suckSpecificItem("minecraft:bone_meal", 64 - getBoneMealCount(), "top") bFirst = true while getBoneMealCount() < 10 do if bFirst then print("Waiting for new Bone Meal!") bFirst = false end if not suckSpecificItem("minecraft:bone_meal", 64 - getBoneMealCount(), "top") then sleep(5) end end end compactInventory() goToStartOfTree() end -- === Initialization === local function destroyTreeBlocks() local suc, item = turtle.inspect() if not suc then return end local treeBlocks = {"minecraft:pale_oak_leaves", "minecraft:pale_oak_log"} cnt = 1 while cnt <= 2 do if item.name == treeBlocks[cnt] then turtle.dig() return end cnt = cnt + 1 end end local function saveStartingParameters() local parameterList = {pos = turtlePos, dir = direction} local file = fs.open("paleOakStartingParameters.txt", "w") file.write(textutils.serialize(parameterList)) file.close() end local function loadStartingParameters() if not fs.exists("paleOakStartingParameters.txt") then return false end local file = fs.open("paleOakStartingParameters.txt", "r") local data = textutils.unserialize(file.readAll()) file.close() startPos = data.pos startDir = data.dir return true end local function initProgram() turtlePos = getGPSPosition() if not turtlePos then error("GPS failure, cannot run the program") end destroyTreeBlocks() getDirection() if not loadStartingParameters() then startPos = turtlePos startDir = direction saveStartingParameters() end end -- === Main === local function main() bSaplingPlanted = true while turtle.getFuelLevel() < 5 do print("Turtle needs more fuel") return end initProgram() if turtleNeedsFuel() then return end if (getBoneMealCount() == 0) or (getSaplingCount() < 4) then processAndStockInventory() end goToStartOfTree() plantAllSaplings() while true do if turtleNeedsFuel() then return end if bSaplingPlanted then suc, item = turtle.inspect() if suc and isSapling(item) then if selectBoneMealSlot() then turtle.place() else processAndStockInventory() end else if suc and isLog(item) then fellTree() bSaplingPlanted = false end slotCount = turtle.getItemCount(16) if slotCount > 0 then processAndStockInventory() end end else if not plantAllSaplings() then processAndStockInventory() if not plantAllSaplings() then goToPos(startPos) print("Error: Saplings cannot be planted!") return end end bSaplingPlanted = true end end end main()
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)