Advertisement
bcash8

APBlockScannerStripMiner

Jul 27th, 2022 (edited)
838
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local MINFUELLEVEL = 4000
  2. local tunnelLength = 0
  3. local torches = false
  4. local garbage = {
  5.     ["minecraft:cobblestone"] = true,
  6.     ["minecraft:dirt"] = true,
  7.     ["minecraft:gravel"] = true,
  8.     ["minecraft:stone"] = true,
  9.     ["minecraft:sand"] = true
  10. }
  11.  
  12.  
  13.  
  14.  
  15.  
  16. local args = {...}
  17.  
  18. local sides = {"left", "right"}
  19. local equipment = {left = nil, right = nil}
  20. local tools = {["minecraft:compass"] = true, ["advancedperipherals:geo_scanner"] = true, ["minecraft:diamond_pickaxe"] = true}
  21. local inventory = {} -- {itemName = {slot1, slot2, slot3}}
  22. local pos = vector.new(0, 0, 0)
  23. local heading = vector.new(1, 0, 0)
  24. local directions = {NORTH = vector.new(0, 0, -1), EAST = vector.new(1, 0, 0), SOUTH = vector.new(0, 0, 1), WEST = vector.new(-1, 0, 0)}
  25. local orientations = {[vector.new(0, 0, -1):tostring()] = 0, [vector.new(1, 0, 0):tostring()] = 1, [vector.new(0, 0, 1):tostring()] = 2, [vector.new(-1, 0, 0):tostring()] = 3}
  26. local home = vector.new(0, 0, 0)
  27. local startingHeading
  28. -- init
  29. function init()
  30.  
  31.     if args then
  32.         if args[1] then
  33.             tunnelLength = args[1]
  34.         end
  35.  
  36.         if args[2] then
  37.             torches = args[2]
  38.         end
  39.     end
  40.  
  41.     heading = getFacing()
  42.     startingHeading = heading
  43.     print(heading)
  44.     for _, side in pairs(sides) do
  45.         local tool = peripheral.getType(side)
  46.         if tool then
  47.             equipment[side] = tool
  48.         end
  49.     end
  50.  
  51.     for side, tool in pairs(equipment) do
  52.         print(side .. ": " .. tool)
  53.     end
  54.  
  55.     scanInventory()
  56. end
  57.  
  58. -- inventory functions
  59. function scanInventory()
  60.     inventory = {}
  61.  
  62.     for i = 1, 16 do
  63.         local data = turtle.getItemDetail(i)
  64.         if data then
  65.             if inventory[data.name] then
  66.                 table.insert(inventory[data.name], i)
  67.             else
  68.                 inventory[data.name] = {i}
  69.             end
  70.         end
  71.     end
  72. end
  73.  
  74. function selectItem(itemName)
  75.     scanInventory()
  76.     if not inventory[itemName] then return false end
  77.  
  78.     turtle.select(inventory[itemName][1])
  79.     return true
  80. end
  81.  
  82. function equipItem(itemName, side)
  83.     side = side or "right"
  84.     scanInventory()
  85.     if not inventory[itemName] then return false end
  86.     turtle.select(inventory[itemName][1])
  87.  
  88.     if side == "right" then
  89.         turtle.equipRight()
  90.     else
  91.         turtle.equipLeft()
  92.     end
  93. end
  94.  
  95. function purgeInv()
  96.     for i = 1, 16 do
  97.         local data = turtle.getItemDetail(i)
  98.         if data then
  99.             if garbage[data.name] then
  100.                 turtle.select(i)
  101.                 turtle.dropUp()
  102.             end
  103.  
  104.             for b = 1, i-1 do
  105.                 local d = turtle.getItemDetail(b)
  106.                 if d then
  107.                     if d.name == data.name then
  108.                         turtle.select(i)
  109.                         turtle.transferTo(b)
  110.                     end
  111.                 end
  112.             end
  113.         end
  114.     end
  115. end
  116.  
  117. function refuel()
  118.     scanInventory()
  119.     if inventory["minecraft:coal"] then
  120.         turtle.select(inventory["minecraft:coal"][1])
  121.         turtle.refuel()
  122.     end
  123. end
  124.  
  125. function emptyInventory()
  126.     purgeInv()
  127.  
  128.     for i = 1, 16 do
  129.         local data = turtle.getItemDetail(i)
  130.         if data then
  131.             if not tools[data.name] then
  132.                 turtle.select(i)
  133.                 turtle.drop()
  134.             end
  135.         end
  136.     end
  137. end
  138.  
  139. function getEmptySpace()
  140.     local emptySpace = 0
  141.  
  142.     for i = 1, 16 do
  143.         local count = turtle.getItemCount(i)
  144.         if count == 0 then
  145.             emptySpace = emptySpace + 1
  146.         end
  147.     end
  148.     return emptySpace
  149. end
  150. -- navigation
  151. function getFacing()
  152.     equipItem("minecraft:compass")
  153.     local facing = peripheral.call("right", "getFacing")
  154.     return directions[string.upper(facing)]
  155. end
  156.  
  157. function compareVectors(vec1, vec2)
  158.     if vec1.x == vec2.x and vec1.y == vec2.y and vec1.z == vec2.z then
  159.         return true
  160.     else
  161.         return false
  162.     end
  163. end
  164.  
  165. function turnRight()
  166.     turtle.turnRight()
  167.  
  168.     if compareVectors(heading, vector.new(1, 0, 0)) then
  169.         heading = vector.new(0, 0, 1)
  170.     elseif compareVectors(heading, vector.new(-1, 0, 0)) then
  171.         heading = vector.new(0, 0, -1)
  172.     elseif compareVectors(heading, vector.new(0, 0, 1)) then
  173.         heading = vector.new(-1, 0, 0)
  174.     elseif compareVectors(heading, vector.new(0, 0, -1)) then
  175.         heading = vector.new(1, 0, 0)
  176.     end
  177.  
  178.     return true
  179. end
  180.  
  181. function turnLeft()
  182.     turtle.turnLeft()
  183.  
  184.     if compareVectors(heading, vector.new(1, 0, 0)) then
  185.         heading = vector.new(0, 0, -1)
  186.     elseif compareVectors(heading, vector.new(-1, 0, 0)) then
  187.         heading = vector.new(0, 0, 1)
  188.     elseif compareVectors(heading, vector.new(0, 0, 1)) then
  189.         heading = vector.new(1, 0, 0)
  190.     elseif compareVectors(heading, vector.new(0, 0, -1)) then
  191.         heading = vector.new(-1, 0, 0)
  192.     end
  193.  
  194.     return true
  195. end
  196.  
  197. function forward()
  198.     local tries = 0
  199.     repeat
  200.         if tries > 50 then return false end
  201.         tries = tries + 1
  202.         turtle.dig()
  203.     until turtle.forward()
  204.     pos = pos + heading
  205.     return true
  206. end
  207.  
  208. function back()
  209.     if not turtle.back() then
  210.         turnRight()
  211.         turnRight()
  212.         forward()
  213.         turnLeft()
  214.         turnLeft()
  215.     else
  216.         pos = pos - heading
  217.     end
  218.  
  219.     return true
  220. end
  221.  
  222. function up()
  223.     repeat turtle.digUp() until turtle.up()
  224.  
  225.     pos = pos + vector.new(0, 1, 0)
  226.     return true
  227. end
  228.  
  229. function down()
  230.     local tries = 0
  231.     repeat
  232.         if tries > 50 then return false end
  233.         tries = tries + 1
  234.         turtle.digDown()
  235.     until turtle.down()
  236.  
  237.     pos = pos + vector.new(0, -1, 0)
  238.     return true
  239. end
  240.  
  241. function turnToHeading(newHeading)
  242.     if compareVectors(newHeading, heading) then
  243.         return true
  244.     end
  245.  
  246.     if compareVectors(newHeading, -heading) then
  247.         turnRight()
  248.         turnRight()
  249.         return true
  250.     end
  251.  
  252.     if orientations[newHeading:tostring()] == 0 and orientations[heading:tostring()] == 3 then
  253.         turnRight()
  254.         return true
  255.     end
  256.  
  257.     if orientations[newHeading:tostring()] == 3 and orientations[heading:tostring()] == 0 then
  258.         turnLeft()
  259.         return true
  260.     end
  261.  
  262.  
  263.     if orientations[newHeading:tostring()] > orientations[heading:tostring()] then
  264.         turnRight()
  265.     else
  266.         turnLeft()
  267.     end
  268. end
  269.  
  270. function goto(newPos)
  271.     if newPos.x > pos.x then
  272.         turnToHeading(vector.new(1, 0, 0))
  273.         while newPos.x > pos.x do
  274.             if not forward() then return false end
  275.         end
  276.     end
  277.  
  278.     if newPos.x < pos.x then
  279.         turnToHeading(vector.new(-1, 0, 0))
  280.         while newPos.x < pos.x do
  281.             if not forward() then return false end
  282.         end
  283.     end
  284.  
  285.     if newPos.z > pos.z then
  286.         turnToHeading(vector.new(0, 0, 1))
  287.         while newPos.z > pos.z do
  288.             if not forward() then return false end
  289.         end
  290.     end
  291.  
  292.     if newPos.z < pos.z then
  293.         turnToHeading(vector.new(0, 0, -1))
  294.         while newPos.z < pos.z do
  295.             if not forward() then return false end
  296.         end
  297.     end
  298.  
  299.     while newPos.y > pos.y do
  300.         up()
  301.     end
  302.  
  303.     while newPos.y < pos.y do
  304.         if not down() then return false end
  305.     end
  306. end
  307.  
  308.  
  309. -- mining functions
  310. function isOreBlock(name)
  311.     if string.find(name, "ore")  and string.find(name, "minecraft") then return true end
  312.     if string.find(name, "ore")  and string.find(name, "thermal") then return true end
  313.     return false
  314. end
  315.  
  316. function scanArea()
  317.     if equipment.right ~= "advancedperipherals:geo_scanner" then
  318.         equipItem("advancedperipherals:geo_scanner")
  319.     end
  320.  
  321.     local data = peripheral.call("right", "scan")
  322.     local ores = {}
  323.  
  324.     for _, block in pairs(data) do
  325.         if isOreBlock(block.name) then
  326.             block.x = block.x + pos.x
  327.             block.y = block.y + pos.y
  328.             block.z = block.z + pos.z
  329.             table.insert(ores, block)
  330.         end
  331.     end
  332.  
  333.     return ores
  334. end
  335.  
  336. function getDistance(pos1, pos2)
  337.     local x = math.abs(pos1.x - pos2.x)
  338.     local y = math.abs(pos1.y - pos2.y)
  339.     local z = math.abs(pos1.z - pos2.z)
  340.     return (x + y + z)
  341. end
  342.  
  343. function createMiningPath(ores)
  344.     local unassignedOres = ores
  345.     local assignedOres = {}
  346.  
  347.     local lowestScore = 999
  348.     local lowestIndex = 1
  349.     for i = 1, #unassignedOres do
  350.         local dis = getDistance(unassignedOres[i], pos)
  351.         if dis < lowestScore then
  352.             lowestIndex = i
  353.             lowestScore = dis
  354.         end
  355.     end
  356.  
  357.     table.insert(assignedOres, unassignedOres[lowestIndex])
  358.     table.remove(unassignedOres, lowestIndex)
  359.  
  360.     while #unassignedOres > 0 do
  361.  
  362.         local lowestScore = 999
  363.         local lowestIndex = 1
  364.         for i = 1, #unassignedOres do
  365.             local dis = getDistance(unassignedOres[i], assignedOres[#assignedOres])
  366.             if dis < lowestScore then
  367.                 lowestIndex = i
  368.                 lowestScore = dis
  369.             end
  370.         end
  371.         table.insert(assignedOres, unassignedOres[lowestIndex])
  372.         table.remove(unassignedOres, lowestIndex)
  373.     end
  374.  
  375.     print(#assignedOres)
  376.     return assignedOres
  377. end
  378.  
  379. function scanAndMine()
  380.     local ores = scanArea()
  381.     equipItem("minecraft:diamond_pickaxe")
  382.     local path = createMiningPath(ores)
  383.  
  384.     print(#path)
  385.     for i = 1, #path do
  386.         if i % 5 == 0 then
  387.             purgeInv()
  388.             if getEmptySpace() < 3 then
  389.                 dumpItems()
  390.             end
  391.         end
  392.  
  393.         goto(vector.new(path[i].x, path[i].y, path[i].z))
  394.     end
  395. end
  396.  
  397. function dumpItems()
  398.     local thisPos = pos
  399.     local thisHeading = heading
  400.     goto(home)
  401.     turnToHeading(-startingHeading)
  402.     emptyInventory()
  403.  
  404.     goto(thisPos)
  405.     turnToHeading(thisHeading)
  406. end
  407.  
  408. function main()
  409.     equipItem("minecraft:diamond_pickaxe")
  410.     for i = 1, 5 do
  411.         turtle.digUp()
  412.         forward()
  413.     end
  414.     for i = 1, tunnelLength/8 do
  415.         equipItem("minecraft:diamond_pickaxe")
  416.         for b = 1, 8 do
  417.             turtle.digUp()
  418.             forward()
  419.         end
  420.  
  421.         local curPos = pos
  422.         local curHeading = heading
  423.         scanAndMine()
  424.         goto(curPos)
  425.         turnToHeading(curHeading)
  426.         purgeInv()
  427.  
  428.         if turtle.getFuelLevel() < MINFUELLEVEL then
  429.             refuel()
  430.             if turtle.getFuelLevel() < MINFUELLEVEL then
  431.                 goto(home)
  432.                 return
  433.             end
  434.         end
  435.     end
  436.     goto(home)
  437.     turnToHeading(-startingHeading)
  438.     emptyInventory()
  439. end
  440.  
  441. init()
  442. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement