diff --git a/FS25_ADSmartPickup/adChain.lua b/FS25_ADSmartPickup/adChain.lua
index 84be85d..b23c890 100644
--- a/FS25_ADSmartPickup/adChain.lua
+++ b/FS25_ADSmartPickup/adChain.lua
@@ -270,9 +270,13 @@ local function plan(data, state)
protected = ADChainModel.build(ADChain.modelRecipes(data.recipes, {}, state.userOff), data.husbandry, data.crops).needRecipes
end
local used = ADChain.unionFruits(data.usedFruits, chain.fieldDemand)
- local shortages = ADCropPlan.shortages(chain.fieldDemand, data.stock, data.fields, data.yields)
- state.dismissed = ADChain.pruneDismissed(state.dismissed, shortages)
- local actions = ADCropPlan.choose(shortages, data.fields, used, data.yields, data.prices, ADChain.dismissedFruits(state.dismissed))
+ -- ufuldstændig markliste: udbuddet ville være undervurderet -> ingen mangler, forslag eller markskift endnu
+ local shortages, actions = {}, {}
+ if not data.fieldsIncomplete then
+ shortages = ADCropPlan.shortages(chain.fieldDemand, data.stock, data.fields, data.yields)
+ state.dismissed = ADChain.pruneDismissed(state.dismissed, shortages)
+ actions = ADCropPlan.choose(shortages, data.fields, used, data.yields, data.prices, ADChain.dismissedFruits(state.dismissed))
+ end
-- de ægte opskrifter (ikke kopien): en pauset rod er stadig tændt og må ikke "tændes" og overtages af kæden
local prod = ADChainActions.productions(data.recipes, chain.needRecipes, protected)
return {chain = chain, shortages = shortages, actions = actions, prod = prod, edges = ADChainActions.edges(chain)}
@@ -318,7 +322,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, data = data, fields = data.fields, titles = data.fillTitles, at = ADChain.now, switchCount = ADChain.switchCount}
+ paused = paused, data = data, fields = data.fields, fieldsIncomplete = data.fieldsIncomplete == true, titles = data.fillTitles, at = ADChain.now, switchCount = ADChain.switchCount}
return ADChain.last
end
diff --git a/FS25_ADSmartPickup/adChainData.lua b/FS25_ADSmartPickup/adChainData.lua
index a4b5789..6d2b486 100644
--- a/FS25_ADSmartPickup/adChainData.lua
+++ b/FS25_ADSmartPickup/adChainData.lua
@@ -187,7 +187,12 @@ local function readUsedFruits(data, adEnv, farmId, nameOf)
if not ok then failed(data, "rates", "staldforbrug kunne ikke læses: %s", tostring(err)) end
end
+-- Markscanningen har ikke nået alle marker endnu (efter indlæsning ~én mark pr. 2 s): marklisten er ufuldstændig,
+-- så udbud undervurderes -> fieldsIncomplete (kæden rører ingen marker) og partial (intet slukkes/stoppes).
local function readFields(data)
+ if ADFields.isScanComplete ~= nil and not ADFields.isScanComplete() then
+ data.partial, data.fieldsIncomplete = true, true
+ end
for _, info in ipairs(ADFields.list() or {}) do
local ok, entry = pcall(function()
local field = ADFieldJobs.getField(info.id)
@@ -208,7 +213,8 @@ end
-- ---- samlet ----
-- byChain = {[recipeKey] = true} for produktioner kæden selv har tændt (ikke rødder).
--- data.partial = true når noget ikke kunne læses i dette kald.
+-- data.partial = true når noget ikke kunne læses i dette kald; data.fieldsIncomplete = true mens markscanningen
+-- ikke har nået alle marker.
function ADChainData.collect(adEnv, farmId, byChain)
local data = {recipes = {}, husbandry = {}, crops = {}, stock = {}, fields = {}, yields = {}, prices = {},
usedFruits = {}, points = {}, fillTitles = {}, fillIndex = {}}
diff --git a/FS25_ADSmartPickup/adChainView.lua b/FS25_ADSmartPickup/adChainView.lua
index 51d94b7..b489b67 100644
--- a/FS25_ADSmartPickup/adChainView.lua
+++ b/FS25_ADSmartPickup/adChainView.lua
@@ -2,7 +2,7 @@
-- Rækkerne til fanen Kæder ud fra ADChain.last. Hver rod er foldet sammen som standard (én linje med samlet
-- status + antal forslag); foldet ud vises varerne rekursivt (kilde, behov pr. måned, status, lager). Forslag
-- vises altid (under roden eller under afgrøden). Pausede rødder (som modellen ikke længere ser som rødder)
--- får en grå linje med [Genoptag]. Nederst frie marker + antal automatiske skift. Ingen spiladgang:
+-- får en grå linje med [Genoptag]. Nederst frie marker + antal automatiske skift (+ "marker scannes endnu"). Ingen spiladgang:
-- titleOf(navn) -> titel, fmt(liter) -> kompakt tal, textOf(l10n-nøgle) -> tekst gives udefra.
-- Række: {kind="header"|"root"|"node"|"suggest"|"auto"|"info"|"empty", indent, level, cells={c1..c5}, text,
-- actions={[celle]={kind="approve"|"dismiss"|"pause"|"resume", fieldId|rootKey}}, toggle=rootKey, fillType}
@@ -19,7 +19,7 @@ ADChainView.TIGHT_MONTHS = 3
ADChainView.TEXT_KEYS = {"spu_chain_empty", "spu_chain_approve", "spu_chain_dismiss", "spu_chain_auto",
"spu_chain_flowOk", "spu_chain_flowMissing", "spu_chain_flowNone", "spu_chain_flowStopped", "spu_chain_bottleneck",
"spu_chain_buy", "spu_chain_cycle", "spu_chain_fieldShort", "spu_chain_tight", "spu_chain_noField", "spu_chain_buySource",
- "spu_chain_pause", "spu_chain_resume", "spu_chain_rootOk", "spu_chain_rootError", "spu_chain_rootWaiting",
+ "spu_chain_pause", "spu_chain_resume", "spu_chain_scanning", "spu_chain_rootOk", "spu_chain_rootError", "spu_chain_rootWaiting",
"spu_chain_rootPaused", "spu_chain_rootSummary", "spu_chain_free", "spu_chain_switches", "spu_chain_gone", "spu_chain_col_item",
"spu_chain_col_source", "spu_chain_col_perMonth", "spu_chain_col_status", "spu_chain_col_stock"}
@@ -270,6 +270,7 @@ local function footerRows(rows, last, textOf)
local freeText = string.format(textOf("spu_chain_free"), #names > 0 and table.concat(names, ", ") or "-")
table.insert(rows, {kind = "info", indent = 0, text = freeText})
table.insert(rows, {kind = "info", indent = 0, text = string.format(textOf("spu_chain_switches"), last.switchCount or 0)})
+ if last.fieldsIncomplete then table.insert(rows, {kind = "info", indent = 0, text = textOf("spu_chain_scanning")}) end
end
-- expanded = {[rodnøgle] = true} for udfoldede rødder (alle andre er foldet sammen).
diff --git a/FS25_ADSmartPickup/adFields.lua b/FS25_ADSmartPickup/adFields.lua
index f5e7450..a5c0a38 100644
--- a/FS25_ADSmartPickup/adFields.lua
+++ b/FS25_ADSmartPickup/adFields.lua
@@ -10,6 +10,9 @@ ADFields.MARKER_MAX_DISTANCE = 400
ADFields.cache = {}
ADFields.order = {}
ADFields.scanIndex = 0
+-- {[markId] = true}: marker hvis scanning er afsluttet (med resultat) eller fejlede — til isScanComplete
+ADFields.scanFailed = {}
+ADFields.ownedDone = false
ADFields.mowable = nil
-- markliste og F-markører ændrer sig sjældent: slås op igen efter så lang tid (ikke hvert scan)
ADFields.OWNED_REFRESH_MS = 30000
@@ -566,9 +569,20 @@ local function finishOwnedScan(scan)
if not ids[id] then ADFields.cache[id] = nil end
end
ADFields.order = scan.result
+ ADFields.ownedDone = true
ADFields.listCache = nil
end
+-- Har scanningen nået alle ejede marker mindst én gang (resultat i cachen, eller scanningen fejlede)?
+-- Indtil da er marklisten ufuldstændig (efter indlæsning fyldes den ~én mark pr. SCAN_INTERVAL_MS).
+function ADFields.isScanComplete()
+ if not ADFields.ownedDone then return false end
+ for _, entry in ipairs(ADFields.order) do
+ if ADFields.cache[entry.id] == nil and not ADFields.scanFailed[entry.id] then return false end
+ end
+ return true
+end
+
-- Kaldes HVERT frame: kører én opgave af den aktuelle scanning. En ny mark påbegyndes højst hvert
-- SCAN_INTERVAL_MS; marklisten opdateres hvert OWNED_REFRESH_MS.
ADFields.SCAN_INTERVAL_MS = 2000
@@ -612,6 +626,7 @@ function ADFields.scanStep(adEnv, farmId, now)
local ok, err = pcall(task)
if not ok then
Logging.warning("ADSmartPickup: F%s kunne ikke scannes: %s", tostring(scan.id or "-"), tostring(err))
+ if scan.id ~= nil then ADFields.scanFailed[scan.id] = true end
ADFields.activeScan = nil
return
end
@@ -628,7 +643,10 @@ function ADFields.scanStep(adEnv, farmId, now)
else
ok, err = pcall(finishScan, adEnv, scan)
end
- if not ok then Logging.warning("ADSmartPickup: F%s scanning kunne ikke afsluttes: %s", tostring(scan.id or "-"), tostring(err)) end
+ if not ok then
+ Logging.warning("ADSmartPickup: F%s scanning kunne ikke afsluttes: %s", tostring(scan.id or "-"), tostring(err))
+ if scan.id ~= nil then ADFields.scanFailed[scan.id] = true end
+ end
end
-- Samme liste indtil næste scanning (list() kaldes hvert sekund; ingen ny tabel hver gang).
diff --git a/FS25_ADSmartPickup/l10n/l10n_da.xml b/FS25_ADSmartPickup/l10n/l10n_da.xml
index d2ade53..840833c 100644
--- a/FS25_ADSmartPickup/l10n/l10n_da.xml
+++ b/FS25_ADSmartPickup/l10n/l10n_da.xml
@@ -606,6 +606,7 @@
+
diff --git a/FS25_ADSmartPickup/l10n/l10n_en.xml b/FS25_ADSmartPickup/l10n/l10n_en.xml
index 64adee8..56754d8 100644
--- a/FS25_ADSmartPickup/l10n/l10n_en.xml
+++ b/FS25_ADSmartPickup/l10n/l10n_en.xml
@@ -606,6 +606,7 @@
+