local rs = require('libs/rs') local MAIN_DELAY_ON = 0.25 local MAIN_DELAY_OFF = 0 local SECONDARY_DELAY_ON = 0.75 local SECONDARY_DELAY_OFF = 0.25 local MAIN_INPUT_SIDE = 'top' local MAIN_OUTPUT_SIDE = 'left' local SECONDARY_INPUT_SIDE = 'back' local SECONDARY_OUTPUT_SIDE = 'front' local VERSION = '1.0.1' local function getMainColorsOrder() return { colors.white, colors.orange, colors.magenta, colors.lightBlue, colors.yellow, colors.lime, colors.pink, colors.gray, colors.lightGray, colors.cyan, colors.purple, colors.blue, colors.brown, colors.green, colors.red, colors.black } end local function getSecondaryColorsOrder() return { colors.white, colors.orange, colors.magenta } end local function switchOnLight(bundledOutput, colorsOrder, sleepTime) if sleepTime <= 0 then bundledOutput.setColorState(colors.combine(table.unpack(colorsOrder))) return end for _, color in pairs(colorsOrder) do bundledOutput.setOn(color) os.sleep(sleepTime) end end local function switchOffLight(bundledOutput, colorsOrder, sleepTime) if sleepTime <= 0 then bundledOutput.setColorState(0) return end for _, color in pairs(colorsOrder) do bundledOutput.setOff(color) os.sleep(sleepTime) end end local mainLoopQueue = {} local function applyMainCommand(bundledOutput, lightIsOn) local mainColorsOrder = getMainColorsOrder() if lightIsOn then switchOnLight(bundledOutput, mainColorsOrder, MAIN_DELAY_ON) else switchOffLight(bundledOutput, mainColorsOrder, MAIN_DELAY_OFF) end end local function applySecondaryCommand(bundledOutput, lightIsOn) local secondaryColorsOrder = getSecondaryColorsOrder() if lightIsOn then switchOnLight(bundledOutput, secondaryColorsOrder, SECONDARY_DELAY_ON) else switchOffLight(bundledOutput, secondaryColorsOrder, SECONDARY_DELAY_OFF) end end local function mainLoop() local mainOutput = rs.createBundledOutput(MAIN_OUTPUT_SIDE) local secondaryOutput = rs.createBundledOutput(SECONDARY_OUTPUT_SIDE) while true do local _, typeOfRoom, lightIsOn = os.pullEvent('light_command') table.remove(mainLoopQueue, 1) if typeOfRoom == 'main' then applyMainCommand(mainOutput, lightIsOn) elseif typeOfRoom == 'secondary' then applySecondaryCommand(mainOutput, lightIsOn) else error('unknown type of room "' .. tostring(typeOfRoom) .. '"', 0) end local event = table.remove(mainLoopQueue, 1) if event and event.typeOfRoom == 'main' then applyMainCommand(mainOutput, event.lightIsOn) elseif event and event.typeOfRoom == 'secondary' then applySecondaryCommand(secondaryOutput, event.lightIsOn) end end end local function redstoneLoop() local mainState = nil local secondaryState = nil while true do local newMainState = redstone.getInput(MAIN_INPUT_SIDE) local newSecondaryState = redstone.getInput(SECONDARY_INPUT_SIDE) if mainState ~= newMainState then mainState = newMainState table.insert(mainLoopQueue, { typeOfRoom = 'main', lightIsOn = newMainState }) os.queueEvent('light_command', 'main', newMainState) end if secondaryState ~= newSecondaryState then secondaryState = newSecondaryState table.insert(mainLoopQueue, { typeOfRoom = 'secondary', lightIsOn = newSecondaryState }) os.queueEvent('light_command', 'secondary', newSecondaryState) end os.pullEvent('redstone') end end print('> Starting light server v' .. VERSION) parallel.waitForAny(mainLoop, redstoneLoop)