Skip to content

Instantly share code, notes, and snippets.

@tomjn
Last active December 17, 2015 11:49
Show Gist options
  • Select an option

  • Save tomjn/5605425 to your computer and use it in GitHub Desktop.

Select an option

Save tomjn/5605425 to your computer and use it in GitHub Desktop.
Computercraft excavate that digs 2 levels at a time, working on a third
--[[
TExcavate by Tom J Nowell
A modified version of the excavate command, mines 3 layers of rock at a time, and keeps persistent variables
requires: http://www.computercraft.info/forums2/index.php?/topic/1195-132-yet-another-persistent-variables-api-uses-metatable/
]]--
os.loadAPI("apis/persistentVar") -- Only use this line if you copied the API in your computers apis folder
local state = persistentVar:new( "/vars_texcavate/" )
local startup = persistentVar:new( "/vars_startup/" )
function reset_state_vars()
state.depth = 0
state.unloaded = 0
state.collected = 0
state.xPos =0
state.zPos = 0
state.xDir = 0
state.zDir = 1
end
if state.running ~= true then
local tArgs = { ... }
if #tArgs ~= 1 then
print( "Usage: advexcavate <diameter>" )
return
end
-- Mine in a quarry pattern until we hit something we can't dig
state.size = tonumber( tArgs[1] )
if state.size < 1 then
print( "Excavate diameter must be positive" )
return
end
else
state.running = true
startup.program = "texcavate"
reset_state_vars()
end
-- state.goTo -- Filled in further down
-- state.refuel -- Filled in further down
local function unload( _bKeepOneFuelStack )
print( "Unloading items..." )
local dropUp = false
if turtle.detect() then
dropUp = false
else
if turtle.detectUp() then
dropUp = true
end
end
for n=1,16 do
local nCount = turtle.getItemCount(n)
if nCount > 0 then
turtle.select(n)
local bDrop = true
if _bKeepOneFuelStack and turtle.state.refuel(0) then
bDrop = false
_bKeepOneFuelStack = false
end
if bDrop then
local result = false
while result == false do
if dropUp then
result = turtle.dropUp()
else
result = turtle.drop()
end
end
state.unloaded = state.unloaded + nCount
end
end
end
state.collected = 0
turtle.select(1)
end
local function returnSupplies()
local x,y,z,xd,zd = state.xPos,state.depth,state.zPos,state.xDir,state.zDir
print( "Returning to surface..." )
state.goTo( 0,0,0,0,-1 )
local fuelNeeded = 2*(x+y+z) + 1
if not state.refuel( fuelNeeded ) then
unload( true )
print( "Waiting for fuel" )
while not state.refuel( fuelNeeded ) do
sleep(1)
end
else
unload( true )
end
print( "Resuming mining..." )
state.goTo( x,y,z,xd,zd )
end
local function collect()
local bFull = true
local nTotalItems = 0
for n=1,16 do
local nCount = turtle.getItemCount(n)
if nCount == 0 then
bFull = false
end
nTotalItems = nTotalItems + nCount
end
if nTotalItems > state.collected then
state.collected = nTotalItems
if math.fmod(state.collected + state.unloaded, 50) == 0 then
print( "Mined "..(state.collected + state.unloaded).." items." )
end
end
if bFull then
print( "No empty slots left." )
return false
end
return true
end
function state.refuel( ammount )
local fuelLevel = turtle.getFuelLevel()
if fuelLevel == "unlimited" then
return true
end
local needed = ammount or (state.xPos + state.zPos + state.depth + 1)
if turtle.getFuelLevel() < needed then
local fueled = false
for n=1,16 do
if turtle.getItemCount(n) > 0 then
turtle.select(n)
if turtle.state.refuel(1) then
while turtle.getItemCount(n) > 0 and turtle.getFuelLevel() < needed do
turtle.state.refuel(1)
end
if turtle.getFuelLevel() >= needed then
turtle.select(1)
return true
end
end
end
end
turtle.select(1)
return false
end
return true
end
local function tryForwards()
if not state.refuel() then
print( "Not enough Fuel" )
returnSupplies()
end
if turtle.detectDown() then
turtle.digDown()
end
if state.depth > 0 then
if turtle.detectUp() then
turtle.digUp()
end
end
while not turtle.forward() do
if turtle.detect() or turtle.detectDown() then
local dug = false
dug = turtle.dig()
dugdown = turtle.digDown()
dugup = turtle.digUp()
dugboth = dug or dugdown or dugup
if dugboth then
if not collect() then
returnSupplies()
end
else
if not dug then
return false
end
end
elseif turtle.attack() then
if not collect() then
returnSupplies()
end
else
sleep( 0.1 )
end
end
state.xPos = state.xPos + state.xDir
state.zPos = state.zPos + state.zDir
return true
end
local function tryDown()
if not state.refuel() then
print( "Not enough Fuel" )
returnSupplies()
end
if state.depth > 0 then
if turtle.detectUp() then
if turtle.digUp() then
if not collect() then
returnSupplies()
end
end
end
end
while not turtle.down() do
if turtle.detectDown() then
if turtle.digDown() then
if not collect() then
returnSupplies()
end
else
return false
end
elseif turtle.attackDown() then
if not collect() then
returnSupplies()
end
else
sleep( 0.2 )
end
end
state.depth = state.depth + 1
if math.fmod( state.depth, 10 ) == 0 then
print( "Descended "..state.depth.." metres." )
end
return true
end
local function turnLeft()
turtle.turnLeft()
state.xDir, state.zDir = -state.zDir, state.xDir
end
local function turnRight()
turtle.turnRight()
state.xDir, state.zDir = state.zDir, -state.xDir
end
function state.goTo( x, y, z, xd, zd )
while state.depth > y do
if turtle.up() then
state.depth = state.depth - 1
elseif turtle.digUp() or turtle.attackUp() then
collect()
else
sleep( 0.5 )
end
end
if state.xPos > x then
while state.xDir ~= -1 do
turnLeft()
end
while state.xPos > x do
if turtle.forward() then
state.xPos = state.xPos - 1
elseif turtle.dig() or turtle.attack() then
collect()
else
sleep( 0.5 )
end
end
elseif state.xPos < x then
while state.xDir ~= 1 do
turnLeft()
end
while state.xPos < x do
if turtle.forward() then
state.xPos = state.xPos + 1
elseif turtle.dig() or turtle.attack() then
collect()
else
sleep( 0.5 )
end
end
end
if state.zPos > z then
while state.zDir ~= -1 do
turnLeft()
end
while state.zPos > z do
if turtle.forward() then
state.zPos = state.zPos - 1
elseif turtle.dig() or turtle.attack() then
collect()
else
sleep( 0.5 )
end
end
elseif state.zPos < z then
while state.zDir ~= 1 do
turnLeft()
end
while state.zPos < z do
if turtle.forward() then
state.zPos = state.zPos + 1
elseif turtle.dig() or turtle.attack() then
collect()
else
sleep( 0.5 )
end
end
end
while state.depth < y do
if turtle.down() then
state.depth = state.depth + 1
elseif turtle.digDown() or turtle.attackDown() then
collect()
else
sleep( 0.5 )
end
end
while state.zDir ~= zd or state.xDir ~= xd do
turnLeft()
end
end
if not state.refuel() then
print( "Out of Fuel" )
return
end
print( "Excavating..." )
local reseal = false
turtle.select(1)
if turtle.digDown() then
reseal = true
end
local alternate = 0
local done = false
while not done do
for n=1,state.size do
for m=1,state.size-1 do
if not tryForwards() then
done = true
break
end
end
if done then
break
end
if n<state.size then
if math.fmod(n + alternate,2) == 0 then
turnLeft()
if not tryForwards() then
done = true
break
end
turnLeft()
else
turnRight()
if not tryForwards() then
done = true
break
end
turnRight()
end
end
end
if done then
break
end
if state.size > 1 then
if math.fmod(state.size,2) == 0 then
turnRight()
else
if alternate == 0 then
turnLeft()
else
turnRight()
end
alternate = 1 - alternate
end
end
for i=1, 3, 1 do
if not tryDown() then
done = true
break
end
end
end
print( "Returning to surface..." )
-- Return to where we started
state.goTo( 0,0,0,0,-1 )
unload( false )
state.goTo( 0,0,0,0,1 )
-- Seal the hole
if reseal then
turtle.placeDown()
end
print( "Mined "..(state.collected + state.unloaded).." items total." )
reset_state_vars()
state.running = false
startup.program = nil
@tomjn
Copy link
Author

tomjn commented May 20, 2013

note that revision 2 has issues stemming from the persistent variables API, need to research a new one, and consider a wrapper API for the various variables

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment