-- resumable signed-volume miner with start offset, slow start, return+dual-dump local ST="mine_state.txt" local t=turtle 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 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 local S=load() if not S then local X=rd("X (signed fwd/back)"); if X=="resume" then S=load() 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, oy=OY, oz=OZ, at_off=false, slow=10, px=0,py=0,pz=0, h=0, sh=0 } save(S) end end 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 local function tick() if S.slow and S.slow>0 then sleep(5); S.slow=S.slow-1; save(S) end end 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 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 local function goto_rel(x,y,z) while S.pyy do dgd(); D() end if S.pxx then face(2); for i=1,S.px-x do digf(); F() end end if S.pzz then face(3); for i=1,S.pz-z do digf(); F() end end end local function dump_home() -- must be at (0,0,0) 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() dgd(); D(); dgd(); D() face(2) 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() face(2); digf(); F() face(0) -- now near home; ensure exact home: goto_rel(0,0,0) end go_off() if S.xneg then T2() 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