Track actual scheduler output arrivals
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
-- ATM10 Create factory scheduler V1
|
||||
-- Persistent jobs, dependency planning, progress-aware retries and diagnostics.
|
||||
|
||||
local VERSION = "1.0.0"
|
||||
local VERSION = "1.0.1"
|
||||
local REFRESH_SECONDS = 1
|
||||
local CONFIRM_SECONDS = 6
|
||||
local DRAIN_SECONDS = 60
|
||||
@@ -128,8 +128,18 @@ local function loadState()
|
||||
state.version, state.nextJobId = state.version or 1, state.nextJobId or 1
|
||||
state.mode, state.jobs, state.errors = state.mode or "MANUAL", state.jobs or {}, state.errors or {}
|
||||
for _, job in ipairs(state.jobs) do
|
||||
job.lastObserved, job.baseline = job.lastObserved or {}, job.baseline or {}
|
||||
local hadArrivalCounter = type(job.arrived) == "table"
|
||||
job.lastObserved, job.baseline, job.arrived = job.lastObserved or {}, job.baseline or {}, job.arrived or {}
|
||||
job.retries, job.status = job.retries or 0, job.status or "WAITING"
|
||||
-- One-time migration of jobs created by V1.0.0.
|
||||
if not hadArrivalCounter and (job.progress or 0) > 0 then
|
||||
local recipe = RECIPES[job.recipeId]
|
||||
if recipe and recipe.output then
|
||||
job.arrived[recipe.output] = job.progress
|
||||
elseif recipe and recipe.outputs and recipe.outputs[1] then
|
||||
job.arrived[recipe.outputs[1]] = job.progress
|
||||
end
|
||||
end
|
||||
job.lastProgressAt, job.phaseStartedAt = epoch(), epoch()
|
||||
end
|
||||
-- Timers were deliberately rebased above; begin a fresh pause window too.
|
||||
@@ -177,12 +187,16 @@ local function stationBusy(station, exceptJob)
|
||||
end
|
||||
|
||||
local function produced(job, item)
|
||||
return math.max(0, (stock[item] or 0) - (job.baseline[item] or 0))
|
||||
-- Count real positive arrivals. Unlike a stock difference this never drops
|
||||
-- when another factory step consumes the output while the job is running.
|
||||
return math.max(0, (job.arrived and job.arrived[item]) or 0)
|
||||
end
|
||||
|
||||
local function setBaseline(job, item)
|
||||
if job.baseline[item] == nil then
|
||||
job.baseline[item], job.lastObserved[item] = stock[item] or 0, stock[item] or 0
|
||||
job.arrived = job.arrived or {}
|
||||
job.arrived[item] = job.arrived[item] or 0
|
||||
end
|
||||
end
|
||||
|
||||
@@ -216,13 +230,20 @@ end
|
||||
|
||||
local function observeItems(job, items)
|
||||
local changed = false
|
||||
job.arrived = job.arrived or {}
|
||||
for _, item in ipairs(items) do
|
||||
local current = stock[item] or 0
|
||||
if current > (job.lastObserved[item] or current) then changed = true end
|
||||
local previous = job.lastObserved[item]
|
||||
if previous == nil then previous = current end
|
||||
if current > previous then
|
||||
job.arrived[item] = (job.arrived[item] or 0) + (current - previous)
|
||||
changed = true
|
||||
end
|
||||
job.lastObserved[item] = current
|
||||
end
|
||||
if changed then
|
||||
job.lastProgressAt, job.drainStartedAt, job.warned = epoch(), epoch(), false
|
||||
saveState()
|
||||
end
|
||||
return changed
|
||||
end
|
||||
@@ -303,7 +324,8 @@ local function dispatchZincWashing(job, remaining)
|
||||
if sent <= 0 then failJob(job, "Zinc-Clump-Versand fehlgeschlagen: " .. tostring(err or "unbekannt")) return end
|
||||
job.activeStation, job.phase, job.status = "fan:washing", "WASHING", "RUNNING"
|
||||
job.lastBatchInput, job.phaseStartedAt, job.lastProgressAt, job.warned = sent, epoch(), epoch(), false
|
||||
job.phaseOutputBaseline, job.phaseExpected = stock["alltheores:zinc_nugget"] or 0, sent * 9
|
||||
job.phaseOutputBaseline = produced(job, "alltheores:zinc_nugget")
|
||||
job.phaseExpected = sent * 9
|
||||
logEvent("#" .. job.id .. " Teilauftrag: " .. sent .. " Clumps waschen", colors.orange) saveState()
|
||||
end
|
||||
|
||||
@@ -327,7 +349,7 @@ local function updateZinc(job)
|
||||
if job.phase == "CRUSHING" then
|
||||
job.status, job.phase, job.lastProgressAt = "WAITING", "PLAN", epoch() saveState()
|
||||
elseif job.phase == "WASHING" then
|
||||
local phaseGain = math.max(0, (stock["alltheores:zinc_nugget"] or 0) - (job.phaseOutputBaseline or 0))
|
||||
local phaseGain = math.max(0, produced(job, "alltheores:zinc_nugget") - (job.phaseOutputBaseline or 0))
|
||||
if phaseGain >= (job.phaseExpected or 0) then
|
||||
-- Batch arrived completely, but the parent still needs more: replan.
|
||||
job.status, job.phase, job.lastProgressAt = "WAITING", "PLAN", epoch()
|
||||
@@ -356,7 +378,7 @@ local function newJob(recipeId)
|
||||
id = state.nextJobId, recipeId = recipeId, status = "WAITING",
|
||||
phase = recipe.planner and "PLAN" or "NORMAL",
|
||||
targetCount = recipe.targetCount or recipe.outputCount or 1,
|
||||
baseline = {}, lastObserved = {}, progress = 0, retries = 0,
|
||||
baseline = {}, lastObserved = {}, arrived = {}, progress = 0, retries = 0,
|
||||
createdAt = epoch(), lastProgressAt = epoch(), phaseStartedAt = epoch(),
|
||||
}
|
||||
state.nextJobId = state.nextJobId + 1
|
||||
@@ -416,9 +438,13 @@ local function drawStock(width)
|
||||
end
|
||||
|
||||
local function progressText(job)
|
||||
local recipe = RECIPES[job.recipeId]
|
||||
local idle = math.max(0, epoch() - (job.lastProgressAt or epoch()))
|
||||
if recipe and recipe.completion == "activity" then
|
||||
return formatNumber(job.progress or 0) .. " ANGEKOMMEN " .. tostring(job.phase) .. " " .. idle .. "s"
|
||||
end
|
||||
local target, progress = math.max(1, job.targetCount or 1), math.min(job.targetCount or 1, job.progress or 0)
|
||||
local percent = math.floor(progress * 1000 / target) / 10
|
||||
local idle = math.max(0, epoch() - (job.lastProgressAt or epoch()))
|
||||
return formatNumber(progress) .. "/" .. formatNumber(target) .. " " .. percent .. "% " .. tostring(job.phase) .. " " .. idle .. "s"
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user