robathome icon

Untitled

robathome | PRO | 09/30/25 03:44:07 PM UTC | 0 ⭐ | 395 👁️ | Never ⏰ | []
text |

5.37 KB

|

None

|

0 👍

/

0 👎

-- resumable signed-volume miner with start offset, slow start, return+dual-dump (fixed nil compares)
local ST="mine_state.txt"
local t=turtle
 -- read number or "quit"/"resume"
local function rd(p)
  io.write(p..": ")
  local s=read() or ""
  s=s:lower()
  if s=="quit" then error() end
  if s=="resume" then return "resume" end
  local n=tonumber(s)
  if not n then return rd(p) end
  return n
end
 local function save(S)
  local h=fs.open(ST,"w"); h.write(textutils.serialize(S)); h.close()
end
local function load()
  if not fs.exists(ST) then return nil end
  local h=fs.open(ST,"r"); local s=h.readAll(); h.close()
  return textutils.unserialize(s)
end
 -- dig helpers
local function digf() while t.detect() do t.dig() end end
local function dgu() while t.detectUp() do t.digUp() end end
local function dgd() while t.detectDown() do t.digDown() end end
 -- state
local S=load()
 -- start or resume safely
if not S then
  local X=rd("X (signed fwd/back)")
  if X=="resume" then
    S=load()
    if not S then print("no saved state"); return end
  end
  if not S then
    local Y=rd("Y (signed up/down)")
    local Z=rd("Z (signed right/left)")
    local OX=rd("OffX (signed fwd/back; stand beside first mined)")
    local OY=rd("OffY (signed up/down)")
    local OZ=rd("OffZ (signed right/left)")
    S={
      xlen=math.abs(X), ylen=math.abs(Y), zlen=math.abs(Z),
      xneg=X<0, yneg=Y<0, zneg=Z<0,
      x=1, y=1, z=1, dir=0,
      ox=OX or 0, oy=OY or 0, oz=OZ or 0, at_off=false,
      slow=10,
      px=0, py=0, pz=0, h=0, sh=0
    }
    S.sh=S.h  -- capture initial heading
    save(S)
  end
else
  -- ensure required keys exist on old saves
  S.ox=S.ox or 0; S.oy=S.oy or 0; S.oz=S.oz or 0
  S.px=S.px or 0; S.py=S.py or 0; S.pz=S.pz or 0
  S.h=S.h or 0;  S.sh=S.sh or 0
  S.slow=S.slow or 0
  S.at_off = S.at_off or false
end
 -- turns and facing
local function TL() t.turnLeft();  S.h=(S.h+3)%4 end
local function TR() t.turnRight(); S.h=(S.h+1)%4 end
local function T2() TL(); TL() end
local function face(d) while S.h~=d do if (d-S.h)%4==1 then TR() else TL() end end end
 -- slow-start pause on first 10 moves
local function tick() if S.slow>0 then sleep(5); S.slow=S.slow-1; save(S) end end
 -- moves track pos
local function F()
  local n=0
  while not t.forward() do t.attack(); digf(); n=n+1; if n>50 then return end end
  if S.h==0 then S.px=S.px+1 elseif S.h==1 then S.pz=S.pz+1 elseif S.h==2 then S.px=S.px-1 else S.pz=S.pz-1 end
  tick(); save(S)
end
local function U()
  local n=0
  while not t.up() do t.attackUp(); dgu(); n=n+1; if n>50 then return end end
  S.py=S.py+1; tick(); save(S)
end
local function D()
  local n=0
  while not t.down() do t.attackDown(); dgd(); n=n+1; if n>50 then return end end
  S.py=S.py-1; tick(); save(S)
end
 -- go to start offset once (adjacent space)
local function go_off()
  if S.at_off then return end
  if S.oy>0 then for i=1,S.oy do dgu(); U() end
  elseif S.oy<0 then for i=1,-S.oy do dgd(); D() end end
  if S.oz>0 then TR(); for i=1,S.oz do digf(); F() end; TL()
  elseif S.oz<0 then TL(); for i=1,-S.oz do digf(); F() end; TR() end
  if S.ox>0 then for i=1,S.ox do digf(); F() end
  elseif S.ox<0 then T2(); for i=1,-S.ox do digf(); F() end; T2() end
  S.at_off=true; save(S)
end
 -- Manhattan goto in carved space
local function goto_rel(x,y,z)
  while S.py<y do dgu(); U() end
  while S.py>y do dgd(); D() end
  if S.px<x then face(0); for i=1,x-S.px do digf(); F() end
  elseif S.px>x then face(2); for i=1,S.px-x do digf(); F() end end
  if S.pz<z then face(1); for i=1,z-S.pz do digf(); F() end
  elseif S.pz>z then face(3); for i=1,S.pz-z do digf(); F() end end
end
 -- dump at home using two chests: y=-1 for cobble/dirt/gravel/sand; y=-2 for everything else
local function dump_home()
  local A={["minecraft:cobblestone"]=1,["minecraft:dirt"]=1,["minecraft:gravel"]=1,["minecraft:sand"]=1}
  for s=1,16 do local d=t.getItemDetail(s); if d and A[d.name] then t.select(s); t.dropDown() end end
  face(0); digf(); F()           -- (1,0,0)
  dgd(); D(); dgd(); D()         -- (1,-2,0)
  face(2)                         -- toward chests
  for s=1,16 do local d=t.getItemDetail(s); if d and not A[d.name] then t.select(s); t.drop() end end
  face(0); dgu(); U(); dgu(); U() -- back to y=0
  face(2); digf(); F()            -- back to (0,0,0)
  face(0)
  goto_rel(0,0,0)
end
 -- === run ===
go_off()
if S.xneg then T2() end
 -- guard missing dims on resume
if not (S.xlen and S.ylen and S.zlen) then print("bad state"); return end
if not (S.x and S.y and S.z) then S.x=1; S.y=1; S.z=1 end
if S.dir==nil then S.dir=0 end
 while S.y<=S.ylen do
  if S.dir==1 then T2() end
  for i=S.x,S.xlen do
    dgu(); dgd()
    local last=(i==S.xlen) and (S.z==S.zlen) and (S.y==S.ylen)
    if not last and i<S.xlen then digf(); F() end
    S.x=i+1; save(S)
  end
  S.x=1
  if S.z<S.zlen then
    if not S.zneg then TR(); digf(); F(); TR() else TL(); digf(); F(); TL() end
    S.z=S.z+1; S.dir=1-S.dir; save(S)
  else
    if S.y<S.ylen then
      if not S.yneg then dgu(); U() else dgd(); D() end
      if (S.z%2)==1 then T2(); for i=1,S.xlen-1 do digf(); F() end; T2() end
      S.y=S.y+1; S.z=1; S.dir=0; save(S)
    else
      break
    end
  end
end
 goto_rel(0,0,0)
dump_home()
goto_rel(0,0,0)
face(S.sh or 0)
if fs.exists(ST) then fs.delete(ST) end
print("done")
 

Comments