Stabilize boiler mapping and clutch fail-safe

This commit is contained in:
2026-07-16 21:44:44 +02:00
parent 484b6a5117
commit b347855349
2 changed files with 56 additions and 29 deletions
+47 -22
View File
@@ -1,11 +1,16 @@
-- Create boiler status board for CC:Tweaked.
-- All Create values are read through Advanced Peripherals Block Readers.
local EXPECTED_BOILERS = 3
local REFRESH_SECONDS = 1
local MIN_WIDTH = 38
local MIN_HEIGHT = 14
local CLUTCH_OUTPUT_SIDE = "right"
local CLUTCH_OUTPUT_SIDE = "left"
local BOILERS = {
{ label = "BOILER 1", position = { 11266, 64, 10810 } },
{ label = "BOILER 2", position = { 11260, 64, 10810 } },
{ label = "BOILER 3", position = { 11252, 64, 10810 } },
}
local clutchButton = { x1 = 0, x2 = 0, y = 0 }
@@ -64,6 +69,13 @@ local function samePosition(a, b)
and tonumber(a[3]) == tonumber(b[3])
end
local function positionKey(position)
if type(position) ~= "table" then return nil end
local x, y, z = tonumber(position[1]), tonumber(position[2]), tonumber(position[3])
if not x or not y or not z then return nil end
return ("%d,%d,%d"):format(x, y, z)
end
local function discoverReaders()
local boilers, networks = {}, {}
local names = peripheral.getNames()
@@ -78,7 +90,9 @@ local function discoverReaders()
local speed = getValueIgnoringCase(data, { "Speed" })
if type(boiler) == "table" then
boilers[#boilers + 1] = { name = name, data = data, boiler = boiler }
local position = getValueIgnoringCase(data, { "LastKnownPos", "Controller" })
local key = positionKey(position)
if key then boilers[key] = { name = name, data = data, boiler = boiler } end
elseif type(network) == "table" and tonumber(speed) then
networks[#networks + 1] = { name = name, data = data, network = network }
end
@@ -136,8 +150,10 @@ end
local function drawClutchButton(height)
local width = monitor.getSize()
local signal = redstone.getOutput(CLUTCH_OUTPUT_SIDE)
local label = signal and " CLUTCH SIGNAL: ON " or " CLUTCH SIGNAL: OFF "
-- With the external redstone-torch inverter, output ON means the clutch is
-- unpowered and production runs. Output OFF is the fail-safe stopped state.
local running = redstone.getOutput(CLUTCH_OUTPUT_SIDE)
local label = running and " PRODUCTION: RUNNING " or " PRODUCTION: STOPPED "
local x = math.max(1, math.floor((width - #label) / 2) + 1)
local y = math.max(13, height - 1)
@@ -149,15 +165,15 @@ local function drawClutchButton(height)
monitor.setBackgroundColor(colors.black)
monitor.write((" "):rep(width))
monitor.setCursorPos(x, y)
monitor.setBackgroundColor(signal and colors.orange or colors.gray)
monitor.setBackgroundColor(running and colors.lime or colors.red)
monitor.setTextColor(colors.black)
monitor.write(label)
monitor.setBackgroundColor(colors.black)
end
local function toggleClutchSignal()
local signal = redstone.getOutput(CLUTCH_OUTPUT_SIDE)
redstone.setOutput(CLUTCH_OUTPUT_SIDE, not signal)
local function toggleProduction()
local running = redstone.getOutput(CLUTCH_OUTPUT_SIDE)
redstone.setOutput(CLUTCH_OUTPUT_SIDE, not running)
end
local function render()
@@ -169,9 +185,10 @@ local function render()
monitor.clear()
center(1, "CREATE KRAFTWERK", colors.cyan)
for index = 1, EXPECTED_BOILERS do
local state, heatMode, color = readBoiler(boilers[index])
center(2 + index, ("BOILER %d %-7s %s"):format(index, state, heatMode), color)
for index, configuredBoiler in ipairs(BOILERS) do
local reader = boilers[positionKey(configuredBoiler.position)]
local state, heatMode, color = readBoiler(reader)
center(2 + index, ("%s %-7s %s"):format(configuredBoiler.label, state, heatMode), color)
end
center(7, "MAIN SHAFT", colors.cyan)
@@ -187,7 +204,7 @@ local function render()
end
drawClutchButton(height)
center(height, "Touch = Redstone umschalten", colors.gray)
center(height, "Touch = Produktion umschalten", colors.gray)
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
term.setCursorPos(1, 1)
@@ -206,16 +223,24 @@ end
safeRender()
local refreshTimer = os.startTimer(REFRESH_SECONDS)
while true do
local event, first, second, third = os.pullEvent()
if event == "timer" and first == refreshTimer then
safeRender()
refreshTimer = os.startTimer(REFRESH_SECONDS)
elseif event == "monitor_touch" then
local x, y = second, third
if y == clutchButton.y and x >= clutchButton.x1 and x <= clutchButton.x2 then
toggleClutchSignal()
local function run()
while true do
local event, first, second, third = os.pullEventRaw()
if event == "terminate" then
return
elseif event == "timer" and first == refreshTimer then
safeRender()
refreshTimer = os.startTimer(REFRESH_SECONDS)
elseif event == "monitor_touch" then
local x, y = second, third
if y == clutchButton.y and x >= clutchButton.x1 and x <= clutchButton.x2 then
toggleProduction()
safeRender()
end
end
end
end
local ok, reason = pcall(run)
redstone.setOutput(CLUTCH_OUTPUT_SIDE, false)
if not ok then error(reason, 0) end