robathome icon

Untitled

robathome | PRO | 09/30/25 03:03:14 PM UTC | 0 ⭐ | 305 👁️ | Never ⏰ | [MC auto miner]
text |

8.87 KB

|

None

|

0 👍

/

0 👎

-- mine_volume.lua  (CC:Tweaked Turtle)
-- Mines a prompted rectangular volume from a prompted relative start offset.
-- Optionally fills voids below the lowest Y of that volume with cobble (slot 2).
-- Assumptions:
--   - A fuel container is directly below start (y = -1).
--   - A dump container is directly below that (y = -2).
--   - Slot 2 contains cobblestone at start. Never fully consume or dump it.
 -- ======= User-tunable constants =======
local MIN_FUEL_BUFFER = 500
local COBBLE_SLOT = 2
local COBBLE_RESERVE = 16
local RETURN_INTERVAL_STEPS = 400
-- ======================================
 local t = turtle
 -- state
local pos = {x=0,y=0,z=0}   -- start is (0,0,0)
-- heading: 0=+X, 1=+Z, 2=-X, 3=-Z
local heading = 0
local start_heading = heading  -- capture initial facing to restore at the end
 -- utility: safe read
local function read_num(prompt)
  while true do
    io.write(prompt); local s = read()
    local n = tonumber(s)
    if n and math.floor(n) == n then return n end
    print("Enter an integer.")
  end
end
 local function read_yesno(prompt)
  while true do
    io.write(prompt.." [y/n]: "); local s = (read() or ""):lower()
    if s=="y" or s=="yes" then return true end
    if s=="n" or s=="no" then return false end
  end
end
 -- movement wrappers
 local function select_nonempty()
  for i=1,16 do if t.getItemCount(i)>0 then t.select(i); return true end end
  return false
end
 local function ensure_dig_forward()
  local tries = 0
  while t.detect() do
    t.dig(); sleep(0.1); tries = tries + 1
    if tries>50 then break end
  end
end
 local function ensure_dig_up()
  local tries = 0
  while t.detectUp() do
    t.digUp(); sleep(0.1); tries = tries + 1
    if tries>50 then break end
  end
end
 local function ensure_dig_down()
  local tries = 0
  while t.detectDown() do
    t.digDown(); sleep(0.1); tries = tries + 1
    if tries>50 then break end
  end
end
 local function forward()
  local tries=0
  while not t.forward() do
    ensure_dig_forward()
    if not t.forward() then
      t.attack(); sleep(0.1)
      tries=tries+1; if tries>50 then return false end
    end
  end
  if heading==0 then pos.x=pos.x+1
  elseif heading==1 then pos.z=pos.z+1
  elseif heading==2 then pos.x=pos.x-1
  else pos.z=pos.z-1 end
  return true
end
 local function up()
  local tries=0
  while not t.up() do
    ensure_dig_up()
    if not t.up() then
      t.attackUp(); sleep(0.1)
      tries=tries+1; if tries>50 then return false end
    end
  end
  pos.y=pos.y+1; return true
end
 local function down()
  local tries=0
  while not t.down() do
    ensure_dig_down()
    if not t.down() then
      t.attackDown(); sleep(0.1)
      tries=tries+1; if tries>50 then return false end
    end
  end
  pos.y=pos.y-1; return true
end
 local function turnLeft()  heading=(heading+3)%4; t.turnLeft()  end
local function turnRight() heading=(heading+1)%4; t.turnRight() end
 local function face(dir)
  while heading~=dir do
    local diff = (dir - heading) % 4
    if diff==1 then turnRight()
    elseif diff==3 then turnLeft()
    else turnRight() end
  end
end
 local function mine_step_forward()
  ensure_dig_forward()
  forward()
  ensure_dig_up()
  ensure_dig_down()
end
 -- inventory helpers
 local function free_slots()
  local free=0
  for i=1,16 do
    if i~=COBBLE_SLOT and t.getItemCount(i)==0 then free=free+1 end
  end
  return free
end
 local function need_dump()
  return free_slots()==0
end
 -- refuel from the fuel container directly below start
local function refuel_from_home()
  for _=1,8 do
    for i=1,16 do
      if i~=COBBLE_SLOT then
        t.select(i)
        t.suckDown(64)
        if t.refuel(64) then
          if turtle.getFuelLevel()>=MIN_FUEL_BUFFER then return end
        else
          t.dropDown(64)
        end
      end
    end
    sleep(0.2)
  end
end
 -- go_home with optional final facing
local function go_home(final_face_dir)
  while pos.y>0 do up() end
  while pos.y<0 do down() end
  if pos.x>0 then face(2); for _=1,pos.x do forward() end
  elseif pos.x<0 then face(0); for _=1,-pos.x do forward() end end
  if pos.z>0 then face(3); for _=1,pos.z do forward() end
  elseif pos.z<0 then face(1); for _=1,-pos.z do forward() end end
  if final_face_dir~=nil then face(final_face_dir) end
end
 -- service pocket near dump chest; preserves caller state
local function ensure_dump_service()
  local saved = {x=pos.x,y=pos.y,z=pos.z,h=heading}
  -- assume starting from home
  face(0)
  ensure_dig_forward(); forward()  -- (1,0,0)
  ensure_dig_down(); down()        -- (1,-1,0)
  ensure_dig_down(); down()        -- (1,-2,0)
  face(2); if t.detect() then t.dig() end
  forward()                        -- (0,-2,0)
  face(0); forward()               -- (1,-2,0)
  up(); up()                       -- (1,0,0)
  face(2); forward()               -- (0,0,0)
  face(saved.h)
  -- restore explicit pos since we tracked moves
  pos = {x=saved.x,y=saved.y,z=saved.z}; heading = saved.h
end
 -- dump inventory except reserved cobble; preserves caller state and returns to home
local function dump_at_home()
  local saved = {x=pos.x,y=pos.y,z=pos.z,h=heading}
  -- to cavity
  face(0); forward()          -- (1,0,0); pos updated
  down(); down()              -- (1,-2,0)
  face(2); forward()          -- (0,-2,0)
  face(2)
  for i=1,16 do
    if i~=COBBLE_SLOT then
      local cnt = t.getItemCount(i)
      if cnt>0 then t.select(i); t.drop(64) end
    end
  end
  -- back to home
  face(0); forward()          -- (1,-2,0)
  up(); up()                  -- (1,0,0)
  face(2); forward()          -- (0,0,0)
  face(saved.h)
  pos = {x=saved.x,y=saved.y,z=saved.z}; heading = saved.h
end
 local function goto_rel(tx,ty,tz)
  while pos.y < ty do up() end
  while pos.y > ty do down() end
  if pos.x < tx then face(0); for _=1, tx-pos.x do mine_step_forward() end
  elseif pos.x > tx then face(2); for _=1, pos.x-tx do mine_step_forward() end end
  if pos.z < tz then face(1); for _=1, tz-pos.z do mine_step_forward() end
  elseif pos.z > tz then face(3); for _=1, pos.z-tz do mine_step_forward() end end
end
 local function ensure_fuel()
  if t.getFuelLevel()=="unlimited" then return end
  if t.getFuelLevel() < MIN_FUEL_BUFFER then
    local saved = {x=pos.x,y=pos.y,z=pos.z,h=heading}
    go_home()
    refuel_from_home()
    ensure_dump_service()
    goto_rel(saved.x,saved.y,saved.z); face(saved.h)
  end
end
 local function maybe_fill_void_below(filling_enabled)
  if not filling_enabled then return end
  if t.detectDown() then return end
  local cnt = t.getItemCount(COBBLE_SLOT)
  if cnt and cnt > COBBLE_RESERVE then
    t.select(COBBLE_SLOT)
    t.placeDown()
  end
end
 local function mine_cell(floorY, filling_enabled)
  ensure_dig_up()
  ensure_dig_down()
  if pos.y==floorY then maybe_fill_void_below(filling_enabled) end
end
 local step_counter = 0
local function periodic_service()
  step_counter = step_counter + 1
  if step_counter >= RETURN_INTERVAL_STEPS or need_dump() or (t.getFuelLevel()~="unlimited" and t.getFuelLevel()<MIN_FUEL_BUFFER) then
    local saved = {x=pos.x,y=pos.y,z=pos.z,h=heading}
    go_home()
    refuel_from_home()
    ensure_dump_service()
    dump_at_home()
    goto_rel(saved.x,saved.y,saved.z); face(saved.h)
    step_counter = 0
  end
end
 -- ===== Main =====
 print("Enter volume dimensions (X width, Z length, Y height) in blocks.")
local X = math.abs(read_num("X (>=1): "))
local Z = math.abs(read_num("Z (>=1): "))
local Y = math.abs(read_num("Y (>=1): "))
 print("Enter relative start offset vector from current position.")
local sx = read_num("Start offset dx (right +, left -): ")
local sy = read_num("Start offset dy (up +, down -): ")
local sz = read_num("Start offset dz (forward +, back -): ")
 local fill_voids = read_yesno("Fill empty space below the volume’s lowest Y with cobble from slot 2?")
 print("Preparing…")
ensure_fuel()
go_home()            -- ensure pos=(0,0,0)
ensure_dump_service()
refuel_from_home()
 -- move to start offset
goto_rel(sx, sy, sz)
 -- define floorY in current relative coordinates
local floorY = pos.y
 -- mine by layers from floor up
for layer=0,(Y-1) do
  goto_rel(pos.x, floorY + layer, pos.z)
  local dirX = 1
  goto_rel(sx, floorY + layer, sz)
  face(0)
  for rz=0,(Z-1) do
    if dirX==1 then face(0) else face(2) end
    for rx=0,(X-1) do
      mine_cell(floorY, fill_voids)
      if not (rx==X-1 and rz==Z-1) then
        if rx < X-1 then
          ensure_fuel()
          mine_step_forward()
        end
      end
      periodic_service()
    end
    if rz < Z-1 then
      face(1); mine_step_forward()
      dirX = 1 - dirX
    end
  end
end
 -- finish: return home, unload/refuel, then restore original facing
go_home()
ensure_dump_service()
dump_at_home()
refuel_from_home()
face(start_heading)
print("Done.")
 

Comments