View difference between Paste ID: hejgCauq and rHZLvdQb
SHOW: | | - or go back to the newest paste.
1
----------------------------------
2
-- Warning ! WORK IN PROGRESS ! --
3
-- Has not been fully tested !  --
4
----------------------------------
5-
    turtle.drop()
5+
--
6
-- MigukNamja's 1st Quarry Program
7
-- Copyright 2013 MigukNamja
8
-- [email protected]
9
--
10
-- Setup:
11-
-- refuel chest is behind it
11+
--   The quarried block drop-off container should be placed on the mining turtle's *LEFT* side
12
--   A chest or container with solid fuel (ex. charcoal) should be placed directly *BEHIND* the turtle
13-
  if minFuelLevel ~= nil and turtle.getFuelLevel() >= minFuelLevel then
13+
--   These inventories may (should) be automatically emptied and re-supplied, respectively, to ensure smooth
14-
    return
14+
--   operation. The turtle will drop-off and refuel from the start, so it is not necessary to pre-fuel the
15
--   mining turtle
16
--
17
-- The command line arguments are:
18
-- 1st : The number of blocks to move forward. It needs to be a positive, even number
19
-- 2nd : The number of blocks to move rightward. It can be any positive number, including 0
20-
  turtle.suck()
20+
-- 3rd : (Optional) The number of blocks down to begin quarry.
21-
  turtle.refuel()
21+
--
22
-- It will stop if it cannot:
23
-- (A) Drop-off its inventory
24
-- (B) Its inventory somehow fills up before it can drop it off
25
-- (C) Runs out of fuel or cannot refuel to minimum level
26
-- (D) Overcome an obstacle, such as multiple undiggable entities, like multiple mobs or a quickly-moving mob
27-
function bedrockForward_NotFinished()
27+
--
28-
  local blocksUp = 0
28+
-- Note this also does a vertical striping by shafts rather than the usual "strip mine" approach.
29
-- This means lower-layer minerals like diamond and gold will show up *faster* then the usual "strip mine"
30-
  -- must move forward by exactly 1  
30+
--  approach that automated machines like the BC Quarry use. You can furthemore tell it to start its quarry
31-
  while not turtle.forward() do
31+
--  a variable depth below the surface so minerals like gold, diamond, restone, lapis, etc.,. can be focused.
32
--
33-
    -- clear out block, including sand or gravel
33+
-- It can also handle an arbitrary quarry size, so quarries (much larger) then 64x64 are possible.
34-
    while turtle.dig() do
34+
-- In theory, if chunks are loaded it could do near-infinite-size quarries, though the round-trip travel
35-
      turtle.dig()
35+
-- time to the drop-off chest and the refuel chest would make it woefully inefficient.
36
--
37
-- The turtle will then attempt to dig a quarry forward by rightward and "down to bedrock" depth.
38-
    -- block cleared out or unbreakable (bedrock)
38+
-- It will do so by first digging straight down, then up, and forward (repeat down and up), then when done
39-
    -- try to move forward
39+
-- with a complete forward 'column', will move rightward 1 and repeat.
40-
    if not turtle.forward() then
40+
--
41-
      turtle.up()
41+
-- It will return to the drop-off chest and the fuel supply chest after every down-up run.
42-
      blocksUp = blocksUp + 1
42+
--
43
-- The usual turtle robot caveats apply, such as being in a loaded chunk, limited inventory, etc.,.
44
--
45
-- This program does *not* use the Wireless modem and GPS api. Instead, it tries very hard
46
--  to track the x, y, and z deltas. It is therefore suitable for early-game turtle mining and could be used
47
--  as soon as one has 3 diamonds to build a mining turtle. Later or different versions of this program may
48-
  local blocksUp = 3
48+
--  use the gps API for more robust behavior and fewer trips back to the drop-off and refuel chests
49-
  for i=1,blocksUp do
49+
--
50-
    turtle.up()
50+
51
tForward = 0
52-
  while turtle.dig() do
52+
tRight = 0
53-
    turtle.dig()
53+
tDown = 0
54
55-
  turtle.forward()
55+
function down()
56-
  return blocksUp
56+
  if turtle.down() then
57
    tDown = tDown + 1
58
    return true
59-
function digDown()
59+
60-
  local blocks = 0
60+
61-
  while 1 do
61+
62-
    if turtle.digDown() then
62+
63-
      turtle.down()
63+
64-
      blocks = blocks + 1
64+
function up()
65-
    elseif turtle.down() then
65+
  if turtle.up() then
66-
      blocks = blocks + 1
66+
    tDown = tDown - 1
67
    return true
68-
      return blocks
68+
69
    return false
70
  end
71
end
72
73-
function digUp(blocks)
73+
--
74-
  for i=1,blocks do
74+
-- Drop off items in inventory
75-
    turtle.digUp()
75+
-- Will return true if it could successfully drop off everything
76-
    while not turtle.up() do
76+
-- Will return false if it could not, i.e. target inventory was full
77-
      turtle.digUp()
77+
--
78
function dropOffItems()
79
  turtle.turnLeft()
80
  
81
  for i=1,16 do
82-
function downAndUp()
82+
83-
  bDn = digDown()
83+
    if turtle.getItemCount(i) > 0 and not turtle.drop() then
84-
  bDn = bDn - bedrockForward()
84+
      return false
85-
  digUp(bDn)
85+
86-
  turtle.back()
86+
87
  
88
  turtle.turnRight()
89
  turtle.select(1)
90
  
91-
  for i=1,blocks do
91+
  return true
92-
    turtle.back()
92+
93
94
-- Refuel
95
-- Input : Minimum fuel level in turtle units
96-
function moveForw(blocks)
96+
--         http://computercraft.info/wiki/Turtle.refuel#Fuel_Values
97-
  for i=1,blocks do
97+
-- Precondition : Turtle is facing 180 degrees away from chest with fuel in it,
98-
    while not turtle.forward() do
98+
--                but is adjacent to it
99-
      turtle.dig()
99+
-- Postcondition : Turtle has at least the minimum fuel level in its fuel buffer
100
--
101
-- If no arguments are given, it defaults to a minimum of a stack of charcoal
102
--
103
function refuel(minFuelLevel)
104
  if minFuelLevel == nil then
105
    minFuelLevel = 80 * 64 -- a stack of charcoal
106-
  moveForw(blocks)
106+
  elseif turtle.getFuelLevel() >= minFuelLevel then
107
    return true
108
  end
109
  
110
  turtle.turnRight()
111
  turtle.turnRight()
112-
  moveForw(blocks)
112+
113
  
114
  while turtle.getFuelLevel() < minFuelLevel do 
115
    if not turtle.suck() then
116-
function checkArgs(args)
116+
      return false
117-
  if args[1] == nil or args[2] == nil then
117+
118-
    print( "Usage: quarry <blocks forward> <blocks right>")
118+
      turtle.refuel()
119
    end
120-
  elseif args[1] % 2 ~= 0 or args[2] % 2 ~= 0 then
120+
121-
    print( "Please use even numbers for blocks")
121+
122
  turtle.select(1)
123
  turtle.turnLeft()
124
  turtle.turnLeft()
125
  
126
  return true
127
end
128-
args = {...}
128+
129-
if not checkArgs(args) then
129+
--
130-
  print("Exiting...")
130+
-- Check to see if we have enough fuel to keep going a little while longer
131-
else
131+
--
132-
  local bForw = args[1]
132+
function enoughFuel()
133-
  local bRight = args[2]
133+
  if turtle.getFuelLevel() >= (64 * 8) then
134-
  for r = 0, bRight/2 do
134+
135-
    for f = 0, bForw/2 do
135+
136-
      dropOffItems()
136+
137-
      refuel(1000)
137+
138
end
139-
      moveRight( r )
139+
140-
      moveForw( f * 2 )
140+
--
141
-- Check to see if we have enough fuel to keep going a little while longer
142-
      downAndUp()
142+
-- Perhaps 6 slots out of 16 free is enough
143
--
144-
      moveBack( f * 2 )
144+
function enoughFreeSpace()
145-
      moveLeft( r )
145+
  local slotsUsed = 0
146
  for i=1,16 do
147
    --turtle.select(i)
148
    if turtle.getItemCount(i) > 0 then
149-
  dropOffItems()
149+
      slotsUsed = slotsUsed + 1
150-
end
150+
151
  end
152
  
153
  turtle.select(1)
154
  
155
  if slotsUsed <= 10 then
156
    return true
157
  else
158
    return false
159
  end
160
end
161
162
-- Move forward 'blocks' number of blocks, digging when necessary
163
-- Hitting bedrock or something undiggable like an entity (creature) will
164
--   prevent forward movement, and attempts will be made to go around
165
--
166
-- Return actual blocks moved forward
167
function moveForward(blocks)
168
  if blocks < 0 then return moveBack(0-blocks) end
169
  if blocks == 0 then return 0 end
170
  
171
  local moved = 0
172
  
173
  while moved < blocks do
174
    if turtle.forward() then -- air, nothing to dig, but go down
175
      moved = moved + 1
176
    elseif turtle.dig() then -- had to dig to go forwards
177
      if not turtle.forward() then
178
        local attempts = 0
179
        while turtle.dig() and attempts < 20 do
180
          attempts = attempts + 1 -- take care water won't cause infinite digging
181
          sleep(0.25) -- might have to chew through a stack of sand or gravel
182
        end
183
        
184
        if turtle.forward() then
185
          moved = moved + 1
186
        end
187
      else
188
        moved = moved + 1
189
      end
190
    else -- undiggable, give up (for now)
191
      return moved
192
    end
193
    
194
    sleep(0.25) -- sleep to avoid yielding error
195
  end
196
  
197
  return moved
198
end
199
200
-- Move downwards 'blocks' number of blocks, digging when necessary
201
-- Hitting bedrock or something undiggable like an entity (creature) will
202
--   prevent downwards movement, and attempts will be made to go around
203
--
204
-- Return actual blocks moved down
205
function moveDown(blocks)
206
  if blocks < 0 then return moveUp(0-blocks) end
207
  if blocks == 0 then return 0 end
208
  
209
  local moved = 0
210
  
211
  while moved < blocks do
212
    if down() then -- air, nothing to dig, but go down
213
      moved = moved + 1
214
    elseif turtle.digDown() then -- had to dig to go down
215
      if not down() then
216
        while turtle.digDown() do end
217
        if down() then
218
          moved = moved + 1
219
        end
220
      else
221
        moved = moved + 1
222
      end
223
    else -- undiggable, give up (for now)
224
      return moved
225
    end
226
    
227
    sleep(0.25) -- sleep to avoid yielding error
228
  end
229
  
230
  return moved
231
end
232
233
-- Move upwards 'blocks' number of blocks, digging when necessary
234
-- Hitting bedrock or something undiggable like an entity (creature) will
235
--   prevent upwards movement, and attempts will be made to go around
236
--
237
-- Return actual blocks moved up
238
function moveUp(blocks)
239
  if blocks < 0 then return moveDown(0-blocks) end
240
  if blocks == 0 then return 0 end
241
242
  local moved = 0
243
  
244
  while moved < blocks do
245
    if up() then -- air, nothing to dig, but go up
246
      moved = moved + 1
247
    elseif turtle.digUp() then -- dig up to go up
248
      if not up() then
249
        local attempts = 0
250
        while turtle.digUp() and attempts < 20 do
251
          attempts = attempts + 1 -- take care water won't cause infinite digging
252
          sleep(0.25) -- there may be a stack of sand or gravel above us, wait for it to fall
253
        end
254
           
255
        if up() then
256
          moved = moved + 1
257
        else -- try to go around
258
          assert( moveForward( 1 ) == 1 )
259
          assert( moveUp( 1 ) == 1 )
260
          assert( moveBack( 1 ) == 1 )
261
          moved = moved + 1
262
        end
263
      else
264
        moved = moved + 1
265
      end
266
    else -- undiggable, likely an entity (aka mob), try to go around
267
      assert( moveForward( 3 ) == 3 )
268
      assert( moveUp( 1 ) == 1 )
269
      assert( moveBack( 3 ) == 3 )
270
      moved = moved + 1
271
    end
272
273
    sleep(0.25) -- sleep to avoid yielding error
274
  end
275
  
276
  return moved
277
end
278
279
-- Move backwards, digging when necessary
280
function moveBack(blocks)
281
  if blocks < 0 then return moveForward(0-blocks) end
282
  if blocks == 0 then return 0 end
283
284
  local moved = 0
285
  
286
  turtle.turnRight()
287
  turtle.turnRight()
288
  moved = moveForward(blocks)
289
  turtle.turnRight()
290
  turtle.turnRight()
291
  
292
  tForward = tForward - moved
293
  
294
  return moved
295
end
296
297
-- Move to the right, digging when necessary
298
function moveRight(blocks)
299
  if blocks < 0 then return moveLeft(0-blocks) end
300
  if blocks == 0 then return 0 end
301
302
  local moved = 0
303
  
304
  turtle.turnRight()
305
  moved = moveForward(blocks)
306
  turtle.turnLeft()
307
  
308
  tRight = tRight + moved
309
  
310
  return moved
311
end
312
313
-- Move to the left, digging when necessary
314
function moveLeft(blocks)
315
  if blocks < 0 then return moveRight(0-blocks) end
316
  if blocks == 0 then return 0 end
317
318
  local moved = 0
319
   
320
  turtle.turnLeft()
321
  moved = moveForward(blocks)
322
  turtle.turnRight()
323
  
324
  tRight = tRight - moved
325
  
326
  return moved
327
end
328
329
-- Preconditions:
330
-- (1) Turtle is directly above bedrock and cannot go down further
331
-- (2) Anything above turtle will be dug and is diggable
332
-- (3) Return value is how many blocks up we moved
333
--
334
-- Note : the chunks I'm in have perfectly flat bedrock, so this extra code to handle uneven
335
--        bedrock is commented out
336
function bedrockForward()
337
338
  -- Largest delta between lowest possible bedrock and highest possible bedrock....right ?
339
  --local blocksUp = 4
340
  
341
  --assert( moveUp(blocksUp) == blocksUp )
342
  assert( moveForward(1) == 1 )
343
  --local movedDn = moveDown(blocksUp * 2) -- We might have been on top layer of bedrock
344
345
  --return blocksUp - movedDn
346
  
347
  return tonumber(0)
348
end
349
350
-- Dig straight down to bedrock or otherwise undiggable, then move forward 1, and dig straight up
351
-- This is a 2 deep by 1 width by <as deep as we can go> shaft
352
function downAndUp(maxDig)
353
  local bDn = tonumber(moveDown(maxDig))
354
  print( "downAndUp(), moved down ", bDn )
355
  
356
  bedrockForward()
357
  --print( "downAndUp(), bedworkForward() returned ", delta )
358
  
359
  local movedUp = moveUp(bDn)
360
  if movedUp ~= bDn then
361
    print( "downAndUp(), movedUp", movedUp, " ~= ", bDn )  
362
    return false
363
  end
364
  
365
  return true
366
end
367
368
function usage()
369
  print( "Usage: quarry <blocks_forward> <blocks_right> [max depth] [start depth]" )
370
  print( "Forward must be at least 2 and right at least 1. Max depth must be at least 1 if specified." )
371
end
372
373
function parseArgs(args)
374
  local validSyntax = false
375
  local bForward = 0
376
  local bRight = 0
377
  local maxDig = 256
378
  local startDig = 0
379
  
380
  if #args < 2 or #args > 3 then
381
    return false
382
  elseif args[1] == "help" then
383
    return false
384
  elseif args[1] == nil or args[2] == nil then
385
    return false
386
  else
387
    bForward = tonumber( args[1] )
388
    bRight   = tonumber( args[2] )
389
    
390
    if #args >= 3 then
391
      maxDig = tonumber( args[3] )
392
    end
393
    
394
    if #args == 4 then
395
      startDig = tonumber( args[4] )
396
    end
397
398
    if bForward < 2 or bRight < 1 or maxDig < 1 or startDig < 0 then
399
      validSyntax = false
400
    else
401
      validSyntax = true
402
    end
403
  end 
404
  
405
  return validSyntax, bForward, bRight, maxDig, startDig
406
end
407
408
local tArgs = { ... }
409
validSyntax, bForward, bRight, maxDig, startDig = parseArgs(tArgs)
410
if not validSyntax then
411
  usage()
412
  return
413
end
414
415
print( "Quarrying ", bForward, " forward, ", bRight, " right ", maxDig, " layers down starting from ", startDig, " layers down." )
416
417
local minFuelLevel = 1000
418
419
local rLimit = bRight
420
local fLimit = bForward
421
422
local r = 0
423
local f = 0
424
425
while r < rLimit do
426
  while f + 1 < fLimit do
427
  
428
    --print( "1st r = ", r, " f = ", f, "rLimit = ", rLimit, " fLimit = ", fLimit )
429
430
    if not dropOffItems() then
431
      error( "Could not drop off items. Perhaps chest or other inventory is full." )
432
    end
433
    
434
    if not refuel( minFuelLevel ) then
435
      error( "Could not refuel to minimum level ", minFuelLevel, ". Please check fuel container." )
436
    end
437
    
438
    -- Optional feature to start the main part of the dig below the current level
439
    -- This serves two main benefits : keeping the current level (usually the ground level) intact
440
    --   and getting to the premium ores faster, if that is desired
441
    assert( moveDown( startDig ) == startDig )
442
    
443
    -- Traverse to the next dig coordinates
444
    assert( moveRight( r ) == r )
445
    assert( moveForward( f ) == f )
446
447
    -- The main part of the dig that goes all the way down, moves 1 forward, then comes straight back up
448
    while enoughFuel() and enoughFreeSpace() do
449
    
450
      -- Yield to avoid a "Too long without yielding" error !
451
      sleep(1)
452
    
453
      assert( downAndUp( maxDig )  )      
454
      f = f + 1
455
      
456
      if f + 1 < fLimit then
457
        assert( moveForward( 1 ) )
458
        f = f + 1
459
      else
460
        break
461
      end
462
    end
463
464
    --print( "2nd r = ", r, " f = ", f, "rLimit = ", rLimit, " fLimit = ", fLimit )
465
466
    -- Traverse in the reverse direction from the dig coordinates
467
    assert( moveBack( f ) == f )
468
    assert( moveLeft( r ) == r )
469
    
470
    -- Come back up to the main level
471
    assert( moveUp( startDig ) == startDig )
472
    
473
    -- Yield to avoid a "Too long without yielding" error !
474
    sleep(1)
475
  end
476
477
  --print( "3rd r = ", r, " f = ", f, "rLimit = ", rLimit, " fLimit = ", fLimit )
478
479
  r = r + 1
480
  f = 0
481
end
482
483
-- The last drop-off !
484
dropOffItems()
485
486
print( "I have finished the assigned task, my master !" )