Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- print("Running turtle explorer!")
- turtle.turnLeft()
- turtle.turnLeft()
- salt=require("salt")
- rednet.open("left")
- serverID=rednet.lookup("backroomExplorer","server")
- local currX,currY,currZ=gps.locate()
- function turnLeft()
- turtle.turnLeft()
- currRot=currRot-1
- if currRot<0 then
- currRot=3
- end
- end
- function turnRight()
- turtle.turnRight()
- currRot=currRot+1
- if currRot>3 then
- currRot=0
- end
- end
- function setup()
- local currX,currY,currZ=gps.locate()
- while turtle.detect() do
- turtle.turnLeft()
- end
- turtle.forward()
- currRot=0
- firstX,firstY,firstZ=gps.locate()
- if currX<firstX then
- currRot=0
- end
- if currX>firstX then
- currRot=2
- end
- if currZ<firstZ then
- currRot=1
- end
- if currZ>firstZ then
- currRot=3
- end
- end
- function gotoRotation(rot)
- while currRot~=rot do
- turnRight()
- end
- end
- function main()
- print("Running Setup")
- setup()
- print("Starting parallel loop")
- parallel.waitForAny(comms,mainLoop)
- end
- local dataBlock=nil
- local world={}
- --world=salt.load("World.lua")
- if world==nil then
- world={}
- end
- function getData(x,z)
- if world[x .. "," .. z] then
- dataBlock = world[x .. "," .. z]
- return
- end
- --print("Sending data request for " .. x .. "," .. z)
- dataBlock=nil
- rednet.send(serverID,textutils.serialize({x=x,z=z}),"backroomExplorer")
- sleep(0.25)
- while dataBlock== nil do
- sleep(1)
- rednet.send(serverID,textutils.serialize({x=x,z=z}),"backroomExplorer")
- sleep(1)
- --print("Waiting for data block...")
- end
- if type(dataBlock)=="table" then
- if dataBlock.type==-1 or dataBlock.type==1 or dataBlock.type==3 or dataBlock.type==4 then
- world[dataBlock.x .. "," .. dataBlock.z] = dataBlock
- salt.save(world,"World.lua",true)
- end
- end
- end
- local newExploreX=0
- local newExploreZ=0
- function mainLoop()
- while true do
- print("Getting new air block")
- local currX,currY,currZ=gps.locate()
- newExploreX=nil
- newExploreZ=nil
- while newExploreX==nil and newExploreZ==nil do
- rednet.send(serverID,textutils.serialize({x=currX,z=currZ}),"getNewAir")
- sleep(2)
- end
- brokenPath=false
- print("Calling explore!")
- if pcall(explore)==false then
- rednet.send(serverID,textutils.serialize({x=newExploreX,z=newExploreZ}),"broken")
- print("Sending error:")
- print(textutils.serialize({x=newExploreX,z=newExploreZ}))
- end
- if brokenPath then
- rednet.send(serverID,textutils.serialize({x=newExploreX,z=newExploreZ}),"broken")
- end
- sleep(0)
- end
- end
- function pathTo(goalX, goalZ)
- local playerX, playerY, playerZ = gps.locate()
- local search = {} -- key: "x,z", value: depth level
- local currentDepth = 0
- if playerX == goalX and playerZ == goalZ then
- print("Already at correct spot!")
- return
- end
- -- Check if goal is valid
- getData(goalX, goalZ)
- if type(dataBlock) ~= "table" or dataBlock.type == -1 or dataBlock.type == 2 then
- print("Invalid goal location")
- brokenPath=true
- return
- end
- -- Start BFS from goal
- local frontier = { { x = goalX, z = goalZ } }
- search[goalX .. "," .. goalZ] = 0
- print("Starting pathfinding")
- local found = false
- while #frontier > 0 and not found do
- local nextFrontier = {}
- for _, node in ipairs(frontier) do
- local dirs = {
- { x = 1, z = 0 },
- { x = -1, z = 0 },
- { x = 0, z = 1 },
- { x = 0, z = -1 },
- }
- for _, dir in ipairs(dirs) do
- local nx, nz = node.x + dir.x, node.z + dir.z
- local key = nx .. "," .. nz
- if not search[key] then
- getData(nx, nz)
- if type(dataBlock) == "table" and dataBlock.type ~= -1 and dataBlock.type ~= 2 then
- search[key] = currentDepth + 1
- table.insert(nextFrontier, { x = nx, z = nz })
- if nx == playerX and nz == playerZ then
- found = true
- break
- end
- end
- end
- end
- if found then break end
- end
- frontier = nextFrontier
- currentDepth = currentDepth + 1
- end
- if not found then
- print("No path found")
- brokenPath=true
- error()
- return
- end
- print("Path found, following it")
- -- Follow the path by moving through decreasing depths
- while not (playerX == goalX and playerZ == goalZ) and currentDepth > 0 do
- currentDepth = currentDepth - 1
- local moved = false
- local directions = {
- { x = 1, z = 0, rot = 0 },
- { x = 0, z = 1, rot = 1 },
- { x = -1, z = 0, rot = 2 },
- { x = 0, z = -1, rot = 3 },
- }
- for _, dir in ipairs(directions) do
- local nx, nz = playerX + dir.x, playerZ + dir.z
- local key = nx .. "," .. nz
- if search[key] == currentDepth and moved~=true then
- getData(nx, nz)
- if type(dataBlock) == "table" and dataBlock.type ~= -1 and dataBlock.type ~= 2 then
- local nextBlock = dataBlock
- getData(playerX, playerZ)
- local currentBlock = dataBlock
- moveToY(currentBlock.maxY)
- gotoRotation(dir.rot)
- if nextBlock.maxY>0 then
- moveToY(nextBlock.maxY)
- end
- while turtle.forward()==false do
- -- Only update position if move succeeded
- if turtle.detect() then
- local block,detail=turtle.inspect()
- if string.find(detail.name,"turtle") then
- while turtle.down()==false do
- sleep(0)
- end
- sleep(math.random(1,4))
- while turtle.up()==false do
- sleep(0)
- end
- end
- end
- playerX, playerY, playerZ = gps.locate()
- moved = true
- end
- playerX, playerY, playerZ = gps.locate()
- moved = true
- end
- end
- end
- if not moved then
- print("Path blocked or invalid")
- brokenPath=true
- error()
- return
- end
- end
- print("Destination reached")
- end
- function moveToY(yLevel)
- local currX, currY, currZ = gps.locate()
- while currY < yLevel do
- if turtle.up() then
- currY = currY + 1
- else
- return false
- end
- end
- while currY > yLevel do
- if turtle.down() then
- currY = currY - 1
- else
- return false
- end
- end
- return true
- end
- function splitString(str, sep)
- if sep == nil then
- sep = " "
- end
- local t = {}
- local start = 1
- while true do
- local sepStart, sepEnd = string.find(str, sep, start, true)
- if not sepStart then
- table.insert(t, string.sub(str, start))
- break
- end
- table.insert(t, string.sub(str, start, sepStart - 1))
- start = sepEnd + 1
- end
- return t
- end
- function explore()
- local goX=newExploreX
- local goZ=newExploreZ
- local goalX=0
- local goalZ=0
- local goalRot
- print("Checking for air blocks")
- getData(goX+1,goZ)
- if dataBlock~="Empty" then
- if dataBlock.type==1 or dataBlock.type==3 or dataBlock.type==4 then
- goalX=goX+1
- goalZ=goZ
- goalRot=2
- end
- end
- getData(goX-1,goZ)
- if dataBlock~="Empty" then
- if dataBlock.type==1 or dataBlock.type==3 or dataBlock.type==4 then
- goalX=goX-1
- goalZ=goZ
- goalRot=0
- end
- end
- getData(goX,goZ+1)
- if dataBlock~="Empty" then
- if dataBlock.type==1 or dataBlock.type==3 or dataBlock.type==4 then
- goalX=goX
- goalZ=goZ+1
- goalRot=3
- end
- end
- getData(goX,goZ-1)
- if dataBlock~="Empty" then
- if dataBlock.type==1 or dataBlock.type==3 or dataBlock.type==4 then
- goalX=goX
- goalZ=goZ-1
- goalRot=1
- end
- end
- if(goalX== 0 and goalZ==0) then
- return false
- end
- pathTo(goalX,goalZ)
- local currX,currY,currZ=gps.locate()
- getData(currX,currZ)
- local curr=dataBlock
- moveToY(curr.maxY)
- gotoRotation(goalRot)
- newBlock={
- x=goX,
- z=goZ,
- type=0,
- minY=0,
- maxY=0,
- name=""
- }
- isNonWall=turtle.detect()==false
- while isNonWall==false and turtle.down() do
- isNonWall=turtle.detect()==false
- end
- if isNonWall==false then
- newBlock.type=-1
- newBlock.name="Wall"
- rednet.send(serverID,textutils.serialize(newBlock),"inputData")
- return
- else
- turtle.forward()
- while turtle.down() do
- sleep(0)
- end
- print("Hit rock bottom")
- local currX,currY,currZ=gps.locate()
- newBlock.minY=currY
- local exist,block=turtle.inspectDown()
- print("Checking block name")
- newBlock.name=block.name
- print("Block name:",newBlock.name)
- if(string.find(newBlock.name,"sculk")) then
- newBlock.type=4
- elseif (string.find(newBlock.name,"carpet")) then
- newBlock.type=1
- else
- newBlock.type=3
- end
- print("Block Type:",newBlock.type)
- while turtle.up() do
- sleep(0)
- end
- print("Went Up!")
- local currX,currY,currZ=gps.locate()
- newBlock.maxY=currY
- rednet.send(serverID,textutils.serialize(newBlock),"inputData")
- return
- end
- end
- function comms()
- while true do
- local event, sender, message, protocol = os.pullEvent("rednet_message")
- --print("Got message!")
- if protocol ~= nil then
- --print("Received message from " .. sender .. " with protocol " .. protocol .. " and message " .. tostring(message))
- if protocol == "backroomExplorer" then
- if textutils.unserialize(message)~=nil then
- dataBlock=textutils.unserialize(message)
- else
- dataBlock="Empty"
- end
- elseif protocol=="getNewAir" then
- local newCoord=textutils.unserialize(message)
- newExploreX=newCoord.x
- newExploreZ=newCoord.z
- end
- else
- --print("Received message from " .. sender .. " with message " .. tostring(message))
- end
- sleep(0)
- end
- end
- main()
Advertisement
Add Comment
Please, Sign In to add comment