Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- resumable signed-volume miner with start offset, slow start, return+dump
- local ST="mine_state.txt"
- local t=turtle
- -- input: numbers 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()
- 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 -- pos/orient rel to start
- }
- save(S)
- end
- 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 and S.slow>0 then sleep(5); S.slow=S.slow-1; save(S) end end
- -- moves that 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 (stand in adjacent space, NOT on first mined block)
- 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 (vertical, then X, then Z) in mined 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 (0,0,0). below is chest A for [cobble,dirt,gravel,sand]. chest B is one lower.
- local function dump_home()
- -- pass 1: drop selected down into chest A
- local ok = {["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 ok[d.name] then t.select(s); t.dropDown() end
- end
- -- pass 2: side-drop everything else into chest B (y=-2)
- -- carve a tiny service to chest B side and drop forward
- face(0); digf(); F() -- (1,0,0)
- dgd(); D() ; dgd(); D() -- (1,-2,0)
- face(2) -- face -X (toward chests)
- for s=1,16 do
- local d=t.getItemDetail(s)
- if d and not ok[d.name] then t.select(s); t.drop() end
- end
- face(0); F() -- (1,-2,1) -> step out to avoid re-picking? optional
- face(2); F() -- back to (1,-2,0)
- face(0); -- reorient
- -- return to home (0,0,0)
- face(2); F() -- (0,-2,0)
- U(); U(); -- (0,0,0)
- end
- -- === run ===
- 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<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
- -- return to start, dump, restore facing
- goto_rel(0,0,0)
- dump_home()
- goto_rel(0,0,0)
- face(S.sh)
- if fs.exists(ST) then fs.delete(ST) end
- print("done")
Advertisement
Add Comment
Please, Sign In to add comment