Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- minimal resumable volume miner w/ signed dims and quit/resume
- local ST="mine_state.txt"
- local function rd(p)
- io.write(p..": ")
- local s=read()
- if not s then return nil end
- s=s:lower()
- if s=="quit" then print("bye") error() end
- if s=="resume" then return "resume" end
- local n=tonumber(s); if not n then print("num/quit/resume"); 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
- -- moves
- local t=turtle
- local function digf() while t.detect() do t.dig() end end
- local function df() while not t.forward() do t.attack(); digf() end end
- local function dug() while t.detectUp() do t.digUp() end end
- local function ddn() while t.detectDown() do t.digDown() end end
- local function up() while not t.up() do t.attackUp(); dug() end end
- local function dn() while not t.down() do t.attackDown(); ddn() end end
- -- state (progress)
- local S = load()
- if S=="resume" then S=nil end
- if S then
- print("resuming")
- else
- 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 serpentine)")
- local xlen=math.abs(X); local ylen=math.abs(Y); local zlen=math.abs(Z)
- local xneg = X<0; local yneg = Y<0; local zneg = Z<0
- -- starting facing: forward mines along +X; flip if X<0
- if xneg then t.turnLeft(); t.turnLeft() end
- S={xlen=xlen,ylen=ylen,zlen=zlen,x=1,y=1,z=1,dir=0,xneg=xneg,yneg=yneg,zneg=zneg,started=true}
- save(S)
- end
- end
- -- helpers to go to next line and layer based on signs
- local function next_row(S)
- if S.z>=S.zlen then return false end
- if not S.zneg then
- t.turnRight(); digf(); df(); t.turnRight()
- else
- t.turnLeft(); digf(); df(); t.turnLeft()
- end
- S.z=S.z+1; S.dir=1-S.dir; save(S)
- return true
- end
- local function next_layer(S)
- if S.y>=S.ylen then return false end
- if not S.yneg then dug(); up() else ddn(); dn() end
- -- reset row to 1 and go to row start
- if S.z%2==1 then
- -- we ended at row end; go back to row start for new layer
- t.turnLeft(); t.turnLeft()
- for i=1,S.xlen-1 do digf(); df() end
- t.turnLeft(); t.turnLeft()
- end
- -- go to first row start cell in new layer
- S.y=S.y+1; S.z=1; S.dir=0; save(S)
- return true
- end
- -- main loop: layers -> rows -> cells
- while S.y<=S.ylen do
- -- at start of a row, face correct dir
- if S.dir==0 then
- -- face forward
- else
- t.turnLeft(); t.turnLeft()
- end
- -- advance along X for remaining cells in this row
- local startx = S.x
- for i=startx,S.xlen do
- -- mine current cell
- dug(); ddn()
- -- move forward unless last cell of last row/layer
- local last = (i==S.xlen) and (S.z==S.zlen) and (S.y==S.ylen)
- if not last then
- if i<S.xlen then digf(); df() end
- end
- S.x = i+1; save(S)
- end
- -- row done
- S.x=1
- if not next_row(S) then
- -- rows done in this layer
- if not next_layer(S) then break end
- end
- end
- -- finished: delete state and dump dirt/cobble
- if fs.exists(ST) then fs.delete(ST) end
- for s=1,16 do
- local d=t.getItemDetail(s)
- if d and (d.name=="minecraft:dirt" or d.name=="minecraft:cobblestone") then
- t.select(s); t.dropDown()
- end
- end
- print("done")
Advertisement
Add Comment
Please, Sign In to add comment