Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local log_file = "log.txt"
- local options_file = "flex_options.cfg"
- os.loadAPI("flex.lua")
- os.loadAPI("dig.lua")
- local modem_channel = 6464
- -- local received_command = nil -- Remove if not needed for status only
- dig.doBlacklist() -- Avoid Protected Blocks
- dig.doAttack() -- Attack entities that block the way
- dig.setFuelSlot(1)
- dig.setBlockSlot(2)
- local world_height = 384
- if fs.exists(options_file) then
- local file = fs.open("flex_options.cfg", "r")
- local line = file.readLine()
- while line ~= nil do
- if string.find(line, "modem_channel=") == 1 then
- modem_channel = tonumber( string.sub(
- line, 15, string.len(line) ) )
- break
- end --if
- line = file.readLine()
- end --while
- file.close()
- end --if
- -- Add debug prints around modem initialization
- print("DEBUG: Attempting to initialize modem.")
- local modem -- Make sure modem is declared here, outside of any function
- local hasModem = false
- local p = flex.getPeripheral("modem")
- if #p > 0 then
- print("DEBUG: Modem peripheral found: " .. tostring(p[1]))
- hasModem = true
- modem = peripheral.wrap(p[1])
- -- No need to open modem if only using modem.transmit for broadcast on a specific channel
- print("DEBUG: Modem peripheral wrapped. Will attempt to transmit status on channel 6465.")
- else
- print("DEBUG: No modem peripheral found during initialization. Status updates disabled.")
- -- The script can still run without a modem, but status updates won't work.
- end
- -- ... (modemListener coroutine and related removed if only status is needed) ...
- local args = {...}
- if #args == 0 then
- flex.printColors(
- "quarry <length> [width] [depth]\n"..
- "[skip <layers>] [dump] [nolava] [nether]",
- colors.lightBlue)
- return
- end --if
- local reloaded = false
- if dig.saveExists() then
- reloaded = true
- dig.loadCoords()
- end --if
- dig.makeStartup("quarry",args)
- local zmax = tonumber(args[1])
- local xmax = tonumber(args[2]) or zmax
- local depth = world_height-1
- if tonumber(args[2]) ~= nil then
- depth = tonumber(args[3]) or depth
- end --if
- local ymin = -depth --(1-depth)
- if xmax == nil or zmax == nil then
- flex.send("Invalid dimensions,",colors.red)
- shell.run("rm startup.lua")
- return
- end --if
- local x
- local skip = 0 -- Initialized to 0
- local lava = true
- local dodumps = false
- for x=1,#args do
- if args[x] == "dump" then
- dodumps = true
- elseif args[x] == "nolava" then
- lava = false
- elseif args[x] == "nether" then
- dig.setBlockStacks(4)
- end --if
- if args[x] == "skip" then
- local skip_value = tonumber(args[x+1]) -- Use a temporary variable
- if skip_value == nil then
- flex.printColors("Please specify skip depth",
- colors.red)
- dig.saveClear()
- return -- Script exits
- end --if
- skip = skip_value -- Assign only if it's a number
- if dig.getymin() > -skip then
- dig.setymin(-skip)
- end --if
- end --if
- end --for
- -- After this loop, if "skip" arg was used with a number, `skip` is that number.
- -- If "skip" arg was NOT used, `skip` remains 0.
- -- If "skip" arg was used without a number, the script should have returned.
- if not lava then -- Block lava around edges of quarry
- dig.setBlockSlot(0)
- -- Always keep a stack of blocks
- end --if
- ----------------------------------------------
- -- |¯¯]|| |||\ || /¯][¯¯][¯¯] /¯\ |\ ||/¯¯\ --
- -- | ] ||_||| \ || [ || ][ | O || \ |\_¯\ --
- -- || \__||| \| \_] || [__] \_/ || \|\__/ --
- ----------------------------------------------
- local location
- local function gotoBase()
- local x = dig.getxlast()
- location = dig.location()
- -- skip is used here
- if dig.gety() < -skip then dig.up() end
- dig.gotox(0)
- dig.gotoz(0)
- dig.gotor(180)
- dig.gotoy(0)
- dig.gotox(0)
- dig.setxlast(x)
- dig.gotoz(0)
- dig.gotor(180)
- return location
- end --function
- local function returnFromBase(loc)
- local loc = loc or location
- local x = dig.getxlast()
- dig.gotor(0)
- checkFuel()
- -- skip is used here
- dig.gotoy(math.min(loc[2]+1,-skip))
- checkFuel()
- dig.gotoz(loc[3])
- checkFuel()
- dig.gotox(loc[1])
- dig.setxlast(x) -- Important for restoring
- checkFuel()
- dig.gotor(loc[4])
- checkFuel()
- dig.gotoy(loc[2])
- end --function
- local function checkHalt()
- -- Remote control halt via modem is removed (assuming for status only)
- -- Check for redstone signal from above
- if not rs.getInput("top") then
- return
- end --if
- -- skip is used here
- if dig.gety() == -skip then -- Check against skip depth
- return
- end --if
- if dig.gety() == 0 then -- Check against surface
- return
- end --if
- local loc,x
- -- Manual halt; redstone signal from above
- flex.send("Manual halt initiated (Redstone)", colors.orange)
- flex.printColors("Press ENTER to resume mining\n"
- .."or SPACE to return to base",
- colors.pink)
- while true do
- x = flex.getKey()
- if x == keys.enter then return end
- if x == keys.space then break end
- end --while
- flex.send("Returning to base", colors.yellow)
- loc = gotoBase()
- print(" ")
- flex.printColors("Press ENTER to resume mining",
- colors.pink)
- while flex.getKey() ~= keys.enter do
- sleep(1)
- end --while
- if dodumps then dig.doDumpDown() end
- dig.dropNotFuel()
- flex.send("Resuming quarry",colors.yellow)
- returnFromBase(loc)
- end --function
- local function checkInv()
- if turtle.getItemCount(16) > 0 then
- if dodumps then
- dig.right(2)
- dig.doDump()
- dig.left(2)
- end --if
- if turtle.getItemCount(14) > 0 then
- local loc = gotoBase()
- dig.dropNotFuel()
- returnFromBase(loc)
- end --if
- end --if
- end --function
- function checkFuel()
- local a = turtle.getFuelLevel()
- -- This fuel estimate is very basic, you might need to adjust it
- -- local b = ( zmax + xmax + math.abs(dig.gety() - ymin) ) * 2 -- Original basic fuel estimate
- local c = true
- -- More detailed fuel estimate based on remaining blocks
- local total_quarry_blocks = xmax * zmax * (dig.getymax() - dig.getymin() + 1) -- Assuming ymax is start y
- local current_dug_blocks = dig.getdug()
- local estimated_remaining_blocks = total_quarry_blocks - current_dug_blocks
- -- Rough estimate of fuel needed per block (adjust based on your setup)
- local fuel_per_block = 0.05 -- Example: needs calibration
- local estimated_fuel_needed = estimated_remaining_blocks * fuel_per_block
- -- Use a more robust fuel check based on estimated needs
- -- Only check if estimated_fuel_needed is a valid number (it should be if math is correct)
- if type(estimated_fuel_needed) == 'number' and a < estimated_fuel_needed * 1.2 then -- Check if current fuel is less than 120% of estimated needed
- flex.send("Fuel low (Estimated needed: "..tostring(math.ceil(estimated_fuel_needed)).."), returning to surface", colors.yellow)
- local loc = gotoBase()
- turtle.select(1)
- if dodumps then dig.doDumpDown() end
- while turtle.suckUp() do sleep(0) end
- dig.dropNotFuel()
- -- Ensure refuel amount is not nil or non-positive
- local refuel_amount = estimated_fuel_needed * 1.5
- if type(refuel_amount) == 'number' and refuel_amount > 0 then
- dig.refuel(refuel_amount) -- Refuel to 150% of estimated needed
- else
- dig.refuel(1000) -- Fallback refuel amount
- end
- flex.send("Fuel acquired! ("..tostring(turtle.getFuelLevel()).." fuel)", colors.lightBlue)
- returnFromBase(loc)
- end
- -- ADDED MISSING `end` FOR checkFuel
- end --function checkFuel()
- -- Add this function to gather and send status (DEFINED OUTSIDE any function)
- local function sendStatus()
- -- Gather status data
- local total_quarry_blocks = xmax * zmax * (dig.getymax() - dig.getymin() + 1) -- Assuming ymax is start y
- local current_dug_blocks = dig.getdug()
- local estimated_remaining_blocks = total_quarry_blocks - current_dug_blocks
- local estimated_time_display = "Calculating..."
- -- Only calculate estimated time if remaining blocks is a valid number > 0
- if type(estimated_remaining_blocks) == 'number' and estimated_remaining_blocks > 0 then
- local avg_blocks_per_second = 0.8 -- Calibrate this value
- local estimated_time_seconds = estimated_remaining_blocks / avg_blocks_per_second
- local hours = math.floor(estimated_time_seconds / 3600)
- local minutes = math.floor((estimated_time_seconds % 3600) / 60)
- local seconds = math.floor(estimated_time_seconds % 60)
- estimated_time_display = string.format("%02d:%02d:%02d", hours, minutes, seconds)
- end
- -- Get inventory summary (basic example)
- local inventory_summary = {}
- for slot = 1, 16 do
- local item = turtle.getItemDetail(slot)
- if item then
- table.insert(inventory_summary, { name = item.name, count = item.count })
- end
- end
- -- Ensure 'done' is accessible or determine mining state differently if 'done' is local to main loop
- local is_mining_status = false
- -- Assuming 'done' is a boolean defined in the main loop's scope
- if type(done) == "boolean" then
- is_mining_status = not done and not dig.isStuck()
- else
- -- If 'done' is not globally available, assume mining is true unless stuck
- is_mining_status = not dig.isStuck()
- end
- local status_message = {
- type = "status_update", -- Indicate this is a status update
- id = os.getComputerID(), -- Include turtle ID
- label = os.getComputerLabel(), -- Include turtle label
- fuel = turtle.getFuelLevel(),
- position = { x = dig.getx(), y = dig.gety(), z = dig.getz(), r = dig.getr() },
- is_mining = is_mining_status, -- Reflect actual mining state
- estimated_time = estimated_time_display,
- dug_blocks = dig.getdug(),
- inventory_summary = inventory_summary -- Include basic inventory summary
- }
- -- Send the status message on a specific channel (e.g., 6465)
- local status_channel = modem_channel -- Channel for status updates
- if modem then -- Check if modem peripheral is available
- print("DEBUG: Attempting to transmit status on channel " .. status_channel) -- NEW DEBUG PRINT before transmit
- -- Transmit from status_channel to status_channel for a broadcast on 6465
- modem.transmit(status_channel, status_channel, status_message)
- print("DEBUG: Status update sent on channel " .. status_channel) -- Optional debug
- else
- print("DEBUG: sendStatus called but modem is nil. Cannot transmit.") -- NEW DEBUG PRINT if modem is nil
- end
- end
- -- Variables for status sending interval (DEFINED OUTSIDE any function)
- local last_status_sent_time = os.epoch("utc") or 0 -- Initialize defensively
- local status_send_interval = 10 * 1000 -- Send status every 10 seconds (in milliseconds)
- local dug = dig.getdug()
- local ydeep = dig.getymin()
- local function checkProgress()
- -- print("DEBUG: checkProgress called.")
- -- Print detailed progress information (keep this for console)
- term.setCursorPos(1,1)
- term.clearLine()
- flex.printColors("Pos: X="..tostring(dig.getx())..
- ", Y="..tostring(dig.gety())..
- ", Z="..tostring(dig.getz())..
- ", Rot="..tostring(dig.getr()%360), colors.white)
- term.setCursorPos(1,2)
- term.clearLine()
- flex.printColors("Fuel: "..tostring(turtle.getFuelLevel()), colors.orange)
- term.setCursorPos(1,3)
- term.clearLine()
- flex.printColors("Dug: "..tostring(dig.getdug()).." blocks", colors.lightBlue)
- term.setCursorPos(1,4)
- term.clearLine()
- flex.printColors("Depth: "..tostring(-dig.gety()).."m / "..tostring(-ymin).."m", colors.green)
- -- Use os.epoch("utc") for timing comparison in milliseconds
- local current_epoch_time_ms = os.epoch("utc") or 0 -- Get current epoch time in milliseconds
- local time_difference_ms = current_epoch_time_ms - (last_status_sent_time or 0) -- Calculate difference in milliseconds
- -- print("DEBUG: Status check timing (Epoch UTC) - os.epoch(): "..tostring(current_epoch_time_ms)..", last_status_sent_time: "..tostring(last_status_sent_time)..", difference: "..tostring(time_difference_ms)..", interval (ms): "..tostring(status_send_interval))
- -- Send status update periodically using os.epoch() for the check
- if type(current_epoch_time_ms) == 'number' and time_difference_ms >= status_send_interval then
- -- print("DEBUG: Status send interval met (Epoch UTC). Calling sendStatus.")
- sendStatus()
- last_status_sent_time = current_epoch_time_ms -- Update last sent time using epoch time in milliseconds
- -- else
- -- print("DEBUG: Status send interval not met (Epoch UTC).")
- end
- -- Removed original progress prints
- local a = 1000 --report every <a> blocks dug
- local b = 5 --report every <b> meters descended
- if math.floor(dug/a) < math.floor(dig.getdug()/a) then
- flex.send("Dug "..tostring(dig.getdug())..
- " blocks",colors.lightBlue)
- end --if
- if math.floor(-ydeep/b) < math.floor(-dig.gety()/b) then
- flex.send("Descended "..tostring(-dig.gety())..
- "m",colors.green)
- end --if
- dug = dig.getdug()
- ydeep = dig.gety()
- -- checkReceivedCommand() -- Remove if not doing remote control
- end --function checkProgress()
- -- ... (processCommand and checkReceivedCommand removed if not doing remote control) ...
- local newlayer = false
- function checkNewLayer()
- if newlayer then
- -- This encodes whether or not the turtle has
- -- started a new layer if at the edge
- dig.setr(dig.getr() % 360 + 360)
- else
- dig.setr(dig.getr() % 360)
- end --if
- end --function
- function lavax()
- if dig.getx() == 0 then
- dig.gotor(270)
- checkNewLayer()
- dig.blockLava()
- elseif dig.getx() == xmax-1 then
- dig.gotor(90)
- checkNewLayer()
- dig.blockLava()
- end --if/else
- end --function
- function lavaz()
- if dig.getz() == 0 then
- dig.gotor(180)
- checkNewLayer()
- dig.blockLava()
- elseif dig.getz() == zmax-1 then
- dig.gotor(0)
- checkNewLayer()
- dig.blockLava()
- end --if/else
- end --function
- function checkLava(n)
- if lava then
- local x
- local r = dig.getr() % 360
- if r == 0 or r == 180 then
- lavaz()
- lavax()
- else
- lavax()
- lavaz()
- end --if/else
- -- skip is used here
- if dig.gety() == -skip then
- dig.blockLavaUp()
- end --if
- -- skip is used here
- if dig.getx() == 0 and dig.getz() == 0
- and dig.gety() > -skip then
- for x=1,4 do
- dig.blockLava()
- dig.left()
- checkNewLayer()
- end --for
- end --if
- if n ~= 0 then
- dig.gotor(r)
- checkNewLayer()
- end --if
- end --if
- end --function
- local function checkAll(n)
- checkNewLayer()
- checkProgress() -- checkProgress calls status send logic
- checkFuel()
- checkInv()
- checkHalt() -- checkHalt also uses skip
- checkLava(n)
- dig.checkBlocks()
- checkNewLayer()
- end --function
- ---------------------------------------
- -- |\/| /\ [¯¯] |\ || --
- -- | | | | ][ | \ | --
- -- |||| |||| [__] || \| --
- ---------------------------------------
- -- |¯\ |¯\ /¯\ /¯¯] |¯\ /\ |\/| --
- -- | / | / | O | | [¯| | / | | | | --
- -- || | \ \_/ \__| | \ |||| |||| --
- ---------------------------------------
- local a,b,c,x,y,z,r,loc
- local xdir, zdir = 1, 1
- turtle.select(1)
- if reloaded then
- flex.send("Resuming "..tostring(zmax).."x"
- ..tostring(xmax).." quarry",colors.yellow)
- if dig.gety()==dig.getymin() and dig.gety()~=0 then
- zdir = dig.getzlast()
- if zdir == 0 then zdir = 1 end
- xdir = dig.getxlast()
- if xdir == 0 then xdir = 1 end
- if dig.getr() >= 360 then
- -- This encodes whether or not the turtle has
- -- started a new layer if at the edge
- xdir = -xdir
- newlayer = true
- end --if
- else
- gotoBase()
- if dodumps then dig.doDumpDown() end
- dig.dropNotFuel()
- dig.gotor(0)
- checkFuel()
- -- skip is used here
- dig.gotoy(math.min(dig.getymin(),-skip)) -- Corrected: go to min y or skip depth
- end --if
- else
- flex.send("Starting "..tostring(zmax).."x"
- ..tostring(xmax).." quarry",colors.yellow)
- -- skip is used here
- if skip > 0 then
- flex.send("Skipping "..tostring(skip)
- .."m", colors.lightGray)
- end --if
- if depth < world_height-1 then
- flex.send("Going "..tostring(-ymin)
- .."m deep", colors.lightGray)
- else
- flex.send("To bedrock!",colors.lightGray)
- end --if/else
- end --if/else
- -- Immediately before the descent loop
- print("DEBUG: Before descent loop. dig.gety(): " .. tostring(dig.gety()) .. ", -skip: " .. tostring(-skip)) -- Debug print kept
- -- ERROR IS HERE: while dig.gety() > -skip do
- while dig.gety() > -skip do
- checkFuel()
- dig.down()
- if dig.isStuck() then
- flex.send("Co-ordinates lost! Shutting down",
- colors.red)
- --rs.delete("startup.lua")
- return
- end --if
- -- checkReceivedCommand() -- Remove if not doing remote control
- end --while
- print("DEBUG: After descent loop.") -- Debug print kept
- --------------------------
- -- |\/| /\ [¯¯] |\ || --
- -- | | | | ][ | \ | --
- -- |||| |||| [__] || \| --
- --------------------------
- -- || /¯\ /¯\ |¯\ --
- -- ||_ | O | | O | | / --
- -- |__] \_/ \_/ || --
- --------------------------
- local done = false -- 'done' is local to this main loop
- while not done and not dig.isStuck() do
- -- checkReceivedCommand() -- Remove if not doing remote control
- turtle.select(1)
- while not done do
- -- checkReceivedCommand() -- Remove if not doing remote control
- checkAll(0) -- checkAll calls checkProgress, which calls status send
- if dig.getz()<=0 and zdir==-1 then break end
- if dig.getz()>=zmax-1 and zdir==1 then break end
- if zdir == 1 then dig.gotor(0)
- elseif zdir == -1 then dig.gotor(180)
- end --if/else
- checkNewLayer()
- dig.fwd()
- if dig.isStuck() then
- done = true
- end --if
- end --while (z loop)
- if done then break end
- zdir = -zdir
- newlayer = false
- -- Add print at the start of a new row
- flex.printColors("Starting new row at X="..tostring(dig.getx()).." Z="..tostring(dig.getz()).." Layer="..tostring(-dig.gety()), colors.gray)
- if dig.getx()<=0 and xdir==-1 then
- newlayer = true
- elseif dig.getx()>=xmax-1 and xdir==1 then
- newlayer = true
- else
- checkAll(0) -- checkAll calls checkProgress, which calls status send
- dig.gotox(dig.getx()+xdir)
- end --if/else
- if newlayer and not dig.isStuck() then
- xdir = -xdir
- if dig.getymin() <= ymin then break end
- checkAll(0) -- checkAll calls checkProgress, which calls status send
- dig.down()
- -- Add print at the start of a new layer
- flex.printColors("Starting new layer at Y="..tostring(dig.gety()), colors.purple)
- end --if
- end --while (cuboid dig loop)
- flex.send("Digging completed, returning to surface",
- colors.yellow)
- gotoBase()
- flex.send("Descended "..tostring(-dig.getymin())..
- "m total",colors.green)
- flex.send("Dug "..tostring(dig.getdug())..
- " blocks total",colors.lightBlue)
- for x=1,16 do
- if dig.isBuildingBlock(x) then
- turtle.select(x)
- dig.placeDown()
- break
- end --if
- end --for
- turtle.select(1)
- if dodumps then
- dig.gotor(0)
- dig.doDump()
- dig.gotor(180)
- end
- dig.dropNotFuel()
- dig.gotor(0)
- dig.clearSave()
- flex.modemOff() -- Keep this to close the modem even if not used for remote control
- os.unloadAPI("dig.lua")
- os.unloadAPI("flex.lua")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement