Advertisement
drpepper240

Multiminer v4

Dec 27th, 2023 (edited)
866
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.70 KB | None | 0 0
  1. -- MultiMiner v4 by DrPepper
  2. -- made for tweaked.cc and WarpDrive Minecraft mods
  3.  
  4. -- settings (peristent)
  5. local defaultSettings = {
  6. minerRefreshSeconds = 0.25,
  7. inactiveMinerRefreshSeconds = 5,
  8. silkTouch = false,
  9. onlyOres = true,
  10. laserOffset = 8,
  11. fontSize = 5,   -- times 10
  12. redstoneOut = false
  13. }
  14.  
  15. -- program state
  16. local isQuitting = false
  17. local startMining = false
  18. local stopMining = false
  19. local isActive = false
  20. local laserCnt = 0
  21. local laserStartingH = 0
  22. local laserSettingsChanged = true
  23. local energyUnits = nil
  24. local showPositions = false
  25.  
  26. local lasers = {}
  27. local settings = {}
  28. local monitor = nil
  29.  
  30. -- functions
  31. local BoolToRedGreen, FixOffset, IncFontSize, RedstoneOutput, AttachNewLaser
  32. local Init, MinerLoop, InputLoop, RedrawLoop, RefreshLoop, Shutdown, ReadSettings, WriteSettings
  33. local DrawAll, DrawHeader, DrawTable, DrawFooter
  34.  
  35. function BoolToRedGreen(value)
  36.     if value then
  37.         return colors.green
  38.     else
  39.         return colors.red
  40.     end
  41. end
  42.  
  43.  
  44. function FixOffset(laserOffsetInput)
  45.     if laserOffsetInput > 255 then
  46.         return 255
  47.     elseif laserOffsetInput < 0 then
  48.         return 0
  49.     else
  50.         return laserOffsetInput
  51.     end
  52. end
  53.  
  54.  
  55. function IncFontSize(currentSize)
  56.     if currentSize >= 50 or currentSize < 5 then
  57.         return 5
  58.     else
  59.         return currentSize + 5
  60.     end
  61. end
  62.  
  63.  
  64. function RedstoneOutput(emit)
  65.     for _, side in pairs(redstone.getSides()) do
  66.         rs.setOutput(side, emit)
  67.     end
  68. end
  69.  
  70.  
  71. function ReadSettings()
  72.     local file = fs.open("multiminer.cfg","r")
  73.     if file ~= nil then
  74.         settings = textutils.unserialize(file.readAll())
  75.     end
  76.     for k,v in pairs (defaultSettings) do
  77.         if settings[k] == nil then
  78.             settings[k] = defaultSettings[k]
  79.         end
  80.     end
  81.     for k,v in pairs (settings) do
  82.         print("Settings: " .. tostring(k) .. " : " .. tostring(v))
  83.     end
  84. end
  85.  
  86.  
  87. function WriteSettings()
  88.     local file = fs.open("multiminer.cfg","w")
  89.     file.write(textutils.serialize(settings))
  90.     file.close()
  91. end
  92.  
  93.  
  94. function AttachNewLaser(side)
  95.     laserCnt = laserCnt + 1
  96.     lasers[laserCnt] = {}
  97.     lasers[laserCnt].peripheral = peripheral.wrap(side)
  98.     lasers[laserCnt].side = side
  99.     print("Wrapped warpdriveMiningLaser on " .. side .. " side")
  100.     if energyUnits == nil then
  101.         energyUnits = lasers[laserCnt].peripheral.energyDisplayUnits()
  102.     end
  103.     local lx, ly, lz = lasers[laserCnt].peripheral.getLocalPosition()
  104.     lasers[laserCnt].x = lx
  105.     lasers[laserCnt].y = ly
  106.     lasers[laserCnt].z = lz
  107. end
  108.  
  109.  
  110. function Init()
  111.     if not term.isColor() then
  112.         print("Advanced computer required. Go find some gold.")
  113.     end
  114.     ReadSettings()
  115.     WriteSettings()
  116.     local sides = peripheral.getNames()
  117.     for _, side in pairs(sides) do
  118.         if peripheral.getType(side) == "warpdriveMiningLaser" then
  119.             AttachNewLaser(side)
  120.         elseif monitor == nil and peripheral.getType(side) == "monitor" then
  121.             print("Wrapping monitor on " .. side .. " side")
  122.             monitor = peripheral.wrap(side)
  123.             monitor.setBackgroundColor(colors.black)
  124.             monitor.clear()
  125.             monitor.setTextScale(settings.fontSize / 10.0)
  126.             monitor.setPaletteColor(colors.lightGray, 0.4, 0.4, 0.4)
  127.         end
  128.     end
  129.    
  130.     sleep(1)
  131.     term.clear()
  132.     term.setPaletteColor(colors.lightGray, 0.4, 0.4, 0.4)
  133.     os.queueEvent("redraw")
  134. end
  135.  
  136.  
  137. function Shutdown()
  138.     term.setTextColor(colors.white)
  139.     term.setBackgroundColor(colors.black)
  140.     term.clear()
  141.     term.setPaletteColor(colors.lightGray, term.nativePaletteColor(colors.lightGray))
  142.     term.setCursorPos(1,1)
  143.     RedstoneOutput(false)
  144. end
  145.  
  146.  
  147. function RefreshLoop()
  148.     while not isQuitting do
  149.         os.queueEvent("refreshMiners")
  150.         sleep(settings.inactiveMinerRefreshSeconds)
  151.     end
  152. end
  153.  
  154.  
  155. function MinerLoop()
  156.     local timerId = nil
  157.     while not isQuitting do
  158.         local redrawNeeded = false
  159.         local ev, p2 = os.pullEvent()
  160.        
  161.         if ev == "peripheral_detach" then
  162.             for _,v in pairs (lasers) do
  163.                 if v.side == p2 then
  164.                     v.peripheral = nil
  165.                     v.status = "DETACHED"
  166.                     redrawNeeded = true
  167.                 end
  168.             end
  169.         end
  170.        
  171.         if ev == "peripheral" and peripheral.getType(p2) == "warpdriveMiningLaser" then
  172.             local existingLaser = false
  173.             for _,v in pairs (lasers) do
  174.                 if v.side == p2 then
  175.                     v.peripheral = peripheral.wrap(p2)
  176.                     existingLaser = true
  177.                 end
  178.             end
  179.             if not existingLaser then
  180.                 AttachNewLaser(p2)
  181.             end
  182.             redrawNeeded = true
  183.         end
  184.        
  185.         if (ev == "timer" and p2 == timerId) or ev == "refreshMiners" then
  186.             RedstoneOutput(settings.redstoneOut and (isActive or startMining))
  187.             if not laserSettingsChanged then
  188.                 if startMining or isActive then
  189.                     timerId = os.startTimer(settings.minerRefreshSeconds)
  190.                 end
  191.             end
  192.             isActive = false
  193.             for k,v in pairs (lasers) do
  194.                 if v.peripheral ~= nil then
  195.                     if laserSettingsChanged or startMining then
  196.                         v.peripheral.offset(settings.laserOffset)
  197.                         v.peripheral.onlyOres(settings.onlyOres)
  198.                         v.peripheral.silktouch(settings.silkTouch)
  199.                     end
  200.                     if startMining then
  201.                         v.peripheral.enable(true)
  202.                         redrawNeeded = true
  203.                     end
  204.                     if stopMining then
  205.                         v.peripheral.enable(false)
  206.                         redrawNeeded = true
  207.                     end
  208.                     local r1, r2, r3, r4, r5, r6 = v.peripheral.state()
  209.                     if v.status ~=r1 or
  210.                         v.isActive ~= r2 or
  211.                         v.energy ~= r3 or
  212.                         v.currentLayer ~= r4 or
  213.                         v.mined ~= r5 or
  214.                         v.total ~= r6 then
  215.                         v.status, v.isActive, v.energy, v.currentLayer, v.mined, v.total = r1, r2, r3, r4, r5, r6
  216.                         redrawNeeded = true
  217.                     end
  218.                     v.offset = v.peripheral.offset()
  219.                     isActive = isActive or r2
  220.                 end
  221.             end
  222.             if isActive then
  223.                 startMining = false
  224.             else
  225.                 stopMining = false
  226.             end
  227.             laserSettingsChanged = false
  228.         end
  229.         if redrawNeeded then
  230.             os.queueEvent("redraw")
  231.         end
  232.     end
  233. end
  234.  
  235.  
  236. function InputLoop()
  237.     while not isQuitting do
  238.         local event, p2, p3, p4, p5 = os.pullEvent("key")
  239.         if keys.getName(p2) == "q" then
  240.             isQuitting = true
  241.         elseif keys.getName(p2) == "s" then
  242.             stopMining = true
  243.             os.queueEvent("refreshMiners")
  244.         elseif keys.getName(p2) == "m" then
  245.             startMining = true
  246.             os.queueEvent("refreshMiners")
  247.         elseif keys.getName(p2) == "o" then
  248.             settings.onlyOres = not settings.onlyOres
  249.             laserSettingsChanged = true
  250.             os.queueEvent("refreshMiners")
  251.         elseif keys.getName(p2) == "t" then
  252.             settings.silkTouch = not settings.silkTouch
  253.             laserSettingsChanged = true
  254.             os.queueEvent("refreshMiners")
  255.         elseif keys.getName(p2) == "down" then
  256.             settings.laserOffset = FixOffset(settings.laserOffset + 1)
  257.             laserSettingsChanged = true
  258.         elseif keys.getName(p2) == "up" then
  259.             settings.laserOffset = FixOffset(settings.laserOffset - 1)
  260.             laserSettingsChanged = true
  261.         elseif keys.getName(p2) == "right" then
  262.             settings.laserOffset = FixOffset(settings.laserOffset - 10)
  263.             laserSettingsChanged = true
  264.         elseif keys.getName(p2) == "left" then
  265.             settings.laserOffset = FixOffset(settings.laserOffset + 10)
  266.             laserSettingsChanged = true
  267.         elseif keys.getName(p2) == "p" then
  268.             showPositions = not showPositions
  269.         elseif keys.getName(p2) == "f" then
  270.             if monitor ~= nil then
  271.                 settings.fontSize = IncFontSize(settings.fontSize)
  272.                 monitor.setTextScale(settings.fontSize / 10.0)
  273.             end
  274.         elseif keys.getName(p2) == "r" then
  275.             settings.redstoneOut = not settings.redstoneOut
  276.         end
  277.         WriteSettings()
  278.         os.queueEvent("redraw")
  279.     end
  280. end
  281.  
  282.  
  283. function RedrawLoop()
  284.     while not isQuitting do
  285.         local event = os.pullEvent("redraw")
  286.         DrawAll()
  287.     end
  288. end
  289.  
  290.  
  291. function DrawAll()
  292.     DrawHeader(term)
  293.     DrawHeader(monitor)
  294.     DrawTable(term)
  295.     DrawTable(monitor)
  296.     DrawFooter(term)
  297. end
  298.  
  299.  
  300. function DrawHeader(drawDevice)
  301.     if drawDevice == nil then
  302.         return
  303.     end
  304.     local maxX, maxY = drawDevice.getSize()
  305.     local str = "MultiMiner v4"
  306.     drawDevice.setCursorPos(math.ceil((maxX - string.len(str)) / 2 + 1), 1)
  307.     drawDevice.setTextColor(colors.orange)
  308.     drawDevice.setBackgroundColor(colors.black)
  309.     drawDevice.clearLine()
  310.     drawDevice.write(str)
  311.     drawDevice.setTextColor(colors.black)
  312.     drawDevice.setBackgroundColor(colors.orange)
  313.     drawDevice.setCursorPos(1, 2)
  314.     drawDevice.clearLine()
  315.     laserStartingH = 0
  316.     for k,v in pairs (lasers) do
  317.         if v.y ~= nil then
  318.             local newH = v.y - settings.laserOffset - 1
  319.             if newH > laserStartingH then
  320.                 laserStartingH = newH
  321.             end
  322.         end
  323.     end
  324.     drawDevice.write("Starts at height: " .. laserStartingH)
  325.     if (settings.redstoneOut) then
  326.         if (isActive) then
  327.             drawDevice.setTextColor(colors.red)
  328.         else
  329.             drawDevice.setTextColor(colors.black)
  330.         end
  331.         drawDevice.write("  R")
  332.     end
  333.     drawDevice.setCursorPos(maxX - 25, 2)
  334.     drawDevice.setTextColor(BoolToRedGreen(settings.onlyOres))
  335.     drawDevice.write("\7")
  336.     drawDevice.setTextColor(colors.black)
  337.     drawDevice.write(" Only ores")
  338.     drawDevice.setCursorPos(maxX - 11, 2)
  339.     drawDevice.setTextColor(BoolToRedGreen(settings.silkTouch))
  340.     drawDevice.write("\7")
  341.     drawDevice.setTextColor(colors.black)
  342.     drawDevice.write(" Silk touch")
  343.  
  344.     if isQuitting then
  345.         drawDevice.setCursorPos(1,1)
  346.         drawDevice.setTextColor(colors.white)
  347.         drawDevice.setBackgroundColor(colors.black)
  348.         drawDevice.clearLine()
  349.         drawDevice.write("Quitting...")
  350.     end
  351. end
  352.  
  353. --###################################################
  354. --#    Status                   Energy    Hei Min/Tot
  355. --99 o Status message           123456 EU 999 123/456
  356.  
  357. function DrawTable(drawDevice)
  358.     if drawDevice == nil then
  359.         return
  360.     end
  361.     local maxX, maxY = drawDevice.getSize()
  362.     drawDevice.setCursorPos(1, 3)
  363.     drawDevice.setTextColor(colors.black)
  364.     drawDevice.setBackgroundColor(colors.orange)
  365.     drawDevice.clearLine()
  366.     drawDevice.write("#    Status")
  367.     local xAlign = maxX - 21
  368.     if xAlign < 5 then xAlign = 5 end
  369.     drawDevice.setCursorPos(xAlign, 3)
  370.     drawDevice.write(string.format(" %-9.9s %-3.3s %-3.3s/%-3.3s", "Energy", "Height", "Mined", "Total"))
  371.    
  372.     drawDevice.setCursorPos(1, 4)
  373.     for k,v in pairs (lasers) do
  374.         local cx, cy = drawDevice.getCursorPos()
  375.         if cy % 2 == 1 then
  376.             drawDevice.setBackgroundColor(colors.gray)
  377.         else
  378.             drawDevice.setBackgroundColor(colors.lightGray)
  379.         end
  380.         drawDevice.setTextColor(colors.white)
  381.         drawDevice.clearLine()
  382.         drawDevice.write(string.format("%2d", tonumber(k)))
  383.         drawDevice.setTextColor(BoolToRedGreen(v.isActive))
  384.         drawDevice.write(" \7 ")
  385.         drawDevice.setTextColor(colors.white)
  386.         local status = tostring(v.status)
  387.         if showPositions then
  388.             status = tostring(v.x) .. "; " .. tostring(v.y) .. "; " .. tostring(v.z)
  389.         end
  390.         drawDevice.write(status)
  391.         drawDevice.setCursorPos(xAlign, cy)
  392.         drawDevice.write(string.format(" %-6s %-2.2s %3s %3.3s/%-3.3s",
  393.             tostring(v.energy),
  394.             energyUnits,
  395.             tostring(v.currentLayer),
  396.             tostring(v.mined),
  397.             tostring(v.total)))
  398.         drawDevice.setCursorPos(1, cy + 1)
  399.     end
  400. end
  401.  
  402.  
  403. function DrawFooter(drawDevice)
  404.     if drawDevice == nil then
  405.         return
  406.     end
  407.     local maxX, maxY = drawDevice.getSize()
  408.     drawDevice.setTextColor(colors.white)
  409.     drawDevice.setBackgroundColor(colors.gray)
  410.     drawDevice.setCursorPos(1, maxY-2)
  411.     drawDevice.clearLine()
  412.     drawDevice.blit(    "[P] Toggle position   [F] Font size   [R] Redstone",
  413.                         "01000000000000000000000100000000000000010000000000",
  414.                         "77777777777777777777777777777777777777777777777777"    )
  415.     drawDevice.setBackgroundColor(colors.gray)
  416.     drawDevice.setCursorPos(1, maxY-1)
  417.     drawDevice.clearLine()
  418.     drawDevice.blit(    "[O] Only ores   [T] Silk touch   [\24\25\26\27] Offset:",
  419.                         "01000000000000000100000000000000001111000000000",
  420.                         "77777777777777777777777777777777777777777777777"   )
  421.     drawDevice.setBackgroundColor(colors.black)
  422.     drawDevice.write(string.format(" %3s", settings.laserOffset))
  423.     drawDevice.setBackgroundColor(colors.gray)
  424.     drawDevice.setCursorPos(1, maxY)
  425.     drawDevice.clearLine()
  426.     drawDevice.blit(    "[M] Mine   [S] Stop   [Q] Exit",
  427.                         "010000000000100000000001000000",
  428.                         "777777777777777777777777777777"    )
  429. end
  430.  
  431. Init()
  432. parallel.waitForAny(MinerLoop, RedrawLoop, InputLoop, RefreshLoop)
  433. Shutdown()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement