From 83394aabfda253e38903b7565470a22e196a3d9b Mon Sep 17 00:00:00 2001 From: masterdraco Date: Wed, 30 Sep 2026 14:27:08 +0200 Subject: [PATCH] =?UTF-8?q?perf(k=C3=A6de):=20priser=20sl=C3=A5s=20kun=20o?= =?UTF-8?q?p=20for=20kandidatmarker,=20fanen=20genbruger=20resultater=20un?= =?UTF-8?q?der=2030=20s=20og=20k=C3=A6den=20m=C3=A5les=20af=20profileren?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FS25_ADSmartPickup/adChain.lua | 8 ++++- FS25_ADSmartPickup/adChainData.lua | 32 ++++++++++++++++--- FS25_ADSmartPickup/adProfiler.lua | 2 ++ .../gui/SmartPickupChainTab.lua | 17 +++------- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/FS25_ADSmartPickup/adChain.lua b/FS25_ADSmartPickup/adChain.lua index b23c890..9511435 100644 --- a/FS25_ADSmartPickup/adChain.lua +++ b/FS25_ADSmartPickup/adChain.lua @@ -275,7 +275,7 @@ local function plan(data, state) 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)) + actions = ADCropPlan.choose(shortages, data.fields, used, data.yields, data.priceOf or 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) @@ -326,6 +326,12 @@ function ADChain.evaluate(adEnv, act) return ADChain.last end +-- Alder (ms, spillets ur) af det sidste resultat; math.huge når der intet er. Fanen genbruger et friskt resultat. +function ADChain.lastAge() + if ADChain.last == nil then return math.huge end + return ADChain.now - (ADChain.last.at or 0) +end + function ADChain.tick(adEnv, dt) if adEnv == nil then return end ADChain.now = ADChain.now + (dt or 0) diff --git a/FS25_ADSmartPickup/adChainData.lua b/FS25_ADSmartPickup/adChainData.lua index 6d2b486..0c5b600 100644 --- a/FS25_ADSmartPickup/adChainData.lua +++ b/FS25_ADSmartPickup/adChainData.lua @@ -141,6 +141,27 @@ local function readPlaceables(data, farmId, byChain, nameOf) table.sort(data.recipes, function(a, b) return a.key < b.key end) end +-- Markedspris for en afgrøde, først når kæden spørger (kun kandidatmarkernes afgrøder, kun ved mangel); +-- hver afgrøde slås højst op én gang pr. læsning. Fejl -> 0 (logget én gang). +local function priceResolver(data) + local cache = {} + return function(fruitName) + if cache[fruitName] ~= nil then return cache[fruitName] end + local index = data.fruitFillIndex[fruitName] + local price = 0 + if index ~= nil then + local ok, quote = pcall(ADSources.getMarketQuote, index) + if ok then + price = quote ~= nil and quote.price or 0 + else + ADChainData.warnOnce("price:" .. tostring(fruitName), "pris for %s kunne ikke læses: %s", tostring(fruitName), tostring(quote)) + end + end + cache[fruitName] = price + return price + end +end + local function readCrops(data, nameOf) local fruits = g_fruitTypeManager ~= nil and g_fruitTypeManager.fruitTypes or {} for _, fruit in ipairs(fruits) do @@ -151,8 +172,7 @@ local function readCrops(data, nameOf) if fruit.fillType.index ~= nil then nameOf(fruit.fillType.index) end data.crops[fillName] = fruit.name data.yields[fruit.name] = (tonumber(fruit.literPerSqm) or 0) * 10000 - local quote = fruit.fillType.index ~= nil and ADSources.getMarketQuote(fruit.fillType.index) or nil - data.prices[fruit.name] = quote ~= nil and quote.price or 0 + data.fruitFillIndex[fruit.name] = fruit.fillType.index end) if not ok then failed(data, "fruit:" .. tostring(fruit.name), "afgrøde %s kunne ikke læses: %s", tostring(fruit.name), tostring(err)) end end @@ -169,7 +189,8 @@ local function readStock(data, adEnv, farmId, nameOf) if not ok then failed(data, "stock", "lager kunne ikke læses: %s", tostring(err)) end end --- Afgrøder gården selv bruger: input i en tændt produktion eller foder/halm i en stald. +-- Afgrøder gården selv bruger: input i en tændt produktion eller foder/halm i en stald (kun staldenes forbrug +-- læses: feedOnly springer fabrikkernes rater over — dem dækker opskrifterne allerede). local function readUsedFruits(data, adEnv, farmId, nameOf) for _, recipe in ipairs(data.recipes) do if recipe.enabled then @@ -179,7 +200,7 @@ local function readUsedFruits(data, adEnv, farmId, nameOf) end end local ok, err = pcall(function() - for index, rate in pairs(ADSources.getFarmRates(adEnv, farmId) or {}) do + for index, rate in pairs(ADSources.getFarmRates(adEnv, farmId, true) or {}) do local fruit = data.crops[nameOf(index) or ""] if fruit ~= nil and (rate.consumption or 0) > 0 then data.usedFruits[fruit] = true end end @@ -216,9 +237,10 @@ end -- 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 = {}, + local data = {recipes = {}, husbandry = {}, crops = {}, stock = {}, fields = {}, yields = {}, fruitFillIndex = {}, usedFruits = {}, points = {}, fillTitles = {}, fillIndex = {}} local nameOf = nameResolver(data) + data.priceOf = priceResolver(data) readPlaceables(data, farmId, byChain, nameOf) readCrops(data, nameOf) readStock(data, adEnv, farmId, nameOf) diff --git a/FS25_ADSmartPickup/adProfiler.lua b/FS25_ADSmartPickup/adProfiler.lua index fa092fc..868c081 100644 --- a/FS25_ADSmartPickup/adProfiler.lua +++ b/FS25_ADSmartPickup/adProfiler.lua @@ -110,6 +110,8 @@ function ADProfiler.install() {ADSources, "getFarmInventory", "gårdens lagre"}, {ADWaitPool, "hasRouteTo", "rutetjek"}, {ADWaitPool, "hasRouteBothWays", "rutetjek frem+tilbage"}, + {ADChain, "evaluate", "kæde"}, + {ADChainData, "collect", "kæde: læs gården"}, } for _, target in ipairs(targets) do ADProfiler.wrap(target[1], target[2], target[3]) diff --git a/FS25_ADSmartPickup/gui/SmartPickupChainTab.lua b/FS25_ADSmartPickup/gui/SmartPickupChainTab.lua index 71d9c50..fe85554 100644 --- a/FS25_ADSmartPickup/gui/SmartPickupChainTab.lua +++ b/FS25_ADSmartPickup/gui/SmartPickupChainTab.lua @@ -1,22 +1,15 @@ -- Smart Pickup — fanen Kæder -- Produktionskæderne som træ: rod (produktion spilleren har tændt) -> varer -> råvarer, med kilde, behov pr. -- måned og flowstatus; afgrødeforslag kan godkendes/afvises og en rod sættes på pause. Rækkerne bygges af --- ADChainView (testet); her kun kloning, farve og klik. Evaluering højst hvert CHAIN_EVALUATE_MS (visning, handler ikke). +-- ADChainView (testet); her kun kloning, farve og klik. Et resultat yngre end CHAIN_MAX_AGE_MS (fra kædens eget +-- tick eller en tidligere visning) genbruges; ellers evalueres (visning, handler ikke). Klik evaluerer altid. -SmartPickupFrame.CHAIN_EVALUATE_MS = 5000 - --- Spillets ur i ms; uden g_time evalueres ved hver opbygning (der kun sker hvert CHAIN_REBUILD_TICKS s). -local function nowMs() - return type(g_time) == "number" and g_time or nil -end +SmartPickupFrame.CHAIN_MAX_AGE_MS = 30000 function SmartPickupFrame:chainLast(adEnv, force) - local now = nowMs() - local due = force or ADChain.last == nil or now == nil or self.chainEvaluatedAt == nil - or now - self.chainEvaluatedAt >= SmartPickupFrame.CHAIN_EVALUATE_MS - if due then + local age = ADChain.lastAge ~= nil and ADChain.lastAge() or math.huge + if force or ADChain.last == nil or age >= SmartPickupFrame.CHAIN_MAX_AGE_MS then ADChain.evaluate(adEnv) - self.chainEvaluatedAt = now end return ADChain.last end