macks2008

Quarry backfiller 1.0

Feb 23rd, 2021 (edited)
526
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --constants
  2. ---CONFIG_constants
  3. local CONFIG_targetBlock = "minecraft:dirt"
  4. ---ARGUMENT_CONSTANTs
  5. local tArgs = { ... }
  6. local ZONE_DEPTH
  7. -- local ACCEPTABLE_FUELS
  8. if #tArgs < 2 then
  9.     local myname = shell.getRunningProgram()
  10.     local b = string.find(myname, "/")
  11.     while b do
  12.         local startindex, endindex = b
  13.         myname = string.sub(endindex)
  14.     end
  15.     print( "Usage:"..myname.." <diameter> <quarry depth>" )
  16.     return
  17. elseif #tArgs >= 2 then
  18.     ZONE_DEPTH = tonumber ( tArgs[2] )
  19. end
  20. local DIAMETER = tonumber( tArgs[1] )
  21.  
  22. -- if #tArgs > 2 then
  23.     -- for n=3,#tArgs do
  24.         -- ACCEPTABLE_FUELS = tArgs[2]
  25. -- else
  26.     -- ACCEPTABLE_FUELS
  27. -- end
  28. --variables
  29. local acceptableFuels = {["minecraft:coal"] = true}
  30. local nextTurnDirection = right
  31. local depth = 0 --this keeps track of how far we had descended from our starting position
  32. local xPos,zPos = 0,0 --these store the turtle's location within its own relativistic world grid
  33. local xDir,zDir = 0,1 --these are a direction vector that assumes we face positive Z initially
  34.                       --(but whether this is true is irrelevant since we don't rely on GPS, etc.
  35.                       --We just track our location and direction internally)
  36.  
  37. --functions
  38. local function turnLeft() --this just updates the direction vector
  39.     turtle.turnLeft()
  40.     xDir, zDir = -zDir, xDir --this is pretty smart vector handling, TBH. I might have to remember this...
  41. end
  42.  
  43. local function turnRight() --this just updates the direction vector
  44.     turtle.turnRight()
  45.     xDir, zDir = zDir, -xDir
  46. end
  47. function refuel( amount ) -- checks if we have enough fuel, and if not, search the inventory for valid fuels
  48.     local fuelLevel = turtle.getFuelLevel()
  49.     if fuelLevel == "unlimited" then
  50.         return true -- if fuel requirements are disabled for any reason, this function always returns true
  51.     end
  52.    
  53.     local needed = amount or (xPos + zPos + depth + 2) -- if amount isn't specified, estimate how much we need to get "home"
  54.     if turtle.getFuelLevel() < needed then
  55.         local fueled = false
  56.         for n=1,16 do
  57.             if turtle.getItemCount(n) > 0 then
  58.                 turtle.select(n)
  59.                 local function membershipTest(x, mySet)
  60.                     for n=1,#mySet do
  61.                         if x == mySet[n] then
  62.                             return true
  63.                         end
  64.                     end
  65.                     return false
  66.                 end
  67.                 if acceptableFuels[turtle.getItemDetail().name] then --I only want to accept certain fuels
  68.                     while turtle.getItemCount(n) > 0 and turtle.getFuelLevel() < needed do
  69.                         turtle.refuel(1)
  70.                     end
  71.                     if turtle.getFuelLevel() >= needed then
  72.                         turtle.select(1) -- reset the inventory cursor
  73.                         return true
  74.                     end
  75.                 end
  76.             end
  77.         end
  78.         turtle.select(1)
  79.         return false -- if the fuel requirements could not be met, refuel failed
  80.     end
  81.    
  82.     return true
  83. end
  84. local function collect()    --checks if inventory has an open slot
  85.     local bFull = true  --assume backpack is full until disproven
  86.     for n=1,16 do
  87.         local nCount = turtle.getItemCount(n)
  88.         if nCount == 0 then --good, we have an empty slot
  89.             bFull = false
  90.         end
  91.     end
  92.     if bFull then
  93.         print( "No empty slots left." )
  94.         return false
  95.     end
  96.     return true
  97. end
  98. local function chestIO( _bKeepOneFuelStack ) --adjusted to account for not dropping targetBlock
  99.     print( "Unloading items..." )
  100.     local targetBlockCount = 0
  101.     for n=1,16 do
  102.         local nCount = turtle.getItemCount(n)
  103.         if nCount > 0 then
  104.             turtle.select(n)           
  105.             local bDrop = true
  106.             if _bKeepOneFuelStack and turtle.refuel(0) then
  107.                 bDrop = false
  108.                 _bKeepOneFuelStack = false
  109.             elseif turtle.getItemDetail().name == CONFIG_targetBlock then
  110.                 bDrop = false
  111.                 targetBlockCount = targetBlockCount + nCount
  112.             end      
  113.             if bDrop then
  114.                 turtle.drop()
  115.             end
  116.         end
  117.     end
  118.     local function countTargetBlock(threshold)
  119.         local myCount = 0
  120.         for n=1,16 do
  121.             local nCount = turtle.getItemCount(n)
  122.             if nCount > 0 then
  123.                 turtle.select(n)
  124.                 if turtle.getItemDetail().name == CONFIG_targetBlock then
  125.                     myCount = myCount + nCount
  126.                     if myCount > threshold then
  127.                         return true
  128.                     end
  129.                 end
  130.             end
  131.         end
  132.         return false
  133.     end
  134.     if targetBlockCount < 512 then
  135.         print ( "Waiting for"..CONFIG_targetBlock.."...")
  136.         while not countTargetBlock(512) do
  137.             os.pullEvent( "turtle_inventory" )
  138.         end
  139.     end
  140.     turtle.select(1)
  141. end
  142. function goTo( x, y, z, xd, zd ) --given a location and a current direction vector, go to location
  143.     --while we are too low, forcibly go up (y axis translation part 1)
  144.     while depth > y do
  145.         if turtle.up() then
  146.             depth = depth - 1
  147.         elseif turtle.digUp() or turtle.attackUp() then --if something was in the way[...]
  148.             collect()                                 --update the inventory manager. Isn't functional programming fun?
  149.         else
  150.             sleep( 0.5 )
  151.         end
  152.     end
  153.     --while we are too high, forcibly go down(y axis translation part 2)
  154.     while depth < y do
  155.         if turtle.down() then
  156.             depth = depth + 1
  157.         elseif turtle.digDown() or turtle.attackDown() then --if something was in the way[...]
  158.             --ensure there's still empty space
  159.             collect()
  160.         else
  161.             sleep( 0.5 )
  162.         end
  163.     end
  164.     --x axis translation
  165.     if xPos > x then        --if we need to go toward negative X
  166.         while xDir ~= -1 do --... but we aren't facing negative X
  167.             turnLeft()    --turn and update the vector
  168.         end
  169.         while xPos > x do --start moving left just like we did with up
  170.             if turtle.forward() then
  171.                 xPos = xPos - 1
  172.             elseif turtle.dig() or turtle.attack() then
  173.                 collect()
  174.             else
  175.                 sleep( 0.5 )
  176.             end
  177.         end
  178.     elseif xPos < x then    --same as above, but reversed
  179.         while xDir ~= 1 do
  180.             turnLeft()
  181.         end
  182.         while xPos < x do
  183.             if turtle.forward() then
  184.                 xPos = xPos + 1
  185.             elseif turtle.dig() or turtle.attack() then
  186.                 collect()
  187.             else
  188.                 sleep( 0.5 )
  189.             end
  190.         end
  191.     end
  192.     --z axis translation
  193.     if zPos > z then        --same as above, but the other axis (negative Z)
  194.         while zDir ~= -1 do
  195.             turnLeft()
  196.         end
  197.         while zPos > z do
  198.             if turtle.forward() then
  199.                 zPos = zPos - 1
  200.             elseif turtle.dig() or turtle.attack() then
  201.                 collect()
  202.             else
  203.                 sleep( 0.5 )
  204.             end
  205.         end
  206.     elseif zPos < z then    --same as above, but reverse (positive Z)
  207.         while zDir ~= 1 do
  208.             turnLeft()
  209.         end
  210.         while zPos < z do
  211.             if turtle.forward() then
  212.                 zPos = zPos + 1
  213.             elseif turtle.dig() or turtle.attack() then
  214.                 collect()
  215.             else
  216.                 sleep( 0.5 )
  217.             end
  218.         end
  219.     end
  220.     --Rotation to match aim vector
  221.     while zDir ~= zd or xDir ~= xd do
  222.         turnLeft()
  223.     end
  224. end
  225. local function returnSupplies()
  226.     local x,y,z,xd,zd = xPos,depth,zPos,xDir,zDir
  227.     print( "Returning to surface..." )
  228.     goTo( 0,0,0,0,-1 )
  229.    
  230.     chestIO( true )
  231.     local fuelNeeded = 2*(x+y+z) + 1
  232.     if not refuel( fuelNeeded ) then
  233.         print( "Waiting for fuel" )
  234.         while not refuel( fuelNeeded ) do
  235.             os.pullEvent( "turtle_inventory" ) --waits until something modifies the inventory to add enough fuel
  236.         end
  237.     end
  238.    
  239.     print( "Resuming mining..." )
  240.     goTo( x,y,z,xd,zd )
  241. end
  242. local function seekItem(itemID)
  243.     for n=1,16 do
  244.         local nCount = turtle.getItemCount(n)
  245.         if nCount > 0 then
  246.             turtle.select(n)
  247.             if turtle.getItemDetail().name == itemID then
  248.                 return n
  249.             end
  250.         end
  251.     end
  252.     --return false --I could just let it return nil but I'd rather not
  253. end
  254. local function placeBlock(itemSlot)
  255.     turtle.select(itemSlot)
  256.     while not turtle.placeDown() do --I have the block, place it!
  257.         if not turtle.digDown() then --but smash things if necessary
  258.             turtle.attackDown()
  259.         end
  260.     end
  261.     return true
  262. end
  263. local function seekAndPlaceBlock()
  264.     local targetSlot = seekItem(CONFIG_targetBlock)
  265.     if not targetSlot then
  266.         print("out of target block"..targetSlot)
  267.         returnSupplies()
  268.         targetSlot = seekItem(CONFIG_targetBlock)
  269.     end
  270.     if not targetSlot then
  271.         return false
  272.     end
  273.     placeBlock(targetSlot)
  274.     return true
  275. end
  276. local function forwardOp()
  277.     if not refuel() then -- only move if we can get back from this location
  278.         print( "Not enough Fuel" )
  279.         returnSupplies()
  280.     end
  281.     --keep attempting to go forward; if unsuccessful, break & attack
  282.     while not turtle.forward() do -- keep trying to move forward (digging or attacking if necessary) until successful
  283.         if turtle.detect() then -- is there a block in front of us?
  284.             if turtle.dig() then
  285.                 if not collect() then
  286.                     returnSupplies()
  287.                 end
  288.             else
  289.                 print ("forwardOp aborting!")
  290.                 return false -- The block in front of us couldn't be broken
  291.             end
  292.         elseif turtle.attack() then
  293.             if not collect() then --no empty slots
  294.                 returnSupplies()
  295.             end
  296.         else
  297.             sleep( 0.5 )
  298.         end
  299.     end
  300.     --update location
  301.     xPos = xPos + xDir -- adjust the turtle's memory of its location by the direction vector
  302.     zPos = zPos + zDir -- see above
  303.     --Place targetBlock below
  304.     if not seekAndPlaceBlock() then
  305.         print("could not place ".. CONFIG_targetBlock..". Is something in the way or did I break?")
  306.     end
  307.     turtle.select(1)
  308.     return true
  309. end
  310. local function layerChangeOp()
  311.     if not refuel() then -- only move if we can get back from this location
  312.         print( "Not enough Fuel" )
  313.         returnSupplies()
  314.     end
  315.     --keep attempting to go up; if unsuccessful, break & attack
  316.     while not turtle.up() do -- keep trying to move up (digging or attacking if necessary) until successful
  317.         if turtle.detectUp() then -- is there a block above of us?
  318.             if turtle.digUp() then
  319.                 if not collect() then
  320.                     returnSupplies()
  321.                 end
  322.             else
  323.                 print ("layerChangeOp aborting!")
  324.                 return false -- The block above us couldn't be broken
  325.             end
  326.         elseif turtle.attackUp() then
  327.             if not collect() then --no empty slots
  328.                 returnSupplies()
  329.             end
  330.         else
  331.             sleep( 0.5 )
  332.         end
  333.     end
  334.     depth = depth - 1
  335.     turtle.select(1)
  336.     return true
  337. end
  338. local function turnAround(turnDirection)
  339.     if turnDirection == 0 then
  340.         turnLeft()
  341.         if not forwardOp() then
  342.             print ("turnAround aborting!")
  343.             return false
  344.         end
  345.         turnLeft()
  346.     elseif turnDirection == 1 then
  347.         turnRight()
  348.         if not forwardOp() then
  349.             print ("turnAround aborting!")
  350.             return false
  351.         end
  352.         turnRight()
  353.     else
  354.         turnRight()
  355.         if not forwardOp() then
  356.             print ("turnAround aborting!")
  357.             return false
  358.         end
  359.         turnRight()
  360.     end
  361.     return true
  362. end
  363. local function doRow(length)
  364.     for m=1,length-1 do --first row gets done by turnaround
  365.         if not forwardOp() then
  366.             print ("doRow aborting!")
  367.             return false
  368.         end
  369.     end
  370.     return true
  371. end
  372. local function doLayer(width)--handles doRow and turnAround calls. Three-dimensional pathing calls are handled by doCuboid
  373.     --don't forget to place a block on the first spot, not just after each forwardOp
  374.     if not seekAndPlaceBlock() then
  375.         print("could not place ".. CONFIG_targetBlock..". Is something in the way or did I break?")
  376.     end
  377.     turtle.select(1)
  378.     local directionBit
  379.     for n=1,width-1 do
  380.         directionBit = math.fmod(n,2)
  381.         if not doRow(DIAMETER) then
  382.             print ("doLayer aborting!")
  383.             return false
  384.         end
  385.         if not turnAround(directionBit) then
  386.             print ("doLayer aborting!")
  387.             return false
  388.         end
  389.     end
  390.     if not doRow(DIAMETER) then
  391.         print ("doLayer aborting!")
  392.         return false
  393.     end
  394.     if directionBit == 0 then
  395.         turnRight()
  396.         turnRight()
  397.     else
  398.         turnRight()
  399.     end
  400.     return true
  401. end
  402. local function doCuboid(height)
  403.     for p=1,height-1 do
  404.         if not doLayer(DIAMETER) then
  405.             print ("doLayer returned false. doCuboid aborting!")
  406.             return false
  407.         end
  408.         if not layerChangeOp() then
  409.             print ("layerChangeOp returned false. doCuboid aborting!")
  410.             return false
  411.         end
  412.     end
  413.     if not doLayer(DIAMETER) then
  414.         print ("doLayer returned false. doCuboid aborting!")
  415.         return false
  416.     end
  417. end
  418. goTo(0, ZONE_DEPTH-1, 0, 0, 1)
  419. doCuboid(ZONE_DEPTH)
  420. goTo(0, 0, 0, 0, 1)
  421.  
Add Comment
Please, Sign In to add comment