Advertisement
Clor

Energy, Machines and Fluid ME control by NewFragment

Dec 20th, 2024
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.70 KB | Gaming | 0 0
  1. comp = require("component")
  2. screen = require("term")
  3. computer = require("computer")
  4. event = require("event")
  5. GPU1 = comp.gpu
  6. sides = require("sides")
  7. rs = comp.redstone
  8. me_interface = comp.me_interface
  9. gtBattBuf = comp.gt_batterybuffer
  10. gtMachine = comp.gt_machine
  11. --Конфиг
  12. screenWidth = 160
  13. screenHeight = 50
  14. borderColor = 0x1A1A1A
  15. backgroundColor = 0x0D0D0D
  16. progressBarColor = 0x00CC00
  17. errorColor = 0xCC0000
  18. workingColor = 0x00FF00
  19. idleColor = 0xFFFF00
  20. textColor = 0xFFFFFF
  21. maxEUColor = 0xFFE800
  22. currentEUColor = 0x2592E7
  23. positiveEUColor = 0x00CC00
  24. negativeEUColor = 0xCC0000
  25. euUpdateInterval = 3
  26.  
  27. GPU1.setResolution(screenWidth, screenHeight)
  28. firstRead, lastRead, counter, currentIO = 0, 0, 1, 1
  29. machines = {}
  30. fluidNames = {}
  31. fluids = {}
  32.  
  33. --=========== Утилиты
  34.  
  35. -- Формат: Час Минута Секунда
  36. function time(number)
  37.     local formattedTime = {}
  38.     formattedTime[1] = math.floor(number / 3600); formattedTime[2] = "h "
  39.     formattedTime[3] = math.floor((number - formattedTime[1] * 3600) / 60); formattedTime[4] = "min "
  40.     formattedTime[5] = number % 60; formattedTime[6] = "s"
  41.     return table.concat(formattedTime, "")
  42. end
  43.  
  44. -- Формат чисел XXX,XXX,XXX
  45. function splitNumber(number)
  46.     local formattedNumber = {}
  47.     local string = tostring(math.abs(number))
  48.     local sign = number / math.abs(number)
  49.     for i = 1, #string do
  50.         n = string:sub(i, i)
  51.         formattedNumber[i] = n
  52.         if ((#string - i) % 3 == 0) and (#string - i > 0) then
  53.             formattedNumber[i] = formattedNumber[i] .. ","
  54.         end
  55.     end
  56.     if (sign < 0) then table.insert(formattedNumber, 1, "-")
  57.     end
  58.     return table.concat(formattedNumber, "")
  59. end
  60.  
  61. -- Формат: процентраж (%)
  62. function getPercent(number)
  63.     percent = {}
  64.     percent[1] = math.floor(number * 1000) / 10
  65.     percent[2] = "%"
  66.     return table.concat(percent, " ")
  67. end
  68.  
  69. -- Прогресс текст
  70. function progressText(current, max)
  71.     formattedProgress = {}
  72.     formattedProgress[1] = current
  73.     formattedProgress[2] = max
  74.     return table.concat(formattedProgress, "/")
  75. end
  76.  
  77. -- Вывод боксов
  78. function box(x, y, w, h, color)
  79.     local oldColor = GPU1.setBackground(color)
  80.     GPU1.fill(x, y, w, h, " ")
  81.     GPU1.setBackground(oldColor)
  82. end
  83.  
  84. -- Вывод текста
  85. function write(x, y, text, color)
  86.     color = color or textColor
  87.     screen.setCursor(x, y)
  88.     oldColor = GPU1.setForeground(color)
  89.     screen.write(text)
  90.     GPU1.setForeground(oldColor)
  91. end
  92.  
  93. -- Регистрация Мультиблоков
  94. function gtMachine(x, y, address, label)
  95.     machine = comp.proxy(comp.get(address))
  96.  
  97.     maintenanceIndex = 0
  98.     if machines[label] == nil then
  99.         machines[label] = machine
  100.         box(x, y, 4, 3, borderColor)
  101.         box(x + 4, y, 19, 3, backgroundColor)
  102.         write(x + 5, y, label, textColor)
  103.     end
  104.  
  105.     box(x + 4, y + 1, 19, 2, backgroundColor)
  106.     box(x + 5 + #label, y, 23 - #label - 5, 1, backgroundColor)
  107.     for i = 1, #machine.getSensorInformation() do
  108.         if string.match(machine.getSensorInformation()[i], "Problems") then
  109.             maintenanceIndex = i + 1
  110.         end
  111.     end
  112.     if (machine.hasWork()) then
  113.         GPU1.setBackground(backgroundColor)
  114.         box(x + 1, y + 1, 2, 1, workingColor)
  115.         box(x + 5, y + 1, math.floor(18 * (machine.getWorkProgress() / machine.getWorkMaxProgress())), 1, progressBarColor)
  116.         local progressString = progressText(math.floor(machine.getWorkProgress() / 20), math.floor(machine.getWorkMaxProgress() / 20)) .. "s"
  117.         write(x + 23 - #progressString, y, progressString)
  118.     else
  119.         box(x + 1, y + 1, 2, 1, idleColor)
  120.     end
  121.     GPU1.setBackground(backgroundColor)
  122.     if (maintenanceIndex == 0 or string.match(machine.getSensorInformation()[maintenanceIndex], "0")) and machine.isWorkAllowed() then
  123.         --Do nothing
  124.     else
  125.         if (machine.isWorkAllowed()) then
  126.             box(x + 1, y + 1, 2, 1, idleColor)
  127.             write(x + 5, y + 2, "Needs maintenance!", errorColor)
  128.         else
  129.             box(x + 1, y + 1, 2, 1, errorColor)
  130.             write(x + 5, y + 2, "Machine disabled!", errorColor)
  131.         end
  132.     end
  133. end
  134.  
  135. --Регистрация БатБуферов
  136. function substation(x, y, width, heigth)
  137.     width = width or screenWidth - 2 * x; heigth = heigth or 4
  138.     GPU1.setBackground(0x000000)
  139.     local currentEU = 0
  140.     local maxEU = 0
  141.     local avgInput = 0
  142.     local avgOutput = 0
  143.     currentIO = 0
  144.     for adress, name in comp.list("gt_batterybuffer", true) do
  145.             current_buffer = comp.proxy(adress)
  146.             currentEU = currentEU + string.gsub(current_buffer.getSensorInformation()[3], "([^0-9]+)", "")
  147.             maxEU = maxEU + string.gsub(current_buffer.getSensorInformation()[4], "([^0-9]+)", "")
  148.             avgInput = avgInput + current_buffer.getAverageElectricInput()
  149.             avgOutput = avgOutput + current_buffer.getAverageElectricOutput()
  150.             currentIO = currentIO + current_buffer.getAverageElectricInput() - current_buffer.getAverageElectricOutput()
  151.     end
  152.     local progress = (width - 2) * (currentEU / maxEU)
  153.     box(x, y, width, heigth, borderColor)
  154.     box(x + 1 + progress, y + 1, width - 1 - progress, heigth - 2, backgroundColor)
  155.     box(x + 1, y + 1, progress, heigth - 2, progressBarColor)
  156.     write(x, y - 1, splitNumber(tonumber(string.format("%.0f", currentEU))), currentEUColor); screen.write(" EU")
  157.     write(x + width - #splitNumber(maxEU), y - 1, splitNumber(tonumber(string.format("%.0f", maxEU))), maxEUColor); screen.write(" EU")
  158.     box(x + width / 2 - 3, y - 1, 8, 1, 0x000000)
  159.     local percentString = getPercent(progress / (width - 2))
  160.     write(x + width / 2 - #percentString / 2, y - 1, percentString)
  161.     box(x, y + heigth, width, 1, 0x000000)
  162.     if currentIO >= 0 then
  163.         write(x + width / 2 - #tostring(currentIO) / 2 - 2, y + heigth, splitNumber(tonumber(string.format("%.0f", currentIO))), positiveEUColor); screen.write(" EU/t")
  164.     else
  165.         write(x + width / 2 - #tostring(currentIO) / 2 - 2, y + heigth, splitNumber(tonumber(string.format("%.0f", currentIO))), negativeEUColor); screen.write(" EU/t")
  166.     end
  167.     write(x + 18, y + heigth, splitNumber(tonumber(string.format("%.0f", avgInput))), positiveEUColor); screen.write(" EU/t")
  168.     write(x, y + heigth, "Total Generation:");
  169.     write(x, y + heigth + 1, "Total Cost:");
  170.     write(x + 12, y + heigth + 1, splitNumber(tonumber(string.format("%.0f", avgOutput))), negativeEUColor); screen.write(" EU/t")
  171.     if currentIO > 0 then
  172.         fillTime = math.floor((maxEU - currentEU) / (currentIO * 20))
  173.         fillTimeString = time(math.abs(fillTime))
  174.         write(x + width - #fillTimeString - 6, y + heigth, "Full: " .. fillTimeString)
  175.     elseif currentIO == 0 then
  176.         if currentEU == maxEU then
  177.             write(x + width - 13, y + heigth, "Stable charge")
  178.         else
  179.             write(x + width - 11, y + heigth, "Need charge")
  180.         end
  181.     else
  182.         fillTime = math.floor((currentEU) / (currentIO * 20))
  183.         fillTimeString = time(math.abs(fillTime))
  184.         write(x + width - #fillTimeString - 7, y + heigth, "Empty: " .. fillTimeString)
  185.     end
  186.     if currentEU / maxEU <= 0.08 then
  187.         rs.setOutput(0, 15)
  188.         rs.setOutput(1, 15)
  189.         rs.setOutput(2, 15)
  190.         rs.setOutput(3, 15)
  191.         rs.setOutput(4, 15)
  192.         rs.setOutput(5, 15)
  193.     else if currentEU / maxEU >= 0.98 then
  194.         rs.setOutput(0, 0)
  195.         rs.setOutput(1, 0)
  196.         rs.setOutput(2, 0)
  197.         rs.setOutput(3, 0)
  198.         rs.setOutput(4, 0)
  199.         rs.setOutput(5, 0)
  200.     end
  201.     end
  202.     if rs.getOutput(0) == 0 then
  203.         box(x, y + heigth - 10, 2, 1, 0xff0000)
  204.         GPU1.set(x + 4, y + heigth - 10, "Energy Generation Disable")
  205.     else
  206.         box(x, y + heigth - 10, 2, 1, 0x00ff00)
  207.         GPU1.set(x + 4, y + heigth - 10, "Energy Generation Enable ")
  208.     end
  209. end
  210.  
  211. local fluidList = me_interface.getFluidsInNetwork()
  212. function fluidslistUpdate()
  213.     fluidList = me_interface.getFluidsInNetwork()
  214. end
  215.  
  216. -- Регистрация жидкостей
  217. function fluid(nameOnMonitor, name, color, max, x, y)
  218.     local amountFLuid
  219.     local amount
  220.     local abort = true
  221.     for number, fluid in ipairs(fluidList) do
  222.         if fluid.name == name then
  223.             label = fluid.label
  224.             amountFLuid = tonumber(fluid.amount)
  225.             abort = false
  226.             break
  227.         end
  228.     end
  229.     if abort then return end -- Пропустить если нету жижи
  230.  
  231.     amount = math.floor(amountFLuid / 1000)
  232.     local width = 21
  233.     old = GPU1.setBackground(borderColor)
  234.     if (fluidNames[name] == nil) then
  235.         fluidNames[name] = 1
  236.         box(x, y, width + 2, 3, borderColor)
  237.         write(x + 1, y, nameOnMonitor, color)
  238.         write(x + 16, y + 2, "L/1000", color)
  239.     else
  240.     end
  241.     local progress = 0
  242.     if (amount / max > 0.5) then
  243.         progress = math.min(math.ceil((amount / max) * width), width)
  244.     else
  245.         progress = math.min(math.floor((amount / max) * width), width)
  246.     end
  247.     local fillString = tostring(amount) .. "/" .. tostring(max)
  248.     GPU1.setBackground(color)
  249.     if (#fillString <= progress) then
  250.         write(x + 1, y + 1, fillString, backgroundColor)
  251.         box(x + 1 + #fillString, y + 1, progress - #fillString, 1, color)
  252.         box(x + 1 + progress, y + 1, width - progress, 1, backgroundColor)
  253.     else
  254.         write(x + 1, y + 1, fillString:sub(1, progress), backgroundColor)
  255.         GPU1.setBackground(backgroundColor)
  256.         write(x + 1 + progress, y + 1, fillString:sub(progress + 1, #fillString), color)
  257.         box(x + 1 + #fillString, y + 1, width - #fillString, 1, backgroundColor)
  258.     end
  259.     GPU1.setBackground(old)
  260. end
  261.  
  262. function offProgram(x)
  263.     write(screenWidth-15, 1, "Off - Ctrl+C", 0x858585)
  264.     write(screenWidth-15, 1, "Off - Ctrl+C", 0x858585)
  265.     x = x + 1
  266.     if (x % 2 == 0) then
  267.         box(screenWidth-2, 1, 2, 1, 0x858585)
  268.     else
  269.         box(screenWidth-2, 1, 2, 1, 0xffffff)
  270.     end
  271.  
  272. end
  273.  
  274. screen.clear()
  275. step = 1
  276. --[[=================================================================================================================
  277.  
  278.     ДОБАВЛЕНИЕ СВОИХ КОМПОНЕНТОВ
  279.  
  280.     Критерии для работы:
  281.     1) Комп тир 3
  282.     2) Мониторы тир 3
  283.     3) GPU тир 3
  284.     4) CPU тир 3
  285.  
  286. ]]
  287.  
  288. while (true) do
  289.  
  290.     --[[=================================================================================================================
  291.  
  292.     Многоблоки
  293.     Как работает отображение машин? Вы подключаетесь адаптером (или адаптером с MFU, если к контролеру нельзя напрямую подключится)
  294.     к контролеру, задаете адресс адаптера в регистрацию и комп выводит инфу
  295.  
  296.  
  297.     Как правильно зарегать машины:
  298.     gtMachine(Координата X, Координата Y, Адресс Адаптера (или Адаптера с MFU), Название для вывода)
  299.  
  300.     Важно! Расположение бокса по координатам между машин должно быть минимум 4 по координате Y
  301.  
  302.     ]]
  303.  
  304.  
  305.     --gtMachine(3, 8, "71e26", "Пример1")
  306.     --gtMachine(1, 8, "9645a", "Пример2")
  307.  
  308.     --[[=================================================================================================================
  309.     Батбуфер
  310.     Как работает отображение батбуфера? Вы подключаетесь адаптером к любому батбуферу, комп ищет в сети батбуфер и выдает всю информацию
  311.     Обязательно нужно для подключения Redstone Port (RS Port) из OC, сигнал силой 15 выдается во все стороны
  312.  
  313.     Как правильно зарегать буфер:
  314.     substation(Координата X, Координата Y, Ширина(x = растянуть по всей ширине), Высота бара)
  315.    
  316.     upd: добавил возможность считывать несколько батбуферов, ничего не нужно делать и регистрировать, только подключить второй
  317.     батбуфер к адаптеру компьютера, после этого, его ёмкость, заряд и средние IO будут добавлены к основному заряду на инфопанельке
  318.     ]]
  319.     substation(31, 40, 100, 6)
  320.  
  321.     --[[=================================================================================================================
  322.     Жижи
  323.  
  324.     Как работает отображение жидкостей? Вы подключаетесь адаптером к обычному интерфейсу (не жидкостному!), комп сканирует
  325.     жидкости в МЕ, далее жидкость которую вы указали, он выведет на экран, если такой жидоксти нет, то ничего не выведет
  326.  
  327.     Как правильно зарегать жидкость:
  328.     fluid(Любое ваше название (выводится на мониторе), Название жидкости (смотреть по универсальной капсуле), Цвет по HEX, Максимальный размер(не ограничен, но я указываю обычно 256 ведер, чтобы были для вида), Координата X, Координата Y)
  329.  
  330.     Размеры бокса 21x3
  331.  
  332.     ]]
  333.     fluidslistUpdate()
  334.     --Примеры
  335.     --fluid("Argon", "argon", 0x7c21cc, 30000, screenWidth - 25, 4)
  336.     --fluid("Helium-3", "helium-3", 0xfbff00, 1000000, screenWidth - 25, 8)
  337.     --fluid("Hydrogen", "hydrogen", 0x2445ed, 6500, screenWidth - 25, 12)
  338.     --fluid("Oxygen", "oxygen", 0x3de5ff, 6500, screenWidth - 25, 16)
  339.     --fluid("Rocket_fuel", "rocket_fuel", 0x7d5c36, 10000, screenWidth - 25, 20)
  340.     --fluid("Sulfuric acid", "sulfuricacid", 0xffa024, 10000, screenWidth - 25, 24)
  341.     --fluid("Water", "water", 0x2196cc, 1602, screenWidth - 25, 28)
  342.     --fluid("Radon", "radon", 0xdd00ff, 1000, screenWidth - 50, 4)
  343.     --fluid("Oxygen plasma", "plasma.oxygen", 0x0afcec, 100000, screenWidth - 50, 8)
  344.  
  345.     offProgram(step)
  346.     step = step + 1
  347.     -- Выключить программу ctrl+c
  348.     os.sleep(0.1)
  349.     if event.pull(.5, "interrupted") then
  350.         screen.clear()
  351.         break
  352.     end
  353. end
Tags: IIA
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement