Le_JuiceBOX

[App] [v3.1] mine.lua

Sep 1st, 2025 (edited)
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.88 KB | None | 0 0
  1. -- eXXmchmd
  2.  
  3. -- MIN_FULL_SLOTS leaves slots open to avoid mining more than turtle can hold
  4. local MIN_FULL_SLOTS = 10
  5.  
  6. local cmdArgs = table.pack(...)
  7.  
  8. local Params = {
  9.     Width = nil,
  10.     Height = nil,
  11.     Depth = nil,
  12.     StartX = nil,
  13.     StartDepth = nil,
  14.     DepositMode = nil,
  15. }
  16.  
  17. local DepoMode = {
  18.     RunHome = 1,
  19.     LeaveChest = 2,
  20.     EnderChest = 3,
  21.     Discard = 4
  22. }
  23.  
  24. local Dir = {
  25.     N = 1,
  26.     E = 2,
  27.     S = 3,
  28.     W = 4
  29. }
  30.  
  31. local FILE_PARAMS_DATA = "/temp/current_mine_params.txt"
  32. local FILE_NAV_DATA = "/temp/mine_nav_data.txt"
  33.  
  34. local Brain = require("/turtleBrain"):new(FILE_NAV_DATA)
  35. local Terminal = require("/terminal"):new()
  36. local mineVolume = 0
  37. local isResuming = false
  38. local depositedResources = {}
  39.  
  40. --=====================================================================================
  41.  
  42. function Main()
  43.     Terminal:print("PrawgMine - v3.1")
  44.     if #cmdArgs > 0 then
  45.         Params.Width = tonumber(cmdArgs[1])
  46.         Params.Height = tonumber(cmdArgs[2])
  47.         Params.Depth = tonumber(cmdArgs[3])
  48.         Params.StartX = tonumber(cmdArgs[4])
  49.         Params.StartDepth = tonumber(cmdArgs[5])
  50.         Params.DepositMode = tonumber(cmdArgs[6])
  51.     else
  52.         local success = GetParams()
  53.         if success == false then return; end
  54.     end
  55.     Brain.X = Params.StartX
  56.     Terminal:reset()
  57.     Terminal:print("Starting work!")
  58.     local start = 1
  59.     if isResuming then
  60.         Brain:moveTo(Params.StartX,0,Brain.Z-1)
  61.         Brain:turnToFace(Dir.N)
  62.     else
  63.         Brain:forceForward(Params.StartDepth)
  64.     end
  65.     print("starting now!!!")
  66.     --// Mining
  67.     for i = start, Params.Depth do
  68.         local success, msg = mineLayer()
  69.         if success == false then
  70.             Terminal:reset()
  71.             Terminal:print(msg)
  72.             break
  73.         end
  74.     end
  75.     depositItems()
  76.     --// Finish
  77.     Brain:moveTo(Params.StartX,1,0,{1,2,3})
  78.     repeat
  79.         Brain:deleteNav()
  80.         Terminal:reset()
  81.         Terminal:print("Turtle finished job.")
  82.         Terminal:print()  
  83.         local resName, resInd = Terminal:promptOptions("&1What do you want to do?",false,{
  84.             "Exit",
  85.             "View Info",
  86.             "View Mined Resources"
  87.         })
  88.         if resInd == 3 then
  89.             local yPos = 4
  90.             local sorted = {}
  91.             for name,ct in pairs(depositedResources) do
  92.                 table.insert(sorted,{name,ct})
  93.             end
  94.             table.sort(sorted, function(a, b) return a[2] > b[2] end)
  95.             repeat  
  96.                 Terminal:reset()
  97.                 Terminal.output.setCursorPos(1,yPos)
  98.                 for i, data in pairs(sorted) do
  99.                     local dispName = Terminal:getItemDisplayName(data[1])
  100.                     local halfScreen = math.ceil(Terminal.size.x/2)
  101.                     local str = dispName.."&8"
  102.                     for i = 1, halfScreen-#dispName do
  103.                         str = str.."."
  104.                     end
  105.                     Terminal:print(str.."&8x&4"..tostring(data[2]))
  106.                 end
  107.                 Terminal:writeLine(1,"&1[Backspace] - exit.")
  108.                 Terminal:writeLine(2,"&1[ArrowKeys] - scroll.")
  109.                 Terminal:writeLine(3,"")
  110.                 local key = Terminal:waitForKey()
  111.                 if key == 265 then -- up
  112.                     yPos = yPos + 1
  113.                 elseif key == 264 then -- down
  114.                     yPos = yPos - 1
  115.                 end
  116.             until key == 259 -- backspace
  117.             Terminal:reset()
  118.         end
  119.     until resInd == 1
  120.     Terminal:reset()
  121.     -- clean up
  122.     if fs.exists(FILE_PARAMS_DATA) then
  123.         fs.delete(FILE_PARAMS_DATA)
  124.     end
  125. end
  126.  
  127. function GetParams()
  128.     if fs.exists(FILE_NAV_DATA) then
  129.         Terminal:reset()
  130.         Terminal:print("&eAlert!")
  131.         Terminal:print("This turtle shutdown half-way through")
  132.         Terminal:print("most recent job.")
  133.         Terminal:print()
  134.         Terminal:print("&8This is possibly due to the turtle:")
  135.         Terminal:print("&8breaking, shutting down, exploring an")
  136.         Terminal:print("&8unloaded chunk, or the server shutdown.")
  137.         Terminal:print()
  138.         local res = Terminal:promptConf("&1Do you want to resume?",true)
  139.         if res then
  140.             Brain:loadNav(Brain:getHasMoved())
  141.             Params.Width = tonumber(w)
  142.             Params.Height = tonumber(h)
  143.             Params.Depth = tonumber(d)
  144.             Params.StartX = tonumber(startX)
  145.             Params.StartDepth = tonumber(start)
  146.             Params.DepositMode = tonumber(mode)
  147.             isResuming = true
  148.             return true -- continue
  149.         else
  150.             Brain:deleteNav()
  151.             if fs.exists(FILE_PARAMS_DATA) then
  152.                 fs.delete(FILE_PARAMS_DATA)
  153.             end
  154.         end
  155.     end
  156.     repeat
  157.         Params = {
  158.             Width = nil,
  159.             Height = nil,
  160.             Depth = nil,
  161.             StartX = nil,
  162.             StartDepth = nil,
  163.             DepositMode = nil,
  164.         }
  165.         Terminal:reset()
  166.         Params.Width = Terminal:promptNum("Input block width:")
  167.         Params.Height = Terminal:promptNum("Input block height:")
  168.         Params.Depth = Terminal:promptNum("Input block depth:")
  169.         Params.StartX = Terminal:promptNum("Input starting X: (leave blank for none)") or 0
  170.         Params.StartDepth = Terminal:promptNum("Input starting Z: (leave blank for none)") or 0
  171.     until Terminal:promptConf("Continue with these parameters?",true)
  172.     repeat
  173.         Terminal:reset()
  174.         local menu = {
  175.             "Return Home",
  176.             "Leave Chests",
  177.             "Enderchest",
  178.             "Discard",
  179.         }
  180.         local modeName,mode = Terminal:promptOptions("Select a deposit mode:",false,menu)
  181.         Terminal:reset()
  182.         if mode == DepoMode.RunHome then
  183.             Terminal:display(nil,
  184.                 "Return Home:",
  185.                 "Turtle will return to origin to",
  186.                 "deposit its items.",
  187.                 ""
  188.             )    
  189.         elseif mode == DepoMode.LeaveChest then
  190.             Terminal:display(nil,
  191.                 "Leave Chests:",
  192.                 "Turtle will place chests when its inventory",
  193.                 "fills up and deposits the items into it.",
  194.                 "NOTE: Uses multiple chests."
  195.             )  
  196.         elseif mode == DepoMode.EnderChest then
  197.             Terminal:display(nil,
  198.                 "Enderchest:",
  199.                 "Turtle will place an ender chest and deposit",
  200.                 "its inventory into it. Turtle will break the EC",
  201.                 "and continue forth when inventory is deposited.",
  202.                 "NOTE: Ender chest must always be empty.",
  203.                 ""
  204.             )  
  205.         elseif mode == DepoMode.Discard then
  206.             Terminal:display(nil,
  207.                 "Discard:",
  208.                 "Throw any items mined on to the ground.",
  209.                 ""
  210.             )
  211.         end
  212.         --Terminal:pressAnyKeyToContinue()
  213.         local res = Terminal:promptConf("&1Confirm selection? &8('"..menu[mode].."')",true)
  214.         if res then Params.DepositMode = mode end
  215.     until res
  216.     Terminal:reset()
  217.     mineVolume = Params.Width * Params.Height * Params.Depth
  218.     --// Check if we have enough fuel for this job
  219.     if Brain:hasEnoughFuel(mineVolume) then
  220.         reset()
  221.         print("Preparing to mine "..mineVolume.." blocks.")
  222.         os.sleep(0.5)        
  223.     else
  224.         Terminal:print("There isn't enough fuel to complete")
  225.         Terminal:print("this job.")
  226.         Terminal:print("")
  227.         Terminal:print("Current Fuel: &e"..turtle.getFuelLevel())
  228.         Terminal:print("Required Fuel: &d"..mineVolume)
  229.         Terminal:print("")
  230.         local res = Terminal:promptConf("Continue anyway?",true)
  231.         if res == false then return false; end
  232.     end
  233.     --// Confirm certain requirments for desired mode
  234.     if Params.DepositMode == DepoMode.LeaveChest then
  235.         Terminal:reset()
  236.         local predChests = math.ceil(mineVolume/1728)
  237.  
  238.         print(
  239.             "Make sure a container block is placed in slot 1 of the turtle.\n"..
  240.             "Without it, you will lose all your items.\n"..
  241.             "(You'll need about "..predChests.." containers [ADD x2, POOR ESITIMATE])\n\n"
  242.         )
  243.         Terminal:pressAnyKeyToContinue()
  244.         Terminal:reset()
  245.     elseif Params.DepositMode == DepoMode.EnderChest then
  246.         Terminal:reset()
  247.         print(
  248.             "Make sure an EnderChest, or something of the sort is placed in slot 1 of the turtle.\n"..
  249.             "Without it, you will lose all your items.\n\n"
  250.         )
  251.         Terminal:pressAnyKeyToContinue()
  252.         Terminal:reset()
  253.     end
  254.     Terminal:reset()
  255.     -- save data to file
  256.     local paramLines = {
  257.         Params.Width,
  258.         Params.Height,
  259.         Params.Depth,
  260.         Params.StartX,
  261.         Params.StartDepth,
  262.         Params.DepositMode
  263.     }
  264.     return true;
  265. end
  266.  
  267. --=====================================================================================
  268.  
  269. function mineLayer()
  270.     --// check if we have fuel for this layer
  271.     local roundTrip = getRoundTripCost()
  272.     local homeTrip = Brain:predictFuelUsageTo(0,0,0)
  273.     if Brain:hasEnoughFuel(getLayerFuelCost()) == false then return false,"Not enough fuel to mine the next layer.\n(has: "..turtle.getFuelLevel()..", needed: "..homeTrip + getLayerFuelCost()..")"; end
  274.     --// Move into layer to mine
  275.     Brain:turnToFace(Dir.N)
  276.     Brain:forceForward()
  277.     if Params.Height == 1 and Params.Width == 1 then return true; end
  278.     --// Mine rows until finished
  279.     while Brain.Y <= Params.Height-1 do
  280.         local mod = Brain.Y % 2
  281.         if mod <= 0 then -- if we odd
  282.             Brain:turnToFace(Dir.E)
  283.             Brain:forceForward(Params.Width-1)
  284.             if Brain:isInvFull(MIN_FULL_SLOTS) then depositItems(true) end
  285.         elseif mod > 0  then -- if we even
  286.             Brain:turnToFace(Dir.W)
  287.             Brain:forceForward(Params.Width-1)
  288.             if Brain:isInvFull(MIN_FULL_SLOTS) then depositItems(true) end
  289.         end
  290.         if Brain.Y == Params.Height-1 then break; end
  291.         Brain:forceUp()
  292.     end
  293.     moveToGroundY()
  294.     --// Reorientate afterwards
  295.     if Brain.X == Params.Width-1 then -- if we are on the far end of X
  296.         Brain:turnToFace(Dir.W)
  297.         Brain:forceForward(Params.Width-1)
  298.     end
  299.     Terminal:reset()
  300.     Terminal:print("Current Progress:")
  301.     Terminal:print(Brain.Z.." out of "..Params.Depth.." layers completed.")
  302.     return true
  303. end
  304.  
  305. function depositItems(doReturn)
  306.     doReturn = doReturn or false
  307.     local lastPos = Brain:getPos()
  308.     local lastDir = Brain.CurrentDir
  309.  
  310.     if Params.DepositMode == DepoMode.RunHome then        
  311.         Brain:moveTo(0,0,0)
  312.         logDepositItems()
  313.         Brain:emptyInventoryDown()
  314.         if doReturn then
  315.             if Brain:hasEnoughFuel(table.unpack(lastPos)) == false then
  316.                 print("Not enough fuel to continue mining, staying at home.")
  317.                 return
  318.             end
  319.             Brain:moveTo(table.unpack(lastPos))
  320.             Brain:turnToFace(lastDir)
  321.         end
  322.  
  323.     elseif Params.DepositMode == DepoMode.LeaveChest then
  324.         -- leave chest
  325.         moveToGroundY()
  326.         turtle.digDown()
  327.         turtle.select(1)
  328.         turtle.placeDown()
  329.         logDepositItems(1)
  330.         Brain:emptyInventoryDown(1)
  331.         -- go back
  332.         Brain:moveTo(table.unpack(lastPos))
  333.         Brain:turnToFace(lastDir)
  334.     elseif Params.DepositMode == DepoMode.EnderChest then
  335.         -- leave ender chest
  336.         turtle.digDown()
  337.         turtle.select(1)
  338.         turtle.placeDown()
  339.         logDepositItems(1)
  340.         Brain:emptyInventoryDown(1)
  341.         turtle.select(1)
  342.         turtle.digDown()
  343.     elseif Params.DepositMode == DepoMode.Discard then
  344.         logDepositItems()
  345.         Brain:emptyInventoryDown()
  346.     end
  347. end
  348.  
  349. --=====================================================================================
  350.  
  351. function logDepositItems(ignoreSlot)
  352.     ignoreSlot = ignoreSlot or -1
  353.     for i = 1, 16 do
  354.         if i ~= ignoreSlot then
  355.             --turtle.select(i)
  356.             local itemData = turtle.getItemDetail(i)
  357.             if itemData then
  358.                 local added = false
  359.                 for name,val in pairs(depositedResources) do
  360.                     if name == itemData.name then
  361.                         depositedResources[name] = depositedResources[name] + itemData.count
  362.                         added = true
  363.                     end
  364.                 end
  365.                 if added == false then
  366.                     depositedResources[itemData.name] = itemData.count
  367.                 end
  368.             end
  369.         end
  370.     end
  371. end
  372.  
  373. function moveToGroundY()
  374.     Brain:moveTo(nil,0,nil)
  375. end
  376.  
  377. function promtBool(text)
  378.     local res = promtNum(text)
  379.     return (res == 1)
  380. end
  381.  
  382. function promtNum(text)
  383.     local res = promt(text)
  384.     return tonumber(res)
  385. end
  386.  
  387. function promt(text)
  388.     reset()
  389.     print(tostring(text))
  390.     term.write("> ")
  391.     return io.read()
  392. end
  393.  
  394. function repeatFunc(times,func)
  395.     for i = 1, times do
  396.         func()
  397.     end
  398. end
  399.  
  400. function reset()
  401.     term.clear()
  402.     term.setCursorPos(1,1)
  403. end
  404.  
  405. function getRoundTripCost()
  406.     local home = {0,0,0}
  407.     local current = Brain:getPos()
  408.     return Brain:predictFuelUsageTo(0,0,0)
  409.     + Brain:predictFuelUsage(0,0,0,current[1],current[2],current[3])
  410. end
  411.  
  412. function getLayerFuelCost()
  413.     return (Params.Width*Params.Height)
  414. end
  415.  
  416. function writeParams(...)
  417.     local p = {...}
  418.     return "W: "..(p[1] or "?")..", H: "..(p[2] or "?")..", D: "..(p[3] or "?")
  419. end
  420.  
  421. function clamp(num,min,max)
  422.     if num > max then
  423.         return max;
  424.     elseif num < min then
  425.         return min
  426.     end
  427.     return num
  428. end
  429.  
  430. function customForceForward(times, ignoreTurts)
  431.     ignoreTurts = ignoreTurts or false
  432.     times = times or 1
  433.     if times == 0 then return; end
  434.     turtle.select(1)
  435.     for i = 1, times do
  436.         self:setHasMoved(false)
  437.         self:saveLastNav()
  438.         if self.CurrentDir == module.Dir.N then
  439.             self.Z = self.Z + 1
  440.         elseif self.CurrentDir == module.Dir.S then
  441.             self.Z = self.Z - 1
  442.         elseif self.CurrentDir == module.Dir.E then
  443.             self.X = self.X + 1
  444.         elseif self.CurrentDir == module.Dir.W then
  445.             self.X = self.X - 1
  446.         end
  447.         self:saveNav()
  448.                
  449.         -- wait for no turtle
  450.         if ignoreTurts == false then
  451.             local isBlock,data = turtle.inspect()
  452.             if isBlock and string.find(data.name,"computercraft:turtle") then
  453.                 repeat os.sleep(0.25) until not turtle.inspect()
  454.             end
  455.         end
  456.        
  457.         repeat turtle.dig() until turtle.forward()
  458.         os.sleep(MOVE_DELAY)
  459.         self:setHasMoved(true)
  460.     end
  461. end
  462. --=====================================================================================
  463.  
  464. Main()
Add Comment
Please, Sign In to add comment