19a10ab67c
problemText giver årsag og råd for køb/flaskehals/kredsløb og 'slukket af dig' (userOff-kopi på ADChain.last); modellens problemer får need. Fanen Kæder viser teksten som rød tekstrække under varen (foldet ud). Kræver handling får én rød post pr. kæde (højst 2, score 3500+alvor mellem rød tom og rød fuld); klik åbner fanen med kæden foldet ud. Engangsbesked pr. nyt led (rod|vare|art) kun fra tick, ikke i opstartsfristen eller på delvise data/ufærdig markscanning. Manualer og CHANGELOG opdateret.
143 lines
7.1 KiB
Lua
143 lines
7.1 KiB
Lua
-- Smart Pickup — "Kræver handling" -> flow (v1.60)
|
|
-- En "løber tør"-linje i lagerfanerne kan klikkes: findes der et flow der leverer varen til forbrugerne, åbnes
|
|
-- det; ligger varen andre steder på gården, åbnes "Nyt flow" udfyldt (ind til forbrugerne, varen valgt); ellers
|
|
-- siges det at et flow ikke hjælper (producér/køb). Afgørelsen er ADStorageStats.flowAdvice (testet).
|
|
-- Funktionerne lægges på SmartPickupFrame (indlæses efter SmartPickupFrame.lua).
|
|
|
|
local function fillTypeName(fillType)
|
|
return g_fillTypeManager ~= nil and g_fillTypeManager:getFillTypeNameByIndex(fillType) or tostring(fillType)
|
|
end
|
|
|
|
-- Forsyningsflow der allerede leverer varen til en af forbrugerne -> run eller nil.
|
|
local function existingSupplyRun(consumerIds, name)
|
|
for _, run in ipairs(ADRunsController.store.runs) do
|
|
if run.kind ~= "outbound" then
|
|
local carries = run.ingredientMode ~= "manual"
|
|
for _, ingredient in ipairs(run.ingredients or {}) do
|
|
if ingredient == name then carries = true end
|
|
end
|
|
if carries then
|
|
for _, id in ipairs(run.targetBuildingIds or {}) do
|
|
if consumerIds[id] then return run end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
-- Udkørselsflow der allerede sælger varen fra en af bygningerne -> run eller nil.
|
|
local function existingSellRun(sourceIds, name)
|
|
for _, run in ipairs(ADRunsController.store.runs) do
|
|
if run.kind == "outbound" then
|
|
local sells = false
|
|
for _, product in ipairs(run.products or {}) do
|
|
if product.fillType == name and (product.policy == "sell" or product.policy == "sellElseStore") then sells = true end
|
|
end
|
|
if sells then
|
|
for _, id in ipairs(run.sourceBuildingIds or {}) do
|
|
if sourceIds[id] then return run end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
-- "Sælg nu": kilder = fanens bygninger med varen.
|
|
local function sellAdviceFor(stat)
|
|
local sourceIds, ids = {}, {}
|
|
for _, building in ipairs(stat.buildings or {}) do
|
|
local id = building.placeable ~= nil and ADBuildings.getId(building.placeable) or nil
|
|
if id ~= nil and not sourceIds[id] then
|
|
sourceIds[id] = true
|
|
table.insert(ids, id)
|
|
end
|
|
end
|
|
local name = fillTypeName(stat.fillType)
|
|
local run = existingSellRun(sourceIds, name)
|
|
local advice = ADStorageStats.sellAdvice({sourceCount = #ids, existingRunId = run ~= nil and run.id or nil})
|
|
return advice, {buildingIds = ids, run = run, name = name, stat = stat, sell = true}
|
|
end
|
|
|
|
-- entry fra ADStorageStats.attentionList -> advice ("open"|"flow"|"produce"|"none"), info
|
|
function SmartPickupFrame:attentionAdvice(entry)
|
|
-- kæde-forslag og manglende led har ingen vare (stat): klik fører til fanen Kæder
|
|
if entry ~= nil and (entry.kind == "chainSuggest" or entry.kind == "chainProblem") 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
|
|
local consumers = ADStorageStats.consumersOf(self.lastFullInventory, stat.fillType)
|
|
local consumerIds, consumerLevel, ids = {}, 0, {}
|
|
for _, consumer in ipairs(consumers) do
|
|
consumerLevel = consumerLevel + consumer.level
|
|
local id = consumer.placeable ~= nil and ADBuildings.getId(consumer.placeable) or nil
|
|
if id ~= nil and not consumerIds[id] then
|
|
consumerIds[id] = true
|
|
table.insert(ids, id)
|
|
end
|
|
end
|
|
local name = fillTypeName(stat.fillType)
|
|
local run = existingSupplyRun(consumerIds, name)
|
|
local advice = ADStorageStats.flowAdvice({farmLevel = stat.farmLevel or stat.level, consumerLevel = consumerLevel,
|
|
perDay = stat.consumption, consumerCount = #ids, existingRunId = run ~= nil and run.id or nil})
|
|
return advice, {consumers = consumers, buildingIds = ids, run = run, name = name, stat = stat}
|
|
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
|
|
return ""
|
|
end
|
|
|
|
function SmartPickupFrame:onAttentionClick(entry)
|
|
self:safe(function(frame)
|
|
if entry ~= nil and (entry.kind == "chainSuggest" or entry.kind == "chainProblem") then
|
|
-- manglende led: kæden foldes ud, så problemteksten står under den røde linje
|
|
if entry.kind == "chainProblem" and entry.rootKey ~= nil then
|
|
frame.chainExpanded = frame.chainExpanded or {}
|
|
frame.chainExpanded[entry.rootKey] = true
|
|
end
|
|
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
|
|
if advice == "open" then
|
|
frame.selectedRunId = info.run.id
|
|
frame:switchTab(SmartPickupFrame.TAB_FLOWS)
|
|
frame:openEditPanel("flow", info.run.id)
|
|
return
|
|
end
|
|
if advice == "produce" then
|
|
local text = string.format(frame.i18n:getText("spu_attention_produce"), tostring(info.stat.title),
|
|
SmartPickupFrame.formatCompact(info.stat.farmLevel or 0))
|
|
frame.statusOverride, frame.statusOverrideTicks = text, SmartPickupFrame.STATUS_OVERRIDE_TICKS
|
|
if ADFieldJobs ~= nil and ADFieldJobs.notify ~= nil then ADFieldJobs.notify(text, false) end
|
|
return
|
|
end
|
|
local guide
|
|
if info.sell then
|
|
-- udfyldt "Nyt flow": ud af bygningerne med varen, varen til salg
|
|
local name = string.format(frame.i18n:getText("spu_attention_sellFlowName"), tostring(info.stat.title))
|
|
guide = ADFlowGuide.openNew(name, {})
|
|
guide.draft.kind = "outbound"
|
|
guide.draft.sourceBuildingIds = info.buildingIds
|
|
guide.draft.products = {{fillType = info.name, policy = "sell"}}
|
|
else
|
|
-- udfyldt "Nyt flow": ind til forbrugerne, kun denne vare; guiden åbnes på oversigten (Gem/Start eller [Ret])
|
|
local name = string.format(frame.i18n:getText("spu_attention_flowName"), tostring(info.stat.title), tostring(info.consumers[1].name))
|
|
guide = ADFlowGuide.openNew(name, {})
|
|
guide.draft.targetBuildingIds = info.buildingIds
|
|
guide.draft.ingredientMode = "manual"
|
|
guide.draft.ingredients = {info.name}
|
|
end
|
|
guide = ADGuide.new(ADFlowGuide.DEF, guide.draft, frame:flowGuideContext(adEnv, guide.draft), {step = "summary"})
|
|
frame:switchTab(SmartPickupFrame.TAB_FLOWS)
|
|
frame:openGuide("flow", guide)
|
|
end)
|
|
end
|