Alkerss

Nav

May 6th, 2014
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.94 KB | None | 0 0
  1. --------------------------------------------------------------------------------------------------------------------------------
  2. --[[------------ Descriptions of function calls --------------------------------------------------------------------------------
  3. Go( [ { x, z, y [,f] } ], [isRelative], [,style]).
  4. EXAMPLE: Lets say we are at coordinates X=2, Z=-3, Y=4 and if we want to go to X=0,Z=0,Y=0 then all the following will do.
  5. Nav.Go()
  6. Nav.Go({0,0,0})
  7. Nav.Go({0,0,0,1})
  8. Nav.Go({0,0,0},false,"Normal")
  9. Nav.Go({-2,3,-4},true,"Normal")
  10. pos = {x=0, z=0, y=0}; Nav.Go(pos)
  11. INPUT:
  12. table { num x, num z, num y [,num f]} : target position and face. If table is nil then default is current position and undefined face. Returns nil if X or Z or Y is nil. F are:
  13. 0: North/X+
  14. 1: East/Z+
  15. 2: South/X-
  16. 3: West/Z-
  17. else Undefined
  18. num isRelative : defines if coords are given in absolute or relative.
  19. Nil|false|0: Absolute
  20. true|1: Relative
  21. 2+: Relative to facing direction
  22. string style : defines different styles how to move around, mostly pathfinding function.
  23. Default: use "Normal"
  24. "Normal": combination of "Careful" and "DigCareful" - prefers not to dig but digs if very needed. Recommended for most purposes.
  25. "Careful": move carefully (recalculate path if block is in a way, doesn't destroy blocks), good for moving inside a base, but inefficient.
  26. "Dig": move and destroy blocks if one is in a way except if tagged "Use with caution, may destroy other turtles! Use "DigCareful"
  27. "DigCareful": like "Dig" but returns if there is a turtle in 2sq in front.
  28. "Explore": move carefully AND check sides if they are unexplored. Good for mapping, but slow.
  29. "SurfaceExplore": like "Exlore" but ignores Y coordinate and moves on surface, ignoring openings 3+sq deep and 1-2sq wide.
  30. else use Default
  31. OUTPUT:
  32. Returns true if succeeded, false if not.
  33. Nav.TurnRight()
  34. INPUT: nothing
  35. OUTPUT: nothing
  36. Nav.TurnLeft()
  37. INPUT: nothing
  38. OUTPUT: nothing
  39. Nav.TurnAround()
  40. INPUT: nothing
  41. OUTPUT: nothing
  42. Nav.GetPos([string switchXZYF])
  43. INPUT:
  44. string switchXZYF: any of the following values "x", "X", "z", "Z", "y", "Y", "f", "F"
  45. OUTPUT:
  46. Default: table {x, z, y, f}, where XZY is absolute coordinates and f is facing direction (0 to 3)
  47. if switchXZYF: num returnXZYF, a numeric value depending on input string
  48. --]]
  49. --------------------------------------------------------------------------------------------------------------------------------
  50. ---------------- Dependencies --------------------------------------------------------------------------------------------------
  51. -- Name Section:
  52. -- Declare the name library will use. Leave it alone and
  53. local Lib = {}
  54. Nav = Lib
  55.  
  56. -- Import Section:
  57. -- declare everything this library needs from outside
  58. -- FYI You can change or shorten names if you wish so.
  59.  
  60. ---- Luaj unmodified libraries. Import only needed sub-functions.
  61. -- Full list (functions): assert, collectgarbage, error, _G, ipairs, load, loadstring, next, pcall, rawequal, rawget, rawset, select, setfenv, setmetatable, tonumber, tostring, unpack, _VERSION, xpcall, require, module
  62. -- Full list (tables): coroutine, package, table, math
  63. -- local
  64. local os, select, table, math = os, select, table, math
  65.  
  66. ---- CC libraries. Import only needed sub-functions.
  67. -- Full list (modified Luaj functions): getfenv, getmetatable, loadfile, dofile, print, type, string.sub, string.find, write
  68. -- Full list (modified Luaj tables): string, os, io
  69. -- Full list (new tables): os, colors, disk, gps, help, keys, paintutils, parallel, peripheral, rednet, term, textutils, turtle, vector, window
  70. local type = type
  71. -- local
  72. local turtle = turtle
  73.  
  74. ---- TuCoWa libraries. Import only needed sub-functions.
  75. -- Full list: Gui, Rui, Hud, Logger, Stats, Comm, Utils, Nav, Jobs, Resm, Logic, Init
  76. local Gui, Rui, Hud, Logger, Stats, Comm, Utils = Gui, Rui, Hud, Logger, Stats, Comm, Utils
  77.  
  78. -- no more external access after this point
  79. setfenv(1, Lib)
  80.  
  81. --------------------------------------------------------------------------------------------------------------------------------
  82. ---------------- Library wide variables ----------------------------------------------------------------------------------------
  83.  
  84. local Pos = {} --
  85. Pos.x = 0 -- North
  86. Pos.z = 0 -- East
  87. Pos.y = 0 -- Height
  88. Pos.f = 0 -- Facing direction, modulus of 4 // 0,1,2,3 = North, East, South, West
  89. local Map = {} -- Id={nil=unexplored,false=air,0=RandomBlock,####=Block}, Updated=server's time, Tag={nil,true if tagged by special events}, Owner="".
  90. Map.InitTime = os.time()
  91. Map.UpdatedTime = os.time()
  92.  
  93. --------------------------------------------------------------------------------------------------------------------------------
  94. ---------------- Classes -------------------------------------------------------------------------------------------------------
  95.  
  96. -- none
  97.  
  98. --------------------------------------------------------------------------------------------------------------------------------
  99. ---------------- Functions ----------------------------------------------------------------------------------------------
  100.  
  101. -- Technical and independent functions
  102. local function PutMap (pos,name,value)
  103. -- local shout = os.difftime(os.time() - Map.UpdatedTime)
  104. Map.UpdatedTime = os.time()
  105.  
  106. if Map[GetPos(pos,"x")] == nil then Map[GetPos(pos,"x")]={} end
  107. if Map[GetPos(pos,"x")][GetPos(pos,"z")] == nil then Map[GetPos(pos,"x")][GetPos(pos,"z")]={} end
  108. if Map[GetPos(pos,"x")][GetPos(pos,"z")][GetPos(pos,"y")] == nil then Map[GetPos(pos,"x")][GetPos(pos,"z")][GetPos(pos,"y")]={} end
  109.  
  110. Map[GetPos(pos,"x")][GetPos(pos,"z")][GetPos(pos,"y")]["Updated"] = Map.UpdatedTime
  111. Map[GetPos(pos,"x")][GetPos(pos,"z")][GetPos(pos,"y")][name] = value
  112. return shout
  113. end
  114. local function UpdatePos (face)
  115. --Logger.Debug("Nav.UpdateCoord(%s)\n",face)
  116. Pos.x = GetPos(face,"x")
  117. Pos.z = GetPos(face,"z")
  118. Pos.y = GetPos(face,"y")
  119. end
  120. local function Test ()
  121. return 1
  122. end
  123. local function ComparePos (position1,position2)
  124. if type(position1) ~= "table" then return "Nav TABLE" end
  125. if type(position2) ~= "table" then return "Nav TABLE" end
  126. pos1 = {}
  127. pos2 = {}
  128. pos1.x = position1.x or position1[1]
  129. pos1.z = position1.z or position1[2]
  130. pos1.y = position1.y or position1[3]
  131. pos1.f = position1.f or position1[4]
  132. pos2.x = position2.x or position2[1]
  133. pos2.z = position2.z or position2[2]
  134. pos2.y = position2.y or position2[3]
  135. pos2.f = position2.f or position2[4]
  136. if pos1.x ~= pos2.x then return false end
  137. if pos1.z ~= pos2.z then return false end
  138. if pos1.y ~= pos2.y then return false end
  139. if pos1.f and pos2.f and pos1.f ~= pos2.f then return false end
  140. return true
  141. end
  142. function GetPos ( ... ) -- Input Position (table), FacingDirection (num) and returnSwitch (string) in any order
  143. local Face = nil
  144. local Switch = nil
  145. local P = {}
  146. local Arg = {}
  147. P.x = Pos.x
  148. P.z = Pos.z
  149. P.y = Pos.y
  150. P.f = Pos.f
  151.  
  152. for i=1,select('#',...) do
  153. Arg[i] = select(i,...)
  154. end
  155.  
  156. for i=1,3,1 do
  157. if type(Arg[i]) == "number" then Face = Arg[i]
  158. elseif type(Arg[i]) == "table" then
  159. P.x = Arg[i].x or Arg[i][1] or Pos.x or 0
  160. P.z = Arg[i].z or Arg[i][2] or Pos.z or 0
  161. P.y = Arg[i].y or Arg[i][3] or Pos.y or 0
  162. P.f = Arg[i].f or Arg[i][4] or Pos.f or 0
  163. elseif Arg[i] == "x" or Arg[i] == "X" then Switch = Arg[i]
  164. elseif Arg[i] == "z" or Arg[i] == "Z" then Switch = Arg[i]
  165. elseif Arg[i] == "y" or Arg[i] == "Y" then Switch = Arg[i]
  166. elseif Arg[i] == "f" or Arg[i] == "F" then Switch = Arg[i]
  167. end
  168. end
  169.  
  170. if Switch == nil or type(Switch) ~= "string" then
  171. if Face == nil then return {P.x, P.z, P.y}
  172. elseif Face == 0 then return {P.x+1, P.z, P.y}
  173. elseif Face == 1 then return {P.x, P.z+1, P.y}
  174. elseif Face == 2 then return {P.x-1, P.z, P.y}
  175. elseif Face == 3 then return {P.x, P.z-1, P.y}
  176. elseif Face == 4 then return {P.x, P.z, P.y+1}
  177. elseif Face == 5 then return {P.x, P.z, P.y-1}
  178. else return {P.x, P.z, P.y}
  179. end
  180. elseif Switch == "x" or Switch == "X" then
  181. if Face == nil then return P.x
  182. elseif Face == 0 then return P.x+1
  183. elseif Face == 1 then return P.x
  184. elseif Face == 2 then return P.x-1
  185. elseif Face == 3 then return P.x
  186. elseif Face == 4 then return P.x
  187. elseif Face == 5 then return P.x
  188. else return P.x
  189. end
  190. elseif Switch == "z" or Switch == "Z" then
  191. if Face == nil then return P.z
  192. elseif Face == 0 then return P.z
  193. elseif Face == 1 then return P.z+1
  194. elseif Face == 2 then return P.z
  195. elseif Face == 3 then return P.z-1
  196. elseif Face == 4 then return P.z
  197. elseif Face == 5 then return P.z
  198. else return P.z
  199. end
  200. elseif Switch == "y" or Switch == "Y" then
  201. if Face == nil then return P.y
  202. elseif Face == 0 then return P.y
  203. elseif Face == 1 then return P.y
  204. elseif Face == 2 then return P.y
  205. elseif Face == 3 then return P.y
  206. elseif Face == 4 then return P.y+1
  207. elseif Face == 5 then return P.y-1
  208. else return P.y
  209. end
  210. elseif Switch == "f" or Switch == "F" then
  211. if Face == nil then return P.f
  212. elseif Face == 0 then return Face
  213. elseif Face == 1 then return Face
  214. elseif Face == 2 then return Face
  215. elseif Face == 3 then return Face
  216. elseif Face == 4 then return P.f
  217. elseif Face == 5 then return P.f
  218. else return P.f
  219. end
  220. end
  221. return nil
  222. end
  223.  
  224. -- Technical and dependent functions, 1st level
  225. function GetMap (pos,name)
  226. --Logger.Debug("GetMap(%s,%s,%s)\n", x,z,y)
  227. if Map[GetPos(pos,"x")] == nil then Map[GetPos(pos,"x")]={} end
  228. if Map[GetPos(pos,"x")][GetPos(pos,"z")] == nil then Map[GetPos(pos,"x")][GetPos(pos,"z")]={} end
  229. if Map[GetPos(pos,"x")][GetPos(pos,"z")][GetPos(pos,"y")] == nil then Map[GetPos(pos,"x")][GetPos(pos,"z")][GetPos(pos,"y")]={} end
  230.  
  231. if name == nil then
  232. return Map[GetPos(pos,"x")][GetPos(pos,"z")][GetPos(pos,"y")]
  233. else
  234. return Map[GetPos(pos,"x")][GetPos(pos,"z")][GetPos(pos,"y")][name]
  235. end
  236. end
  237. function UpdateMap (location,value) -- location{nil|dir|XZY), value{false=air,0=unknown block,1+=known block}
  238. --Logger.Check("UpdateMap:%s,%s",location,value)
  239. if type(location) == "nil" or type(location) == "number" then
  240. if turtle.detect() then PutMap(GetPos(GetPos("f")),"Id",0) else PutMap(GetPos(GetPos("f")),"Id",false) end
  241. if turtle.detectUp() then PutMap(GetPos(4),"Id",0) else PutMap(GetPos(4),"Id",false) end
  242. if turtle.detectDown() then PutMap(GetPos(5),"Id",0) else PutMap(GetPos(5),"Id",false) end
  243. elseif type(location)=="table" then
  244. location.x = location.x or location[1]
  245. location.z = location.z or location[2]
  246. location.y = location.y or location[3]
  247. location.f = location.f or location[4]
  248. PutMap({location.x, location.x, location.y},"Id",value)
  249. end
  250. end
  251. local function GetPath (target,options) -- TODO: multiple targets!
  252. --[[ DISCLAIMER.
  253. This code (May 04, 2014) is written by Akuukis
  254. who based on code (Sep 21, 2006) by Altair
  255. who ported and upgraded code of LMelior
  256. --]]
  257. --[[ PRE.
  258. Map[][][] is a 3d infinite array (.Id, .Updated, .Evade)
  259. Pos.x is the player's current x or North
  260. Z is the player's current z or East
  261. Pos.y is the player's current y or Height (not yet implemented)
  262. target.x is the target x
  263. target.z is the target z
  264. target.y is the target y (not yet implemented)
  265. options is the preference (not yet implemented)
  266.  
  267. Note. all the x and z are the x and z to be used in the table.
  268. By this I mean, if the table is 3 by 2, the x can be 1,2,3 and the z can be 1 or 2.
  269. --]]
  270. --[[ POST.
  271. path is a list with all the x and y coords of the nodes of the path to the target.
  272. OR nil if closedlist==nil
  273. -- Intro to A* - http://www.raywenderlich.com/4946/introduction-to-a-pathfinding
  274. -- Try it out! - http://zerowidth.com/2013/05/05/jump-point-search-explained.html
  275. --]]
  276. if target.y == nil then target.y = GetPos("y") end
  277.  
  278. CalcHeuristic = function (pos1, pos2, options)
  279. -- Useful - http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html
  280. AverageCost = 1
  281. for i=1,table.maxn(options) do
  282. if options[i] == "Manhattan" or options[i] == 1 then
  283. dx = math.abs(GetPos(pos1,"x")-GetPos(pos2,"x"))
  284. dz = math.abs(GetPos(pos1,"z")-GetPos(pos2,"z"))
  285. dy = math.abs(GetPos(pos1,"y")-GetPos(pos2,"y"))
  286. return AverageCost * (dx + dz + dy)
  287. elseif options[i] == "ManhattanTieBreaker" or options[i] == 2 then
  288. dx = math.abs(GetPos(pos1,"x")-GetPos(pos2,"x"))
  289. dz = math.abs(GetPos(pos1,"z")-GetPos(pos2,"z"))
  290. dy = math.abs(GetPos(pos1,"y")-GetPos(pos2,"y"))
  291. return AverageCost * (dx + dz + dy) * (1 + 1/1000)
  292. end
  293. end
  294. dx = math.abs(GetPos(pos1,"x")-GetPos(pos2,"x")) --Default
  295. dz = math.abs(GetPos(pos1,"z")-GetPos(pos2,"z"))
  296. dy = math.abs(GetPos(pos1,"y")-GetPos(pos2,"y"))
  297. return AverageCost * (dx + dz + dy) * (1 + 1/1000)
  298. end
  299.  
  300. -- Logger.Debug("Nav.GetPath(%s,%s,%s)\n",target.x,target.z,target.y)
  301.  
  302. local closedlist = {} -- Initialize table to store checked gridsquares
  303. local openlist = {} -- Initialize table to store possible moves
  304. openlist[1] = {} -- Make starting point in list
  305. openlist[1].x = GetPos("x")
  306. openlist[1].z = GetPos("z")
  307. openlist[1].y = GetPos("y")
  308. openlist[1].DistExactStart = 0
  309. openlist[1].DistHeuristicTarget = CalcHeuristic(GetPos(),target,options)
  310. openlist[1].DistSum = openlist[1].DistExactStart + openlist[1].DistHeuristicTarget
  311. openlist[1].parent = 1
  312. local openk = 1 -- Openlist counter
  313. local closedk = 0 -- Closedlist counter
  314. local DefaultWeight = 3 -- TODO!
  315. -- Logger.Check("Openlist.x|y|z=%s,%s,%s\n",openlist[1].x,openlist[1].z,openlist[1].y)
  316. -- Logger.Debug("Nav.GetPath() CurbaseXZ. %s",options[1])
  317.  
  318. while openk > 0 and table.maxn(closedlist)<256 do -- Growing loop
  319.  
  320. for i=1,table.maxn(options) do
  321. if options[i] == "Careful" and GetMap(target,"Id") and GetMap(target,"Id") > 0 then return nil end -- return nil if target is not accessable
  322. end
  323.  
  324. local lowestDS = openlist[openk].DistSum -- Get the lowest f of the openlist
  325. local basis = openk
  326. for i = openk,1,-1 do -- Prefer newer nodes
  327. if openlist[i].DistSum < lowestDS then
  328. lowestDS = openlist[i].DistSum
  329. basis = i
  330. end
  331. end
  332. closedk = closedk + 1
  333. closedlist[closedk] = openlist[basis]
  334. local curbase = closedlist[closedk] -- define current base from which to grow list
  335. -- Logger.Check("Openlist.x|y|z=%s,%s,%s\n",openlist[1].x,openlist[1].z,openlist[1].y)
  336. -- Logger.Debug("\n%s/%s:(%s,%s,%s)(%s,%s,%s|%s)F:", closedk, openk, curbase.x, curbase.z, curbase.y, math.floor(curbase.DistExactStart), math.floor(curbase.DistHeuristicTarget), math.floor(curbase.DistSum), curbase.parent)
  337. table.remove(openlist,basis) -- This function deletes an element of a numerical table and moves up the remaining indices if necessary.
  338. openk = openk - 1
  339.  
  340. local OK = {}
  341. for face=0,5 do OK[face] = 1 end
  342.  
  343. for i=1,table.maxn(options) do
  344. if options[i] == "Normal" then -- If it IS on the map, check map for obstacles
  345. for face=0,5 do
  346. --Logger.Debug("%s",GetMap(GetPos(curbase,face),"Id"))
  347. if GetMap(GetPos(curbase,face),"Id") then OK[face] = DefaultWeight end end
  348. elseif options[i] == "Careful" then
  349. for face=0,5 do if GetMap(GetPos(curbase,face),"Id") then OK[face] = false end end
  350. end
  351. end
  352.  
  353. for face=0,5 do if GetMap(GetPos(curbase,face),"Tag") == true then OK[face] = false end end -- Look through Tagged
  354.  
  355. if closedk>0 then -- Look through closedlist
  356. for i=1,closedk do
  357. for face=0,5 do
  358. if ComparePos(GetPos(closedlist[i]),GetPos(curbase,face)) then OK[face] = false end
  359. end
  360. end
  361. end
  362.  
  363. for i=1,openk do -- check if the move from the current base is shorter than from the former parent
  364. for face=0,5 do
  365. if OK[face] and openlist[i].DistExactStart > curbase.DistExactStart + OK[face] and ComparePos(GetPos(openlist[i]),GetPos(curbase,face)) then
  366. --tempDTT = math.abs((curbase.x+1)-target.x)+math.abs(curbase.z-target.z)
  367. openlist[i].DistExactStart = curbase.DistExactStart + OK[face]
  368. openlist[i].DistSum = openlist[i].DistHeuristicTarget + openlist[i].DistExactStart
  369. openlist[i].parent = closedk
  370. NorthOK=false
  371. end
  372. end
  373. end
  374.  
  375. -- for face=0,5 do Logger.Debug("%s",OK[face]) end
  376.  
  377. for face=0,5 do -- Add points to openlist
  378. if OK[face] then
  379. openk = openk + 1
  380. openlist[openk] = {}
  381. openlist[openk].x = GetPos(curbase,face,"x")
  382. openlist[openk].z = GetPos(curbase,face,"z")
  383. openlist[openk].y = GetPos(curbase,face,"y")
  384. openlist[openk].DistExactStart = curbase.DistExactStart + OK[face]
  385. openlist[openk].DistHeuristicTarget = CalcHeuristic(GetPos(curbase,face),target,options)
  386. openlist[openk].DistSum = openlist[openk].DistExactStart + openlist[openk].DistHeuristicTarget
  387. openlist[openk].parent = closedk
  388. --Logger.Debug("F:%s:",face)
  389. --for n in pairs(openlist[openk]) do Logger.Debug("%s:%s,",n,openlist[openk][n]) end
  390. --Logger.Check("\n")
  391. end
  392. end
  393.  
  394. --Logger.Check("")
  395.  
  396. if ComparePos(closedlist[closedk],target) then
  397. --Logger.Debug("\n")
  398. --Logger.Debug("Nav.GetPath() Found the path! Openlist: %s, Closedlist: %s, Steps: ", openk, closedk)
  399. -- Change Closed list into a list of XZ coordinates starting with player
  400. local path = {}
  401. local last = closedk
  402. local pathIndex = {}
  403. pathIndex[1] = closedk
  404. local i = 1 -- we will include starting position into a table, otherwise 1
  405. while pathIndex[i] > 1 do
  406. i = i + 1
  407. pathIndex[i] = closedlist[pathIndex[i-1]].parent
  408. end
  409. --Logger.Debug("%s\n", i)
  410. --Logger.Debug("Nav.GetPath() Path. ")
  411. for i=1,table.maxn(pathIndex),1 do
  412. path[i] = {}
  413. path[i].x = closedlist[pathIndex[table.maxn(pathIndex)+1-i]].x
  414. path[i].z = closedlist[pathIndex[table.maxn(pathIndex)+1-i]].z
  415. path[i].y = closedlist[pathIndex[table.maxn(pathIndex)+1-i]].y
  416. --Logger.Debug("%s|%s|%s, ", path[i].x,path[i].z,path[i].y)
  417. end
  418.  
  419. --for i=1,table.maxn(pathIndex) do
  420. -- Logger.Debug("%s(%s,%s,%s)", i, path[i].x, path[i].z, path[i].y)
  421. --end
  422.  
  423. closedlist=nil
  424.  
  425. -- Change list of XZ coordinates into a list of directions
  426. --Logger.Debug("\n")
  427. Logger.Debug("Nav.GetPath() FPath. ")
  428. local fpath = {}
  429. for i=1,table.maxn(path)-1,1 do
  430. if path[i+1].x > path[i].x then fpath[i]=0 end -- North
  431. if path[i+1].z > path[i].z then fpath[i]=1 end -- East
  432. if path[i+1].x < path[i].x then fpath[i]=2 end -- South
  433. if path[i+1].z < path[i].z then fpath[i]=3 end -- West
  434. if path[i+1].y > path[i].y then fpath[i]=4 end -- Up
  435. if path[i+1].y < path[i].y then fpath[i]=5 end -- Down
  436. Logger.Debug("%s, ", fpath[i])
  437. end
  438. Logger.Debug("\n")
  439. return fpath
  440. end
  441. end
  442. return nil
  443. end
  444. local function Move (face, options) -- face={0=North|1=East|2=South|3=West|4=up|5=down}, returns true if succeeded
  445. options[1] = options[1] or "Normal" -- Usually "Normal" because Nav.Go will default on "Normal".
  446. local success = false
  447. local Id = GetMap(GetPos(face),"Id")
  448. --Logger.Debug("Nav.Move(%s,%s,%s)\n", face.f, face.id, options)
  449. Utils.Refuel()
  450. if face==4 then -- Up
  451. success = turtle.up()
  452. elseif face==5 then -- Down
  453. success = turtle.down()
  454. elseif face==GetPos("f")-1 or face==GetPos("f")+3 then -- Left
  455. TurnLeft()
  456. success = turtle.forward()
  457. elseif face==GetPos("f")-2 or face==GetPos("f")+2 then -- Right
  458. TurnAround()
  459. success = turtle.forward()
  460. elseif face==GetPos("f")-3 or face==GetPos("f")+1 then -- 180
  461. TurnRight()
  462. success = turtle.forward()
  463. else -- Forward
  464. success = turtle.forward()
  465. end
  466. if success then
  467. UpdatePos(face)
  468. UpdateMap(face)
  469. --Logger.Debug("Nav.Move() Return true\n")
  470. return true
  471. else
  472. Recalc = true
  473. if not Id and not GetMap(GetPos(face),"Id") then Recalc = false end
  474. if Id and GetMap(GetPos(face),"Id") and Id == GetMap(GetPos(face),"Id") then Recalc = false end
  475. -- Logger.Debug("%s,%s",not GetMap(GetPos(face),"Tag"),Recalc)
  476. for i=1,table.maxn(options) do
  477. if not Recalc and not GetMap(GetPos(face),"Tag") and options[i] == "Normal" then
  478. --Logger.Check("TRUE")
  479. if face == 4 then turtle.digUp(); success = turtle.up()
  480. elseif face == 5 then success = turtle.digDown(); turtle.down()
  481. else turtle.dig(); success = turtle.forward()
  482. end
  483. if success then
  484. UpdatePos(face)
  485. UpdateMap(face)
  486. return true
  487. end
  488. else
  489. UpdateMap()
  490. --Logger.Debug("Nav.Move() Return false\n")
  491. return false
  492. end
  493. end
  494. end
  495. end
  496.  
  497. -- Core functions
  498. function TurnRight ()
  499. turtle.turnRight()
  500. Logger.Debug("Nav.TurnRight() Nav.Pos.f. %s => ",GetPos("f"))
  501. Pos.f = (GetPos("f")+1)%4
  502. Logger.Debug("%s\n",GetPos("f"))
  503. UpdateMap()
  504. end
  505. function TurnLeft ()
  506. turtle.turnLeft()
  507. Logger.Debug("Nav.TurnLeft() Nav.Pos.f. %s => ",GetPos("f"))
  508. Pos.f = (GetPos("f")+3)%4
  509. Logger.Debug("%s\n",GetPos("f"))
  510. UpdateMap()
  511. end
  512. function Go ( ... ) -- table position, num isRelative, text option1 [, text option2 ...]
  513.  
  514. local target = {}
  515. local options = {}
  516. local isRelative = false
  517.  
  518. for i=1,select('#',...) do
  519. local temp = select(i,...)
  520. if type(temp) == "table" then target = temp end
  521. if type(temp) == "boolean" then if temp == true then isRelative = 1 else isRelative = 0 end end
  522. if type(temp) == "number" then isRelative = temp end
  523. if type(temp) == "text" then options[table.maxn(options)+1] = temp end
  524. end
  525.  
  526. target.x = target.x or target[1] or 0
  527. target.z = target.z or target[2] or 0
  528. target.y = target.y or target[3] or 0
  529. target.f = target.f or target[4] or GetPos("f")
  530.  
  531. if isRelative and isRelative > 0 then
  532. if isRelative > 1 then
  533. if GetPos("f") == 0 then target.x = GetPos("x") + target.x; target.z = GetPos("z") + target.z end
  534. if GetPos("f") == 1 then target.x = GetPos("x") - target.z; target.z = GetPos("z") + target.x end
  535. if GetPos("f") == 2 then target.x = GetPos("x") - target.x; target.z = GetPos("z") - target.z end
  536. if GetPos("f") == 3 then target.x = GetPos("x") + target.z; target.z = GetPos("z") - target.x end
  537. else
  538. target.x = target.x + GetPos("x")
  539. target.z = target.z + GetPos("z")
  540. end
  541. end
  542.  
  543. for i=1,table.maxn(options) do
  544. if options[i] == "Normal" or options[i] == "normal" then options[i] = "Normal"
  545. elseif options[i] == "Careful" or options[i] == "careful" then options[i] = "Careful"
  546. elseif options[i] == "Dig" or options[i] == "dig" then return "Error: Style " .. options[i] .. " not implemented yet."
  547. elseif options[i] == "DigCareful" or options[i] == "Digcareful" or options[i] == "digcareful" then return "Error: Style " .. options[i] .. " not implemented yet."
  548. elseif options[i] == "Explore" or options[i] == "explore" then return "Error: Style " .. options[i] .. " not implemented yet."
  549. elseif options[i] == "SurfaceExplore" or options[i] == "Surfaceexplore" or options[i] == "surfaceexplore" then return "Error: Style " .. options[i] .. " not implemented yet."
  550. else options[i] = "Normal"
  551. end
  552. end
  553.  
  554.  
  555. local tries=32 -- TODO
  556. Logger.Debug("Nav.Go(%s,%s,%s) Style: %s\n", target.x, target.z, target.y, options[1])
  557. repeat
  558. if ComparePos(GetPos(),target) then return true else tries = tries - 1 end
  559. -- Logger.Debug("Nav.Go() @ (%s,%s,%s,F%s)/%s\n",GetPos("x"),GetPos("z"),GetPos("y"),GetPos("f"),tries)
  560. local fpath = GetPath(target,options)
  561. if fpath == nil then
  562. -- Logger.Debug("Nav.Go() FPath=nil!")
  563. UpdateMap()
  564. TurnRight()
  565. else
  566. i = 1
  567. success = false
  568. while i <= table.maxn(fpath) and not success do
  569. -- Logger.Debug("%s",i)
  570. -- Logger.Debug("@(%s,%s,%s),(%s,%s) Moving %s/%s ...\n", GetPos("x"),GetPos("z"),GetPos("y"),not fpath[i],not GetMap(GetPos(fpath[i]),"Id"),i,table.maxn(fpath))
  571. success = not Move(fpath[i], options)
  572. i = i + 1
  573. end
  574. end
  575. until tries < 0
  576. -- Logger.Debug("Nav.Go() Out-of-UNTIL! /%s",tries)
  577. return false
  578. end
  579.  
  580. -- Shortcut functions
  581. function TurnAround ()
  582. if 1==math.random(0,1) then
  583. TurnRight()
  584. TurnRight()
  585. else
  586. TurnLeft()
  587. TurnLeft()
  588. end
  589. end
  590. function Step(...)
  591. return Move(GetPos("f"),{...})
  592. end
  593. function StepUp(...)
  594. return Move(4,{...})
  595. end
  596. function StepDown(...)
  597. return Move(5,{...})
  598. end
  599. function GetDistance (target, ...) -- Gets distance between your position and a target with given options
  600. local options = {}
  601. for i=1,select('#',...) do
  602. local temp = select(i,...)
  603. if type(temp) == "text" then options[table.maxn(options)+1] = temp end
  604. end
  605. return table.maxn( GetPath(target,options) )
  606. end
  607. function GoNextTo ( ... )
  608. -- WiP
  609. end
  610.  
  611. --------------------------------------------------------------------------------------------------------------------------------
  612. ---------------- Details & Notes -----------------------------------------------------------------------------------------------
  613.  
  614. --[[ Tutorials
  615. General: http://www.lua.org/pil/contents.html
  616. Varargs: http://lua-users.org/wiki/VarargTheSecondClassCitizen
  617. Nav.ComparePos({1,2,3},{1,2,3})
  618. --]]
Advertisement
Add Comment
Please, Sign In to add comment