diff --git a/CHANGELOG.md b/CHANGELOG.md index 037eb32..6d797bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ står i [docs/BRUGERMANUAL.md](docs/BRUGERMANUAL.md) (dansk) og [docs/USER_MANUA ## 1.61 — Produktionskæder -- **1.61.0** Produktionskæder: slå et produkt til i en fabrik, og moden holder det kørende helt tilbage til marken. Kæden regner baglæns gennem dine egne fabrikker og stalde til afgrøderne og ser 12 måneder frem. Ny fane **Kæder** med træ pr. rod-produktion, farvet status, fold ud/ind og **[Pause]**/**[Start]**. Marker markeret **Fri til kæden** skifter afgrøde automatisk (højst 2 i minuttet); andre marker får forslag med **[Godkend]**/**[Afvis]** (højst 3 pr. afgrøde) i fanen og som ét samlet punkt i **Kræver handling**. En afgrøde, du selv har valgt, ændres aldrig. Mellemled tændes og slukkes kun igen, hvis kæden tændte dem. Flows **Kæde: → ** oprettes med en ledig pool-traktor og tipvogn (ellers stoppet: *mangler traktor/vogn*; paller altid stoppet) og stoppes, ikke slettes, når kæden slås fra. Dine egne tændte produktioner bruges som kilde først; slukker du en produktion, tænder kæden den ikke igen, før du tænder en ny. Stoppede kædeflows slippes af kæden. Ingen handlinger de første 2 minutter, ingen markskift før alle marker er scannet, og intet slukkes ved delvise læsefejl. Begrænsninger: intet køb, ingen dyrekøb, flerårige afgrøder og græsmarker skiftes aldrig, grundudbytte uden gødningsbonus. **Vigtigt:** hver produktion, du tænder i en fabrik, prøver moden at forsyne — tænd kun det, du vil have produceret; sluk produktionen eller tryk [Pause] for at stoppe kæden. Manglende led forklares i klart sprog med råd (*Ingen af dine fabrikker laver Mel — byg en eller køb*, *Mølle kan kun lave 800 af 1.0k/md*, *Dine stalde leverer ikke nok Mælk …*, *… er slukket af dig*, *Kredsløb omkring …*): som rød tekst under varen i fanen Kæder, som én rød linje pr. kæde i **Kræver handling** (højst 2; klik åbner kæden foldet ud) og som engangsbesked med kædens navn foran, når et nyt led mangler (ikke i opstartsfristen eller mens markerne scannes). Nyt **statusvindue** på skærmen (i stil med Simple Inspector), som slås til/fra med **venstre Alt + Insert** (kan ændres under Styring; virker til fods og i køretøjer): øverst til højre under info-boksen vises flow-traktorernes handling og fyld, markarbejde i gang, kæder med manglende led og advarsler (slukkede nødvendige fabrikker, køretøjer der har stået stille over 2 min — solgte vises ikke —, ventende kædeforslag); traktorlinjernes farve følger flowets niveau som Flows-listen — højst 18 linjer, opdateres hvert sekund, skjules ved menu/dialog, skjult HUD og søvn; tændt/slukket gemmes pr. bruger i `modSettings/FS25_ADSmartPickup/status.xml`. **Advarsel når en nødvendig fabrik slukkes** (også uden kæder): slukker du en produktion, hvis vare et tændt flow kører (valgt vare eller målet tager den i auto), en stald æder eller en aktiv kæde bruger, kommer én besked pr. slukning (*Advarsel: du slukkede Fermenteringssilo 3 (Ensilage) — Cow Food, Goat Food +1 bruger det. Lageret rækker ca. 12 dage.*) og en rød linje *Slukket men nødvendig: …* i **Kræver handling** (højst 2; klik åbner fanen Fabrikker, eller Kæder hvis kun en kæde bruger varen) og i statusvinduet, så længe den er slukket og nødvendig. Ingen advarsel når en anden tændt produktion dækker med nok kapacitet, lageret rækker over 60 dage, kæden selv slukkede den, eller den allerede var slukket ved indlæsning; produktioner ingen bruger, advarer aldrig. Manual og ordliste opdateret. +- **1.61.0** Produktionskæder: slå et produkt til i en fabrik, og moden holder det kørende helt tilbage til marken. Kæden regner baglæns gennem dine egne fabrikker og stalde til afgrøderne og ser 12 måneder frem. Ny fane **Kæder** med træ pr. rod-produktion, farvet status, fold ud/ind og **[Pause]**/**[Start]**. Marker markeret **Fri til kæden** skifter afgrøde automatisk (højst 2 i minuttet); andre marker får forslag med **[Godkend]**/**[Afvis]** (højst 3 pr. afgrøde) i fanen og som ét samlet punkt i **Kræver handling**. En afgrøde, du selv har valgt, ændres aldrig. Mellemled tændes og slukkes kun igen, hvis kæden tændte dem. Flows **Kæde: → ** oprettes med en ledig pool-traktor og tipvogn (ellers stoppet: *mangler traktor/vogn*; paller altid stoppet) og stoppes, ikke slettes, når kæden slås fra. Dine egne tændte produktioner bruges som kilde først; slukker du en produktion, tænder kæden den ikke igen, før du tænder en ny. Stoppede kædeflows slippes af kæden. Ingen handlinger de første 2 minutter, ingen markskift før alle marker er scannet, og intet slukkes ved delvise læsefejl. Begrænsninger: intet køb, ingen dyrekøb, flerårige afgrøder og græsmarker skiftes aldrig, grundudbytte uden gødningsbonus. **Vigtigt:** hver produktion, du tænder i en fabrik, prøver moden at forsyne — tænd kun det, du vil have produceret; sluk produktionen eller tryk [Pause] for at stoppe kæden. Manglende led forklares i klart sprog med råd (*Ingen af dine fabrikker laver Mel — byg en eller køb*, *Mølle kan kun lave 800 af 1.0k/md*, *Dine stalde leverer ikke nok Mælk …*, *… er slukket af dig*, *Kredsløb omkring …*): som rød tekst under varen i fanen Kæder, som én rød linje pr. kæde i **Kræver handling** (højst 2; klik åbner kæden foldet ud) og som engangsbesked med kædens navn foran, når et nyt led mangler (ikke i opstartsfristen eller mens markerne scannes). Nyt **statusvindue** på skærmen (i stil med Simple Inspector), som slås til/fra med **venstre Alt + Insert** (kan ændres under Styring; virker til fods og i køretøjer): øverst til højre under info-boksen vises flow-traktorernes handling og fyld, markarbejde i gang, kæder med manglende led og advarsler (slukkede nødvendige fabrikker, køretøjer der har stået stille over 2 min — solgte vises ikke —, ventende kædeforslag); traktorlinjernes farve følger flowets niveau som Flows-listen — højst 18 linjer, opdateres hvert sekund, skjules ved menu/dialog, skjult HUD og søvn; tændt/slukket gemmes pr. bruger i `modSettings/FS25_ADSmartPickup/status.xml`. **Advarsel når en nødvendig fabrik slukkes** (også uden kæder): slukker du en produktion, hvis vare et tændt flow kører (valgt vare, eller målet tager den i auto og gården forbruger den), en stald æder eller en aktiv kæde bruger sammen med et flow/en stald, kommer én besked pr. slukning (*Advarsel: du slukkede Fermenteringssilo 3 (Ensilage) — Cow Food, Goat Food +1 bruger det. Lageret rækker ca. 12 dage.*) og en rød linje *Slukket men nødvendig: …* i **Kræver handling** (højst 2; klik åbner fanen Fabrikker) og i statusvinduet, så længe den er slukket og nødvendig. Ingen advarsel når en anden opskrift i samme fabrik laver varen og er tændt, en anden tændt produktion dækker med nok kapacitet, kun kæder bruger varen (meldes som manglende led), lageret rækker over 60 dage, kæden selv slukkede den, eller den allerede var slukket ved indlæsning; produktioner ingen bruger, advarer aldrig. Manual og ordliste opdateret. ## 1.60 — "Kræver handling" → flow, menuplacering, flow-vogne i guiden diff --git a/FS25_ADSmartPickup/adChainData.lua b/FS25_ADSmartPickup/adChainData.lua index a01bddd..981aa1f 100644 --- a/FS25_ADSmartPickup/adChainData.lua +++ b/FS25_ADSmartPickup/adChainData.lua @@ -334,8 +334,17 @@ function ADChainData.dependencyInputs(data, chain, flows) end end table.sort(goods) + -- auto-flowets mål tager mange varer (fx biogas: korn, ensilage, gylle): kun varer gården faktisk forbruger + -- (stald eller fabrik) eller en kæde vil have, tæller + local consumed = {} + for _, name in ipairs(goods) do + local rate = (data.rates or {})[name] + if (rate ~= nil and (rate.consumption or 0) > 0) or ((chain ~= nil and chain.demand or {})[name] or 0) > 0 then + table.insert(consumed, name) + end + end local needed = ADDependency.neededOutputs(flows, data.barnFood, ADChainData.chainInputs(chain, data.fillTitles), - #goods > 0 and ADChainData.acceptsMap(data, flows, goods) or {}) + #consumed > 0 and ADChainData.acceptsMap(data, flows, consumed) or {}) local adjustment = data.timeAdjustment or 1 local capacity, demand, stockDays = {}, {}, {} for name, perMonth in pairs(ADDependency.capacity(data.recipes)) do capacity[name] = perMonth * adjustment end diff --git a/FS25_ADSmartPickup/adDependency.lua b/FS25_ADSmartPickup/adDependency.lua index a1982c6..774b21c 100644 --- a/FS25_ADSmartPickup/adDependency.lua +++ b/FS25_ADSmartPickup/adDependency.lua @@ -23,24 +23,27 @@ end -- flows = {{name, kind, stopped, targetBuildingIds, ingredientMode, ingredients}} -- barnFood = {[vare] = {staldnavn...}}, chainInputs = {[vare] = {kædenavn...}} -- accepts = {[bygnings-id] = {[vare] = true}}: hvad auto-flowenes mål tager (adapteren slår op) --- -> {[vare] = {users = {navn...}, onlyChain}} (brugere i rækkefølgen flows, stalde, kæder; hver kun én gang) +-- -> {[vare] = {users = {navn...}, onlyChain, strong}} (brugere i rækkefølgen flows, stalde, kæder; hver kun én gang). +-- strong = varen er valgt som manuel vare i et flow eller er kæde-input: behovet gælder også uden kendt forbrug. +-- Stald-foder og auto-flowenes mål er "svage": uden kendt forbrug (lagerdage) er de ikke nødvendige. function ADDependency.neededOutputs(flows, barnFood, chainInputs, accepts) local result = {} - local function add(name, user, isChain) + local function add(name, user, isChain, isStrong) if name == nil or user == nil then return end local entry = result[name] if entry == nil then - entry = {users = {}, onlyChain = true} + entry = {users = {}, onlyChain = true, strong = false} result[name] = entry end if not isChain then entry.onlyChain = false end + if isStrong then entry.strong = true end if not contains(entry.users, user) then table.insert(entry.users, user) end end for _, flow in ipairs(flows or {}) do if flow.kind ~= "outbound" and not flow.stopped then local user = tostring(flow.name or "?") if flow.ingredientMode == "manual" then - for _, name in ipairs(flow.ingredients or {}) do add(name, user, false) end + for _, name in ipairs(flow.ingredients or {}) do add(name, user, false, true) end else for _, building in ipairs(flow.targetBuildingIds or {}) do for _, name in ipairs(sortedKeys((accepts or {})[building])) do add(name, user, false) end @@ -52,7 +55,7 @@ function ADDependency.neededOutputs(flows, barnFood, chainInputs, accepts) for _, barn in ipairs(barnFood[name]) do add(name, tostring(barn), false) end end for _, name in ipairs(sortedKeys(chainInputs)) do - for _, root in ipairs(chainInputs[name]) do add(name, tostring(root), true) end + for _, root in ipairs(chainInputs[name]) do add(name, tostring(root), true, true) end end return result end @@ -91,13 +94,34 @@ local function stockLasts(name, stockDays) return days ~= nil and days > ADDependency.STOCK_DAYS_OK end +-- {[bygning|vare] = true} for tændte opskrifter: spilleren har valgt hvilken opskrift i fabrikken der kører. +local function enabledInBuilding(recipes) + local result = {} + for _, recipe in ipairs(recipes or {}) do + if recipe.enabled then + for name, amount in pairs(recipe.outputs or {}) do + if (amount or 0) > 0 then result[tostring(recipe.building) .. "|" .. name] = true end + end + end + end + return result +end + +-- Er behovet for varen reelt? Kun kæder: nej (Task 10 melder kæderne). Svagt behov (stald-foder, auto-flowets mål) +-- kræver kendt forbrug (lagerdage); manuel flow-vare og kæde-input gælder også uden. +local function isNeeded(need, name, stockDays) + if need == nil or need.onlyChain then return false end + return need.strong == true or (stockDays or {})[name] ~= nil +end + -- Første nødvendige, udækkede vare (efter navn) for en slukket produktion (ikke kædens) -> advarsel eller nil. -local function check(recipe, needed, stockDays, otherCapacity, demand) +local function check(recipe, needed, stockDays, otherCapacity, demand, alternatives) if recipe.enabled or recipe.byChain then return nil end for _, name in ipairs(sortedKeys(recipe.outputs)) do local need = (needed or {})[name] - if need ~= nil and (recipe.outputs[name] or 0) > 0 and not isCovered(name, otherCapacity, demand) - and not stockLasts(name, stockDays) then + if isNeeded(need, name, stockDays) and (recipe.outputs[name] or 0) > 0 + and not alternatives[tostring(recipe.building) .. "|" .. name] + and not isCovered(name, otherCapacity, demand) and not stockLasts(name, stockDays) then local days = (stockDays or {})[name] return {recipeKey = recipe.key, building = recipe.building, buildingName = recipe.buildingName, fillType = name, users = need.users, onlyChain = need.onlyChain == true, days = days} @@ -109,8 +133,9 @@ end -- Alle slukkede, nødvendige produktioner (én pr. fabrik) — "Slukket men nødvendig" i Kræver handling. function ADDependency.offNeeded(recipes, needed, stockDays, otherCapacity, demand) local result, seen = {}, {} + local alternatives = enabledInBuilding(recipes) for _, recipe in ipairs(recipes or {}) do - local warning = check(recipe, needed, stockDays, otherCapacity, demand) + local warning = check(recipe, needed, stockDays, otherCapacity, demand, alternatives) if warning ~= nil and not seen[tostring(warning.building)] then seen[tostring(warning.building)] = true table.insert(result, warning) @@ -119,14 +144,17 @@ function ADDependency.offNeeded(recipes, needed, stockDays, otherCapacity, deman return result end +-- Fælles regler (warnings og offNeeded): ingen advarsel når en anden opskrift i SAMME fabrik laver varen og er +-- tændt, når andre tændte produktioner dækker behovet, når lageret rækker > 60 dage, eller når kun kæder bruger varen. -- Nye slukninger siden sidste evaluering: tændt i prevEnabled, slukket nu, nødvendig og ikke dækket. -- prevEnabled = nil (første evaluering efter indlæsning) -> ingen. Én pr. fabrik og vare. function ADDependency.warnings(prevEnabled, recipes, needed, stockDays, otherCapacity, demand) local result, seen = {}, {} if prevEnabled == nil then return result end + local alternatives = enabledInBuilding(recipes) for _, recipe in ipairs(recipes or {}) do if prevEnabled[recipe.key] then - local warning = check(recipe, needed, stockDays, otherCapacity, demand) + local warning = check(recipe, needed, stockDays, otherCapacity, demand, alternatives) local id = warning ~= nil and (tostring(warning.building) .. "|" .. warning.fillType) or nil if warning ~= nil and not seen[id] then seen[id] = true diff --git a/docs/BRUGERMANUAL.md b/docs/BRUGERMANUAL.md index bdfd9ea..20e68a4 100644 --- a/docs/BRUGERMANUAL.md +++ b/docs/BRUGERMANUAL.md @@ -694,9 +694,12 @@ Beskederne: Slukker du en produktion, som gården er afhængig af, advarer moden dig — også når ingen kæde er i gang. En produktion er nødvendig, når en af dens varer bruges af gården: -- et tændt forsyningsflow kører varen (valgt som vare, eller flowets mål tager varen i auto), +- et tændt forsyningsflow har varen valgt som vare, +- et tændt flow i auto kører til et mål, der tager varen, og gården forbruger varen, - en stald æder varen lige nu, eller -- en aktiv kæde har varen som input. +- en aktiv kæde har varen som input (bruger kun kæder varen, meldes det i stedet som manglende led, se ovenfor). + +Ved flows i auto og stalde skal gårdens forbrug af varen kendes; ellers regnes varen ikke som nødvendig. Eksempel: du slukker fermenteringssiloerne, men flowene *Cow Food*, *Goat Food* og *Biogas Silage* henter ensilage. Så kommer beskeden *Advarsel: du slukkede Fermenteringssilo 3 (Ensilage) — Cow Food, Goat Food +1 @@ -705,10 +708,12 @@ de). Beskeden kommer én gang pr. slukning, højst et minut efter. Så længe produktionen er slukket og stadig nødvendig, står der en rød linje i **Kræver handling**: *Slukket men nødvendig: Fermenteringssilo 3* (højst 2; også i statusvinduet under Advarsler). Et klik åbner -lagerfanen **Fabrikker** — eller **Kæder**, hvis kun en kæde bruger varen. +lagerfanen **Fabrikker**. Der advares ikke, når: +- en anden opskrift i samme fabrik laver varen og er tændt (du har valgt, hvilken opskrift der kører — fx én + ensilage-opskrift i en fermenteringssilo), - en anden tændt produktion laver varen med nok kapacitet, - gården har lager til mere end 60 dage, - kæden selv slukkede produktionen, eller diff --git a/docs/USER_MANUAL.md b/docs/USER_MANUAL.md index 0fc168a..2798b8b 100644 --- a/docs/USER_MANUAL.md +++ b/docs/USER_MANUAL.md @@ -710,9 +710,13 @@ The messages: If you switch off a production the farm depends on, the mod warns you — also when no chain is running. A production is needed when one of its goods is used by the farm: -- a running supply flow carries the goods (chosen as goods, or the flow's target takes the goods in auto), +- a running supply flow has the goods chosen as goods, +- a running flow in auto goes to a target that takes the goods, and the farm consumes the goods, - a barn is eating the goods right now, or -- an active chain has the goods as input. +- an active chain has the goods as input (if only chains use the goods, it is reported as a missing link + instead, see above). + +For auto flows and barns the farm's consumption of the goods must be known; otherwise the goods do not count as needed. Example: you switch off the fermenting silos, but the flows *Cow Food*, *Goat Food* and *Biogas Silage* fetch silage. You then get the message *Warning: you switched off Fermenting silo 3 (Silage) — Cow Food, Goat Food @@ -721,10 +725,12 @@ The message comes once per switch-off, at most a minute later. As long as the production is off and still needed, **Needs attention** shows a red line: *Switched off but needed: Fermenting silo 3* (at most 2; also in the status window under Warnings). Clicking opens the storage -tab **Factories** — or **Chains** if only a chain uses the goods. +tab **Factories**. No warning when: +- another recipe in the same factory makes the goods and is on (you chose which recipe runs — for example one + silage recipe in a fermenting silo), - another running production makes the goods with enough capacity, - the farm has stock for more than 60 days, - the chain switched the production off itself, or