Lock Create jobs until their outputs return

This commit is contained in:
2026-07-18 01:49:08 +02:00
parent b0e9b3ed23
commit d23a39dbfa
+125 -16
View File
@@ -3,6 +3,7 @@
local REFRESH_SECONDS = 1.0 local REFRESH_SECONDS = 1.0
local CONFIRM_SECONDS = 6.0 local CONFIRM_SECONDS = 6.0
local JOB_TIMEOUT_SECONDS = 180.0
local LOG_FILE = "factory_test_log.txt" local LOG_FILE = "factory_test_log.txt"
local trackedItems = { local trackedItems = {
@@ -14,36 +15,62 @@ local trackedItems = {
{ id = "minecraft:oak_planks", label = "Oak Planks" }, { id = "minecraft:oak_planks", label = "Oak Planks" },
{ id = "alltheores:zinc_clump", label = "Zinc Clumps" }, { id = "alltheores:zinc_clump", label = "Zinc Clumps" },
{ id = "alltheores:zinc_nugget", label = "Zinc Nuggets" }, { id = "alltheores:zinc_nugget", label = "Zinc Nuggets" },
{ id = "create:shaft", label = "Shafts" },
} }
local actions = { local actions = {
{ {
id = "crush_asurine", id = "crush_asurine",
label = "64 ASURINE -> crushing", label = "64 ASURINE CRUSHEN",
lockKey = "crushing",
address = "crushing", address = "crushing",
item = "create:asurine", item = "create:asurine",
count = 64, inputCount = 64,
completion = {
mode = "any_increase",
outputs = { "alltheores:zinc_clump", "alltheores:zinc_nugget" },
},
}, },
{ {
id = "strip_oak", id = "strip_oak",
label = "64 OAK LOGS -> saw:2", label = "64 STRIPPED OAK",
lockKey = "saw:2",
address = "saw:2", address = "saw:2",
item = "minecraft:oak_log", item = "minecraft:oak_log",
count = 64, inputCount = 64,
completion = {
mode = "expected",
output = "minecraft:stripped_oak_log",
outputPerInput = 1,
},
}, },
{ {
id = "planks_oak", id = "planks_oak",
label = "64 STRIPPED -> saw:2", label = "64 OAK PLANKS",
lockKey = "saw:2",
address = "saw:2", address = "saw:2",
item = "minecraft:stripped_oak_log", item = "minecraft:stripped_oak_log",
count = 64, -- Create yields 6 planks per stripped log. 11 inputs produce 66 planks.
inputCount = 11,
completion = {
mode = "expected",
output = "minecraft:oak_planks",
outputPerInput = 6,
},
}, },
{ {
id = "shafts", id = "shafts",
label = "64 ALLOY -> saw:1", label = "64 SHAFTS",
lockKey = "saw:1",
address = "saw:1", address = "saw:1",
item = "create:andesite_alloy", item = "create:andesite_alloy",
count = 64, -- Create yields 6 shafts per Andesite Alloy. 11 inputs produce 66 shafts.
inputCount = 11,
completion = {
mode = "expected",
output = "create:shaft",
outputPerInput = 6,
},
}, },
} }
@@ -73,6 +100,7 @@ monitor.setTextScale(0.5)
local stock = {} local stock = {}
local buttons = {} local buttons = {}
local messages = {} local messages = {}
local jobs = {}
local armedAction = nil local armedAction = nil
local armedUntil = 0 local armedUntil = 0
local statusText = "Bereit - nur Testbetrieb, keine Redstone-Steuerung" local statusText = "Bereit - nur Testbetrieb, keine Redstone-Steuerung"
@@ -124,6 +152,39 @@ local function refreshStock()
return true return true
end end
local function jobComplete(job)
if job.completion.mode == "expected" then
local current = stock[job.completion.output] or 0
return current >= job.baseline[job.completion.output] + job.expectedOutput
end
if job.completion.mode == "any_increase" then
for _, output in ipairs(job.completion.outputs) do
if (stock[output] or 0) > (job.baseline[output] or 0) then
return true
end
end
end
return false
end
local function updateJobs()
for lockKey, job in pairs(jobs) do
if jobComplete(job) then
statusText = "FERTIG: " .. job.label
statusColor = colors.lime
appendLog(statusText)
jobs[lockKey] = nil
elseif os.clock() - job.startedAt > JOB_TIMEOUT_SECONDS and not job.timedOut then
job.timedOut = true
statusText = "TIMEOUT: " .. job.label .. " - Anlage pruefen"
statusColor = colors.red
appendLog(statusText)
end
end
end
local function writeAt(x, y, text, foreground, background) local function writeAt(x, y, text, foreground, background)
local width, height = monitor.getSize() local width, height = monitor.getSize()
if y < 1 or y > height or x > width then if y < 1 or y > height or x > width then
@@ -144,11 +205,15 @@ end
local function drawButton(action, x1, y1, x2, y2) local function drawButton(action, x1, y1, x2, y2)
local isArmed = armedAction == action.id and os.clock() <= armedUntil local isArmed = armedAction == action.id and os.clock() <= armedUntil
local available = stock[action.item] or 0 local available = stock[action.item] or 0
local enabled = available > 0 local activeJob = jobs[action.lockKey]
local enabled = available >= action.inputCount and activeJob == nil
local background = colors.gray local background = colors.gray
local foreground = colors.lightGray local foreground = colors.lightGray
if enabled then if activeJob then
background = activeJob.timedOut and colors.red or colors.orange
foreground = activeJob.timedOut and colors.white or colors.black
elseif enabled then
background = isArmed and colors.orange or colors.green background = isArmed and colors.orange or colors.green
foreground = isArmed and colors.black or colors.white foreground = isArmed and colors.black or colors.white
end end
@@ -158,10 +223,12 @@ local function drawButton(action, x1, y1, x2, y2)
end end
local label = action.label local label = action.label
if isArmed then if activeJob then
label = (activeJob.timedOut and "TIMEOUT: " or "IN ARBEIT: ") .. activeJob.label
elseif isArmed then
label = "NOCHMALS: " .. label label = "NOCHMALS: " .. label
elseif not enabled then elseif not enabled then
label = "KEIN BESTAND: " .. label label = "ZU WENIG INPUT: " .. label
end end
local labelX = math.max(x1, math.floor((x1 + x2 - #label) / 2)) local labelX = math.max(x1, math.floor((x1 + x2 - #label) / 2))
@@ -174,6 +241,7 @@ local function drawButton(action, x1, y1, x2, y2)
x2 = x2, x2 = x2,
y2 = y2, y2 = y2,
enabled = enabled, enabled = enabled,
activeJob = activeJob,
} }
end end
@@ -228,9 +296,18 @@ end
local function submit(action) local function submit(action)
local filter = { local filter = {
name = action.item, name = action.item,
_requestCount = action.count, _requestCount = action.inputCount,
} }
local baseline = {}
if action.completion.mode == "expected" then
baseline[action.completion.output] = stock[action.completion.output] or 0
else
for _, output in ipairs(action.completion.outputs) do
baseline[output] = stock[output] or 0
end
end
local ok, sent = pcall( local ok, sent = pcall(
peripheral.call, peripheral.call,
tickerName, tickerName,
@@ -247,8 +324,34 @@ local function submit(action)
end end
local amount = tonumber(sent) or 0 local amount = tonumber(sent) or 0
statusText = formatNumber(amount) .. "x " .. action.item .. " -> " .. action.address if amount <= 0 then
statusColor = amount > 0 and colors.lime or colors.orange statusText = "NICHT GESENDET: " .. action.label
statusColor = colors.orange
appendLog(statusText)
refreshStock()
return
end
local expectedOutput = 0
if action.completion.mode == "expected" then
expectedOutput = amount * action.completion.outputPerInput
end
jobs[action.lockKey] = {
label = action.label,
actionId = action.id,
address = action.address,
inputItem = action.item,
inputSent = amount,
completion = action.completion,
baseline = baseline,
expectedOutput = expectedOutput,
startedAt = os.clock(),
timedOut = false,
}
statusText = "GESTARTET: " .. action.label .. " (" .. formatNumber(amount) .. " Input)"
statusColor = colors.orange
appendLog(statusText) appendLog(statusText)
refreshStock() refreshStock()
end end
@@ -256,8 +359,13 @@ end
local function handleTouch(x, y) local function handleTouch(x, y)
for _, button in ipairs(buttons) do for _, button in ipairs(buttons) do
if x >= button.x1 and x <= button.x2 and y >= button.y1 and y <= button.y2 then if x >= button.x1 and x <= button.x2 and y >= button.y1 and y <= button.y2 then
if button.activeJob then
statusText = "Auftrag laeuft bereits: " .. button.activeJob.label
statusColor = button.activeJob.timedOut and colors.red or colors.orange
return
end
if not button.enabled then if not button.enabled then
statusText = "Kein passender Rohstoff im Stock-Ticker-Netz" statusText = "Zu wenig Rohstoff fuer diesen Auftrag"
statusColor = colors.orange statusColor = colors.orange
appendLog(statusText) appendLog(statusText)
return return
@@ -300,6 +408,7 @@ while true do
statusColor = colors.gray statusColor = colors.gray
end end
refreshStock() refreshStock()
updateJobs()
render() render()
refreshTimer = os.startTimer(REFRESH_SECONDS) refreshTimer = os.startTimer(REFRESH_SECONDS)
elseif event == "peripheral_detach" or event == "peripheral" then elseif event == "peripheral_detach" or event == "peripheral" then