alexnolan

minecraftae2fuel

Mar 27th, 2025
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.37 KB | None | 0 0
  1. -- Powah Reactor Monitoring System
  2. -- Based on the multi-monitor interface framework
  3.  
  4. -- Configuration
  5. local MONITOR_WIDTH = 5  -- 5 monitors wide
  6. local MONITOR_HEIGHT = 3 -- 3 monitors high
  7. local REACTOR_NAME = "powah:reactor_part_0" -- Change this to match your reactor's peripheral name
  8. local SPEAKER_NAME = "speaker" -- Change this to match your speaker's peripheral name
  9. local CHECK_INTERVAL = 5 -- Check fuel every 5 seconds
  10.  
  11. -- Global variables
  12. local monitors = {}
  13. local reactor = nil
  14. local speaker = nil
  15. local totalWidth = 0
  16. local totalHeight = 0
  17. local buttons = {}
  18. local alertMuted = false
  19. local fuelEmpty = false
  20. local lastFuelAmount = 0
  21.  
  22. -- Initialize the system
  23. function init()
  24.     -- Find monitors - improved detection
  25.     local allPeripherals = peripheral.getNames()
  26.     local monitorCount = 0
  27.    
  28.     -- Print all available peripherals for debugging
  29.     print("Available peripherals:")
  30.     for _, name in ipairs(allPeripherals) do
  31.         print("- " .. name .. " (" .. peripheral.getType(name) .. ")")
  32.     end
  33.    
  34.     -- First try the standard naming convention with a wider range
  35.     for i = 0, 15 do  -- Try a wider range of indices
  36.         local name = "monitor_" .. i
  37.         if peripheral.isPresent(name) then
  38.             print("Found monitor: " .. name)
  39.             monitors[monitorCount+1] = peripheral.wrap(name)
  40.             monitors[monitorCount+1].setTextScale(0.5)
  41.             monitors[monitorCount+1].clear()
  42.             monitorCount = monitorCount + 1
  43.         end
  44.     end
  45.    
  46.     -- If we didn't find enough monitors, look for any monitor peripherals
  47.     if monitorCount < (MONITOR_WIDTH * MONITOR_HEIGHT) then
  48.         for _, name in ipairs(allPeripherals) do
  49.             -- Check if it's a monitor and not already in our list
  50.             if peripheral.getType(name) == "monitor" then
  51.                 local alreadyAdded = false
  52.                 for _, existingMonitor in pairs(monitors) do
  53.                     if peripheral.getName(existingMonitor) == name then
  54.                         alreadyAdded = true
  55.                         break
  56.                     end
  57.                 end
  58.                
  59.                 if not alreadyAdded and monitorCount < (MONITOR_WIDTH * MONITOR_HEIGHT) then
  60.                     monitorCount = monitorCount + 1
  61.                     monitors[monitorCount] = peripheral.wrap(name)
  62.                     monitors[monitorCount].setTextScale(0.5)
  63.                     monitors[monitorCount].clear()
  64.                     print("Added monitor: " .. name)
  65.                 end
  66.             end
  67.         end
  68.     end
  69.    
  70.     if monitorCount < (MONITOR_WIDTH * MONITOR_HEIGHT) then
  71.         print("Warning: Not all monitors detected. Found " .. monitorCount .. "/" .. (MONITOR_WIDTH * MONITOR_HEIGHT))
  72.         -- If we found at least one monitor, let's continue anyway
  73.         if monitorCount > 0 then
  74.             print("Continuing with available monitors...")
  75.             -- Adjust the expected dimensions based on what we have
  76.             MONITOR_WIDTH = 1
  77.             MONITOR_HEIGHT = monitorCount
  78.         else
  79.             return false
  80.         end
  81.     else
  82.         print("Successfully connected to " .. monitorCount .. " monitors")
  83.     end
  84.    
  85.     -- Find Powah Reactor
  86.     reactor = peripheral.wrap(REACTOR_NAME)
  87.     if not reactor then
  88.         print("Error: Powah Reactor not found! Trying to find it automatically...")
  89.         -- Try to find it automatically
  90.         reactor = peripheral.find("powah_reactor")
  91.         if not reactor then
  92.             print("Error: Could not find any Powah Reactor!")
  93.             return false
  94.         else
  95.             print("Found Powah Reactor: " .. peripheral.getName(reactor))
  96.         end
  97.     else
  98.         print("Connected to Powah Reactor: " .. REACTOR_NAME)
  99.     end
  100.    
  101.     -- Find Speaker
  102.     speaker = peripheral.wrap(SPEAKER_NAME)
  103.     if not speaker then
  104.         print("Warning: Speaker not found! Trying to find it automatically...")
  105.         -- Try to find it automatically
  106.         speaker = peripheral.find("speaker")
  107.         if not speaker then
  108.             print("Warning: Could not find any speaker. Alerts will be visual only.")
  109.         else
  110.             print("Found Speaker: " .. peripheral.getName(speaker))
  111.         end
  112.     else
  113.         print("Connected to Speaker: " .. SPEAKER_NAME)
  114.     end
  115.    
  116.     -- Get monitor dimensions
  117.     if monitorCount > 0 then
  118.         local w, h = monitors[1].getSize()
  119.         totalWidth = w * MONITOR_WIDTH
  120.         totalHeight = h * MONITOR_HEIGHT
  121.         print("Total display size: " .. totalWidth .. "x" .. totalHeight)
  122.     end
  123.    
  124.     return true
  125. end
  126.  
  127. -- Convert global coordinates to monitor-specific coordinates
  128. function getMonitorAt(x, y)
  129.     if x < 1 or y < 1 or x > totalWidth or y > totalHeight then
  130.         return nil
  131.     end
  132.    
  133.     local monitorWidth = totalWidth / MONITOR_WIDTH
  134.     local monitorHeight = totalHeight / MONITOR_HEIGHT
  135.    
  136.     local monX = math.ceil(x / monitorWidth)
  137.     local monY = math.ceil(y / monitorHeight)
  138.     local index = (monY - 1) * MONITOR_WIDTH + monX
  139.    
  140.     -- Check if the monitor exists at this index
  141.     if not monitors[index] then
  142.         print("Warning: No monitor found at index " .. index .. " (position " .. monX .. "," .. monY .. ")")
  143.         return nil
  144.     end
  145.    
  146.     local relX = (x - 1) % monitorWidth + 1
  147.     local relY = (y - 1) % monitorHeight + 1
  148.    
  149.     return monitors[index], relX, relY
  150. end
  151.  
  152. -- Clear all monitors
  153. function clearScreen()
  154.     for _, monitor in pairs(monitors) do
  155.         monitor.clear()
  156.     end
  157. end
  158.  
  159. -- Write text at global coordinates
  160. function writeText(x, y, text, textColor, bgColor)
  161.     local monitor, relX, relY = getMonitorAt(x, y)
  162.     if monitor then
  163.         if textColor then monitor.setTextColor(textColor) end
  164.         if bgColor then monitor.setBackgroundColor(bgColor) end
  165.         monitor.setCursorPos(relX, relY)
  166.         monitor.write(text)
  167.     end
  168. end
  169.  
  170. -- Draw a filled rectangle
  171. function fillRect(startX, startY, endX, endY, color)
  172.     for y = startY, endY do
  173.         for x = startX, endX do
  174.             local monitor, relX, relY = getMonitorAt(x, y)
  175.             if monitor then
  176.                 monitor.setBackgroundColor(color)
  177.                 monitor.setCursorPos(relX, relY)
  178.                 monitor.write(" ")
  179.             end
  180.         end
  181.     end
  182. end
  183.  
  184. -- Draw a button with text
  185. function drawButton(x, y, width, height, text, bgColor, textColor)
  186.     fillRect(x, y, x + width - 1, y + height - 1, bgColor or colors.blue)
  187.    
  188.     -- Center the text
  189.     local textX = x + math.floor((width - #text) / 2)
  190.     local textY = y + math.floor(height / 2)
  191.     writeText(textX, textY, text, textColor or colors.white, bgColor or colors.blue)
  192.    
  193.     return {
  194.         x = x,
  195.         y = y,
  196.         width = width,
  197.         height = height,
  198.         text = text
  199.     }
  200. end
  201.  
  202. -- Check if coordinates are within a button
  203. function isInButton(button, x, y)
  204.     return x >= button.x and x < button.x + button.width and
  205.            y >= button.y and y < button.y + button.height
  206. end
  207.  
  208. -- Draw a centered title
  209. function drawTitle(y, text, color)
  210.     local textX = math.floor((totalWidth - #text) / 2) + 1
  211.     writeText(textX, y, text, color or colors.yellow, colors.black)
  212. end
  213.  
  214. -- Get reactor fuel information
  215. function getReactorInfo()
  216.     if not reactor then
  217.         return {
  218.             fuelAmount = 0,
  219.             maxFuelAmount = 1,
  220.             energyStored = 0,
  221.             maxEnergyStored = 1,
  222.             generating = 0,
  223.             active = false
  224.         }
  225.     end
  226.    
  227.     local info = {
  228.         fuelAmount = 0,
  229.         maxFuelAmount = 64,
  230.         energyStored = 0,
  231.         maxEnergyStored = 1000000,
  232.         generating = 0,
  233.         active = false
  234.     }
  235.    
  236.     -- Try to get fuel information
  237.     if reactor.list then
  238.         local items = reactor.list()
  239.         for slot, item in pairs(items) do
  240.             -- Check for uraninite
  241.             if item.name and item.name:find("uraninite") then
  242.                 info.fuelAmount = info.fuelAmount + item.count
  243.                 if item.maxCount then
  244.                     info.maxFuelAmount = item.maxCount * 8 -- Assuming 8 fuel slots
  245.                 end
  246.             end
  247.         end
  248.     end
  249.    
  250.     -- Get energy information
  251.     if reactor.getEnergy then
  252.         info.energyStored = reactor.getEnergy()
  253.         info.maxEnergyStored = reactor.getEnergyCapacity() or 1000000
  254.     end
  255.    
  256.     -- Get generation rate
  257.     if reactor.getGenerationRate then
  258.         info.generating = reactor.getGenerationRate()
  259.     end
  260.    
  261.     -- Get active status
  262.     if reactor.isActive then
  263.         info.active = reactor.isActive()
  264.     else
  265.         info.active = (info.fuelAmount > 0)
  266.     end
  267.    
  268.     return info
  269. end
  270.  
  271.  
  272. -- Play alert sound
  273. function playAlert()
  274.     if speaker and not alertMuted then
  275.         speaker.playNote("block.note_block.bell", 1.0, 1.0)
  276.         sleep(0.2)
  277.         speaker.playNote("block.note_block.bell", 1.0, 0.8)
  278.         sleep(0.2)
  279.         speaker.playNote("block.note_block.bell", 1.0, 0.6)
  280.     end
  281. end
  282.  
  283. -- Draw the main monitoring screen
  284. function drawMonitoringScreen()
  285.     clearScreen()
  286.     buttons = {}
  287.    
  288.     -- Draw title
  289.     drawTitle(2, "Powah Reactor Monitoring System", colors.yellow)
  290.    
  291.     -- Get reactor info
  292.     local info = getReactorInfo()
  293.    
  294.     -- Calculate fuel percentage
  295.     local fuelPercent = (info.fuelAmount / info.maxFuelAmount) * 100
  296.    
  297.     -- Draw fuel gauge background
  298.     local gaugeWidth = math.floor(totalWidth * 0.8)
  299.     local gaugeHeight = 3
  300.     local gaugeX = math.floor((totalWidth - gaugeWidth) / 2)
  301.     local gaugeY = 6
  302.     fillRect(gaugeX, gaugeY, gaugeX + gaugeWidth - 1, gaugeY + gaugeHeight - 1, colors.gray)
  303.    
  304.     -- Draw fuel gauge fill
  305.     local fillWidth = math.floor((fuelPercent / 100) * gaugeWidth)
  306.     if fillWidth > 0 then
  307.         local fillColor = colors.green
  308.         if fuelPercent < 25 then
  309.             fillColor = colors.red
  310.         elseif fuelPercent < 50 then
  311.             fillColor = colors.orange
  312.         end
  313.         fillRect(gaugeX, gaugeY, gaugeX + fillWidth - 1, gaugeY + gaugeHeight - 1, fillColor)
  314.     end
  315.    
  316.     -- Draw fuel text
  317.     local fuelText = string.format("Uraninite: %d / %d (%.1f%%)",
  318.                                   info.fuelAmount,
  319.                                   info.maxFuelAmount,
  320.                                   fuelPercent)
  321.     writeText(math.floor((totalWidth - #fuelText) / 2), gaugeY + 1, fuelText, colors.white)
  322.    
  323.     -- Draw status information
  324.     local statusY = gaugeY + gaugeHeight + 2
  325.     local statusColor = colors.white
  326.    
  327.     -- Reactor status
  328.     local statusText = "Reactor Status: "
  329.     if info.active then
  330.         statusText = statusText .. "Active"
  331.         statusColor = colors.green
  332.     else
  333.         statusText = statusText .. "Inactive"
  334.         statusColor = colors.red
  335.     end
  336.     writeText(math.floor((totalWidth - #statusText) / 2), statusY, statusText, statusColor)
  337.    
  338.     -- Energy information
  339.     local energyY = statusY + 2
  340.     local energyPercent = (info.energyStored / info.maxEnergyStored) * 100
  341.     local energyText = string.format("Energy: %.1f%% (%.1f FE/t)",
  342.                                     energyPercent,
  343.                                     info.generating)
  344.     writeText(math.floor((totalWidth - #energyText) / 2), energyY, energyText, colors.white)
  345.    
  346.     -- Alert status
  347.     local alertY = energyY + 2
  348.     local alertText = "Fuel Alert: "
  349.     if fuelEmpty then
  350.         alertText = alertText .. "FUEL EMPTY!"
  351.         writeText(math.floor((totalWidth - #alertText) / 2), alertY, alertText, colors.red)
  352.        
  353.         -- Draw mute button
  354.         local buttonText = alertMuted and "Unmute Alert" or "Mute Alert"
  355.         local muteButton = drawButton(
  356.             math.floor(totalWidth / 2) - 8,
  357.             alertY + 2,
  358.             16,
  359.             3,
  360.             buttonText,
  361.             alertMuted and colors.gray or colors.red
  362.         )
  363.         muteButton.action = "toggle_mute"
  364.         table.insert(buttons, muteButton)
  365.        
  366.         -- Play alert if not muted and fuel is empty
  367.         if not alertMuted and info.fuelAmount == 0 and os.clock() % 10 < 5 then
  368.             playAlert()
  369.         end
  370.     else
  371.         alertText = alertText .. "Normal"
  372.         writeText(math.floor((totalWidth - #alertText) / 2), alertY, alertText, colors.green)
  373.     end
  374.    
  375.     -- Draw refresh button
  376.     local refreshButton = drawButton(
  377.         totalWidth - 12,
  378.         totalHeight - 4,
  379.         10,
  380.         3,
  381.         "Refresh",
  382.         colors.blue
  383.     )
  384.     refreshButton.action = "refresh"
  385.     table.insert(buttons, refreshButton)
  386.    
  387.     -- Draw last updated time
  388.     local timeText = "Last updated: " .. textutils.formatTime(os.time(), true)
  389.     writeText(2, totalHeight - 1, timeText, colors.lightGray)
  390.    
  391.     -- Check if fuel status has changed
  392.     local currentlyEmpty = (info.fuelAmount == 0)
  393.     if currentlyEmpty ~= fuelEmpty then
  394.         fuelEmpty = currentlyEmpty
  395.         if fuelEmpty then
  396.             -- Fuel just ran out
  397.             playAlert()
  398.         else
  399.             -- Fuel was added back
  400.             alertMuted = false
  401.         end
  402.     end
  403.    
  404.     -- Store last fuel amount
  405.     lastFuelAmount = info.fuelAmount
  406. end
  407.  
  408. -- Handle touch events
  409. function handleTouch(x, y)
  410.     for _, button in ipairs(buttons) do
  411.         if isInButton(button, x, y) then
  412.             if button.action == "toggle_mute" then
  413.                 alertMuted = not alertMuted
  414.                 drawMonitoringScreen()
  415.             elseif button.action == "refresh" then
  416.                 drawMonitoringScreen()
  417.             end
  418.             break
  419.         end
  420.     end
  421. end
  422.  
  423. -- Main program
  424. function run()
  425.     if not init() then
  426.         print("Failed to initialize the system")
  427.         return
  428.     end
  429.    
  430.     -- Draw initial screen
  431.     drawMonitoringScreen()
  432.    
  433.     -- Main event loop with periodic updates
  434.     local lastUpdateTime = os.clock()
  435.    
  436.     while true do
  437.         -- Check if it's time for a periodic update
  438.         local currentTime = os.clock()
  439.         if currentTime - lastUpdateTime >= CHECK_INTERVAL then
  440.             drawMonitoringScreen()
  441.             lastUpdateTime = currentTime
  442.         end
  443.        
  444.         -- Handle events
  445.         local event, side, x, y = os.pullEvent("monitor_touch")
  446.         handleTouch(x, y)
  447.     end
  448. end
  449.  
  450. -- Start the program
  451. run()
  452.  
  453.  
Add Comment
Please, Sign In to add comment