diff --git a/FS25_ADSmartPickup/adChainView.lua b/FS25_ADSmartPickup/adChainView.lua new file mode 100644 index 0000000..6c24a41 --- /dev/null +++ b/FS25_ADSmartPickup/adChainView.lua @@ -0,0 +1,187 @@ +-- AD Chain View (ren logik) +-- Rækkerne til fanen Kæder ud fra ADChain.last: rod -> noder rekursivt (kilde, behov pr. måned, flowstatus), +-- forslag/auto-skift under afgrøden, og nederst frie marker + antal automatiske skift. Ingen spiladgang: +-- titleOf(navn) -> visningstitel, fmt(liter) -> kompakt tal, textOf(l10n-nøgle) -> tekst gives udefra. +-- Række: {kind="root"|"node"|"suggest"|"dismiss"|"auto"|"info"|"empty", indent, text, level, cells={c1..c5}, +-- action={kind="approve"|"dismiss"|"pause"|"resume", fieldId|rootKey}, fillType} + +ADChainView = {} +ADChainView.INDENT = " " +-- nøgler ud over spu_tab_chains/spu_chain_empty/... som rækkerne bruger (til l10n-testen) +ADChainView.TEXT_KEYS = {"spu_chain_perMonth", "spu_chain_noField", "spu_chain_buySource", "spu_chain_cycle", + "spu_chain_fieldShort", "spu_chain_flowOk", "spu_chain_flowNone", "spu_chain_flowStopped", "spu_chain_approve", + "spu_chain_dismiss", "spu_chain_switches", "spu_chain_rootOk", "spu_chain_rootError", "spu_chain_rootWaiting", + "spu_chain_rootPaused"} + +local FLOW_KEYS = {ok = "spu_chain_flowOk", missing = "spu_chain_flowNone", stopped = "spu_chain_flowStopped", noVehicle = "spu_chain_flowMissing"} + +local function identity(value) return tostring(value) end + +local function plannedFruit(field) + if field.targetFruit ~= nil and field.targetFruit ~= "" then return field.targetFruit end + return field.fruit +end + +local function haText(ha) + return string.format("%.0f", ha or 0) +end + +local function edgeKey(node) + return tostring(node.consumer) .. "|" .. tostring(node.fillType) +end + +local function shortageByFruit(last) + local result = {} + for _, shortage in ipairs(last.shortages or {}) do result[shortage.fruit] = shortage end + return result +end + +-- Alle noder under roden (dybde først). +local function eachNode(nodes, fn, depth) + for _, node in ipairs(nodes or {}) do + fn(node, depth or 1) + eachNode(node.children, fn, (depth or 1) + 1) + end +end + +function ADChainView.rootLevel(root, last) + last = last or {} + if (last.paused or {})[root.key] then return "stopped" end + for _, problem in ipairs((last.chain or {}).problems or {}) do + if problem.rootKey == root.key then return "error" end + end + local short, flowStatus = shortageByFruit(last), last.flowStatus or {} + local hasShortage, hasWaiting = false, false + eachNode(root.children, function(node) + if node.fruit ~= nil and short[node.fruit] ~= nil then hasShortage = true end + if (node.shortPerMonth or 0) > 0 then hasShortage = true end + local status = node.consumer ~= nil and flowStatus[edgeKey(node)] or nil + if status ~= nil and status ~= "ok" then hasWaiting = true end + end) + if hasShortage then return "error" end + if hasWaiting then return "waiting" end + return "running" +end + +-- Kilden som tekst: fabrikker / stalde / marker med planlagt afgrøde / køb. +local function sourceText(node, last, textOf) + local names = {} + if node.source == "production" then + for _, producer in ipairs(node.producers or {}) do table.insert(names, tostring(producer.buildingName)) end + elseif node.source == "husbandry" then + for _, herd in ipairs(node.herds or {}) do table.insert(names, tostring(herd.buildingName)) end + elseif node.source == "field" then + for _, field in ipairs(last.fields or {}) do + if plannedFruit(field) == node.fruit then + table.insert(names, string.format("F%s (%s ha)", tostring(field.id), haText(field.areaHa))) + end + end + if #names == 0 then return textOf("spu_chain_noField") end + elseif node.source == "buy" then + return textOf("spu_chain_buySource") + else + return "-" + end + return table.concat(names, ", ") +end + +-- Nodens status (tekst, niveau): mangel/flaskehals/køb/kredsløb først, ellers flowets status. +local function nodeStatus(node, last, titleOf, fmt, textOf, short) + local title = titleOf(node.fillType) + if node.source == "cycle" then return textOf("spu_chain_cycle"), "error" end + if (node.shortPerMonth or 0) > 0 then + if node.source == "production" then + return string.format(textOf("spu_chain_bottleneck"), title, fmt(node.shortPerMonth)), "error" + end + return string.format(textOf("spu_chain_buy"), title, fmt(node.shortPerMonth)), "error" + end + local shortage = node.fruit ~= nil and short[node.fruit] or nil + if shortage ~= nil then + return string.format(textOf("spu_chain_fieldShort"), haText(shortage.missingHa)), "error" + end + local status = node.consumer ~= nil and (last.flowStatus or {})[edgeKey(node)] or nil + if status == nil then return "", "running" end + return textOf(FLOW_KEYS[status] or "spu_chain_flowNone"), status == "ok" and "running" or "waiting" +end + +local function joinCells(cells) + local parts = {} + for _, cell in ipairs(cells) do + if cell ~= nil and cell ~= "" then table.insert(parts, cell) end + end + return table.concat(parts, " · ") +end + +local function makeRow(kind, indent, level, cells, action) + return {kind = kind, indent = indent, level = level, cells = cells, action = action, text = joinCells(cells)} +end + +-- Forslag (godkend + afvis) og auto-skift for afgrøden, lige under dens node. +local function actionRows(rows, fruit, indent, last, titleOf, textOf, shown) + if fruit == nil or shown[fruit] then return end + shown[fruit] = true + local pad = string.rep(ADChainView.INDENT, indent) + for _, action in ipairs(last.actions or {}) do + if action.to == fruit then + local fromTitle = (action.from ~= nil and action.from ~= "") and titleOf(action.from) or "-" + if action.mode == "suggest" then + local text = string.format(textOf("spu_chain_suggest"), action.fieldId, fromTitle, titleOf(action.to), action.hectares or 0) + table.insert(rows, makeRow("suggest", indent, "waiting", {pad, "", "", text, textOf("spu_chain_approve")}, + {kind = "approve", fieldId = action.fieldId})) + table.insert(rows, makeRow("dismiss", indent, "waiting", {pad, "", "", "", textOf("spu_chain_dismiss")}, + {kind = "dismiss", fieldId = action.fieldId})) + else + local text = string.format(textOf("spu_chain_auto"), action.fieldId, titleOf(action.to)) + table.insert(rows, makeRow("auto", indent, "running", {pad, "", "", text, ""}, nil)) + end + end + end +end + +local ROOT_STATUS = {running = "spu_chain_rootOk", error = "spu_chain_rootError", waiting = "spu_chain_rootWaiting", stopped = "spu_chain_rootPaused"} + +local function rootRows(rows, root, last, titleOf, fmt, textOf, short) + local level = ADChainView.rootLevel(root, last) + local paused = (last.paused or {})[root.key] == true + table.insert(rows, makeRow("root", 0, level, {titleOf(root.name), tostring(root.buildingName or ""), "", + textOf(ROOT_STATUS[level]), textOf(paused and "spu_chain_resume" or "spu_chain_pause")}, + {kind = paused and "resume" or "pause", rootKey = root.key})) + local shown = {} + eachNode(root.children, function(node, depth) + local status, nodeLevel = nodeStatus(node, last, titleOf, fmt, textOf, short) + local row = makeRow("node", depth, nodeLevel, {string.rep(ADChainView.INDENT, depth) .. titleOf(node.fillType), + sourceText(node, last, textOf), string.format(textOf("spu_chain_perMonth"), fmt(node.perMonth or 0)), status, ""}, nil) + row.fillType = node.fillType + table.insert(rows, row) + if node.source == "field" then actionRows(rows, node.fruit, depth + 1, last, titleOf, textOf, shown) end + end) +end + +local function footerRows(rows, last, textOf) + local free = {} + for _, field in ipairs(last.fields or {}) do + if field.chainFree then table.insert(free, field.id) end + end + table.sort(free) + local names = {} + for _, id in ipairs(free) do table.insert(names, "F" .. tostring(id)) end + 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)}) +end + +function ADChainView.rows(last, titleOf, fmt, textOf) + textOf, fmt = textOf or identity, fmt or identity + local titles = last ~= nil and last.titles or {} + titleOf = titleOf or function(name) return (titles or {})[name] or tostring(name) end + local rows = {} + local roots = last ~= nil and last.chain ~= nil and last.chain.roots or {} + if #roots == 0 then + table.insert(rows, {kind = "empty", indent = 0, text = textOf("spu_chain_empty")}) + end + if last == nil then return rows end + local short = shortageByFruit(last) + for _, root in ipairs(roots) do rootRows(rows, root, last, titleOf, fmt, textOf, short) end + footerRows(rows, last, textOf) + return rows +end diff --git a/FS25_ADSmartPickup/adSmartPickup.lua b/FS25_ADSmartPickup/adSmartPickup.lua index fb27cb9..8034482 100644 --- a/FS25_ADSmartPickup/adSmartPickup.lua +++ b/FS25_ADSmartPickup/adSmartPickup.lua @@ -28,6 +28,7 @@ if ADSmartPickup.dir ~= nil and source ~= nil then source(ADSmartPickup.dir .. "gui/SmartPickupFieldTab.lua") source(ADSmartPickup.dir .. "gui/SmartPickupMonthTab.lua") source(ADSmartPickup.dir .. "gui/SmartPickupFieldSiloTab.lua") + source(ADSmartPickup.dir .. "gui/SmartPickupChainTab.lua") source(ADSmartPickup.dir .. "gui/SmartPickupGuide.lua") source(ADSmartPickup.dir .. "gui/SmartPickupFieldGuide.lua") source(ADSmartPickup.dir .. "gui/SmartPickupFlowGuide.lua") diff --git a/FS25_ADSmartPickup/adStorageStats.lua b/FS25_ADSmartPickup/adStorageStats.lua index a4fe73f..522a6c4 100644 --- a/FS25_ADSmartPickup/adStorageStats.lua +++ b/FS25_ADSmartPickup/adStorageStats.lua @@ -258,15 +258,51 @@ function ADStorageStats.attentionList(stats, max) for _, stat in ipairs(stats or {}) do for _, entry in ipairs(attentionEntries(stat)) do table.insert(list, entry) end end + return ADStorageStats.rankAttention(list, max) +end + +-- Kæde-forslag ligger ikke på en vare (ingen stat): navnet til den stabile rækkefølge tages fra teksten. +local function entryName(entry) + return tostring(entry.stat ~= nil and entry.stat.title or entry.text) +end + +function ADStorageStats.rankAttention(list, max) table.sort(list, function(a, b) if a.score ~= b.score then return a.score > b.score end - return tostring(a.stat.title) < tostring(b.stat.title) + return entryName(a) < entryName(b) end) local result = {} for index = 1, math.min(#list, max or #list) do result[index] = list[index] end return result end +-- "Kræver handling" fra kæden (ADChain.last): ét gult punkt pr. afgrødeforslag spilleren skal tage stilling til. +-- Rangeres over "sælg nu" (score < 1000) og under røde punkter (>= 3000). +ADStorageStats.CHAIN_SCORE = 1000 + +function ADStorageStats.chainEntries(last) + local entries = {} + local titles = last ~= nil and last.titles or {} + local function title(name) return tostring((titles or {})[name] or name) end + for _, action in ipairs(last ~= nil and last.actions or {}) do + if action.mode == "suggest" then + local from = (action.from ~= nil and action.from ~= "") and title(action.from) or "-" + table.insert(entries, {kind = "chainSuggest", level = "yellow", score = ADStorageStats.CHAIN_SCORE, fieldId = action.fieldId, + from = from, to = title(action.to), hectares = action.hectares, + text = string.format("F%s %s → %s", tostring(action.fieldId), from, title(action.to))}) + end + end + return entries +end + +-- Varepunkterne (allerede rangeret) + kædens punkter, samme loft. +function ADStorageStats.mergeAttention(attention, chainEntries, max) + local list = {} + for _, entry in ipairs(attention or {}) do table.insert(list, entry) end + for _, entry in ipairs(chainEntries or {}) do table.insert(list, entry) end + return ADStorageStats.rankAttention(list, max) +end + function ADStorageStats.kpis(stats) local kpi = {valueNow = 0, gain = 0, emptyCount = 0, fullCount = 0} for _, stat in ipairs(stats or {}) do diff --git a/FS25_ADSmartPickup/gui/SmartPickupAttentionFlow.lua b/FS25_ADSmartPickup/gui/SmartPickupAttentionFlow.lua index a058e4e..99e635d 100644 --- a/FS25_ADSmartPickup/gui/SmartPickupAttentionFlow.lua +++ b/FS25_ADSmartPickup/gui/SmartPickupAttentionFlow.lua @@ -62,6 +62,8 @@ end -- entry fra ADStorageStats.attentionList -> advice ("open"|"flow"|"produce"|"none"), info function SmartPickupFrame:attentionAdvice(entry) + -- kæde-forslag har ingen vare (stat): klik fører til fanen Kæder + if entry ~= nil and entry.kind == "chainSuggest" then return "chain", nil end if entry ~= nil and entry.kind == "sell" and entry.stat ~= nil then return sellAdviceFor(entry.stat) end if entry == nil or entry.kind ~= "empty" or entry.stat == nil then return "none", nil end local stat = entry.stat @@ -83,6 +85,7 @@ function SmartPickupFrame:attentionAdvice(entry) end function SmartPickupFrame:attentionHint(advice, info) + if advice == "chain" then return self.i18n:getText("spu_attention_hintChain") end if advice == "open" then return string.format(self.i18n:getText("spu_attention_hintOpen"), tostring(info.run.name)) end if advice == "flow" then return self.i18n:getText(info.sell and "spu_attention_hintSellFlow" or "spu_attention_hintFlow") end if advice == "produce" then return self.i18n:getText("spu_attention_hintProduce") end @@ -91,6 +94,10 @@ end function SmartPickupFrame:onAttentionClick(entry) self:safe(function(frame) + if entry ~= nil and entry.kind == "chainSuggest" then + frame:switchTab(SmartPickupFrame.TAB_CHAINS) + return + end local adEnv = frame.getAdEnv() local advice, info = frame:attentionAdvice(entry) if adEnv == nil or advice == "none" then return end diff --git a/FS25_ADSmartPickup/gui/SmartPickupChainTab.lua b/FS25_ADSmartPickup/gui/SmartPickupChainTab.lua new file mode 100644 index 0000000..e50e871 --- /dev/null +++ b/FS25_ADSmartPickup/gui/SmartPickupChainTab.lua @@ -0,0 +1,83 @@ +-- 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). + +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 + +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 + ADChain.evaluate(adEnv) + self.chainEvaluatedAt = now + end + return ADChain.last +end + +function SmartPickupFrame:chainTitle(last, name) + local title = last ~= nil and last.titles ~= nil and last.titles[name] or nil + return title or self:fruitTitle(name) +end + +-- Klik på en kæde-knap: udfør, evaluér straks (ny visning) og genopbyg. +function SmartPickupFrame:onChainAction(action) + if action.kind == "approve" then + ADChain.approve(action.fieldId) + elseif action.kind == "dismiss" then + ADChain.dismiss(action.fieldId) + elseif action.kind == "pause" or action.kind == "resume" then + ADChain.setPaused(action.rootKey, action.kind == "pause") + end + local adEnv = self.getAdEnv() + if adEnv ~= nil then self:chainLast(adEnv, true) end + self:requestRebuild() +end + +-- Række med prik + c1..c5 (flowListPrefab); knappen er c5 (klik i c5 = handling, som Flows-listen). +function SmartPickupFrame:addChainRow(entry) + local unpackFn = table.unpack or unpack + local row = self:addRow(self.flowListPrefab, {kind = "chainRow"}) + local cells = {} + for index = 1, 5 do cells[index] = row:getDescendantByName("c" .. index) end + SmartPickupFrame.setCells(cells, entry.cells) + local dot = row:getDescendantByName("dot") + local color = ADFlowView.LEVEL_COLORS[entry.level or "running"] + if dot ~= nil and dot.setImageColor ~= nil and color ~= nil then + dot:setImageColor(nil, unpackFn(color)) + -- rækker uden egen status (forslag/afvis/auto) får ingen prik — kun rod og noder har status + if entry.kind ~= "root" and entry.kind ~= "node" and dot.setVisible ~= nil then dot:setVisible(false) end + end + if cells[4] ~= nil and cells[4].setTextColor ~= nil and color ~= nil and entry.level ~= "running" then + cells[4]:setTextColor(unpackFn(color)) + end + if entry.action ~= nil then + local action, actionCell = entry.action, cells[5] + self:makeRowClickable(row, function(frame) + local onButton = frame.lastClickX == nil or actionCell == nil or actionCell.absPosition == nil + or frame.lastClickX >= actionCell.absPosition[1] + if onButton then frame:onChainAction(action) end + end) + end + return row +end + +function SmartPickupFrame:fillChainRows(adEnv) + local i18n = self.i18n + local last = self:chainLast(adEnv, false) + local rows = ADChainView.rows(last, function(name) return self:chainTitle(last, name) end, + SmartPickupFrame.formatCompact, function(key) return i18n:getText(key) end) + for _, entry in ipairs(rows) do + if entry.kind == "info" or entry.kind == "empty" then + self:addTextRow(entry.text) + else + self:addChainRow(entry) + end + end +end diff --git a/FS25_ADSmartPickup/gui/SmartPickupFrame.lua b/FS25_ADSmartPickup/gui/SmartPickupFrame.lua index 34d68c5..148d0b8 100644 --- a/FS25_ADSmartPickup/gui/SmartPickupFrame.lua +++ b/FS25_ADSmartPickup/gui/SmartPickupFrame.lua @@ -16,8 +16,11 @@ SmartPickupFrame.TAB_OVERVIEW, SmartPickupFrame.TAB_FLOWS, SmartPickupFrame.TAB_ SmartPickupFrame.MONTH_REBUILD_TICKS = 5 -- Marksilo-fanen har klikbare valg: genopbygges sjældnere, så fokus ikke rykker midt i et valg SmartPickupFrame.FIELDSILO_REBUILD_TICKS = 30 +-- Kæder-fanen (gui/SmartPickupChainTab.lua): klikbare forslag/pause, så genopbygning sjældent (som Marksiloer) +SmartPickupFrame.TAB_CHAINS = 10 +SmartPickupFrame.CHAIN_REBUILD_TICKS = 30 -- Lagerfaner: én pr. bygningstype (indeks -> kind i ADSources.getFarmInventory) -SmartPickupFrame.TAB_NAMES = {"spu_tab_overview", "spu_tab_flows", "spu_tab_fields", "spu_tab_month", "spu_tab_fieldsilos", "spu_tab_factories", "spu_tab_silos", "spu_tab_barns", "spu_tab_sheds"} +SmartPickupFrame.TAB_NAMES = {"spu_tab_overview", "spu_tab_flows", "spu_tab_fields", "spu_tab_month", "spu_tab_fieldsilos", "spu_tab_factories", "spu_tab_silos", "spu_tab_barns", "spu_tab_sheds", "spu_tab_chains"} SmartPickupFrame.TAB_KINDS = {[6] = "factory", [7] = "silo", [8] = "husbandry", [9] = "objectStorage"} function SmartPickupFrame.getTabKind(tab) @@ -466,6 +469,17 @@ function SmartPickupFrame:rebuild() self:restoreFocusIfLost() return end + if self.currentTab == SmartPickupFrame.TAB_CHAINS then + if adEnv ~= nil then + self:fillChainRows(adEnv) + end + self.monthRebuildTicks = SmartPickupFrame.CHAIN_REBUILD_TICKS + self:colorRows() + self.boxLayout:invalidateLayout() + self:refreshButtons() + self:restoreFocusIfLost() + return + end if self.currentTab == SmartPickupFrame.TAB_MONTH then if adEnv ~= nil then self:fillMonthRows(adEnv) @@ -611,7 +625,8 @@ function SmartPickupFrame:refreshButtons() wanted = self.overviewButtons elseif self.currentTab == SmartPickupFrame.TAB_FIELDS then wanted = self:getFieldButtons() - elseif self.currentTab == SmartPickupFrame.TAB_MONTH or self.currentTab == SmartPickupFrame.TAB_FIELDSILOS then + elseif self.currentTab == SmartPickupFrame.TAB_MONTH or self.currentTab == SmartPickupFrame.TAB_FIELDSILOS + or self.currentTab == SmartPickupFrame.TAB_CHAINS then wanted = self.monthButtons elseif SmartPickupFrame.getTabKind(self.currentTab) ~= nil then wanted = self.storageButtons @@ -636,7 +651,8 @@ function SmartPickupFrame:refreshLive() self:setStatusText(self.i18n:getText("spu_status_noAd")) return end - if self.currentTab == SmartPickupFrame.TAB_MONTH or self.currentTab == SmartPickupFrame.TAB_FIELDSILOS then + if self.currentTab == SmartPickupFrame.TAB_MONTH or self.currentTab == SmartPickupFrame.TAB_FIELDSILOS + or self.currentTab == SmartPickupFrame.TAB_CHAINS then self.monthRebuildTicks = (self.monthRebuildTicks or 0) - 1 if self.monthRebuildTicks <= 0 then self:requestRebuild() end self:refreshButtons() diff --git a/FS25_ADSmartPickup/gui/SmartPickupStorageView.lua b/FS25_ADSmartPickup/gui/SmartPickupStorageView.lua index 38129c3..8bcf4c1 100644 --- a/FS25_ADSmartPickup/gui/SmartPickupStorageView.lua +++ b/FS25_ADSmartPickup/gui/SmartPickupStorageView.lua @@ -183,8 +183,18 @@ function SmartPickupFrame:addKpiRow(stats) return row end +-- Varepunkterne + kædens afgrødeforslag (ADChain.last; ingen evaluering her), samme loft MAX_ATTENTION. +function SmartPickupFrame:attentionFor(stats) + local attention = ADStorageStats.attentionList(stats, SmartPickupFrame.MAX_ATTENTION) + if ADChain == nil or ADChain.last == nil then return attention end + return ADStorageStats.mergeAttention(attention, ADStorageStats.chainEntries(ADChain.last), SmartPickupFrame.MAX_ATTENTION) +end + function SmartPickupFrame:alertText(entry) local stat, fc, i18n = entry.stat, SmartPickupFrame.formatCompact, self.i18n + if entry.kind == "chainSuggest" then + return string.format(i18n:getText("spu_attention_chainSuggest"), entry.fieldId or 0, tostring(entry.from), tostring(entry.to)) + end if entry.kind == "empty" then return string.format(i18n:getText("spu_alert_empty"), stat.title, self:formatDays(stat.days), fc(stat.farmLevel or 0), fc(math.abs(stat.net or 0))) elseif entry.kind == "full" then @@ -263,7 +273,7 @@ end function SmartPickupFrame:fillItemOverview(adEnv, inventory, fullInventory) local i18n = self.i18n local stats = self:computeItemStats(adEnv, inventory, fullInventory) - local attention = ADStorageStats.attentionList(stats, SmartPickupFrame.MAX_ATTENTION) + local attention = self:attentionFor(stats) self.itemView = {kpiRow = self:addKpiRow(stats), alertRows = {}, itemRows = {}, key = self:itemStructureKey(stats, attention)} self.itemRebuildTicks = SmartPickupFrame.ITEM_REBUILD_TICKS self:addTextRow(i18n:getText("spu_attention")) @@ -307,7 +317,7 @@ function SmartPickupFrame:refreshItemOverview(adEnv, inventory, fullInventory) local view = self.itemView if view == nil then return end local stats = self:computeItemStats(adEnv, inventory, fullInventory) - local attention = ADStorageStats.attentionList(stats, SmartPickupFrame.MAX_ATTENTION) + local attention = self:attentionFor(stats) if self:itemStructureKey(stats, attention) ~= view.key then self.itemRebuildTicks = (self.itemRebuildTicks or 0) - 1 if self.itemRebuildTicks <= 0 then self:requestRebuild() end diff --git a/FS25_ADSmartPickup/l10n/l10n_da.xml b/FS25_ADSmartPickup/l10n/l10n_da.xml index 7a1f33f..75a72ad 100644 --- a/FS25_ADSmartPickup/l10n/l10n_da.xml +++ b/FS25_ADSmartPickup/l10n/l10n_da.xml @@ -575,5 +575,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FS25_ADSmartPickup/l10n/l10n_en.xml b/FS25_ADSmartPickup/l10n/l10n_en.xml index afe75ac..f6a8c9b 100644 --- a/FS25_ADSmartPickup/l10n/l10n_en.xml +++ b/FS25_ADSmartPickup/l10n/l10n_en.xml @@ -575,5 +575,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index f65dcd7..ad85ac3 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -61,6 +61,7 @@ +