quarry.cc.lua

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