-- Smart Pickup — fanen Marker -- Tabel over alle gårdens marker (Mark · Afgrøde · Plan · Kørsel · Status · Maskiner); klik på en række -- viser markens detaljer under tabellen: plan efter markens art (slåafgrøde, høst, bar), maskiner pr. trin, -- aflæsningsvogne, efter høst, såning, pleje, tving lager, jordtilstand. Nederst markflåden med flueben. -- Al logik ligger i ADFieldJobs/ADFieldWork/ADFieldModel/ADFieldView. -- Funktionerne lægges på SmartPickupFrame (indlæses efter SmartPickupFrame.lua). SmartPickupFrame.FIELD_ROW_KINDS = { fieldProduct = true, fieldMode = true, fieldRake = true, fieldStore = true, fleetVehicle = true, fieldRigs = true, fieldUnloaders = true, fieldMulch = true, fieldLime = true, fieldSoil = true, fieldSow = true, fieldSowFruit = true, fieldRoll = true, fieldFertilize = true, fieldWeed = true, fieldTarget = true, fleetMode = true, fieldStraw = true, fieldRig = true, } SmartPickupFrame.ROLE_KEYS = { mower = "spu_field_role_mower", tedder = "spu_field_role_tedder", rake = "spu_field_role_rake", collector = "spu_field_role_collector", harvester = "spu_field_role_harvester", unloader = "spu_field_role_unloader", mulcher = "spu_field_role_mulcher", limer = "spu_field_role_limer", plow = "spu_field_role_plow", cultivator = "spu_field_role_cultivator", seeder = "spu_field_role_seeder", roller = "spu_field_role_roller", weeder = "spu_field_role_weeder", fertilizer = "spu_field_role_fertilizer", baler = "spu_field_role_baler", baleCollector = "spu_field_role_baleCollector", } SmartPickupFrame.SOIL_VALUES = {"auto", "cultivate", "plow", "none"} -- simple Ja/Nej-valg på planen: rækketype -> plan-felt SmartPickupFrame.PLAN_TOGGLES = { fieldRake = "rake", fieldMulch = "mulch", fieldLime = "lime", fieldSow = "sow", fieldRoll = "roll", fieldFertilize = "fertilize", fieldWeed = "weed", } -- valg med flere muligheder: rækketype -> plan-felt SmartPickupFrame.PLAN_CHOICES = {fieldRigs = "rigs", fieldUnloaders = "unloaders", fieldSoil = "soil", fieldSowFruit = "sowFruit", fieldStraw = "straw"} SmartPickupFrame.STRAW_VALUES = {"chop", "collect", "bale"} -- ---- tekster ---- function SmartPickupFrame:roleText(role) return self.i18n:getText(SmartPickupFrame.ROLE_KEYS[role] or "spu_field_role_mower") end function SmartPickupFrame:fieldReasonText(reason) if type(reason) ~= "table" then return nil end if reason.text ~= nil then return reason.text end local first = reason.name or (reason.role ~= nil and self:roleText(reason.role)) or "" local template = self.i18n:getText(reason.key) local args = reason.args or {} local ok, text = pcall(string.format, template, first, args[1] or 0, args[2] or 0) return ok and text or template end function SmartPickupFrame:soilText(info) local texts = {} for _, part in ipairs(ADFieldView.soilParts(info)) do table.insert(texts, self.i18n:getText("spu_field_need_" .. part)) end return table.concat(texts, ", ") end function SmartPickupFrame:fieldStatusText(field, info) local text = self.i18n:getText(ADFieldView.statusKey(field, info)) if info.markerId == nil then return string.format(text, info.id) end if (field.stage == "idle" or field.stage == "ready") and info.kind ~= "bare" and info.readyRatio ~= nil then text = string.format("%s %d %%", text, math.floor((info.readyRatio or 0) * 100 + 0.5)) end local decision = ADFieldJobs.lastDecision[info.id] if decision ~= nil and decision.care ~= nil and not ADFieldModel.isWorking(field) then text = text .. " — " .. string.format(self.i18n:getText("spu_field_careNeed"), self.i18n:getText("spu_field_stage_" .. decision.care)) end local target = field.plan.targetFruit if target ~= nil and target ~= "" and info.kind == "bare" and field.stage == "idle" and not ADFieldJobs.environment().plantable(target) then text = text .. " — " .. string.format(self.i18n:getText("spu_field_waitSowing"), self:fruitTitle(target)) end local reason = self:fieldReasonText(field.reason) if reason ~= nil then text = text .. ": " .. reason end return text end -- Hvad moden gør med marken frem mod mål-afgrøden (én linje under valget). function SmartPickupFrame:targetSummary(field, info) local target = self:fruitTitle(field.plan.targetFruit) if info.kind == "bare" then return string.format(self.i18n:getText("spu_field_target_bare"), target) end if info.fruitName == field.plan.targetFruit and info.kind == "mowable" then return string.format(self.i18n:getText("spu_field_target_keep"), target) end return string.format(self.i18n:getText("spu_field_target_switch"), tostring(info.cropTitle or "-"), target) end function SmartPickupFrame:fruitTitle(name) local fruit = g_fruitTypeManager ~= nil and name ~= nil and name ~= "" and g_fruitTypeManager:getFruitTypeByName(name) or nil return fruit ~= nil and fruit.fillType ~= nil and tostring(fruit.fillType.title) or tostring(name) end function SmartPickupFrame:fieldPlanText(field, info) if field.plan.targetFruit ~= nil and field.plan.targetFruit ~= "" then return "-> " .. self:fruitTitle(field.plan.targetFruit) end local text = self.i18n:getText(ADFieldView.planKey(field.plan, info.kind)) if field.plan.rake and info.kind == "mowable" then text = text .. " + " .. self.i18n:getText("spu_field_plan_rake") end if field.plan.sow and info.kind ~= "mowable" then text = text .. " + " .. self.i18n:getText("spu_field_plan_sow") end if (field.plan.rigs or 1) > 1 then text = string.format("%s (x%d)", text, field.plan.rigs) end return text end function SmartPickupFrame:fieldCells(row) local info, field = row.info, row.field local names = {} for _, assignment in ipairs(ADFieldJobs.assignmentsFor(info.id)) do table.insert(names, ADRuns.vehicleLabel(assignment.vehicle)) end local name = string.format("%s%sF%d", info.id == self.selectedFieldId and "> " or "", info.markerId == nil and "! " or "", info.id) local crop = ADFieldView.cropText(info, function(key) return self.i18n:getText(key) end) return { name, crop, self:fieldPlanText(field, info), self.i18n:getText(field.plan.mode == "auto" and "spu_field_mode_auto" or "spu_field_mode_manual"), self:fieldStatusText(field, info), ADFlowView.joinCounted(names, ", ", "-"), } end -- ---- rækker ---- -- Valg med flere muligheder (klon af productPrefab): values[i] er værdien for texts[i]. function SmartPickupFrame:addChoiceRow(kind, title, texts, values, current) local row = self:addRow(self.productPrefab, {kind = kind, values = values}) local option = row:getDescendantByName("option") option:setTexts(texts) local index = 1 for position, value in ipairs(values) do if value == current then index = position end end option:setState(index, false) row:getDescendantByName("title"):setText(title) return option end local function numberTexts(from, to) local texts, values = {}, {} for value = from, to do table.insert(texts, tostring(value)) table.insert(values, value) end return texts, values end -- Afgrøder der kan sås (første valg: samme som den høstede / ingen mål-afgrøde). function SmartPickupFrame:sowFruitChoices(firstKey) local texts, values = {self.i18n:getText(firstKey or "spu_field_sowSame")}, {""} for _, fruit in ipairs(g_fruitTypeManager ~= nil and g_fruitTypeManager.fruitTypes or {}) do if fruit.allowsSeeding ~= false and fruit.fillType ~= nil and fruit.name ~= nil then table.insert(texts, tostring(fruit.fillType.title or fruit.name)) table.insert(values, fruit.name) end end return texts, values end -- ---- opbygning ---- function SmartPickupFrame:fillFieldRows(adEnv) self.fieldRows = {} local i18n = self.i18n local infos = ADFields.list() if #infos == 0 then self:addTextRow(i18n:getText("spu_field_scanning")) else self:addTextRow(i18n:getText("spu_field_hint")) self:addCellRow(self.fieldPrefab, {i18n:getText("spu_col_field"), i18n:getText("spu_col_crop"), i18n:getText("spu_col_plan"), i18n:getText("spu_col_mode"), i18n:getText("spu_col_status"), i18n:getText("spu_col_tractors")}) for _, row in ipairs(ADFieldView.rows(infos, ADFieldJobs.state.fields)) do local cells = self:addCellRow(self.fieldPrefab, self:fieldCells(row)) local fieldId = row.info.id if cells[1] ~= nil and cells[1].parent ~= nil then self:makeRowClickable(cells[1].parent, function(frame) frame.selectedFieldId = fieldId frame:requestRebuild() end) end table.insert(self.fieldRows, {id = fieldId, cells = cells}) end end local selected = self.selectedFieldId ~= nil and ADFields.getInfo(self.selectedFieldId) or nil if selected ~= nil then self:fillFieldDetail(adEnv, selected) end self:fillFleetRows(adEnv) end -- lagervalget viser de nærmeste siloer (plus valgte, marksiloer og gæringssiloer) SmartPickupFrame.FIELD_STORE_ROWS = 8 function SmartPickupFrame:fillFieldDetail(adEnv, info) local i18n = self.i18n local field = ADFieldJobs.getField(info.id) local plan = field.plan local yesNo = {i18n:getText("ui_no"), i18n:getText("ui_yes")} local crop = ADFieldView.cropText(info, function(key) return i18n:getText(key) end) self:addTextRow(string.format(i18n:getText("spu_field_section"), info.id, crop)) -- hele statusteksten (tabellens celle afkorter den) self:addTextRow(" " .. string.format(i18n:getText("spu_field_statusFull"), self:fieldStatusText(field, info))) local targetTexts, targetValues = self:sowFruitChoices("spu_field_target_none") self:addChoiceRow("fieldTarget", i18n:getText("spu_field_target"), targetTexts, targetValues, plan.targetFruit or "") local hasTarget = plan.targetFruit ~= nil and plan.targetFruit ~= "" if hasTarget then self:addTextRow(" " .. self:targetSummary(field, info)) else self:addToggleRow("fieldMode", i18n:getText("spu_field_mode"), {i18n:getText("spu_field_mode_manual"), i18n:getText("spu_field_mode_auto")}, plan.mode == "auto") end local rigTexts, rigValues = numberTexts(1, ADFieldModel.MAX_RIGS) self:addChoiceRow("fieldRigs", i18n:getText("spu_field_rigs"), rigTexts, rigValues, plan.rigs or 1) -- græs-valgene (ensilage/hø, riv) også når målet er en slåafgrøde (fx græs på en kornmark) local targetMowable = false if hasTarget and ADFields ~= nil and g_fruitTypeManager ~= nil then local targetFruit = g_fruitTypeManager:getFruitTypeByName(plan.targetFruit) targetMowable = targetFruit ~= nil and ADFields.getMowable()[targetFruit.index] ~= nil end if info.kind == "mowable" or targetMowable then local isHay = ADFieldModel.product(plan, "mowable") == "hay" self:addToggleRow("fieldProduct", i18n:getText("spu_field_plan"), {i18n:getText("spu_field_plan_silage"), i18n:getText("spu_field_plan_hay")}, isHay) self:addToggleRow("fieldRake", i18n:getText("spu_field_rake"), yesNo, plan.rake == true) end -- klargøring: høst-/bare marker, og græsmarker der skal skifte til en anden mål-afgrøde if info.kind ~= "mowable" or (hasTarget and info.fruitName ~= plan.targetFruit) then if info.kind == "harvest" then local unloaderTexts, unloaderValues = numberTexts(1, ADFieldModel.MAX_UNLOADERS) self:addChoiceRow("fieldUnloaders", i18n:getText("spu_field_unloaders"), unloaderTexts, unloaderValues, plan.unloaders or 1) local strawTexts = {} for _, value in ipairs(SmartPickupFrame.STRAW_VALUES) do table.insert(strawTexts, i18n:getText("spu_field_straw_" .. value)) end self:addChoiceRow("fieldStraw", i18n:getText("spu_field_straw"), strawTexts, SmartPickupFrame.STRAW_VALUES, plan.straw or "chop") end self:addTextRow(i18n:getText(info.kind == "harvest" and "spu_field_section_after" or "spu_field_section_prep")) self:addToggleRow("fieldMulch", i18n:getText("spu_field_mulch"), yesNo, plan.mulch == true) local soilTexts = {} for _, value in ipairs(SmartPickupFrame.SOIL_VALUES) do table.insert(soilTexts, i18n:getText("spu_field_soil_" .. value)) end self:addChoiceRow("fieldSoil", i18n:getText("spu_field_soil"), soilTexts, SmartPickupFrame.SOIL_VALUES, plan.soil or "auto") if not hasTarget then self:addToggleRow("fieldSow", i18n:getText("spu_field_sow"), yesNo, plan.sow == true) if plan.sow then local fruitTexts, fruitValues = self:sowFruitChoices() self:addChoiceRow("fieldSowFruit", i18n:getText("spu_field_sowFruit"), fruitTexts, fruitValues, plan.sowFruit or "") end end if hasTarget or plan.sow then self:addToggleRow("fieldRoll", i18n:getText("spu_field_roll"), yesNo, plan.roll == true) end end self:addTextRow(i18n:getText("spu_field_section_care")) self:addToggleRow("fieldFertilize", i18n:getText("spu_field_fertilize"), yesNo, plan.fertilize ~= false) self:addToggleRow("fieldLime", i18n:getText("spu_field_lime"), yesNo, plan.lime ~= false) if info.kind ~= "mowable" then self:addToggleRow("fieldWeed", i18n:getText("spu_field_weed"), yesNo, plan.weed ~= false) end local soil = self:soilText(info) self:addTextRow(" " .. string.format(i18n:getText("spu_field_soilState"), soil ~= "" and soil or i18n:getText("spu_field_soilOk"))) if info.markerId ~= nil then self:addTextRow(string.format(i18n:getText("spu_field_marker"), tostring(info.markerName), info.markerDistance or 0)) else self:addTextRow(" " .. string.format(i18n:getText("spu_field_noMarker"), info.id)) end if field.mowWidth ~= nil then self:addTextRow(string.format(i18n:getText("spu_field_mowWidth"), field.mowWidth)) end if field.plan.rake and field.windrowOffset ~= nil then self:addTextRow(string.format(i18n:getText("spu_field_windrowOffset"), math.abs(field.windrowOffset), i18n:getText(math.abs(field.windrowOffset) <= 0.05 and "spu_field_side_center" or (field.windrowOffset > 0 and "spu_field_side_left" or "spu_field_side_right")))) end self:fillFieldStoreRows(adEnv, info, field) end -- Tving lager: siloer der tager markens vare (skår/tørskår/høst); ved ensilage også gæringssiloer. function SmartPickupFrame:fillFieldStoreRows(adEnv, info, field) local i18n = self.i18n local product = ADFieldModel.product(field.plan, info.kind) local fillType if info.kind == "mowable" then fillType = product == "hay" and info.hay or info.windrow else fillType = info.harvestFillType end if fillType == nil then return end self:fillDedicatedRows(adEnv, field) self:addTextRow(i18n:getText("spu_field_section_store")) local chosen = {} for _, id in ipairs(field.plan.storeBuildingIds) do chosen[id] = true end local farmId = g_currentMission:getFarmId() local fieldSilos = {} for _, building in ipairs(ADFields.fieldSilos(adEnv, farmId, info)) do fieldSilos[building.id] = building end local fermenterIds = {} if info.kind == "mowable" and product == "silage" then for _, building in ipairs(ADFieldJobs.getFermenters(adEnv, farmId, fillType, info.x, info.z)) do fermenterIds[building.id] = true end end -- kandidater med markørnavn og afstand til marken (34 ens "Farma 500 + Obi 1000" kan ellers ikke skelnes) local entries = {} for _, building in ipairs(ADBuildings.list(adEnv, farmId)) do local isSilo = building.kind == "silo" and ADRunsController.canStoreAt(adEnv, building, {{fillType = fillType, isPallet = false}}) if chosen[building.id] or isSilo or fermenterIds[building.id] then local distance = nil local node = building.placeable ~= nil and building.placeable.rootNode or nil if node ~= nil and info.x ~= nil then local bx, _, bz = getWorldTranslation(node) distance = math.sqrt((bx - info.x) ^ 2 + (bz - info.z) ^ 2) end table.insert(entries, {id = building.id, building = building, distance = distance, chosen = chosen[building.id] == true, fieldSilo = fieldSilos[building.id] ~= nil, fermenter = fermenterIds[building.id] == true}) end end local storeRows, hiddenStores = ADFieldView.storeRows(entries, SmartPickupFrame.FIELD_STORE_ROWS) local count = #storeRows for _, entry in ipairs(storeRows) do local building = entry.building local row = self:addRow(self.ingredientPrefab, {kind = "fieldStore", buildingId = building.id}) local markers = ADBuildings.getMarkers ~= nil and ADBuildings.getMarkers(building, "unload") or {} -- det der skelner rækkerne først (rækken afkorter bagfra): markør, afstand, art — så bygningens navn local label = (markers[1] ~= nil and tostring(markers[1].name) or tostring(building.name)) .. ", " .. ADFieldView.distanceText(entry.distance) if entry.fieldSilo then label = label .. " (" .. i18n:getText("spu_field_fieldSilo") .. ")" end if entry.fermenter then label = label .. " (" .. i18n:getText("spu_field_fermenter") .. ")" end if markers[1] ~= nil then label = label .. " — " .. tostring(building.name) end row:getDescendantByName("title"):setText(" " .. label) row:getDescendantByName("option"):setState(entry.chosen and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, false) end if hiddenStores > 0 then self:addTextRow(" " .. string.format(i18n:getText("spu_field_storeHidden"), hiddenStores)) end if count == 0 then self:addTextRow(" " .. i18n:getText("spu_field_noStore")) elseif #field.plan.storeBuildingIds == 0 then self:addTextRow(" " .. i18n:getText((info.kind == "mowable" and product == "silage") and "spu_field_storeAutoSilage" or "spu_field_storeAuto")) end -- marksiloer skal tømmes hjem af et udkørselsflow for id, building in pairs(fieldSilos) do local emptied = false for _, run in ipairs(ADRunsController.store.runs) do for _, sourceId in ipairs(run.kind == "outbound" and run.sourceBuildingIds or {}) do if sourceId == id then emptied = true end end end if not emptied then self:addTextRow(" " .. string.format(i18n:getText("spu_field_fieldSiloNotEmptied"), tostring(building.name))) end end end -- Ekstra oplysning pr. sæt i markflåden (afgrøder, frø, strigle/sprøjte, bredde over 50 m, mark). function SmartPickupFrame:rigDetails(rig) local i18n = self.i18n local parts = {} if rig.role == "harvester" then local count = 0 for _ in pairs(rig.fruits or {}) do count = count + 1 end table.insert(parts, string.format(i18n:getText("spu_field_rig_crops"), count)) elseif rig.role == "seeder" then table.insert(parts, i18n:getText(rig.hasSeeds and "spu_field_rig_seeds" or "spu_field_rig_noSeeds")) elseif rig.role == "weeder" then table.insert(parts, i18n:getText(rig.mechanical and "spu_field_rig_mechanical" or "spu_field_rig_herbicide")) end -- samme grænse som udsendelsen (50,0 m med afrunding er ikke "over 50 m") if (rig.width or 0) > ADFieldModel.CP_MAX_WIDTH + ADFieldModel.WIDTH_TOLERANCE then table.insert(parts, i18n:getText("spu_field_tooWideShort")) end if (rig.width or 0) < ADFieldModel.MIN_WORK_WIDTH and not ADFieldModel.NO_WIDTH_ROLES[rig.role] then table.insert(parts, i18n:getText("spu_field_widthUnknownShort")) end -- fast på en mark (valgt under markens "Faste maskiner") og hvor den arbejder nu for fieldId, field in pairs(ADFieldJobs.state.fields) do for _, id in ipairs(field.plan ~= nil and field.plan.rigIds or {}) do if id == rig.id then table.insert(parts, string.format(i18n:getText("spu_field_dedicatedElsewhere"), tostring(fieldId))) end end end local assignment = ADFieldJobs.state.assignments[rig.id] if assignment ~= nil then table.insert(parts, string.format(i18n:getText("spu_field_rig_working"), tostring(assignment.fieldId))) end return #parts > 0 and (" — " .. table.concat(parts, " — ")) or "" end -- Faste maskiner til den valgte mark: en fast maskine bruges kun her, og marken venter på sin egen hellere -- end at låne en anden med samme opgave. Maskiner der er faste på en anden mark er markeret. function SmartPickupFrame:fillDedicatedRows(adEnv, field) local i18n = self.i18n self:addTextRow(i18n:getText("spu_field_section_dedicated")) local owner = {} for fieldId, other in pairs(ADFieldJobs.state.fields) do for _, id in ipairs(other.plan ~= nil and other.plan.rigIds or {}) do owner[id] = fieldId end end local rigs = ADFieldJobs.getRigs(adEnv) table.sort(rigs, function(a, b) local ma, mb = owner[a.id] == field.id, owner[b.id] == field.id if ma ~= mb then return ma end if a.role ~= b.role then return a.role < b.role end return ADFlowView.naturalLess(a.label, b.label) end) for _, rig in ipairs(rigs) do local row = self:addRow(self.vehiclePrefab, {kind = "fieldRig", vehicleId = rig.id}) local elsewhere = owner[rig.id] ~= nil and owner[rig.id] ~= field.id and (" — " .. string.format(i18n:getText("spu_field_dedicatedElsewhere"), tostring(owner[rig.id]))) or "" row:getDescendantByName("title"):setText(string.format(" %s — %s%s", tostring(rig.label), self:roleText(rig.role), elsewhere)) row:getDescendantByName("option"):setState(owner[rig.id] == field.id and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, false) end end function SmartPickupFrame:fillFleetRows(adEnv) local i18n = self.i18n self:addTextRow(i18n:getText("spu_field_section_fleet")) local useAll = ADFieldJobs.state.fleetMode ~= "ticked" self:addToggleRow("fleetMode", i18n:getText("spu_field_fleetAll"), {i18n:getText("ui_no"), i18n:getText("ui_yes")}, useAll) local rigs = ADFieldJobs.getRigs(adEnv) table.sort(rigs, function(a, b) if a.role ~= b.role then return a.role < b.role end return ADFlowView.naturalLess(a.label, b.label) end) for _, rig in ipairs(rigs) do local row = self:addRow(self.vehiclePrefab, {kind = "fleetVehicle", vehicleId = rig.id}) local title = string.format(" %s — %s, %.1f m%s", tostring(rig.label), self:roleText(rig.role), rig.width or 0, self:rigDetails(rig)) row:getDescendantByName("title"):setText(title) row:getDescendantByName("option"):setState(rig.enabled and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, false) end if #rigs == 0 then self:addTextRow(" " .. i18n:getText("spu_field_noRigs")) end end -- ---- live ---- function SmartPickupFrame:refreshFieldRows(adEnv) local rowsById = {} for _, row in ipairs(ADFieldView.rows(ADFields.list(), ADFieldJobs.state.fields)) do rowsById[row.info.id] = row end local working, total = 0, 0 for _, entry in ipairs(self.fieldRows or {}) do local row = rowsById[entry.id] if row ~= nil then SmartPickupFrame.setCells(entry.cells, self:fieldCells(row)) total = total + 1 if ADFieldModel.isWorking(row.field) then working = working + 1 end end end self:setStatusText(self.statusOverride or string.format(self.i18n:getText("spu_field_status"), working, total)) local selected = self.selectedFieldId ~= nil and ADFieldJobs.getField(self.selectedFieldId) or nil local info = self.selectedFieldId ~= nil and ADFields.getInfo(self.selectedFieldId) or nil local isWorking = selected ~= nil and ADFieldModel.isWorking(selected) self.fieldStartButtonInfo.text = self.i18n:getText(isWorking and "spu_field_button_stop" or "spu_field_button_start") self.fieldStartButtonInfo.disabled = selected == nil or info == nil or (not isWorking and info.markerId == nil) end -- ---- klik ---- function SmartPickupFrame:onClickFieldRow(state, data) self:safe(function(frame) local isOn = state == SmartPickupFrame.STATE_ON local id = frame.selectedFieldId if data.kind == "fleetVehicle" then ADFieldJobs.toggleFleet(data.vehicleId) elseif data.kind == "fleetMode" then ADFieldJobs.setFleetMode(isOn and "all" or "ticked") elseif id == nil then return elseif data.kind == "fieldTarget" then ADFieldJobs.setTarget(id, data.values ~= nil and data.values[state] or "") elseif SmartPickupFrame.PLAN_CHOICES[data.kind] ~= nil then local value = data.values ~= nil and data.values[state] or nil if value ~= nil then ADFieldJobs.setPlan(id, {[SmartPickupFrame.PLAN_CHOICES[data.kind]] = value}) end elseif data.kind == "fieldProduct" then ADFieldJobs.setPlan(id, {product = isOn and "hay" or "silage"}) elseif data.kind == "fieldMode" then ADFieldJobs.setPlan(id, {mode = isOn and "auto" or "manual"}) elseif SmartPickupFrame.PLAN_TOGGLES[data.kind] ~= nil then ADFieldJobs.setPlan(id, {[SmartPickupFrame.PLAN_TOGGLES[data.kind]] = isOn}) elseif data.kind == "fieldRig" then -- fast på denne mark (og fjernes fra en anden mark) local byField = {} for fieldId, other in pairs(ADFieldJobs.state.fields) do byField[fieldId] = other.plan ~= nil and other.plan.rigIds or {} end local updated = ADFieldFleet.dedicate(byField, id, data.vehicleId, isOn) for fieldId, ids in pairs(updated) do local before = table.concat(byField[fieldId] or {}, " ") if before ~= table.concat(ids, " ") then ADFieldJobs.setPlan(fieldId, {rigIds = ids}) end end elseif data.kind == "fieldStore" then local ids = {} for _, buildingId in ipairs(ADFieldJobs.getField(id).plan.storeBuildingIds) do if buildingId ~= data.buildingId then table.insert(ids, buildingId) end end if isOn then table.insert(ids, data.buildingId) end ADFieldJobs.setPlan(id, {storeBuildingIds = ids}) end frame:requestRebuild() end) end -- Start nu: pleje hvis marken trænger (og vokser), ellers hele kæden (høst/slå, eller klargøring på bar mark). function SmartPickupFrame:onClickFieldStartStop() self:safe(function(frame) local id = frame.selectedFieldId if id == nil then return end local field = ADFieldJobs.getField(id) if ADFieldModel.isWorking(field) then ADFieldJobs.stopField(frame.getAdEnv(), id) else local decision = ADFieldJobs.lastDecision[id] if decision == nil or decision.care == nil then ADFieldJobs.forceReady(id) end ADFieldJobs.requestStart(id) frame.statusOverride = string.format(frame.i18n:getText("spu_field_startRequested"), id) frame.statusOverrideTicks = SmartPickupFrame.STATUS_OVERRIDE_TICKS end frame:requestRebuild() end) end