firex20

reactor_alert

Nov 11th, 2025 (edited)
244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.72 KB | Gaming | 0 0
  1. -- reactor_alert_big.lua
  2. -- Alarma para reactor con letras grandes y opción de audio por URL.
  3. -- Uso:
  4. --   shell.run("reactor_alert_big", <audioURL_or_empty>, <textScale>)
  5. -- Ejemplo:
  6. --   shell.run("reactor_alert_big", "", "2")
  7. --   shell.run("reactor_alert_big", "https://mi-servidor.com/alarma.ogg", "1.5")
  8.  
  9. local inputSide   = "bottom"
  10. local monitorSide = "top"
  11. local speakerSide = "back"
  12.  
  13. -- parámetros (ajustables)
  14. local blinkInterval = 0.5    -- s entre cambios de color
  15. local soundInterval = 0.12   -- s entre reproducciones (si se usa método repetido)
  16. local bgA = colors.red
  17. local bgB = colors.orange or colors.red
  18. local bgOff = colors.black
  19. local textColor = colors.white
  20. local alertText = "ALERTA REACTOR !!!"
  21.  
  22. local args = {...}
  23. local audioURL = args[1] or ""          -- si pasas URL directa a mp3/ogg se intentará playAudio
  24. local requestedTextScale = tonumber(args[2]) or nil -- ej. 2, 1.5, etc
  25.  
  26. -- helpers periféricos
  27. local function isPeripheral(side) return peripheral.isPresent(side) end
  28. local function wrap(side) if peripheral.isPresent(side) then return peripheral.wrap(side) end return nil end
  29.  
  30. -- detectar métodos speaker disponibles
  31. local function speakerSupports(name)
  32.   local ok, methods = pcall(peripheral.getMethods, speakerSide)
  33.   if not ok or not methods then return false end
  34.   for _, m in ipairs(methods) do if m == name then return true end end
  35.   return false
  36. end
  37.  
  38. -- intentar usar playAudio si hay URL y speaker lo soporta
  39. local function tryPlayAudioURL(url)
  40.   if url == nil or url == "" then return false end
  41.   if speakerSupports("playAudio") then
  42.     local ok = pcall(peripheral.call, speakerSide, "playAudio", url)
  43.     return ok
  44.   end
  45.   return false
  46. end
  47.  
  48. -- intenta reproducir una nota/sonido estridente y fuerte (fallback)
  49. local function playLoudSoundOnce()
  50.   local ok, methods = pcall(peripheral.getMethods, speakerSide)
  51.   if ok and methods then
  52.     -- preferimos playSound con volumen alto si existe
  53.     for _, m in ipairs(methods) do
  54.       if m == "playSound" then
  55.         -- soundName, volume, pitch (volume alto para ser estridente)
  56.         pcall(peripheral.call, speakerSide, "playSound", "entity.creeper.primed", 3, 1)
  57.         return true
  58.       elseif m == "playNote" then
  59.         -- instrumento "hat" o "snare" suena más 'agudo'
  60.         pcall(peripheral.call, speakerSide, "playNote", "hat", 3)
  61.         return true
  62.       elseif m == "play" then
  63.         pcall(peripheral.call, speakerSide, "play")
  64.         return true
  65.       end
  66.     end
  67.   end
  68.   -- si no hay periférico speaker detectable retornamos false (caller hará fallback por redstone)
  69.   return false
  70. end
  71.  
  72. -- fallback por redstone: toggle rápido para activar un altavoz por redstone si tienes uno
  73. local function fallbackRedstoneBeep()
  74.   pcall(redstone.setOutput, speakerSide, true)
  75.   sleep(0.035)
  76.   pcall(redstone.setOutput, speakerSide, false)
  77. end
  78.  
  79. -- monitor: intentar setTextScale grande si se pidió y si el monitor lo permite
  80. local monitorWrap = nil
  81. local monW, monH = nil, nil
  82. if isPeripheral(monitorSide) then
  83.   monitorWrap = wrap(monitorSide)
  84.   local ok, s = pcall(function()
  85.     if requestedTextScale then
  86.       -- muchos monitores aceptan 0.5, 1, 2; CC:Tweaked admite setTextScale con valores decimales en algunas versiones
  87.       if monitorWrap.setTextScale then
  88.         pcall(monitorWrap.setTextScale, monitorWrap, requestedTextScale)
  89.       end
  90.     end
  91.     monW, monH = monitorWrap.getSize()
  92.   end)
  93.   if not ok then monitorWrap = nil end
  94. end
  95.  
  96. -- función para dibujar centrado con tamaño actual del monitor
  97. local function drawOnMonitor(bg)
  98.   if not monitorWrap then
  99.     term.setBackgroundColor(bg)
  100.     term.clear()
  101.     term.setCursorPos(1,1)
  102.     term.setTextColor(textColor)
  103.     print(alertText)
  104.     return
  105.   end
  106.   monitorWrap.setBackgroundColor(bg)
  107.   monitorWrap.setTextColor(textColor)
  108.   monitorWrap.clear()
  109.   -- recalcular tamaño y centrar
  110.   monW, monH = monitorWrap.getSize()
  111.   -- si el texto supera el ancho, intentar reducir escala (si es posible)
  112.   if #alertText > monW then
  113.     -- intentar reducir a escala 1 si existía una mayor
  114.     if monitorWrap.setTextScale then
  115.       pcall(monitorWrap.setTextScale, monitorWrap, 1)
  116.       monW, monH = monitorWrap.getSize()
  117.     end
  118.   end
  119.   local x = math.max(1, math.floor((monW - #alertText) / 2) + 1)
  120.   local y = math.max(1, math.floor(monH / 2))
  121.   monitorWrap.setCursorPos(x, y)
  122.   monitorWrap.write(alertText)
  123. end
  124.  
  125. local function clearMonitorNow()
  126.   if not monitorWrap then
  127.     term.setBackgroundColor(bgOff); term.clear(); term.setCursorPos(1,1)
  128.     return
  129.   end
  130.   if monitorWrap.setTextScale and requestedTextScale then
  131.     -- opcional: restaurar escala a 1 al limpiar (no obligatorio)
  132.     pcall(monitorWrap.setTextScale, monitorWrap, 1)
  133.   end
  134.   monitorWrap.setBackgroundColor(bgOff)
  135.   monitorWrap.clear()
  136.   monitorWrap.setCursorPos(1,1)
  137. end
  138.  
  139. -- estado y temporizadores
  140. local alarmOn = false
  141. local blinkState = false
  142. local lastBlink = os.clock()
  143. local lastSound = os.clock()
  144.  
  145. -- Si hay URL y speaker soporta playAudio, iniciamos la reproducción al activar, y al apagar intentamos detener con 'stop' si existe.
  146. local audioPlaying = false
  147.  
  148. local function startAudioStream(url)
  149.   if url == nil or url == "" then return false end
  150.   if speakerSupports("playAudio") then
  151.     local ok = pcall(peripheral.call, speakerSide, "playAudio", url)
  152.     if ok then audioPlaying = true; return true end
  153.   end
  154.   return false
  155. end
  156.  
  157. local function stopAudioStream()
  158.   if audioPlaying and speakerSupports("stop") then
  159.     pcall(peripheral.call, speakerSide, "stop")
  160.   end
  161.   audioPlaying = false
  162. end
  163.  
  164. -- inicial: si la señal ya está activa, arrancamos alarma
  165. if redstone.getInput(inputSide) then
  166.   alarmOn = true
  167.   blinkState = true
  168.   lastBlink = os.clock()
  169.   lastSound = os.clock()
  170.   drawOnMonitor((blinkState and bgA or bgB))
  171.   -- si audioURL y soporte playAudio -> arrancar stream
  172.   if audioURL ~= "" and startAudioStream(audioURL) then
  173.     -- stream arrancado
  174.   else
  175.     -- primer sonido inmediato fallback
  176.     if not playLoudSoundOnce() then fallbackRedstoneBeep() end
  177.   end
  178. end
  179.  
  180. -- timer de polling
  181. local timerId = os.startTimer(1)
  182. print("Alarma lista. Esperando señal en " .. inputSide .. " ...")
  183.  
  184. while true do
  185.   local ev = { os.pullEvent() }
  186.   if ev[1] == "redstone" then
  187.     local sig = redstone.getInput(inputSide)
  188.     if sig and not alarmOn then
  189.       -- start alarm
  190.       alarmOn = true
  191.       blinkState = true
  192.       lastBlink = os.clock()
  193.       lastSound = os.clock()
  194.       drawOnMonitor((blinkState and bgA or bgB))
  195.       -- intentar stream si URL
  196.       if audioURL ~= "" and startAudioStream(audioURL) then
  197.         -- streaming
  198.       else
  199.         -- sonido repetitivo
  200.         if not playLoudSoundOnce() then fallbackRedstoneBeep() end
  201.       end
  202.  
  203.     elseif (not sig) and alarmOn then
  204.       -- stop alarm
  205.       alarmOn = false
  206.       stopAudioStream()
  207.       -- asegurar que cualquier redstone fallback está apagado
  208.       pcall(redstone.setOutput, speakerSide, false)
  209.       clearMonitorNow()
  210.     end
  211.  
  212.   elseif ev[1] == "timer" then
  213.     timerId = os.startTimer(1)
  214.  
  215.     if alarmOn then
  216.       local now = os.clock()
  217.       if now - lastBlink >= blinkInterval then
  218.         blinkState = not blinkState
  219.         lastBlink = now
  220.         drawOnMonitor((blinkState and bgA or bgB))
  221.       end
  222.  
  223.       if now - lastSound >= soundInterval then
  224.         lastSound = now
  225.         -- si estamos con stream (playAudio), no hacemos nada — el stream debería reproducirse por sí mismo
  226.         if audioPlaying then
  227.           -- opcional: no hacer nada
  228.         else
  229.           -- reproducir sonido fuerte repetido
  230.           if not playLoudSoundOnce() then fallbackRedstoneBeep() end
  231.         end
  232.       end
  233.     end
  234.   end
  235. end
  236.  
Advertisement
Add Comment
Please, Sign In to add comment