Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- reactor_alert_big.lua
- -- Alarma para reactor con letras grandes y opción de audio por URL.
- -- Uso:
- -- shell.run("reactor_alert_big", <audioURL_or_empty>, <textScale>)
- -- Ejemplo:
- -- shell.run("reactor_alert_big", "", "2")
- -- shell.run("reactor_alert_big", "https://mi-servidor.com/alarma.ogg", "1.5")
- local inputSide = "bottom"
- local monitorSide = "top"
- local speakerSide = "back"
- -- parámetros (ajustables)
- local blinkInterval = 0.5 -- s entre cambios de color
- local soundInterval = 0.12 -- s entre reproducciones (si se usa método repetido)
- local bgA = colors.red
- local bgB = colors.orange or colors.red
- local bgOff = colors.black
- local textColor = colors.white
- local alertText = "ALERTA REACTOR !!!"
- local args = {...}
- local audioURL = args[1] or "" -- si pasas URL directa a mp3/ogg se intentará playAudio
- local requestedTextScale = tonumber(args[2]) or nil -- ej. 2, 1.5, etc
- -- helpers periféricos
- local function isPeripheral(side) return peripheral.isPresent(side) end
- local function wrap(side) if peripheral.isPresent(side) then return peripheral.wrap(side) end return nil end
- -- detectar métodos speaker disponibles
- local function speakerSupports(name)
- local ok, methods = pcall(peripheral.getMethods, speakerSide)
- if not ok or not methods then return false end
- for _, m in ipairs(methods) do if m == name then return true end end
- return false
- end
- -- intentar usar playAudio si hay URL y speaker lo soporta
- local function tryPlayAudioURL(url)
- if url == nil or url == "" then return false end
- if speakerSupports("playAudio") then
- local ok = pcall(peripheral.call, speakerSide, "playAudio", url)
- return ok
- end
- return false
- end
- -- intenta reproducir una nota/sonido estridente y fuerte (fallback)
- local function playLoudSoundOnce()
- local ok, methods = pcall(peripheral.getMethods, speakerSide)
- if ok and methods then
- -- preferimos playSound con volumen alto si existe
- for _, m in ipairs(methods) do
- if m == "playSound" then
- -- soundName, volume, pitch (volume alto para ser estridente)
- pcall(peripheral.call, speakerSide, "playSound", "entity.creeper.primed", 3, 1)
- return true
- elseif m == "playNote" then
- -- instrumento "hat" o "snare" suena más 'agudo'
- pcall(peripheral.call, speakerSide, "playNote", "hat", 3)
- return true
- elseif m == "play" then
- pcall(peripheral.call, speakerSide, "play")
- return true
- end
- end
- end
- -- si no hay periférico speaker detectable retornamos false (caller hará fallback por redstone)
- return false
- end
- -- fallback por redstone: toggle rápido para activar un altavoz por redstone si tienes uno
- local function fallbackRedstoneBeep()
- pcall(redstone.setOutput, speakerSide, true)
- sleep(0.035)
- pcall(redstone.setOutput, speakerSide, false)
- end
- -- monitor: intentar setTextScale grande si se pidió y si el monitor lo permite
- local monitorWrap = nil
- local monW, monH = nil, nil
- if isPeripheral(monitorSide) then
- monitorWrap = wrap(monitorSide)
- local ok, s = pcall(function()
- if requestedTextScale then
- -- muchos monitores aceptan 0.5, 1, 2; CC:Tweaked admite setTextScale con valores decimales en algunas versiones
- if monitorWrap.setTextScale then
- pcall(monitorWrap.setTextScale, monitorWrap, requestedTextScale)
- end
- end
- monW, monH = monitorWrap.getSize()
- end)
- if not ok then monitorWrap = nil end
- end
- -- función para dibujar centrado con tamaño actual del monitor
- local function drawOnMonitor(bg)
- if not monitorWrap then
- term.setBackgroundColor(bg)
- term.clear()
- term.setCursorPos(1,1)
- term.setTextColor(textColor)
- print(alertText)
- return
- end
- monitorWrap.setBackgroundColor(bg)
- monitorWrap.setTextColor(textColor)
- monitorWrap.clear()
- -- recalcular tamaño y centrar
- monW, monH = monitorWrap.getSize()
- -- si el texto supera el ancho, intentar reducir escala (si es posible)
- if #alertText > monW then
- -- intentar reducir a escala 1 si existía una mayor
- if monitorWrap.setTextScale then
- pcall(monitorWrap.setTextScale, monitorWrap, 1)
- monW, monH = monitorWrap.getSize()
- end
- end
- local x = math.max(1, math.floor((monW - #alertText) / 2) + 1)
- local y = math.max(1, math.floor(monH / 2))
- monitorWrap.setCursorPos(x, y)
- monitorWrap.write(alertText)
- end
- local function clearMonitorNow()
- if not monitorWrap then
- term.setBackgroundColor(bgOff); term.clear(); term.setCursorPos(1,1)
- return
- end
- if monitorWrap.setTextScale and requestedTextScale then
- -- opcional: restaurar escala a 1 al limpiar (no obligatorio)
- pcall(monitorWrap.setTextScale, monitorWrap, 1)
- end
- monitorWrap.setBackgroundColor(bgOff)
- monitorWrap.clear()
- monitorWrap.setCursorPos(1,1)
- end
- -- estado y temporizadores
- local alarmOn = false
- local blinkState = false
- local lastBlink = os.clock()
- local lastSound = os.clock()
- -- Si hay URL y speaker soporta playAudio, iniciamos la reproducción al activar, y al apagar intentamos detener con 'stop' si existe.
- local audioPlaying = false
- local function startAudioStream(url)
- if url == nil or url == "" then return false end
- if speakerSupports("playAudio") then
- local ok = pcall(peripheral.call, speakerSide, "playAudio", url)
- if ok then audioPlaying = true; return true end
- end
- return false
- end
- local function stopAudioStream()
- if audioPlaying and speakerSupports("stop") then
- pcall(peripheral.call, speakerSide, "stop")
- end
- audioPlaying = false
- end
- -- inicial: si la señal ya está activa, arrancamos alarma
- if redstone.getInput(inputSide) then
- alarmOn = true
- blinkState = true
- lastBlink = os.clock()
- lastSound = os.clock()
- drawOnMonitor((blinkState and bgA or bgB))
- -- si audioURL y soporte playAudio -> arrancar stream
- if audioURL ~= "" and startAudioStream(audioURL) then
- -- stream arrancado
- else
- -- primer sonido inmediato fallback
- if not playLoudSoundOnce() then fallbackRedstoneBeep() end
- end
- end
- -- timer de polling
- local timerId = os.startTimer(1)
- print("Alarma lista. Esperando señal en " .. inputSide .. " ...")
- while true do
- local ev = { os.pullEvent() }
- if ev[1] == "redstone" then
- local sig = redstone.getInput(inputSide)
- if sig and not alarmOn then
- -- start alarm
- alarmOn = true
- blinkState = true
- lastBlink = os.clock()
- lastSound = os.clock()
- drawOnMonitor((blinkState and bgA or bgB))
- -- intentar stream si URL
- if audioURL ~= "" and startAudioStream(audioURL) then
- -- streaming
- else
- -- sonido repetitivo
- if not playLoudSoundOnce() then fallbackRedstoneBeep() end
- end
- elseif (not sig) and alarmOn then
- -- stop alarm
- alarmOn = false
- stopAudioStream()
- -- asegurar que cualquier redstone fallback está apagado
- pcall(redstone.setOutput, speakerSide, false)
- clearMonitorNow()
- end
- elseif ev[1] == "timer" then
- timerId = os.startTimer(1)
- if alarmOn then
- local now = os.clock()
- if now - lastBlink >= blinkInterval then
- blinkState = not blinkState
- lastBlink = now
- drawOnMonitor((blinkState and bgA or bgB))
- end
- if now - lastSound >= soundInterval then
- lastSound = now
- -- si estamos con stream (playAudio), no hacemos nada — el stream debería reproducirse por sí mismo
- if audioPlaying then
- -- opcional: no hacer nada
- else
- -- reproducir sonido fuerte repetido
- if not playLoudSoundOnce() then fallbackRedstoneBeep() end
- end
- end
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment