Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- 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.")
Advertisement
Add Comment
Please, Sign In to add comment