Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- pastebin get tDYAq4GS BoneMealTransporter
- local distanceX, distanceZ = ...
- if not distanceX then distanceX = -11 end
- if not distanceZ then distanceZ = 8 end
- distanceX = tonumber(distanceX)
- distanceZ = tostring(distanceZ)
- 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
- -- === 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")
- moveForward()
- -- 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 goToLift()
- local coord = add(startPos, startDir)
- local deltaX = coord.x - turtlePos.x
- 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}))
- moveForward()
- 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)}))
- moveForward()
- deltaZ = coord.z - turtlePos.z
- end
- end
- if dirX == 0 then
- moveToEqualX()
- moveToEqualZ()
- elseif dirZ == 0 then
- moveToEqualZ()
- moveToEqualX()
- end
- end
- 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}))
- moveForward()
- 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)}))
- moveForward()
- deltaZ = coord.z - turtlePos.z
- end
- end
- local function moveToEqualY()
- while not (deltaY == 0) do
- if deltaY > 0 then
- moveUp()
- elseif deltaY < 0 then
- moveDown()
- end
- deltaY = coord.y - turtlePos.y
- end
- end
- if not (deltaY == 0) then
- goToLift()
- moveToEqualY()
- deltaX = coord.x - turtlePos.x
- deltaZ = coord.z - turtlePos.z
- end
- if dirX == 0 then
- moveToEqualZ()
- moveToEqualX()
- elseif dirZ == 0 then
- moveToEqualX()
- moveToEqualZ()
- end
- end
- -- === Initialization ===
- local function saveStartingParameters()
- local parameterList = {pos = turtlePos, dir = direction, diffX = distanceX, diffZ = distanceZ}
- local file = fs.open("startingParameters.txt", "w")
- file.write(textutils.serialize(parameterList))
- file.close()
- end
- local function loadStartingParameters()
- if not fs.exists("startingParameters.txt") then return false end
- local file = fs.open("startingParameters.txt", "r")
- local data = textutils.unserialize(file.readAll())
- file.close()
- startPos = data.pos
- startDir = data.dir
- distanceX = data.diffX
- distanceZ = data.diffZ
- return true
- end
- local function initProgram()
- turtlePos = getGPSPosition()
- if not turtlePos then error("GPS failure, cannot run the program") end
- getDirection()
- if not loadStartingParameters() then
- startPos = turtlePos
- startDir = direction
- saveStartingParameters()
- end
- end
- -- === Inventory ===
- local function isBoneMeal(item)
- if not item or not item.name then return false end
- return item.name == "minecraft:bone_meal"
- 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 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 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 dumpInventory()
- 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
- for slot = 1, 16 do
- local item = turtle.getItemDetail(slot)
- if item then
- turtle.select(slot)
- while not turtle.drop() do sleep(5) end
- end
- end
- turtle.select(1)
- end
- local function turtleNeedsFuel()
- local fuelLevel = turtle.getFuelLevel()
- if fuelLevel < 1000 then
- if not isEqual(startPos, turtlePos) then
- goToPos(startPos)
- end
- print("Turtle needs more fuel")
- return true
- end
- return false
- end
- local function main()
- local diffToFinish = {x = distanceX, y = 0, z = distanceZ}
- local finishPos = add(startPos, diffToFinish)
- while true do
- if turtleNeedsFuel() then
- return
- end
- local bEnoughBoneMeal = true
- goToPos(startPos)
- for i=1, 16 do
- turtle.select(i)
- turtle.suckDown()
- if not selectBoneMealSlot() then
- bEnoughBoneMeal = false
- end
- end
- if not (bEnoughBoneMeal and getBoneMealCount() >= 64) then
- bEnoughBoneMeal = false
- sleep(60)
- end
- if bEnoughBoneMeal then
- compactInventory()
- goToPos(finishPos)
- turnInDirection(getTurnDirection(direction, startDir))
- dumpInventory()
- end
- end
- end
- initProgram()
- main()
Advertisement
Add Comment
Please, Sign In to add comment