-- 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()
Comments
0 B
|0 👍
/0 👎
0 B
|👍
/👎