Guest User

Untitled

a guest
Jul 22nd, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.78 KB | None | 0 0
  1. Node = {x=0,y=0,z=0,g=0,h=0,f=0,pid="",ID=0,active=true,
  2.  
  3. setActive = function(self,state)
  4. self.active = state
  5. end,
  6.  
  7. isActive = function(self)
  8. return self.active
  9. end,
  10.  
  11. getPos = function(self)
  12. return self.x,self.y,self.z
  13. end,
  14.  
  15. setPos = function(self,xs,ys,zs)
  16. self.x,self.y,self.z = xs,ys,zs
  17. end,
  18.  
  19. getID = function(self)
  20. return self.ID
  21. end,
  22.  
  23. setID = function(self,id)
  24. self.ID = id
  25. end,
  26.  
  27. getPid = function(self)
  28. return self.pid
  29. end,
  30.  
  31. setPid = function(self,id)
  32. self.pid = id
  33. end,
  34.  
  35. getPosString = function(self)
  36. return self.x..","..self.y..","..self.z
  37. end}
  38.  
  39. function Node:new(xs,ys,zs,xe,ye,ze,id,pid,s,penalty,o)
  40. if not penalty then penalty = 0 end
  41. o = o or {}
  42. setmetatable(o, self)
  43. self.__index = self
  44. if not s then o.g = nodes[pid].g + 10
  45. o.pid = nodes[pid]:getPid()..pid.."," end
  46. o.h = (math.abs(xs-xe)+math.abs(ys-ye)+math.abs(zs-ze)-1)*10+penalty
  47. o.f = o.h + o.g
  48. o.x,o.y,o.z = xs,ys,zs
  49. o.ID = id
  50. nodes[id] = o
  51. nodeF[id] = o.f
  52. return o
  53. end
  54.  
  55. function pathfindDijkstra(xe,ye,ze)
  56. local xs,ys,zs = getPos()
  57. if xe == xs and ye == ys and ze == zs then return true end
  58. if getBlock(xe,ye,ze,true) ~= 0 then print("You can only pathfind to air.") return false end
  59. local count,solutionID = 1,0
  60. local done = false
  61. local vertices = {}
  62. local cooldown = 0
  63. local takenPos = {xs..","..ys..","..zs}
  64. local q = 0
  65. vertices[1] = Vertex:new()
  66. vertices[1]:setID(1)
  67. vertices[1]:setPos(xs,ys,zs)
  68. while not done do
  69. for i=1,#vertices,1 do
  70. if vertices[i]:isActive() then
  71. for ii=0,5,1 do
  72. cooldown = cooldown + 1
  73. if cooldown >= 50 then sleep(0) cooldown = 0 end
  74. count = count + 1
  75. vertices[count] = Vertex:new()
  76. vertices[count]:setID(count)
  77. xs,ys,zs = vertices[i]:getPos()
  78. vertices[count]:setPos(getCoordsInDir(xs,ys,zs,ii))
  79. for q=1,#takenPos,1 do
  80. if vertices[count]:getPosString() == takenPos[q] then
  81. vertices[count]:setActive(false)
  82. end
  83. end
  84. table.insert(takenPos,#takenPos+1,vertices[count]:getPosString())
  85. if getBlock(vertices[count]:getPos()) ~= 0 then
  86. vertices[count]:setActive(false)
  87. elseif vertices[count]:isActive() then
  88. for iii=1,#vertices[i]:getPath(),1 do
  89. vertices[count]:addPath(vertices[i]:getPath()[iii])
  90. end
  91. vertices[count]:addPath(vertices[count]:getPosString())
  92. end
  93. end
  94. vertices[i]:setActive(false)
  95. end
  96. end
  97. for i=1,#vertices,1 do
  98. if vertices[i]:getPosString() == xe..","..ye..","..ze then
  99. solutionID = vertices[i]:getID()
  100. done = true
  101. break
  102. end
  103. end
  104. end
  105. for k,v in ipairs(vertices[solutionID]:getPath()) do
  106. q = getSeperated(v..",|")
  107. xs,ys,zs = q[1],q[2],q[3]
  108. if not goToCoordsPath(xs,ys,zs) then return false end
  109. end
  110. return done
  111. end
  112.  
  113. function exploreTypeSel(xq,yq,zq,xw,yw,zw,goback,mode)
  114. print("Warning: exploreTypeSel() is in beta testing, expect an occasional bug.")
  115. mapSidesType()
  116. if goback == nil then goback = true end
  117. if mode == nil then mode = true end
  118. local xs,ys,zs = getPos()
  119. local q,w
  120. local xe,ye,ze
  121. local a
  122. local done = false
  123. local loops = 1
  124. q = getCubeSel(xq,yq,zq,xw,yw,zw,126)
  125. local tmp = #q
  126. if #q == 0 then exploreProgress(1,1,4) return true end
  127. for i=1,2,1 do
  128. while not done do
  129. w = getSeperated(q[loops]..",|")
  130. xe,ye,ze = w[1],w[2],w[3]
  131. a = getBlockTypeDirection(air,getBorderingBlocks(xe,ye,ze))
  132. if a and a ~= 6 then
  133. t1,t2,t3 = getCoordsInDir(xe,ye,ze,a)
  134. pathfind(t1,t2,t3,10)
  135. mapSidesType()
  136. q = getCubeSel(xq,yq,zq,xw,yw,zw,126,i)
  137. tmp = #q
  138. end
  139. loops = loops + 1
  140. if loops > tmp then done = true end
  141. if mode and not done then
  142. if i == 0 then
  143. exploreProgress(loops,tmp,i)
  144. else
  145. exploreProgress(loops,tmp,i)
  146. end
  147. end
  148. end
  149. done = false
  150. q = getCubeSel(xq,yq,zq,xw,yw,zw,126)
  151. tmp = #q
  152. loops = 1
  153. end
  154. while not done do --Safety loop, gets any missed spots at the cost of being slower. That's why we did a fast loop before, to clear out most of the unmapped blocks
  155. w = getSeperated(q[loops]..",|")
  156. xe,ye,ze = w[1],w[2],w[3]
  157. a = getBlockTypeDirection(air,getBorderingBlocks(xe,ye,ze))
  158. if a and a ~= 6 then
  159. t1,t2,t3 = getCoordsInDir(xe,ye,ze,a)
  160. pathfind(t1,t2,t3,10)
  161. mapSidesType()
  162. end
  163. loops = loops + 1
  164. if loops > tmp then done = true end
  165. if mode and not done then
  166. exploreProgress(loops,tmp,3)
  167. end
  168. end
  169. exploreProgress(loops-1,tmp,4)
  170. if goback then pathfind(xs,ys,zs) end
  171. return done
  172. end
  173.  
  174. function exploreSel(xq,yq,zq,xw,yw,zw,goback,mode)
  175. print("Warning: exploreSel() is in beta testing, expect an occasional bug.")
  176. mapSides()
  177. if goback == nil then goback = true end
  178. if mode == nil then mode = true end
  179. local xs,ys,zs = getPos()
  180. local q,w
  181. local xe,ye,ze
  182. local t1,t2,t3
  183. local a
  184. local done = false
  185. local loops = 1
  186. q = getCubeSel(xq,yq,zq,xw,yw,zw,126)
  187. local tmp = #q
  188. if #q == 0 then exploreProgress(1,1,4) return true end
  189. for i=1,2,1 do
  190. while not done do
  191. w = getSeperated(q[loops]..",|")
  192. xe,ye,ze = w[1],w[2],w[3]
  193. a = getBlockTypeDirection(air,getBorderingBlocks(xe,ye,ze))
  194. if a and a ~= 6 then
  195. t1,t2,t3 = getCoordsInDir(xe,ye,ze,a)
  196. pathfind(t1,t2,t3,10)
  197. mapSides()
  198. q = getCubeSel(xq,yq,zq,xw,yw,zw,126,i)
  199. tmp = #q
  200. end
  201. loops = loops + 1
  202. if loops > tmp then done = true end
  203. if mode and not done then
  204. if i == 0 then
  205. exploreProgress(loops,tmp,i)
  206. else
  207. exploreProgress(loops,tmp,i)
  208. end
  209. end
  210. end
  211. done = false
  212. q = getCubeSel(xq,yq,zq,xw,yw,zw,126)
  213. tmp = #q
  214. loops = 1
  215. end
  216. while not done do --Safety loop, gets any missed spots at the cost of being slower. That's why we did a fast loop before, to clear out most of the unmapped blocks
  217. w = getSeperated(q[loops]..",|")
  218. xe,ye,ze = w[1],w[2],w[3]
  219. a = getBlockTypeDirection(air,getBorderingBlocks(xe,ye,ze))
  220. if a and a ~= 6 then
  221. t1,t2,t3 = getCoordsInDir(xe,ye,ze,a)
  222. pathfind(t1,t2,t3,10)
  223. mapSides()
  224. end
  225. loops = loops + 1
  226. if loops > tmp then done = true end
  227. if mode and not done then
  228. exploreProgress(loops,tmp,3)
  229. end
  230. end
  231. exploreProgress(loops-1,tmp,4)
  232. if goback then pathfind(xs,ys,zs) end
  233. return done
  234. end
  235.  
  236. function pathfind(xe,ye,ze,tc,up,s,t)
  237. local ue
  238. if not tc then ue = false else ue = true end
  239. if not tc then tc = 10 else tc = math.abs(tc) end
  240. if not up then up = false end
  241. if not s then s = 0 end
  242. if not t then t = false else t = true end
  243. local xs,ys,zs = getPos()
  244. local waypoints = getWaypoints(xs,ys,zs,xe,ye,ze,ue,up)
  245. local tmp,done,breaking
  246. local tries = 0
  247. local prev = waypoints
  248. local cooldown = 0
  249. while not done do
  250. tries = tries + 1
  251. tmp = 0
  252. for i=1,min(#prev,#waypoints),1 do
  253. if prev[i]:getPos() ~= waypoints[i]:getPos() then breaking = i end
  254. end
  255. if not breaking then breaking = -1 end
  256. if breaking > -1 then pathfind(waypoints[breaking - 1]:getPos()) end
  257. for k,v in pairs(waypoints) do
  258. cooldown = cooldown + 1 if cooldown >= 100 then cooldown = 0 sleep(0) end
  259. if (k >= breaking or breaking == -1) and not goToCoordsPath(v:getPos()) and k ~= 1 then
  260. tmp = -1
  261. done = false
  262. break
  263. end
  264. end
  265. prev = waypoints
  266. if tmp ~= -1 then
  267. goToCoordsPath(xe,ye,ze)
  268. done = true
  269. else
  270. if s < 1 then
  271. if t then mapSidesType() else mapSides() end
  272. if tries >= tc then tries = 0 xs,ys,zs = getPos() end
  273. waypoints = getWaypoints(xs,ys,zs,xe,ye,ze,ue,up)
  274. else
  275. explore(s)
  276. if tries >= tc then tries = 0 xs,ys,zs = getPos() end
  277. waypoints = getWaypoints(xs,ys,zs,xe,ye,ze,ue,up)
  278. end
  279. end
  280. end
  281. return true
  282. end
  283.  
  284. function getWaypoints(xs,ys,zs,xe,ye,ze,ue,up)
  285. local returnpack = {}
  286. local done = false
  287. local xp,yp,zp = xs,ys,zs
  288. local penalty = 0
  289. if xs == xe and ys == ye and zs == ze then return {xs..","..ys..","..zs} end
  290. local open = {}
  291. nodes = {} nodeF = {}
  292. local closest = nil
  293. if s and getBlock(xe,ye,ze) == 126 then
  294. closest = getClosest(xe,ye,ze,5,air)
  295. if #closest ~= 0 then
  296. local w = getSeperated(closest[1]..",|")
  297. pathfind(w[1],w[2],w[3])
  298. end
  299. end
  300. local tmp,temp
  301. local cooldown = 0
  302. open[1] = Node:new(xs,ys,zs,xe,ye,ze,1,false,true)
  303. table.sort(nodeF)
  304. table.sort(open, function(a,b) return a.f<b.f end)
  305. while not done do
  306. for ii=0,5,1 do
  307. tmp = nil
  308. temp = false
  309. cooldown = cooldown + 1 if cooldown > 50 then sleep(0) cooldown = 0 end
  310. xs,ys,zs = open[1]:getPos()
  311. if (getBlockInDir(xs,ys,zs,ii) == 0 or (ue and getBlockInDir(xs,ys,zs,ii) == 126)) and temp ~= true then
  312. if getBlockInDir(xs,ys,zs,ii) == 126 then penalty = up end
  313. xs,ys,zs = getCoordsInDir(xs,ys,zs,ii)
  314. for iii=1,#open,1 do if open[iii]:getPosString() == xs..","..ys..","..zs then tmp = true temp = open[iii] end end
  315. if not tmp then
  316. open[#open+1] = Node:new(xs,ys,zs,xe,ye,ze,#nodes+1,open[1].ID,false,penalty)
  317. if open[#open]:getPosString() == xe..","..ye..","..ze then done = open[#open] end
  318. elseif open[1].g > temp.g + 10 then
  319. open[1].pid = temp.pid
  320. tmp = getSeperated(open[1].pid..",|")
  321. open[1].g = nodes[tmp[#tmp]].g + 10
  322. open[1].f = open[1].g + open[1].h
  323. nodeF[open[1].ID] = open[1].f
  324. table.sort(nodeF)
  325. table.sort(open, function(a,b) return a.f<b.f end)
  326. end
  327. end
  328. penalty = 0
  329. end
  330. if temp == true then xs,ys,zs = xp,yp,zp open[1] = Node:new(xp,yp,zp,xe,ye,ze,1,false,true) break end
  331. nodeF[open[1].ID] = math.huge
  332. table.remove(open,1)
  333. table.sort(nodeF)
  334. table.sort(open, function(a,b) return a.f<b.f end)
  335. if #open == 0 then done = false end
  336. end
  337. table.sort(nodeF)
  338. table.sort(open, function(a,b) return a.f<b.f end)
  339. if done then
  340. tmp = getSeperated(done.pid.."|")
  341. for i=1,#tmp,1 do
  342. table.insert(returnpack,nodes[tmp[i]])
  343. end
  344. nodes = {} nodeF = {}
  345. return returnpack
  346. else nodes = {} nodeF = {} return {} end
  347. end
Add Comment
Please, Sign In to add comment