Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ----------------------------------
- -- Warning ! WORK IN PROGRESS ! --
- -- Has not been fully tested ! --
- ----------------------------------
- --
- -- MigukNamja's 1st Quarry Program
- -- Copyright 2013 MigukNamja
- --
- -- Setup:
- -- The quarried block drop-off container should be placed on the mining turtle's *LEFT* side
- -- A chest or container with solid fuel (ex. charcoal) should be placed directly *BEHIND* the turtle
- -- These inventories may (should) be automatically emptied and re-supplied, respectively, to ensure smooth
- -- operation. The turtle will drop-off and refuel from the start, so it is not necessary to pre-fuel the
- -- mining turtle
- --
- -- The command line arguments are:
- -- 1st : The number of blocks to move forward. It needs to be a positive, even number
- -- 2nd : The number of blocks to move rightward. It can be any positive number, including 0
- -- 3rd : (Optional) The number of blocks down to begin quarry.
- --
- -- It will stop if it cannot:
- -- (A) Drop-off its inventory
- -- (B) Its inventory somehow fills up before it can drop it off
- -- (C) Runs out of fuel or cannot refuel to minimum level
- -- (D) Overcome an obstacle, such as multiple undiggable entities, like multiple mobs or a quickly-moving mob
- --
- -- Note this also does a vertical striping by shafts rather than the usual "strip mine" approach.
- -- This means lower-layer minerals like diamond and gold will show up *faster* then the usual "strip mine"
- -- approach that automated machines like the BC Quarry use. You can furthemore tell it to start its quarry
- -- a variable depth below the surface so minerals like gold, diamond, restone, lapis, etc.,. can be focused.
- --
- -- It can also handle an arbitrary quarry size, so quarries (much larger) then 64x64 are possible.
- -- In theory, if chunks are loaded it could do near-infinite-size quarries, though the round-trip travel
- -- time to the drop-off chest and the refuel chest would make it woefully inefficient.
- --
- -- The turtle will then attempt to dig a quarry forward by rightward and "down to bedrock" depth.
- -- It will do so by first digging straight down, then up, and forward (repeat down and up), then when done
- -- with a complete forward 'column', will move rightward 1 and repeat.
- --
- -- It will return to the drop-off chest and the fuel supply chest after every down-up run.
- --
- -- The usual turtle robot caveats apply, such as being in a loaded chunk, limited inventory, etc.,.
- --
- -- This program does *not* use the Wireless modem and GPS api. Instead, it tries very hard
- -- to track the x, y, and z deltas. It is therefore suitable for early-game turtle mining and could be used
- -- as soon as one has 3 diamonds to build a mining turtle. Later or different versions of this program may
- -- use the gps API for more robust behavior and fewer trips back to the drop-off and refuel chests
- --
- tForward = 0
- tRight = 0
- tDown = 0
- function down()
- if turtle.down() then
- tDown = tDown + 1
- return true
- else
- return false
- end
- end
- function up()
- if turtle.up() then
- tDown = tDown - 1
- return true
- else
- return false
- end
- end
- --
- -- Drop off items in inventory
- -- Will return true if it could successfully drop off everything
- -- Will return false if it could not, i.e. target inventory was full
- --
- function dropOffItems()
- turtle.turnLeft()
- for i=1,16 do
- turtle.select(i)
- if turtle.getItemCount(i) > 0 and not turtle.drop() then
- return false
- end
- end
- turtle.turnRight()
- turtle.select(1)
- return true
- end
- -- Refuel
- -- Input : Minimum fuel level in turtle units
- -- http://computercraft.info/wiki/Turtle.refuel#Fuel_Values
- -- Precondition : Turtle is facing 180 degrees away from chest with fuel in it,
- -- but is adjacent to it
- -- Postcondition : Turtle has at least the minimum fuel level in its fuel buffer
- --
- -- If no arguments are given, it defaults to a minimum of a stack of charcoal
- --
- function refuel(minFuelLevel)
- if minFuelLevel == nil then
- minFuelLevel = 80 * 64 -- a stack of charcoal
- elseif turtle.getFuelLevel() >= minFuelLevel then
- return true
- end
- turtle.turnRight()
- turtle.turnRight()
- turtle.select(16)
- while turtle.getFuelLevel() < minFuelLevel do
- if not turtle.suck() then
- return false
- else
- turtle.refuel()
- end
- end
- turtle.select(1)
- turtle.turnLeft()
- turtle.turnLeft()
- return true
- end
- --
- -- Check to see if we have enough fuel to keep going a little while longer
- --
- function enoughFuel()
- if turtle.getFuelLevel() >= (64 * 8) then
- return true
- else
- return false
- end
- end
- --
- -- Check to see if we have enough fuel to keep going a little while longer
- -- Perhaps 6 slots out of 16 free is enough
- --
- function enoughFreeSpace()
- local slotsUsed = 0
- for i=1,16 do
- --turtle.select(i)
- if turtle.getItemCount(i) > 0 then
- slotsUsed = slotsUsed + 1
- end
- end
- turtle.select(1)
- if slotsUsed <= 10 then
- return true
- else
- return false
- end
- end
- -- Move forward 'blocks' number of blocks, digging when necessary
- -- Hitting bedrock or something undiggable like an entity (creature) will
- -- prevent forward movement, and attempts will be made to go around
- --
- -- Return actual blocks moved forward
- function moveForward(blocks)
- if blocks < 0 then return moveBack(0-blocks) end
- if blocks == 0 then return 0 end
- local moved = 0
- while moved < blocks do
- if turtle.forward() then -- air, nothing to dig, but go down
- moved = moved + 1
- elseif turtle.dig() then -- had to dig to go forwards
- if not turtle.forward() then
- local attempts = 0
- while turtle.dig() and attempts < 20 do
- attempts = attempts + 1 -- take care water won't cause infinite digging
- sleep(0.25) -- might have to chew through a stack of sand or gravel
- end
- if turtle.forward() then
- moved = moved + 1
- end
- else
- moved = moved + 1
- end
- else -- undiggable, give up (for now)
- return moved
- end
- sleep(0.25) -- sleep to avoid yielding error
- end
- return moved
- end
- -- Move downwards 'blocks' number of blocks, digging when necessary
- -- Hitting bedrock or something undiggable like an entity (creature) will
- -- prevent downwards movement, and attempts will be made to go around
- --
- -- Return actual blocks moved down
- function moveDown(blocks)
- if blocks < 0 then return moveUp(0-blocks) end
- if blocks == 0 then return 0 end
- local moved = 0
- while moved < blocks do
- if down() then -- air, nothing to dig, but go down
- moved = moved + 1
- elseif turtle.digDown() then -- had to dig to go down
- if not down() then
- while turtle.digDown() do end
- if down() then
- moved = moved + 1
- end
- else
- moved = moved + 1
- end
- else -- undiggable, give up (for now)
- return moved
- end
- sleep(0.25) -- sleep to avoid yielding error
- end
- return moved
- end
- -- Move upwards 'blocks' number of blocks, digging when necessary
- -- Hitting bedrock or something undiggable like an entity (creature) will
- -- prevent upwards movement, and attempts will be made to go around
- --
- -- Return actual blocks moved up
- function moveUp(blocks)
- if blocks < 0 then return moveDown(0-blocks) end
- if blocks == 0 then return 0 end
- local moved = 0
- while moved < blocks do
- if up() then -- air, nothing to dig, but go up
- moved = moved + 1
- elseif turtle.digUp() then -- dig up to go up
- if not up() then
- local attempts = 0
- while turtle.digUp() and attempts < 20 do
- attempts = attempts + 1 -- take care water won't cause infinite digging
- sleep(0.25) -- there may be a stack of sand or gravel above us, wait for it to fall
- end
- if up() then
- moved = moved + 1
- else -- try to go around
- assert( moveForward( 1 ) == 1 )
- assert( moveUp( 1 ) == 1 )
- assert( moveBack( 1 ) == 1 )
- moved = moved + 1
- end
- else
- moved = moved + 1
- end
- else -- undiggable, likely an entity (aka mob), try to go around
- assert( moveForward( 3 ) == 3 )
- assert( moveUp( 1 ) == 1 )
- assert( moveBack( 3 ) == 3 )
- moved = moved + 1
- end
- sleep(0.25) -- sleep to avoid yielding error
- end
- return moved
- end
- -- Move backwards, digging when necessary
- function moveBack(blocks)
- if blocks < 0 then return moveForward(0-blocks) end
- if blocks == 0 then return 0 end
- local moved = 0
- turtle.turnRight()
- turtle.turnRight()
- moved = moveForward(blocks)
- turtle.turnRight()
- turtle.turnRight()
- tForward = tForward - moved
- return moved
- end
- -- Move to the right, digging when necessary
- function moveRight(blocks)
- if blocks < 0 then return moveLeft(0-blocks) end
- if blocks == 0 then return 0 end
- local moved = 0
- turtle.turnRight()
- moved = moveForward(blocks)
- turtle.turnLeft()
- tRight = tRight + moved
- return moved
- end
- -- Move to the left, digging when necessary
- function moveLeft(blocks)
- if blocks < 0 then return moveRight(0-blocks) end
- if blocks == 0 then return 0 end
- local moved = 0
- turtle.turnLeft()
- moved = moveForward(blocks)
- turtle.turnRight()
- tRight = tRight - moved
- return moved
- end
- -- Preconditions:
- -- (1) Turtle is directly above bedrock and cannot go down further
- -- (2) Anything above turtle will be dug and is diggable
- -- (3) Return value is how many blocks up we moved
- --
- -- Note : the chunks I'm in have perfectly flat bedrock, so this extra code to handle uneven
- -- bedrock is commented out
- function bedrockForward()
- -- Largest delta between lowest possible bedrock and highest possible bedrock....right ?
- --local blocksUp = 4
- --assert( moveUp(blocksUp) == blocksUp )
- assert( moveForward(1) == 1 )
- --local movedDn = moveDown(blocksUp * 2) -- We might have been on top layer of bedrock
- --return blocksUp - movedDn
- return tonumber(0)
- end
- -- Dig straight down to bedrock or otherwise undiggable, then move forward 1, and dig straight up
- -- This is a 2 deep by 1 width by <as deep as we can go> shaft
- function downAndUp(maxDig)
- local bDn = tonumber(moveDown(maxDig))
- print( "downAndUp(), moved down ", bDn )
- bedrockForward()
- --print( "downAndUp(), bedworkForward() returned ", delta )
- local movedUp = moveUp(bDn)
- if movedUp ~= bDn then
- print( "downAndUp(), movedUp", movedUp, " ~= ", bDn )
- return false
- end
- return true
- end
- function usage()
- print( "Usage: quarry <blocks_forward> <blocks_right> [max depth] [start depth]" )
- print( "Forward must be at least 2 and right at least 1. Max depth must be at least 1 if specified." )
- end
- function parseArgs(args)
- local validSyntax = false
- local bForward = 0
- local bRight = 0
- local maxDig = 256
- local startDig = 0
- if #args < 2 or #args > 3 then
- return false
- elseif args[1] == "help" then
- return false
- elseif args[1] == nil or args[2] == nil then
- return false
- else
- bForward = tonumber( args[1] )
- bRight = tonumber( args[2] )
- if #args >= 3 then
- maxDig = tonumber( args[3] )
- end
- if #args == 4 then
- startDig = tonumber( args[4] )
- end
- if bForward < 2 or bRight < 1 or maxDig < 1 or startDig < 0 then
- validSyntax = false
- else
- validSyntax = true
- end
- end
- return validSyntax, bForward, bRight, maxDig, startDig
- end
- local tArgs = { ... }
- validSyntax, bForward, bRight, maxDig, startDig = parseArgs(tArgs)
- if not validSyntax then
- usage()
- return
- end
- print( "Quarrying ", bForward, " forward, ", bRight, " right ", maxDig, " layers down starting from ", startDig, " layers down." )
- local minFuelLevel = 1000
- local rLimit = bRight
- local fLimit = bForward
- local r = 0
- local f = 0
- while r < rLimit do
- while f + 1 < fLimit do
- --print( "1st r = ", r, " f = ", f, "rLimit = ", rLimit, " fLimit = ", fLimit )
- if not dropOffItems() then
- error( "Could not drop off items. Perhaps chest or other inventory is full." )
- end
- if not refuel( minFuelLevel ) then
- error( "Could not refuel to minimum level ", minFuelLevel, ". Please check fuel container." )
- end
- -- Optional feature to start the main part of the dig below the current level
- -- This serves two main benefits : keeping the current level (usually the ground level) intact
- -- and getting to the premium ores faster, if that is desired
- assert( moveDown( startDig ) == startDig )
- -- Traverse to the next dig coordinates
- assert( moveRight( r ) == r )
- assert( moveForward( f ) == f )
- -- The main part of the dig that goes all the way down, moves 1 forward, then comes straight back up
- while enoughFuel() and enoughFreeSpace() do
- -- Yield to avoid a "Too long without yielding" error !
- sleep(1)
- assert( downAndUp( maxDig ) )
- f = f + 1
- if f + 1 < fLimit then
- assert( moveForward( 1 ) )
- f = f + 1
- else
- break
- end
- end
- --print( "2nd r = ", r, " f = ", f, "rLimit = ", rLimit, " fLimit = ", fLimit )
- -- Traverse in the reverse direction from the dig coordinates
- assert( moveBack( f ) == f )
- assert( moveLeft( r ) == r )
- -- Come back up to the main level
- assert( moveUp( startDig ) == startDig )
- -- Yield to avoid a "Too long without yielding" error !
- sleep(1)
- end
- --print( "3rd r = ", r, " f = ", f, "rLimit = ", rLimit, " fLimit = ", fLimit )
- r = r + 1
- f = 0
- end
- -- The last drop-off !
- dropOffItems()
- print( "I have finished the assigned task, my master !" )
Add Comment
Please, Sign In to add comment