Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- dirTable = {{0, 1}, {-1, 0}, {0, -1}, {1, 0}}
- posX = 0
- posY = 0
- posZ = 0
- dir = 1
- fuel = 0
- protectedBlocks = {'computercraft:turtle_normal', 'computercraft:turtle_advanced'}
- protectedChunks = {}
- nodes = {}
- function GetPosition()
- x, y, z = gps.locate()
- if x ~= nil then --Recieved our position
- posX, posY, posZ = x, y, z
- return true
- end
- return false
- end
- function UpdatePChunkLoop()
- rednet.open('left')
- while true do
- sender,message,distance = rednet.receive("V_PC")
- protectedChunks = textutils.unserialise(message)
- end
- end
- local function has_value (tab, val)
- for index, value in ipairs(tab) do
- if value == val then
- return true
- end
- end
- return false
- end
- function IsTurtle(name)
- if name == protectedBlocks[1] or name == protectedBlocks[2] then
- return true
- end
- return false
- end
- function IsInProtectedChunk()
- chunkX = math.floor(posX/16)
- chunkZ = math.floor(posZ/16)
- if has_value(protectedChunks, chunkX..','..chunkZ) then
- return true
- end
- return false
- end
- function ifProtected(data, ignorePChunk)
- -- Check if block is turtle
- if IsTurtle(data.name) then
- return true
- end
- if ignorePChunk then
- return false
- end
- return IsInProtectedChunk()
- end
- function DirToCoords(direction)
- x = dirTable[direction][1]
- z = dirTable[direction][2]
- return x, z
- end
- function IncrementDir(amount)
- if dir + amount > 4 then
- dir = 1
- elseif dir + amount < 1 then
- dir = 4
- end
- end
- function Forward(ignorePChunk)
- success, data = turtle.inspect()
- if ifProtected(data, ignorePChunk) ~= true then
- if success then
- turtle.dig('right')
- end
- if turtle.forward() then
- x, z = DirToCoords(dir)
- posX = posX + x
- posZ = posZ + z
- return true
- end
- end
- return false
- end
- function Up(ignorePChunk)
- success, data = turtle.inspect()
- if ifProtected(data, ignorePChunk) ~= true then
- if success then
- turtle.digUp('right')
- end
- if turtle.up() then
- posY = posY + 1
- return true
- end
- end
- return false
- end
- function Down(ignorePChunk)
- success, data = turtle.inspect()
- if ifProtected(data, ignorePChunk) ~= true then
- if success then
- turtle.digDown('right')
- end
- if turtle.down() then
- posY = posY - 1
- return true
- end
- end
- return false
- end
- function ToWorldHeight()
- while true do
- success, data = turtle.inspectUp()
- if success then -- If a block above
- while true do
- success, data = turtle.inspectUp()
- if IsTurtle(data.name) == false then
- break
- end
- Forward(true) -- Otherwise go forward and try again
- end
- turtle.digUp()
- end
- if turtle.up() == false then --Reached height limit
- break
- end
- end
- end
- function OutOfFuelCall()
- while true do
- if fuel <= 1 then
- rednet.broadcast("OUT OF FUEL X"..posX..', Y'..posY..', Z'..posZ, "V_M")
- fuel = turtle.getFuelLevel()
- end
- sleep(60)
- end
- end
- function DownUntil()
- while true do
- success, data = turtle.inspectDown()
- if success then
- if IsTurtle(data.name) then
- sleep(1)
- else
- break -- We reached a block that is not a tutel
- end
- else
- if turtle.down() then
- posY = posY - 1
- end
- end
- end
- end
- function Refuel()
- for i=1, 16 do
- turtle.select(i)
- turtle.refuel()
- if turtle.getFuelLevel() == turtle.getFuelLimit() then
- break
- end
- end
- fuel = turtle.getFuelLevel()
- turtle.select(1)
- end
- function LeaveProtectedChunk()
- ToWorldHeight()
- while true do
- Forward(true)
- if IsInProtectedChunk() == false then
- break
- end
- end
- DownUntil()
- end
- function Dump()
- for i=1, 16 do
- turtle.select(i)
- turtle.dropDown()
- end
- turtle.select(1)
- end
- function ToNode()
- print('Moving to node...')
- -- Face south
- print('Facing south...')
- while true do
- if dir == 1 then
- break
- end
- turtle.turnRight()
- IncrementDir(1)
- end
- -- Go to height limit
- print('Moving to world height...')
- ToWorldHeight()
- -- Get nodes
- rednet.broadcast("Node request", "V_RN")
- nodes = {}
- while true do
- sender,message,distance = rednet.receive("V_N", 2)
- if message == nil then
- break
- end
- print('Recieved a node')
- table.insert(nodes, {textutils.unserialise(message), distance})
- end
- -- Choose nearest node
- closestNode = {0,0}
- closestDist = 99999999
- for i=1,#nodes do
- nX = nodes[i][1][1]
- nZ = nodes[i][1][2]
- nDist = math.sqrt(math.pow(nX - posX, 2) + math.pow(nZ - posZ, 2))
- if nDist < closestDist then
- closestNode = nodes[i][1]
- closestDist = nDist
- end
- end
- print('Moving to node at '..closestNode[1]..', '..closestNode[2])
- -- Go to node
- if closestNode[1] > posX then
- turtle.turnLeft()
- IncrementDir(-1)
- while posX ~= closestNode[1] do
- Forward(true)
- end
- turtle.turnRight()
- IncrementDir(1)
- else
- turtle.turnRight()
- IncrementDir(1)
- while posX ~= closestNode[1] do
- Forward(true)
- end
- turtle.turnLeft()
- IncrementDir(-1)
- end
- print('Arrived at node X')
- if closestNode[2] > posZ then
- while posZ ~= closestNode[2] do
- Forward(true)
- end
- else
- turtle.turnLeft()
- turtle.turnLeft()
- IncrementDir(-2)
- while posZ ~= closestNode[2] do
- Forward(true)
- end
- turtle.turnRight()
- turtle.turnRight()
- IncrementDir(2)
- end
- print('Arrived at node Z')
- -- Go down until block is reached
- DownUntil()
- -- Recheck that we have arrived at a node
- while GetPosition() == false do
- rednet.broadcast("COULD NOT RESOLVE POSITION X"..posX..', Y'..posY..', Z'..posZ, "V_M")
- sleep(60)
- end
- if posX == closestNode[1] and posZ == closestNode[2] then
- -- Dump inventory into node
- Dump()
- -- Refuel
- turtle.select(1)
- while turtle.getFuelLevel() ~= turtle.getFuelLimit() do
- if turtle.suck(64) == false then
- sleep(5)
- end
- turtle.refuel(64)
- end
- -- Dump exess fuel
- Dump()
- -- Leave node area
- turtle.turnRight()
- turtle.forward()
- turtle.turnLeft()
- LeaveProtectedChunk()
- else
- rednet.broadcast("FAILED TO REACH NODE X"..closestNode[1]..', Z'..closestNode[2], "V_M")
- ToNode()
- end
- end
- function RunCommands()
- while true do
- sender,message,distance = rednet.receive("V_CT")
- if message == 'pos' then
- rednet.send(sender, 'pos '..posX..' '..posY..' '..posZ, "V_M")
- elseif message == 'upd' then
- shell.run('update.lua')
- end
- end
- end
- function Main()
- if IsInProtectedChunk() then
- print('Inside protected chunk!')
- LeaveProtectedChunk()
- end
- lastRot = 0
- lastV = 0
- while true do
- fuel = turtle.getFuelLevel()
- if fuel < 5000 or turtle.getItemCount(16) > 0 then
- ToNode()
- end
- while fuel <= 1 do
- rednet.broadcast("OUT OF FUEL X"..posX..', Y'..posY..', Z'..posZ, "V_M")
- fuel = turtle.getFuelLevel()
- sleep(60)
- end
- rand = math.random(5)
- if rand == 1 and lastRot ~= -1 then
- turtle.turnRight()
- IncrementDir(1)
- Forward(false)
- lastRot = 1
- lastV = 0
- elseif rand == 2 and lastRot ~= 1 then
- turtle.turnLeft()
- IncrementDir(-1)
- Forward(false)
- lastRot = -1
- lastV = 0
- elseif rand == 3 then
- Forward(false)
- lastV = 0
- elseif rand == 4 and lastV ~= -1 then
- Up(false)
- lastV = 1
- elseif lastV ~= 1 then
- Down(false)
- lastV = -1
- end
- end
- end
- print('Add fuel and equip tools')
- print('Ensure Turtle is near gps node')
- print('Ensure Turtle is facing south')
- print('Initializing Turtle...')
- Refuel()
- turtle.select(1)
- print('Fuel: '..turtle.getFuelLevel())
- while GetPosition() == false do
- print('Could not resolve position. Ensure turtle is near functional GPS node')
- sleep(30)
- end
- print('Received position X'..posX..' Y'..posY..' Z'..posZ)
- rednet.open('left')
- rednet.broadcast('V_RPC', 'V_RPC')
- sender,message,distance = rednet.receive("V_PC")
- rednet.close()
- protectedChunks = textutils.unserialise(message)
- print('Received '..#protectedChunks..' protected chunks')
- print('Initialization complete! m a y t h e v o i d e m b r a c e y o u')
- parallel.waitForAll(UpdatePChunkLoop, Main, OutOfFuelCall, RunCommands)
Add Comment
Please, Sign In to add comment