diff --git a/FS25_ADSmartPickup/adChainView.lua b/FS25_ADSmartPickup/adChainView.lua index 6c24a41..efbd20f 100644 --- a/FS25_ADSmartPickup/adChainView.lua +++ b/FS25_ADSmartPickup/adChainView.lua @@ -1,31 +1,73 @@ -- 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} +-- 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: +-- 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} 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"} +ADChainView.INDENT = " " +-- Tegnbudget pr. celle i flowListPrefab (gui/SmartPickupFrame.xml: textMaxWidth 192/162/62/244/92 px). +-- Antaget ~11,5 px pr. tegn (spuInfoText: 800 px ~ 70 tegn), fed ~12,5 px; c3 har kun tal (~10 px pr. tegn). +ADChainView.CELL_CHARS = {15, 14, 6, 21, 8} +ADChainView.MAX_SOURCE_NAMES = 2 +-- "stramt": lager for en mark-afgrøde under så mange måneders behov -> gul +ADChainView.TIGHT_MONTHS = 3 +-- nøgler rækkerne bruger (til l10n-testen) +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_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"} local FLOW_KEYS = {ok = "spu_chain_flowOk", missing = "spu_chain_flowNone", stopped = "spu_chain_flowStopped", noVehicle = "spu_chain_flowMissing"} +local ROOT_STATUS = {running = "spu_chain_rootOk", error = "spu_chain_rootError", waiting = "spu_chain_rootWaiting", stopped = "spu_chain_rootPaused"} 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 +-- ---- UTF-8-sikker længde/afkortning (æøå og → er flere bytes) ---- + +function ADChainView.textLength(text) + local count = 0 + for _ in tostring(text):gmatch("[^\128-\191]") do count = count + 1 end + return count +end + +local function utf8Prefix(text, chars) + local result, count = {}, 0 + for char in text:gmatch("[^\128-\191][\128-\191]*") do + if count >= chars then break end + table.insert(result, char) + count = count + 1 + end + return table.concat(result) +end + +-- Afkort til celle-budgettet med ".." til sidst. +function ADChainView.fit(text, chars) + text = tostring(text or "") + if ADChainView.textLength(text) <= chars then return text end + return utf8Prefix(text, math.max(0, chars - 2)) .. ".." +end + +local function fitCells(cells) + local result = {} + for index = 1, 5 do result[index] = ADChainView.fit(cells[index] or "", ADChainView.CELL_CHARS[index]) end + return result end local function haText(ha) return string.format("%.0f", ha or 0) end +local function plannedFruit(field) + if field.targetFruit ~= nil and field.targetFruit ~= "" then return field.targetFruit end + return field.fruit +end + local function edgeKey(node) return tostring(node.consumer) .. "|" .. tostring(node.fillType) end @@ -36,7 +78,17 @@ local function shortageByFruit(last) return result end --- Alle noder under roden (dybde først). +local function stockOf(last, fruit) + local stock = last.data ~= nil and last.data.stock or nil + return stock ~= nil and stock[fruit] or nil +end + +-- Mark-afgrøde uden mangel men med lager under TIGHT_MONTHS måneders behov. +local function isTight(node, last, short) + if node.source ~= "field" or node.fruit == nil or short[node.fruit] ~= nil then return false end + return (stockOf(last, node.fruit) or 0) < ADChainView.TIGHT_MONTHS * (node.perMonth or 0) +end + local function eachNode(nodes, fn, depth) for _, node in ipairs(nodes or {}) do fn(node, depth or 1) @@ -56,14 +108,22 @@ function ADChainView.rootLevel(root, last) 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 + if (status ~= nil and status ~= "ok") or isTight(node, last, short) 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. +-- Højst MAX_SOURCE_NAMES navne + " +k". +local function joinCapped(names) + local shown = {} + for index = 1, math.min(#names, ADChainView.MAX_SOURCE_NAMES) do shown[index] = names[index] end + local text = table.concat(shown, ", ") + if #names > #shown then text = text .. " +" .. tostring(#names - #shown) end + return text +end + local function sourceText(node, last, textOf) local names = {} if node.source == "production" then @@ -72,9 +132,7 @@ local function sourceText(node, last, textOf) 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 + if plannedFruit(field) == node.fruit then table.insert(names, "F" .. tostring(field.id)) end end if #names == 0 then return textOf("spu_chain_noField") end elseif node.source == "buy" then @@ -82,29 +140,26 @@ local function sourceText(node, last, textOf) else return "-" end - return table.concat(names, ", ") + return joinCapped(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) +-- Nodens status (tekst, niveau): kredsløb/flaskehals/køb/mangel (rød) > flow ikke ok (gul) > stramt lager (gul) > flow ok. +local function nodeStatus(node, last, fmt, textOf, short) 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" + local key = node.source == "production" and "spu_chain_bottleneck" or "spu_chain_buy" + return string.format(textOf(key), 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 + 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" + if status ~= nil and status ~= "ok" then return textOf(FLOW_KEYS[status] or "spu_chain_flowNone"), "waiting" end + if isTight(node, last, short) then return textOf("spu_chain_tight"), "waiting" end + if status == "ok" then return textOf("spu_chain_flowOk"), "running" end + return "", "running" end -local function joinCells(cells) +local function joinText(cells) local parts = {} for _, cell in ipairs(cells) do if cell ~= nil and cell ~= "" then table.insert(parts, cell) end @@ -112,51 +167,98 @@ local function joinCells(cells) 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)} +local function makeRow(kind, indent, level, cells, actions, toggle) + local fitted = fitCells(cells) + return {kind = kind, indent = indent, level = level, cells = fitted, actions = actions or {}, toggle = toggle, text = joinText(fitted)} 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 function suggestRow(action, indent, titleOf, textOf) 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 + local from = (action.from ~= nil and action.from ~= "") and titleOf(action.from) or "-" + local cells = {pad .. "F" .. tostring(action.fieldId) .. " " .. from, "→ " .. titleOf(action.to), haText(action.hectares) .. " ha"} + if action.mode == "suggest" then + cells[4], cells[5] = textOf("spu_chain_approve"), textOf("spu_chain_dismiss") + return makeRow("suggest", indent, "waiting", cells, + {[4] = {kind = "approve", fieldId = action.fieldId}, [5] = {kind = "dismiss", fieldId = action.fieldId}}) end + cells[4] = textOf("spu_chain_auto") + return makeRow("auto", indent, "running", cells) end -local ROOT_STATUS = {running = "spu_chain_rootOk", error = "spu_chain_rootError", waiting = "spu_chain_rootWaiting", stopped = "spu_chain_rootPaused"} +-- Handlinger for de afgrøder (i rækkefølge) der hentes fra mark under roden. +local function rootFruits(root) + local fruits, seen = {}, {} + eachNode(root.children, function(node) + if node.source == "field" and node.fruit ~= nil and not seen[node.fruit] then + seen[node.fruit] = true + table.insert(fruits, node.fruit) + end + end) + return fruits +end -local function rootRows(rows, root, last, titleOf, fmt, textOf, short) +local function actionsFor(last, fruit, modes) + local list = {} + for _, action in ipairs(last.actions or {}) do + if action.to == fruit and modes[action.mode] then table.insert(list, action) end + end + return list +end + +local function rootRows(rows, root, last, ctx, isExpanded) 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 suggestions = {} + for _, fruit in ipairs(rootFruits(root)) do + for _, action in ipairs(actionsFor(last, fruit, {suggest = true})) do table.insert(suggestions, action) end + end + local status = ctx.textOf(ROOT_STATUS[level]) + if #suggestions > 0 then status = string.format(ctx.textOf("spu_chain_rootSummary"), status, #suggestions) end + local marker = (#(root.children or {}) > 0) and (isExpanded and "– " or "+ ") or "" + table.insert(rows, makeRow("root", 0, level, {marker .. ctx.titleOf(root.name), tostring(root.buildingName or ""), "", status, + ctx.textOf(paused and "spu_chain_resume" or "spu_chain_pause")}, + {[5] = {kind = paused and "resume" or "pause", rootKey = root.key}}, root.key)) + if not isExpanded then + for _, action in ipairs(suggestions) do table.insert(rows, suggestRow(action, 1, ctx.titleOf, ctx.textOf)) end + return + end 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) + local text, nodeLevel = nodeStatus(node, last, ctx.fmt, ctx.textOf, ctx.short) + local stock = node.source == "field" and stockOf(last, node.fruit) or nil + local row = makeRow("node", depth, nodeLevel, {string.rep(ADChainView.INDENT, depth) .. ctx.titleOf(node.fillType), + sourceText(node, last, ctx.textOf), ctx.fmt(node.perMonth or 0), text, stock ~= nil and ctx.fmt(stock) or ""}) row.fillType = node.fillType table.insert(rows, row) - if node.source == "field" then actionRows(rows, node.fruit, depth + 1, last, titleOf, textOf, shown) end + if node.source == "field" and node.fruit ~= nil and not shown[node.fruit] then + shown[node.fruit] = true + for _, action in ipairs(actionsFor(last, node.fruit, {suggest = true, auto = true})) do + table.insert(rows, suggestRow(action, depth + 1, ctx.titleOf, ctx.textOf)) + end + end end) end +-- Pausede rødder: recipesWithPaused slukker dem, så modellen ser dem ikke som rødder -> grå linje med [Genoptag]. +local function pausedRows(rows, last, ctx) + local present, keys = {}, {} + for _, root in ipairs(last.chain ~= nil and last.chain.roots or {}) do present[root.key] = true end + for key in pairs(last.paused or {}) do + if not present[key] then table.insert(keys, key) end + end + table.sort(keys, function(a, b) return tostring(a) < tostring(b) end) + for _, key in ipairs(keys) do + local recipe + for _, candidate in ipairs(last.data ~= nil and last.data.recipes or {}) do + if candidate.key == key then recipe = candidate end + end + local name = recipe ~= nil and recipe.name ~= nil and ctx.titleOf(recipe.name) or tostring(key) + table.insert(rows, makeRow("root", 0, "stopped", {name, recipe ~= nil and tostring(recipe.buildingName or "") or "", "", + ctx.textOf("spu_chain_rootPaused"), ctx.textOf("spu_chain_resume")}, {[5] = {kind = "resume", rootKey = key}})) + end + return #keys +end + local function footerRows(rows, last, textOf) local free = {} for _, field in ipairs(last.fields or {}) do @@ -170,18 +272,25 @@ local function footerRows(rows, last, textOf) 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 +-- expanded = {[rodnøgle] = true} for udfoldede rødder (alle andre er foldet sammen). +function ADChainView.rows(last, titleOf, fmt, textOf, expanded) + textOf, fmt, expanded = textOf or identity, fmt or identity, expanded or {} 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 + local hasPaused = last ~= nil and next(last.paused or {}) ~= nil + if #roots == 0 and not hasPaused 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 + if #roots > 0 or hasPaused then + table.insert(rows, makeRow("header", 0, nil, {textOf("spu_chain_col_item"), textOf("spu_chain_col_source"), + textOf("spu_chain_col_perMonth"), textOf("spu_chain_col_status"), textOf("spu_chain_col_stock")})) + end + local ctx = {titleOf = titleOf, fmt = fmt, textOf = textOf, short = shortageByFruit(last)} + for _, root in ipairs(roots) do rootRows(rows, root, last, ctx, expanded[root.key] == true) end + pausedRows(rows, last, ctx) footerRows(rows, last, textOf) return rows end diff --git a/FS25_ADSmartPickup/gui/SmartPickupChainTab.lua b/FS25_ADSmartPickup/gui/SmartPickupChainTab.lua index e50e871..71d9c50 100644 --- a/FS25_ADSmartPickup/gui/SmartPickupChainTab.lua +++ b/FS25_ADSmartPickup/gui/SmartPickupChainTab.lua @@ -26,21 +26,46 @@ function SmartPickupFrame:chainTitle(last, name) return title or self:fruitTitle(name) end --- Klik på en kæde-knap: udfør, evaluér straks (ny visning) og genopbyg. +-- Klik på en kæde-knap: udfør, evaluér straks (ny visning) og genopbyg. Et forslag der ikke længere findes +-- (approve/dismiss -> false) meldes i statuslinjen som i "Kræver handling". function SmartPickupFrame:onChainAction(action) + local ok = true if action.kind == "approve" then - ADChain.approve(action.fieldId) + ok = ADChain.approve(action.fieldId) elseif action.kind == "dismiss" then - ADChain.dismiss(action.fieldId) + ok = ADChain.dismiss(action.fieldId) elseif action.kind == "pause" or action.kind == "resume" then ADChain.setPaused(action.rootKey, action.kind == "pause") end + if ok == false then + local text = self.i18n:getText("spu_chain_gone") + self.statusOverride, self.statusOverrideTicks = text, SmartPickupFrame.STATUS_OVERRIDE_TICKS + if ADFieldJobs ~= nil and ADFieldJobs.notify ~= nil then ADFieldJobs.notify(text, false) end + 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). +-- Klik på rodens linje uden for knappen: fold ud/sammen (huskes kun mens spillet kører). +function SmartPickupFrame:toggleChainRoot(rootKey) + self.chainExpanded = self.chainExpanded or {} + self.chainExpanded[rootKey] = not self.chainExpanded[rootKey] or nil + self:requestRebuild() +end + +-- Hvilken celle blev der klikket i? Højeste celle hvis venstre kant ligger til venstre for klikket. +local function clickedCell(frame, cells) + if frame.lastClickX == nil then return nil end + for index = #cells, 1, -1 do + local cell = cells[index] + if cell ~= nil and cell.absPosition ~= nil and frame.lastClickX >= cell.absPosition[1] then return index end + end + return nil +end + +-- Række med prik + c1..c5 (flowListPrefab). Knapper er celler (entry.actions[celle], som [Start]/[Stop] i +-- Flows-listen); et klik andetsteds på en rodlinje folder den ud/sammen. function SmartPickupFrame:addChainRow(entry) local unpackFn = table.unpack or unpack local row = self:addRow(self.flowListPrefab, {kind = "chainRow"}) @@ -48,21 +73,22 @@ function SmartPickupFrame:addChainRow(entry) 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 + local color = entry.level ~= nil and ADFlowView.LEVEL_COLORS[entry.level] or nil + if dot ~= nil and dot.setImageColor ~= nil and color ~= nil then dot:setImageColor(nil, unpackFn(color)) end + -- kun rod og varer har en status-prik (overskrift, forslag og auto-skift har ingen) + if dot ~= nil and dot.setVisible ~= nil and entry.kind ~= "root" and entry.kind ~= "node" then dot:setVisible(false) end + if cells[4] ~= nil and cells[4].setTextColor ~= nil and color ~= nil and entry.level ~= "running" and entry.kind ~= "suggest" then cells[4]:setTextColor(unpackFn(color)) end - if entry.action ~= nil then - local action, actionCell = entry.action, cells[5] + local actions, toggle = entry.actions or {}, entry.toggle + if next(actions) ~= nil or toggle ~= nil then 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 + local action = actions[clickedCell(frame, cells) or 0] + if action ~= nil then + frame:onChainAction(action) + elseif toggle ~= nil then + frame:toggleChainRoot(toggle) + end end) end return row @@ -72,7 +98,7 @@ 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) + SmartPickupFrame.formatCompact, function(key) return i18n:getText(key) end, self.chainExpanded or {}) for _, entry in ipairs(rows) do if entry.kind == "info" or entry.kind == "empty" then self:addTextRow(entry.text) diff --git a/FS25_ADSmartPickup/gui/SmartPickupFrame.lua b/FS25_ADSmartPickup/gui/SmartPickupFrame.lua index 148d0b8..3f86cd7 100644 --- a/FS25_ADSmartPickup/gui/SmartPickupFrame.lua +++ b/FS25_ADSmartPickup/gui/SmartPickupFrame.lua @@ -473,6 +473,7 @@ function SmartPickupFrame:rebuild() if adEnv ~= nil then self:fillChainRows(adEnv) end + self.statusRow = self:addTextRow(self.statusOverride or "") self.monthRebuildTicks = SmartPickupFrame.CHAIN_REBUILD_TICKS self:colorRows() self.boxLayout:invalidateLayout() @@ -653,6 +654,12 @@ function SmartPickupFrame:refreshLive() end if self.currentTab == SmartPickupFrame.TAB_MONTH or self.currentTab == SmartPickupFrame.TAB_FIELDSILOS or self.currentTab == SmartPickupFrame.TAB_CHAINS then + if self.currentTab == SmartPickupFrame.TAB_CHAINS then + -- "forslaget gælder ikke længere" står STATUS_OVERRIDE_TICKS sekunder + self.statusOverrideTicks = (self.statusOverrideTicks or 0) - 1 + if self.statusOverrideTicks <= 0 then self.statusOverride = nil end + self:setStatusText(self.statusOverride or "") + end self.monthRebuildTicks = (self.monthRebuildTicks or 0) - 1 if self.monthRebuildTicks <= 0 then self:requestRebuild() end self:refreshButtons() diff --git a/FS25_ADSmartPickup/l10n/l10n_da.xml b/FS25_ADSmartPickup/l10n/l10n_da.xml index 75a72ad..d2ade53 100644 --- a/FS25_ADSmartPickup/l10n/l10n_da.xml +++ b/FS25_ADSmartPickup/l10n/l10n_da.xml @@ -577,27 +577,33 @@ - - + + + + + + - + + - - + + - - - + + + - + - + - - + + + diff --git a/FS25_ADSmartPickup/l10n/l10n_en.xml b/FS25_ADSmartPickup/l10n/l10n_en.xml index f6a8c9b..64adee8 100644 --- a/FS25_ADSmartPickup/l10n/l10n_en.xml +++ b/FS25_ADSmartPickup/l10n/l10n_en.xml @@ -577,27 +577,33 @@ - - - - + + + + + + + + + - - + + - - - + + + - + - - + + +