Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- pastebin ID: LXSNkj5r
- -- URL: https://pastebin.com/LXSNkj5r
- local logFilePath = "mine.log"
- local noChest = false
- local startChest = true -- Make startChest the default behavior
- -- Precious blocks list - blocks to detect and avoid mining unless blocking path
- local preciousBlocks = {
- "diamond",
- "lapis",
- "debris"
- }
- -- Mainframe communication
- local MAINFRAME_ID = nil
- local modemSide = nil
- local detectionRunning = false
- -- Direction vectors: north (-Z), east (+X), south (+Z), west (-X)
- local dirs = {
- [0] = {x = 0, z = -1}, -- North
- [1] = {x = 1, z = 0}, -- East
- [2] = {x = 0, z = 1}, -- South
- [3] = {x = -1, z = 0}, -- West
- }
- -- Initial state - use relative coordinates for movement
- local pos = {x = 0, y = 0, z = 0}
- local heading = 0 -- 0=north, 1=east, 2=south, 3=west
- -- Function to find and open modem
- function openModem()
- if modemSide then return true end
- local sides = {"left", "right", "top", "bottom", "front", "back"}
- for _, side in ipairs(sides) do
- if peripheral.getType(side) == "modem" then
- rednet.open(side)
- modemSide = side
- log("Modem opened on " .. side)
- return true
- end
- end
- log("No modem found for mainframe communication")
- return false
- end
- -- Function to discover mainframe ID via broadcast
- function discoverMainframe()
- if MAINFRAME_ID then return MAINFRAME_ID end
- if not openModem() then
- log("Cannot discover mainframe - no modem available")
- return nil
- end
- log("Broadcasting to discover mainframe...")
- rednet.broadcast("discover_mainframe")
- -- Wait for responses for up to 3 seconds
- local timeout = os.clock() + 3
- while os.clock() < timeout do
- local senderId, message = rednet.receive(0.1)
- if senderId and message == "mainframe_here" then
- MAINFRAME_ID = senderId
- log("Discovered mainframe at ID: " .. MAINFRAME_ID)
- return MAINFRAME_ID
- end
- end
- log("No mainframe found via broadcast")
- return nil
- end
- -- Function to report precious block to mainframe
- function reportPreciousBlock(blockName, x, y, z)
- local mainframeId = discoverMainframe()
- if mainframeId and openModem() then
- local message = {
- type = "precious",
- blockName = blockName,
- x = x,
- y = y,
- z = z
- }
- rednet.send(mainframeId, message)
- log("Reported to mainframe " .. mainframeId .. ": " .. blockName .. " at (" .. x .. ", " .. y .. ", " .. z .. ")")
- else
- log("Cannot report precious block - mainframe not available")
- end
- end
- -- Function to report current GPS location to mainframe
- function reportLocationToMainframe()
- local mainframeId = discoverMainframe()
- if mainframeId and openModem() then
- local gpsX, gpsY, gpsZ = gps.locate()
- if gpsX and gpsY and gpsZ then
- local message = {
- type = "location",
- x = gpsX,
- y = gpsY,
- z = gpsZ
- }
- rednet.send(mainframeId, message)
- log("Reported location to mainframe " .. mainframeId .. ": (" .. gpsX .. ", " .. gpsY .. ", " .. gpsZ .. ")")
- else
- -- Fallback to relative coordinates if GPS not available
- local absPos = getAbsolutePosition()
- local message = {
- type = "location",
- x = absPos.x,
- y = absPos.y,
- z = absPos.z
- }
- rednet.send(mainframeId, message)
- log("Reported relative location to mainframe " .. mainframeId .. ": (" .. absPos.x .. ", " .. absPos.y .. ", " .. absPos.z .. ")")
- end
- else
- log("Cannot report location - mainframe not available")
- end
- end
- -- Function to scrub precious locations from mainframe for this turtle
- function scrubPreciousLocations()
- local mainframeId = discoverMainframe()
- if mainframeId and openModem() then
- local myId = os.getComputerID()
- local message = "scrub_precious " .. myId
- rednet.send(mainframeId, message)
- log("Requested mainframe " .. mainframeId .. " to scrub precious locations for turtle " .. myId)
- -- Wait for confirmation
- local timeout = os.clock() + 2
- while os.clock() < timeout do
- local senderId, response = rednet.receive(0.1)
- if senderId == mainframeId and type(response) == "string" and string.find(response, "Scrubbed") then
- log("Mainframe confirmed: " .. response)
- return true
- end
- end
- log("No confirmation received from mainframe for scrub request")
- else
- log("Cannot scrub precious locations - mainframe not available")
- end
- return false
- end
- -- Continuous precious block detection that runs in parallel
- function continuousDetection()
- detectionRunning = true
- log("Starting continuous precious block detection...")
- while detectionRunning do
- -- Get current GPS coordinates directly
- local gpsX, gpsY, gpsZ = gps.locate()
- if not gpsX then
- -- Fallback to relative coordinates if GPS not available
- gpsX, gpsY, gpsZ = pos.x, pos.y, pos.z
- end
- -- Check only forward, up, and down directions (no side inspection to avoid interfering with mining)
- local directions = {
- {name = "forward", detect = turtle.inspect},
- {name = "up", detect = turtle.inspectUp},
- {name = "down", detect = turtle.inspectDown}
- }
- -- Check forward, up, down only
- for _, dir in ipairs(directions) do
- local success, data = dir.detect()
- if success and data and data.name and isPreciousBlock(data.name) then
- reportPreciousBlock(data.name, gpsX, gpsY, gpsZ)
- end
- end
- -- Sleep briefly to avoid overwhelming the system
- sleep(0.5)
- end
- log("Continuous precious block detection stopped")
- end
- -- Function to stop continuous detection
- function stopDetection()
- detectionRunning = false
- end
- -- Function to log messages to a file
- function log(message)
- local file = fs.open(logFilePath, "a")
- print(message)
- file.writeLine(message)
- file.close()
- end
- -- Function to clean block name by removing everything before ':'
- function cleanBlockName(blockName)
- if not blockName then return "unknown" end
- local colonPos = string.find(blockName, ":")
- if colonPos then
- return string.sub(blockName, colonPos + 1)
- else
- return blockName
- end
- end
- -- Function to check if a block name contains precious materials
- function isPreciousBlock(blockName)
- if not blockName then return false end
- for _, precious in ipairs(preciousBlocks) do
- if string.find(string.lower(blockName), precious) then
- return true
- end
- end
- return false
- end
- -- Function to detect and log precious blocks in all directions
- function detectPreciousBlocks()
- local directions = {
- {name = "forward", detect = turtle.inspect, pos = "front"},
- {name = "up", detect = turtle.inspectUp, pos = "above"},
- {name = "down", detect = turtle.inspectDown, pos = "below"}
- }
- for _, dir in ipairs(directions) do
- local success, data = dir.detect()
- if success and data and data.name then
- if isPreciousBlock(data.name) then
- log("PRECIOUS BLOCK DETECTED " .. dir.pos .. ": " .. data.name .. " at relative position (" .. pos.x .. ", " .. pos.y .. ", " .. pos.z .. ")")
- end
- end
- end
- end
- -- Function to get GPS coordinates for absolute positioning
- function getGPSPosition()
- local x, y, z = gps.locate()
- if x and y and z then
- log("GPS coordinates obtained: (" .. x .. ", " .. y .. ", " .. z .. ")")
- return {x = x, y = y, z = z}
- else
- log("WARNING: GPS not available, absolute coordinates will not be available")
- return nil
- end
- end
- -- Get starting GPS position for absolute coordinate conversion
- local startGPS = getGPSPosition()
- -- Function to get current absolute coordinates
- function getAbsolutePosition()
- if startGPS then
- return {
- x = startGPS.x + pos.x,
- y = startGPS.y + pos.y,
- z = startGPS.z + pos.z
- }
- else
- -- If GPS not available, return relative coordinates
- return {x = pos.x, y = pos.y, z = pos.z}
- end
- end
- -- Helpers
- function turnLeft()
- turtle.turnLeft()
- heading = (heading - 1 + 4) % 4 -- Ensure positive modulo result
- end
- function turnRight()
- turtle.turnRight()
- heading = (heading + 1) % 4
- end
- function moveForward()
- while not turtle.forward() do
- turtle.attack()
- digForward()
- sleep(0.5)
- end
- pos.x = pos.x + dirs[heading].x
- pos.z = pos.z + dirs[heading].z
- reportLocationToMainframe()
- end
- function moveBackward()
- turtle.back()
- pos.x = pos.x - dirs[heading].x
- pos.z = pos.z - dirs[heading].z
- reportLocationToMainframe()
- end
- function moveUp()
- while not turtle.up() do
- turtle.attackUp()
- digUp()
- sleep(0.5)
- end
- pos.y = pos.y + 1
- reportLocationToMainframe()
- end
- function moveDown()
- while not turtle.down() do
- turtle.attackDown()
- digDown()
- sleep(0.5)
- end
- pos.y = pos.y - 1
- reportLocationToMainframe()
- end
- function digForward()
- while turtle.detect() do
- turtle.dig()
- sleep(0.3)
- end
- end
- function digUp()
- while turtle.detectUp() do
- turtle.digUp()
- sleep(0.3)
- end
- end
- function digDown()
- while turtle.detectDown() do
- turtle.digDown()
- sleep(0.3)
- end
- end
- function isInventoryFull()
- for i = 1, 16 do
- if turtle.getItemCount(i) == 0 then return false end
- end
- log("InventoryFull. startChest: " .. tostring(startChest) .. ", noChest: " .. tostring(noChest))
- return true
- end
- function refuelIfNeeded()
- for i = 1, 16 do
- turtle.select(i)
- local itemDetail = turtle.getItemDetail()
- if itemDetail and string.find(itemDetail.name, "coal") then
- while turtle.getItemCount(i) > 0 do
- turtle.refuel(1)
- end
- log("Refueled with " .. itemDetail.name .. " from slot " .. i)
- end
- end
- turtle.select(1)
- end
- function dumpJunk()
- local junkItems = {
- "cobblestone", "diorite", "gravel", "dirt", "tuff", "blackstone", "pebble", "polished blackstone wall",
- "nether brick wall", "nether brick fence", "red nether brick", "nether brick staires", "cracked nether bricks",
- "nether bricks",
- "granite", "deepslate", "netherrack", "rhyolite", "schist", "pebble", "asphalt", "andesite"
- }
- for i = 1, 16 do
- turtle.select(i)
- local itemDetail = turtle.getItemDetail()
- if itemDetail then
- for _, junk in ipairs(junkItems) do
- if string.find(itemDetail.name, junk) then
- turtle.drop()
- log("Dropped junk item: " .. itemDetail.name .. " from slot " .. i)
- break
- end
- end
- end
- end
- turtle.select(1)
- end
- -- Safe digging functions for digTriplet - avoid precious blocks that aren't blocking movement
- function digForwardSafe()
- while turtle.detect() do
- local success, data = turtle.inspect()
- if success and data and data.name and isPreciousBlock(data.name) then
- local cleanedName = cleanBlockName(data.name)
- log("AVOIDING precious block in front (not blocking path): " .. cleanedName .. " at position (" .. pos.x .. ", " .. pos.y .. ", " .. pos.z .. ")")
- break -- Don't dig precious blocks when just clearing area
- end
- turtle.dig()
- sleep(0.3)
- end
- end
- function digUpSafe()
- while turtle.detectUp() do
- local success, data = turtle.inspectUp()
- if success and data and data.name and isPreciousBlock(data.name) then
- local cleanedName = cleanBlockName(data.name)
- log("AVOIDING precious block above (not blocking path): " .. cleanedName .. " at position (" .. pos.x .. ", " .. pos.y + 1 .. ", " .. pos.z .. ")")
- break -- Don't dig precious blocks when just clearing area
- end
- turtle.digUp()
- sleep(0.3)
- end
- end
- function digDownSafe()
- while turtle.detectDown() do
- local success, data = turtle.inspectDown()
- if success and data and data.name and isPreciousBlock(data.name) then
- local cleanedName = cleanBlockName(data.name)
- log("AVOIDING precious block below (not blocking path): " .. cleanedName .. " at position (" .. pos.x .. ", " .. pos.y - 1 .. ", " .. pos.z .. ")")
- break -- Don't dig precious blocks when just clearing area
- end
- turtle.digDown()
- sleep(0.3)
- end
- end
- function digTriplet()
- -- Detect precious blocks in all directions before mining
- detectPreciousBlocks()
- digForwardSafe() -- Use safe version - not actually moving forward here
- moveForward()
- -- Detect precious blocks again after moving
- detectPreciousBlocks()
- -- Use safe digging for up/down since turtle isn't moving in those directions
- digUpSafe()
- digDownSafe()
- end
- function dig()
- digTriplet()
- if isInventoryFull() then
- log("Checking where to drop the stuff. startChest: " .. tostring(startChest) .. ", noChest: " .. tostring(noChest))
- if noChest then
- for i = 1, 16 do
- turtle.select(i)
- turtle.drop()
- end
- elseif startChest then
- local currentPos = {x = pos.x, y = pos.y, z = pos.z, d = heading}
- goTo(0, 0, 0, 2)
- for i = 1, 16 do
- turtle.select(i)
- turtle.drop()
- end
- goTo(currentPos.x, currentPos.y, currentPos.z, currentPos.d) -- Return to the original position
- else
- placeChestAndUnload()
- end
- end
- -- log("Dug block at position: (" .. pos.x .. ", " .. pos.y .. ", " .. pos.z .. ")")
- end
- function placeChestAndUnload()
- turtle.select(1) -- Select slot 1, assuming it's for the chest
- -- Loop until a chest is found in slot 1
- local itemInSlot1 = turtle.getItemDetail(1)
- while not itemInSlot1 or not string.find(itemInSlot1.name, "chest") do
- log("Waiting for chest in slot 1. Current item: " .. (itemInSlot1 and itemInSlot1.name or "nil"))
- print("Please place a chest in slot 1 to continue.")
- sleep(2) -- Wait for 2 seconds before re-checking
- itemInSlot1 = turtle.getItemDetail(1)
- end
- -- Now that a chest is confirmed in slot 1, proceed with placing it
- while not turtle.placeDown() do
- log("Waiting to place chest. Please ensure the space below is clear.")
- print("Waiting to place chest. Please ensure the space below is clear.")
- sleep(2) -- Wait for 2 seconds before retrying
- end
- log("Placed chest below at position: (" .. pos.x .. ", " .. pos.y .. ", " .. pos.z .. ")")
- for i = 2, 16 do -- Start from slot 2, assuming slot 1 is for the chest
- turtle.select(i)
- turtle.dropDown()
- end
- turtle.select(1) -- Re-select slot 1
- end
- function digTunnel(x)
- for i = 1, x do
- dig()
- end
- refuelIfNeeded()
- dumpJunk()
- end
- function goTo(x, y, z, d)
- while pos.y < y do moveUp() end
- while pos.y > y do moveDown() end
- local dx = x - pos.x
- if dx ~= 0 then
- -- Determine target heading based on dx
- local targetHeadingX = (dx > 0) and 1 or 3 -- East or West
- faceDirection(targetHeadingX)
- for i = 1, math.abs(dx) do digTriplet() end
- end
- local dz = z - pos.z
- if dz ~= 0 then
- -- Determine target heading based on dz
- local targetHeadingZ = (dz > 0) and 2 or 0 -- South or North
- faceDirection(targetHeadingZ)
- for i = 1, math.abs(dz) do digTriplet() end
- end
- faceDirection(d)
- end
- function faceDirection(dir)
- while heading ~= dir do
- turnRight()
- end
- end
- local args = { ... }
- function digLayer(width, length, spacing)
- tunnelLength = width - 1
- numTunnels = math.floor((length + spacing) / (1 + spacing))
- log("Starting layer mining with tunnel length: " .. tunnelLength .. ", number of tunnels: " .. numTunnels .. ", spacing: " .. spacing)
- for _ = 1, math.floor(numTunnels / 2) do
- -- Move to start of first tunnel (connecting segment)
- digTunnel(1 + spacing)
- -- Turn into first main tunnel
- turnLeft()
- digTunnel(tunnelLength)
- -- Turn to move to next connecting segment
- turnRight()
- digTunnel(1 + spacing)
- -- Turn into second main tunnel
- turnRight()
- digTunnel(tunnelLength)
- -- Turn back to original orientation for next pair of tunnels
- turnLeft()
- end
- if numTunnels % 2 == 1 then
- log("Warning: numTunnels is odd. The last tunnel might not follow the full zig-zag pattern.")
- end
- if noChest then
- log("No chest mode: Dropping items on the ground.")
- for i = 1, 16 do
- turtle.select(i)
- turtle.drop()
- end
- elseif startChest then
- log("Start chest mode: Returning to start to unload.")
- goTo(0, 0, 0, 2)
- for i = 1, 16 do
- turtle.select(i)
- turtle.drop()
- end
- end
- end
- -- Mining function that runs the actual mining operations
- function runMining()
- local width = tonumber(args[1])
- local length = tonumber(args[2])
- local tspacing = tonumber(args[3])
- local layers = tonumber(args[4])
- local lspacing = tonumber(args[5])
- for i = 1, layers do
- log("Starting layer ".. i)
- goTo(0, - (i - 1) * (3 + lspacing), 0, 0)
- digLayer(width, length, tspacing)
- end
- if noChest then
- log("No chest mode: Dropping items on the ground.")
- for i = 1, 16 do
- turtle.select(i)
- turtle.drop()
- end
- elseif startChest then
- log("Start chest mode: Returning to start to unload.")
- goTo(0, 0, 0, 2)
- for i = 1, 16 do
- turtle.select(i)
- turtle.drop()
- end
- end
- goTo(0, 0, 0, 0)
- -- Stop continuous detection when mining is complete
- stopDetection()
- log("Mining complete.")
- end
- function main()
- if #args < 5 then
- print("Usage: mine <width> <length> <tunnelSpacing> <numLayers> <layerSpacing> [--nochest | --nostartchest]")
- return
- end
- local width = tonumber(args[1])
- local length = tonumber(args[2])
- local tspacing = tonumber(args[3])
- local layers = tonumber(args[4])
- local lspacing = tonumber(args[5])
- -- Parse optional flags
- for i = 6, #args do
- if args[i] == "--nochest" then
- log("Detected --nochest")
- noChest = true
- startChest = false -- Override default when --nochest is specified
- elseif args[i] == "--nostartchest" then
- log("Detected --nostartchest")
- startChest = false
- end
- end
- log("startChest: " .. tostring(startChest) .. ", noChest: " .. tostring(noChest))
- if not width or not length or not tspacing or not layers or not lspacing then
- print("Invalid input.")
- return
- end
- -- Scrub previous precious locations when starting new mining operation
- log("Starting new mining operation - scrubbing previous precious locations...")
- scrubPreciousLocations()
- -- Report initial location to mainframe
- reportLocationToMainframe()
- -- Run mining and continuous detection in parallel
- parallel.waitForAll(runMining, continuousDetection)
- end
- main()
Advertisement
Add Comment
Please, Sign In to add comment