Last active
December 17, 2015 11:49
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --[[ | |
| 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 |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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