diff --git a/FS25_ADSmartPickup/adFieldJobs.lua b/FS25_ADSmartPickup/adFieldJobs.lua
index 334f946..156849f 100644
--- a/FS25_ADSmartPickup/adFieldJobs.lua
+++ b/FS25_ADSmartPickup/adFieldJobs.lua
@@ -91,6 +91,10 @@ local function note(fieldId, changes)
setField(ADFieldModel.with(ADFieldJobs.getField(fieldId), changes))
end
+function ADFieldJobs.forceReady(id)
+ setField(ADFieldModel.forceReady(ADFieldJobs.getField(id)))
+end
+
function ADFieldJobs.toggleFleet(vehicleId)
ADFieldJobs.state.fleet = ADFieldFleet.toggle(ADFieldJobs.state.fleet, vehicleId)
ADFieldJobs.save()
diff --git a/FS25_ADSmartPickup/adFieldModel.lua b/FS25_ADSmartPickup/adFieldModel.lua
index 1afdeb7..5d12a57 100644
--- a/FS25_ADSmartPickup/adFieldModel.lua
+++ b/FS25_ADSmartPickup/adFieldModel.lua
@@ -77,6 +77,14 @@ function ADFieldModel.shouldStart(field)
return field.stage == "ready" and (field.plan.mode == "auto" or field.startRequested == true)
end
+-- Start nu fra menuen på en mark der ikke er nået 90 %: den behandles som klar.
+function ADFieldModel.forceReady(field)
+ if field.stage == "idle" or field.stage == "done" then
+ return ADFieldModel.with(field, {stage = "ready"})
+ end
+ return field
+end
+
function ADFieldModel.start(field)
local copy = copyField(field)
copy.stage = ADFieldModel.workStages(field.plan)[1]
diff --git a/FS25_ADSmartPickup/adSmartPickup.lua b/FS25_ADSmartPickup/adSmartPickup.lua
index c9e1108..f312591 100644
--- a/FS25_ADSmartPickup/adSmartPickup.lua
+++ b/FS25_ADSmartPickup/adSmartPickup.lua
@@ -17,6 +17,7 @@ if ADSmartPickup.dir ~= nil and source ~= nil then
source(ADSmartPickup.dir .. "gui/SmartPickupOutboundTab.lua")
source(ADSmartPickup.dir .. "gui/SmartPickupStorageTab.lua")
source(ADSmartPickup.dir .. "gui/SmartPickupFlowTab.lua")
+ source(ADSmartPickup.dir .. "gui/SmartPickupFieldTab.lua")
end
-- Markøren er dér hvor trækkerens næse stopper; læssetriggeren ligger et
diff --git a/FS25_ADSmartPickup/gui/SmartPickupFieldTab.lua b/FS25_ADSmartPickup/gui/SmartPickupFieldTab.lua
new file mode 100644
index 0000000..2c6b5d0
--- /dev/null
+++ b/FS25_ADSmartPickup/gui/SmartPickupFieldTab.lua
@@ -0,0 +1,254 @@
+-- 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.
+-- 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,
+}
+SmartPickupFrame.ROLE_KEYS = {mower = "spu_field_role_mower", tedder = "spu_field_role_tedder", rake = "spu_field_role_rake", collector = "spu_field_role_collector"}
+
+-- ---- tekster ----
+
+function SmartPickupFrame:fieldReasonText(reason)
+ if type(reason) ~= "table" then return nil end
+ if reason.text ~= nil then return reason.text end
+ local role = reason.role ~= nil and self.i18n:getText(SmartPickupFrame.ROLE_KEYS[reason.role] or "spu_field_role_mower") 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)
+ return ok and text or template
+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
+ text = string.format("%s %d %%", text, math.floor((info.readyRatio or 0) * 100 + 0.5))
+ 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.product == "hay" and field.plan.rake then
+ text = text .. " + " .. self.i18n:getText("spu_field_plan_rake")
+ 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)
+ return {
+ name, info.cropTitle or "-", info.mowable and self:fieldPlanText(field) or "-",
+ 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"),
+ ADFlowView.joinCounted(names, ", ", "-"),
+ }
+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"))
+ 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
+ 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
+
+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
+ 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")
+ if isHay then
+ self:addToggleRow("fieldRake", i18n:getText("spu_field_rake"), {i18n:getText("ui_no"), i18n:getText("ui_yes")}, field.plan.rake == true)
+ end
+ 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
+ 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.
+function SmartPickupFrame:fillFieldStoreRows(adEnv, info, field)
+ local i18n = self.i18n
+ 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
+ for _, building in ipairs(ADBuildings.list(adEnv, farmId)) do
+ if building.kind == "silo" and (chosen[building.id] or ADRunsController.canStoreAt(adEnv, building, {{fillType = fillType, isPallet = false}})) then
+ count = count + 1
+ local row = self:addRow(self.ingredientPrefab, {kind = "fieldStore", buildingId = building.id})
+ local suffix = fieldSilos[building.id] ~= nil and (" (" .. i18n:getText("spu_field_fieldSilo") .. ")") or ""
+ row:getDescendantByName("title"):setText(" " .. tostring(building.name) .. suffix)
+ row:getDescendantByName("option"):setState(chosen[building.id] and SmartPickupFrame.STATE_ON or SmartPickupFrame.STATE_OFF, false)
+ end
+ end
+ if count == 0 then
+ self:addTextRow(" " .. i18n:getText("spu_field_noStore"))
+ elseif #field.plan.storeBuildingIds == 0 then
+ self:addTextRow(" " .. i18n:getText("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
+
+function SmartPickupFrame:fillFleetRows(adEnv)
+ local i18n = self.i18n
+ self:addTextRow(i18n:getText("spu_field_section_fleet"))
+ 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", 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
+ 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, true)) 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
+ 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 info.mowable
+ or (not isWorking and (info.markerId == nil or (info.readyRatio or 0) < ADFieldModel.CUT_RATIO))
+end
+
+-- ---- klik ----
+
+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
+ ADFieldJobs.toggleFleet(data.vehicleId)
+ elseif id == nil then
+ return
+ 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 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
+
+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
+ if field.stage ~= "ready" 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
diff --git a/FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua b/FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua
index dd493b2..4d3ad52 100644
--- a/FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua
+++ b/FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua
@@ -65,7 +65,7 @@ function SmartPickupFrame:flowCells(adEnv, run)
end
-- Hele rækken klikbar med musen (Bitmap-rækker har ingen onClick). Klikket gemmes kun som
--- pendingJumpRunId; hoppet sker i update(), fordi genopbygningen sletter netop denne række.
+-- pendingClick; handlingen køres i update(), fordi genopbygningen sletter netop denne række.
local MOUSE_LEFT = Input ~= nil and Input.MOUSE_BUTTON_LEFT or 1
local function isInside(element, posX, posY)
@@ -74,7 +74,7 @@ local function isInside(element, posX, posY)
return posX >= position[1] and posX <= position[1] + size[1] and posY >= position[2] and posY <= position[2] + size[2]
end
-function SmartPickupFrame:makeRowClickable(row, runId)
+function SmartPickupFrame:makeRowClickable(row, action)
local frame = self
local baseMouseEvent = row.mouseEvent
row.mouseEvent = function(element, posX, posY, isDown, isUp, button, eventUsed)
@@ -82,7 +82,7 @@ function SmartPickupFrame:makeRowClickable(row, runId)
-- også inden for listens synlige udsnit: rækker scrollet ud af syne må ikke fange klik
if not used and not eventUsed and isUp and button == MOUSE_LEFT and (element.getIsVisible == nil or element:getIsVisible())
and isInside(element, posX, posY) and isInside(frame.boxLayout, posX, posY) then
- frame.pendingJumpRunId = runId
+ frame.pendingClick = action
return true
end
return used
@@ -100,7 +100,8 @@ function SmartPickupFrame:fillOverviewRows(adEnv)
for _, run in ipairs(group.runs) do
local cells = self:addCellRow(self.flowPrefab, self:flowCells(adEnv, run))
if cells[1] ~= nil and cells[1].parent ~= nil then
- self:makeRowClickable(cells[1].parent, run.id)
+ local runId = run.id
+ self:makeRowClickable(cells[1].parent, function(frame) frame:openFlow(runId) end)
end
table.insert(self.overviewRows, {runId = run.id, cells = cells})
end
diff --git a/FS25_ADSmartPickup/gui/SmartPickupFrame.lua b/FS25_ADSmartPickup/gui/SmartPickupFrame.lua
index d829a0b..dfafc55 100644
--- a/FS25_ADSmartPickup/gui/SmartPickupFrame.lua
+++ b/FS25_ADSmartPickup/gui/SmartPickupFrame.lua
@@ -11,10 +11,10 @@ SmartPickupFrame.STATUS_OVERRIDE_TICKS = 6
SmartPickupFrame.MAX_STATUS_REASONS = 3
SmartPickupFrame.LOG_PREFIX = "ADSmartPickup: "
SmartPickupFrame.STATE_OFF, SmartPickupFrame.STATE_ON = 1, 2
-SmartPickupFrame.TAB_OVERVIEW, SmartPickupFrame.TAB_FLOWS = 1, 2
+SmartPickupFrame.TAB_OVERVIEW, SmartPickupFrame.TAB_FLOWS, SmartPickupFrame.TAB_FIELDS = 1, 2, 3
-- Lagerfaner: én pr. bygningstype (indeks -> kind i ADSources.getFarmInventory)
-SmartPickupFrame.TAB_NAMES = {"spu_tab_overview", "spu_tab_flows", "spu_tab_factories", "spu_tab_silos", "spu_tab_barns", "spu_tab_sheds"}
-SmartPickupFrame.TAB_KINDS = {[3] = "factory", [4] = "silo", [5] = "husbandry", [6] = "objectStorage"}
+SmartPickupFrame.TAB_NAMES = {"spu_tab_overview", "spu_tab_flows", "spu_tab_fields", "spu_tab_factories", "spu_tab_silos", "spu_tab_barns", "spu_tab_sheds"}
+SmartPickupFrame.TAB_KINDS = {[4] = "factory", [5] = "silo", [6] = "husbandry", [7] = "objectStorage"}
function SmartPickupFrame.getTabKind(tab)
return SmartPickupFrame.TAB_KINDS[tab]
@@ -51,6 +51,9 @@ function SmartPickupFrame.new(i18n, getAdEnv)
self.stopAllButtonInfo = {inputAction = InputAction.MENU_EXTRA_2, text = i18n:getText("spu_button_stopAll"), callback = function() self:onClickStopAll() end}
self.flowButtons = {self.backButtonInfo, self.startButtonInfo, self.newButtonInfo, self.renameButtonInfo, self.deleteButtonInfo}
self.overviewButtons = {self.backButtonInfo, self.startAllButtonInfo, self.stopAllButtonInfo, self.newButtonInfo}
+ -- Marker: Start nu / Stop for den valgte mark
+ self.fieldStartButtonInfo = {inputAction = InputAction.MENU_ACTIVATE, text = i18n:getText("spu_field_button_start"), callback = function() self:onClickFieldStartStop() end}
+ self.fieldButtons = {self.backButtonInfo, self.fieldStartButtonInfo}
-- Egen reference til listen: fallback'en i refreshButtons skal kunne sende den igen.
self.menuButtonInfo = self.overviewButtons
self:setMenuButtonInfo(self.menuButtonInfo)
@@ -68,7 +71,7 @@ end
-- Prefabs skal ud af layoutet før de klones, ellers vises de selv som rækker.
function SmartPickupFrame:initialize()
- for _, name in ipairs({"ingredientPrefab", "vehiclePrefab", "textPrefab", "productPrefab", "statPrefab", "gridPrefab", "flowPrefab"}) do
+ for _, name in ipairs({"ingredientPrefab", "vehiclePrefab", "textPrefab", "productPrefab", "statPrefab", "gridPrefab", "flowPrefab", "fieldPrefab"}) do
local prefab = self[name]
if prefab ~= nil then
prefab:unlinkElement()
@@ -201,10 +204,10 @@ end
-- dets egen klik-håndtering, hopper værdien frem og tilbage og fokus ryger.
function SmartPickupFrame:update(dt)
SmartPickupFrame:superClass().update(self, dt)
- if self.pendingJumpRunId ~= nil then
- local runId = self.pendingJumpRunId
- self.pendingJumpRunId = nil
- self:safe(function(frame) frame:openFlow(runId) end)
+ if self.pendingClick ~= nil then
+ local action = self.pendingClick
+ self.pendingClick = nil
+ self:safe(action)
elseif self.pendingRebuild then
self.pendingRebuild = false
self:safe(self.rebuild)
@@ -380,6 +383,17 @@ function SmartPickupFrame:rebuild()
self:refreshLive()
return
end
+ if self.currentTab == SmartPickupFrame.TAB_FIELDS then
+ if adEnv ~= nil then
+ self:fillFieldRows(adEnv)
+ end
+ self.statusRow = self:addTextRow("")
+ self:colorRows()
+ self.boxLayout:invalidateLayout()
+ self:refreshLive()
+ self:restoreFocusIfLost()
+ return
+ end
if self.currentTab == SmartPickupFrame.TAB_OVERVIEW then
if adEnv ~= nil then
self:fillOverviewRows(adEnv)
@@ -642,7 +656,12 @@ end
-- setMenuButtonInfoDirty findes i FS22/25's TabbedMenuFrameElement; mangler den,
-- sendes listen igen. Kaldes hvert sekund, så den må aldrig kaste.
function SmartPickupFrame:refreshButtons()
- local wanted = self.currentTab == SmartPickupFrame.TAB_OVERVIEW and self.overviewButtons or self.flowButtons
+ local wanted = self.flowButtons
+ if self.currentTab == SmartPickupFrame.TAB_OVERVIEW then
+ wanted = self.overviewButtons
+ elseif self.currentTab == SmartPickupFrame.TAB_FIELDS then
+ wanted = self.fieldButtons
+ end
if self.menuButtonInfo ~= wanted then
self.menuButtonInfo = wanted
self:setMenuButtonInfo(wanted)
@@ -666,6 +685,13 @@ function SmartPickupFrame:refreshLive()
if isOverview then
self:refreshOverview(adEnv)
end
+ if self.currentTab == SmartPickupFrame.TAB_FIELDS then
+ self:refreshFieldRows(adEnv)
+ self.statusOverrideTicks = (self.statusOverrideTicks or 0) - 1
+ if self.statusOverrideTicks <= 0 then self.statusOverride = nil end
+ self:refreshButtons()
+ return
+ end
self:refreshStorageRows(adEnv)
local isRunning = false
if isOverview then
@@ -738,6 +764,8 @@ function SmartPickupFrame:onClickIngredient(state, element)
if data.kind == "showAllVehicles" then self.showAllVehicles = isOn else self.showAllBuildings = isOn end
self:requestRebuild()
return
+ elseif data ~= nil and SmartPickupFrame.FIELD_ROW_KINDS[data.kind] then
+ return self:onClickFieldRow(state, data)
elseif data ~= nil and (data.kind == "sourceBuilding" or data.kind == "targetBuilding" or data.kind == "storeBuilding") then
return self:onClickBuilding(state, element)
end
@@ -764,6 +792,10 @@ function SmartPickupFrame:onClickWaitPool(state)
end
function SmartPickupFrame:onClickVehicle(state, element)
+ local clicked = self.rowData[element]
+ if clicked ~= nil and clicked.kind == "fleetVehicle" 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.locked then return end
diff --git a/FS25_ADSmartPickup/gui/SmartPickupFrame.xml b/FS25_ADSmartPickup/gui/SmartPickupFrame.xml
index 0a13383..85d8da5 100644
--- a/FS25_ADSmartPickup/gui/SmartPickupFrame.xml
+++ b/FS25_ADSmartPickup/gui/SmartPickupFrame.xml
@@ -81,6 +81,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/FS25_ADSmartPickup/l10n/l10n_da.xml b/FS25_ADSmartPickup/l10n/l10n_da.xml
index f341903..69882ec 100644
--- a/FS25_ADSmartPickup/l10n/l10n_da.xml
+++ b/FS25_ADSmartPickup/l10n/l10n_da.xml
@@ -39,6 +39,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FS25_ADSmartPickup/l10n/l10n_en.xml b/FS25_ADSmartPickup/l10n/l10n_en.xml
index 6ae257e..5567613 100644
--- a/FS25_ADSmartPickup/l10n/l10n_en.xml
+++ b/FS25_ADSmartPickup/l10n/l10n_en.xml
@@ -39,6 +39,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/test_adFieldModel.lua b/tests/test_adFieldModel.lua
index 2737a70..aa9688a 100644
--- a/tests/test_adFieldModel.lua
+++ b/tests/test_adFieldModel.lua
@@ -95,5 +95,9 @@ check("M9 grund", noted.reason.text, "x"); check("M9 pause", noted.retryAt, 5)
check("M9 plan flettet", noted.plan.product, "hay"); check("M9 mode bevaret", noted.plan.mode, "manual")
check("M9 trin bevaret", noted.stage, "mowing"); check("M9 original urørt", base.plan.product, "silage")
+-- M10: Start nu på en mark der ikke er helt klar -> klar; arbejdende mark røres ikke
+check("M10 venter -> klar", M.forceReady(M.newField(2)).stage, "ready")
+check("M10 arbejdende uændret", M.forceReady(base).stage, "mowing")
+
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1)