-- miner_startup.lua -- Ultra-dumb miner. Verbose local console + heartbeats. -- Requires: wireless (ender) modem; label set via: label set miner_alpha local PROTOCOL = "minesys:v1" local HEARTBEAT_SEC = 2 local modem = peripheral.find("modem", function(_, p) return p.isWireless() end) if not modem then error("No wireless modem") end if not turtle then error("Run on a turtle") end rednet.open(peripheral.getName(modem)) -- ---------------- console/status ---------------- local state = { status = "waiting", extra = nil, facing = "N", pos = nil, fuel = turtle.getFuelLevel(), lastDraw = 0, } local function invStats() local empty = 0 for i=1,16 do if turtle.getItemCount(i)==0 then empty = empty + 1 end end local pct = (empty/16)*100 return { freeSlots = empty, freePct = pct } end local function now() return os.epoch("utc") end local function gpsPos() local x, y, z = gps.locate(1) if x then state.pos = {x=x,y=y,z=z} end return x, y, z end local function setStatus(s, extra) state.status = s or state.status state.extra = extra or nil end local function drawConsole(force) local t = now() if not force and (t - state.lastDraw) < 100 then return end -- 0.1s throttle state.lastDraw = t term.setBackgroundColor(colors.black) term.setTextColor(colors.white) term.clear() term.setCursorPos(1,1) local lbl = os.getComputerLabel() or ("id"..os.getComputerID()) print(("Miner %s"):format(lbl)) print(("Fuel: %s"):format(tostring(state.fuel))) local p = state.pos print(("Pos: %s"):format(p and ("("..p.x..","..p.y..","..p.z..")") or "unknown")) print(("Facing: %s"):format(state.facing)) print(("Status: %s"):format(state.status)) if state.extra then -- Render compact progress lines if state.extra.kind=="move" then print(("- Move %s: %d/%d"):format(state.extra.axis, state.extra.step, state.extra.total)) elseif state.extra.kind=="clear" then print(("- Clear LxWxH: %d×%d×%d"):format(state.extra.L, state.extra.W, state.extra.H)) print((" Layer: %d/%d Row: %d/%d Step: %d/%d"):format( state.extra.layer, state.extra.H, state.extra.row, state.extra.W, state.extra.step, state.extra.L )) elseif state.extra.kind=="face" then print(("- Face: %s"):format(state.extra.dir)) elseif state.extra.kind=="note" and state.extra.msg then print(("- Note: %s"):format(state.extra.msg)) end end end local function hb() state.fuel = turtle.getFuelLevel() gpsPos() local msg = { t = now(), op = "status", id = os.getComputerID(), label = os.getComputerLabel(), pos = state.pos, fuel = state.fuel, facing = state.facing, status = state.status, extra = state.extra, inv = invStats(), } rednet.broadcast(msg, PROTOCOL) end local function report(s, extra, forceDraw) setStatus(s, extra) drawConsole(forceDraw) hb() end -- ---------------- motion primitives ---------------- local DIRS = {N=0, E=1, S=2, W=3} local dirNames = {"N","E","S","W"} local function setFacing(newDir) if not DIRS[newDir] then return false, "bad dir" end if state.facing == newDir then report("waiting", {kind="face", dir=newDir}) return true end local idx = DIRS[state.facing]; local tgt = DIRS[newDir] local diff = (tgt - idx) % 4 report("waiting", {kind="face", dir=newDir}, true) if diff == 1 then turtle.turnRight() elseif diff == 2 then turtle.turnRight(); turtle.turnRight() elseif diff == 3 then turtle.turnLeft() end state.facing = newDir report("waiting", {kind="face", dir=newDir}) return true end local function digForward() while turtle.detect() do turtle.dig() sleep(0.15) end end local function forward(n) n = math.max(0, n or 1) for i=1, n do report("moving to", {kind="move", axis="fwd", step=i, total=n}) digForward() local tries=0 while not turtle.forward() do digForward() tries=tries+1 if tries>50 then report("waiting", {kind="note", msg="blocked fwd"}) return false, "blocked" end sleep(0.15) end end report("waiting") return true end local function up(n) n = math.max(0, n or 1) for i=1, n do report("moving to", {kind="move", axis="up", step=i, total=n}) while turtle.detectUp() do turtle.digUp(); sleep(0.15) end local tries=0 while not turtle.up() do while turtle.detectUp() do turtle.digUp(); sleep(0.15) end tries=tries+1 if tries>50 then report("waiting", {kind="note", msg="blocked up"}) return false, "blocked" end sleep(0.15) end end report("waiting") return true end local function down(n) n = math.max(0, n or 1) for i=1, n do report("moving to", {kind="move", axis="down", step=i, total=n}) while turtle.detectDown() do turtle.digDown(); sleep(0.15) end local tries=0 while not turtle.down() do while turtle.detectDown() do turtle.digDown(); sleep(0.15) end tries=tries+1 if tries>50 then report("waiting", {kind="note", msg="blocked down"}) return false, "blocked" end sleep(0.15) end end report("waiting") return true end -- ---------------- clear area ---------------- local function clearArea(length, width, height, startDir) local L = math.max(1, length or 1) local W = math.max(1, width or 1) local H = math.max(1, height or 1) setFacing(startDir or state.facing) local function sweepRow(len, layerIdx, rowIdx) for i=1,len do report("clearing area", { kind="clear", L=L, W=W, H=H, layer=layerIdx, row=rowIdx, step=i }) digForward() if i