feat(kæde): ét flow pr. bygning, slutprodukter sælges straks (Sælg/Behold), tomme kædeflows foldes sammen; såmaskine ikke gødningsspreder (v1.61.4.0)

This commit is contained in:
2026-09-30 17:44:06 +02:00
parent d2970a1bda
commit 74537f7ec2
13 changed files with 297 additions and 40 deletions
+28 -5
View File
@@ -17,7 +17,7 @@ ADChain.LOG_PREFIX = "ADSmartPickup: kæde: "
-- Et afvist forslag vises igen, når manglen for afgrøden har ændret sig mere end dette.
ADChain.DISMISS_CHANGE = 0.25
ADChain.state = {byChain = {}, paused = {}, dismissed = {}, userOff = {}}
ADChain.state = {byChain = {}, paused = {}, dismissed = {}, userOff = {}, finalKeep = {}, soldByChain = {}}
ADChain.last = nil
-- {[nøgle] = true}: produktioner (ikke kædens) der var tændt ved sidste tick — til at se spillerens slukninger
ADChain.prevEnabled = nil
@@ -53,12 +53,14 @@ end
-- userOff = {[recipeKey] = true}: produktioner spilleren slukkede selv — kæden tænder dem ikke igen.
-- roots = {[recipeKey] = true} rødderne ved sidste tick (nil = ukendt, fx gem fra en ældre version).
function ADChain.newState()
return {byChain = {}, paused = {}, dismissed = {}, userOff = {}, roots = nil}
-- finalKeep = {[rodnøgle] = true}: slutproduktet beholdes (standard: sælg straks); soldByChain = {["rod|vare"] = true}
return {byChain = {}, paused = {}, dismissed = {}, userOff = {}, roots = nil, finalKeep = {}, soldByChain = {}}
end
function ADChain.stateToRecords(state)
local records = {byChain = sortedKeys(state.byChain), paused = sortedKeys(state.paused), userOff = sortedKeys(state.userOff), dismissed = {},
roots = state.roots ~= nil and sortedKeys(state.roots) or nil}
roots = state.roots ~= nil and sortedKeys(state.roots) or nil,
finalKeep = sortedKeys(state.finalKeep or {}), soldByChain = sortedKeys(state.soldByChain or {})}
local ids = {}
for id in pairs(state.dismissed or {}) do table.insert(ids, id) end
table.sort(ids)
@@ -75,6 +77,8 @@ function ADChain.stateFromRecords(records)
for _, key in ipairs(records.byChain or {}) do state.byChain[key] = true end
for _, key in ipairs(records.paused or {}) do state.paused[key] = true end
for _, key in ipairs(records.userOff or {}) do state.userOff[key] = true end
for _, key in ipairs(records.finalKeep or {}) do state.finalKeep[key] = true end
for _, key in ipairs(records.soldByChain or {}) do state.soldByChain[key] = true end
if records.roots ~= nil then
state.roots = {}
for _, key in ipairs(records.roots) do state.roots[key] = true end
@@ -378,7 +382,7 @@ function ADChain.evaluate(adEnv, act)
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), finalKeep = copySet(state.finalKeep or {}), data = data, fields = data.fields, fieldsIncomplete = data.fieldsIncomplete == true, titles = data.fillTitles, at = ADChain.now, switchCount = ADChain.switchCount,
dependency = dependency}
return ADChain.last
end
@@ -491,6 +495,13 @@ function ADChain.dismiss(fieldId)
return true
end
-- Slutprodukt for en kæde: keep = true -> "Behold", ellers "Sælg straks" (standard). Anvendes ved næste tick.
function ADChain.setFinalKeep(rootKey, keep)
if rootKey == nil then return end
ADChain.state.finalKeep[rootKey] = keep and true or nil
Logging.info(ADChain.LOG_PREFIX .. "%s: slutprodukt %s", tostring(rootKey), keep and "beholdes" or "sælges straks")
end
function ADChain.setPaused(rootKey, isPaused)
if rootKey == nil then return end
ADChain.state.paused[rootKey] = isPaused and true or nil
@@ -520,6 +531,12 @@ function ADChain.save()
for index, key in ipairs(records.userOff) do
xmlFile:setString(string.format("%s.userOff.recipe(%d)#key", ADChain.ROOT, index - 1), key)
end
for index, key in ipairs(records.finalKeep) do
xmlFile:setString(string.format("%s.finalKeep.root(%d)#key", ADChain.ROOT, index - 1), key)
end
for index, key in ipairs(records.soldByChain) do
xmlFile:setString(string.format("%s.soldByChain.output(%d)#key", ADChain.ROOT, index - 1), key)
end
if records.roots ~= nil then
xmlFile:setBool(ADChain.ROOT .. ".roots#known", true)
for index, key in ipairs(records.roots) do
@@ -547,7 +564,13 @@ function ADChain.load()
if path == nil or not fileExists(path) then return end
local xmlFile = XMLFile.load("ADSmartPickupChain", path)
if xmlFile == nil then return end
local records = {byChain = {}, paused = {}, userOff = {}, dismissed = {}}
local records = {byChain = {}, paused = {}, userOff = {}, dismissed = {}, finalKeep = {}, soldByChain = {}}
xmlFile:iterate(ADChain.ROOT .. ".finalKeep.root", function(_, key)
table.insert(records.finalKeep, xmlFile:getString(key .. "#key"))
end)
xmlFile:iterate(ADChain.ROOT .. ".soldByChain.output", function(_, key)
table.insert(records.soldByChain, xmlFile:getString(key .. "#key"))
end)
xmlFile:iterate(ADChain.ROOT .. ".byChain.recipe", function(_, key)
table.insert(records.byChain, xmlFile:getString(key .. "#key"))
end)