remie92

explore

Jul 25th, 2025 (edited)
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.02 KB | None | 0 0
  1. print("Running turtle explorer!")
  2. turtle.turnLeft()
  3. turtle.turnLeft()
  4. salt=require("salt")
  5.  
  6. rednet.open("left")
  7. serverID=rednet.lookup("backroomExplorer","server")
  8. local currX,currY,currZ=gps.locate()
  9.  
  10. function turnLeft()
  11. turtle.turnLeft()
  12. currRot=currRot-1
  13. if currRot<0 then
  14. currRot=3
  15. end
  16. end
  17.  
  18. function turnRight()
  19. turtle.turnRight()
  20. currRot=currRot+1
  21. if currRot>3 then
  22. currRot=0
  23. end
  24. end
  25.  
  26. function setup()
  27. local currX,currY,currZ=gps.locate()
  28. while turtle.detect() do
  29. turtle.turnLeft()
  30. end
  31.  
  32. turtle.forward()
  33.  
  34.  
  35. currRot=0
  36. firstX,firstY,firstZ=gps.locate()
  37.  
  38. if currX<firstX then
  39. currRot=0
  40. end
  41. if currX>firstX then
  42. currRot=2
  43. end
  44. if currZ<firstZ then
  45. currRot=1
  46. end
  47. if currZ>firstZ then
  48. currRot=3
  49. end
  50. end
  51.  
  52. function gotoRotation(rot)
  53. while currRot~=rot do
  54. turnRight()
  55. end
  56. end
  57.  
  58. function main()
  59. print("Running Setup")
  60. setup()
  61. print("Starting parallel loop")
  62. parallel.waitForAny(comms,mainLoop)
  63.  
  64. end
  65.  
  66.  
  67.  
  68.  
  69. local dataBlock=nil
  70. local world={}
  71.  
  72. --world=salt.load("World.lua")
  73.  
  74. if world==nil then
  75. world={}
  76. end
  77.  
  78. function getData(x,z)
  79. if world[x .. "," .. z] then
  80. dataBlock = world[x .. "," .. z]
  81. return
  82. end
  83. --print("Sending data request for " .. x .. "," .. z)
  84. dataBlock=nil
  85. rednet.send(serverID,textutils.serialize({x=x,z=z}),"backroomExplorer")
  86. sleep(0.25)
  87. while dataBlock== nil do
  88. sleep(1)
  89. rednet.send(serverID,textutils.serialize({x=x,z=z}),"backroomExplorer")
  90. sleep(1)
  91. --print("Waiting for data block...")
  92. end
  93. if type(dataBlock)=="table" then
  94. if dataBlock.type==-1 or dataBlock.type==1 or dataBlock.type==3 or dataBlock.type==4 then
  95. world[dataBlock.x .. "," .. dataBlock.z] = dataBlock
  96. salt.save(world,"World.lua",true)
  97. end
  98. end
  99. end
  100.  
  101. local newExploreX=0
  102. local newExploreZ=0
  103. function mainLoop()
  104. while true do
  105. print("Getting new air block")
  106. local currX,currY,currZ=gps.locate()
  107. newExploreX=nil
  108. newExploreZ=nil
  109. while newExploreX==nil and newExploreZ==nil do
  110. rednet.send(serverID,textutils.serialize({x=currX,z=currZ}),"getNewAir")
  111. sleep(2)
  112. end
  113. brokenPath=false
  114. print("Calling explore!")
  115. if pcall(explore)==false then
  116. rednet.send(serverID,textutils.serialize({x=newExploreX,z=newExploreZ}),"broken")
  117. print("Sending error:")
  118. print(textutils.serialize({x=newExploreX,z=newExploreZ}))
  119. end
  120. if brokenPath then
  121. rednet.send(serverID,textutils.serialize({x=newExploreX,z=newExploreZ}),"broken")
  122. end
  123. sleep(0)
  124. end
  125. end
  126.  
  127.  
  128.  
  129. function pathTo(goalX, goalZ)
  130. local playerX, playerY, playerZ = gps.locate()
  131. local search = {} -- key: "x,z", value: depth level
  132. local currentDepth = 0
  133. if playerX == goalX and playerZ == goalZ then
  134. print("Already at correct spot!")
  135. return
  136. end
  137. -- Check if goal is valid
  138. getData(goalX, goalZ)
  139. if type(dataBlock) ~= "table" or dataBlock.type == -1 or dataBlock.type == 2 then
  140. print("Invalid goal location")
  141. brokenPath=true
  142. return
  143. end
  144.  
  145. -- Start BFS from goal
  146. local frontier = { { x = goalX, z = goalZ } }
  147. search[goalX .. "," .. goalZ] = 0
  148.  
  149. print("Starting pathfinding")
  150.  
  151. local found = false
  152.  
  153. while #frontier > 0 and not found do
  154. local nextFrontier = {}
  155. for _, node in ipairs(frontier) do
  156. local dirs = {
  157. { x = 1, z = 0 },
  158. { x = -1, z = 0 },
  159. { x = 0, z = 1 },
  160. { x = 0, z = -1 },
  161. }
  162.  
  163. for _, dir in ipairs(dirs) do
  164. local nx, nz = node.x + dir.x, node.z + dir.z
  165. local key = nx .. "," .. nz
  166. if not search[key] then
  167. getData(nx, nz)
  168. if type(dataBlock) == "table" and dataBlock.type ~= -1 and dataBlock.type ~= 2 then
  169. search[key] = currentDepth + 1
  170. table.insert(nextFrontier, { x = nx, z = nz })
  171.  
  172. if nx == playerX and nz == playerZ then
  173. found = true
  174. break
  175. end
  176. end
  177. end
  178. end
  179. if found then break end
  180. end
  181. frontier = nextFrontier
  182. currentDepth = currentDepth + 1
  183. end
  184.  
  185. if not found then
  186. print("No path found")
  187. brokenPath=true
  188. error()
  189. return
  190. end
  191.  
  192. print("Path found, following it")
  193.  
  194. -- Follow the path by moving through decreasing depths
  195. while not (playerX == goalX and playerZ == goalZ) and currentDepth > 0 do
  196. currentDepth = currentDepth - 1
  197. local moved = false
  198.  
  199. local directions = {
  200. { x = 1, z = 0, rot = 0 },
  201. { x = 0, z = 1, rot = 1 },
  202. { x = -1, z = 0, rot = 2 },
  203. { x = 0, z = -1, rot = 3 },
  204. }
  205.  
  206. for _, dir in ipairs(directions) do
  207. local nx, nz = playerX + dir.x, playerZ + dir.z
  208. local key = nx .. "," .. nz
  209.  
  210. if search[key] == currentDepth and moved~=true then
  211. getData(nx, nz)
  212. if type(dataBlock) == "table" and dataBlock.type ~= -1 and dataBlock.type ~= 2 then
  213. local nextBlock = dataBlock
  214. getData(playerX, playerZ)
  215. local currentBlock = dataBlock
  216. moveToY(currentBlock.maxY)
  217. gotoRotation(dir.rot)
  218. if nextBlock.maxY>0 then
  219. moveToY(nextBlock.maxY)
  220. end
  221.  
  222. while turtle.forward()==false do
  223. -- Only update position if move succeeded
  224. if turtle.detect() then
  225. local block,detail=turtle.inspect()
  226. if string.find(detail.name,"turtle") then
  227. while turtle.down()==false do
  228. sleep(0)
  229. end
  230. sleep(math.random(1,4))
  231. while turtle.up()==false do
  232. sleep(0)
  233. end
  234. end
  235. end
  236. playerX, playerY, playerZ = gps.locate()
  237. moved = true
  238. end
  239. playerX, playerY, playerZ = gps.locate()
  240. moved = true
  241. end
  242. end
  243. end
  244.  
  245. if not moved then
  246. print("Path blocked or invalid")
  247. brokenPath=true
  248. error()
  249. return
  250. end
  251. end
  252.  
  253. print("Destination reached")
  254. end
  255.  
  256.  
  257.  
  258.  
  259. function moveToY(yLevel)
  260. local currX, currY, currZ = gps.locate()
  261. while currY < yLevel do
  262. if turtle.up() then
  263. currY = currY + 1
  264. else
  265. return false
  266. end
  267. end
  268. while currY > yLevel do
  269. if turtle.down() then
  270. currY = currY - 1
  271. else
  272. return false
  273. end
  274. end
  275. return true
  276. end
  277.  
  278. function splitString(str, sep)
  279. if sep == nil then
  280. sep = " "
  281. end
  282.  
  283. local t = {}
  284. local start = 1
  285.  
  286. while true do
  287. local sepStart, sepEnd = string.find(str, sep, start, true)
  288. if not sepStart then
  289. table.insert(t, string.sub(str, start))
  290. break
  291. end
  292. table.insert(t, string.sub(str, start, sepStart - 1))
  293. start = sepEnd + 1
  294. end
  295.  
  296. return t
  297. end
  298.  
  299. function explore()
  300. local goX=newExploreX
  301. local goZ=newExploreZ
  302. local goalX=0
  303. local goalZ=0
  304. local goalRot
  305. print("Checking for air blocks")
  306. getData(goX+1,goZ)
  307.  
  308. if dataBlock~="Empty" then
  309. if dataBlock.type==1 or dataBlock.type==3 or dataBlock.type==4 then
  310. goalX=goX+1
  311. goalZ=goZ
  312. goalRot=2
  313. end
  314. end
  315. getData(goX-1,goZ)
  316.  
  317. if dataBlock~="Empty" then
  318. if dataBlock.type==1 or dataBlock.type==3 or dataBlock.type==4 then
  319. goalX=goX-1
  320. goalZ=goZ
  321. goalRot=0
  322. end
  323. end
  324. getData(goX,goZ+1)
  325.  
  326. if dataBlock~="Empty" then
  327. if dataBlock.type==1 or dataBlock.type==3 or dataBlock.type==4 then
  328. goalX=goX
  329. goalZ=goZ+1
  330. goalRot=3
  331. end
  332. end
  333. getData(goX,goZ-1)
  334. if dataBlock~="Empty" then
  335. if dataBlock.type==1 or dataBlock.type==3 or dataBlock.type==4 then
  336. goalX=goX
  337. goalZ=goZ-1
  338. goalRot=1
  339. end
  340. end
  341.  
  342. if(goalX== 0 and goalZ==0) then
  343. return false
  344. end
  345.  
  346. pathTo(goalX,goalZ)
  347.  
  348. local currX,currY,currZ=gps.locate()
  349. getData(currX,currZ)
  350. local curr=dataBlock
  351. moveToY(curr.maxY)
  352. gotoRotation(goalRot)
  353.  
  354.  
  355. newBlock={
  356. x=goX,
  357. z=goZ,
  358. type=0,
  359. minY=0,
  360. maxY=0,
  361. name=""
  362. }
  363.  
  364. isNonWall=turtle.detect()==false
  365. while isNonWall==false and turtle.down() do
  366. isNonWall=turtle.detect()==false
  367. end
  368.  
  369. if isNonWall==false then
  370. newBlock.type=-1
  371. newBlock.name="Wall"
  372. rednet.send(serverID,textutils.serialize(newBlock),"inputData")
  373. return
  374. else
  375. turtle.forward()
  376. while turtle.down() do
  377. sleep(0)
  378. end
  379. print("Hit rock bottom")
  380. local currX,currY,currZ=gps.locate()
  381. newBlock.minY=currY
  382. local exist,block=turtle.inspectDown()
  383. print("Checking block name")
  384. newBlock.name=block.name
  385. print("Block name:",newBlock.name)
  386.  
  387. if(string.find(newBlock.name,"sculk")) then
  388. newBlock.type=4
  389. elseif (string.find(newBlock.name,"carpet")) then
  390. newBlock.type=1
  391. else
  392. newBlock.type=3
  393. end
  394. print("Block Type:",newBlock.type)
  395. while turtle.up() do
  396. sleep(0)
  397. end
  398. print("Went Up!")
  399. local currX,currY,currZ=gps.locate()
  400. newBlock.maxY=currY
  401. rednet.send(serverID,textutils.serialize(newBlock),"inputData")
  402. return
  403. end
  404.  
  405. end
  406.  
  407.  
  408. function comms()
  409. while true do
  410. local event, sender, message, protocol = os.pullEvent("rednet_message")
  411. --print("Got message!")
  412. if protocol ~= nil then
  413. --print("Received message from " .. sender .. " with protocol " .. protocol .. " and message " .. tostring(message))
  414. if protocol == "backroomExplorer" then
  415. if textutils.unserialize(message)~=nil then
  416. dataBlock=textutils.unserialize(message)
  417. else
  418. dataBlock="Empty"
  419. end
  420. elseif protocol=="getNewAir" then
  421. local newCoord=textutils.unserialize(message)
  422. newExploreX=newCoord.x
  423. newExploreZ=newCoord.z
  424. end
  425.  
  426.  
  427. else
  428. --print("Received message from " .. sender .. " with message " .. tostring(message))
  429. end
  430. sleep(0)
  431. end
  432. end
  433.  
  434. main()
Advertisement
Add Comment
Please, Sign In to add comment