Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Dungeon excavator
- -- by SukaiPoppuGo
- --
- -- for turtle
- -- Excavate a dungeon, avoid mob_spawner digging
- local baseWidth, baseLength, deepLength = ...
- --Enlarge below levels
- local pyramid = true
- --But dig only 2 block high for each level
- local layerHeight = 2
- --Mod enable
- local MOD_PLETHORA = true
- --Usage
- local programUsage = string.format(
- "%s <baseWidth> <baseLength> <deepLength>\n",
- fs.getName(shell.getRunningProgram())
- )
- -- Args check
- baseWidth = tonumber(baseWidth)
- baseLength = tonumber(baseLength)
- deepLength = tonumber(deepLength)
- assert(turtle, "Dungeon excavator is an exclusive program for Turtles")
- assert(baseWidth and baseWidth > 0, programUsage.."baseWidth must be positive number")
- assert(baseLength and baseLength > 0, programUsage.."baseLength must be positive number")
- assert(deepLength and deepLength > 0, programUsage.."deepLength must be positive number")
- -- CONST -- turtle err msg
- local err = {}
- err.NOTHING_TO_DIG_HERE = "Nothing to dig here"
- err.MOVEMENT_OBSTRUCTED = "Movement obstructed"
- err.OUT_OF_FUEL = "Out of fuel"
- err.UNBREAKABLE_BLOCK_DETECTED = "Unbreakable block detected"
- err.NO_TOOL_TO_DIG_WITH = "No tool to dig with"
- -- Params
- local widthPos, lengthPos, deepPos
- local width, length, deep = math.floor(baseWidth), math.floor(baseLength), math.floor(deepLength)
- --Display
- local function header()
- local x,y = term.getCursorPos()
- term.setCursorPos(1,1)
- term.clearLine()
- term.blit(
- string.sub(
- string.format("%s", fs.getName(shell.getRunningProgram()))..
- string.rep(" ", term.getSize()),1, term.getSize()),
- string.rep("7", term.getSize()),
- string.rep("0", term.getSize())
- )
- term.setCursorPos(1,2)
- term.clearLine()
- term.blit(
- string.rep("\131", term.getSize()),
- string.rep("8", term.getSize()),
- string.rep("f", term.getSize())
- )
- term.setCursorPos(x,y)
- end
- --Param left / right corner
- local alt = true
- local padding = math.floor((term.getSize()-7)/2)
- term.clear()
- header()
- term.setCursorPos(2,3)
- term.write("Is turtle on right or left corner ?")
- term.setCursorPos(2,7)
- term.write("Press [\27] or [\26] key to set")
- term.setCursorPos(2,8)
- term.write("Press [enter] to confirm")
- while true do
- term.setCursorPos(alt and padding +2 or padding -2,4)
- term.clearLine()
- term.blit(
- alt and "\159\143\143\143\143\143\144" or "\143\143\143\143\143\144",
- alt and "ffffff0" or "fffff0",
- alt and "000000f" or "00000f"
- )
- term.setCursorPos(alt and padding +2 or padding -2,5)
- term.clearLine()
- term.blit(
- alt and "\149Right\149" or "\149Left\149",
- alt and "ffffff8" or "8ffff0",
- alt and "000000f" or "00000f"
- )
- term.setCursorPos(alt and padding +2 or padding -2,6)
- term.clearLine()
- term.blit(
- alt and "\130\131\131\131\131\131\129" or "\131\131\131\131\131\129",
- alt and "8888888" or "888888",
- alt and "fffffff" or "ffffff"
- )
- term.setCursorPos(1,9)
- local e,p = os.pullEvent("key")
- if p == keys.left then
- alt = false
- elseif p == keys.right then
- alt = true
- elseif p == keys.enter then
- os.pullEvent("key_up")
- term.setCursorPos(2,9)
- term.clearLine()
- print("Confirmed")
- break
- end
- end
- -- helper
- local startRightCorner = alt
- --Blacklist blocks (that turtle cannot dig)
- local _blacklist = {}
- local function blacklist(name)
- _blacklist[name] = true
- end
- local function whitelist(name)
- _blacklist[name] = false
- end
- local function isBlacklisted(block)
- if block and block.name and _blacklist[block.name] then
- return _blacklist[block.name]
- else
- return false
- end
- end
- --init blacklist
- blacklist("minecraft:mob_spawner")
- local function hasInventory(block, side)
- if MOD_PLETHORA then
- return type(peripheral.call(side,"list")) == "table"
- else
- return block and block.name and (
- block.name == "minecraft:chest"
- or block.name == "minecraft:trapped_chest"
- or block.name == "minecraft:dispenser"
- or block.name == "minecraft:dropper"
- or block.name == "minecraft:hopper"
- or block.name == "minecraft:furnace"
- or block.name == "minecraft:jukebox"
- or block.name == "ironchest:ironchest"
- )
- end
- end
- --Scan blocks
- local function scan()
- local bf, f = turtle.inspect()
- local bu, u = turtle.inspectUp()
- return bf, f, bu, u
- end
- --Turtle action
- --Dig columns of gravel/sand
- local function digHard()
- local test, msg = turtle.dig()
- while turtle.detect() and turtle.dig() do
- sleep()
- end
- return test, msg
- end
- local function digUpHard()
- local test, msg = turtle.digUp()
- while turtle.detectUp() and turtle.digUp() do
- sleep()
- end
- return test, msg
- end
- --Dont care if blocks below is gravel/sand
- local function digDownHard()
- return turtle.digDown()
- end
- --Avoid digging blacklisted blocks
- --Preserve loot when digging a block with inventory
- local function _digSafe(_inspect, _dig, _suck, _side)
- local test, block = _inspect()
- if test and isBlacklisted(block) then
- return false, err.UNBREAKABLE_BLOCK_DETECTED
- elseif test and hasInventory(block, _side) then
- while _suck() do end
- local r = {_dig()}
- sleep(.5)
- while _suck() do sleep() end
- return unpack(r)
- elseif test then
- return _dig()
- end
- return false, err.NOTHING_TO_DIG_HERE
- end
- local function safeDig()
- return _digSafe(turtle.inspect, digHard, turtle.suck, "front")
- end
- local function safeDigUp()
- return _digSafe(turtle.inspectUp, digUpHard, turtle.suckUp, "top")
- end
- local function safeDigDown()
- return _digSafe(turtle.inspectDown, digDownHard, turtle.suckDown, "bottom")
- end
- --Turtle moves
- local function requiredFuel(_width, _length)
- -->3 fuels/step -> up, down, forward (dig 3 block wide)
- -->3 fuels/turn -> 3 forward (dig 1 block wide)
- return _width * _length + _width
- end
- local function waitRefuel(minRequired)
- minRequired = minRequired and math.max(0,minRequired) or 0
- if turtle.getFuelLevel() >= minRequired then
- return true
- end
- term.clear()
- header()
- term.setCursorPos(2,3)
- term.write("Please refuel")
- while true do
- term.setCursorPos(2,4)
- term.clearLine()
- term.write(string.format(
- "Required: %s/%s",
- math.max(0, minRequired - turtle.getFuelLevel()),
- minRequired
- ))
- term.setCursorPos(2,5)
- term.clearLine()
- term.write(string.format(
- "Fuellevel: %s/%s (%s%s)",
- turtle.getFuelLevel(),
- turtle.getFuelLimit(),
- math.floor(turtle.getFuelLevel()*100/turtle.getFuelLimit()),
- "%"
- ))
- term.setCursorPos(2,6)
- term.clearLine()
- term.write("Insert fuel item")
- if turtle.getFuelLevel() > minRequired then
- term.setCursorPos(2,7)
- term.clearLine()
- term.write("then press [enter] to resume")
- end
- local notEnough = turtle.getFuelLevel() < minRequired
- local e, p = os.pullEvent(notEnough and "turtle_inventory" or nil)
- if e == "turtle_inventory" then
- for slot=1,16 do
- if turtle.getItemCount(slot) > 0 then
- turtle.select(slot)
- turtle.refuel(64)
- end
- end
- elseif e == "key" and p == keys.enter then
- os.pullEvent("key_up")
- break
- end
- end
- return turtle.getFuelLevel() >= minRequired
- end
- local function turn(turnRight)
- if turnRight then
- --start on the right corner
- --at the en of tunneling, turn to left
- turtle.turnLeft()
- else
- turtle.turnRight()
- end
- end
- --Walk one step
- --TODO
- local function step()
- digUpHard()
- digHard()
- turtle.forward()
- end
- --Pathfind to dodge a blacklisted block without digging
- --TODO
- local function dodgeBlock()
- end
- --Main
- for deepPos=1, deep, layerHeight do
- for wPos=1, width, 3 do --tunnel dig 3 blocks width
- --Between each layer, ask enough fuel
- if not waitRefuel(requiredFuel(width, length)) then
- printError("Terminated")
- break
- end
- shell.run("tunnel", length)
- print("Tunnel", length, "completed")
- if wPos+3 <= width then
- print(string.format("Reposition on %s side", alt and "right" or "left"))
- turn(alt)
- local stepToDo = 3
- if wPos+4 == width then
- stepToDo = 2
- elseif wPos+3 == width then
- stepToDo = 1
- end
- for i=1,stepToDo do
- step()
- end
- turn(alt)
- alt = not alt
- end
- end
- if deepPos + layerHeight >= deep then
- print("Finished")
- break
- end
- --Next level
- print("Next layer")
- for i=1,layerHeight do
- safeDigDown()
- turtle.down()
- end
- --Pyramid resize
- if pyramid then
- width = width+(layerHeight*2)
- length = length+(layerHeight*2)
- for i=1,layerHeight do
- step()
- end
- turn(alt)
- for i=1,layerHeight do
- step()
- end
- else
- turn(alt)
- end
- turn(alt)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement