View difference between Paste ID: d4DFQ4YK and PAPDddcb
SHOW: | | - or go back to the newest paste.
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
--]]
15
local tArgs = { ... }
16
local sizeZ -- Quarry is this long in direction turtle is initially facing, including block turtle is on
17
local sizeX -- Quarry is this wide to the right of where turtle is facing, including block turtle is on
18
local sizeY -- Quarry removes this many layers of blocks including layer where turtle starts
19
local bDebug= false
20
21
local goUnload	-- Forward declaration
22
23
if (#tArgs == 1) then
24
	sizeZ,sizeX,sizeY = tonumber(tArgs[1]),tonumber(tArgs[1]),256
25
elseif (#tArgs == 2) then
26
	sizeZ,sizeX,sizeY = tonumber(tArgs[1]),tonumber(tArgs[2]),256
27
elseif (#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
else
33
	print( "Usage: quarry <sq. size> <optional width > <optional fixed depth> <optional 1 for debug mode>" )
34
	return
35
end
36
37
-- Validate dimensions
38
if (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
41
end
42
43
local minFuel = math.ceil((math.ceil(sizeY/3)*(sizeX*sizeY)+(2*sizeY))/1200)
44
local maxFuel = "TBD"
45
46
print("Place fuel reserves in slot 1 (upper left) if desired and hit any key to start.")
47
os.pullEvent("key")
48
49
local tX,tZ,tY = 0,0,0    -- Place the turtle starts is considered block 0,0,0 in the turtle's local coordinate system
50
local xDir,zDir = 0,1     -- Turtle is considered as initially facing positive z direction, regardless of global world facing direction
51
local 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
57
local 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
114
end
115
116
local function turnLeft()
117
  turtle.turnLeft()
118
  xDir,zDir = -zDir,xDir
119
  return true
120
end
121
122
local function turnRight()
123
  turtle.turnRight()
124
  xDir,zDir = zDir,-xDir
125
  return true
126
end
127
128
local 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
171
end
172
173
local 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
211
end
212
213
local 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
251
end
252
253
local 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
290
end
291
292
local 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
346
end
347
348
local 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
395
end
396
397
function 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
485
end
486
487
local 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
502
end
503
504
--[[
505
506
  START OF THE MAIN PROGRAM
507
  
508
--]]
509
510
checkFreeSlot()
511
512
local abort = false
513
local traversal = 1 -- Counts x-z layers we're rasterizing. Used to determine turning directions at end of columns and layers
514
local lowestY = 1-sizeY
515
local bDigBelow, bDigAbove = false, false -- initially false
516
while 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
777
end -- 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
780
if 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
784
else
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)
795
end
796
797
if abort then
798
  print("Quarrying ended due to encounter with undiggable block.")
799
else
800
  print("Quarrying complete to desired depth.")
801
end