Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local args = { ... }
- local length = 0
- local width = 0
- local height = 1
- local dumpInventory = true
- local posX = -1 -- Relative distance from the starting corner. We start one block outside of the area.
- local posZ = 0
- local posY = 0
- local orientation = 0 -- 0: starting orientation; 1: right; 2: back; 3: left
- local doneRows = 0 -- Already cleared area on the current layer
- local doneLayers = 0 -- Already cleared layers
- local smallerDimension = 0
- local largerDimension = 0
- local tunnelingDirection = 0 -- Direction that the tunnels will be dug (axis)
- local nextTunnelDirection = 0 -- The direction of the next tunnel (alternates with +-2 when going back and forth)
- local tunnelingOrder = 0 -- In which direction are we creating the new tunnels (= the direction perpendicular to the tunnels)
- local distanceTraveled = 0 -- Total distance moved
- local numBlocks = 0 -- Total number of blocks mined
- local numAttacks = 0 -- Total number of times that we attacked mobs
- if #args < 1 then
- print("Usage: progname <length> [width] [height] [dumpInventory (true|false)]")
- return
- end
- length = tonumber( args[1] )
- if #args >= 2 then
- width = tonumber( args[2] )
- else
- width = length
- end
- if #args >= 3 then
- height = tonumber( args[3] )
- end
- if #args >= 4 then
- dumpInventory = args[4]
- end
- if length < 1 then
- print("Error: Length must be at least 1")
- return
- end
- if width < 1 then
- print("Error: Width must be at least 1")
- return
- end
- if height < 1 then
- print("Error: Height must be at least 1")
- return
- end
- -- Dump the contents of the inventory into a chest
- function dumpInventory()
- -- If there is a block behind the starting position, assume it is a chest
- -- and dump the inventory to it.
- if turtle.detect() == true then
- for i = 1, 16 do
- local num = turtle.getItemCount(i)
- if num > 0 then
- turtle.select(i)
- local filterNum = 0
- local dropNum = num
- -- We are currently handling the filter slots
- if i <= numFilters then
- dropNum = num - 1
- filterNum = i
- else
- -- Get the filter slot number that corresponds to the current slot's item type
- for j = 1, numFilters do
- if turtle.compareTo(j) == true then
- filterNum = j
- break
- end
- end
- end
- if turtle.drop(dropNum) == false then
- return false
- end
- -- Update the item counters
- invNumBlocksTotal = invNumBlocksTotal - dropNum
- invNumBlocksType[filterNum] = invNumBlocksType[filterNum] - dropNum
- -- Not a filter slot, so we dropped all of the items in that slot
- if dropNum == num then
- invNumEmptySlots = invNumEmptySlots + 1
- end
- end
- end
- end
- return true
- end
- -- Dig the block in front of the turtle until no block is detected anymore
- function digUntilClear(face)
- if face == nil then
- face = "front"
- end
- if face == "up" then
- -- If there is a block above, dig it. Loop in case of falling sand/gravel.
- while turtle.detectUp() == true do
- if turtle.digUp() == true then
- numBlocks = numBlocks + 1
- else
- print("digUntilClear(\"up\"): Could not dig the block above! Aborting...")
- return false
- end
- sleep(0.5)
- end
- elseif face == "down" then
- -- If there is a block below, dig it.
- while turtle.detectDown() == true do
- if turtle.digDown() == true then
- numBlocks = numBlocks + 1
- else
- print("digUntilClear(\"down\"): Could not dig the block below! Aborting...")
- return false
- end
- -- sleep(0.5)
- end
- else -- front
- -- If there is a block in front, dig it. Loop in case of falling sand/gravel.
- while turtle.detect() == true do
- if turtle.dig() == true then
- numBlocks = numBlocks + 1
- else
- print("digUntilClear(): Could not dig the block in front! Aborting...")
- return false
- end
- sleep(0.5)
- end
- end
- return true
- end
- -- Attack as long as the attack succeeds (= mobs in front)
- function attackUntilClear()
- local tmp1 = 0
- -- Attack if there are mobs in front of the turtle
- while turtle.attack() == true do
- numAttacks = numAttacks + 1
- -- Failsafe limit
- tmp1 = tmp1 + 1
- if tmp1 > 100 then
- print("attackUntilClear(): Hit the failsafe limit (100) of attacks!")
- return false
- end
- end
- return true
- end
- -- Attack as long as the attack succeeds (= mobs above)
- function attackUpUntilClear()
- local tmp1 = 0
- -- Attack if there are mobs in front of the turtle
- while turtle.attackUp() == true do
- numAttacks = numAttacks + 1
- -- Failsafe limit
- tmp1 = tmp1 + 1
- if tmp1 > 100 then
- print("attackUpUntilClear(): Hit the failsafe limit (100) of attacks!")
- return false
- end
- end
- return true
- end
- -- Attack as long as the attack succeeds (= mobs above)
- function attackDownUntilClear()
- local tmp1 = 0
- -- Attack if there are mobs in front of the turtle
- while turtle.attackDown() == true do
- numAttacks = numAttacks + 1
- -- Failsafe limit
- tmp1 = tmp1 + 1
- if tmp1 > 100 then
- print("attackDownUntilClear(): Hit the failsafe limit (100) of attacks!")
- return false
- end
- end
- return true
- end
- -- Move forward dist blocks
- function moveForward(dist)
- local tmp2 = 0
- if dist <= 0 then
- return true
- end
- for i = 1, dist do
- tmp2 = 0
- -- Attack while we can't move forward (because someONE is blocking us)
- while turtle.forward() == false do
- if attackUntilClear() == false then
- print("moveForward(dist = " .. dist .. "): attackUntilClear() returned false")
- return false
- end
- -- Failsafe limit
- tmp2 = tmp2 + 1
- if tmp2 > 100 then
- print("moveForward(dist = " .. dist .. "): Hit the failsafe limit (100) of trying to move")
- return false
- end
- end
- if orientation == 0 then
- posX = posX + 1
- elseif orientation == 1 then
- posZ = posZ + 1
- elseif orientation == 2 then
- posX = posX - 1
- elseif orientation == 3 then
- posZ = posZ - 1
- else
- print("moveForward(dist = " .. dist .. "): Invalid orientation!")
- return false
- end
- distanceTraveled = distanceTraveled + 1
- end
- return true
- end
- function moveUp(dist)
- local tmp2 = 0
- if dist <= 0 then
- return true
- end
- for i = 1, dist do
- tmp2 = 0
- -- Attack while we can't move forward (because someONE is blocking us)
- while turtle.up() == false do
- if attackUpUntilClear() == false then
- print("moveUp(dist = " .. dist .. "): attackUpUntilClear() returned false")
- return false
- end
- -- Failsafe limit
- tmp2 = tmp2 + 1
- if tmp2 > 100 then
- print("moveUp(dist = " .. dist .. "): Hit the failsafe limit (100) of trying to move")
- return false
- end
- end
- posY = posY - 1
- distanceTraveled = distanceTraveled + 1
- end
- return true
- end
- function moveDown(dist)
- local tmp2 = 0
- if dist <= 0 then
- return true
- end
- for i = 1, dist do
- tmp2 = 0
- -- Attack while we can't move forward (because someONE is blocking us)
- while turtle.down() == false do
- if attackDownUntilClear() == false then
- print("moveDown(dist = " .. dist .. "): attackDownUntilClear() returned false")
- return false
- end
- -- Failsafe limit
- tmp2 = tmp2 + 1
- if tmp2 > 100 then
- print("moveDown(dist = " .. dist .. "): Hit the failsafe limit (100) of trying to move")
- return false
- end
- end
- posY = posY + 1
- distanceTraveled = distanceTraveled + 1
- end
- return true
- end
- function turnRight()
- turtle.turnRight()
- if orientation == 3 then
- orientation = 0
- else
- orientation = orientation + 1
- end
- end
- function turnLeft()
- turtle.turnLeft()
- if orientation == 0 then
- orientation = 3
- else
- orientation = orientation - 1
- end
- end
- function reOrient(dir)
- if dir == orientation then
- return true
- end
- if dir > orientation then
- if (dir - orientation) <= 2 then
- while orientation ~= dir do
- turnRight()
- end
- else
- while orientation ~= dir do
- turnLeft()
- end
- end
- else -- orientation >= dir
- if (orientation - dir) <= 2 then
- while orientation ~= dir do
- turnLeft()
- end
- else
- while orientation ~= dir do
- turnRight()
- end
- end
- end
- return true
- end
- function digAndMoveUp(dist)
- if dist <= 0 then return true end
- for i = 1, dist do
- if digUntilClear("up") == false then
- print("digAndMoveUp(dist = " .. dist .. "): digUntilClear(\"up\") (i = " .. i .. ")")
- return false
- end
- if moveUp(1) == false then
- print("digAndMoveUp(dist = " .. dist .. "): moveUp(1) (i = " .. i .. ")")
- return false
- end
- end
- return true
- end
- function digAndMoveDown(dist)
- if dist <= 0 then return true end
- for i = 1, dist do
- if digUntilClear("down") == false then
- print("digAndMoveDown(dist = " .. dist .. "): digUntilClear(\"down\") (i = " .. i .. ")")
- return false
- end
- if moveDown(1) == false then
- print("digAndMoveDown(dist = " .. dist .. "): moveDown(1) (i = " .. i .. ")")
- return false
- end
- end
- return true
- end
- -- Dig and move forward in a straight line (1 high)
- function digAndMoveForward1W(len, ud)
- if len <= 0 then return true end
- if ud == nil then ud = "none" end
- for i = 1, len do
- if digUntilClear() == false then
- print("digAndMoveForward1W(len = " .. len .. ", ud = \"" .. ud .. "\"): digUntilClear() (i = " .. i .. ")")
- return false
- end
- if moveForward(1) == false then
- print("digAndMoveForward1W(len = " .. len .. ", ud = \"" .. ud .. "\): moveForward(1) (i = " .. i .. ")")
- return false
- end
- if ud == "up" or ud == "both" then
- if digUntilClear("up") == false then
- print("digAndMoveForward1W(len = " .. len .. ", ud = \"" .. ud .. "\): digUntilClear(\"up\") (i = " .. i .. ")")
- return false
- end
- end
- if ud == "down" or ud == "both" then
- if digUntilClear("down") == false then
- print("digAndMoveForward1W(len = " .. len .. ", ud = \"" .. ud .. "\): digUntilClear(\"down\") (i = " .. i .. ")")
- return false
- end
- end
- end
- return true
- end
- -- Move to the requested X coordinate
- function moveToX(X)
- if X < posX then
- reOrient(2)
- if digAndMoveForward1W(posX - X, "none") == false then
- print("moveToX(): digAndMoveForward1W(posX - X = " .. (posX - X) .. ", \"none\")")
- return false
- end
- elseif posX < X then
- reOrient(0)
- if digAndMoveForward1W(X - posX, "none") == false then
- print("moveToX(): digAndMoveForward1W(X - posX = " .. (X - posX) .. ", \"none\")")
- return false
- end
- end
- return true
- end
- -- Move to the requested Z coordinate
- function moveToZ(Z)
- if Z < posZ then
- reOrient(3)
- if digAndMoveForward1W(posZ - Z, "none") == false then
- print("moveToZ(): digAndMoveForward1W(posZ - Z = " .. (posZ - Z) .. ", \"none\")")
- return false
- end
- elseif posZ < Z then
- reOrient(1)
- if digAndMoveForward1W(Z - posZ, "none") == false then
- print("moveToZ(): digAndMoveForward1W(Z - posZ = " .. (Z - posZ) .. ", \"none\")")
- return false
- end
- end
- return true
- end
- -- Move to the requested Y coordinate
- function moveToY(Y)
- if Y < posY then
- if digAndMoveUp(posY - Y) == false then
- print("moveToY(): digAndMoveUp(posY - Y = " .. (posY - Y) .. ")")
- return false
- end
- elseif posY < Y then
- if digAndMoveDown(Y - posY) == false then
- print("moveToY(): digAndMoveDown(Y - posY = " .. (Y - posY) .. ")")
- return false
- end
- end
- return true
- end
- -- Get the tunnel axis direction
- -- The tunnels will be dug along the longer dimension,
- -- so that we can avoid unnecessary zig-zag motion.
- -- This only needs to be called once
- function getTunnelingDirection()
- if width > length then
- return 1
- end
- return 0
- end
- -- Get the next tunnel's digging direction
- -- This should be called when moving to position for the next tunnel
- function getNextTunnelDirection()
- -- Tunnels go along the X-axis: diggingDirection is 0 or 2
- if tunnelingDirection == 0 then
- -- We are closer to the starting corner than the back corner in X-direction
- if posX <= (length - 1 - posX) then
- return 0
- else
- return 2
- end
- else -- Tunnels go along the Z-axis: diggingDirection is 1 or 3
- -- We are closer to the starting corner than the back corner in Z-direction
- if posZ <= (width - 1 - posZ) then
- return 1
- else
- return 3
- end
- end
- return false
- end
- -- Get tunneling order (starting from the front or the back end of the area?)
- -- This should be called when starting a new layer (Y-coordinate changes)
- function getTunnelingOrder()
- -- Tunnels go along the X-axis: diggingDirection is 0 or 2
- if tunnelingDirection == 0 then
- -- We are closer to the starting corner than the back corner in X-direction
- if posZ <= (width - 1 - posZ) then
- return 1
- else
- return 3
- end
- else -- Tunnels go along the Z-axis: diggingDirection is 1 or 3
- -- We are closer to the starting corner than the back corner in Z-direction
- if posX <= (length - 1 - posX) then
- return 0
- else
- return 2
- end
- end
- return false
- end
- -- Move to the starting position for the next tunnel (so that the tunnel
- -- will align with the already dug area)
- function moveToTunnelStartPosVertical()
- local Z = 0
- local X = 0
- -- Tunnels along the X-axis
- if tunnelingDirection == 0 then
- -- Tunnels go from the starting corner to the right
- if tunnelingOrder == 1 then
- Z = doneRows
- else -- Tunnels go from the right towards the starting corner
- Z = width - doneRows - 1
- end
- moveToZ(Z)
- else -- Tunnels along the Z-axis
- -- Tunnels go from the starting corner towards the back
- if tunnelingOrder == 0 then
- X = doneRows -- one block into the undug part
- else -- Tunnels go from the back towards the starting corner
- X = length - doneRows - 1 -- one block into the undug part
- end
- moveToX(X)
- end
- if height > (doneLayers + 2) then
- moveToY(doneLayers + 1)
- else
- moveToY(doneLayers)
- end
- -- Clear the block above and/or below
- if posY > 0 then
- digUntilClear("up")
- end
- if posY < (height - 1) then
- digUntilClear("down")
- end
- return true
- end
- function digTunnelVertical(len)
- -- At least 3 layers to go
- if doneLayers < (height - 2) then
- digAndMoveForward1W(len, "both")
- elseif doneLayers == (height - 2) then
- digAndMoveForward1W(len, "down")
- elseif doneLayers == (height - 1) then
- digAndMoveForward1W(len, "none")
- else
- print("Error: digTunnelVertical(len = " .. len .. "): We are done already?")
- return false
- end
- return true
- end
- -- Select the first slot so that the items get filled to the inventory starting from the first slot
- turtle.select(1)
- -- Corner case check: only dig the one block if the area is 1x1.
- if length == 1 and width == 1 then
- digUntilClear()
- doneRows = 1
- else -- normal, larger than 1x1 areas: move to the starting corner 0, 0
- moveToX(0)
- end
- if length >= width then
- smallerDimension = width
- largerDimension = length
- else
- smallerDimension = length
- largerDimension = width
- end
- tunnelingDirection = getTunnelingDirection()
- tunnelingOrder = getTunnelingOrder()
- -- Dig the area
- while doneLayers < height do
- while (smallerDimension - doneRows) > 0 do
- nextTunnelDirection = getNextTunnelDirection()
- print("posX: " .. posX)
- print("posZ: " .. posZ)
- print("posY: " .. posY)
- print("tunnelingDirection: " .. tunnelingDirection)
- print("tunnelingOrder: " .. tunnelingOrder)
- print("nextTunnelDirection: " .. nextTunnelDirection)
- moveToTunnelStartPosVertical()
- reOrient(nextTunnelDirection)
- digTunnelVertical(largerDimension - 1)
- doneRows = doneRows + 1
- end
- -- We dig 3 layers at a time until there is less than that left
- if doneLayers <= (height - 3) then
- doneLayers = doneLayers + 3
- else
- doneLayers = height
- end
- if doneLayers >= height then
- break
- end
- -- We dig 3 layers at a time until there is less than that left
- if doneLayers <= (height - 3) then
- -- Dig down three blocks, we are starting the next 3 blocks high layer
- digAndMoveDown(3)
- else
- -- Less than 3 blocks to go, we dig one block into the undug part
- digAndMoveDown(2)
- end
- -- Clear the block below, if we are not at the bottom most Y position already
- if posY < (height - 1) then
- digUntilClear("down")
- end
- doneRows = 0
- --tunnelingOrder = getTunnelingOrder()
- tunnelingOrder = (tunnelingOrder + 2) % 4
- end
- -- Return to the starting corner
- if length > 1 or width > 1 then
- -- Return to the starting level
- if moveToY(0) == false then
- print("Error while returning to the starting corner (Y)")
- return false
- end
- -- Return to the starting corner
- if orientation == 0 or orientation == 3 then
- if moveToZ(0) == false then
- print("Error while returning to the starting corner (Z)")
- return false
- end
- if moveToX(0) == false then
- print("Error while returning to the starting corner (X)")
- return false
- end
- else
- if moveToX(0) == false then
- print("Error while returning to the starting corner (X)")
- return false
- end
- if moveToZ(0) == false then
- print("Error while returning to the starting corner (Z)")
- return false
- end
- end
- end
- -- Return to the starting position
- if posX == 0 then
- reOrient(2)
- if digAndMoveForward1W(1, "none") == false then
- print("digAndMoveForward1W(1, \"none\"): Error while trying to move to the starting corner of the area")
- return false
- end
- elseif posX ~= -1 then
- print("Error: Wrong position while trying to move to the starting spot")
- return false
- end
- if dumpInventory == "true" then
- -- reOrient(2)
- dumpInventory()
- end
- -- And finally reorient
- reOrient(0)
- -- And print a summary
- print("Done.")
- print("Mined " .. numBlocks .. " blocks.")
- print("Moved a total of " .. distanceTraveled .. " blocks.")
- print("Attacked mobs " .. numAttacks .. " times.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement