--[[ Dig a mine shaft, but avoid digging ores to let the player mine them with a fortune pickaxe ]] local junk = { "chisel:basalt1", "chisel:basalt2", "chisel:limestone1", "chisel:limestone2", "chisel:marble1", "chisel:marble2", "create:asurine", "minecraft:andesite", "minecraft:cobbled_deepslate", "minecraft:cobblestone", "minecraft:deepslate", "minecraft:diorite", "minecraft:dirt", "minecraft:granite", "minecraft:grass", "minecraft:gravel", "minecraft:mossy_cobblestone", "minecraft:sand", "minecraft:stone", "minecraft:tuff", } --- Current up/down position, where 1 is the bottom local currentY = 1 --- Current forward position, where 0 is the starting position, --- but 1 is the first vertical column to dig. local currentZ = 0 ---@param tbl table local function contains(tbl, elem) for _, v in ipairs(tbl) do if v == elem then return true end end return false end ---@param direction "" | "Up" | "Down" | nil local function dig(direction) direction = direction or "" local success, data = turtle["inspect" .. direction]() if not success then return true end if not contains(junk, data.name) then print(string.format("Found non-junk '%s'", data.name)) return false end repeat until not turtle["dig" .. direction]() return true end local function moveUp() for attempt = 1, 20 do if not dig("Up") then return false end local success, err = turtle.up() if success then currentY = currentY + 1 return true end print("Can't move up:", err) end print("Can't move up: max attempts reached") return false end local function moveDown() for attempt = 1, 20 do if not dig("Down") then return false end local success, err = turtle.down() if success then currentY = currentY - 1 return true end print("Can't move down:", err) end print("Can't move down: max attempts reached") return false end local function moveForward() for attempt = 1, 20 do if not dig("") then return false end local success, err = turtle.forward() if success then currentZ = currentZ + 1 return true end print("Can't move forward:", err) end print("Can't move forward: max attempts reached") return false end ---@param maxHeight number local function moveForwardSomewhere(maxHeight) if moveForward() then return true end print("Can't move forward here, trying another position") while currentY > 1 do if not moveDown() then break end if moveForward() then return true end end print("Can't move further down, so let's try moving up") while currentY < maxHeight do if not moveUp() then break end if moveForward() then return true end end print("Can't move further up. I'm stuck!") local success, data = turtle.inspect() print(string.format("Please break the block in front of me: '%s'", success and data.name or "air")) repeat sleep(1) until not turtle.detect() moveForward() end ---@param maxHeight number local function digColumnUp(maxHeight) if currentY > 1 then dig("Down") end for attempts = 1, maxHeight do if currentY >= maxHeight then print("Already too high up") return true elseif currentY == maxHeight - 1 then return dig("Up") else if not moveUp() then return false end end end error("Tried moving up too many times. Aborting") end ---@param maxHeight number local function digColumnDown(maxHeight) if currentY <= maxHeight - 1 then dig("Up") end for attempts = 1, maxHeight do if currentY <= 1 then print("Already too far down") return true elseif currentY == 2 then return dig("Down") else if not moveDown() then return false end end end error("Tried moving down too many times. Aborting") end local function usage(sMsg) sMsg = sMsg and (sMsg .. "\n") or "" error(sMsg .. "Usage: shaft [height=3]", 0) end local args = { ... } if #args < 1 then usage("Missing length.") end local maxLength = tonumber(args[1]) if not maxLength then usage("Failed to parse length as number") end if maxLength < 0 then usage("Length must be positive") end local maxHeight = 3 if #args >= 2 then local h = tonumber(args[1]) if not h then usage("Failed to parse height as number") end if h < 1 then usage("Height must be at least 1") end maxHeight = h end --(( Main program ))-- print(string.format("Shaft %d long, %d high", maxLength, maxHeight)) moveForward() local goUp = true while currentZ < maxLength do if goUp then print("Digging upwards") digColumnUp(maxHeight) else print("Digging downwards") digColumnDown(maxHeight) end goUp = not goUp moveForwardSomewhere(maxHeight) print(string.format("Progress: %d / %d", currentZ, maxLength)) end digColumnDown(maxHeight) if currentY == 2 then moveDown() end print("Done!")