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 !" ) |