feat(kæde): kæder slås selv til ([Kæde til]/[Fjern]); tomme kædeflows slettes; runsView med traktorer (v1.62.0.0)
This commit is contained in:
@@ -6,6 +6,10 @@ står i [docs/BRUGERMANUAL.md](docs/BRUGERMANUAL.md) (dansk) og [docs/USER_MANUA
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 1.62 — Kæder slås selv til
|
||||||
|
|
||||||
|
- **1.62.0** **En kæde er noget du selv slår til:** tændte produktioner er ikke længere automatisk kæder (FS25 tænder nye produktioner som standard — 7 ensilagetårne gav 56 kæder og fik AIO-fabrikkens høproduktion tændt). Fanen **Kæder** har nederst *N tændte produktioner uden kæde* (foldet sammen); **[Kæde til]** gør en produktion til en kæde. En pauset kæde har **[Fjern]**. Ikke-valgte produktioner bruges stadig som kilde. Når en kæde fjernes, slettes dens tomme kædeflows (uden traktor), og mellemled kæden selv tændte slukkes igen. Rettet: kædens flowoversigt manglede traktorerne, så sammenlægning/oprydning kunne ramme et kædeflow med traktor. Udkørsel fra palleskur holder AutoDrive, mens moden tager paller ud.
|
||||||
|
|
||||||
## 1.61 — Produktionskæder
|
## 1.61 — Produktionskæder
|
||||||
|
|
||||||
- **1.61.13** Udkørsel fra palleskur: mens moden tager paller ud (én ad gangen), holdes AutoDrives egen pålæsning, så vognen ikke kører halvfuld, når triggeren et øjeblik er tom. Pålæsningen slutter, når vognen er fuld, lageret er tomt, eller skuret ikke har udleveret noget i 30 s.
|
- **1.61.13** Udkørsel fra palleskur: mens moden tager paller ud (én ad gangen), holdes AutoDrives egen pålæsning, så vognen ikke kører halvfuld, når triggeren et øjeblik er tom. Pålæsningen slutter, når vognen er fuld, lageret er tomt, eller skuret ikke har udleveret noget i 30 s.
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ ADChain.LOG_PREFIX = "ADSmartPickup: kæde: "
|
|||||||
-- Et afvist forslag vises igen, når manglen for afgrøden har ændret sig mere end dette.
|
-- Et afvist forslag vises igen, når manglen for afgrøden har ændret sig mere end dette.
|
||||||
ADChain.DISMISS_CHANGE = 0.25
|
ADChain.DISMISS_CHANGE = 0.25
|
||||||
|
|
||||||
ADChain.state = {byChain = {}, paused = {}, dismissed = {}, userOff = {}, finalKeep = {}, soldByChain = {}}
|
ADChain.state = {byChain = {}, paused = {}, dismissed = {}, userOff = {}, finalKeep = {}, soldByChain = {}, optIn = {}}
|
||||||
ADChain.last = nil
|
ADChain.last = nil
|
||||||
-- {[nøgle] = true}: produktioner (ikke kædens) der var tændt ved sidste tick — til at se spillerens slukninger
|
-- {[nøgle] = true}: produktioner (ikke kædens) der var tændt ved sidste tick — til at se spillerens slukninger
|
||||||
ADChain.prevEnabled = nil
|
ADChain.prevEnabled = nil
|
||||||
@@ -54,13 +54,15 @@ end
|
|||||||
-- roots = {[recipeKey] = true} rødderne ved sidste tick (nil = ukendt, fx gem fra en ældre version).
|
-- roots = {[recipeKey] = true} rødderne ved sidste tick (nil = ukendt, fx gem fra en ældre version).
|
||||||
function ADChain.newState()
|
function ADChain.newState()
|
||||||
-- finalKeep = {[rodnøgle] = true}: slutproduktet beholdes (standard: sælg straks); soldByChain = {["rod|vare"] = true}
|
-- finalKeep = {[rodnøgle] = true}: slutproduktet beholdes (standard: sælg straks); soldByChain = {["rod|vare"] = true}
|
||||||
return {byChain = {}, paused = {}, dismissed = {}, userOff = {}, roots = nil, finalKeep = {}, soldByChain = {}}
|
-- optIn = {[opskriftsnøgle] = true}: produktioner spilleren selv har slået til som kæde (tændte produktioner er
|
||||||
|
-- ellers ikke kæder — FS25 tænder dem som standard)
|
||||||
|
return {byChain = {}, paused = {}, dismissed = {}, userOff = {}, roots = nil, finalKeep = {}, soldByChain = {}, optIn = {}}
|
||||||
end
|
end
|
||||||
|
|
||||||
function ADChain.stateToRecords(state)
|
function ADChain.stateToRecords(state)
|
||||||
local records = {byChain = sortedKeys(state.byChain), paused = sortedKeys(state.paused), userOff = sortedKeys(state.userOff), dismissed = {},
|
local records = {byChain = sortedKeys(state.byChain), paused = sortedKeys(state.paused), userOff = sortedKeys(state.userOff), dismissed = {},
|
||||||
roots = state.roots ~= nil and sortedKeys(state.roots) or nil,
|
roots = state.roots ~= nil and sortedKeys(state.roots) or nil,
|
||||||
finalKeep = sortedKeys(state.finalKeep or {}), soldByChain = sortedKeys(state.soldByChain or {})}
|
finalKeep = sortedKeys(state.finalKeep or {}), soldByChain = sortedKeys(state.soldByChain or {}), optIn = sortedKeys(state.optIn or {})}
|
||||||
local ids = {}
|
local ids = {}
|
||||||
for id in pairs(state.dismissed or {}) do table.insert(ids, id) end
|
for id in pairs(state.dismissed or {}) do table.insert(ids, id) end
|
||||||
table.sort(ids)
|
table.sort(ids)
|
||||||
@@ -79,6 +81,7 @@ function ADChain.stateFromRecords(records)
|
|||||||
for _, key in ipairs(records.userOff or {}) do state.userOff[key] = true end
|
for _, key in ipairs(records.userOff or {}) do state.userOff[key] = true end
|
||||||
for _, key in ipairs(records.finalKeep or {}) do state.finalKeep[key] = true end
|
for _, key in ipairs(records.finalKeep or {}) do state.finalKeep[key] = true end
|
||||||
for _, key in ipairs(records.soldByChain or {}) do state.soldByChain[key] = true end
|
for _, key in ipairs(records.soldByChain or {}) do state.soldByChain[key] = true end
|
||||||
|
for _, key in ipairs(records.optIn or {}) do state.optIn[key] = true end
|
||||||
if records.roots ~= nil then
|
if records.roots ~= nil then
|
||||||
state.roots = {}
|
state.roots = {}
|
||||||
for _, key in ipairs(records.roots) do state.roots[key] = true end
|
for _, key in ipairs(records.roots) do state.roots[key] = true end
|
||||||
@@ -123,12 +126,15 @@ end
|
|||||||
|
|
||||||
-- Modellens kopi af opskrifterne: pausede rødder markeres paused (kører for sig selv, men skaber intet nyt), og
|
-- Modellens kopi af opskrifterne: pausede rødder markeres paused (kører for sig selv, men skaber intet nyt), og
|
||||||
-- slukkede userOff-produktioner får 0 cyklusser (de dækker intet behov). Originalerne røres ikke.
|
-- slukkede userOff-produktioner får 0 cyklusser (de dækker intet behov). Originalerne røres ikke.
|
||||||
function ADChain.modelRecipes(recipes, paused, userOff)
|
-- optIn = {[nøgle] = true}: kun de produktioner er rødder (andre tændte markeres notChosen: kører for sig selv som
|
||||||
|
-- kilde, men kæden skaber intet for dem). optIn = nil = alle tændte er rødder (som før).
|
||||||
|
function ADChain.modelRecipes(recipes, paused, userOff, optIn)
|
||||||
local result = {}
|
local result = {}
|
||||||
for index, recipe in ipairs(recipes or {}) do
|
for index, recipe in ipairs(recipes or {}) do
|
||||||
local copy = {}
|
local copy = {}
|
||||||
for key, value in pairs(recipe) do copy[key] = value end
|
for key, value in pairs(recipe) do copy[key] = value end
|
||||||
if (paused or {})[recipe.key] then copy.paused = true end
|
if (paused or {})[recipe.key] then copy.paused = true end
|
||||||
|
if optIn ~= nil and recipe.enabled and not recipe.byChain and not optIn[recipe.key] then copy.notChosen = true end
|
||||||
if (userOff or {})[recipe.key] and not recipe.enabled then copy.cyclesPerMonth = 0 end
|
if (userOff or {})[recipe.key] and not recipe.enabled then copy.cyclesPerMonth = 0 end
|
||||||
result[index] = copy
|
result[index] = copy
|
||||||
end
|
end
|
||||||
@@ -263,7 +269,9 @@ function ADChain.runsView(runs)
|
|||||||
for _, run in ipairs(runs or {}) do
|
for _, run in ipairs(runs or {}) do
|
||||||
table.insert(list, {id = run.id, name = run.name, kind = run.kind, targetBuildingIds = run.targetBuildingIds,
|
table.insert(list, {id = run.id, name = run.name, kind = run.kind, targetBuildingIds = run.targetBuildingIds,
|
||||||
ingredientMode = run.ingredientMode, ingredients = run.ingredients, stopped = run.stopped == true,
|
ingredientMode = run.ingredientMode, ingredients = run.ingredients, stopped = run.stopped == true,
|
||||||
chain = run.chain, waitPoolGroup = run.waitPoolGroup})
|
chain = run.chain, waitPoolGroup = run.waitPoolGroup,
|
||||||
|
-- traktorerne: uden dem ligner alle kædeflows tomme (sammenlægning/sletning må kun ramme tomme)
|
||||||
|
vehicleIds = run.vehicleIds or {}})
|
||||||
end
|
end
|
||||||
return list
|
return list
|
||||||
end
|
end
|
||||||
@@ -293,12 +301,12 @@ local function farmId()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function plan(data, state)
|
local function plan(data, state)
|
||||||
local recipes = ADChain.modelRecipes(data.recipes, state.paused, state.userOff)
|
local recipes = ADChain.modelRecipes(data.recipes, state.paused, state.userOff, state.optIn)
|
||||||
local chain = ADChainModel.build(recipes, data.husbandry, data.crops, data.fieldGoods)
|
local chain = ADChainModel.build(recipes, data.husbandry, data.crops, data.fieldGoods)
|
||||||
-- pausede rødder: det de bruger, er beskyttet mod slukning (modellen regnet som om de ikke var pauset)
|
-- pausede rødder: det de bruger, er beskyttet mod slukning (modellen regnet som om de ikke var pauset)
|
||||||
local protected = {}
|
local protected = {}
|
||||||
if next(state.paused) ~= nil then
|
if next(state.paused) ~= nil then
|
||||||
protected = ADChainModel.build(ADChain.modelRecipes(data.recipes, {}, state.userOff), data.husbandry, data.crops, data.fieldGoods).needRecipes
|
protected = ADChainModel.build(ADChain.modelRecipes(data.recipes, {}, state.userOff, state.optIn), data.husbandry, data.crops, data.fieldGoods).needRecipes
|
||||||
end
|
end
|
||||||
local used = ADChain.unionFruits(data.usedFruits, chain.fieldDemand)
|
local used = ADChain.unionFruits(data.usedFruits, chain.fieldDemand)
|
||||||
-- ufuldstændig markliste: udbuddet ville være undervurderet -> ingen mangler, forslag eller markskift endnu
|
-- ufuldstændig markliste: udbuddet ville være undervurderet -> ingen mangler, forslag eller markskift endnu
|
||||||
@@ -383,7 +391,7 @@ function ADChain.evaluate(adEnv, act)
|
|||||||
ADChain.last = {chain = result.chain, shortages = result.shortages, actions = result.actions, edges = result.edges,
|
ADChain.last = {chain = result.chain, shortages = result.shortages, actions = result.actions, edges = result.edges,
|
||||||
missingFlows = ADChainActions.missingFlows(result.edges, runs), flowStatus = ADChain.flowStatus(result.edges, runs, ADChain.noVehicle),
|
missingFlows = ADChainActions.missingFlows(result.edges, runs), flowStatus = ADChain.flowStatus(result.edges, runs, ADChain.noVehicle),
|
||||||
paused = paused, userOff = copySet(state.userOff), finalKeep = copySet(state.finalKeep or {}),
|
paused = paused, userOff = copySet(state.userOff), finalKeep = copySet(state.finalKeep or {}),
|
||||||
sellable = ADChain.sellableRoots(data, result, runs), data = data, fields = data.fields, fieldsIncomplete = data.fieldsIncomplete == true, titles = data.fillTitles, at = ADChain.now, switchCount = ADChain.switchCount,
|
sellable = ADChain.sellableRoots(data, result, runs), candidates = ADChain.candidates(data.recipes, state), data = data, fields = data.fields, fieldsIncomplete = data.fieldsIncomplete == true, titles = data.fillTitles, at = ADChain.now, switchCount = ADChain.switchCount,
|
||||||
dependency = dependency}
|
dependency = dependency}
|
||||||
return ADChain.last
|
return ADChain.last
|
||||||
end
|
end
|
||||||
@@ -496,6 +504,29 @@ function ADChain.dismiss(fieldId)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Tændte produktioner der ikke er valgt som kæde (og ikke pauset): {{key, name, buildingName}} til fanen Kæder.
|
||||||
|
function ADChain.candidates(recipes, state)
|
||||||
|
local list = {}
|
||||||
|
for _, recipe in ipairs(recipes or {}) do
|
||||||
|
if recipe.enabled and not recipe.byChain and not (state.optIn or {})[recipe.key] and not (state.paused or {})[recipe.key] then
|
||||||
|
table.insert(list, {key = recipe.key, name = recipe.name, buildingName = recipe.buildingName})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.sort(list, function(a, b)
|
||||||
|
if tostring(a.buildingName) ~= tostring(b.buildingName) then return tostring(a.buildingName) < tostring(b.buildingName) end
|
||||||
|
return tostring(a.name) < tostring(b.name)
|
||||||
|
end)
|
||||||
|
return list
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Slå en produktion til/fra som kæde (fra = også pausen ophæves, kæden slipper den ved næste tick).
|
||||||
|
function ADChain.setOptIn(recipeKey, on)
|
||||||
|
if recipeKey == nil then return end
|
||||||
|
ADChain.state.optIn[recipeKey] = on and true or nil
|
||||||
|
if not on then ADChain.state.paused[recipeKey] = nil end
|
||||||
|
Logging.info(ADChain.LOG_PREFIX .. "%s %s", tostring(recipeKey), on and "slået til som kæde" or "fjernet fra kæderne")
|
||||||
|
end
|
||||||
|
|
||||||
-- Rødder med et slutprodukt der kan sælges straks (gården bruger det ikke selv). -> {[rodnøgle] = true}
|
-- Rødder med et slutprodukt der kan sælges straks (gården bruger det ikke selv). -> {[rodnøgle] = true}
|
||||||
function ADChain.sellableRoots(data, result, runs)
|
function ADChain.sellableRoots(data, result, runs)
|
||||||
local set = {}
|
local set = {}
|
||||||
@@ -546,6 +577,9 @@ function ADChain.save()
|
|||||||
for index, key in ipairs(records.soldByChain) do
|
for index, key in ipairs(records.soldByChain) do
|
||||||
xmlFile:setString(string.format("%s.soldByChain.output(%d)#key", ADChain.ROOT, index - 1), key)
|
xmlFile:setString(string.format("%s.soldByChain.output(%d)#key", ADChain.ROOT, index - 1), key)
|
||||||
end
|
end
|
||||||
|
for index, key in ipairs(records.optIn) do
|
||||||
|
xmlFile:setString(string.format("%s.optIn.recipe(%d)#key", ADChain.ROOT, index - 1), key)
|
||||||
|
end
|
||||||
if records.roots ~= nil then
|
if records.roots ~= nil then
|
||||||
xmlFile:setBool(ADChain.ROOT .. ".roots#known", true)
|
xmlFile:setBool(ADChain.ROOT .. ".roots#known", true)
|
||||||
for index, key in ipairs(records.roots) do
|
for index, key in ipairs(records.roots) do
|
||||||
@@ -573,7 +607,10 @@ function ADChain.load()
|
|||||||
if path == nil or not fileExists(path) then return end
|
if path == nil or not fileExists(path) then return end
|
||||||
local xmlFile = XMLFile.load("ADSmartPickupChain", path)
|
local xmlFile = XMLFile.load("ADSmartPickupChain", path)
|
||||||
if xmlFile == nil then return end
|
if xmlFile == nil then return end
|
||||||
local records = {byChain = {}, paused = {}, userOff = {}, dismissed = {}, finalKeep = {}, soldByChain = {}}
|
local records = {byChain = {}, paused = {}, userOff = {}, dismissed = {}, finalKeep = {}, soldByChain = {}, optIn = {}}
|
||||||
|
xmlFile:iterate(ADChain.ROOT .. ".optIn.recipe", function(_, key)
|
||||||
|
table.insert(records.optIn, xmlFile:getString(key .. "#key"))
|
||||||
|
end)
|
||||||
xmlFile:iterate(ADChain.ROOT .. ".finalKeep.root", function(_, key)
|
xmlFile:iterate(ADChain.ROOT .. ".finalKeep.root", function(_, key)
|
||||||
table.insert(records.finalKeep, xmlFile:getString(key .. "#key"))
|
table.insert(records.finalKeep, xmlFile:getString(key .. "#key"))
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -59,7 +59,9 @@ end
|
|||||||
function ADChainActions.flowsToStop(runs, activeRootKeys)
|
function ADChainActions.flowsToStop(runs, activeRootKeys)
|
||||||
local list = {}
|
local list = {}
|
||||||
for _, run in ipairs(runs or {}) do
|
for _, run in ipairs(runs or {}) do
|
||||||
if run.chain ~= nil and run.chain ~= "" and not run.stopped and not (activeRootKeys or {})[run.chain] then
|
-- også stoppede kædeflows uden traktor (de ryddes op); stoppede med traktor er allerede sluppet/spillerens
|
||||||
|
local idle = #(run.vehicleIds or {}) == 0
|
||||||
|
if run.chain ~= nil and run.chain ~= "" and (not run.stopped or idle) and not (activeRootKeys or {})[run.chain] then
|
||||||
table.insert(list, run)
|
table.insert(list, run)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -163,3 +165,10 @@ function ADChainActions.finalSales(chain, recipes, edges, keep, farmUses)
|
|||||||
end
|
end
|
||||||
return list
|
return list
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Kædeflow for en kæde der er slået fra: uden traktor slettes det (auto-oprettet og tomt), ellers stoppes og slippes
|
||||||
|
-- det (bliver spillerens eget). (in-game 30/9: ellers 12 tomme "Kæde: …"-flows blandt spillerens egne)
|
||||||
|
function ADChainActions.releaseAction(run)
|
||||||
|
if #(run.vehicleIds or {}) == 0 then return "delete" end
|
||||||
|
return "release"
|
||||||
|
end
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ function ADChainModel.build(recipes, husbandry, crops, fieldGoods)
|
|||||||
for _, recipe in ipairs(recipes or {}) do
|
for _, recipe in ipairs(recipes or {}) do
|
||||||
capacity[recipe.key] = recipe.cyclesPerMonth or 0
|
capacity[recipe.key] = recipe.cyclesPerMonth or 0
|
||||||
if recipe.enabled and not recipe.byChain then
|
if recipe.enabled and not recipe.byChain then
|
||||||
if not recipe.paused then table.insert(roots, recipe) end
|
if not recipe.paused and not recipe.notChosen then table.insert(roots, recipe) end
|
||||||
standalone[recipe.key] = true
|
standalone[recipe.key] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -292,6 +292,15 @@ function ADChainRun.stopFlows(adEnv, chain, edges)
|
|||||||
ADRunsController.updateRun(run.id, {chain = rootKey})
|
ADRunsController.updateRun(run.id, {chain = rootKey})
|
||||||
log("flow '%s' hører nu til kæden %s", tostring(run.name), tostring(rootKey))
|
log("flow '%s' hører nu til kæden %s", tostring(run.name), tostring(rootKey))
|
||||||
changed = changed + 1
|
changed = changed + 1
|
||||||
|
elseif ADChainActions.releaseAction(run) == "delete" then
|
||||||
|
local ok, err = pcall(ADRunsController.deleteRun, run.id, adEnv)
|
||||||
|
if ok then
|
||||||
|
ADChain.noVehicle[run.id] = nil
|
||||||
|
log("tomt kædeflow '%s' slettet: kæden %s er slået fra", tostring(run.name), tostring(run.chain))
|
||||||
|
changed = changed + 1
|
||||||
|
else
|
||||||
|
warn("flow '%s' kunne ikke slettes: %s", tostring(run.name), tostring(err))
|
||||||
|
end
|
||||||
else
|
else
|
||||||
local ok, err = pcall(ADRunsController.stopRun, adEnv, run.id)
|
local ok, err = pcall(ADRunsController.stopRun, adEnv, run.id)
|
||||||
if ok then
|
if ok then
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ ADChainView.TEXT_ROW_CHARS = 70
|
|||||||
-- "stramt": lager for en mark-afgrøde under så mange måneders behov -> gul
|
-- "stramt": lager for en mark-afgrøde under så mange måneders behov -> gul
|
||||||
ADChainView.TIGHT_MONTHS = 3
|
ADChainView.TIGHT_MONTHS = 3
|
||||||
-- nøgler rækkerne bruger (til l10n-testen)
|
-- nøgler rækkerne bruger (til l10n-testen)
|
||||||
ADChainView.TEXT_KEYS = {"spu_chain_finalFarm", "spu_chain_finalSell", "spu_chain_finalKeep", "spu_chain_suggestHeader", "spu_chain_empty", "spu_chain_approve", "spu_chain_dismiss", "spu_chain_auto",
|
ADChainView.TEXT_KEYS = {"spu_chain_optIn", "spu_chain_optOut", "spu_chain_notChosen", "spu_chain_candidatesShow", "spu_chain_candidatesHide", "spu_chain_finalFarm", "spu_chain_finalSell", "spu_chain_finalKeep", "spu_chain_suggestHeader", "spu_chain_empty", "spu_chain_approve", "spu_chain_dismiss", "spu_chain_auto",
|
||||||
"spu_chain_flowOk", "spu_chain_flowMissing", "spu_chain_flowPallet", "spu_chain_flowNone", "spu_chain_flowStopped", "spu_chain_bottleneck",
|
"spu_chain_flowOk", "spu_chain_flowMissing", "spu_chain_flowPallet", "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_fromFields",
|
"spu_chain_buy", "spu_chain_cycle", "spu_chain_fieldShort", "spu_chain_tight", "spu_chain_noField", "spu_chain_buySource", "spu_chain_fromFields",
|
||||||
"spu_chain_pause", "spu_chain_resume", "spu_chain_scanning", "spu_chain_rootOk", "spu_chain_rootError", "spu_chain_rootWaiting",
|
"spu_chain_pause", "spu_chain_resume", "spu_chain_scanning", "spu_chain_rootOk", "spu_chain_rootError", "spu_chain_rootWaiting",
|
||||||
@@ -372,12 +372,27 @@ local function pausedRows(rows, last, ctx)
|
|||||||
if candidate.key == key then recipe = candidate end
|
if candidate.key == key then recipe = candidate end
|
||||||
end
|
end
|
||||||
local name = recipe ~= nil and recipe.name ~= nil and ctx.titleOf(recipe.name) or tostring(key)
|
local name = recipe ~= nil and recipe.name ~= nil and ctx.titleOf(recipe.name) or tostring(key)
|
||||||
|
-- pauset kæde: [Start] genoptager, [Fjern] tager den ud af kæderne
|
||||||
table.insert(rows, makeRow("root", 0, "stopped", {name, recipe ~= nil and tostring(recipe.buildingName or "") or "", "",
|
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}}))
|
ctx.textOf("spu_chain_optOut"), ctx.textOf("spu_chain_resume")},
|
||||||
|
{[4] = {kind = "optOut", rootKey = key}, [5] = {kind = "resume", rootKey = key}}))
|
||||||
end
|
end
|
||||||
return #keys
|
return #keys
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Tændte produktioner uden kæde: foldet sammen under én linje; udfoldet med [Kæde til] pr. produktion.
|
||||||
|
local function candidateRows(rows, last, ctx, isExpanded)
|
||||||
|
local list = last.candidates or {}
|
||||||
|
if #list == 0 then return end
|
||||||
|
local key = isExpanded and "spu_chain_candidatesHide" or "spu_chain_candidatesShow"
|
||||||
|
table.insert(rows, makeRow("root", 0, nil, {(isExpanded and "– " or "+ ") .. string.format(ctx.textOf(key), #list), "", "", "", ""}, {}, "__candidates"))
|
||||||
|
if not isExpanded then return end
|
||||||
|
for _, candidate in ipairs(list) do
|
||||||
|
table.insert(rows, makeRow("root", 1, nil, {ADChainView.INDENT .. ctx.titleOf(candidate.name), tostring(candidate.buildingName or ""), "",
|
||||||
|
ctx.textOf("spu_chain_notChosen"), ctx.textOf("spu_chain_optIn")}, {[5] = {kind = "optIn", rootKey = candidate.key}}))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- "Marker fri til kæden: F1, F2 +k" — så mange navne som tekstlinjen kan rumme, resten talt.
|
-- "Marker fri til kæden: F1, F2 +k" — så mange navne som tekstlinjen kan rumme, resten talt.
|
||||||
function ADChainView.freeText(names, textOf)
|
function ADChainView.freeText(names, textOf)
|
||||||
local format = textOf("spu_chain_free")
|
local format = textOf("spu_chain_free")
|
||||||
@@ -430,6 +445,7 @@ function ADChainView.rows(last, titleOf, fmt, textOf, expanded)
|
|||||||
end
|
end
|
||||||
for _, root in ipairs(ADChainView.sortRoots(roots, last)) do rootRows(rows, root, last, ctx, expanded[root.key] == true) end
|
for _, root in ipairs(ADChainView.sortRoots(roots, last)) do rootRows(rows, root, last, ctx, expanded[root.key] == true) end
|
||||||
pausedRows(rows, last, ctx)
|
pausedRows(rows, last, ctx)
|
||||||
|
candidateRows(rows, last, ctx, expanded["__candidates"] == true)
|
||||||
footerRows(rows, last, textOf)
|
footerRows(rows, last, textOf)
|
||||||
return rows
|
return rows
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ function SmartPickupFrame:onChainAction(action)
|
|||||||
ok = ADChain.approve(action.fieldId)
|
ok = ADChain.approve(action.fieldId)
|
||||||
elseif action.kind == "dismiss" then
|
elseif action.kind == "dismiss" then
|
||||||
ok = ADChain.dismiss(action.fieldId)
|
ok = ADChain.dismiss(action.fieldId)
|
||||||
|
elseif action.kind == "optIn" or action.kind == "optOut" then
|
||||||
|
ADChain.setOptIn(action.rootKey, action.kind == "optIn")
|
||||||
elseif action.kind == "finalMode" then
|
elseif action.kind == "finalMode" then
|
||||||
ADChain.setFinalKeep(action.rootKey, action.keep)
|
ADChain.setFinalKeep(action.rootKey, action.keep)
|
||||||
elseif action.kind == "pause" or action.kind == "resume" then
|
elseif action.kind == "pause" or action.kind == "resume" then
|
||||||
|
|||||||
@@ -584,6 +584,11 @@
|
|||||||
<text name="spu_item_share" text="%d %% af varen"/>
|
<text name="spu_item_share" text="%d %% af varen"/>
|
||||||
<text name="spu_tab_chains" text="Kæder"/>
|
<text name="spu_tab_chains" text="Kæder"/>
|
||||||
<text name="spu_chain_noFlow" text="Intet flow kører den vare endnu — kæden opretter det, når der er en ledig traktor/vogn"/>
|
<text name="spu_chain_noFlow" text="Intet flow kører den vare endnu — kæden opretter det, når der er en ledig traktor/vogn"/>
|
||||||
|
<text name="spu_chain_optIn" text="[Kæde til]"/>
|
||||||
|
<text name="spu_chain_optOut" text="[Fjern]"/>
|
||||||
|
<text name="spu_chain_notChosen" text="ingen kæde"/>
|
||||||
|
<text name="spu_chain_candidatesShow" text="%d tændte produktioner uden kæde — klik for at vise"/>
|
||||||
|
<text name="spu_chain_candidatesHide" text="%d tændte produktioner uden kæde — klik for at skjule"/>
|
||||||
<text name="spu_chain_finalFarm" text="Gård"/>
|
<text name="spu_chain_finalFarm" text="Gård"/>
|
||||||
<text name="spu_chain_finalSell" text="Sælg"/>
|
<text name="spu_chain_finalSell" text="Sælg"/>
|
||||||
<text name="spu_chain_finalKeep" text="Behold"/>
|
<text name="spu_chain_finalKeep" text="Behold"/>
|
||||||
|
|||||||
@@ -584,6 +584,11 @@
|
|||||||
<text name="spu_item_share" text="%d %% of the good"/>
|
<text name="spu_item_share" text="%d %% of the good"/>
|
||||||
<text name="spu_tab_chains" text="Chains"/>
|
<text name="spu_tab_chains" text="Chains"/>
|
||||||
<text name="spu_chain_noFlow" text="No flow carries that good yet — the chain creates one when a tractor/trailer is free"/>
|
<text name="spu_chain_noFlow" text="No flow carries that good yet — the chain creates one when a tractor/trailer is free"/>
|
||||||
|
<text name="spu_chain_optIn" text="[Chain on]"/>
|
||||||
|
<text name="spu_chain_optOut" text="[Remove]"/>
|
||||||
|
<text name="spu_chain_notChosen" text="no chain"/>
|
||||||
|
<text name="spu_chain_candidatesShow" text="%d productions on without a chain — click to show"/>
|
||||||
|
<text name="spu_chain_candidatesHide" text="%d productions on without a chain — click to hide"/>
|
||||||
<text name="spu_chain_finalFarm" text="Farm"/>
|
<text name="spu_chain_finalFarm" text="Farm"/>
|
||||||
<text name="spu_chain_finalSell" text="Sell"/>
|
<text name="spu_chain_finalSell" text="Sell"/>
|
||||||
<text name="spu_chain_finalKeep" text="Keep"/>
|
<text name="spu_chain_finalKeep" text="Keep"/>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
<modDesc descVersion="107">
|
<modDesc descVersion="107">
|
||||||
<author>masterdraco</author>
|
<author>masterdraco</author>
|
||||||
<version>1.61.13.0</version>
|
<version>1.62.0.0</version>
|
||||||
<title>
|
<title>
|
||||||
<en>AD Smart Pickup</en>
|
<en>AD Smart Pickup</en>
|
||||||
</title>
|
</title>
|
||||||
|
|||||||
Reference in New Issue
Block a user