KinoftheFlames

quarry

Sep 21st, 2012
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.99 KB | None | 0 0
  1. --quarry
  2. --by KinoftheFlames
  3. --REQUIRES following APIs: hare
  4. --ATM assumes fuel is unlimited
  5.  
  6. --digs a cube by provided paramaters
  7. --from its starting orientation, length is forward, and width is to the right, STARTING BLOCK INCLUDED
  8. --moves down at start, so doesn't dig the plane it starts on
  9.  
  10. os.loadAPI("hare")
  11.  
  12.  
  13.  
  14. --PROGRAM ARGUMENTS
  15. arg = { ... }
  16. if #arg ~= 3 and #arg ~= 4 then
  17.     print("Syntax: quarry<length, width, height, [only|exclude]>")
  18.     return false end
  19.  
  20. --filter setup
  21. if #arg == 4 then
  22.     --asures filter value is valid
  23.     if arg[4] ~= "only" and arg[4] ~= "exclude" then
  24.         print("Syntax: quarry<length, width, height, [only|exclude]>")
  25.         return false end
  26.    
  27.     hare.netprint("Preparing filter...")
  28.     filterOn = true
  29.     filterType = tostring(arg[4])
  30.     filter = {} --will contain a list of slots that have filter seed items
  31.    
  32.     --create a filter of each unique block in the turtle's inventory
  33.     for curSlot=1,16 do
  34.         turtle.select(curSlot)
  35.         if #filter == 0 and turtle.getItemCount(curSlot) > 0 then
  36.             table.insert(filter, curSlot) end --adds current slot to the filter list
  37.         match = false
  38.         for j, slot in ipairs(filter) do
  39.             if turtle.compareTo(slot) then --if the current slot's unique block is not registered in the filter yet and its not empty
  40.                 match = true
  41.                 break
  42.             end
  43.         end
  44.         if not match and turtle.getItemCount(curSlot) > 0 then --if unique and not empty
  45.             table.insert(filter, curSlot) end --adds current slot to the filter list
  46.     end
  47.     turtle.select(1)
  48.    
  49.     if #filter ~= 0 then
  50.         io.write("Filter ("..filterType.."): ")
  51.         for i,slot in ipairs(filter) do
  52.             io.write(slot.." ")
  53.         end
  54.         io.write("\n")
  55.     end
  56. else filterOn = false end
  57.  
  58.  
  59.  
  60.  
  61.  
  62. --VARIABLES
  63. FACE = {forward=0, right=1, back=2, left=3} --position // x, y, z (length, width, height)
  64.  
  65. length = tonumber(arg[1])
  66. width = tonumber(arg[2])
  67. height = tonumber(arg[3])
  68.  
  69. --position and direction relative to start
  70. pos = {x=0, y=0, z=0} --position // x, y, z (length, width, height)
  71. dir = 0 --direction // 0 = forward, 1 = right, 2 = back, 3 = left // SO turnLeft = -1, turnRight = +1 // (dir % 4 gives accurate numbers)
  72. lastTurnRight = false
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81. --FUNCTIONS
  82.  
  83.  
  84. --checks if inventory is full
  85. --valid nextDig: forward down up [none]
  86. function inventoryFull(nextDig)
  87.     --seperated for speed (turtle.select() is slow)
  88.     for i=1,16 do
  89.         if turtle.getItemCount(i) == 0 then --if empty slot
  90.             return false end
  91.     end
  92.     for curSlot=1,16 do
  93.         turtle.select(curSlot)
  94.        
  95.         --if next block to dig is the same as the current slot, and the slot is not full
  96.         if (nextDig == "forward" and turtle.compare() and turtle.getItemSpace(curSlot) > 0)
  97.             or (nextDig == "up" and turtle.compareUp() and turtle.getItemSpace(curSlot) > 0)
  98.             or (nextDig == "down" and turtle.compareDown() and turtle.getItemSpace(curSlot) > 0)
  99.         then
  100.             turtle.select(1)
  101.             return false end
  102.     end
  103.     hare.netprint("Inventory full.")
  104.     turtle.select(1)
  105.     return true
  106. end
  107.  
  108. --change direction
  109. function direct(newDir)
  110.     while newDir ~= dir % 4 do --while incorrect directions
  111.         if newDir > dir % 4 then --turn right if it's quicker
  112.             if newDir == FACE.left and dir % 4 == FACE.forward then
  113.                 turtle.turnLeft()
  114.                 dir = dir - 1
  115.             else
  116.                 turtle.turnRight()
  117.                 dir = dir + 1
  118.             end
  119.         elseif newDir < dir % 4 then --else turn left
  120.             if newDir == FACE.forward and dir % 4 == FACE.left then
  121.                 turtle.turnRight()
  122.                 dir = dir + 1
  123.             else
  124.                 turtle.turnLeft()
  125.                 dir = dir - 1
  126.             end
  127.         end
  128.     end
  129. end
  130.  
  131. function moveTo(x, y, z)
  132.     if pos.x == x and pos.y == y and pos.z == z then return end
  133.     hare.netprint("Moving from ("..pos.x..","..pos.y..","..pos.z..") to ("..x..","..y..","..z..")")
  134.    
  135.     --moves up once or down once as needed before continuing to prevent hitting potential
  136.     --      blocks in the unmined spaces
  137.     if pos.z < z and pos.z ~= z - 1 then --move up
  138.         if hare.digMoveUp() then
  139.             pos.z = pos.z + 1 end
  140.     elseif pos.z > z and pos.z ~= z + 1 then --move down
  141.         if hare.digMoveDown() then
  142.             pos.z = pos.z - 1 end
  143.     end
  144.    
  145.     --left/right
  146.     if pos.y > y then
  147.         direct(FACE.left)
  148.         while pos.y > y do --move left
  149.             if hare.digMove() then
  150.                 pos.y = pos.y - 1 end
  151.         end
  152.     elseif pos.y < y then
  153.         direct(FACE.right)
  154.         while pos.y < y do --move right
  155.             if hare.digMove() then
  156.                 pos.y = pos.y + 1 end
  157.         end
  158.     end
  159.    
  160.     --forward/back
  161.     if pos.x > x then
  162.         direct(FACE.back)
  163.         while pos.x > x do --move back
  164.             if hare.digMove() then
  165.                 pos.x = pos.x - 1 end
  166.         end
  167.     elseif pos.x < x then
  168.         direct(FACE.forward)
  169.         while pos.x < x do --move back
  170.             if hare.digMove() then
  171.                 pos.x = pos.x + 1 end
  172.         end
  173.     end
  174.    
  175.     --up/down
  176.     while pos.z < z do --move up
  177.         if hare.digMoveUp() then
  178.             pos.z = pos.z + 1 end
  179.     end
  180.     while pos.z > z do --move down
  181.         if hare.digMoveDown() then
  182.             pos.z = pos.z - 1 end
  183.     end
  184.    
  185.     hare.netprint("Arrived at ("..x..","..y..","..z..")")
  186. end
  187.  
  188. --removes items from inventory based on filter, returns true if items were discarded
  189. --discarding is command turtle.dropDown()
  190. function filterInventory()
  191.     hare.netprint("Discarding innapropriate items...")
  192.     discarded = false
  193.     for curSlot=1,16 do
  194.         turtle.select(curSlot)
  195.        
  196.         --determine if match in filter
  197.         match = false
  198.         for j, slot in ipairs(filter) do
  199.             if turtle.compareTo(slot) then --if curent slot matches a filter item
  200.                 match = true
  201.                 matchSlot = j
  202.                 break
  203.             end
  204.         end
  205.        
  206.         if filterType == "only" and not match then --if it matches the filter, keep it
  207.             turtle.dropDown()
  208.             discarded = true
  209.         elseif filterType == "exclude" and match then --if it matches the filter, drop it
  210.             if matchSlot ~= curSlot then --drop all if not the seed slot
  211.                 turtle.dropDown()
  212.                 discarded = true
  213.             else --otherwise drop all but 1
  214.                 turtle.dropDown(turtle.getItemCount(curSlot)-1) end
  215.         end
  216.     end
  217.    
  218.     turtle.select(1)
  219.     if discarded then return true end
  220.     return false
  221. end
  222.  
  223. --unloads inventory (presumed to be home)
  224. function unload(alreadyFiltered)
  225.     if not alreadyFiltered and filterOn then
  226.         filterInventory() end
  227.    
  228.     hare.netprint("Unloading inventory...")
  229.     turtle.turnLeft()
  230.     dir = dir - 1
  231.     for curSlot=1,16 do
  232.         turtle.select(curSlot)
  233.         if filterOn then --if filter is on, don't drop seed items
  234.             match = false
  235.             for j, slot in ipairs(filter) do
  236.                 if curSlot == slot then
  237.                     match = true
  238.                     turtle.drop(turtle.getItemCount(curSlot)-1) --drop all but 1
  239.                     break
  240.                 end
  241.             end
  242.             if not match then --if not a seed item, drop all
  243.                 turtle.drop() end
  244.         else turtle.drop() end --if no filter
  245.     end
  246.     turtle.select(1)
  247.     turtle.turnRight()
  248.     dir = dir + 1
  249. end
  250.  
  251. --return to startls
  252.  
  253. function returnHome()
  254.     hare.netprint("Returning home...")
  255.     moveTo(0,0,0)
  256.     direct(FACE.forward)
  257. end
  258.  
  259. --drops off inventory at chest 1 left of home
  260. function goUnload()
  261.     hare.netprint("Making unload trip...")
  262.    
  263.     --if filter on, dump appropriate items and reevaluate unload run
  264.     if filterOn and filterInventory() then
  265.         hare.netprint("Inventory no longer full. Cancelling trip.")
  266.         return end
  267.    
  268.     digPos = {x=pos.x, y=pos.y, z=pos.z}
  269.     digDir = dir % 4
  270.    
  271.     returnHome()
  272.     unload(true)
  273.    
  274.     hare.netprint("Returning to work...")
  275.     moveTo(digPos.x, digPos.y, digPos.z)
  276.     direct(digDir)
  277. end
  278.  
  279.  
  280. --movements
  281. function down()
  282.     if inventoryFull("down") then
  283.         goUnload() end
  284.     if hare.digMoveDown() then
  285.         pos.z = pos.z - 1
  286.     else
  287.         return false end
  288.     return true
  289. end
  290.  
  291. function forward()
  292.     if inventoryFull("forward") then
  293.         goUnload() end
  294.     if hare.digMove() then
  295.         if dir % 4 == FACE.forward then
  296.             pos.x = pos.x + 1
  297.         else
  298.             pos.x = pos.x - 1 end
  299.     else
  300.         return false end
  301.     return true
  302. end
  303.  
  304. function forwardRow()
  305.     if inventoryFull("forward") then
  306.         goUnload() end
  307.     if hare.digMove() then
  308.         if dir % 4 == FACE.right then
  309.             pos.y = pos.y + 1
  310.         else
  311.             pos.y = pos.y - 1 end
  312.     else
  313.         return false end
  314.     return true
  315. end
  316.  
  317. function turnLeft()
  318.     turtle.turnLeft()
  319.     dir = dir - 1
  320. end
  321.  
  322. function turnRight()
  323.     turtle.turnRight()
  324.     dir = dir + 1
  325. end
  326.  
  327. --dig!
  328. function quarry(startLength, startWidth, startHeight)
  329.     --actual digging
  330.     hare.netprint("Digging quarry ["..length.."x"..width.."x"..height.."]...")
  331.     i = startHeight
  332.     while i <= height do --cube
  333.         if not down() then return end
  334.        
  335.         j = startWidth
  336.         while j <= width do --plane
  337.             k = startLength
  338.             while k <= length - 1 do --row
  339.                 if not forward() then return end
  340.                 k = k + 1
  341.             end
  342.             if j < width then --only start new row if needed
  343.                 if lastTurnRight then --turn left
  344.                     turnLeft()
  345.                     if not forwardRow() then return end
  346.                     turnLeft()
  347.                     lastTurnRight = false
  348.                 else --turn right
  349.                     turnRight()
  350.                     if not forwardRow() then return end
  351.                     turnRight()
  352.                     lastTurnRight = true
  353.                 end
  354.             end
  355.             j = j + 1
  356.         end
  357.         if i < height and (width > 1 or length > 1) then --only turn around if needed
  358.             hare.turnAround()
  359.             dir = dir + 2
  360.         end
  361.         i = i + 1
  362.     end
  363.     hare.netprint("Quarry complete.")
  364. end
  365.  
  366. --check all possible situations and resume from there
  367. quarry(1, 1, 1)
  368. returnHome()
  369. unload(false)
  370. hare.netprint("Program complete.")
  371. return true
Advertisement
Add Comment
Please, Sign In to add comment