Advertisement
skypop

CC DungeonExcavator

Aug 3rd, 2018
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.43 KB | None | 0 0
  1. -- Dungeon excavator
  2. -- by SukaiPoppuGo
  3. --
  4. -- for turtle
  5. -- Excavate a dungeon, avoid mob_spawner digging
  6.  
  7. local baseWidth, baseLength, deepLength = ...
  8.  
  9. --Enlarge below levels
  10. local pyramid = true
  11.  
  12. --But dig only 2 block high for each level
  13. local layerHeight = 2
  14.  
  15. --Mod enable
  16. local MOD_PLETHORA = true
  17.  
  18. --Usage
  19. local programUsage = string.format(
  20.     "%s <baseWidth> <baseLength> <deepLength>\n",
  21.     fs.getName(shell.getRunningProgram())
  22. )
  23.  
  24. -- Args check
  25. baseWidth  = tonumber(baseWidth)
  26. baseLength = tonumber(baseLength)
  27. deepLength = tonumber(deepLength)
  28. assert(turtle, "Dungeon excavator is an exclusive program for Turtles")
  29. assert(baseWidth  and baseWidth  > 0, programUsage.."baseWidth must be positive number")
  30. assert(baseLength and baseLength > 0, programUsage.."baseLength must be positive number")
  31. assert(deepLength and deepLength > 0, programUsage.."deepLength must be positive number")
  32.  
  33.  
  34. -- CONST -- turtle err msg
  35. local err = {}
  36. err.NOTHING_TO_DIG_HERE = "Nothing to dig here"
  37. err.MOVEMENT_OBSTRUCTED = "Movement obstructed"
  38. err.OUT_OF_FUEL = "Out of fuel"
  39. err.UNBREAKABLE_BLOCK_DETECTED = "Unbreakable block detected"
  40. err.NO_TOOL_TO_DIG_WITH = "No tool to dig with"
  41.  
  42. -- Params
  43. local widthPos, lengthPos, deepPos
  44. local width, length, deep = math.floor(baseWidth), math.floor(baseLength), math.floor(deepLength)
  45.  
  46. --Display
  47. local function header()
  48.     local x,y = term.getCursorPos()
  49.     term.setCursorPos(1,1)
  50.     term.clearLine()
  51.     term.blit(
  52.         string.sub(
  53.             string.format("%s", fs.getName(shell.getRunningProgram()))..
  54.             string.rep(" ", term.getSize()),1, term.getSize()),
  55.         string.rep("7", term.getSize()),
  56.         string.rep("0", term.getSize())
  57.     )
  58.     term.setCursorPos(1,2)
  59.     term.clearLine()
  60.     term.blit(
  61.         string.rep("\131", term.getSize()),
  62.         string.rep("8", term.getSize()),
  63.         string.rep("f", term.getSize())
  64.     )
  65.     term.setCursorPos(x,y)
  66. end
  67.  
  68. --Param left / right corner
  69. local alt = true
  70. local padding = math.floor((term.getSize()-7)/2)
  71. term.clear()
  72. header()
  73. term.setCursorPos(2,3)
  74. term.write("Is turtle on right or left corner ?")
  75.  
  76. term.setCursorPos(2,7)
  77. term.write("Press [\27] or [\26] key to set")
  78. term.setCursorPos(2,8)
  79. term.write("Press [enter] to confirm")
  80. while true do
  81.     term.setCursorPos(alt and padding +2 or padding -2,4)
  82.     term.clearLine()
  83.     term.blit(
  84.         alt and "\159\143\143\143\143\143\144" or "\143\143\143\143\143\144",
  85.         alt and "ffffff0" or "fffff0",
  86.         alt and "000000f" or "00000f"
  87.     )
  88.     term.setCursorPos(alt and padding +2 or padding -2,5)
  89.     term.clearLine()
  90.     term.blit(
  91.         alt and "\149Right\149" or "\149Left\149",
  92.         alt and "ffffff8" or "8ffff0",
  93.         alt and "000000f" or "00000f"
  94.     )
  95.     term.setCursorPos(alt and padding +2 or padding -2,6)
  96.     term.clearLine()
  97.     term.blit(
  98.         alt and "\130\131\131\131\131\131\129" or  "\131\131\131\131\131\129",
  99.         alt and "8888888" or "888888",
  100.         alt and "fffffff" or "ffffff"
  101.     )
  102.     term.setCursorPos(1,9)
  103.     local e,p = os.pullEvent("key")
  104.     if p == keys.left then
  105.         alt = false
  106.     elseif p == keys.right then
  107.         alt = true
  108.     elseif p == keys.enter then
  109.         os.pullEvent("key_up")
  110.         term.setCursorPos(2,9)
  111.         term.clearLine()
  112.         print("Confirmed")
  113.         break
  114.     end
  115. end
  116. -- helper
  117. local startRightCorner = alt
  118.  
  119. --Blacklist blocks (that turtle cannot dig)
  120. local _blacklist = {}
  121. local function blacklist(name)
  122.     _blacklist[name] = true
  123. end
  124. local function whitelist(name)
  125.     _blacklist[name] = false
  126. end
  127. local function isBlacklisted(block)
  128.     if block and block.name and _blacklist[block.name] then
  129.         return _blacklist[block.name]
  130.     else
  131.         return false
  132.     end
  133. end
  134.  
  135. --init blacklist
  136. blacklist("minecraft:mob_spawner")
  137.  
  138. local function hasInventory(block, side)
  139.     if MOD_PLETHORA then
  140.         return type(peripheral.call(side,"list")) == "table"
  141.     else
  142.         return block and block.name and (
  143.                block.name == "minecraft:chest"
  144.             or block.name == "minecraft:trapped_chest"
  145.             or block.name == "minecraft:dispenser"
  146.             or block.name == "minecraft:dropper"
  147.             or block.name == "minecraft:hopper"
  148.             or block.name == "minecraft:furnace"
  149.             or block.name == "minecraft:jukebox"
  150.             or block.name == "ironchest:ironchest"
  151.         )
  152.     end
  153. end
  154.  
  155. --Scan blocks
  156. local function scan()
  157.     local bf, f = turtle.inspect()
  158.     local bu, u = turtle.inspectUp()
  159.     return bf, f, bu, u
  160. end
  161.  
  162. --Turtle action
  163. --Dig columns of gravel/sand
  164. local function digHard()
  165.     local test, msg = turtle.dig()
  166.     while turtle.detect() and turtle.dig() do
  167.         sleep()
  168.     end
  169.     return test, msg
  170. end
  171. local function digUpHard()
  172.     local test, msg = turtle.digUp()
  173.     while turtle.detectUp() and turtle.digUp() do
  174.         sleep()
  175.     end
  176.     return test, msg
  177. end
  178. --Dont care if blocks below is gravel/sand
  179. local function digDownHard()
  180.     return turtle.digDown()
  181. end
  182.  
  183. --Avoid digging blacklisted blocks
  184. --Preserve loot when digging a block with inventory
  185. local function _digSafe(_inspect, _dig, _suck, _side)
  186.     local test, block = _inspect()
  187.     if test and isBlacklisted(block) then
  188.         return false, err.UNBREAKABLE_BLOCK_DETECTED
  189.     elseif test and hasInventory(block, _side) then
  190.         while _suck() do end
  191.         local r = {_dig()}
  192.         sleep(.5)
  193.         while _suck() do sleep() end
  194.         return unpack(r)
  195.     elseif test then
  196.         return _dig()
  197.     end
  198.     return false, err.NOTHING_TO_DIG_HERE
  199. end
  200. local function safeDig()
  201.     return _digSafe(turtle.inspect, digHard, turtle.suck, "front")
  202. end
  203. local function safeDigUp()
  204.     return _digSafe(turtle.inspectUp, digUpHard, turtle.suckUp, "top")
  205. end
  206. local function safeDigDown()
  207.     return _digSafe(turtle.inspectDown, digDownHard, turtle.suckDown, "bottom")
  208. end
  209.  
  210.  
  211. --Turtle moves
  212. local function requiredFuel(_width, _length)
  213.     -->3 fuels/step -> up, down, forward (dig 3 block wide)
  214.     -->3 fuels/turn -> 3 forward (dig 1 block wide)
  215.     return _width * _length + _width
  216. end
  217.  
  218. local function waitRefuel(minRequired)
  219.     minRequired = minRequired and math.max(0,minRequired) or 0
  220.     if turtle.getFuelLevel() >= minRequired then
  221.         return true
  222.     end
  223.     term.clear()
  224.     header()
  225.     term.setCursorPos(2,3)
  226.     term.write("Please refuel")
  227.     while true do
  228.         term.setCursorPos(2,4)
  229.         term.clearLine()
  230.         term.write(string.format(
  231.             "Required: %s/%s",
  232.             math.max(0, minRequired - turtle.getFuelLevel()),
  233.             minRequired
  234.         ))
  235.         term.setCursorPos(2,5)
  236.         term.clearLine()
  237.         term.write(string.format(
  238.             "Fuellevel: %s/%s (%s%s)",
  239.             turtle.getFuelLevel(),
  240.             turtle.getFuelLimit(),
  241.             math.floor(turtle.getFuelLevel()*100/turtle.getFuelLimit()),
  242.             "%"
  243.         ))
  244.         term.setCursorPos(2,6)
  245.         term.clearLine()
  246.         term.write("Insert fuel item")
  247.         if turtle.getFuelLevel() > minRequired then
  248.             term.setCursorPos(2,7)
  249.             term.clearLine()
  250.             term.write("then press [enter] to resume")
  251.         end
  252.         local notEnough = turtle.getFuelLevel() < minRequired
  253.         local e, p = os.pullEvent(notEnough and "turtle_inventory" or nil)
  254.         if e == "turtle_inventory" then
  255.             for slot=1,16 do
  256.                 if turtle.getItemCount(slot) > 0 then
  257.                     turtle.select(slot)
  258.                     turtle.refuel(64)
  259.                 end
  260.             end
  261.         elseif e == "key" and p == keys.enter then
  262.             os.pullEvent("key_up")
  263.             break
  264.         end
  265.     end
  266.     return turtle.getFuelLevel() >= minRequired
  267. end
  268.  
  269. local function turn(turnRight)
  270.     if turnRight then
  271.         --start on the right corner
  272.         --at the en of tunneling, turn to left
  273.         turtle.turnLeft()
  274.     else
  275.         turtle.turnRight()
  276.     end
  277. end
  278.  
  279. --Walk one step
  280. --TODO
  281. local function step()
  282.     digUpHard()
  283.     digHard()
  284.     turtle.forward()
  285. end
  286.  
  287. --Pathfind to dodge a blacklisted block without digging
  288. --TODO
  289. local function dodgeBlock()
  290.  
  291. end
  292.  
  293.  
  294. --Main
  295. for deepPos=1, deep, layerHeight do
  296.     for wPos=1, width, 3 do --tunnel dig 3 blocks width
  297.         --Between each layer, ask enough fuel
  298.         if not waitRefuel(requiredFuel(width, length)) then
  299.             printError("Terminated")
  300.             break
  301.         end
  302.         shell.run("tunnel", length)
  303.         print("Tunnel", length, "completed")
  304.         if wPos+3 <= width then
  305.             print(string.format("Reposition on %s side", alt and "right" or "left"))
  306.             turn(alt)
  307.             local stepToDo = 3
  308.             if wPos+4 == width then
  309.                 stepToDo = 2
  310.             elseif wPos+3 == width then
  311.                 stepToDo = 1
  312.             end
  313.             for i=1,stepToDo do
  314.                 step()
  315.             end
  316.             turn(alt)
  317.             alt = not alt
  318.         end
  319.     end
  320.     if deepPos + layerHeight >= deep then
  321.         print("Finished")
  322.         break
  323.     end
  324.     --Next level
  325.     print("Next layer")
  326.     for i=1,layerHeight do
  327.         safeDigDown()
  328.         turtle.down()
  329.     end
  330.     --Pyramid resize
  331.     if pyramid then
  332.         width = width+(layerHeight*2)
  333.         length = length+(layerHeight*2)
  334.         for i=1,layerHeight do
  335.             step()
  336.         end
  337.         turn(alt)
  338.         for i=1,layerHeight do
  339.             step()
  340.         end
  341.     else
  342.         turn(alt)
  343.     end
  344.     turn(alt)
  345. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement