macks2008

Quarry backfiller WIP

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