-- Smart Pickup — fanen Udkørsel -- Kilder (afkrydsning), varer med politik (Fra/Lager/Salg/Salg, ellers lager) og aktuel pris i -- % af årets top, regler (pristærskel, lagertærskel, opsamlingsrunde) og status/advarsler. -- Funktionerne lægges på SmartPickupFrame (indlæses efter SmartPickupFrame.lua). -- Bedste pris-% for varen over alle salgssteder (uanset vejnet — det er til visning; turen -- bruger kun nåelige). {percent, stationName} eller nil. function SmartPickupFrame:getProductQuote(adEnv, fillType) if ADSources == nil or ADPrices == nil then return nil end local best = nil for _, entry in ipairs(ADSources.getSellMarkers(adEnv, g_currentMission:getFarmId())) do if ADSources.stationAccepts(entry.station, fillType) then local quote = ADPrices.getQuote(entry.station, fillType) if quote ~= nil and (best == nil or quote.percent > best.percent) then best = {percent = quote.percent, stationName = tostring(entry.marker.name)} end end end return best end -- "Sukker — 150.0k l — 78 % af top (Grain Elevator)" function SmartPickupFrame:describeProduct(adEnv, product) local price = self.i18n:getText("spu_price_none") local quote = self:getProductQuote(adEnv, product.fillType) if quote ~= nil then price = string.format(self.i18n:getText("spu_price_pct"), quote.percent, quote.stationName) end return string.format(self.i18n:getText("spu_product_row"), tostring(product.title), SmartPickupFrame.formatCompact(product.available or 0), price) end function SmartPickupFrame:getPolicyIndex(policy) for index, name in ipairs(SmartPickupFrame.POLICIES) do if name == policy then return index end end return 1 end function SmartPickupFrame:fillSourceRows(adEnv, run) local chosen = {} for _, id in ipairs(run.sourceWayPointIds or {}) do chosen[id] = true end local entries = ADRunsController.getSourceMarkers(adEnv, g_currentMission:getFarmId()) for _, entry in ipairs(entries) do local row = self:addRow(self.ingredientPrefab, {kind = "source", wayPointId = entry.marker.id}) local kindText = self.i18n:getText("spu_source_kind_" .. tostring(entry.kind)) row:getDescendantByName("title"):setText(string.format(" %s — %s (%s)", tostring(entry.marker.name), tostring(entry.name), kindText)) row:getDescendantByName("option"):setState(chosen[entry.marker.id] and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, false) end if #entries == 0 then self:addTextRow(self.i18n:getText("spu_noSources")) end end function SmartPickupFrame:fillProductRows(adEnv, run) self.productRows = {} local policyTexts = {} for _, policy in ipairs(SmartPickupFrame.POLICIES) do table.insert(policyTexts, self.i18n:getText("spu_policy_" .. policy)) end local products = ADRunsController.getRunProducts(adEnv, run) for _, product in ipairs(products) do local row = self:addRow(self.productPrefab, {kind = "product", name = product.name}) local option = row:getDescendantByName("option") option:setTexts(policyTexts) option:setState(self:getPolicyIndex(product.policy), false) local title = row:getDescendantByName("title") title:setText(self:describeProduct(adEnv, product)) table.insert(self.productRows, {name = product.name, title = title, option = option}) end if #products == 0 then self:addTextRow(#(run.sourceWayPointIds or {}) == 0 and self.i18n:getText("spu_noSources") or self.i18n:getText("spu_noProducts")) end end function SmartPickupFrame:fillOutboundStatusRows(adEnv, run) self.outboundStatusRows = {} local status = ADRunsController.getOutboundStatus(adEnv, run) for _, reason in ipairs(status.reasons or {}) do table.insert(self.outboundStatusRows, self:addTextRow(string.format(self.i18n:getText("spu_outbound_waiting"), reason))) end if status.warning ~= nil then table.insert(self.outboundStatusRows, self:addTextRow(string.format(self.i18n:getText("spu_outbound_warning"), status.warning))) end end function SmartPickupFrame:rebuildOutboundTab(adEnv, run) self.sellAtOption:setState(SmartPickupFrame.getStepIndex(self.sellAtSteps, run.sellAtPercent, ADRuns.DEFAULT_SELL_AT_PERCENT), false) self.storeAboveOption:setState(SmartPickupFrame.getStepIndex(self.storeAboveSteps, run.storeAbovePercent, ADRuns.DEFAULT_STORE_ABOVE_PERCENT), false) self.collectRoundOption:setState(run.collectRound and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, false) self:addTextRow(self.i18n:getText("spu_section_sources")) self:fillSourceRows(adEnv, run) self:addTextRow(self.i18n:getText("spu_section_products")) self:fillProductRows(adEnv, run) self:fillOutboundStatusRows(adEnv, run) end -- Hvert sekund: produktrækkernes mængde/pris og statuslinjerne (antal linjer ændres kun ved rebuild). function SmartPickupFrame:refreshOutboundRows(adEnv, run) local byName = {} for _, product in ipairs(ADRunsController.getRunProducts(adEnv, run)) do byName[product.name] = product end for _, row in ipairs(self.productRows or {}) do if byName[row.name] ~= nil then row.title:setText(self:describeProduct(adEnv, byName[row.name])) end end local status = ADRunsController.getOutboundStatus(adEnv, run) local lines = {} for _, reason in ipairs(status.reasons or {}) do table.insert(lines, string.format(self.i18n:getText("spu_outbound_waiting"), reason)) end if status.warning ~= nil then table.insert(lines, string.format(self.i18n:getText("spu_outbound_warning"), status.warning)) end for index, row in ipairs(self.outboundStatusRows or {}) do row:setText(lines[index] or "") end end -- Oversigt: "SUGAR 78 % af top (kræver 90), lager 41 % · ⚠ …" eller "Sukker 150.0k l — 92 % af top (…)". function SmartPickupFrame:describeOutboundOverview(adEnv, run) local status = ADRunsController.getOutboundStatus(adEnv, run) local parts = {} for _, reason in ipairs(status.reasons or {}) do table.insert(parts, reason) end if #parts == 0 then for _, product in ipairs(status.products or {}) do if product.policy ~= "off" then table.insert(parts, self:describeProduct(adEnv, product)) end end end if status.warning ~= nil then table.insert(parts, string.format(self.i18n:getText("spu_outbound_warning"), status.warning)) end if #parts == 0 then return self.i18n:getText("spu_noSources") end return table.concat(parts, " · ") end -- ---- callbacks ---- function SmartPickupFrame:onClickSource(state, element) self:safe(function(frame) local run, data = frame:getRun(), frame.rowData[element] if run == nil or data == nil then return end ADRunsController.store = ADRuns.toggleSource(ADRunsController.store, run.id, data.wayPointId) Logging.info(SmartPickupFrame.LOG_PREFIX .. "run '%s': sources=%s", tostring(run.name), table.concat(ADRuns.getRun(ADRunsController.store, run.id).sourceWayPointIds, " ")) frame:requestRebuild() end) end function SmartPickupFrame:onClickProduct(state, element) self:safe(function(frame) local run, data = frame:getRun(), frame.rowData[element] if run == nil or data == nil or data.kind ~= "product" then return end local policy = SmartPickupFrame.POLICIES[state] or "off" ADRunsController.store = ADRuns.setProductPolicy(ADRunsController.store, run.id, data.name, policy) Logging.info(SmartPickupFrame.LOG_PREFIX .. "run '%s': %s=%s", tostring(run.name), tostring(data.name), policy) end) end function SmartPickupFrame:onClickSellAt(state) self:safe(function(frame) local run = frame:getRun() if run == nil then return end ADRunsController.updateRun(run.id, {sellAtPercent = frame.sellAtSteps[state] or ADRuns.DEFAULT_SELL_AT_PERCENT}) end) end function SmartPickupFrame:onClickStoreAbove(state) self:safe(function(frame) local run = frame:getRun() if run == nil then return end ADRunsController.updateRun(run.id, {storeAbovePercent = frame.storeAboveSteps[state] or ADRuns.DEFAULT_STORE_ABOVE_PERCENT}) end) end function SmartPickupFrame:onClickCollectRound(state) self:safe(function(frame) local run = frame:getRun() if run == nil then return end ADRunsController.updateRun(run.id, {collectRound = state == SmartPickupFrame.STATE_ON}) end) end