Krutoy Turtle wrapper

Jun 9th, 2014
224
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. -- ********************************************************************************** --
2. -- **                                                                              ** --
3. -- **   Krutoy Turtle Wrapper                                                      ** --
4. -- **   ----------------------------------------------------                       ** --
5. -- **                                                                              ** --
6. -- **   Wrap standart turtle functions but monitoring position and orientation     ** --
7. -- **   To get turtle pos and orient use Turtle.pos and Turtle.orient              ** --
8. -- **                                                                              ** --
9. -- **   ----------------------------------------------------                       ** --
10. -- **   Most of code was used from "OreQuarry" from AustinKK                       ** --
11. -- **                                                                              ** --
12. -- ********************************************************************************** --
13.
14. -- Enumeration to store names for the 6 directions
15. local way = { FORWARD=0, RIGHT=1, BACK=2, LEFT=3, UP=4, DOWN=5 }
16. local lastMoveNeededDig
17. local maximumGravelStackSupported = 26
18.
19. -- Global Turtle variable
20. Turtle = {}
21. Turtle.__index = Turtle
22.
23. -- Variables to store the current location and orientation of the turtle. x is right, left, z is up, down and
24. -- y is forward, back with relation to the starting orientation.
25. Turtle.orient = way.FORWARD
26.
27. Turtle.pos = vector.new() -- Start Pos is 0,0,0
28.
29. local surround = {
30. [way.FORWARD] = vector.new( 0, 1, 0),
31. [way.RIGHT]   = vector.new( 1, 0, 0),
32. [way.BACK]    = vector.new( 0,-1, 0),
33. [way.LEFT]    = vector.new(-1, 0, 0),
34. [way.UP]      = vector.new( 0, 0, 1),
35. [way.DOWN]    = vector.new( 0, 0,-1)
36. }
37.
38.
39. -- ********************************************************************************** --
40. -- Sets the turtle to a specific orientation, irrespective of its current orientation
41. -- ********************************************************************************** --
42. function Turtle.setOrient(newOrient)
43.
45.   if (Turtle.orient == newOrient) then return true end
46.
47.
48.   -- Wrong parameters - we cant turn up or down
49.   if newOrient < 0 or newOrient > way.LEFT then
50.     error("Invalid newOrient in Turtle.setOrient function")
51.     return false
52.   end
53.
54.   local turn = Turtle.orient - newOrient
55.   local turnFnc
56.
57.   if turn==1 or turn==-3 then
58.     turnFnc = turtle.turnLeft
59.   else
60.     turnFnc = turtle.turnRight
61.   end
62.
63.   turn = math.abs(turn)
64.   if(turn==3) then turn=1 end
65.
66.   Turtle.orient = newOrient
67.
68.
69.   for i=1, turn do
70.     turnFnc()
71.   end
72.
73.   return true
74. end
75.
76. --===========================================================
77. -- Dig, depending on direction
78. --===========================================================
79. function Turtle.dig(direction)
80.   direction = direction or way.FORWARD -- Optional param
81.
82.   if(direction ~= way.DOWN and direction ~= way.UP and direction ~= way.FORWARD) then
83.     error('Wrong params in Turtle.dig()')
84.     return false
85.   end
86.
87.   local digFnc = {[way.FORWARD]=turtle.dig, [way.DOWN]=turtle.digDown, [way.UP]=turtle.digUp}
88.
89.   return digFnc[direction]()
90. end
91.
92. -- ********************************************************************************** --
93. -- Generic function to move the Turtle (pushing through any gravel or other
94. -- things such as mobs that might get in the way).
95. --
96. -- The only thing that should stop the turtle moving is bedrock. Where this is
97. -- found, the function will return after 15 seconds returning false
98. -- ********************************************************************************** --
99. function Turtle.move(moveFn, detectFn, digFn, attackFn, compareFn, suckFn, maxDigCount, newX, newY, newZ)
100.
101.   local moveSuccess = false
102.
103.
104.   -- Flag to determine whether digging has been tried yet. If it has
105.   -- then pause briefly before digging again to allow sand or gravel to drop
106.   local digCount = 0
107.
108.   if (lastMoveNeededDig == false) then
109.     -- Didn't need to dig last time the turtle moved, so try moving first
110.
111.     moveSuccess = moveFn()
112.
113.     if (moveSuccess == true) then
114.       Turtle.pos.x = newX
115.       Turtle.pos.y = newY
116.       Turtle.pos.z = newZ
117.     end
118.   else
119.     -- Try to dig (without doing a detect as it is quicker)
120.     local digSuccess = digFn()
121.     if (digSuccess == true) then
122.       digCount = 1
123.     end
124.
125.     moveSuccess = moveFn()
126.
127.     if (moveSuccess == true) then
128.       lastMoveNeededDig = digSuccess
129.       Turtle.pos.x = newX
130.       Turtle.pos.y = newY
131.       Turtle.pos.z = newZ
132.     end
133.
134.   end
135.
136.   -- Loop until we've successfully moved
137.   if (moveSuccess == false) then
138.     while ((moveSuccess == false) and (digCount < maxDigCount)) do
139.
140.         -- If there is a block in front, dig it
141.       if (detectFn() == true) then
142.
143.         -- If we've already tried digging, then pause before digging again to let
144.         -- any sand or gravel drop, otherwise check for a chest before digging
145.         if(digCount ~= 0) then
146.           sleep(0.1)
147.         end
148.
149.         digFn()
150.         digCount = digCount + 1
151.       else
152.        -- Am being stopped from moving by a mob, attack it
153.        attackFn()
154.       end
155.
156.       -- Try the move again
157.       moveSuccess = moveFn()
158.
159.       if (moveSuccess == true) then
160.         Turtle.pos.x = newX
161.         Turtle.pos.y = newY
162.         Turtle.pos.z = newZ
163.       end
164.     end
165.
166.     if (digCount == 0) then
167.       lastMoveNeededDig = false
168.     else
169.       lastMoveNeededDig = true
170.     end
171.   end
172.
173.   -- Return the move success
174.   return moveSuccess
175. end
176.
177. -- ********************************************************************************** --
178. -- Get relativety position from direction of turtle
179. -- ********************************************************************************** --
180. function Turtle.getRelativeCoord(direct)
181.
182.   local irrespectiveOrient -- New irrespective orientation to world
183.
184.   if direct == way.UP or direct == way.DOWN then
185.     irrespectiveOrient = direct
186.   else
187.     irrespectiveOrient = (Turtle.orient + direct)%4
188.   end
189.
190.   -- Return direction with displace
191.   return Turtle.pos + surround[irrespectiveOrient]
192. end
193.
194.
195. -- ********************************************************************************** --
196. -- Move the turtle forward one block (updating the turtle's position)
197. -- ********************************************************************************** --
198. function Turtle.forward()
199.
200.   -- Determine the new co-ordinate that the turtle will be moving to
201.   local newX, newY
202.
203.   -- Update the current co-ordinates
204.   if (Turtle.orient == way.FORWARD) then
205.     newY = Turtle.pos.y + 1
206.     newX = Turtle.pos.x
207.   elseif (Turtle.orient == way.LEFT) then
208.     newX = Turtle.pos.x - 1
209.     newY = Turtle.pos.y
210.   elseif (Turtle.orient == way.BACK) then
211.     newY = Turtle.pos.y - 1
212.     newX = Turtle.pos.x
213.   elseif (Turtle.orient == way.RIGHT) then
214.     newX = Turtle.pos.x + 1
215.     newY = Turtle.pos.y
216.   end
217.
218.   local returnVal = Turtle.move(turtle.forward, turtle.detect, turtle.dig, turtle.attack, turtle.compare, turtle.suck, maximumGravelStackSupported, newX, newY, Turtle.pos.z)
219.
220.
221.   return returnVal
222. end
223.
224. -- ********************************************************************************** --
225. -- Move the turtle up one block (updating the turtle's position)
226. -- ********************************************************************************** --
227. function Turtle.up()
228.   local  returnVal = Turtle.move(turtle.up, turtle.detectUp, turtle.digUp, turtle.attackUp, turtle.compareUp, turtle.suckUp, maximumGravelStackSupported, Turtle.pos.x, Turtle.pos.y, Turtle.pos.z + 1)
229.   return returnVal
230. end
231.
232. -- ********************************************************************************** --
233. -- Move the turtle down one block (updating the turtle's position)
234. -- ********************************************************************************** --
235. function Turtle.down()
236.   local  returnVal = Turtle.move(turtle.down, turtle.detectDown, turtle.digDown, turtle.attackDown, turtle.compareDown, turtle.suckDown, 1, Turtle.pos.x, Turtle.pos.y, Turtle.pos.z - 1)
237.   return returnVal
238. end
239.
240. -- ********************************************************************************** --
241. -- Move the turtle back one block (updating the turtle's position)
242. -- ********************************************************************************** --
243. function Turtle.back(doNotTurnBack)
244.
245.   -- Assume that the turtle will move, and switch the co-ords back if it doesn't
246.   -- (do this so that we can write the co-ords to a file before moving)
247.   local newX, newY
248.
249.   -- Update the current co-ordinates
250.   if (Turtle.orient == way.FORWARD) then
251.     newY = Turtle.pos.y - 1
252.     newX = Turtle.pos.x
253.   elseif (Turtle.orient == way.LEFT) then
254.     newX = Turtle.pos.x + 1
255.     newY = Turtle.pos.y
256.   elseif (Turtle.orient == way.BACK) then
257.     newY = Turtle.pos.y + 1
258.     newX = Turtle.pos.x
259.   elseif (Turtle.orient == way.RIGHT) then
260.     newX = Turtle.pos.x - 1
261.     newY = Turtle.pos.y
262.   end
263.
264.   -- First try to move back using the standard function
265.   local returnVal = turtle.back()
266.
267.   if (returnVal == false) then
268.     turtle.turnRight()
269.     turtle.turnRight()
270.
271.     -- Try to move by using the forward function (note, the orientation will be set as
272.     -- the same way as this function started because if the function stops, that is the
273.     -- way that we want to consider the turtle to be pointing)
274.     returnVal = Turtle.move(turtle.forward, turtle.detect, turtle.dig, turtle.attack, turtle.compare, turtle.suck, maximumGravelStackSupported, newX, newY, Turtle.pos.z)
275.
276.     if doNotTurnBack ~= true then
277.       turtle.turnRight()
278.       turtle.turnRight()
279.     end
280.   else
281.     Turtle.pos.x = newX
282.     Turtle.pos.y = newY
283.   end
284.
285.   return returnVal
286. end
287.
288. --===========================================================
289. -- Find path to coordinates, avoid block listed cells
290. -- Using A* algorithm http://pastebin.com/CHCB8nDz
291. --===========================================================
292. function Turtle.pathTo(world,_x,_y,_z)
293.
294.   -- Get first crumb of path
295.   local crumb = AStarFindPath(world, Turtle.pos, vector.new(_x,_y,_z))
296.
297.   if crumb then
298.     -- Run over all crumbs
299.     while crumb.next ~= nil do
300.       crumb = crumb.next
301.       Turtle.goTo(crumb.pos)
302.     end
303.   else
304.     -- Path can be found. Move straight
305.     Turtle.goTo(_x,_y,_z)
306.   end
307.
308. end
309.
310. --===========================================================
311. -- Move turtle on needed position
312. -- Simple move by x, then y, then z
313. -- args can be vector or three parameters x,y,z
314. --===========================================================
315. function Turtle.goTo(_x,_y,_z)
316.   local x,y,z
317.
318.   -- Overload to working with vectors
319.   if type(_x) ~= 'number' and _x ~= nil then
320.     if _x.x and _x.y and _x.z then
321.       x,y,z = _x.x, _x.y, _x.z
322.     else
323.       error('Wrong Turtle.goTo() params')
324.     end
325.   else
326.     x,y,z = _x,_y,_z
327.   end
328.
329.   -- If param undefined, leave it unchanged
330.   if not x then x=Turtle.pos.x end
331.   if not y then y=Turtle.pos.y end
332.   if not z then z=Turtle.pos.z end
333.
334.   local targetVec = vector.new(x,y,z) - Turtle.pos
335.
336.
337.   -- X
338.   if (targetVec.x<0 and Turtle.orient==way.RIGHT)   or
339.      (targetVec.x>0 and Turtle.orient==way.LEFT)    then
340.      while Turtle.pos.x ~= x do
341.        Turtle.back(true)
342.      end
343.   end
344.
345.   while (x<Turtle.pos.x) do
346.     Turtle.setOrient(way.LEFT)
347.     Turtle.forward()
348.   end
349.   while (x>Turtle.pos.x) do
350.     Turtle.setOrient(way.RIGHT)
351.     Turtle.forward()
352.   end
353.
354.
355.   -- Y
356.   if(targetVec.y<0 and Turtle.orient==way.FORWARD) or
357.     (targetVec.y>0 and Turtle.orient==way.BACK)    then
358.      while Turtle.pos.y ~= y do
359.        Turtle.back(true)
360.      end
361.   end
362.
363.   while (y<Turtle.pos.y) do
364.     Turtle.setOrient(way.BACK)
365.     Turtle.forward()
366.   end
367.   while (y>Turtle.pos.y) do
368.     Turtle.setOrient(way.FORWARD)
369.     Turtle.forward()
370.   end
371.
372.
373.   -- Z
374.   while (z<Turtle.pos.z) do
375.     Turtle.down()
376.   end
377.   while (z>Turtle.pos.z) do
378.     Turtle.up()
379.   end
380. end
381.
382. -- ********************************************************************************** --
383. -- Select non-empty slot
384. -- ********************************************************************************** --
385. function Turtle.selectNonEmptySlot()
386.   for i=1, 16 do
387.     if( turtle.getItemCount(i) > 0) then
388.       turtle.select(i)
389.       return true
390.     end
391.   end
392.   return false
393. end
394.
395. -- ********************************************************************************** --
396. -- Place item in front of turtle. Check if item already placed.
397. -- ********************************************************************************** --
398. function Turtle.place(itemSlot, direction)
399.
400.   local detectFnc, compareFnc, placeFnc, attackFnc =
401.         turtle.detect, turtle.compare, turtle.place,turtle.attack
402.
403.   if( direction == way.UP ) then
404.     detectFnc, compareFnc, placeFnc, attackFnc =
405.     turtle.detectUp, turtle.compareUp, turtle.placeUp, turtle.attackUp
406.   elseif( direction == way.DOWN )then
407.     detectFnc, compareFnc, placeFnc, attackFnc =
408.     turtle.detectDown, turtle.compareDown, turtle.placeDown, turtle.attackDown
409.   end
410.
411.   -- slotsPattern is array of 16 nubbers that represent
412.   -- what kind of blocks lying in what kind of
413.   if(itemSlot == nil) then
414.     Turtle.selectNonEmptySlot()
415.   else
416.     turtle.select(itemSlot)
417.   end
418.
419.   local placeSucces = false
420.   local digCount = 0
421.   local maxDigCount = 20
422.
423.
424.   -- Check if there is already item  then try to place
425.   placeSucces = placeFnc()
426.
427.   if((not placeSucces) and detectFnc()) then
428.     if(compareFnc()) then
429.       -- Item that we must set already here
430.       return true
431.     else
432.       -- There is something else. Dig/Attack and place item
433.       Turtle.dig(direction)
434.       digCount = digCount + 1
435.     end
436.   end
437.
438.   -- Now try to place item until item will placed
439.   while ((placeSucces == false) and (digCount < maxDigCount)) do
440.     if (detectFnc()) then
441.       if(digCount > 0) then
442.         sleep(0.1)
443.       end
444.       Turtle.dig(direction)
445.       digCount = digCount + 1
446.     else
447.        -- Am being stopped from moving by a mob, attack it
448.        attackFnc()
449.     end
450.     -- Try the place again
451.     placeSucces = placeFnc()
452.   end
453.
454.   return placeSucces
455. end