Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- home is a world location
- home = {x = nil, y = nil, z = nil, rotation = nil}
- -- work is relative to home
- work = {x = nil, y = nil, z = nil, rotation = nil}
- -- location is relative to home
- location = {x = nil, y = nil, z = nil, rotation = nil}
- listeners = {}
- validTools = {crafting = "Crafting", pickaxe = "Pickaxe", axe = "Axe", shovel = "Shovel", hoe = "Hoe", modem = "Modem", none = "None"}
- tools = {left = validTools.none, right = validTools.none}
- fuel = { "minecraft:coal", "minecraft:charcoal" }
- -- initialises the co-ordinates system and links up rednet
- function init()
- local x, y, z, rotation, startRotation = getInitialPosition()
- initHome(x, y, z).
- location.x = home.x - x
- location.y = home.y - y
- location.z = home.z - z
- location.rotation = rotation
- initWork()
- rotateTo(startRotation)
- end
- -- returns current x, y, z position of the turtle as well as the current rotation
- function getInitialPosition()
- local x1, y1, z1 = gps.locate()
- local rotation = 0
- local worldRotation = nil
- local foundRotation = false
- -- attempt to move turtle to find the facing location of the turtle
- while not foundRotation and rotation < 4 do
- moved = turtle.forward()
- local x2, y2, z2 = gps.locate()
- if moved then
- if z2 > z1 then worldRotation = 0
- elseif x2 > x1 then worldRotation = 1
- elseif z2 < z1 then worldRotation = 2
- elseif x2 < x1 then worldRotation = 3 end
- foundRotation = true
- -- return location back to start
- turtle.turnLeft()
- turtle.turnLeft()
- turtle.forward()
- else
- -- rotate clockwise
- turtle.turnRight()
- rotation = rotation + 1
- end
- end
- -- error out if rotation could not be found
- if not foundRotation then
- sendStatus("Could not find rotation")
- error()
- end
- local startWorldRotation = (worldRotation - rotation - 2) % 4
- home.rotation = settings.get("HomeRotation", startWorldRotation)
- local startRotation = (home.rotation - startWorldRotation) % 4
- local currentRotation = (home.rotation - worldRotation) % 4
- return x1, y1, z1, currentRotation, startRotation
- end
- -- collects existing home location or creates home location
- function initHome(x, y, z, dir)
- settings.load("settings")
- home.x = settings.get("HomeXPos", x)
- home.y = settings.get("HomeYPos", y)
- home.z = settings.get("HomeZPos", z)
- saveHome()
- end
- -- saves home location to settings
- function saveHome()
- settings.load("settings")
- settings.set("HomeXPos", home.x)
- settings.set("HomeYPos", home.y)
- settings.set("HomeZPos", home.z)
- settings.set("HomeRotation", home.rotation)
- settings.save("settings")
- end
- -- sends a gps request to get current work location, uses home rotation to infer correct rotation
- function initWorkLocation()
- settings.load("settings")
- work.x = settings.get("WorkXPos", location.x)
- work.y = settings.get("WorkYPos", location.y)
- work.z = settings.get("WorkZPos", location.z)
- work.rotation = settings.get("WorkRotation", location.rotation)
- saveWork()
- end
- -- saves work location to settings
- function saveWork()
- settings.load("settings")
- settings.set("WorkXPos", work.x)
- settings.set("WorkYPos", work.y)
- settings.set("WorkZPos", work.z)
- settings.set("WorkRotation", work.rotation)
- settings.save("settings")
- end
- -- moves position using co-ordinates relatove to home
- function moveToPosition(newX, newY, newZ, newRot, locationName)
- if not locationName then locationName = "Somewhere" end
- local newLocation = {x = newX, y = newY, z = newZ, rotation = newRot}
- local blockages = 0
- while not compareLocations(location, newLocation) and blockages < 10 do
- -- move to new y location
- while location.y ~= newLocation.y do
- if location.y > newLocation.y then
- sendStatus("Moving Down towards ".. locationName)
- moved = moveDown()
- elseif location.y < newLocation.y then
- sendStatus("Moving Up towards ".. locationName)
- moved = moveUp()
- end
- if not moved then
- blockages = blockages + 1
- break
- end
- end
- -- move to new x location
- while location.x ~= newLocation.x do
- if location.x > newLocation.x then
- sendStatus("Moving Left towards ".. locationName)
- if location.rotation ~= 3 then rotateTo(3) end
- moved = moveForward()
- elseif location.x < newLocation.x then
- sendStatus("Moving Right towards ".. locationName)
- if location.rotation ~= 1 then rotateTo(1) end
- moved = moveForward()
- end
- if not moved then
- blockages = blockages + 1
- break
- end
- end
- -- move to new z location
- while location.z ~= newLocation.z do
- if location.z > newLocation.z then
- sendStatus("Moving Backwards towards ".. locationName)
- if location.rotation ~= 2 then rotateTo(2) end
- moved = moveForward()
- elseif location.z < newLocation.z then
- sendStatus("Moving Forwards towards ".. locationName)
- if location.rotation ~= 0 then rotateTo(0) end
- moved = moveForward()
- end
- if not moved then
- blockages = blockages + 1
- break
- end
- end
- end
- rotateTo(newDir)
- return compareLocations(location, newLocation, true)
- end
- -- moves position using gps and world co-ordinates
- function moveToWorldPosition()
- end
- -- rotates the turtle once to the left and updates it's rotation
- function rotateLeft()
- location.rotation = location.rotation-1
- if (location.rotation == -1) then
- location.rotation = 3
- end
- turtle.turnLeft()
- end
- -- rotates the turtle once to the right and updates it's rotation
- function rotateRight()
- location.rotation = location.rotation+1
- if (location.rotation == 4) then
- location.rotation = 0
- end
- turtle.turnRight()
- end
- -- rotates the turtle to a new rotation based on home relative rotation
- function rotateTo(newDir)
- if location.rotation == newDir then
- return
- elseif (location.rotation + 1) % 4 == newDir then
- rotateRight()
- elseif (location.rotation - 1) % 4 == newDir then
- rotateLeft()
- else
- while location.rotation ~= newDir do
- rotateLeft()
- end
- end
- end
- -- rotates the turtle to face a world rotation
- function rotateToGlobal(newDir)
- end
- -- moves the turtle forward and updates the location based on relative rotation
- -- returns true on successful movement
- function moveForward()
- end
- -- moves the turtle up one block and updates the location
- -- returns true on successful movement
- function moveUp()
- if canDig() then
- while turtle.detectUp() do
- turtle.digUp()
- end
- end
- local moved = turtle.up()
- if not moved then return false end
- location.y = location.y + 1
- return true
- end
- -- moves the turtle down one block and updates the location
- -- returns true on successful movement
- function moveDown()
- if canDig() then
- while turtle.detectDown() do
- turtle.digDown()
- end
- end
- local moved = turtle.down()
- if not moved then return false end
- location.y = location.y - 1
- return true
- end
- -- returns the turtle's current world position
- function currentWorldPosition()
- local x, y, z = gps.locate()
- local rotation = getWorldRotation()
- return "[".. x..", ".. y..", ".. z..", ".. rotation .."]"
- end
- -- returns the turtle's current relative position
- function currentPosition()
- local x = location.x
- local x = location.y
- local x = location.z
- local x = location.rotation
- return "[".. x..", ".. y..", ".. z..", ".. rotation .."]"
- end
- function compareLocations(tab1, tab2, includeRotation)
- if includeRotation then
- return tab1.x == tab2.x and tab1.y == tab2.y and tab1.z == tab2.z and tab1.rotation == tab2.rotation
- else
- return tab1.x == tab2.x and tab1.y == tab2.y and tab1.z == tab2.z
- end
- end
- -- returns list of valid tools
- function getValidToolText()
- local text = ""
- for k, v in pairs(validTools) do
- if text ~= "" then text = text.. ", " end
- text = text .. v
- end
- return text
- end
- -- asks the player to input in the currently equipped tools on the turtle
- function getTools()
- local complete = false
- local toolText = "Valid Tools: ".. getValidToolText()
- local sides = peripheral.getNames()
- if tableContains("left", sides) then
- complete = true
- tools.left = validTools.modem
- end
- while not complete do
- term.clear()
- term.setCursorPos(1,1)
- print(toolText)
- io.write("Enter Left Tool: ")
- local leftTool = io.read()
- local valid, leftTool = validTool(leftTool)
- if valid then
- complete = true
- tools.left = leftTool
- end
- end
- complete = false
- if tableContains("right", sides) then
- complete = true
- tools.right = validTools.modem
- end
- while not complete do
- term.clear()
- term.setCursorPos(1,1)
- print(toolText)
- io.write("Enter Right Tool: ")
- local rightTool = io.read()
- local valid, rightTool = validTool(rightTool)
- if valid then
- complete = true
- tools.right = rightTool
- end
- end
- end
- -- returns true if tool is a tool found in the valid tools list
- function validTool(tool)
- for k,v in pairs(validTools) do
- if string.lower(v) == string.lower(tool) then
- return true, v
- end
- end
- return false, validTools.none
- end
- -- returns true if table contains str
- function tableContains(str, table)
- for k, v in pairs(table) do
- if v == str then return true end
- end
- return false
- end
- -- resets the turtles working settings
- function resetSettings()
- settings.load("settings")
- settings.clear()
- settings.save("settings")
- end
- -- finds an item in the turtle's inventory based off supplied id and returns as a list of inventory slots
- function findItem(id)
- local itemTable = {}
- for i = 1, 16, 1 do
- local slotData = turtle.getItemDetail(i)
- if (slotData and slotData.name == id) then
- table.insert(itemTable, i)
- end
- end
- if table.getn(itemTable) > 0 then
- return itemTable
- end
- return nil
- end
- -- returns true if empty slot was found and item was moved
- function moveItemToEmpty(slot)
- turtle.select(slot)
- for i = 1, 16, 1 do
- if i ~= slot then
- if turtle.transferTo(i) then
- return true
- end
- end
- end
- return false
- end
- -- returns true if space remains
- function checkSpace()
- for i = 1, 16, 1 do
- if not turtle.getItemDetail(i) then
- return true
- end
- end
- return false
- end
- -- attempts to merge stacks of all items starting from the bottom moving to the top most slot
- function minifyStacks()
- for i = 16, 1, -1 do
- local slotData = turtle.getItemDetail(i)
- if slotData then
- slotsTable = findItem(slotData.name)
- if slotsTable and table.getn(slotsTable) > 1 then
- for k,v in pairs(slotsTable or {}) do
- turtle.select(v)
- turtle.transferTo(i, turtle.getItemSpace(i))
- end
- end
- end
- end
- end
- -- returns home and requests more fuel
- function giveMeFuel()
- while not hasFuel() do
- sleep(2)
- end
- returnToWork()
- end
- -- attempts to fill fuel slot, returns true if enough fuel is located in the fuel slot.
- function hasFuel()
- local fuelSlots = {}
- local slotData = turtle.getItemDetail(1)
- -- search the first slot for a valid fuel item
- for k,v in pairs(fuel or {}) do
- -- find if any other slots contain any fuel
- local slotTable = findItem(v)
- table.insert(fuelSlots, slotTable)
- -- look in slot one, if contains fuel return
- if (slotData and slotData.name == v) then
- return turtle.getItemCount(1) > 1, slotTable
- end
- end
- -- move item out of fuel slot
- if slotData then
- moveItemToEmpty(1)
- end
- -- move valid fuel into slot
- for k,v in pairs(fuelSlots or {}) do
- if v then
- if table.getn(v) > 0 then
- turtle.select(v[1])
- turtle.transferTo(1)
- end
- return turtle.getItemCount(1) > 1, v
- end
- end
- return false, nil
- end
- -- returns true if item is a valid source of fuel
- function isFuel(slotData)
- for k,v in pairs(fuel or {}) do
- if slotData.name == v then return true end
- end
- return false
- end
- -- attempts to find the minimum fuel level required to return home safely
- function getMinFuelLevel()
- if locationNil(work) or locationNil(home) then return 800 end
- return math.abs(work.x) + math.abs(work.z) + math.abs(home.y - work.y) + 50
- end
- -- checks fuel levels and attempts to refuel the turtle
- function refuel()
- local hasFuelLeft, fuelSlots = hasFuel()
- if turtle.getFuelLevel() < getMinFuelLevel() then
- if not hasFuelLeft then
- giveMeFuel()
- end
- end
- if turtle.getFuelLevel() < 5120 then
- turtle.select(1)
- coalCount = turtle.getItemCount(1)
- if coalCount > 0 then turtle.refuel(coalCount-1) end
- end
- end
- -- drops any extra stacks of items found in the turtle's inventory, maintaining only one stack of the given item
- function dumpExtraStacks(itemId)
- items = findItem(itemId)
- if items and #items > 1 then
- for i = 2, #items, 1 do
- turtle.select(items[i])
- turtle.drop()
- end
- end
- end
- -- sends a rednet message to find listening computers to send further status updates to
- function getListeners()
- listeners = {rednet.lookup("turtle_status")}
- if listeners then
- for k, v in pairs(listeners) do
- rednet.send(v, "request_connect")
- end
- end
- end
- -- opens up the turtle's rednet system
- function openRednet()
- side = getModemSide()
- if not side then error("could not find modem") end
- rednet.open(side, 255)
- end
- -- returns the side of the turtle the modem is on else it returns nil if no modem is found
- function getModemSide()
- sides = peripheral.getNames()
- for k, v in pairs(sides) do
- if peripheral.getType(v) == "modem" then return v end
- end
- return nil
- end
- -- initialises the turtle's rednet system
- function initRednet()
- term.clear()
- term.setCursorPos(1,1)
- print("Initialising Rednet System")
- openRednet()
- getListeners()
- end
- -- sends a status update to all connected computers registered to listen for status updates
- function sendStatus(status)
- for k, v in pairs(listeners) do
- rednet.send(v, status.. "\n" .. currentWorldPosition())
- end
- end
Add Comment
Please, Sign In to add comment