PICCIONENBERG

Reattore Nuovo

Nov 12th, 2025
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 20.69 KB | Gaming | 0 0
  1. -- ============================================================================
  2. -- CONTROLLO REATTORE IC2 CON LOGICA GATE INTEGRATA
  3. -- ============================================================================
  4. -- Questo programma gestisce automaticamente il reattore IC2 per l'arricchimento
  5. -- del materiale, con logica di controllo integrata che sostituisce i gate hardware.
  6. --
  7. -- LOGICA GATE INTEGRATA (non servono più gate fisici):
  8. -- - RS Latch: Gestisce la commutazione tra modalità normale e rifornimento
  9. --   con isteresi per evitare oscillazioni (soglie: 10s per Set, 15s per Reset)
  10. -- - XNOR: Garantisce che arancione e bianco non siano mai attivi contemporaneamente
  11. --
  12. -- COLORI BUNDLED REDSTONE:
  13. -- - Arancione (2): Modalità normale - Input/output materiale da arricchire ATTIVI
  14. -- - Bianco (1): Modalità rifornimento - Input/output cellule uranio ATTIVI
  15. -- - Nessuno (0): Sistema fermo/errore
  16. -- ============================================================================
  17.  
  18. -- Funzione per verificare che il peripheral sia valido
  19. function getPeripheral()
  20.     local success, s = pcall(function()
  21.         return peripheral.wrap("bottom")
  22.     end)
  23.     if not success or not s then
  24.         return nil, "Peripheral non disponibile"
  25.     end
  26.     return s, nil
  27. end
  28.  
  29. -- Funzione per ottenere il monitor (prova più lati)
  30. function getMonitor()
  31.     local sides = {"top", "left", "right", "front", "back"}
  32.     for _, side in ipairs(sides) do
  33.         local success, monitor = pcall(function()
  34.             local m = peripheral.wrap(side)
  35.             if m and m.setCursorPos then
  36.                 return m, side
  37.             end
  38.             return nil, nil
  39.         end)
  40.         if success and monitor then
  41.             return monitor, side, nil
  42.         end
  43.     end
  44.     return nil, nil, "Monitor non trovato"
  45. end
  46.  
  47. -- Funzione per aggiornare il monitor con i dati del reattore
  48. function updateMonitor(monitor, uuid, state, title, tab, isRefueling, errorMsg)
  49.     if not monitor then
  50.         return false
  51.     end
  52.    
  53.     local success, err = pcall(function()
  54.         -- Ottieni dimensioni del monitor
  55.         local width, height = monitor.getSize()
  56.         if not width or not height then
  57.             -- Fallback se getSize non disponibile
  58.             width, height = 26, 9
  59.         end
  60.        
  61.         -- Configura il monitor
  62.         monitor.setTextScale(0.5) -- Testo più piccolo per monitor 2x3
  63.         monitor.clear()
  64.         monitor.setCursorPos(1, 1)
  65.        
  66.         -- Header
  67.         monitor.setTextColor(colors.white)
  68.         local header = "=== REATTORE IC2 ==="
  69.         if string.len(header) > width then
  70.             header = string.sub(header, 1, width)
  71.         end
  72.         monitor.write(header)
  73.         monitor.setCursorPos(1, 2)
  74.         monitor.setTextColor(colors.gray)
  75.         monitor.write(string.rep("=", width))
  76.        
  77.         local line = 3
  78.        
  79.         -- Mostra errori se presenti
  80.         if errorMsg then
  81.             monitor.setCursorPos(1, line)
  82.             monitor.setTextColor(colors.red)
  83.             monitor.write("ERRORE:")
  84.             line = line + 1
  85.             monitor.setCursorPos(1, line)
  86.             monitor.setTextColor(colors.orange)
  87.             -- Tronca messaggio se troppo lungo
  88.             local msg = string.sub(tostring(errorMsg), 1, width - 1)
  89.             monitor.write(msg)
  90.             line = line + 2
  91.         elseif tab and tab.timeLeft then
  92.             -- Stato del reattore
  93.             monitor.setCursorPos(1, line)
  94.             monitor.setTextColor(colors.cyan)
  95.             monitor.write("Stato: ")
  96.             if isRefueling then
  97.                 monitor.setTextColor(colors.yellow)
  98.                 monitor.write("RIFORNIMENTO")
  99.             else
  100.                 monitor.setTextColor(colors.green)
  101.                 monitor.write("ATTIVO")
  102.             end
  103.             line = line + 1
  104.            
  105.             -- Tempo rimanente
  106.             local hours = math.floor(tab.timeLeft / 3600)
  107.             local minutes = math.floor((tab.timeLeft % 3600) / 60)
  108.             local seconds = tab.timeLeft % 60
  109.            
  110.             monitor.setCursorPos(1, line)
  111.             monitor.setTextColor(colors.lightBlue)
  112.             monitor.write("Tempo:")
  113.             line = line + 1
  114.            
  115.             monitor.setCursorPos(1, line)
  116.             monitor.setTextColor(colors.white)
  117.             local timeStr
  118.             if hours > 0 then
  119.                 timeStr = string.format("%02d:%02d:%02d", hours, minutes, seconds)
  120.             else
  121.                 timeStr = string.format("%02d:%02d", minutes, seconds)
  122.             end
  123.             monitor.write(timeStr)
  124.             line = line + 1
  125.            
  126.             -- Barra di avanzamento (adattata alla larghezza)
  127.             monitor.setCursorPos(1, line)
  128.             monitor.setTextColor(colors.gray)
  129.             monitor.write("[")
  130.            
  131.             local barWidth = math.min(width - 4, 18) -- Lascia spazio per [ e ]
  132.             local timePercent = math.min(tab.timeLeft / 3600, 1) * 100 -- Percentuale basata su 1 ora
  133.             local filled = math.floor((timePercent / 100) * barWidth)
  134.            
  135.             if timePercent > 50 then
  136.                 monitor.setTextColor(colors.green)
  137.             elseif timePercent > 20 then
  138.                 monitor.setTextColor(colors.yellow)
  139.             else
  140.                 monitor.setTextColor(colors.red)
  141.             end
  142.            
  143.             for i = 1, barWidth do
  144.                 if i <= filled then
  145.                     monitor.write("=")
  146.                 else
  147.                     monitor.setTextColor(colors.gray)
  148.                     monitor.write("-")
  149.                 end
  150.             end
  151.            
  152.             monitor.setTextColor(colors.gray)
  153.             monitor.write("]")
  154.             line = line + 1
  155.            
  156.             -- Avviso se tempo basso
  157.             if tab.timeLeft < 60 and not isRefueling then
  158.                 monitor.setCursorPos(1, line)
  159.                 monitor.setTextColor(colors.red)
  160.                 monitor.write("! ATTENZIONE !")
  161.                 if line < height - 1 then
  162.                     line = line + 1
  163.                     monitor.setCursorPos(1, line)
  164.                     monitor.setTextColor(colors.orange)
  165.                     local warning = "Uranio in esaurimento"
  166.                     if string.len(warning) > width then
  167.                         warning = string.sub(warning, 1, width)
  168.                     end
  169.                     monitor.write(warning)
  170.                 end
  171.             end
  172.         else
  173.             -- Nessun dato disponibile
  174.             monitor.setCursorPos(1, line)
  175.             monitor.setTextColor(colors.orange)
  176.             monitor.write("Dati non disponibili")
  177.         end
  178.        
  179.         -- Footer
  180.         if line < height then
  181.             monitor.setCursorPos(1, height)
  182.             monitor.setTextColor(colors.gray)
  183.             monitor.write(string.rep("=", width))
  184.         end
  185.        
  186.         return true
  187.     end)
  188.    
  189.     if not success then
  190.         return false
  191.     end
  192.     return true
  193. end
  194.  
  195. -- Funzione per ottenere lo stato del reattore in modo sicuro
  196. function getReactorState(s)
  197.     if not s then
  198.         return nil, nil, nil, nil, "Peripheral non valido"
  199.     end
  200.    
  201.     local success, uuid, state, title, tab = pcall(function()
  202.         return s.get(1)
  203.     end)
  204.    
  205.     if not success then
  206.         return nil, nil, nil, nil, "Errore nella lettura del reattore: " .. tostring(uuid)
  207.     end
  208.    
  209.     if not tab or type(tab) ~= "table" then
  210.         return uuid, state, title, nil, "Dati reattore non validi"
  211.     end
  212.    
  213.     if tab.timeLeft == nil or type(tab.timeLeft) ~= "number" then
  214.         return uuid, state, title, tab, "timeLeft non valido"
  215.     end
  216.    
  217.     return uuid, state, title, tab, nil
  218. end
  219.  
  220. -- Costanti per la logica RS Latch con isteresi (sostituisce i gate hardware)
  221. local REFUEL_THRESHOLD_LOW = 10  -- Soglia per attivare rifornimento (Set)
  222. local REFUEL_THRESHOLD_HIGH = 15 -- Soglia per disattivare rifornimento (Reset) - isteresi
  223.  
  224. -- Costanti per i colori bundled redstone
  225. local COLOR_ORANGE = 2   -- Arancione: modalità normale (input/output materiale da arricchire)
  226. local COLOR_WHITE = 1    -- Bianco: modalità rifornimento (input/output cellule uranio)
  227. local COLOR_NONE = 0     -- Nessun colore: sistema fermo
  228.  
  229. -- Funzione che implementa la logica RS Latch integrata
  230. -- Gestisce la commutazione tra arancione (normale) e bianco (rifornimento) con isteresi
  231. -- Sostituisce il gate RS Latch hardware
  232. function updateReactorMode(timeLeft, currentMode)
  233.     -- currentMode può essere: "normal" (arancione), "refuel" (bianco), o nil (inizializzazione)
  234.    
  235.     if not timeLeft or timeLeft < 0 then
  236.         return COLOR_NONE, "error" -- Errore: dati non validi
  237.     end
  238.    
  239.     -- Logica RS Latch con isteresi:
  240.     -- - Set (rifornimento): quando timeLeft < REFUEL_THRESHOLD_LOW
  241.     -- - Reset (normale): quando timeLeft >= REFUEL_THRESHOLD_HIGH
  242.     -- - Isteresi: tra LOW e HIGH mantiene lo stato corrente (evita oscillazioni)
  243.    
  244.     if timeLeft < REFUEL_THRESHOLD_LOW then
  245.         -- Set: attiva modalità rifornimento (bianco)
  246.         return COLOR_WHITE, "refuel"
  247.     elseif timeLeft >= REFUEL_THRESHOLD_HIGH then
  248.         -- Reset: attiva modalità normale (arancione)
  249.         return COLOR_ORANGE, "normal"
  250.     else
  251.         -- Zona di isteresi (tra LOW e HIGH): mantieni lo stato corrente
  252.         if currentMode == "refuel" then
  253.             return COLOR_WHITE, "refuel"
  254.         else
  255.             -- Se non c'è uno stato corrente, usa il valore più vicino alla soglia
  256.             -- Se siamo appena scesi sotto HIGH, rimani in normale
  257.             -- Se siamo appena saliti sopra LOW, vai in rifornimento
  258.             -- Per sicurezza, se non c'è stato, considera normale
  259.             return COLOR_ORANGE, "normal"
  260.         end
  261.     end
  262. end
  263.  
  264. -- Funzione che implementa la logica XNOR integrata
  265. -- Garantisce che arancione e bianco non siano mai attivi contemporaneamente
  266. -- (già gestito automaticamente da setBundledOutput, ma questa funzione verifica la logica)
  267. function validateOutput(outputValue)
  268.     -- Verifica che l'output sia valido (solo arancione, bianco o nessuno)
  269.     if outputValue == COLOR_ORANGE or outputValue == COLOR_WHITE or outputValue == COLOR_NONE then
  270.         return true, outputValue
  271.     else
  272.         -- Output non valido: spegni tutto per sicurezza
  273.         return false, COLOR_NONE
  274.     end
  275. end
  276.  
  277. -- Funzione di compatibilità per bundled redstone (ComputerCraft 1.5 vs versioni più recenti)
  278. local function setBundledOutputCompat(side, color)
  279.     -- Prova prima con rs (versioni recenti)
  280.     if rs and rs.setBundledOutput then
  281.         return rs.setBundledOutput(side, color)
  282.     -- Fallback a redstone (ComputerCraft 1.5 per Minecraft 1.4.7)
  283.     elseif redstone and redstone.setBundledOutput then
  284.         return redstone.setBundledOutput(side, color)
  285.     else
  286.         error("API bundled redstone non disponibile")
  287.     end
  288. end
  289.  
  290. -- Funzione per impostare output redstone in modo sicuro con logica gate integrata
  291. function setOutputSafely(outputValue, errorMsg)
  292.     -- Valida l'output (logica XNOR: solo un colore alla volta)
  293.     local isValid, safeValue = validateOutput(outputValue)
  294.     if not isValid then
  295.         print("ATTENZIONE: Output non valido, uso valore sicuro")
  296.         outputValue = safeValue
  297.     end
  298.    
  299.     local success, err = pcall(function()
  300.         setBundledOutputCompat("back", outputValue)
  301.     end)
  302.     if not success then
  303.         print("ERRORE: Impossibile impostare output redstone: " .. tostring(err))
  304.         if errorMsg then
  305.             print(errorMsg)
  306.         end
  307.         return false
  308.     end
  309.     return true
  310. end
  311.  
  312. function clear()
  313.     term.clear()
  314.     term.setCursorPos(1, 1)
  315. end
  316.  
  317. clear()
  318.  
  319. -- Rilevamento versione ComputerCraft e API disponibile
  320. local ccVersion = "sconosciuta"
  321. local bundledAPI = "nessuna"
  322. if rs and rs.setBundledOutput then
  323.     bundledAPI = "rs.setBundledOutput (ComputerCraft recente)"
  324.     ccVersion = "recente"
  325. elseif redstone and redstone.setBundledOutput then
  326.     bundledAPI = "redstone.setBundledOutput (ComputerCraft 1.5 - MC 1.4.7)"
  327.     ccVersion = "1.5"
  328. else
  329.     bundledAPI = "NON DISPONIBILE"
  330.     print("ATTENZIONE: API bundled redstone non trovata!")
  331.     print("Il programma potrebbe non funzionare correttamente")
  332. end
  333.  
  334. print("Versione ComputerCraft rilevata: " .. ccVersion)
  335. print("API bundled redstone: " .. bundledAPI)
  336. print("")
  337.  
  338. -- Inizializzazione sicura
  339. local s, err = getPeripheral()
  340. if not s then
  341.     print("ERRORE CRITICO: " .. err)
  342.     print("Premere un tasto per riprovare...")
  343.     os.pullEvent("key")
  344.     os.reboot()
  345. end
  346.  
  347. -- Inizializzazione monitor
  348. local monitor, monitorSide, monitorErr = getMonitor()
  349. if monitor then
  350.     print("Monitor trovato sul lato: " .. monitorSide)
  351. else
  352.     print("ATTENZIONE: " .. (monitorErr or "Monitor non trovato"))
  353.     print("Il programma continuera' senza monitor")
  354. end
  355.  
  356. -- Lettura iniziale dello stato
  357. local uuid, state, title, tab, err = getReactorState(s)
  358. if err then
  359.     print("ERRORE: " .. err)
  360.     print("Verificare la connessione del reattore")
  361.     if monitor then
  362.         updateMonitor(monitor, nil, nil, nil, nil, false, err)
  363.     end
  364.     print("Premere un tasto per continuare...")
  365.     os.pullEvent("key")
  366. end
  367.  
  368. if tab and tab.timeLeft == 0 then
  369.     print("Caricare il reattore e premere un tasto")
  370.     if monitor then
  371.         updateMonitor(monitor, uuid, state, title, tab, false, "Reattore vuoto - caricare uranio")
  372.     end
  373.     os.pullEvent("key")
  374.     clear()
  375. end
  376.  
  377. print("Pronto")
  378. print("Sistema di sicurezza attivo")
  379. print("Logica gate integrata (XNOR + RS Latch) attiva")
  380.  
  381. -- Variabili per il controllo di sicurezza e logica gate integrata
  382. local lastTimeLeft = nil
  383. local consecutiveErrors = 0
  384. local maxErrors = 5
  385. local currentReactorMode = nil  -- "normal", "refuel", o nil (inizializzazione)
  386. local lastOutputValue = COLOR_NONE  -- Traccia l'ultimo output per evitare cambi inutili
  387.  
  388. -- Inizializzazione stato iniziale basato sul timeLeft corrente
  389. if tab and tab.timeLeft then
  390.     local initOutput, initMode = updateReactorMode(tab.timeLeft, nil)
  391.     currentReactorMode = initMode
  392.     lastOutputValue = initOutput
  393.    
  394.     -- Imposta l'output iniziale
  395.     if initMode == "normal" then
  396.         setOutputSafely(COLOR_ORANGE, "Impossibile impostare modalità iniziale normale")
  397.         print("Stato iniziale: MODALITA' NORMALE (arancione)")
  398.     elseif initMode == "refuel" then
  399.         setOutputSafely(COLOR_WHITE, "Impossibile impostare modalità iniziale rifornimento")
  400.         print("Stato iniziale: MODALITA' RIFORNIMENTO (bianco)")
  401.     else
  402.         setOutputSafely(COLOR_NONE, "Impossibile impostare stato iniziale")
  403.         print("Stato iniziale: ERRORE")
  404.     end
  405. else
  406.     -- Se non ci sono dati, inizia in modalità normale
  407.     currentReactorMode = "normal"
  408.     lastOutputValue = COLOR_ORANGE
  409.     setOutputSafely(COLOR_ORANGE, "Impossibile impostare stato iniziale")
  410.     print("Stato iniziale: MODALITA' NORMALE (dati non disponibili)")
  411. end
  412.  
  413. if monitor then
  414.     local isRefueling = (currentReactorMode == "refuel")
  415.     updateMonitor(monitor, uuid, state, title, tab, isRefueling, nil)
  416. end
  417.  
  418. while true do
  419.     clear()
  420.     print("Caricamento automatico materiale da arricchire in funzione")
  421.    
  422.     -- Verifica periodica della connessione del peripheral
  423.     if consecutiveErrors > 3 then
  424.         print("Riconnessione al peripheral...")
  425.         s, err = getPeripheral()
  426.         if not s then
  427.             print("ERRORE: " .. err)
  428.             print("Attesa 5 secondi prima di riprovare...")
  429.             sleep(5)
  430.             consecutiveErrors = 0
  431.         else
  432.             consecutiveErrors = 0
  433.             print("Riconnesso con successo")
  434.         end
  435.     end
  436.    
  437.     -- Verifica e riconnessione monitor se necessario
  438.     if not monitor or not pcall(function() monitor.getSize() end) then
  439.         monitor, monitorSide, monitorErr = getMonitor()
  440.         if monitor then
  441.             print("Monitor riconnesso sul lato: " .. monitorSide)
  442.         end
  443.     end
  444.    
  445.     -- Lettura sicura dello stato
  446.     uuid, state, title, tab, err = getReactorState(s)
  447.    
  448.     if err then
  449.         consecutiveErrors = consecutiveErrors + 1
  450.         print("ERRORE: " .. err)
  451.         print("Tentativo " .. consecutiveErrors .. "/" .. maxErrors)
  452.        
  453.         -- Aggiorna monitor con errore (mantieni lo stato corrente)
  454.         if monitor then
  455.             local isRefuelingMonitor = (currentReactorMode == "refuel")
  456.             updateMonitor(monitor, uuid, state, title, tab, isRefuelingMonitor, err)
  457.         end
  458.        
  459.         if consecutiveErrors >= maxErrors then
  460.             print("ERRORE CRITICO: Troppi errori consecutivi")
  461.             print("Arresto sistema per sicurezza")
  462.             -- In caso di errore critico, spegni tutto (COLOR_NONE)
  463.             setOutputSafely(COLOR_NONE, "Sistema fermato per sicurezza")
  464.             currentReactorMode = "error"
  465.             lastOutputValue = COLOR_NONE
  466.             if monitor then
  467.                 updateMonitor(monitor, uuid, state, title, tab, false, "SISTEMA FERMATO - Troppi errori")
  468.             end
  469.             print("Premere un tasto per riprovare...")
  470.             os.pullEvent("key")
  471.             consecutiveErrors = 0
  472.             -- Ripristina lo stato iniziale dopo l'errore
  473.             currentReactorMode = nil
  474.         else
  475.             sleep(2)
  476.         end
  477.     else
  478.         consecutiveErrors = 0
  479.        
  480.         -- Validazione dei dati
  481.         if tab and tab.timeLeft then
  482.             -- Verifica coerenza dei dati (timeLeft non dovrebbe aumentare)
  483.             if lastTimeLeft ~= nil and tab.timeLeft > lastTimeLeft + 5 then
  484.                 print("ATTENZIONE: Rilevato incremento anomalo del tempo")
  485.                 print("Possibile errore di lettura, attesa...")
  486.                 sleep(3)
  487.             else
  488.                 lastTimeLeft = tab.timeLeft
  489.             end
  490.            
  491.             local hours = math.floor(tab.timeLeft / 3600)
  492.             local minutes = math.floor((tab.timeLeft % 3600) / 60)
  493.             local seconds = tab.timeLeft % 60
  494.  
  495.             print("Tempo rimanente: " .. hours .. " ore, " .. minutes .. " minuti, " .. seconds .. " secondi")
  496.            
  497.             -- LOGICA GATE INTEGRATA (sostituisce XNOR e RS Latch hardware)
  498.             -- Determina la modalità del reattore basandosi sul timeLeft
  499.             local outputValue, newMode = updateReactorMode(tab.timeLeft, currentReactorMode)
  500.            
  501.             -- Aggiorna lo stato solo se è cambiato
  502.             if newMode ~= currentReactorMode then
  503.                 local oldMode = currentReactorMode
  504.                 currentReactorMode = newMode
  505.                
  506.                 if newMode == "refuel" then
  507.                     clear()
  508.                     print("ATTENZIONE: Uranio in esaurimento")
  509.                     print("Modalità RIFORNIMENTO attivata (bianco)")
  510.                     print("Input/output materiale da arricchire: DISATTIVATI")
  511.                     print("Input/output cellule uranio: ATTIVI")
  512.                 elseif newMode == "normal" then
  513.                     if oldMode == "refuel" then
  514.                         print("Rifornimento completato")
  515.                     end
  516.                     print("Modalità NORMALE attivata (arancione)")
  517.                     print("Input/output materiale da arricchire: ATTIVI")
  518.                     print("Input/output cellule uranio: DISATTIVATI")
  519.                 end
  520.             end
  521.            
  522.             -- Imposta l'output solo se è cambiato (ottimizzazione)
  523.             if outputValue ~= lastOutputValue then
  524.                 local modeName = "normale"
  525.                 if newMode == "refuel" then
  526.                     modeName = "rifornimento"
  527.                 elseif newMode == "error" then
  528.                     modeName = "errore"
  529.                 end
  530.                
  531.                 setOutputSafely(outputValue, "Impossibile impostare modalità " .. modeName)
  532.                 lastOutputValue = outputValue
  533.                
  534.                 if outputValue == COLOR_ORANGE then
  535.                     print("Output: ARANCIONE (normale)")
  536.                 elseif outputValue == COLOR_WHITE then
  537.                     print("Output: BIANCO (rifornimento)")
  538.                 elseif outputValue == COLOR_NONE then
  539.                     print("Output: SPENTO (errore)")
  540.                 end
  541.             end
  542.            
  543.             -- Aggiorna monitor con dati attuali
  544.             local isRefueling = (newMode == "refuel")
  545.             if monitor then
  546.                 updateMonitor(monitor, uuid, state, title, tab, isRefueling, nil)
  547.             end
  548.         else
  549.             print("ERRORE: Dati reattore non validi")
  550.             consecutiveErrors = consecutiveErrors + 1
  551.         end
  552.     end
  553.  
  554.     sleep(1)
  555. end
Advertisement
Add Comment
Please, Sign In to add comment