Advertisement
DubSlime

ae2-monitor v3

Apr 28th, 2025 (edited)
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.29 KB | None | 0 0
  1. -- AE2 Monitor Deluxe Edition
  2. -- Light Theme + Crafting + Storage Recap + Sorted Items + Popup Details
  3. -- By ChatGPT
  4.  
  5. -- Find peripherals
  6. local monitor = peripheral.find("monitor")
  7. local me = peripheral.find("meBridge")
  8.  
  9. if not monitor then error("No monitor connected!") end
  10. if not me then error("No ME Bridge connected!") end
  11.  
  12. -- SETTINGS
  13. monitor.setTextScale(0.5)
  14. local w, h = monitor.getSize()
  15. local itemsPerPage = h - 8
  16. local pageCrafting = 1
  17. local pageStorage = 1
  18. local activeTab = "crafting"
  19. local blinkState = true
  20. local selectedItem = nil
  21. local history = {}
  22.  
  23. -- COLORS
  24. local bgColor = colors.white
  25. local textColor = colors.black
  26. local tabActive = colors.lightBlue
  27. local tabInactive = colors.gray
  28. local footerColor = colors.lightGray
  29. local busyColor = colors.blue
  30. local overloadedColor = colors.red
  31. local idleColor = colors.green
  32. local popupColor = colors.orange
  33.  
  34. -- UTILITIES
  35. local function centerText(text, y, textCol, bgCol)
  36.     monitor.setCursorPos(math.floor((w - #text) / 2) + 1, y)
  37.     monitor.setTextColor(textCol or textColor)
  38.     monitor.setBackgroundColor(bgCol or bgColor)
  39.     monitor.write(text)
  40. end
  41.  
  42. local function drawBlock(x1, y1, x2, y2, bg)
  43.     monitor.setBackgroundColor(bg)
  44.     for y = y1, y2 do
  45.         monitor.setCursorPos(x1, y)
  46.         monitor.write(string.rep(" ", x2 - x1 + 1))
  47.     end
  48. end
  49.  
  50. local function drawButton(x1, x2, label, enabled)
  51.     monitor.setBackgroundColor(enabled and colors.lightBlue or colors.gray)
  52.     local mid = math.floor((x1 + x2) / 2) - math.floor(#label / 2)
  53.     monitor.setCursorPos(mid, h)
  54.     monitor.setTextColor(colors.black)
  55.     monitor.write(label)
  56. end
  57.  
  58. local function drawTabs()
  59.     local half = math.floor(w / 2)
  60.     drawBlock(1, 1, w, 2, footerColor)
  61.  
  62.     drawBlock(1, 1, half, 2, activeTab == "crafting" and tabActive or tabInactive)
  63.     centerText("Crafting", 1, colors.white, activeTab == "crafting" and tabActive or tabInactive)
  64.  
  65.     drawBlock(half + 1, 1, w, 2, activeTab == "storage" and tabActive or tabInactive)
  66.     monitor.setCursorPos(half + math.floor((half - 7) / 2), 1)
  67.     monitor.setTextColor(colors.white)
  68.     monitor.write("Storage")
  69. end
  70.  
  71. local function drawProgressBar(x, y, width, percentage, fgColor, bgColor)
  72.     local fillWidth = math.floor(width * percentage + 0.5)
  73.     monitor.setCursorPos(x, y)
  74.     monitor.setBackgroundColor(fgColor)
  75.     monitor.write(string.rep(" ", fillWidth))
  76.     monitor.setBackgroundColor(bgColor)
  77.     monitor.write(string.rep(" ", width - fillWidth))
  78. end
  79.  
  80. local function drawCraftingTab()
  81.     monitor.setBackgroundColor(bgColor)
  82.     monitor.clear()
  83.     drawTabs()
  84.     centerText("Ongoing Crafting Jobs", 4, textColor, bgColor)
  85.  
  86.     local cpus = me.getCraftingCPUs() or {}
  87.     local totalPages = math.max(1, math.ceil(#cpus / itemsPerPage))
  88.     pageCrafting = math.min(pageCrafting, totalPages)
  89.  
  90.     local startIdx = (pageCrafting - 1) * itemsPerPage + 1
  91.     local endIdx = math.min(#cpus, startIdx + itemsPerPage - 1)
  92.  
  93.     local y = 6
  94.     for idx = startIdx, endIdx do
  95.         local cpu = cpus[idx]
  96.         if cpu then
  97.             local name = cpu.name or ("CPU #" .. idx)
  98.             if name == "" then name = "Unnamed CPU" end
  99.             local busy = cpu.isBusy
  100.  
  101.             local cpuColor = idleColor
  102.             if busy then
  103.                 cpuColor = blinkState and busyColor or overloadedColor
  104.             end
  105.  
  106.             drawBlock(2, y, w - 1, y + 2, footerColor)
  107.             monitor.setCursorPos(4, y + 1)
  108.             monitor.setTextColor(textColor)
  109.             monitor.write(name:sub(1, w - 15))
  110.  
  111.             local usage = busy and 0.6 or 0.1
  112.             monitor.setCursorPos(w - 15, y + 1)
  113.             drawProgressBar(w - 15, y + 1, 13, usage, cpuColor, colors.gray)
  114.  
  115.             y = y + 4
  116.         end
  117.     end
  118.  
  119.     drawBlock(1, h, w, h, footerColor)
  120.     drawButton(1, math.floor(w / 2) - 1, "< Prev", pageCrafting > 1)
  121.     drawButton(math.floor(w / 2) + 1, w, "Next >", pageCrafting < totalPages)
  122.     centerText("Page " .. pageCrafting .. "/" .. totalPages, h - 1, textColor, footerColor)
  123. end
  124.  
  125. local function sortByAmountDesc(a, b)
  126.     return (a.amount or 0) > (b.amount or 0)
  127. end
  128.  
  129. local storageCache = {}
  130.  
  131. local function drawStorageTab()
  132.     monitor.setBackgroundColor(bgColor)
  133.     monitor.clear()
  134.     drawTabs()
  135.     centerText("Storage Overview", 4, textColor, bgColor)
  136.  
  137.     storageCache = me.listItems() or {}
  138.     table.sort(storageCache, sortByAmountDesc)
  139.  
  140.     local totalPages = math.max(1, math.ceil(#storageCache / itemsPerPage))
  141.     pageStorage = math.min(pageStorage, totalPages)
  142.  
  143.     local startIdx = (pageStorage - 1) * itemsPerPage + 1
  144.     local endIdx = math.min(#storageCache, startIdx + itemsPerPage - 1)
  145.  
  146.     local y = 6
  147.     for idx = startIdx, endIdx do
  148.         local item = storageCache[idx]
  149.         local name = item.displayName or "Unknown"
  150.         local amount = item.amount or 0
  151.  
  152.         if idx - startIdx < 5 then
  153.             drawBlock(2, y, w - 1, y, colors.lightBlue)
  154.             monitor.setTextColor(colors.white)
  155.         else
  156.             monitor.setBackgroundColor(bgColor)
  157.             monitor.setTextColor(textColor)
  158.         end
  159.  
  160.         monitor.setCursorPos(3, y)
  161.         monitor.write(name:sub(1, 20))
  162.  
  163.         monitor.setCursorPos(w - 10, y)
  164.         monitor.write("x" .. amount)
  165.  
  166.         y = y + 1
  167.     end
  168.  
  169.     drawBlock(1, h, w, h, footerColor)
  170.     drawButton(1, math.floor(w / 2) - 1, "< Prev", pageStorage > 1)
  171.     drawButton(math.floor(w / 2) + 1, w, "Next >", pageStorage < totalPages)
  172.     centerText("Page " .. pageStorage .. "/" .. totalPages, h - 1, textColor, footerColor)
  173. end
  174.  
  175. local function drawPopup()
  176.     if not selectedItem then return end
  177.  
  178.     local winW = math.floor(w * 0.7)
  179.     local winH = math.floor(h * 0.7)
  180.     local startX = math.floor((w - winW) / 2)
  181.     local startY = math.floor((h - winH) / 2)
  182.  
  183.     drawBlock(startX, startY, startX + winW, startY + winH, popupColor)
  184.     monitor.setTextColor(textColor)
  185.  
  186.     monitor.setCursorPos(startX + 2, startY + 1)
  187.     monitor.write("Item: " .. (selectedItem.displayName or "Unknown"))
  188.  
  189.     monitor.setCursorPos(startX + 2, startY + 2)
  190.     monitor.write("Stored: " .. (selectedItem.amount or 0))
  191.  
  192.     monitor.setCursorPos(startX + 2, startY + 3)
  193.     monitor.write("Live Trend:")
  194.  
  195.     -- Tiny Graph
  196.     local graphWidth = winW - 4
  197.     local graphStartX = startX + 2
  198.     local graphStartY = startY + 5
  199.     local graphHeight = 5
  200.  
  201.     local maxVal = 1
  202.     for _, v in ipairs(history) do
  203.         if v > maxVal then maxVal = v end
  204.     end
  205.  
  206.     for i = 1, math.min(graphWidth, #history) do
  207.         local val = history[#history - i + 1] or 0
  208.         local height = math.floor((val / maxVal) * graphHeight)
  209.  
  210.         for j = 0, height - 1 do
  211.             monitor.setCursorPos(graphStartX + graphWidth - i, graphStartY + graphHeight - j)
  212.             monitor.write(".")
  213.         end
  214.     end
  215.  
  216.     monitor.setCursorPos(startX + math.floor(winW / 2) - 3, startY + winH - 1)
  217.     monitor.write("[ Close ]")
  218. end
  219.  
  220. local function handleTouch(x, y)
  221.     x = tonumber(x)
  222.     if not x then return end
  223.  
  224.     if selectedItem then
  225.         selectedItem = nil
  226.         history = {}
  227.         return
  228.     end
  229.  
  230.     local half = math.floor(w / 2)
  231.     if y <= 2 then
  232.         if x <= half then
  233.             activeTab = "crafting"
  234.             pageCrafting = 1
  235.         else
  236.             activeTab = "storage"
  237.             pageStorage = 1
  238.         end
  239.     elseif y == h then
  240.         if activeTab == "crafting" then
  241.             local cpus = me.getCraftingCPUs() or {}
  242.             if x < w / 2 and pageCrafting > 1 then
  243.                 pageCrafting = pageCrafting - 1
  244.             elseif x >= w / 2 and pageCrafting < math.ceil(#cpus / itemsPerPage) then
  245.                 pageCrafting = pageCrafting + 1
  246.             end
  247.         elseif activeTab == "storage" then
  248.             local storage = me.listItems() or {}
  249.             if x < w / 2 and pageStorage > 1 then
  250.                 pageStorage = pageStorage - 1
  251.             elseif x >= w / 2 and pageStorage < math.ceil(#storage / itemsPerPage) then
  252.                 pageStorage = pageStorage + 1
  253.             end
  254.         end
  255.     elseif activeTab == "storage" and y >= 6 and y <= h - 2 then
  256.         local idx = (y - 6) + (pageStorage - 1) * itemsPerPage + 1
  257.         if storageCache[idx] then
  258.             selectedItem = storageCache[idx]
  259.             history = {selectedItem.amount or 0}
  260.         end
  261.     end
  262. end
  263.  
  264. local function updateHistory()
  265.     if selectedItem then
  266.         local fresh = me.getItem({name = selectedItem.name})
  267.         if fresh then
  268.             table.insert(history, fresh.amount or 0)
  269.             if #history > 100 then
  270.                 table.remove(history, 1)
  271.             end
  272.             selectedItem.amount = fresh.amount
  273.         end
  274.     end
  275. end
  276.  
  277. -- MAIN LOOP
  278. parallel.waitForAny(
  279.     function()
  280.         while true do
  281.             blinkState = not blinkState
  282.             if activeTab == "crafting" then
  283.                 drawCraftingTab()
  284.             elseif activeTab == "storage" then
  285.                 drawStorageTab()
  286.             end
  287.             drawPopup()
  288.             sleep(0.5)
  289.             updateHistory()
  290.         end
  291.     end,
  292.     function()
  293.         while true do
  294.             local _, side, x, y = os.pullEvent("monitor_touch")
  295.             handleTouch(x, y)
  296.         end
  297.     end
  298. )
  299.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement