diff --git a/FS25_ADSmartPickup/adFieldView.lua b/FS25_ADSmartPickup/adFieldView.lua index f6db981..6addb3c 100644 --- a/FS25_ADSmartPickup/adFieldView.lua +++ b/FS25_ADSmartPickup/adFieldView.lua @@ -1,32 +1,39 @@ -- AD Field View --- Rene regler for fanen Marker: hvilke marker vises (slåafgrøder som standard), rækkefølge og --- statusord. GUI'et oversætter nøglerne. +-- Rene regler for fanen Marker: rækkefølge, statusord, planens tekst og jordtilstand. GUI'et oversætter +-- nøglerne. ADFieldView = {} -function ADFieldView.rows(infos, fieldsById, showAll) +-- Alle gårdens marker (slåafgrøder, høstafgrøder og bare), sorteret efter marknummer. +function ADFieldView.rows(infos, fieldsById) local rows = {} for _, info in ipairs(infos or {}) do - if showAll or info.mowable then - table.insert(rows, {info = info, field = fieldsById[info.id] or ADFieldModel.newField(info.id)}) - end + table.insert(rows, {info = info, field = fieldsById[info.id] or ADFieldModel.newField(info.id)}) end table.sort(rows, function(a, b) return a.info.id < b.info.id end) return rows end -function ADFieldView.hiddenCount(infos, showAll) - if showAll then return 0 end - local hidden = 0 - for _, info in ipairs(infos or {}) do - if not info.mowable then hidden = hidden + 1 end - end - return hidden -end - function ADFieldView.statusKey(field, info) if info.markerId == nil then return "spu_field_noMarker" end return "spu_field_stage_" .. tostring(field.stage) end + +-- Planens tekstnøgle ud fra markens art: ensilage/hø for slåafgrøder, høst, eller klargøring (bar mark). +function ADFieldView.planKey(plan, kind) + if kind == "bare" then return "spu_field_plan_prep" end + return "spu_field_plan_" .. ADFieldModel.product(plan, kind) +end + +-- Hvad jorden trænger til, som korte nøgler i fast rækkefølge: kalk, pløj, gødning, ukrudt. +function ADFieldView.soilParts(info) + local parts = {} + local needs = info.needs or {} + if needs.lime then table.insert(parts, "lime") end + if needs.plow then table.insert(parts, "plow") end + if info.fert ~= nil and info.fertMax ~= nil and info.fert < info.fertMax then table.insert(parts, "fert") end + if (info.weed or 0) >= ADFieldModel.WEED_MIN then table.insert(parts, "weed") end + return parts +end diff --git a/FS25_ADSmartPickup/gui/SmartPickupFieldTab.lua b/FS25_ADSmartPickup/gui/SmartPickupFieldTab.lua index 6e5197b..b83444b 100644 --- a/FS25_ADSmartPickup/gui/SmartPickupFieldTab.lua +++ b/FS25_ADSmartPickup/gui/SmartPickupFieldTab.lua @@ -1,44 +1,77 @@ -- Smart Pickup — fanen Marker --- Tabel over gårdens slåafgrøde-marker (Mark · Afgrøde · Plan · Auto/Man. · Status · Maskiner); klik på --- en række viser markens detaljer under tabellen (plan, kørsel, riv, tving lager, marksiloer). Nederst --- markflåden: foreslåede sæt med flueben. Al logik ligger i ADFieldJobs/ADFieldModel/ADFieldView. +-- 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 = { - showAllFields = true, fieldProduct = true, fieldMode = true, fieldRake = true, fieldStore = true, fleetVehicle = true, + 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, } -SmartPickupFrame.ROLE_KEYS = {mower = "spu_field_role_mower", tedder = "spu_field_role_tedder", rake = "spu_field_role_rake", collector = "spu_field_role_collector"} +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", +} +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"} -- ---- 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 role = reason.name or (reason.role ~= nil and self.i18n:getText(SmartPickupFrame.ROLE_KEYS[reason.role] or "spu_field_role_mower")) or "" + 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, role, args[1] or 0, args[2] or 0) + 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.mowable then + 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 reason = self:fieldReasonText(field.reason) if reason ~= nil then text = text .. ": " .. reason end return text end -function SmartPickupFrame:fieldPlanText(field) - local text = self.i18n:getText(field.plan.product == "hay" and "spu_field_plan_hay" or "spu_field_plan_silage") - if field.plan.rake then - text = text .. " + " .. self.i18n:getText("spu_field_plan_rake") - end +function SmartPickupFrame:fieldPlanText(field, info) + 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 @@ -49,14 +82,52 @@ function SmartPickupFrame:fieldCells(row) 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 = info.kind == "bare" and self.i18n:getText("spu_field_bare") or (info.cropTitle or "-") return { - name, info.cropTitle or "-", info.mowable and self:fieldPlanText(field) or "-", + name, crop, self:fieldPlanText(field, info), self.i18n:getText(field.plan.mode == "auto" and "spu_field_mode_auto" or "spu_field_mode_manual"), - info.mowable and self:fieldStatusText(field, info) or self.i18n:getText("spu_field_notMowable"), + 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). +function SmartPickupFrame:sowFruitChoices() + local texts, values = {self.i18n:getText("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) @@ -67,12 +138,8 @@ function SmartPickupFrame:fillFieldRows(adEnv) self:addTextRow(i18n:getText("spu_field_scanning")) else self:addTextRow(i18n:getText("spu_field_hint")) - local hidden = ADFieldView.hiddenCount(infos, self.showAllFields == true) - if hidden > 0 or self.showAllFields then - self:addToggleRow("showAllFields", string.format(i18n:getText("spu_field_showAll"), hidden), {i18n:getText("ui_no"), i18n:getText("ui_yes")}, self.showAllFields == true) - end 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, self.showAllFields == true)) do + 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 @@ -94,15 +161,42 @@ end function SmartPickupFrame:fillFieldDetail(adEnv, info) local i18n = self.i18n local field = ADFieldJobs.getField(info.id) - self:addTextRow(string.format(i18n:getText("spu_field_section"), info.id, tostring(info.cropTitle or "-"))) - if not info.mowable then - self:addTextRow(" " .. i18n:getText("spu_field_notMowable")) - return + local plan = field.plan + local yesNo = {i18n:getText("ui_no"), i18n:getText("ui_yes")} + local crop = info.kind == "bare" and i18n:getText("spu_field_bare") or tostring(info.cropTitle or "-") + self:addTextRow(string.format(i18n:getText("spu_field_section"), info.id, crop)) + self:addToggleRow("fieldMode", i18n:getText("spu_field_mode"), {i18n:getText("spu_field_mode_manual"), i18n:getText("spu_field_mode_auto")}, plan.mode == "auto") + local rigTexts, rigValues = numberTexts(1, ADFieldModel.MAX_RIGS) + self:addChoiceRow("fieldRigs", i18n:getText("spu_field_rigs"), rigTexts, rigValues, plan.rigs or 1) + if info.kind == "mowable" 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) + else + 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) + 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") + 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 "") + self:addToggleRow("fieldRoll", i18n:getText("spu_field_roll"), yesNo, plan.roll == true) + end end - local isHay = field.plan.product == "hay" - self:addToggleRow("fieldProduct", i18n:getText("spu_field_plan"), {i18n:getText("spu_field_plan_silage"), i18n:getText("spu_field_plan_hay")}, isHay) - self:addToggleRow("fieldMode", i18n:getText("spu_field_mode"), {i18n:getText("spu_field_mode_manual"), i18n:getText("spu_field_mode_auto")}, field.plan.mode == "auto") - self:addToggleRow("fieldRake", i18n:getText("spu_field_rake"), {i18n:getText("ui_no"), i18n:getText("ui_yes")}, field.plan.rake == true) + 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 @@ -118,21 +212,28 @@ function SmartPickupFrame:fillFieldDetail(adEnv, info) self:fillFieldStoreRows(adEnv, info, field) end --- Tving lager: siloer der tager markens vare (skår ved ensilage, tørskår ved hø); valgte først. +-- 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:addTextRow(i18n:getText("spu_field_section_store")) - local fillType = field.plan.product == "hay" and info.hay or info.windrow 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 count = 0 local fermenterIds = {} - if field.plan.product ~= "hay" then + 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 + local count = 0 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 @@ -147,7 +248,7 @@ function SmartPickupFrame:fillFieldStoreRows(adEnv, info, field) if count == 0 then self:addTextRow(" " .. i18n:getText("spu_field_noStore")) elseif #field.plan.storeBuildingIds == 0 then - self:addTextRow(" " .. i18n:getText(field.plan.product == "hay" and "spu_field_storeAuto" or "spu_field_storeAutoSilage")) + 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 @@ -163,6 +264,25 @@ function SmartPickupFrame:fillFieldStoreRows(adEnv, info, field) 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 + if (rig.width or 0) > ADFieldModel.CP_MAX_WIDTH then table.insert(parts, i18n:getText("spu_field_tooWideShort")) end + local assignment = ADFieldJobs.state.assignments[rig.id] + if assignment ~= nil then table.insert(parts, string.format("F%d", assignment.fieldId)) end + return #parts > 0 and (" — " .. table.concat(parts, " — ")) or "" +end + function SmartPickupFrame:fillFleetRows(adEnv) local i18n = self.i18n self:addTextRow(i18n:getText("spu_field_section_fleet")) @@ -173,14 +293,7 @@ function SmartPickupFrame:fillFleetRows(adEnv) 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", tostring(rig.label), i18n:getText(SmartPickupFrame.ROLE_KEYS[rig.role]), rig.width or 0) - if (rig.width or 0) > ADFieldModel.CP_MAX_WIDTH then - title = title .. " — " .. i18n:getText("spu_field_tooWideShort") - end - local assignment = ADFieldJobs.state.assignments[rig.id] - if assignment ~= nil then - title = title .. string.format(" — F%d", assignment.fieldId) - end + 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 @@ -193,13 +306,13 @@ end function SmartPickupFrame:refreshFieldRows(adEnv) local rowsById = {} - for _, row in ipairs(ADFieldView.rows(ADFields.list(), ADFieldJobs.state.fields, true)) do rowsById[row.info.id] = row end + 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)) - if row.info.mowable then total = total + 1 end + total = total + 1 if ADFieldModel.isWorking(row.field) then working = working + 1 end end end @@ -208,8 +321,7 @@ function SmartPickupFrame:refreshFieldRows(adEnv) 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 info.mowable - or (not isWorking and (info.markerId == nil or (info.readyRatio or 0) < ADFieldModel.CUT_RATIO)) + self.fieldStartButtonInfo.disabled = selected == nil or info == nil or (not isWorking and info.markerId == nil) end -- ---- klik ---- @@ -218,18 +330,19 @@ function SmartPickupFrame:onClickFieldRow(state, data) self:safe(function(frame) local isOn = state == SmartPickupFrame.STATE_ON local id = frame.selectedFieldId - if data.kind == "showAllFields" then - frame.showAllFields = isOn - elseif data.kind == "fleetVehicle" then + if data.kind == "fleetVehicle" then ADFieldJobs.toggleFleet(data.vehicleId) elseif id == nil then return + 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 data.kind == "fieldRake" then - ADFieldJobs.setPlan(id, {rake = isOn}) + elseif SmartPickupFrame.PLAN_TOGGLES[data.kind] ~= nil then + ADFieldJobs.setPlan(id, {[SmartPickupFrame.PLAN_TOGGLES[data.kind]] = isOn}) elseif data.kind == "fieldStore" then local ids = {} for _, buildingId in ipairs(ADFieldJobs.getField(id).plan.storeBuildingIds) do @@ -242,6 +355,7 @@ function SmartPickupFrame:onClickFieldRow(state, data) 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 @@ -250,7 +364,8 @@ function SmartPickupFrame:onClickFieldStartStop() if ADFieldModel.isWorking(field) then ADFieldJobs.stopField(frame.getAdEnv(), id) else - if field.stage ~= "ready" then + local decision = ADFieldJobs.lastDecision[id] + if decision == nil or decision.care == nil then ADFieldJobs.forceReady(id) end ADFieldJobs.requestStart(id) diff --git a/FS25_ADSmartPickup/gui/SmartPickupOutboundTab.lua b/FS25_ADSmartPickup/gui/SmartPickupOutboundTab.lua index 6c33959..0913490 100644 --- a/FS25_ADSmartPickup/gui/SmartPickupOutboundTab.lua +++ b/FS25_ADSmartPickup/gui/SmartPickupOutboundTab.lua @@ -182,6 +182,9 @@ function SmartPickupFrame:onClickProduct(state, element) if clicked ~= nil and clicked.kind == "storageBuilding" then return self:safe(function(frame) frame:onClickStorageBuilding(state) end) end + if clicked ~= nil and SmartPickupFrame.FIELD_ROW_KINDS ~= nil and SmartPickupFrame.FIELD_ROW_KINDS[clicked.kind] then + return self:onClickFieldRow(state, clicked) + end 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 diff --git a/FS25_ADSmartPickup/l10n/l10n_da.xml b/FS25_ADSmartPickup/l10n/l10n_da.xml index 95d5d83..3d41ef3 100644 --- a/FS25_ADSmartPickup/l10n/l10n_da.xml +++ b/FS25_ADSmartPickup/l10n/l10n_da.xml @@ -93,6 +93,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FS25_ADSmartPickup/l10n/l10n_en.xml b/FS25_ADSmartPickup/l10n/l10n_en.xml index bc0b336..a3c2e1c 100644 --- a/FS25_ADSmartPickup/l10n/l10n_en.xml +++ b/FS25_ADSmartPickup/l10n/l10n_en.xml @@ -93,6 +93,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/test_adFieldView.lua b/tests/test_adFieldView.lua index d7bac23..518bd02 100644 --- a/tests/test_adFieldView.lua +++ b/tests/test_adFieldView.lua @@ -17,20 +17,26 @@ local infos = { } local fields = {[109] = ADFieldModel.newField(109), [12] = ADFieldModel.newField(12)} --- V1: kun slåafgrøder, sorteret efter nummer -local rows = V.rows(infos, fields, false) -check("V1 to rækker", #rows, 2) +-- V1: alle marker (etape 2: også høst og bare), sorteret efter nummer +local rows = V.rows(infos, fields) +check("V1 tre rækker", #rows, 3) check("V1 sorteret", rows[1].info.id, 12) -check("V1 model med", rows[2].field.id, 109) --- V2: vis alle tager resten med; mangler model -> ny standardmark -local all = V.rows(infos, fields, true) -check("V2 tre rækker", #all, 3) -check("V2 standardmodel", all[2].field.stage, "idle") -check("V2 skjulte", V.hiddenCount(infos, false), 1) -check("V2 vis alle skjuler intet", V.hiddenCount(infos, true), 0) +check("V1 model med", rows[3].field.id, 109) +-- V2: mangler model -> ny standardmark +check("V2 standardmodel", rows[2].field.stage, "idle") -- V3: status — manglende markør vinder over trin check("V3 mangler markør", V.statusKey(fields[12], infos[2]), "spu_field_noMarker") check("V3 trin", V.statusKey(fields[109], infos[1]), "spu_field_stage_idle") +-- V4: planens tekstnøgler pr. markart +check("V4 ensilage", V.planKey({product = "auto"}, "mowable"), "spu_field_plan_silage") +check("V4 hø", V.planKey({product = "hay"}, "mowable"), "spu_field_plan_hay") +check("V4 høst", V.planKey({product = "auto"}, "harvest"), "spu_field_plan_harvest") +check("V4 bar mark", V.planKey({product = "auto"}, "bare"), "spu_field_plan_prep") +-- V5: jordtilstand som korte tekstdele +local parts = V.soilParts({lime = 0.2, fert = 1, fertMax = 2, weed = 3, needs = {lime = true, plow = true}}) +check("V5 dele", table.concat(parts, ","), "lime,plow,fert,weed") +check("V5 intet", #V.soilParts({lime = 2, fert = 2, fertMax = 2, weed = 0, needs = {}}), 0) + print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1)