Serious07

IC2 Nuclear Reactor control

Jan 11th, 2021 (edited)
615
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.37 KB | None | 0 0
  1. -- By Serious07 in 2021 y. Twitter @Serious_07 VK: serious07
  2. -- My server is https://gregtechrus.ru
  3.  
  4. -- How to use example: https://imgur.com/a/kdM0ZOT?
  5.  
  6. -- Require:
  7. -- Monitor and GPU tear 2
  8. -- Adapter, Transposer, Redstone controller
  9. -- Container for rods and coolants
  10.  
  11. -- Vars rod rodDeplited cool used to find items for replacement in nuclear reactor
  12. -- Change them if you need to
  13.  
  14. -- Localization
  15. -- Now on Russian you can translate it tou your language
  16. local str_not_enought_free_slots = "  Ошибка в сундуке остутствуют свободные слоты!!!"
  17. local str_not_enought_fuel_rods = "  Ошибка в сундуке недостаточно обогощённых стержней!!!"
  18. local str_reactor_is_active = "  Реактор активен       "
  19. local str_current_step = "  Шаг проверки: "
  20. local str_to_close_program_press_E = "  Для выхода из программы нажимайте клавишу E"
  21. local str_reactor_overheat = "  ПЕРЕГРЕВ РЕАКТОРА!!! Ждём остужения!!!"
  22. local str_rod_replacement = "  Замена стержней!!!"
  23. local str_coolant_replacement = "  Замена охладителей!!!"
  24. local str_replace = "  Заменяем: "
  25. local str_slot_x = "  Слот x: "
  26. local str_program_closed = "  Программа завершена"
  27. local str_reactor_stopped = "  Реактор остановлен"
  28. local str_warning_reactor_is_running = "  ВНИМАНИЕ реактор по прежнему активен !!!"
  29. local str_transposer_not_found = "  Нет транспосера!"
  30. local str_redstone_controller_not_found = "  Нет контроллера красного камня!"
  31. local str_nuclear_reactor_chamber_not_found = "  Камера реактора не найдена, установите Adapter!"
  32. local str_nuclear_reactor_side_not_found = "Реактор не найден! Измените сторону в nuclearSide!"
  33. local str_chest_side_not_found = "Сундук не найден! Измените сторону в containerSide!"
  34. local str_chest_not_enought_space = "Не найдено свободного места в сундуке!"
  35. local str_chest_dont_have_coolant = "Не найден охладитель в сундуке!"
  36. local str_chest_dont_have_rod = "Не найден стержень в сундуке!"
  37.  
  38. local component = require("component")
  39.  
  40. if not component.isAvailable("transposer") then
  41.     print(str_transposer_not_found)
  42.     os.exit()
  43. end
  44. local transposer = component.transposer
  45.  
  46. if not component.isAvailable("redstone") then
  47.     print(str_redstone_controller_not_found)
  48.     os.exit()
  49. end
  50. local red = component.redstone
  51.  
  52. if not component.isAvailable("reactor_chamber") then
  53.     print(str_nuclear_reactor_chamber_not_found)
  54.     os.exit()
  55. end
  56. local reactor = component.reactor_chamber
  57.  
  58. local term = require("term")
  59. local event = require("event")
  60. local colors = require("colors")
  61. local sides = require("sides")
  62. local computer = require("computer")
  63. local keyboard = require("keyboard")
  64.  
  65. local gpu = component.gpu
  66.  
  67. local nuclearSide = sides.south; -- расположение реактора
  68. local containerSide = sides.east; -- расположение контейнера с элементами
  69.  
  70. if not nuclearSide then
  71.     print("\n"..str_nuclear_reactor_side_not_found)
  72.     os.exit()
  73. end
  74. if not containerSide then
  75.     print("\n"..str_chest_side_not_found)
  76.     os.exit()
  77. end
  78.  
  79. local const coolChar = "c" -- обозначение для куланта в реакторе
  80. local const rodChar = "r" -- обозначение для рода в реакторе
  81.  
  82. local rectWidth = 9 -- ширина сетки реактора
  83. local reactHeight = 6 -- высота сетки реактора
  84. local reactorSlotsCount = rectWidth * reactHeight -- общее количество слотов
  85.  
  86. local chestMax = transposer.getInventorySize(containerSide) -- количествослотов сундука
  87.  
  88. local maxDmgCool = 70 -- Условие для замены охлаждающих элементов
  89. local offReac = 6500 --  Температура реактора
  90. local stepsToReplaceCells = 9 -- Условие отображающее количества шагов для замены стержней
  91.  
  92. -- Информация для поиска стержней
  93. local rod = "gregtech:gt.reactorMOXQuad"
  94. local rodDeplited = "IC2:reactorMOXQuaddepleted"
  95. local cool = "gregtech:gt.360k_NaK_Coolantcell"
  96.  
  97. local reactorSlotsList = {"","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""}
  98.  
  99. local firstCheck = true
  100.  
  101. local checksCounter = 0
  102.  
  103. isRunning = true
  104.  
  105. local currentResolution = gpu.getViewport()
  106.  
  107. local function EmmitRedstone(signal)
  108.     for sideRed = 0, 5 do
  109.         red.setOutput(sideRed, signal)
  110.     end
  111. end
  112.  
  113. local function gui()
  114.     term.clear() -- убирает с экрана все символы
  115.     term.setCursor(1,1) -- переносит курсор направо наверх
  116.  
  117.     gpu.setBackground(0x000000)
  118.     gpu.fill(1,1,28,15," ")
  119.     gpu.setForeground(0x669999)
  120.     gpu.set(1,1,"┌──────────────────────────┐")
  121.     gpu.set(1,2,"│  │  │  │  │  │  │  │  │  │")
  122.     gpu.set(1,3,"│──────────────────────────│")
  123.     gpu.set(1,4,"│  │  │  │  │  │  │  │  │  │")
  124.     gpu.set(1,5,"│──────────────────────────│")
  125.     gpu.set(1,6,"│  │  │  │  │  │  │  │  │  │")
  126.     gpu.set(1,7,"│──────────────────────────│")
  127.     gpu.set(1,8,"│  │  │  │  │  │  │  │  │  │")
  128.     gpu.set(1,9,"│──────────────────────────│")
  129.     gpu.set(1,10,"│  │  │  │  │  │  │  │  │  │")
  130.     gpu.set(1,11,"│──────────────────────────│")
  131.     gpu.set(1,12,"│  │  │  │  │  │  │  │  │  │")
  132.     gpu.set(1,13,"└──────────────────────────┘")
  133. end
  134.  
  135. function getGUIX(x)
  136.     return 2 + (3 * (x - 1))
  137. end
  138.  
  139. function getGUIY(y)
  140.     return 2 + (2 * (y - 1))
  141. end
  142.  
  143. local function stop()
  144.     EmmitRedstone(0)
  145.  
  146.     term.clear() -- убирает с экрана все символы
  147.     term.setCursor(1,1) -- переносит курсор направо наверх
  148.  
  149.     gpu.setBackground(0x000000)
  150.     gpu.setForeground(0xFFFFFF)
  151.     print("\n"..str_program_closed)
  152.     os.sleep(1)
  153.     if reactor.producesEnergy() then
  154.         print(str_warning_reactor_is_running)
  155.     else
  156.         print(str_reactor_stopped)
  157.     end
  158.  
  159.     if tMain ~= nil then tMain:kill() end
  160.     if tInterrapt ~= nil then tInterrapt:kill() end
  161.     if tKeyEvent ~= nil then tKeyEvent:kill() end
  162.  
  163.     term.setCursor(1,1) -- переносит курсор направо наверх
  164.     isRunning = false
  165.     os.exit()
  166. end
  167.    
  168. local function alert(message)
  169.     gpu.setForeground(0xFF0000)
  170.     gpu.set(1,15,message)
  171.     computer.beep(500, 1)
  172.     local e = {event.pull(0.03,"key_down")}
  173.     if e[4] == 18 or e[4] == 20 then
  174.         stop()
  175.     end
  176. end
  177.  
  178. local function clearAlert()
  179.     gpu.set(1,14,"                                ")
  180.     gpu.set(1,15,"                                ")
  181. end
  182.  
  183. -- Функция возвращающая X координату из простого числа
  184. function getReactorXSlot(simpleNumber)
  185.     return (simpleNumber % rectWidth)
  186. end
  187. -- Функция возвращающая Y координату из простого числа
  188. function getReactorYSlot(simpleNumber)
  189.     return math.floor(simpleNumber / rectWidth) + 1
  190. end
  191. -- Функция возвращает одномерную позицию слота в сетке слотов
  192. function getReactorSimpleSlotNumber(x, y)
  193.     rowCoords = (y - 1);
  194.  
  195.     return (rowCoords * rectWidth) + x;
  196. end
  197.  
  198. function dump(o)
  199.     if type(o) == 'table' then
  200.        local s = '{ '
  201.        for k,v in pairs(o) do
  202.           if type(k) ~= 'number' then k = '"'..k..'"' end
  203.           s = s .. '['..k..'] = ' .. dump(v) .. ','
  204.        end
  205.        return s .. '} '
  206.     else
  207.        return tostring(o)
  208.     end
  209.  end
  210.  
  211. function findFreeChestSlot()
  212.     for i = 1, chestMax do
  213.         local stack = transposer.getStackInSlot(containerSide, i)
  214.  
  215.         if stack == nil then
  216.             return i
  217.         end
  218.  
  219.         local e = {event.pull(0.03,"key_down")}
  220.         if e[4] == 18 or e[4] == 20 then
  221.             stop()
  222.         end
  223.     end
  224.  
  225.     return -1
  226. end
  227.  
  228. function findNewCool()
  229.     for i = 1, chestMax do
  230.         local stack = transposer.getStackInSlot(containerSide, i)
  231.  
  232.         if stack ~= nil then
  233.             if stack.name == cool and stack.damage == 0 then
  234.                 return i
  235.             end
  236.         end
  237.  
  238.         local e = {event.pull(0.03,"key_down")}
  239.         if e[4] == 18 or e[4] == 20 then
  240.             stop()
  241.         end
  242.     end
  243.  
  244.     return -1
  245. end
  246.  
  247. function findNewRod()
  248.     for i = 1, chestMax do
  249.         local stack = transposer.getStackInSlot(containerSide, i)
  250.  
  251.         if stack ~= nil then
  252.             if stack.name == rod then
  253.                 return i
  254.             end
  255.         end
  256.  
  257.         local e = {event.pull(0.03,"key_down")}
  258.         if e[4] == 18 or e[4] == 20 then
  259.             stop()
  260.         end
  261.     end
  262.  
  263.     return -1
  264. end
  265.  
  266. function updateGUIInCheckProcess(x, y, stack)
  267.     gpu.set(getGUIX(x), getGUIY(y), "██")
  268.     gpu.setForeground(0xFF9900)
  269.     gpu.set(1,17,"                                         ")
  270.     gpu.set(1,18,"                                         ")
  271.     gpu.set(1,17,str_slot_x..x.." y: "..y)
  272.     gpu.set(1,18,str_replace..stack.name)
  273. end
  274.  
  275. function replaceCoolant(slotNumber, freeChestSlot, newCoolSlot)
  276.     local fcs = freeChestSlot
  277.     local ncl = newCoolSlot
  278.  
  279.     if fcs == -1 then
  280.         alert(str_chest_not_enought_space)
  281.         -- Убрать редстоун сигнал
  282.         EmmitRedstone(0)
  283.  
  284.         while fcs == -1 do
  285.             fcs = findFreeChestSlot()
  286.             os.sleep(0.5)
  287.         end
  288.     elseif ncl == -1 then
  289.         alert(str_chest_dont_have_coolant)
  290.         -- Убрать редстоун сигнал
  291.         EmmitRedstone(0)
  292.  
  293.         while ncl == -1 do
  294.             ncl = findNewCool()
  295.             os.sleep(0.5)
  296.         end
  297.  
  298.         fcs = findFreeChestSlot()
  299.  
  300.         if fcs == -1 then
  301.             alert(str_chest_not_enought_space)
  302.             -- Убрать редстоун сигнал
  303.             EmmitRedstone(0)
  304.    
  305.             while fcs == -1 do
  306.                 fcs = findFreeChestSlot()
  307.                 os.sleep(0.5)
  308.             end
  309.         end
  310.     end
  311.  
  312.     -- Вынуть охладитель переложить в сундук
  313.     repeat until transposer.transferItem(nuclearSide, containerSide, 1, slotNumber, fcs)
  314.     -- Из сундука достать первый целый охладитель и поместить в реактор
  315.     repeat until transposer.transferItem(containerSide, nuclearSide, 1, ncl, slotNumber)
  316. end
  317.  
  318. function replaceRod(slotNumber, freeChestSlot, newRodSlot)
  319.     local fcs = freeChestSlot
  320.     local nrs = newRodSlot
  321.  
  322.     if fcs == -1 then
  323.         alert(str_chest_not_enought_space)
  324.         -- Убрать редстоун сигнал
  325.         EmmitRedstone(0)
  326.  
  327.         while fcs == -1 do
  328.             fcs = findFreeChestSlot()
  329.             os.sleep(0.5)
  330.         end
  331.     elseif nrs == -1 then
  332.         alert(str_chest_dont_have_rod)
  333.         -- Убрать редстоун сигнал
  334.         EmmitRedstone(0)
  335.  
  336.         while nrs == -1 do
  337.             nrs = findNewRod()
  338.             os.sleep(0.5)
  339.         end
  340.  
  341.         fcs = findFreeChestSlot()
  342.  
  343.         if fcs == -1 then
  344.             alert(str_chest_not_enought_space)
  345.             -- Убрать редстоун сигнал
  346.             EmmitRedstone(0)
  347.    
  348.             while fcs == -1 do
  349.                 fcs = findFreeChestSlot()
  350.                 os.sleep(0.5)
  351.             end
  352.         end
  353.     end
  354.  
  355.     -- Вынуть стержень переложить в сундук
  356.     repeat until transposer.transferItem(nuclearSide, containerSide, 1, slotNumber, fcs)
  357.     -- Из сундука достать первый целый стержень и поместить в реактор
  358.     repeat until transposer.transferItem(containerSide, nuclearSide, 1, nrs, slotNumber)
  359. end
  360.  
  361. function checkCoolants()
  362.     local needEmmit = false
  363.  
  364.     for x = 1, rectWidth do
  365.         for y = 1, reactHeight do
  366.             local slotNumber = getReactorSimpleSlotNumber(x, y)
  367.  
  368.             if reactorSlotsList[slotNumber] == coolChar then
  369.                 local stack = transposer.getStackInSlot(nuclearSide, slotNumber)
  370.  
  371.                 if stack ~= nil then
  372.                     if stack.name == cool and stack.damage >= maxDmgCool then
  373.                         if freeChestSlot ~= -1 and newCoolSlot ~= -1 then
  374.                             local freeChestSlot = findFreeChestSlot()
  375.                             local newCoolSlot = findNewCool()
  376.                             alert(str_coolant_replacement)
  377.                             -- Убрать редстоун сигнал
  378.                             EmmitRedstone(0)
  379.                             needEmmit = true
  380.                             -- Обновить GUI
  381.                             updateGUIInCheckProcess(x, y, stack)
  382.                             -- Замена охладителя
  383.                             replaceCoolant(slotNumber, freeChestSlot, newCoolSlot)
  384.                             clearAlert()
  385.                         elseif freeChestSlot == -1 then
  386.                             print(str_not_enought_free_slots)
  387.                         elseif newCoolSlot == -1 then
  388.                             print(str_not_enought_fuel_rods)
  389.                         end
  390.                     end
  391.                 end
  392.             end
  393.  
  394.             local e = {event.pull(0.03,"key_down")}
  395.             if e[4] == 18 or e[4] == 20 then
  396.                 break
  397.                 stop()
  398.             end
  399.         end
  400.     end
  401.  
  402.     if needEmmit then
  403.         -- Подать редстоун сигнал
  404.         EmmitRedstone(15)
  405.     end
  406.  
  407.     updateGUI()
  408. end
  409.  
  410. function checkRoads()
  411.     local needEmmit = false
  412.  
  413.     for x = 1, rectWidth do
  414.         for y = 1, reactHeight do
  415.             local slotNumber = getReactorSimpleSlotNumber(x, y)
  416.  
  417.             if reactorSlotsList[slotNumber] == rodChar then
  418.                 local stack = transposer.getStackInSlot(nuclearSide, slotNumber)
  419.    
  420.                 if stack ~= nil and stack.name == rodDeplited then
  421.                     if freeChestSlot ~= -1 and newRodSlot ~= -1 then
  422.                         local freeChestSlot = findFreeChestSlot()
  423.                         local newRodSlot = findNewRod()
  424.                         alert(str_rod_replacement)
  425.                         -- Убрать редстоун сигнал
  426.                         needEmmit = true
  427.                         EmmitRedstone(0)
  428.                         -- Обновить GUI
  429.                         updateGUIInCheckProcess(x, y, stack)
  430.                         -- Замена стержня
  431.                         replaceRod(slotNumber, freeChestSlot, newRodSlot)
  432.                         clearAlert()
  433.                     elseif freeChestSlot == -1 then
  434.                         print(str_not_enought_free_slots)
  435.                     elseif newRodSlot == -1 then
  436.                         print(str_not_enought_fuel_rods)
  437.                     end
  438.                 end
  439.             end
  440.  
  441.             local e = {event.pull(0.03,"key_down")}
  442.             if e[4] == 18 or e[4] == 20 then
  443.                 break
  444.                 stop()
  445.             end
  446.         end
  447.     end
  448.  
  449.     if needEmmit then
  450.         -- Подать редстоун сигнал
  451.         EmmitRedstone(15)
  452.     end
  453.  
  454.     updateGUI()
  455. end
  456.  
  457. function checkReactor()
  458.     local needEmmit = false
  459.  
  460.     for x = 1, rectWidth do
  461.         for y = 1, reactHeight do
  462.             local slotNumber = getReactorSimpleSlotNumber(x, y)
  463.             local stack = transposer.getStackInSlot(nuclearSide, slotNumber)
  464.  
  465.             if stack ~= nil then
  466.                 if stack.name == cool then
  467.                     if firstCheck == true then
  468.                         reactorSlotsList[slotNumber] = coolChar
  469.                     end
  470.                     if freeChestSlot ~= -1 and newCoolSlot ~= -1 and stack.damage >= maxDmgCool then
  471.                         local freeChestSlot = findFreeChestSlot()
  472.                         local newCoolSlot = findNewCool()
  473.  
  474.                         alert(str_coolant_replacement)
  475.                         -- Убрать редстоун сигнал
  476.                         EmmitRedstone(0)
  477.                         needEmmit = true
  478.                         -- Обновить GUI
  479.                         gpu.set(getGUIX(x), getGUIY(y), "██")
  480.                         -- Замена охладителя
  481.                         replaceCoolant(slotNumber, freeChestSlot, newCoolSlot)
  482.                         clearAlert()
  483.                     elseif freeChestSlot == -1 then
  484.                         print(str_not_enought_free_slots)
  485.                     elseif newCoolSlot == -1 then
  486.                         print(str_not_enought_fuel_rods)
  487.                     end
  488.                 elseif stack.name == rodDeplited then
  489.                     if firstCheck == true then
  490.                         reactorSlotsList[slotNumber] = rodChar
  491.                     end
  492.                     if freeChestSlot ~= -1 and newRodSlot ~= -1 then
  493.                         local freeChestSlot = findFreeChestSlot()
  494.                         local newRodSlot = findNewRod()
  495.  
  496.                         alert(str_rod_replacement)
  497.                         -- Убрать редстоун сигнал
  498.                         EmmitRedstone(0)
  499.                         needEmmit = true
  500.                         -- Обновить GUI
  501.                         gpu.set(getGUIX(x), getGUIY(y), "██")
  502.                         -- Замена стержня
  503.                         replaceRod(slotNumber, freeChestSlot, newRodSlot)
  504.                         clearAlert()
  505.                     elseif freeChestSlot == -1 then
  506.                         print(str_not_enought_free_slots)
  507.                     elseif newRodSlot == -1 then
  508.                         print(str_not_enought_fuel_rods)
  509.                     end
  510.                 elseif stack.name == rod then
  511.                     if firstCheck == true then
  512.                         reactorSlotsList[slotNumber] = rodChar
  513.                     end
  514.                 end
  515.             end
  516.  
  517.             local e = {event.pull(0.03,"key_down")}
  518.             if e[4] == 18 or e[4] == 20 then
  519.                 break
  520.                 stop()
  521.             end
  522.         end
  523.     end
  524.  
  525.     if needEmmit then
  526.         -- Подать редстоун сигнал
  527.         EmmitRedstone(15)
  528.     end
  529.  
  530.     updateGUI()
  531.  
  532.     firstCheck = false
  533. end
  534.  
  535. function updateGUI()
  536.     gpu.setForeground(0x23b825)
  537.  
  538.     for x = 1, rectWidth do
  539.         for y = 1, reactHeight do
  540.             local slotNumber = getReactorSimpleSlotNumber(x, y)
  541.             local stack = transposer.getStackInSlot(nuclearSide, slotNumber)
  542.  
  543.             if stack ~= nil then
  544.                 -- Обновить GUI
  545.                 if stack.damage < 100 then
  546.                     if stack.name == cool then
  547.                         gpu.setForeground(0x124be6)
  548.                     elseif stack.name == rod then
  549.                         gpu.setForeground(0x22bf2a)
  550.                     end
  551.                    
  552.                     local dur = tostring(math.floor(stack.damage))
  553.  
  554.                     if string.len(dur) == 1 then
  555.                         dur = "0"..dur
  556.                     end
  557.  
  558.                     gpu.set(getGUIX(x), getGUIY(y), dur)
  559.                 end
  560.             end
  561.         end
  562.     end
  563.  
  564.     OutputEUt = math.ceil(reactor.getReactorEUOutput())
  565.     gpu.setForeground(0x00FF00)
  566.     gpu.set(1,14, "  Eu/t =  "..OutputEUt.."            ")
  567.     gpu.set(1,15, str_reactor_is_active)
  568.     gpu.set(1,16, "                                                ")
  569.     gpu.set(1,16, str_current_step..checksCounter)
  570.     gpu.set(1,17, "                                                ")
  571.     gpu.set(1,18, "                                                ")
  572.     gpu.set(1,19, str_to_close_program_press_E)
  573. end
  574.  
  575. EmmitRedstone(0)
  576.  
  577.  
  578.  
  579. gui()
  580.  
  581. if firstCheck == true then
  582.     checkReactor()
  583.     EmmitRedstone(15)
  584. end
  585.  
  586. -- Цикл программы
  587. while isRunning do
  588.     local e = {event.pull(0.03,"key_down")}
  589.     if e[4] == 18 or e[4] == 20 then
  590.         stop()
  591.     else
  592.         if reactor.getHeat() > offReac then
  593.             alert(str_reactor_overheat)
  594.             EmmitRedstone(0)
  595.             os.sleep(1)
  596.         else
  597.             EmmitRedstone(15)
  598.             checkCoolants()
  599.             if checksCounter == stepsToReplaceCells then
  600.                 checkRoads()
  601.                 checksCounter = 0
  602.             end
  603.  
  604.             checksCounter = checksCounter + 1
  605.             os.sleep(0.03)
  606.         end
  607.     end
  608. end
Add Comment
Please, Sign In to add comment