Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local robot = require('robot')
- local computer = require('computer')
- local c = require('component')
- local ic = c.inventory_controller
- local event = require('event')
- local sides = require('sides')
- local r = require('refuel')
- local tArgs = { ... }
- if #tArgs ~= 1 and #tArgs~=6 then
- print( "Usage: excavate <diameter> " )
- return
- end
- -- Mine in a quarry pattern until we hit something we can't dig
- local size = tonumber( tArgs[1] )
- if size < 1 then
- print( "Excavate diameter must be positive" )
- return
- end
- ------------------Configurations-------------------------
- local usableTool = "Pickaxe"
- local minToolDamage = 100 -- No point going out with a tool that is just going to break on the nth swing
- local minEnergyReserve = 1000
- local wallTile = {['Black Stained Glass']=true}
- local ceilingTile = {['Stone']=true}
- local floorTile = {['Granite']=true}
- -------------------Inits-----------------------------
- local depth = 0
- local unloaded = 0
- local collected = 0
- local xPos,zPos = 0,0
- local xDir,zDir = 0,1
- local goTo -- Filled in further down
- local generator = c.isAvailable('generator')
- local invSize = robot.inventorySize()
- local isChest = false
- local consumptionRates = {
- running = 0.25*1,
- break_block = 0.025*10,
- move = 10*1+8.035555556*0.25,
- turn = 2.5*1+8.0194444*0.25,
- }
- ----------------------Functions-----------------------
- local function unload( --[[TODO _bKeepOneFuelStack ]])
- print( "Unloading items..." )
- for n=1,invSize do
- local nCount = robot.count(n)
- if nCount > 0 then
- robot.select(n)
- local bDrop = true
- if bDrop then
- robot.drop()
- unloaded = unloaded + nCount
- end
- end
- end
- collected = 0
- robot.select(1)
- end
- local function requiredEnergy(nTrips)
- --[[
- Determine if there is a generator upgrade
- if there is, make sure there are items in generator
- else check Energy Levels and return to charger
- if enough fuel return true
- ]]
- nTrips = nTrips or 1
- local moves = math.abs(xPos) + math.abs(zPos) + math.abs(depth)
- local turns = math.abs(1-xDir+zDir)
- local requirements = nTrips * (moves * consumptionRates.move) + (turns * consumptionRates.turn) + consumptionRates.move + minEnergyReserve
- local energy = computer.energy()
- -- if there is enough fuel to cover the return trip return true
- if requirements > energy then
- local x, y, z, xd, zd = xPos, depth, zPos, xDir, zDir
- print( "Not enough Fuel" )
- goTo(0,0,0,0,-1)
- unload()
- r.refuel()
- os.sleep(60)
- goTo(x, y, z, xd, zd)
- end
- end
- local function getSupplies()
- local x, y, z, xd, zd = xPos, depth, zPos, xDir, zDir
- print("Getting Supplies. \nIm at "..x, y, z, xd, zd)
- goTo(0,0,0,0,-1)
- if ic.getInventorySize(sides.front) then isChest = true end
- --Combine the Tiles tables
- if isChest then
- print("dump chest found")
- local tileLists = {wallTile, ceilingTile, floorTile}
- local needsList = {}
- local chestSize = ic.getInventorySize(sides.front)
- for k,v in pairs(tileLists) do
- for a,b in pairs(v) do
- needsList[a] = true
- end
- end
- print("needslist",needsList)
- --for each unique type of block get 1 stack or maxAvailable
- repeat
- print("cycling needed items")
- for a,b in pairs(needsList) do
- print("item: ".. tostring(a))
- local n =1
- for i=1,chestSize do
- local stack = ic.getStackInSlot(sides.front, i)
- if stack then
- if stack.label == a then
- ic.suckFromSlot(sides.front, i)
- table.remove(needsList, n)
- break
- end
- end
- end
- n = n+1
- end
- os.sleep(5)
- until (#needsList==0)
- print("finished gathering supplies. Headed back to "..x,y,z,xd,zd)
- goTo(x,y,z,xd,zd)
- else
- print("no dump chest found")
- goTo(x,y,z,xd,zd)
- return false
- end
- end
- local function returnSupplies()
- local x, y, z, xd, zd = xPos,depth,zPos,xDir,zDir
- print( "Returning to surface..." )
- goTo( 0,0,0,0,-1 )
- unload()
- if not done then getSupplies() end
- print( "Resuming mining..." )
- goTo(x, y, z, xd, zd)
- end
- local function collect()
- local bFull = true
- local nTotalItems = 0
- local nCount = 0
- for n=1,invSize do
- local stack = ic.getStackInInternalSlot(n)
- if not stack then
- -- get Item count (nCount)
- bFull = false
- else
- local nCount = stack.size
- end
- nTotalItems = nTotalItems + nCount
- end
- if nTotalItems > collected then
- collected = nTotalItems
- if math.fmod(collected + unloaded, 50) == 0 then
- print( "Mined "..(collected + unloaded).." items." )
- end
- end
- if bFull then
- print( "No empty slots left." )
- return false
- end
- return true
- end
- local function reTool()
- local x,y,z,xd,zd = xPos,depth,zPos,xDir,zDir
- print("Pickaxe is broken, looking for replacement")
- local dur, msg = robot.durability()
- if not dur then dur =0 end
- local retool = false
- if dur>=0.1then retool = true end
- --cycle through local inventory to find a pickaxe
- print("Looking internally: ")
- if not retool then
- for i = 1, invSize do
- local stack = ic.getStackInInternalSlot(i)
- if stack and not retool then
- if string.find(stack.label, usableTool) and
- stack.maxDamage-stack.damage>=minToolDamage then
- robot.select(i)
- retool, msg = ic.equip()
- robot.select(1)
- dur, msg = robot.durability()
- retool = true
- return
- end
- end
- end
- --Go back to origin point and look in the chest
- goTo(0,0,0,0,-1)
- unload()
- local chestSize = ic.getInventorySize(sides.front)
- if chestSize then
- for i = 1, chestSize do
- local stack = ic.getStackInSlot(sides.front,i)
- if stack and not retool then
- if string.find(stack.label, usableTool) and
- stack.maxDamage-stack.damage>=minToolDamage then
- ic.suckFromSlot(sides.front,i)
- retool, msg = ic.equip()
- dur, msg = robot.durability()
- end
- end
- end
- end
- --Wait for a tool to be added to the internal inventory
- while dur<0.1 and not retool do
- print("require a new tool")
- local bTool, toolSlot = event.pull(1, "inventory_change")
- if toolSlot then ic.equip(toolSlot) end
- dur, msg = robot.durability()
- if not dur then dur = 0 end
- if dur>=0.1 then
- retool = true
- goTo(x, y, z, xd, zd)
- return
- end
- os.sleep(1)
- end
- end
- print('All equipped up and ready to go')
- end
- local function checkPlace(dir)
- local dir = dir or 'f'
- local dirActions = {
- ['u']={ceilingTile, robot.detectUp, robot.placeUp},
- ['d']={floorTile, robot.detectDown, robot.placeDown},
- ['f']={wallTile, robot.detect, robot.place},
- }
- for i = 1, invSize do
- stack = ic.getStackInInternalSlot(i)
- if stack then
- if dirActions[dir][1][stack.label] then
- robot.select(i)
- dirActions[dir][3]()
- robot.select(1)
- return true
- end
- end
- end
- return false
- end
- local function tryForwards()
- requiredEnergy()
- if not robot.durability() or robot.durability()<0.1 then
- reTool()
- end
- local dtct, msg = robot.detect()
- while dtct do
- if robot.swing() then
- if not collect() then
- returnSupplies()
- end
- else
- return false
- end
- dtct, msg = robot.detect()
- end
- if robot.forward() then
- xPos = xPos + xDir
- zPos = zPos + zDir
- end
- return true
- end
- local function tryDown()
- requiredEnergy()
- if not robot.durability() or robot.durability()<0.1 then
- reTool()
- end
- while not robot.down() do
- local block, dMsg = robot.detectDown()
- if block then
- if dMsg=="solid" then
- local action, aMsg = robot.swingDown()
- if action then
- else
- if not collect() then returnSupplies() end
- if aMsg == "block" then return false end
- end
- elseif dMsg == 'entity' then
- robot.swingDown()
- if not collect() then
- returnSupplies()
- end
- end
- else
- os.sleep( 0.5 )
- end
- end
- depth = depth + 1
- if math.fmod( depth, 10 ) == 0 then
- print( "Descended "..depth.." metres." )
- end
- return true
- end
- local function turnLeft()
- robot.turnLeft()
- xDir, zDir = -zDir, xDir
- end
- local function turnRight()
- robot.turnRight()
- xDir, zDir = zDir, -xDir
- end
- local function sealOutside(dir)
- if dir=="left" then
- turnLeft()
- print("place wallTile: ".. tostring(checkPlace("f")))
- turnRight()
- elseif dir=="right" then
- turnLeft()
- print("place wallTile: ".. tostring(checkPlace("f")))
- turnRight()
- end
- end
- function goTo( x, y, z, xd, zd )
- if depth>y then
- if robot.up() then
- depth = depth - 1
- elseif robot.swingUp() then
- collect()
- else
- sleep( 0.5 )
- end
- end
- while depth < y - 1 do
- if robot.down() then
- depth = depth + 1
- elseif robot.swing() then
- collect()
- else
- os.sleep( 0.5 )
- end
- end
- if xPos > x then
- while xDir ~= -1 do
- turnLeft()
- end
- while xPos > x do
- if robot.forward() then
- xPos = xPos - 1
- elseif robot.swing() then
- collect()
- else
- os.sleep( 0.5 )
- end
- end
- elseif xPos < x then
- while xDir ~= 1 do
- turnLeft()
- end
- while xPos < x do
- if robot.forward() then
- xPos = xPos + 1
- elseif robot.swing() then
- collect()
- else
- os.sleep( 0.5 )
- end
- end
- end
- if zPos > z then
- while zDir ~= -1 do
- turnLeft()
- end
- while zPos > z do
- if robot.forward() then
- zPos = zPos - 1
- elseif robot.swing() then
- collect()
- else
- os.sleep( 0.5 )
- end
- end
- elseif zPos < z then
- while zDir ~= 1 do
- turnLeft()
- end
- while zPos < z do
- if robot.forward() then
- zPos = zPos + 1
- elseif robot.swing() then
- collect()
- else
- os.sleep( 0.5 )
- end
- end
- end
- if depth<y then
- if robot.down() then
- depth = depth + 1
- elseif robot.swingDown() then
- collect()
- else
- sleep( 0.5 )
- end
- end
- while depth > y do
- if robot.up() then
- depth = depth - 1
- elseif robot.swingUp() then
- collect()
- else
- sleep( 0.5 )
- end
- end
- while zDir ~= zd or xDir ~= xd do
- turnLeft()
- end
- end
- ----------------------MAIN-----------------------------
- robot.select(1)
- --Check for adequate energy, tools, and supplies
- getSupplies()
- requiredEnergy(2)
- print(reTool())
- ---Use and optional starting position
- if #tArgs==6 then
- print("6 arguments preparing to move")
- local x, y, z, xd, zd = tonumber(tArgs[2]), tonumber(tArgs[3]), tonumber(tArgs[4]), tonumber(tArgs[5]), tonumber(tArgs[6])
- goTo(x, y, z, xd, zd)
- xPos, depth, zPos, xDir, zDir = x, y, z, xd, zd
- end
- print( "Excavating..." )
- local alternate = 0
- local done = false
- while not done do
- for n=1,size do
- for m=1,size-1 do
- print('n: '..n, 'm: '..m)
- if (n==1 or n==size) then
- print("Im in an outside row..."..n)
- --- turn to the outside and detect and place
- --if n is odd turn left
- --else turn right
- if n ==1 then
- sealOutside("left")
- elseif math.fmod(n + alternate,2) == 0 then
- sealOutside("left")
- else
- sealOutside("right")
- end
- end
- if not tryForwards() then
- done = true
- break
- end
- if m==size-1 then
- checkPlace('f')
- end
- end
- if done then
- break
- end
- if n<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 size > 1 then
- if math.fmod(size,2) == 0 then
- turnRight()
- else
- if alternate == 0 then
- turnLeft()
- else
- turnRight()
- end
- alternate = 1 - alternate
- end
- end
- if not tryDown() then
- done = true
- break
- end
- end
- print( "Returning to surface... from "..xPos, depth, zPos, xDir, zDir )
- -- Return to where we started
- goTo( 0,0,0,0,-1 )
- unload( false )
- goTo( 0,0,0,0,1 )
- print( "Mined "..(collected + unloaded).." items total." )
- computer.shutdown()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement