quarry.lua

856 lines · 30.1 KB

Open raw

Rectangular Quarry Program 1.2b by Adam Smith "shiphorns" March 7 2013 1.0b - Original public release 1.1b - Fixes bug with turtle using the wrong axis order when trying to return home after hitting and undiggable block. I erroneously had it trying to do moveTo(0,0,0) instead of goHome() which would result in the turtle trying to move in the x-direction first, and possibly getting blocked by bedrock when trying to move home. 1.2b - Fix for turtle getting stuck if turtle simultaneous encounters bedrock in front and above it. --

Copy & run

wget https://perlytiara.github.io/turtles.tips/raw/programs/perlytiara/quarry/quarry.lua
1--[[
2
3 Rectangular Quarry Program 1.2b
4 by Adam Smith "shiphorns"
5 March 7 2013
6
7 1.0b - Original public release
8 1.1b - Fixes bug with turtle using the wrong axis order when trying to return home after hitting
9 and undiggable block. I erroneously had it trying to do moveTo(0,0,0) instead of goHome()
10 which would result in the turtle trying to move in the x-direction first, and possibly
11 getting blocked by bedrock when trying to move home.
12 1.2b - Fix for turtle getting stuck if turtle simultaneous encounters bedrock in front and above it.
13
14--]]
15local tArgs = { ... }
16local sizeZ -- Quarry is this long in direction turtle is initially facing, including block turtle is on
17local sizeX -- Quarry is this wide to the right of where turtle is facing, including block turtle is on
18local sizeY -- Quarry removes this many layers of blocks including layer where turtle starts
19local bDebug= false
20
21local goUnload -- Forward declaration
22
23if (#tArgs == 1) then
24 sizeZ,sizeX,sizeY = tonumber(tArgs[1]),tonumber(tArgs[1]),256
25elseif (#tArgs == 2) then
26 sizeZ,sizeX,sizeY = tonumber(tArgs[1]),tonumber(tArgs[2]),256
27elseif (#tArgs >= 3) then
28 sizeZ,sizeX,sizeY = tonumber(tArgs[1]),tonumber(tArgs[2]),tonumber(tArgs[3])
29 if (#tArgs > 3) then
30 bDebug = (tonumber(tArgs[4])==1)
31 end
32 if (#tArgs > 4) then
33 bStartBelow = (tonumber(tArgs[5])==1)
34 else
35 bStartBelow = false
36 end
37 if (#tArgs > 5) then
38 bAutoStart = (tonumber(tArgs[6])==1)
39 else
40 bAutoStart = false
41 end
42else
43 print( "Usage: quarry <sq. size> <optional width > <optional fixed depth> <optional 1 for debug mode> <optional 1 for start below> <optional 1 for auto start>" )
44 return
45end
46
47local xSign = 1
48local zSign = 1
49if sizeX < 0 then xSign = -1; sizeX = -sizeX end
50if sizeZ < 0 then zSign = -1; sizeZ = -sizeZ end
51
52-- Validate dimensions
53if (sizeX<2 or sizeZ<2 or sizeY<1) then
54 print( "Dimensions given must be at least 2L x 2W x 1D. Efficiency is optimal if fixed depth is a multiple of 3." )
55 return
56end
57
58local minFuel = math.ceil((math.ceil(sizeY/3)*(sizeX*sizeY)+(2*sizeY))/1200)
59local maxFuel = "TBD"
60
61if bAutoStart then
62 print("Auto-starting quarry (fuel should be in slot 1)...")
63else
64 print("Place fuel reserves in slot 1 (upper left) if desired and hit any key to start.")
65 os.pullEvent("key")
66end
67
68local tX,tZ,tY = 0,0,0 -- Place the turtle starts is considered block 0,0,0 in the turtle's local coordinate system
69local xDir,zDir = 0,1 -- Turtle is considered as initially facing positive z direction, regardless of global world facing direction
70local refuelSlot = 1 -- Turtle can fuel from any slot, but it will never dump this slot's contents so this is where fuel should be placed
71
72-- Define turn functions before using them
73local function turnLeft()
74 turtle.turnLeft()
75 xDir,zDir = -zDir,xDir
76 return true
77end
78
79local function turnRight()
80 turtle.turnRight()
81 xDir,zDir = zDir,-xDir
82 return true
83end
84
85-- Apply initial facing adjustments
86if zSign == -1 then
87 turnLeft()
88 turnLeft()
89end
90
91local myTurnLeft = turnLeft
92local myTurnRight = turnRight
93if xSign == -1 then
94 myTurnLeft = turnRight
95 myTurnRight = turnLeft
96end
97
98-- Debug function assignments
99if bDebug then
100 print("Function assignments complete. myTurnLeft: " .. tostring(myTurnLeft) .. ", myTurnRight: " .. tostring(myTurnRight))
101end
102
103-- Notice that all coordinates formated as 0,0,0 are in X,Z,Y order, NOT alphabetical X,Y,Z order, where Y is up/down axis
104-- Y axis is always the minecraft world Y-axis, but X and Z in this turtle's local coordinate system won't necessarily match his
105-- orientation in the global world system (turtle's system is relative to how he is initially facing, +Z is his facing direction)
106
107local function checkFuel(bMovingAwayFromOrigin)
108 if bDebug then print("checkFuel()") end
109 -- This function returns true only if there is enough fuel left to move 1 block in any direction,
110 -- and still have enough left over for a return trip to 0,0,0 that might be needed for refuel or at
111 -- the end of the quarrying. This ensures the turtle is never stranded in the quarry.
112 local fuelLevel = turtle.getFuelLevel()
113
114 if (fuelLevel == "unlimited") then
115 -- Server has fuel requirement turned off in configs
116 return true
117 end
118
119 -- If the turtle is attempting to move away from its starting location, it is going to
120 -- consume the normal 1 fuel cost to move, but it will also add +1 to the cost of the
121 -- trip to return home to dump/refuel/finish. If we know the turtle is moving closer to
122 -- home, there is no extra cost since it is effectively part of the return trip.
123 local fuelNeeded = math.abs(tX)+math.abs(tY)+math.abs(tZ)
124 if (bMovingAwayFromOrigin == nil or bMovingAwayFromOrigin == true) then
125 -- Turtle is moving away from 0,0,0 or direction is unspecified (assume worst case), add 2 fuel
126 fuelNeeded = fuelNeeded + 2
127 end
128
129 if (fuelLevel >= fuelNeeded) then
130 -- Turtle has enough fuel to do the next 1-block movement, plus enough to
131 -- return home from there.
132 return true
133 end
134
135 -- If we get here, turtle does not have enough fuel for the move plus a return to base
136 -- First we will try to refuel from anything we find in the turtle's inventory. Failing that
137 -- We will return to home and prompt the user to add fuel
138
139 local slot = 1
140 turtle.select(slot)
141
142 if bDebug then print("Entering while true do in checkFuel") end
143 while true do
144 if turtle.refuel(1) then
145 -- Found fuel in current slot, consume 1, see if it's enough, if not loop again
146 if (turtle.getFuelLevel()>=fuelNeeded) then
147 print("Refueled from inventory, resuming quarrying...")
148 return true
149 end
150 else
151 -- Couldn't refuel from currently-selected slot, try next slot. If there are no more slots, ask for player help.
152 if (slot < 16) then
153 slot = slot + 1
154 turtle.select(slot)
155 else
156 -- There are no more slots to look in, reset selection so that we're ready to loop over all slots again, and so that the
157 -- player sees slot 1 highlighted (fastest for turtle to find fuel in). Return to 0,0,0 if we can (in case turtle is
158 -- under lava or otherwise inaccessible), prompt player to add fuel.
159
160 return goUnload(true)
161 end
162 end
163 end
164end
165
166local function goForward(bCheckFuel)
167 if bDebug then print("goForward()") end
168 -- Can't move without fuel. checkFuel() will wait on player if necessary.
169 if (bCheckFuel==true or bCheckFuel==nil) then
170 checkFuel((xDir>0 and tX>=0) or (xDir<0 and tX<=0) or (zDir>0 and tZ>=0) or (zDir<0 and tZ<=0)) -- Passes boolean true if moving away from 0,0,0
171 end
172
173 local tries = 3
174 while not turtle.forward() do
175 if bDebug then print("goForward: while not turtle.forward() do tries="..tries) end
176 if turtle.detect() then
177 if bDebug then print("goForward: detect") end
178 if not turtle.dig() then
179 print("Undiggable block encountered. Will retry in 5 seconds.")
180 -- Turtle is blocked. In case this is a temporary glitch, we try 3 times before conceding hard failure
181 tries = tries - 1
182 if (tries <= 0) then
183 return false
184 else
185 if bDebug then print("goForward: sleep(5)") end
186 sleep(5) -- Wait 5 seconds, hope the problem resolves itself
187 end
188 end
189 elseif turtle.attack() then
190 if bDebug then print("goForward: attack") end
191 -- Had to attack player or mob. You can add additional code here such
192 -- as turtle.suck() if you want to collect killed mob loot. This is a quarry program
193 -- to collect ores, not rotten flesh and bones, so this block is empty.
194 else
195 -- Unknown obstruction, possibly a player in
196 -- peaceful or creative mode. Try again in 0.5 seconds and hope it's gone.
197 if bDebug then
198 print("goForward: sleep(0.5) else block")
199 print("Turtle fuel="..turtle.getFuelLevel())
200 end
201 sleep(0.5)
202 end
203 end
204
205 tX = tX + xDir -- If we're moving in the xDir, this will change tX by + or - 1
206 tZ = tZ + zDir -- If we're moving in the zDir, this will change tZ by + or - 1
207
208 return true -- Turtle moved successfully
209end
210
211local function goDown(bCheckFuel)
212 if bDebug then print("goDown()") end
213 -- Can't move without fuel. checkFuel() will wait on player if necessary.
214 if (bCheckFuel==true or bCheckFuel==nil) then
215 checkFuel(tY<=0) -- Passes boolean true if moving away from 0,0,0
216 end
217
218 local tries = 3
219 while not turtle.down() do
220 if bDebug then print("goDown: while not turtle.down() do tries="..tries) end
221 if turtle.detectDown() then
222 if bDebug then print("goDown: detectDown") end
223 if not turtle.digDown() then
224 print("Undiggable block encountered. Will retry in 5 seconds")
225 -- Turtle is blocked. In case this is a temporary glitch, we try 3 times before conceding hard failure
226 tries = tries - 1
227 if (tries <= 0) then
228 return false
229 else
230 if bDebug then print("goDown: sleep(5)") end
231 sleep(5) -- Wait 5 seconds, hope the problem resolves itself
232 end
233 end
234 elseif turtle.attackDown() then
235 if bDebug then print("goDown: attack") end
236 -- Had to attack player or mob. You can add additional code here such
237 -- as turtle.suck() if you want to collect killed mob loot. This is a quarry program
238 -- to collect ores, not rotten flesh and bones, so this block is empty.
239 else
240 -- Unknown obstruction, possibly a player in
241 -- peaceful or creative mode. Try again in 0.5 seconds and hope it's gone.
242 if bDebug then print("goDown: sleep(0.5)") end
243 sleep(0.5)
244 end
245 end
246
247 tY = tY - 1
248 return true -- Turtle moved successfully
249end
250
251local function goUp(bCheckFuel)
252 if bDebug then print("goUp()") end
253
254 -- Can't move without fuel. checkFuel() will wait on player if necessary.
255 if (bCheckFuel==true or bCheckFuel==nil) then
256 checkFuel(tY>=0) -- Passes boolean true if moving away from 0,0,0
257 end
258
259 local tries = 3
260 while not turtle.up() do
261 if bDebug then print("goUp: while not loop tries="..tries) end
262 if turtle.detectUp() then
263 if bDebug then print("goUp: detectUp") end
264 if not turtle.digUp() then
265 print("Undiggable block encountered. Will retry in 5 seconds.")
266 -- Turtle is blocked. In case this is a temporary glitch, we try 3 times before conceding hard failure
267 tries = tries - 1
268 if (tries <= 0) then
269 return false
270 else
271 sleep(10) -- Wait 10 seconds, hope the problem resolves itself
272 end
273 end
274 elseif turtle.attackUp() then
275 if bDebug then print("goUp: attack") end
276 -- Had to attack player or mob. You can add additional code here such
277 -- as turtle.suck() if you want to collect killed mob loot. This is a quarry program
278 -- to collect ores, not rotten flesh and bones, so this block is empty.
279 else
280 -- Unknown obstruction, possibly a player in
281 -- peaceful or creative mode. Try again in 0.5 seconds and hope it's gone.
282 if bDebug then print("goUp: sleep(0.5)") end
283 sleep(0.5)
284 end
285 end
286
287 tY = tY + 1
288 return true -- Turtle moved successfully
289end
290
291local function orient(targetXdir, targetZdir)
292 -- One of the supplied directions should be -1 or +1, the other should be 0.
293 if ((targetXdir ~= 0) and (targetZdir ~= 0)) or ((targetXdir==0) and (targetZdir==0)) then
294 print("orient() given mutually exclusive values: "..targetXdir..", "..targetZdir)
295 return false
296 end
297
298 if (((targetXdir ~= 0) and (math.abs(targetXdir) ~= 1)) or ((targetZdir ~= 0) and (math.abs(targetZdir) ~= 1))) then
299 print("orient() given bad values: "..targetXdir..", "..targetZdir)
300 return false
301 end
302
303 if (targetXdir ~= 0) and (targetXdir ~= xDir) then
304 -- x axis alignment requested, and differs from current alignment
305 if (xDir ~= 0) then
306 -- Turtle is x-axis aligned 180 from target
307 turnLeft()
308 turnLeft()
309 elseif (zDir == targetXdir) then
310 turnRight()
311 else
312 turnLeft()
313 end
314 elseif (targetZdir ~= 0) and (targetZdir ~= zDir) then
315 -- z axis alignment requested, and differs from current alignment
316 if (zDir ~= 0) then
317 -- Turtle is z-axis aligned 180 from target
318 turnLeft()
319 turnLeft()
320 elseif (xDir == targetZdir) then
321 turnLeft()
322 else
323 turnRight()
324 end
325 end
326
327 return true
328end
329
330local function goHome()
331 -- This is similar to moveTo(0,0,0) but axis ordering of movement is reversed, so that turtle takes
332 -- the same path to and from home location and where it left off. Also, this function passes false to
333 -- goDown, goUp and goForward to make them skip the per-move fuel check, because making that check
334 -- could result in circular function calling: goHome()->goFoward()->checkFuel()->goHome()->goFoward()->checkFuel().. etc.
335 -- This function is set up to move along Y-axis first, then X, then finally Z, unless bReverse is true
336 -- Note: The order doesn't matter much when digging out a space, but can matter when building something
337 -- so that you don't dig a tunnel through what you're building.
338
339 local fuelNeeded = math.abs(tX)+math.abs(tY)+math.abs(tZ)
340 if not (turtle.getFuelLevel()>=fuelNeeded) then
341 print("Error: Turtle ended up in the unexpected state of not having enough fuel to return home.")
342 return false
343 end
344
345 while (tY<0) do
346 if bDebug then print("goHome while tY<0 tY="..tY) end
347 if not goUp(false) then
348 -- Critical movement fail, bail
349 return false
350 end
351 end
352
353 while (tY>0) do
354 if bDebug then print("goHome while tY>0 tY="..tY) end
355 if not goDown(false) then
356 -- Critical movement fail, bail
357 return false
358 end
359 end
360
361 -- If not at tX==targetX, move the right direction until tX==targetX
362 if (tX>0) then orient(-1,0) end
363 if (tX<0) then orient(1,0) end
364 while (tX~=0) do
365 if bDebug then print("goHome while tX~=0 tX="..tX) end
366 if not goForward(false) then
367 -- Critical movement fail, bail
368 return false
369 end
370 end
371
372 -- If not at tZ==targetZ, move the right direction until tZ==targetZ
373 if (tZ>0) then orient(0,-1) end
374 if (tZ<0) then orient(0,1) end
375 while (tZ~=0) do
376 if bDebug then print("goHome while tZ~=0 tZ="..tZ) end
377 if not goForward(false) then
378 -- Critical movement fail, bail
379 return false
380 end
381 end
382
383 return true
384end
385
386local function moveTo(targetX,targetZ,targetY)
387
388 local fuelNeeded = math.abs(tX-targetX)+math.abs(tY-targetY)+math.abs(tZ-targetZ)
389 if not (turtle.getFuelLevel()>=fuelNeeded) then
390 print("Error: Turtle ended up in the unexpected state of not having enough fuel to return home.")
391 return false
392 end
393
394 -- If not at tZ==targetZ, move the right direction until tZ==targetZ
395 if (tZ>targetZ) then orient(0,-1) end
396 if (tZ<targetZ) then orient(0,1) end
397 while (tZ~=targetZ) do
398 if bDebug then print("moveTo while tZ~=targetZ tZ="..tZ.." targetZ="..targetZ) end
399 if not goForward(false) then
400 -- Critical movement fail, bail
401 return false
402 end
403 end
404
405 -- If not at tX==targetX, move the right direction until tX==targetX
406 if (tX>targetX) then orient(-1,0) end
407 if (tX<targetX) then orient(1,0) end
408 while (tX~=targetX) do
409 if bDebug then print("moveTo while tX~=targetX tX="..tX.." targetX="..targetX) end
410 if not goForward(false) then
411 -- Critical movement fail, bail
412 return false
413 end
414 end
415
416 while (tY<targetY) do
417 if bDebug then print("moveTo while tY<targetY tY="..tY.." targetY="..targetY) end
418 if not goUp(false) then
419 -- Critical movement fail, bail
420 return false
421 end
422 end
423
424 while (tY>targetY) do
425 if bDebug then print("moveTo while tY>targetY tY="..tY.." targetY="..targetY) end
426 if not goDown(false) then
427 -- Critical movement fail, bail
428 return false
429 end
430 end
431
432 return true
433end
434
435function goUnload(bNeedsFuel)
436 if bDebug then print("goUnload()") end
437 -- Save position and orientation
438 local saveX = tX
439 local saveZ = tZ
440 local saveY = tY
441 local saveXdir = xDir
442 local saveZdir = zDir
443
444 if not goHome() then
445 -- Critical failure to move
446 return false
447 end
448
449 orient(0,-1)
450
451 -- Drop items. Turtle will not empty the slot designated as the refuel slot.
452 for i=1,16 do
453 if (i ~= refuelSlot) then
454 turtle.select(i)
455 turtle.drop()
456 end
457 end
458
459 orient(0,1)
460
461 -- Select first empty slot, might be a now-empty fuel slot, we don't really care
462 for i=1,16 do
463 if (turtle.getItemCount(i)==0) then
464 turtle.select(i)
465 break
466 end
467 end
468
469
470 -- Since we had to bring the turtle all the way home, calculate
471 -- the fuel needed to get back to where turtle left off mining, do at least one
472 -- full layer's worth of work, plus approximately enough to get back home again. It would be
473 -- silly to leave base with anything less than that, since the fuel would go nearly all to moving
474 -- the turtle through already-mined space doing no work...
475 local fuelNeeded = 2 * (math.abs(tX-saveX) + math.abs(tY-saveY) + math.abs(tZ-saveZ)) + (sizeX * sizeZ)
476
477 while (turtle.getFuelLevel() < fuelNeeded) do
478
479 if bDebug then print("Entering while true do in goUnload fuel check stage") end
480
481 -- Scan inventory for fuel
482 local slot = 1
483 turtle.select(slot)
484 local bRefueled = false
485
486 while true do
487 if turtle.refuel(1) then
488 -- Found fuel in current slot, consume 1, see if it's enough, if not loop again
489 print("Consuming fuel item from slot "..slot)
490 if (turtle.getFuelLevel()>=fuelNeeded) then
491 print("Refueled from inventory, resuming quarrying...")
492 bRefueled = true
493 break
494 end
495 else
496 -- Couldn't refuel from currently-selected slot, try next slot. If there are no more slots, ask for player help.
497 if (slot < 16) then
498 slot = slot + 1
499 turtle.select(slot)
500 else
501 -- There are no more slots to look in, reset selection so that we're ready to loop over all slots again, and so that the
502 slot = 1
503 break
504 end
505 end
506 end
507
508 if not bRefueled then
509 turtle.select(1)
510 print("Please add more fuel items to the turtle and press any key. Has:"..turtle.getFuelLevel().." Needs:"..fuelNeeded)
511 os.pullEvent("key") -- suspend code execution awaiting user keypress
512 end
513 end
514
515 if not moveTo(saveX,saveZ,saveY) then
516 -- Critical failure to move
517 return false
518 end
519
520 orient(saveXdir,saveZdir)
521
522 return true
523end
524
525local function checkFreeSlot()
526 -- This function will return true if the designated refuelSlot is empty, because if there is no fuel reserve there, there
527 -- is no reason not to allow item collection into this slot.
528 for i=1,16 do
529 if turtle.getItemCount(i)==0 then
530 return true
531 end
532 end
533
534 -- Turtle does not have empty slot, goUnload
535 if not goUnload() then
536 return false
537 end
538
539 return true
540end
541
542--[[
543
544 START OF THE MAIN PROGRAM
545
546--]]
547
548checkFreeSlot()
549
550local abort = false
551local traversal = 1 -- Counts x-z layers we're rasterizing. Used to determine turning directions at end of columns and layers
552local lowestY = 1-sizeY
553local bDigBelow, bDigAbove = false, false -- initially false
554if bStartBelow then
555 if not goDown() then
556 print("Cannot dig below starting position. Aborting.")
557 return
558 end
559 tY = -1
560 lowestY = -sizeY
561end
562while true do -- This loops digging layers
563 print("Main loop traversal="..traversal.." tY="..tY.." lowestY="..lowestY)
564
565 local thisTraversal = traversal
566 if zSign == -1 then thisTraversal = traversal + 1 end
567
568 if (traversal==1) then --special case since turtle initially starts NOT on a layer that it just dug out.
569 if ((tY - lowestY) == 0) then
570 bDigBelow, bDigAbove = false, false
571 elseif ((tY - lowestY) == 1) then
572 bDigBelow, bDigAbove = true, false
573 elseif ((tY - lowestY) >= 2) then
574 bDigBelow, bDigAbove = true, true
575 if not goDown() then
576 -- Turtle can't dig down, adjust lowestY because we can't go as deep as planned
577 lowestY = tY - 1
578 end
579 else
580 -- Error: turtle is not in an expected place
581 print("Error: Turtle vertical position is not what we expect on 1st traversal. Aborting, please debug.")
582 abort = true
583 break
584 end
585 else
586 -- Not our first traversal, and turtle should now be on the last layer it dug out.
587 if ((tY - lowestY) == 1) then
588 bDigBelow, bDigAbove = true, false
589 elseif ((tY - lowestY) == 2) then
590 bDigBelow, bDigAbove = true, false
591 if not goDown() then
592 -- Turtle can't go down, adjust lowestY because we can't go as deep as planned
593 lowestY = tY - 1
594 end
595 elseif ((tY - lowestY) >= 3) then
596 bDigBelow, bDigAbove = true, true
597 -- Try to descend 2, if either fails, adjust lowestY to just below where turtle is able to get to, and
598 -- cancel the need to digAbove
599 for j=1,2 do
600 if not goDown() then
601 -- Turtle can't dig down, adjust lowestY because we can't go as deep as planned
602 lowestY = tY - 1
603 bDigAbove = false
604 end
605 end
606 else
607 -- Error: turtle is not in an expected place
608 print("Error: Turtle vertical position is not what we expect on traversal>1. Aborting, please debug.")
609 abort = true
610 break
611 end
612 end
613
614
615
616 for column=1,sizeX do -- This loops sizeX times digging out columns
617 for block=1,(sizeZ-1) do -- this loops (sizeZ-1) times doing digDown and goForward to do all but the end of each column
618
619 -- Since we're about to do a potentially ore-digging move, check for free space in inventory.
620 -- hasFreeSlot() calls goUnload if necessary
621 if not checkFreeSlot() then
622 print("Error: checkFreeSlot failure.")
623 abort = true
624 break
625 end
626
627 if bDigBelow and turtle.detectDown() then
628 if not turtle.digDown() then
629 -- Turtle can't dig down, but we're not moving down so this is not a fatal error.
630 -- It might be bedrock below turtle, but that's not a concern until turtle is level with it.
631 end
632 end
633
634 if bDigAbove and turtle.detectUp() then
635 if not turtle.digUp() then
636 -- Turtle can't dig up. This is actually concerning since we don't want to get him trapped under bedrock.
637 -- Because of the danger of entrapment, we're ending our quarrying here.
638 print("Turtle below undiggable block, backing out and returning home.")
639 myTurnRight()
640 myTurnRight()
641 if not goForward() then
642 -- This failure we care about, because there is something blocking us that we
643 -- can't dig, attack or otherwise resolve. Bust out of our digging loops and attempt to return home
644 print("Fatal Error during column goForward tX="..tX.." tZ="..tZ.." tY="..tY)
645 end
646 abort = true
647 break
648 end
649 sleep(0.5) -- wait to see if anything falls on turtle from above (sand, gravel)
650
651 -- First dig up was successful, so we haven't got an undiggable block above, and undiggables can't fall, so we can
652 -- safely loop trying to dig up as long as something is falling on us (gravel, sand)
653 while turtle.detectUp() do
654 if bDebug then print("in while turtrle.detectUp() loop.") end
655 if not turtle.digUp() then
656 -- whatever is up there, we couldn't dig it, but it's not bedrock. Just move on...
657 break
658 end
659 sleep(0.5)
660 end
661 end
662
663 if not goForward() then
664 -- This failure we care about, because there is something blocking us that we
665 -- can't dig, attack or otherwise resolve. Bust out of our digging loops and attempt to return home
666 -- after first checking to be sure the turtle is not under bedrock (if digging above)
667 print("Fatal Error during column goForward tX="..tX.." tZ="..tZ.." tY="..tY)
668 abort = true
669 break
670 end
671 end -- end of block loop
672
673 -- If movement failed while traversing column, escape out, backing out from under bedrock if needed
674 if abort then
675 if bDigAbove and turtle.detectUp() then
676 if not turtle.digUp() then
677 -- Turtle can't dig up. This is actually concerning since we don't want to get him trapped under bedrock.
678 -- Because of the danger of entrapment, we're ending our quarrying here.
679 print("Turtle below undiggable block, backing out and returning home.")
680 myTurnRight()
681 myTurnRight()
682 if not goForward() then
683 -- This failure we care about, because there is something blocking us that we
684 -- can't dig, attack or otherwise resolve. Bust out of our digging loops and attempt to return home
685 print("Fatal Error during column goForward tX="..tX.." tZ="..tZ.." tY="..tY)
686 end
687 end
688 end
689
690 -- unwinding
691 break
692 end
693
694 -- Dig out the last block of this column
695 if bDigBelow and turtle.detectDown() then
696 if not turtle.digDown() then
697 -- Turtle can't dig down, but we're not moving down so this is not a fatal error.
698 -- It might be bedrock below turtle, but that's not a concern until turtle is level with it.
699 end
700 end
701
702 -- Do last digUp in this column, if required by bDigAbove
703 if bDigAbove and turtle.detectUp() then
704 if not turtle.digUp() then
705 -- Turtle can't dig up. This is actually concerning since we don't want to get him trapped under bedrock.
706 -- Because of the danger of entrapment, we're ending our quarrying here.
707 print("Turtle below undiggable block, backing out and returning home.")
708 myTurnRight()
709 myTurnRight()
710 if not goForward() then
711 -- This failure we care about, because there is something blocking us that we
712 -- can't dig, attack or otherwise resolve. Bust out of our digging loops and attempt to return home
713 print("Fatal Error during column goForward tX="..tX.." tZ="..tZ.." tY="..tY)
714 end
715 abort = true
716 break
717 end
718 sleep(0.5) -- wait to see if anything falls on turtle from above (sand, gravel)
719
720 -- First dig up was successful, so we haven't got an undiggable block above, and undiggables can't fall, so we can
721 -- safely loop trying to dig up as long as something is falling on us (gravel, sand)
722 while turtle.detectUp() do
723 if bDebug then print("in while turtrle.detectUp() loop.") end
724 if not turtle.digUp() then
725 -- whatever is up there, we couldn't dig it, but it's not bedrock. Just move on...
726 break
727 end
728 sleep(0.5)
729 end
730 end
731
732 -- Turtle just finished the column, figure out if we need to advance to a new column, or
733 -- if we've finished the layer. If we need to turn to start a new column, we have to figure out which
734 -- direction to turn
735 if (column<sizeX) then
736 -- Turtle is at the end of a z column, but not the end of the whole x-z layer traversal
737
738 -- FYI: These odd/even values are based on 1-based block, column, traversal numbers not 0-based tX, tZ, tY
739 -- sorry if that's confusing, but Lua convention is to start loop indicies at 1
740 local evenCol = ((column%2)==0)
741 local evenWidth = ((sizeX%2)==0)
742 local evenLayer = ((thisTraversal%2)==0)
743 local backtrackingLayer = (evenWidth and evenLayer)
744
745 if ((not evenCol and not backtrackingLayer) or (evenCol and backtrackingLayer)) then
746 if myTurnRight then
747 myTurnRight() -- turn towards next row
748 else
749 print("Error: myTurnRight is nil!")
750 turnRight()
751 end
752 if not goForward() then
753 print("Fatal Error during goForward from column "..column.." to column "..(column+1).." tX="..tX.." tZ="..tZ.." tY="..tY)
754 abort = true
755 break
756 end
757
758 -- Danger check to see if we've moved under an undiggable block
759 if bDigAbove and turtle.detectUp() and not turtle.digUp() then
760 print("Turtle below undiggable block, backing out 1 and returning home.")
761 myTurnRight()
762 myTurnRight()
763 if not goForward() then
764 -- This failure we care about, because there is something blocking us that we
765 -- can't dig, attack or otherwise resolve. Bust out of our digging loops and attempt to return home
766 print("Fatal Error during column goForward tX="..tX.." tZ="..tZ.." tY="..tY)
767 end
768 abort = true
769 break
770 end
771
772 myTurnRight()
773 else
774 myTurnLeft()
775 if not goForward() then
776 print("Fatal Error during goForward from column "..column.." to column "..(column+1).." tX="..tX.." tZ="..tZ.." tY="..tY)
777 abort = true
778 break
779 end
780
781 -- Danger check to see if we've moved under an undiggable block
782 if bDigAbove and turtle.detectUp() and not turtle.digUp() then
783 print("Turtle below undiggable block, backing out 1 and returning home.")
784 myTurnRight()
785 myTurnRight()
786 if not goForward() then
787 -- This failure we care about, because there is something blocking us that we
788 -- can't dig, attack or otherwise resolve. Bust out of our digging loops and attempt to return home
789 print("Fatal Error during column goForward tX="..tX.." tZ="..tZ.." tY="..tY)
790 end
791 abort = true
792 break
793 end
794
795 myTurnLeft()
796 end
797 -- Turtle is now ready to start the next column
798 else
799 -- Turtle is at the end of the layer, rotate 180
800 myTurnRight()
801 myTurnRight()
802 end
803 end -- end of column loop
804
805 if abort then
806 print("Abort breaking out of while true loop.")
807 -- abort in progress, unwinding out of loops
808 break
809 end
810
811 -- See if we're done yet
812 if ((tY - lowestY) == 0) or (((tY - lowestY) == 1) and (bDigBelow == true)) then
813 -- We're done. We've finished digging our lowest layer either by digging forward or with digDown.
814 done = true
815 break
816 end
817
818 -- If we got past the last if-then, we are not done, so we need to descend in preparation for next layer traversal
819 if bDigBelow then
820 -- We were digging below us on the traversal we just finished, so we need to drop down 2 levels to be on an undug layer
821 -- First we try to descend through the dug-down layer, but since that could have bedrock (we we skimming above it not caring)
822 -- we need to test to see if we can descend into that layer at our current tX,tZ location
823 if not goDown() then
824 print("Turtle finished a traversal and was digging below. Turtle can't go further down, we're done quarrying.")
825 abort = true
826 break
827 end
828 end
829
830 traversal = traversal + 1
831end -- end of while not done loop
832
833-- Quarrying ended, either normally or because of encountering undiggable block. Try to return to 0,0,0
834if not goHome(0,0,0) then
835 -- Can't even get back home :-( Notify the user
836 print("Turtle was not able to safely get back to starting location")
837 abort = true
838else
839 orient(0,-1)
840
841 -- Drop everything
842 -- Drop items. Turtle will not empty the slot designated as the refuel slot.
843 print("Unloading all contents...")
844 for i=1,16 do
845 turtle.select(i)
846 turtle.drop()
847 end
848 orient(0,1)
849end
850
851if abort then
852 print("Quarrying ended due to encounter with undiggable block.")
853else
854 print("Quarrying complete to desired depth.")
855end
856