diff --git a/CHANGELOG.md b/CHANGELOG.md
index f7c3129..653fd63 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ står i [docs/BRUGERMANUAL.md](docs/BRUGERMANUAL.md) (dansk) og [docs/USER_MANUA
## 1.61 — Produktionskæder
+- **1.61.9** *Sælg fra* i udkørselsflows har valget **Altid (uanset pris)** øverst: flowet sælger, så snart der er noget at køre med, uden at vente på en god pris. Resumé og status viser *sælg altid*.
- **1.61.8** Kæderne regner **læs i vogne og høstertanke** med som lager (afgrøder og markvarer), og der kommer ingen forslag eller automatiske markskift for en afgrøde, mens den høstes. Klik på en varelinje i fanen **Kæder** åbner flowet, der kører varen, i redigeringsvinduet (så en stoppet kæde kan få traktor og vogn).
- **1.61.7** Kædelinjen viser *Gård* (uden klik) ved slutprodukter, gården selv bruger (fx ensilage, TMR, roesnitter), og *Sælg*/*Behold* kun ved varer, der faktisk kan sælges straks.
- **1.61.6** Slutprodukter sælges kun straks, hvis gården ikke selv bruger varen (stald, tændt produktion, forbrug eller flow). Varer kæden allerede havde sat til salg, sættes automatisk tilbage til *Behold*, når de ikke længere må sælges (in-game: TMR og roesnitter blev sat til salg).
diff --git a/FS25_ADSmartPickup/adFlowGuide.lua b/FS25_ADSmartPickup/adFlowGuide.lua
index 141283a..e1c94ea 100644
--- a/FS25_ADSmartPickup/adFlowGuide.lua
+++ b/FS25_ADSmartPickup/adFlowGuide.lua
@@ -339,7 +339,12 @@ local function rowsRules(guide)
if isOut(guide) then
local sells, stores = ADFlowView.policyUse(productPolicies(draft))
local rows = {}
- if sells then table.insert(rows, choice("sellAtPercent", L("spu_sellAt"), percentOptions(ADRuns.MIN_SELL_AT_PERCENT, ADRuns.MAX_SELL_AT_PERCENT, 5), draft.sellAtPercent)) end
+ if sells then
+ -- "Altid" (0) øverst: sælg uanset pris (in-game 30/9)
+ local options = {{label = L("spu_sellAt_always"), value = 0}}
+ for _, option in ipairs(percentOptions(ADRuns.MIN_SELL_AT_PERCENT, ADRuns.MAX_SELL_AT_PERCENT, 5)) do table.insert(options, option) end
+ table.insert(rows, choice("sellAtPercent", L("spu_sellAt"), options, draft.sellAtPercent))
+ end
if stores then table.insert(rows, choice("storeAbovePercent", L("spu_storeAbove"), percentOptions(ADRuns.MIN_STORE_ABOVE_PERCENT, ADRuns.MAX_STORE_ABOVE_PERCENT, 5), draft.storeAbovePercent)) end
if sells then table.insert(rows, choice("sellAbovePercent", L("spu_sellAbove"), sellAboveOptions(), draft.sellAbovePercent)) end
table.insert(rows, toggle("collectRound", L("spu_collectRound"), draft.collectRound))
@@ -489,7 +494,7 @@ local SUMMARY = {
if isOut(guide) then
local sells, stores = ADFlowView.policyUse(productPolicies(draft))
local parts = {}
- if sells then table.insert(parts, L("spu_guide_flow_sumSellAt", {draft.sellAtPercent})) end
+ if sells then table.insert(parts, draft.sellAtPercent == 0 and L("spu_guide_flow_sumSellAlways") or L("spu_guide_flow_sumSellAt", {draft.sellAtPercent})) end
if stores then table.insert(parts, L("spu_guide_flow_sumStoreAbove", {draft.storeAbovePercent})) end
if sells and (draft.sellAbovePercent or 0) > 0 then table.insert(parts, L("spu_guide_flow_sumSellAbove", {draft.sellAbovePercent})) end
if draft.collectRound then table.insert(parts, L("spu_guide_flow_sumRound")) end
diff --git a/FS25_ADSmartPickup/adOutboundPlanner.lua b/FS25_ADSmartPickup/adOutboundPlanner.lua
index 1a5c18e..0705766 100644
--- a/FS25_ADSmartPickup/adOutboundPlanner.lua
+++ b/FS25_ADSmartPickup/adOutboundPlanner.lua
@@ -67,7 +67,8 @@ function ADOutboundPlanner.evaluate(product, input)
storagePercent = storagePercent,
storageHigh = storagePercent >= (input.storeAbovePercent or 80),
percent = percent,
- priceOk = percent ~= nil and percent >= (input.sellAtPercent or 90),
+ -- sælg fra 0 % = "Altid": uanset pris (også uden prisdata)
+ priceOk = input.sellAtPercent == 0 or (percent ~= nil and percent >= (input.sellAtPercent or 90)),
-- "sælg altid over X %": kilden er så fuld, at der sælges uanset pris
overflow = (input.sellAbovePercent or 0) > 0 and storagePercent >= input.sellAbovePercent,
}
diff --git a/FS25_ADSmartPickup/adRuns.lua b/FS25_ADSmartPickup/adRuns.lua
index 7db052c..3d9f4ae 100644
--- a/FS25_ADSmartPickup/adRuns.lua
+++ b/FS25_ADSmartPickup/adRuns.lua
@@ -202,7 +202,8 @@ function ADRuns.updateRun(store, runId, changes)
if changes.targetBuildingIds ~= nil then run.targetBuildingIds = copyList(changes.targetBuildingIds) end
if changes.storeBuildingIds ~= nil then run.storeBuildingIds = copyList(changes.storeBuildingIds) end
if changes.products ~= nil then run.products = copyProducts(changes.products) end
- if changes.sellAtPercent ~= nil then run.sellAtPercent = clampRange(changes.sellAtPercent, ADRuns.DEFAULT_SELL_AT_PERCENT, ADRuns.MIN_SELL_AT_PERCENT, ADRuns.MAX_SELL_AT_PERCENT) end
+ -- 0 = "Altid" (sælg uanset pris); ellers 50-100 %
+ if changes.sellAtPercent ~= nil then run.sellAtPercent = tonumber(changes.sellAtPercent) == 0 and 0 or clampRange(changes.sellAtPercent, ADRuns.DEFAULT_SELL_AT_PERCENT, ADRuns.MIN_SELL_AT_PERCENT, ADRuns.MAX_SELL_AT_PERCENT) end
if changes.storeAbovePercent ~= nil then run.storeAbovePercent = clampRange(changes.storeAbovePercent, ADRuns.DEFAULT_STORE_ABOVE_PERCENT, ADRuns.MIN_STORE_ABOVE_PERCENT, ADRuns.MAX_STORE_ABOVE_PERCENT) end
if changes.sellAbovePercent ~= nil then run.sellAbovePercent = clampRange(changes.sellAbovePercent, ADRuns.DEFAULT_SELL_ABOVE_PERCENT, ADRuns.MIN_SELL_ABOVE_PERCENT, ADRuns.MAX_SELL_ABOVE_PERCENT) end
if changes.collectRound ~= nil then run.collectRound = changes.collectRound == true end
@@ -484,7 +485,7 @@ function ADRuns.fromRecords(records)
targetBuildingIds = parseIds(record.targetBuildings),
storeBuildingIds = parseIds(record.storeBuildings),
products = ADRuns.parseProducts(record.products),
- sellAtPercent = clampRange(record.sellAt, ADRuns.DEFAULT_SELL_AT_PERCENT, ADRuns.MIN_SELL_AT_PERCENT, ADRuns.MAX_SELL_AT_PERCENT),
+ sellAtPercent = tonumber(record.sellAt) == 0 and 0 or clampRange(record.sellAt, ADRuns.DEFAULT_SELL_AT_PERCENT, ADRuns.MIN_SELL_AT_PERCENT, ADRuns.MAX_SELL_AT_PERCENT),
storeAbovePercent = clampRange(record.storeAbove, ADRuns.DEFAULT_STORE_ABOVE_PERCENT, ADRuns.MIN_STORE_ABOVE_PERCENT, ADRuns.MAX_STORE_ABOVE_PERCENT),
sellAbovePercent = clampRange(record.sellAbove, ADRuns.DEFAULT_SELL_ABOVE_PERCENT, ADRuns.MIN_SELL_ABOVE_PERCENT, ADRuns.MAX_SELL_ABOVE_PERCENT),
collectRound = tonumber(record.collectRound) == 1,
diff --git a/FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua b/FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua
index a53cb53..982813b 100644
--- a/FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua
+++ b/FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua
@@ -51,7 +51,7 @@ function SmartPickupFrame:flowCells(adEnv, run)
if row.kind == "outbound" then
local sells, stores = ADFlowView.policyUse(row.policies)
local parts = {}
- if sells then table.insert(parts, string.format(i18n:getText("spu_flow_ruleSell"), row.sellAtPercent or 90)) end
+ if sells then table.insert(parts, row.sellAtPercent == 0 and i18n:getText("spu_flow_ruleSellAlways") or string.format(i18n:getText("spu_flow_ruleSell"), row.sellAtPercent or 90)) end
if stores then table.insert(parts, string.format(i18n:getText("spu_flow_ruleStore"), row.storeAbovePercent or 80)) end
rule = table.concat(parts, ", ")
if row.collectRound then rule = rule .. ", " .. i18n:getText("spu_flow_round") end
diff --git a/FS25_ADSmartPickup/l10n/l10n_da.xml b/FS25_ADSmartPickup/l10n/l10n_da.xml
index 1d3b6c8..754e0c0 100644
--- a/FS25_ADSmartPickup/l10n/l10n_da.xml
+++ b/FS25_ADSmartPickup/l10n/l10n_da.xml
@@ -310,6 +310,7 @@
+
@@ -350,6 +351,7 @@
+
@@ -517,6 +519,7 @@
+
diff --git a/FS25_ADSmartPickup/l10n/l10n_en.xml b/FS25_ADSmartPickup/l10n/l10n_en.xml
index 79fc934..2a1155b 100644
--- a/FS25_ADSmartPickup/l10n/l10n_en.xml
+++ b/FS25_ADSmartPickup/l10n/l10n_en.xml
@@ -310,6 +310,7 @@
+
@@ -350,6 +351,7 @@
+
@@ -517,6 +519,7 @@
+
diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml
index 08efa54..5b8f2d0 100644
--- a/FS25_ADSmartPickup/modDesc.xml
+++ b/FS25_ADSmartPickup/modDesc.xml
@@ -1,7 +1,7 @@
masterdraco
- 1.61.8.0
+ 1.61.9.0
AD Smart Pickup