feat(kæde): advarsel når en fabrik gården er afhængig af slukkes
Slukker spilleren en produktion, hvis vare et tændt flow kører (manuel vare eller målet tager den i auto), en stald æder eller en aktiv kæde bruger, kommer én besked pr. slukning med brugere og lagerdage, og en rød post 'Slukket men nødvendig' i Kræver handling og statusvinduet så længe den er slukket og nødvendig. Ingen advarsel når en anden tændt produktion dækker, lageret rækker over 60 dage, kæden selv slukkede den eller den var slukket ved indlæsning. Tjekket kører i kædens tick også uden kæder; ren logik i adDependency.lua.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
-- AD Chain (kæde-kørsel)
|
||||
-- Hvert minut (efter opstartsfristen): læs gården (ADChainData), byg kæden (ADChainModel), find manglende
|
||||
-- afgrøder (ADCropPlan) og lad ADChainRun skifte frie marker, tænde/slukke mellemled og oprette/stoppe flows.
|
||||
-- Samme tick advarer (ADDependency), når spilleren slukker en produktion gården er afhængig af — også uden kæder.
|
||||
-- Resultatet gemmes i ADChain.last til Kæder-fanen. Tilstanden (byChain, pausede rødder, afviste forslag,
|
||||
-- userOff og det sidst kendte sæt af rødder) gemmes i ADSmartPickup_chain.xml under spillets gem.
|
||||
-- Spiladgang kun inde i funktioner (filen dofile's i test).
|
||||
@@ -31,6 +32,9 @@ ADChain.timer = 0
|
||||
ADChain.collectFailed = false
|
||||
-- {[rodnøgle|vare|art] = true}: manglende led der allerede er meldt som besked (kun i hukommelsen; nulstilles ved indlæsning)
|
||||
ADChain.problemKeys = {}
|
||||
-- {[nøgle] = true}: produktioner (ikke kædens) der var tændt ved sidste afhængighedstjek (kun kædens tick, kun på
|
||||
-- hele data). nil efter indlæsning: det der allerede er slukket ved første tjek, advares der ikke om.
|
||||
ADChain.depPrevEnabled = nil
|
||||
|
||||
local function contains(list, value)
|
||||
for _, item in ipairs(list or {}) do if item == value then return true end end
|
||||
@@ -320,6 +324,30 @@ local function applyReconcile(state, data)
|
||||
ADChain.afterLoad = false
|
||||
end
|
||||
|
||||
-- Afhængighedstjek (spec afsnit 8): nye slukninger (kun act) og "Slukket men nødvendig"-posterne. Uafhængigt af
|
||||
-- kædens rødder og af markscanningen; springes over ved læsefejl (så beholdes forrige poster, og slukninger i
|
||||
-- mellemtiden meldes ved næste hele tjek).
|
||||
-- Produktioner kæden selv er ved at tænde (plan.prod.enable), er ikke "slukket men nødvendig".
|
||||
local function dependencyCheck(data, plan, runs, act, previous)
|
||||
if ADDependency == nil or ADChainData.dependencyInputs == nil then return nil end
|
||||
if data.readFailed then
|
||||
return previous ~= nil and {warnings = {}, offNeeded = previous.offNeeded or {}} or nil
|
||||
end
|
||||
local inputs = ADChainData.dependencyInputs(data, plan.chain, runs)
|
||||
local enabling, recipes = {}, {}
|
||||
for _, key in ipairs(plan.prod ~= nil and plan.prod.enable or {}) do enabling[key] = true end
|
||||
for _, recipe in ipairs(data.recipes or {}) do
|
||||
if not enabling[recipe.key] then table.insert(recipes, recipe) end
|
||||
end
|
||||
local prev = act and ADChain.depPrevEnabled or nil
|
||||
local result = {
|
||||
warnings = ADDependency.warnings(prev, recipes, inputs.needed, inputs.stockDays, inputs.capacity, inputs.demand),
|
||||
offNeeded = ADDependency.offNeeded(recipes, inputs.needed, inputs.stockDays, inputs.capacity, inputs.demand),
|
||||
}
|
||||
if act then ADChain.depPrevEnabled = ADDependency.enabledKeys(data.recipes) end
|
||||
return result
|
||||
end
|
||||
|
||||
-- act = true: udfør handlingerne (tick). Uden act kun en frisk visning (GUI).
|
||||
function ADChain.evaluate(adEnv, act)
|
||||
local state = ADChain.state
|
||||
@@ -341,11 +369,17 @@ function ADChain.evaluate(adEnv, act)
|
||||
end
|
||||
if act and ADChainRun ~= nil then ADChainRun.apply(adEnv, data, result) end
|
||||
local runs = ADChain.runsView(ADRunsController.store.runs)
|
||||
local okDep, dependency = pcall(dependencyCheck, data, result, runs, act, ADChain.last ~= nil and ADChain.last.dependency or nil)
|
||||
if not okDep then
|
||||
Logging.warning(ADChain.LOG_PREFIX .. "afhængighedstjek fejlede: %s", tostring(dependency))
|
||||
dependency = nil
|
||||
end
|
||||
local paused = {}
|
||||
for key in pairs(state.paused) do paused[key] = true end
|
||||
ADChain.last = {chain = result.chain, shortages = result.shortages, actions = result.actions, edges = result.edges,
|
||||
missingFlows = ADChainActions.missingFlows(result.edges, runs), flowStatus = ADChain.flowStatus(result.edges, runs, ADChain.noVehicle),
|
||||
paused = paused, userOff = copySet(state.userOff), data = data, fields = data.fields, fieldsIncomplete = data.fieldsIncomplete == true, titles = data.fillTitles, at = ADChain.now, switchCount = ADChain.switchCount}
|
||||
paused = paused, userOff = copySet(state.userOff), data = data, fields = data.fields, fieldsIncomplete = data.fieldsIncomplete == true, titles = data.fillTitles, at = ADChain.now, switchCount = ADChain.switchCount,
|
||||
dependency = dependency}
|
||||
return ADChain.last
|
||||
end
|
||||
|
||||
@@ -378,6 +412,23 @@ function ADChain.notifyProblems(last)
|
||||
return #fresh
|
||||
end
|
||||
|
||||
-- Én besked pr. slukning af en nødvendig produktion (kun fra tick; advarslerne tømmes, når de er meldt).
|
||||
function ADChain.notifyDependencies(last)
|
||||
local dependency = last ~= nil and last.dependency or nil
|
||||
if dependency == nil or #(dependency.warnings or {}) == 0 or ADChain.now < ADChain.STARTUP_GRACE_MS then return 0 end
|
||||
local warnings = dependency.warnings
|
||||
dependency.warnings = {}
|
||||
if ADFieldJobs == nil or ADFieldJobs.notify == nil then return 0 end
|
||||
local textOf = function(key) return g_i18n ~= nil and g_i18n:getText(key) or key end
|
||||
local titleOf = function(name) return tostring((last.titles or {})[name] or name) end
|
||||
for _, warning in ipairs(warnings) do
|
||||
local text = ADDependency.notifyText(warning, textOf, titleOf)
|
||||
Logging.info(ADChain.LOG_PREFIX .. "nødvendig produktion slukket: %s", text)
|
||||
ADFieldJobs.notify(text, true)
|
||||
end
|
||||
return #warnings
|
||||
end
|
||||
|
||||
function ADChain.tick(adEnv, dt)
|
||||
if adEnv == nil then return end
|
||||
ADChain.now = ADChain.now + (dt or 0)
|
||||
@@ -387,6 +438,8 @@ function ADChain.tick(adEnv, dt)
|
||||
local last = ADChain.evaluate(adEnv, true)
|
||||
local ok, err = pcall(ADChain.notifyProblems, last)
|
||||
if not ok then Logging.warning(ADChain.LOG_PREFIX .. "besked om manglende led fejlede: %s", tostring(err)) end
|
||||
local okDep, errDep = pcall(ADChain.notifyDependencies, last)
|
||||
if not okDep then Logging.warning(ADChain.LOG_PREFIX .. "advarsel om slukket produktion fejlede: %s", tostring(errDep)) end
|
||||
end
|
||||
|
||||
-- ---- GUI-handlinger ----
|
||||
@@ -482,6 +535,7 @@ function ADChain.load()
|
||||
ADChain.noVehicle = {}
|
||||
ADChain.prevEnabled, ADChain.afterLoad = nil, true
|
||||
ADChain.problemKeys = {}
|
||||
ADChain.depPrevEnabled = nil
|
||||
local path = getPath()
|
||||
if path == nil or not fileExists(path) then return end
|
||||
local xmlFile = XMLFile.load("ADSmartPickupChain", path)
|
||||
|
||||
Reference in New Issue
Block a user