Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local tArgs = { ... }
- if #tArgs ~= 3 then
- error("Usage: quarry <minY> <maxY> <maxRadius>")
- end
- local discardItems = {"chisel:", "Thaumcraft:", "BiomesOPlenty:", "Forestry:"}
- local minY = tonumber(tArgs[1])
- local maxY = tonumber(tArgs[2])
- local maxRadius = tonumber(tArgs[3])
- if minY < 1 then
- error("minY must be >0")
- end
- if maxY > 255 then
- error("minY must be <256")
- end
- if maxY < minY then
- error("minY > maxY")
- end
- if maxRadius < 1 then
- error("maxRadius must be >0")
- end
- local xPos, yPos, zPos = 0, 0, 0
- local xDir, zDir = 0, 1
- local ownOrientation = false
- local function move(moveFn, detFn, digFn, attFn, xd, yd, zd, dig, count)
- for pos = 1, count do
- while not moveFn() do
- if detFn() then
- if not dig or not digFn() then
- return pos - 1
- end
- elseif not attFn() then
- sleep(0.5)
- end
- end
- xPos = xPos + xd
- yPos = yPos + yd
- zPos = zPos + zd
- end
- return count
- end
- local function forward(count, dig)
- return move(turtle.forward, turtle.detect, turtle.dig, turtle.attack, xDir, 0, zDir, dig, count)
- end
- local function up(count, dig)
- return move(turtle.up, turtle.detectUp, turtle.digUp, turtle.attackUp, 0, 1, 0, dig, count)
- end
- local function down(count, dig)
- return move(turtle.down, turtle.detectDown, turtle.digDown, turtle.attackDown, 0, -1, 0, dig, count)
- end
- local function left()
- turtle.turnLeft()
- xDir, zDir = -zDir, xDir
- end
- local function right()
- turtle.turnRight()
- xDir, zDir = zDir, -xDir
- end
- local function orient(xd, zd)
- while xd ~= xDir or zd ~= zDir do
- if xDir == zd and zDir == -xd then
- left()
- else
- right()
- end
- end
- end
- local function goTo(x, y, z, xd, zd)
- while xPos ~= x or yPos ~= y or zPos ~= z do
- down(yPos - y, true)
- if x < xPos then
- orient(-1, 0)
- forward(xPos - x, true)
- end
- if z < zPos then
- orient(0, -1)
- forward(zPos - z, true)
- elseif z > zPos then
- orient(0, 1)
- forward(z - zPos, true)
- end
- if x > xPos then
- orient(1, 0)
- forward(x - xPos, true)
- end
- up(y - yPos, true)
- end
- orient(xd, zd)
- end
- local function inPrefixList(item, list)
- for _, prefix in pairs(list) do
- if string.sub(item, 1, string.len(prefix)) == prefix then
- return true
- end
- end
- return false
- end
- local function checkInventoryAndFuel(neededFuel)
- local fuel = turtle.getFuelLevel()
- local invFull = true
- for n = 1, 16 do
- if turtle.getItemCount(n) == 0 then
- invFull = false
- elseif fuel < neededFuel then
- turtle.select(n)
- if turtle.refuel(1) then
- local newFuel = turtle.getFuelLevel()
- turtle.refuel((neededFuel - newFuel) / (newFuel - fuel) + 1)
- fuel = newFuel
- end
- end
- end
- return invFull
- end
- local function unloadInventory(keepFuel)
- local fuelSlot = 0
- for slot = 1, 16 do
- if turtle.getItemCount(slot) > 0 then
- turtle.select(slot)
- local keep = false
- if keepFuel and fuelSlot == 0 and turtle.refuel(0) then
- keep = true
- fuelSlot = slot
- end
- if not keep and not turtle.drop() then
- print("Chest is full, waiting for space")
- while not turtle.drop() do
- sleep(1)
- end
- end
- end
- end
- if keepFuel then
- if fuelSlot == 0 then
- fuelSlot = 1
- end
- local space = turtle.getItemSpace(fuelSlot)
- local chest = peripheral.wrap("front")
- if ownOrientation and chest and chest.getAllStacks then
- for slot, stack in pairs(chest.getAllStacks()) do
- if stack.all().id == "minecraft:coal" then
- space = space - chest.pushItem(ownOrientation, slot, space, fuelSlot)
- if space <= 0 then
- break
- end
- end
- end
- end
- end
- turtle.select(1)
- end
- local function doMaintenance()
- print("Going home for maintenance...")
- ox, oy, oz, oxd, ozd = xPos, yPos, zPos, xDir, zDir
- goTo(0, 0, 0, 0, -1)
- unloadInventory(true)
- local neededFuel = 2 * (math.abs(ox) + math.abs(oy) + math.abs(oz)) + 100
- checkInventoryAndFuel(neededFuel)
- if turtle.getFuelLevel() < neededFuel then
- print("Waiting for fuel")
- while turtle.getFuelLevel() < neededFuel do
- os.pullEvent("turtle_inventory")
- checkInventoryAndFuel(neededFuel)
- end
- unloadInventory(true)
- end
- print("Resuming operations...")
- goTo(ox, oy, oz, oxd, ozd)
- end
- local function checkMaintenance()
- local neededFuel = math.abs(xPos) + math.abs(yPos) + math.abs(zPos) + 10
- local invFull = checkInventoryAndFuel(neededFuel)
- if invFull then
- print("Inventory full, cleaning up...")
- for slot = 1, 16 do
- local stack = turtle.getItemDetail(slot)
- while stack and inPrefixList(stack.name, discardItems) do
- turtle.select(slot)
- turtle.dropUp()
- invFull = false
- for i = slot + 1, 16 do
- turtle.select(i)
- turtle.transferTo(slot)
- end
- stack = turtle.getItemDetail(slot)
- end
- end
- end
- if invFull or turtle.getFuelLevel() < neededFuel then
- doMaintenance()
- end
- turtle.select(1)
- end
- local function dig(distance)
- for i = 1, distance do
- forward(1, true)
- turtle.digUp()
- turtle.digDown()
- checkMaintenance()
- end
- end
- local function digLayer(radius)
- dig(radius)
- right()
- for j = 1, 3 do
- dig(2 * radius)
- right()
- end
- dig(radius - 1)
- forward(1, true)
- end
- local function digRadius(radius, numLayers, vertMoveFn, vertDigFn)
- print("Digging radius ", radius, "...")
- for i = 1, numLayers do
- digLayer(radius)
- if i < numLayers then
- vertMoveFn(3, true)
- vertDigFn()
- else
- left()
- dig(1)
- right()
- end
- end
- end
- local chest = peripheral.wrap("back")
- if chest then
- for _, dir in pairs({"north", "east", "south", "west"}) do
- local status, result = pcall(chest.pushItem, dir, 1, 0)
- if status then
- ownOrientation = dir
- break
- end
- end
- end
- doMaintenance()
- while down(1, true) == 1 do
- checkMaintenance()
- end
- print("Base is at Y=", 1 - yPos)
- up(minY)
- while forward(1, false) == 1 do
- checkMaintenance()
- end
- dig(1)
- local radius = zPos
- right()
- local numLayers = math.floor((maxY - minY + 3) / 3)
- while radius <= maxRadius do
- digRadius(radius, numLayers, up, turtle.digUp)
- radius = radius + 1
- if radius > maxRadius then
- break
- end
- digRadius(radius, numLayers, down, turtle.digDown)
- radius = radius + 1
- end
- goTo(0, 0, 0, 0, -1)
- unloadInventory(false)
- goTo(0, 0, 0, 0, 1)
- print("Finished!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement