GLaDOS446

SCHLEUSEN KONTROLLE 2

Jun 7th, 2026 (edited)
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.72 KB | Source Code | 0 0
  1. local component = require("component")
  2. local event = require("event")
  3. local sides = require("sides")
  4. local colors = require("colors")
  5. local term = require("term")
  6. local serialization = require("serialization")
  7. local modem = component.modem
  8. local rs = component.redstone
  9.  
  10. modem.open(225)
  11.  
  12. local CONFIG_FILE = "schleuse_config.cfg"
  13. local config = {}
  14.  
  15. -------------------------------------------------------------------------------
  16. -- EINSTELLUNG FÜR DIE TEXTGRÖSSE (SCHRIFTGRÖSSE)
  17. -------------------------------------------------------------------------------
  18. -- Je KLEINER diese beiden Zahlen sind, desto GRÖSSER wird die Schrift!
  19. -- Die Buttons passen sich automatisch an und bleiben gigantische Blöcke.
  20. -- Standard-Empfehlung für fette Schrift: Breite 24, Höhe 10.
  21. local TEXT_BREITE = 24
  22. local TEXT_HOEHE  = 10
  23.  
  24. -- Redstone & Kabel-Konfiguration
  25. local REDSTONE_SEITE = sides.back
  26. local CABLE_UNGESICHERT = colors.black -- Schwarz = Außen
  27. local CABLE_GESICHERT   = colors.gray  -- Grau = Innenbasis
  28. -------------------------------------------------------------------------------
  29.  
  30. -- Dynamische Zentrierung mit optionalem X-Versatz (für geteilte Bildschirme)
  31. local function printZentriert(gpu, maxW, y, text, fore, back, offsetX)
  32.   offsetX = offsetX or 0
  33.   if fore then gpu.setForeground(fore) end
  34.   if back then gpu.setBackground(back) end
  35.   local gekuerzt = string.sub(text, 1, maxW)
  36.   local x = math.max(1, math.floor((maxW - #gekuerzt) / 2) + 1) + offsetX
  37.   gpu.set(x, y, gekuerzt)
  38. end
  39.  
  40. -------------------------------------------------------------------------------
  41. -- SETUP-ASSISTENT
  42. -------------------------------------------------------------------------------
  43. local function ladeOderErstelleConfig(gpu_test)
  44.   local f = io.open(CONFIG_FILE, "r")
  45.   if f then
  46.     local inhalt = f:read("*a")
  47.     f:close()
  48.     config = serialization.unserialize(inhalt)
  49.     if config and config.grau and config.schwarz and config.innen then
  50.       return
  51.     end
  52.   end
  53.  
  54.   term.clear()
  55.   print("=== SCHLEUSEN SETUP ===")
  56.   print("Monitore werden nacheinander GRÜN.")
  57.   print("Bitte am Terminal zuweisen.\n")
  58.   print("Drücke ENTER zum Starten...")
  59.   io.read()
  60.  
  61.   config = {}
  62.   local alle_monitore = {}
  63.   for addr in component.list("screen") do
  64.     table.insert(alle_monitore, addr)
  65.   end
  66.  
  67.   for i, addr in ipairs(alle_monitore) do
  68.     gpu_test.bind(addr)
  69.     gpu_test.setResolution(TEXT_BREITE, TEXT_HOEHE)
  70.     gpu_test.setBackground(0x00FF00)
  71.     gpu_test.fill(1, 1, TEXT_BREITE, TEXT_HOEHE, " ")
  72.     printZentriert(gpu_test, TEXT_BREITE, math.floor(TEXT_HOEHE/2), "MONITOR " .. i, 0x000000, 0x00FF00)
  73.  
  74.     term.clear()
  75.     print("Ein Monitor leuchtet jetzt GRÜN.")
  76.     print("Welcher Monitor ist das?")
  77.     print("1: Physischer Monitor UNGESICHERT (Aussen)")
  78.     print("2: Physischer Monitor GESICHERT (Basis)")
  79.     print("3: Physischer Monitor INNENRAUM (Karte)")
  80.     print("4: Ignorieren")
  81.    
  82.     local auswahl = ""
  83.     while auswahl ~= "1" and auswahl ~= "2" and auswahl ~= "3" and auswahl ~= "4" do
  84.       io.write("Auswahl (1-4): ")
  85.       auswahl = io.read()
  86.     end
  87.  
  88.     if auswahl == "1" then config.grau = addr
  89.     elseif auswahl == "2" then config.schwarz = addr
  90.     elseif auswahl == "3" then config.innen = addr
  91.     end
  92.  
  93.     gpu_test.setBackground(0x000000)
  94.     gpu_test.fill(1, 1, TEXT_BREITE, TEXT_HOEHE, " ")
  95.   end
  96.  
  97.   if not config.grau or not config.schwarz or not config.innen then
  98.     term.clear()
  99.     print("Fehler: Zuweisung unvollständig! Neustart erforderlich.")
  100.     os.exit()
  101.   end
  102.  
  103.   f = io.open(CONFIG_FILE, "w")
  104.   f:write(serialization.serialize(config))
  105.   f:close()
  106.   term.clear()
  107.   print("Setup gespeichert!")
  108.   os.sleep(1)
  109. end
  110.  
  111. -------------------------------------------------------------------------------
  112. -- HAUPTPROGRAMM
  113. -------------------------------------------------------------------------------
  114. local gpus = {}
  115. for addr in component.list("gpu") do
  116.   table.insert(gpus, component.proxy(addr))
  117. end
  118.  
  119. if #gpus < 2 then
  120.   error("Fehler: Dieser PC benötigt mindestens 2 Grafikkarten!")
  121. end
  122.  
  123. local gpu_aussen = gpus[1]
  124. local gpu_innen  = gpus[2]
  125.  
  126. ladeOderErstelleConfig(gpu_aussen)
  127.  
  128. local status = "BEREIT"
  129. local innen_entsperrt = false
  130. local letzte_eintritts_seite = CABLE_UNGESICHERT
  131.  
  132. -- UI FÜR AUSSEN-MONITORE
  133. local function drawAussenInterface(gpu, titel)
  134.   local w, h = TEXT_BREITE, TEXT_HOEHE
  135.   gpu.setBackground(0x000000)
  136.   gpu.fill(1, 1, w, h, " ")
  137.  
  138.   printZentriert(gpu, w, math.max(1, math.floor(h * 0.15)), "== " .. titel .. " ==", 0xFFFFFF, 0x000000)
  139.  
  140.   if status == "BEREIT" then
  141.     printZentriert(gpu, w, math.max(2, math.floor(h * 0.35)), "STATUS: BEREIT", 0x00FF00, 0x000000)
  142.    
  143.     local btnY = math.floor(h * 0.5)
  144.     local btnH = h - btnY + 1
  145.     gpu.setBackground(0x333333)
  146.     gpu.fill(1, btnY, w, btnH, " ")
  147.     printZentriert(gpu, w, btnY + math.floor(btnH / 2), "[ OEFFNEN ]", 0xFFFFFF, 0x333333)
  148.   else
  149.     printZentriert(gpu, w, math.max(2, math.floor(h * 0.35)), "STATUS:", 0xFF0000, 0x000000)
  150.     printZentriert(gpu, w, math.max(3, math.floor(h * 0.6)), status, 0xFF0000, 0x000000)
  151.   end
  152. end
  153.  
  154. -- UI FÜR INNEN-MONITOR (Zwei fette Blöcke oben, einer unten)
  155. local function drawInnenInterface()
  156.   local w, h = TEXT_BREITE, TEXT_HOEHE
  157.   gpu_innen.setBackground(0x000000)
  158.   gpu_innen.fill(1, 1, w, h, " ")
  159.  
  160.   printZentriert(gpu_innen, w, 1, "=== INNENRAUM ===", 0xFFFFFF, 0x000000)
  161.  
  162.   if status ~= "BEREIT" then
  163.     printZentriert(gpu_innen, w, math.floor(h * 0.5), status, 0xFF0000, 0x000000)
  164.     return
  165.   end
  166.  
  167.   local trennY = math.floor(h * 0.5)
  168.  
  169.   if innen_entsperrt then
  170.     local halbe_breite = math.floor(w / 2)
  171.     local btnH = trennY - 1
  172.    
  173.     -- LINKS: REIN (Gelber Riesenblock)
  174.     gpu_innen.setBackground(0x555500)
  175.     gpu_innen.fill(1, 2, halbe_breite, btnH, " ")
  176.     printZentriert(gpu_innen, halbe_breite, 2 + math.floor(btnH / 2), "[REIN]", 0xFFFFFF, 0x555500, 0)
  177.    
  178.     -- RECHTS: RAUS (Grüner Riesenblock)
  179.     gpu_innen.setBackground(0x005500)
  180.     gpu_innen.fill(halbe_breite + 1, 2, w - halbe_breite, btnH, " ")
  181.     printZentriert(gpu_innen, w - halbe_breite, 2 + math.floor(btnH / 2), "[RAUS]", 0xFFFFFF, 0x005500, halbe_breite)
  182.   else
  183.     printZentriert(gpu_innen, w, math.floor(trennY / 2) + 1, "CARD SCAN", 0xFFFF00, 0x000000)
  184.   end
  185.  
  186.   -- UNTEN: Permanenter Rückweg-Knopf (Dunkelgrauer Riesenblock)
  187.   local rkY = trennY + 1
  188.   local rkH = h - trennY
  189.   gpu_innen.setBackground(0x222222)
  190.   gpu_innen.fill(1, rkY, w, rkH, " ")
  191.  
  192.   local weg_text = (letzte_eintritts_seite == CABLE_UNGESICHERT) and "<-- ZURUECK (RAUS)" or "<-- ZURUECK (REIN)"
  193.   printZentriert(gpu_innen, w, rkY + math.floor(rkH / 2), weg_text, 0xFFFFFF, 0x222222)
  194. end
  195.  
  196. -- Hier erzwingen wir die Auflösung bei JEDEM Bildschirmwechsel neu!
  197. local function updateAlleMonitore()
  198.   gpu_aussen.bind(config.grau)
  199.   gpu_aussen.setResolution(TEXT_BREITE, TEXT_HOEHE)
  200.   drawAussenInterface(gpu_aussen, "AUSSEN")
  201.  
  202.   gpu_aussen.bind(config.schwarz)
  203.   gpu_aussen.setResolution(TEXT_BREITE, TEXT_HOEHE)
  204.   drawAussenInterface(gpu_aussen, "BASIS")
  205.  
  206.   gpu_innen.bind(config.innen)
  207.   gpu_innen.setResolution(TEXT_BREITE, TEXT_HOEHE)
  208.   drawInnenInterface()
  209. end
  210.  
  211. local function oeffneTuer(farbe)
  212.   status = "OEFFNE..."
  213.   updateAlleMonitore()
  214.   rs.setBundledOutput(REDSTONE_SEITE, farbe, 255)
  215.   os.sleep(12)
  216.  
  217.   status = "OFFEN"
  218.   updateAlleMonitore()
  219.   os.sleep(5)
  220.  
  221.   status = "SCHLIESSEN"
  222.   updateAlleMonitore()
  223.   rs.setBundledOutput(REDSTONE_SEITE, farbe, 0)
  224.   os.sleep(2)
  225.  
  226.   -- Sicherheits-Wartezeit (8 Sekunden Blockade für MagCards)
  227.   status = "ZULOCKEN..."
  228.   updateAlleMonitore()
  229.   os.sleep(8)
  230.  
  231.   status = "BEREIT"
  232.   innen_entsperrt = false
  233.   updateAlleMonitore()
  234. end
  235.  
  236. term.clear()
  237. print("[OK] Schleusensteuerung mit fixierter Textgroesse aktiv!")
  238. updateAlleMonitore()
  239.  
  240. -- Haupt-Event-Schleife
  241. while true do
  242.   local id, arg1, arg2, arg3 = event.pull()
  243.  
  244.   if id == "touch" and status == "BEREIT" then
  245.     local screen_addr = arg1
  246.     local x, y = arg2, arg3
  247.    
  248.     local w, h = TEXT_BREITE, TEXT_HOEHE
  249.     local trennY = math.floor(h * 0.5)
  250.    
  251.     -- AUSSEN-MONITORE
  252.     if screen_addr == config.grau then
  253.       if y >= math.floor(h * 0.5) then
  254.         letzte_eintritts_seite = CABLE_UNGESICHERT
  255.         oeffneTuer(CABLE_UNGESICHERT)
  256.       end
  257.     elseif screen_addr == config.schwarz then
  258.       if y >= math.floor(h * 0.5) then
  259.         letzte_eintritts_seite = CABLE_GESICHERT
  260.         oeffneTuer(CABLE_GESICHERT)
  261.       end
  262.      
  263.     -- INNEN-MONITOR
  264.     elseif screen_addr == config.innen then
  265.       -- Klick unten (Rückweg)
  266.       if y > trennY then
  267.         oeffneTuer(letzte_eintritts_seite)
  268.        
  269.       -- Klick oben (Richtungswahl)
  270.       elseif innen_entsperrt and y >= 2 and y <= trennY then
  271.         local halbe_breite = math.floor(w / 2)
  272.         if x <= halbe_breite then
  273.           oeffneTuer(CABLE_GESICHERT)   -- LINKS: [REIN]
  274.         else
  275.           oeffneTuer(CABLE_UNGESICHERT) -- RECHTS: [RAUS]
  276.         end
  277.       end
  278.     end
  279.    
  280.   -- MAGNETKARTEN-READER
  281.   elseif id == "magData" and status == "BEREIT" then
  282.     local card_id = arg3
  283.    
  284.     modem.broadcast(225, "verify", card_id)
  285.     local _, _, _, _, _, replyType, replyId, isValid = event.pull(3, "modem_message")
  286.    
  287.     if replyType == "reply" and replyId == card_id and isValid then
  288.       innen_entsperrt = true
  289.       updateAlleMonitore()
  290.     else
  291.       gpu_innen.bind(config.innen)
  292.       gpu_innen.setResolution(TEXT_BREITE, TEXT_HOEHE)
  293.       gpu_innen.setBackground(0x550000)
  294.       gpu_innen.fill(1, 1, TEXT_BREITE, TEXT_HOEHE, " ")
  295.       printZentriert(gpu_innen, TEXT_BREITE, math.floor(TEXT_HOEHE/2), "ABGEWIESEN!", 0xFFFFFF, 0x550000)
  296.       os.sleep(2)
  297.       updateAlleMonitore()
  298.     end
  299.   end
  300. end
Advertisement
Add Comment
Please, Sign In to add comment