feat(marker): fanen Marker — tabel, detalje (plan/kørsel/riv/tving lager/marksiloer), markflåde, Start nu/Stop
This commit is contained in:
@@ -91,6 +91,10 @@ local function note(fieldId, changes)
|
|||||||
setField(ADFieldModel.with(ADFieldJobs.getField(fieldId), changes))
|
setField(ADFieldModel.with(ADFieldJobs.getField(fieldId), changes))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function ADFieldJobs.forceReady(id)
|
||||||
|
setField(ADFieldModel.forceReady(ADFieldJobs.getField(id)))
|
||||||
|
end
|
||||||
|
|
||||||
function ADFieldJobs.toggleFleet(vehicleId)
|
function ADFieldJobs.toggleFleet(vehicleId)
|
||||||
ADFieldJobs.state.fleet = ADFieldFleet.toggle(ADFieldJobs.state.fleet, vehicleId)
|
ADFieldJobs.state.fleet = ADFieldFleet.toggle(ADFieldJobs.state.fleet, vehicleId)
|
||||||
ADFieldJobs.save()
|
ADFieldJobs.save()
|
||||||
|
|||||||
@@ -77,6 +77,14 @@ function ADFieldModel.shouldStart(field)
|
|||||||
return field.stage == "ready" and (field.plan.mode == "auto" or field.startRequested == true)
|
return field.stage == "ready" and (field.plan.mode == "auto" or field.startRequested == true)
|
||||||
end
|
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)
|
function ADFieldModel.start(field)
|
||||||
local copy = copyField(field)
|
local copy = copyField(field)
|
||||||
copy.stage = ADFieldModel.workStages(field.plan)[1]
|
copy.stage = ADFieldModel.workStages(field.plan)[1]
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ if ADSmartPickup.dir ~= nil and source ~= nil then
|
|||||||
source(ADSmartPickup.dir .. "gui/SmartPickupOutboundTab.lua")
|
source(ADSmartPickup.dir .. "gui/SmartPickupOutboundTab.lua")
|
||||||
source(ADSmartPickup.dir .. "gui/SmartPickupStorageTab.lua")
|
source(ADSmartPickup.dir .. "gui/SmartPickupStorageTab.lua")
|
||||||
source(ADSmartPickup.dir .. "gui/SmartPickupFlowTab.lua")
|
source(ADSmartPickup.dir .. "gui/SmartPickupFlowTab.lua")
|
||||||
|
source(ADSmartPickup.dir .. "gui/SmartPickupFieldTab.lua")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Markøren er dér hvor trækkerens næse stopper; læssetriggeren ligger et
|
-- Markøren er dér hvor trækkerens næse stopper; læssetriggeren ligger et
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -65,7 +65,7 @@ function SmartPickupFrame:flowCells(adEnv, run)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Hele rækken klikbar med musen (Bitmap-rækker har ingen onClick). Klikket gemmes kun som
|
-- 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 MOUSE_LEFT = Input ~= nil and Input.MOUSE_BUTTON_LEFT or 1
|
||||||
|
|
||||||
local function isInside(element, posX, posY)
|
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]
|
return posX >= position[1] and posX <= position[1] + size[1] and posY >= position[2] and posY <= position[2] + size[2]
|
||||||
end
|
end
|
||||||
|
|
||||||
function SmartPickupFrame:makeRowClickable(row, runId)
|
function SmartPickupFrame:makeRowClickable(row, action)
|
||||||
local frame = self
|
local frame = self
|
||||||
local baseMouseEvent = row.mouseEvent
|
local baseMouseEvent = row.mouseEvent
|
||||||
row.mouseEvent = function(element, posX, posY, isDown, isUp, button, eventUsed)
|
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
|
-- 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())
|
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
|
and isInside(element, posX, posY) and isInside(frame.boxLayout, posX, posY) then
|
||||||
frame.pendingJumpRunId = runId
|
frame.pendingClick = action
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return used
|
return used
|
||||||
@@ -100,7 +100,8 @@ function SmartPickupFrame:fillOverviewRows(adEnv)
|
|||||||
for _, run in ipairs(group.runs) do
|
for _, run in ipairs(group.runs) do
|
||||||
local cells = self:addCellRow(self.flowPrefab, self:flowCells(adEnv, run))
|
local cells = self:addCellRow(self.flowPrefab, self:flowCells(adEnv, run))
|
||||||
if cells[1] ~= nil and cells[1].parent ~= nil then
|
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
|
end
|
||||||
table.insert(self.overviewRows, {runId = run.id, cells = cells})
|
table.insert(self.overviewRows, {runId = run.id, cells = cells})
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ SmartPickupFrame.STATUS_OVERRIDE_TICKS = 6
|
|||||||
SmartPickupFrame.MAX_STATUS_REASONS = 3
|
SmartPickupFrame.MAX_STATUS_REASONS = 3
|
||||||
SmartPickupFrame.LOG_PREFIX = "ADSmartPickup: "
|
SmartPickupFrame.LOG_PREFIX = "ADSmartPickup: "
|
||||||
SmartPickupFrame.STATE_OFF, SmartPickupFrame.STATE_ON = 1, 2
|
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)
|
-- 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_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 = {[3] = "factory", [4] = "silo", [5] = "husbandry", [6] = "objectStorage"}
|
SmartPickupFrame.TAB_KINDS = {[4] = "factory", [5] = "silo", [6] = "husbandry", [7] = "objectStorage"}
|
||||||
|
|
||||||
function SmartPickupFrame.getTabKind(tab)
|
function SmartPickupFrame.getTabKind(tab)
|
||||||
return SmartPickupFrame.TAB_KINDS[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.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.flowButtons = {self.backButtonInfo, self.startButtonInfo, self.newButtonInfo, self.renameButtonInfo, self.deleteButtonInfo}
|
||||||
self.overviewButtons = {self.backButtonInfo, self.startAllButtonInfo, self.stopAllButtonInfo, self.newButtonInfo}
|
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.
|
-- Egen reference til listen: fallback'en i refreshButtons skal kunne sende den igen.
|
||||||
self.menuButtonInfo = self.overviewButtons
|
self.menuButtonInfo = self.overviewButtons
|
||||||
self:setMenuButtonInfo(self.menuButtonInfo)
|
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.
|
-- Prefabs skal ud af layoutet før de klones, ellers vises de selv som rækker.
|
||||||
function SmartPickupFrame:initialize()
|
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]
|
local prefab = self[name]
|
||||||
if prefab ~= nil then
|
if prefab ~= nil then
|
||||||
prefab:unlinkElement()
|
prefab:unlinkElement()
|
||||||
@@ -201,10 +204,10 @@ end
|
|||||||
-- dets egen klik-håndtering, hopper værdien frem og tilbage og fokus ryger.
|
-- dets egen klik-håndtering, hopper værdien frem og tilbage og fokus ryger.
|
||||||
function SmartPickupFrame:update(dt)
|
function SmartPickupFrame:update(dt)
|
||||||
SmartPickupFrame:superClass().update(self, dt)
|
SmartPickupFrame:superClass().update(self, dt)
|
||||||
if self.pendingJumpRunId ~= nil then
|
if self.pendingClick ~= nil then
|
||||||
local runId = self.pendingJumpRunId
|
local action = self.pendingClick
|
||||||
self.pendingJumpRunId = nil
|
self.pendingClick = nil
|
||||||
self:safe(function(frame) frame:openFlow(runId) end)
|
self:safe(action)
|
||||||
elseif self.pendingRebuild then
|
elseif self.pendingRebuild then
|
||||||
self.pendingRebuild = false
|
self.pendingRebuild = false
|
||||||
self:safe(self.rebuild)
|
self:safe(self.rebuild)
|
||||||
@@ -380,6 +383,17 @@ function SmartPickupFrame:rebuild()
|
|||||||
self:refreshLive()
|
self:refreshLive()
|
||||||
return
|
return
|
||||||
end
|
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 self.currentTab == SmartPickupFrame.TAB_OVERVIEW then
|
||||||
if adEnv ~= nil then
|
if adEnv ~= nil then
|
||||||
self:fillOverviewRows(adEnv)
|
self:fillOverviewRows(adEnv)
|
||||||
@@ -642,7 +656,12 @@ end
|
|||||||
-- setMenuButtonInfoDirty findes i FS22/25's TabbedMenuFrameElement; mangler den,
|
-- setMenuButtonInfoDirty findes i FS22/25's TabbedMenuFrameElement; mangler den,
|
||||||
-- sendes listen igen. Kaldes hvert sekund, så den må aldrig kaste.
|
-- sendes listen igen. Kaldes hvert sekund, så den må aldrig kaste.
|
||||||
function SmartPickupFrame:refreshButtons()
|
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
|
if self.menuButtonInfo ~= wanted then
|
||||||
self.menuButtonInfo = wanted
|
self.menuButtonInfo = wanted
|
||||||
self:setMenuButtonInfo(wanted)
|
self:setMenuButtonInfo(wanted)
|
||||||
@@ -666,6 +685,13 @@ function SmartPickupFrame:refreshLive()
|
|||||||
if isOverview then
|
if isOverview then
|
||||||
self:refreshOverview(adEnv)
|
self:refreshOverview(adEnv)
|
||||||
end
|
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)
|
self:refreshStorageRows(adEnv)
|
||||||
local isRunning = false
|
local isRunning = false
|
||||||
if isOverview then
|
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
|
if data.kind == "showAllVehicles" then self.showAllVehicles = isOn else self.showAllBuildings = isOn end
|
||||||
self:requestRebuild()
|
self:requestRebuild()
|
||||||
return
|
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
|
elseif data ~= nil and (data.kind == "sourceBuilding" or data.kind == "targetBuilding" or data.kind == "storeBuilding") then
|
||||||
return self:onClickBuilding(state, element)
|
return self:onClickBuilding(state, element)
|
||||||
end
|
end
|
||||||
@@ -764,6 +792,10 @@ function SmartPickupFrame:onClickWaitPool(state)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function SmartPickupFrame:onClickVehicle(state, element)
|
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)
|
self:safe(function(frame)
|
||||||
local run, data = frame:getRun(), frame.rowData[element]
|
local run, data = frame:getRun(), frame.rowData[element]
|
||||||
if run == nil or data == nil or data.locked then return end
|
if run == nil or data == nil or data.locked then return end
|
||||||
|
|||||||
@@ -81,6 +81,15 @@
|
|||||||
<Text profile="spuCell" name="c5" position="620px 0px" size="50px 40px" textMaxWidth="42px"/>
|
<Text profile="spuCell" name="c5" position="620px 0px" size="50px 40px" textMaxWidth="42px"/>
|
||||||
<Text profile="spuCell" name="c6" position="670px 0px" size="140px 40px" textMaxWidth="132px"/>
|
<Text profile="spuCell" name="c6" position="670px 0px" size="140px 40px" textMaxWidth="132px"/>
|
||||||
</Bitmap>
|
</Bitmap>
|
||||||
|
<!-- Marker: én række pr. mark (mark · afgrøde · plan · auto/man. · status · maskiner). Rækken er ~815 px bred. -->
|
||||||
|
<Bitmap profile="fs25_multiTextOptionContainer" id="fieldPrefab">
|
||||||
|
<Text profile="spuCellBold" name="c1" position="20px 0px" size="100px 40px" textMaxWidth="92px"/>
|
||||||
|
<Text profile="spuCell" name="c2" position="120px 0px" size="130px 40px" textMaxWidth="122px"/>
|
||||||
|
<Text profile="spuCell" name="c3" position="250px 0px" size="110px 40px" textMaxWidth="102px"/>
|
||||||
|
<Text profile="spuCell" name="c4" position="360px 0px" size="80px 40px" textMaxWidth="72px"/>
|
||||||
|
<Text profile="spuCell" name="c5" position="440px 0px" size="230px 40px" textMaxWidth="222px"/>
|
||||||
|
<Text profile="spuCell" name="c6" position="670px 0px" size="140px 40px" textMaxWidth="132px"/>
|
||||||
|
</Bitmap>
|
||||||
<!-- Lagre: statistik-tabel (vare · i bygningen · værdi nu · ved toppris · gården · rækker til · forbrug/prod.) -->
|
<!-- Lagre: statistik-tabel (vare · i bygningen · værdi nu · ved toppris · gården · rækker til · forbrug/prod.) -->
|
||||||
<Bitmap profile="fs25_multiTextOptionContainer" id="statPrefab">
|
<Bitmap profile="fs25_multiTextOptionContainer" id="statPrefab">
|
||||||
<Text profile="spuCellBold" name="c1" position="20px 0px" size="140px 40px" textMaxWidth="132px"/>
|
<Text profile="spuCellBold" name="c1" position="20px 0px" size="140px 40px" textMaxWidth="132px"/>
|
||||||
|
|||||||
@@ -39,6 +39,54 @@
|
|||||||
<text name="spu_status_startedAll" text="Startet %d flows (%d traktorer), %d kørte allerede, %d sprunget over"/>
|
<text name="spu_status_startedAll" text="Startet %d flows (%d traktorer), %d kørte allerede, %d sprunget over"/>
|
||||||
<text name="spu_status_stoppedAll" text="Stoppet %d traktorer"/>
|
<text name="spu_status_stoppedAll" text="Stoppet %d traktorer"/>
|
||||||
<text name="spu_overview_hint" text="Klik på et flow for at redigere det"/>
|
<text name="spu_overview_hint" text="Klik på et flow for at redigere det"/>
|
||||||
|
<text name="spu_tab_fields" text="Marker"/>
|
||||||
|
<text name="spu_field_button_start" text="Start nu"/>
|
||||||
|
<text name="spu_field_button_stop" text="Stop mark"/>
|
||||||
|
<text name="spu_field_noMarker" text="! mangler markør F%d"/>
|
||||||
|
<text name="spu_field_stage_idle" text="Venter"/>
|
||||||
|
<text name="spu_field_stage_ready" text="Klar"/>
|
||||||
|
<text name="spu_field_stage_mowing" text="Slås"/>
|
||||||
|
<text name="spu_field_stage_tedding" text="Vendes"/>
|
||||||
|
<text name="spu_field_stage_raking" text="Rives"/>
|
||||||
|
<text name="spu_field_stage_collecting" text="Samles op"/>
|
||||||
|
<text name="spu_field_stage_done" text="Færdig"/>
|
||||||
|
<text name="spu_field_reason_noRig" text="ingen %s med flueben i markflåden"/>
|
||||||
|
<text name="spu_field_reason_allBusy" text="venter på ledig %s"/>
|
||||||
|
<text name="spu_field_reason_tooWide" text="%s for bred: %.1f m > %.0f m (Courseplay)"/>
|
||||||
|
<text name="spu_field_reason_tooNarrow" text="%s for smal: %.1f m < slåbredde %.1f m"/>
|
||||||
|
<text name="spu_field_role_mower" text="slåmaskine"/>
|
||||||
|
<text name="spu_field_role_tedder" text="vender"/>
|
||||||
|
<text name="spu_field_role_rake" text="river"/>
|
||||||
|
<text name="spu_field_role_collector" text="læssevogn"/>
|
||||||
|
<text name="spu_field_plan_silage" text="Ensilage"/>
|
||||||
|
<text name="spu_field_plan_hay" text="Hø"/>
|
||||||
|
<text name="spu_field_plan_rake" text="riv"/>
|
||||||
|
<text name="spu_field_mode_auto" text="Auto"/>
|
||||||
|
<text name="spu_field_mode_manual" text="Manuel"/>
|
||||||
|
<text name="spu_field_notMowable" text="ikke græs/kløver"/>
|
||||||
|
<text name="spu_field_scanning" text="Marker indlæses ... (én mark pr. sekund)"/>
|
||||||
|
<text name="spu_field_hint" text="Klik på en mark for at vælge den. Sæt flueben ved maskinerne i markflåden nederst."/>
|
||||||
|
<text name="spu_field_showAll" text="Vis alle marker (%d skjult)"/>
|
||||||
|
<text name="spu_col_field" text="Mark"/>
|
||||||
|
<text name="spu_col_crop" text="Afgrøde"/>
|
||||||
|
<text name="spu_col_plan" text="Plan"/>
|
||||||
|
<text name="spu_col_mode" text="Kørsel"/>
|
||||||
|
<text name="spu_field_section" text="— Mark F%d: %s —"/>
|
||||||
|
<text name="spu_field_plan" text="Plan"/>
|
||||||
|
<text name="spu_field_mode" text="Kørsel"/>
|
||||||
|
<text name="spu_field_rake" text="Riv høet sammen før opsamling"/>
|
||||||
|
<text name="spu_field_marker" text=" Markør %s, %.0f m fra marken"/>
|
||||||
|
<text name="spu_field_mowWidth" text=" Slået med %.1f m — opsamling skal være mindst lige så bred"/>
|
||||||
|
<text name="spu_field_section_store" text="— Tving lager (ellers nærmeste silo med plads) —"/>
|
||||||
|
<text name="spu_field_fieldSilo" text="marksilo"/>
|
||||||
|
<text name="spu_field_noStore" text="ingen silo tager markens vare"/>
|
||||||
|
<text name="spu_field_storeAuto" text="intet valgt: nærmeste silo med plads bruges"/>
|
||||||
|
<text name="spu_field_fieldSiloNotEmptied" text="! Marksilo %s tømmes ikke hjem — lav et Ud fra bygning-flow"/>
|
||||||
|
<text name="spu_field_section_fleet" text="— Markflåde (flueben = må sendes ud) —"/>
|
||||||
|
<text name="spu_field_tooWideShort" text="!! over 50 m"/>
|
||||||
|
<text name="spu_field_noRigs" text="ingen køretøjer med slåmaskine, vender, river eller læssevogn"/>
|
||||||
|
<text name="spu_field_status" text="Marker i gang: %d af %d"/>
|
||||||
|
<text name="spu_field_startRequested" text="F%d startes, når en maskine er ledig"/>
|
||||||
<text name="spu_button_start" text="Start run"/>
|
<text name="spu_button_start" text="Start run"/>
|
||||||
<text name="spu_button_stop" text="Stop run"/>
|
<text name="spu_button_stop" text="Stop run"/>
|
||||||
<text name="spu_button_new" text="Nyt run"/>
|
<text name="spu_button_new" text="Nyt run"/>
|
||||||
|
|||||||
@@ -39,6 +39,54 @@
|
|||||||
<text name="spu_status_startedAll" text="Started %d flows (%d tractors), %d already running, %d skipped"/>
|
<text name="spu_status_startedAll" text="Started %d flows (%d tractors), %d already running, %d skipped"/>
|
||||||
<text name="spu_status_stoppedAll" text="Stopped %d tractors"/>
|
<text name="spu_status_stoppedAll" text="Stopped %d tractors"/>
|
||||||
<text name="spu_overview_hint" text="Click a flow to edit it"/>
|
<text name="spu_overview_hint" text="Click a flow to edit it"/>
|
||||||
|
<text name="spu_tab_fields" text="Fields"/>
|
||||||
|
<text name="spu_field_button_start" text="Start now"/>
|
||||||
|
<text name="spu_field_button_stop" text="Stop field"/>
|
||||||
|
<text name="spu_field_noMarker" text="! missing marker F%d"/>
|
||||||
|
<text name="spu_field_stage_idle" text="Waiting"/>
|
||||||
|
<text name="spu_field_stage_ready" text="Ready"/>
|
||||||
|
<text name="spu_field_stage_mowing" text="Mowing"/>
|
||||||
|
<text name="spu_field_stage_tedding" text="Tedding"/>
|
||||||
|
<text name="spu_field_stage_raking" text="Raking"/>
|
||||||
|
<text name="spu_field_stage_collecting" text="Collecting"/>
|
||||||
|
<text name="spu_field_stage_done" text="Done"/>
|
||||||
|
<text name="spu_field_reason_noRig" text="no %s ticked in the field fleet"/>
|
||||||
|
<text name="spu_field_reason_allBusy" text="waiting for a free %s"/>
|
||||||
|
<text name="spu_field_reason_tooWide" text="%s too wide: %.1f m > %.0f m (Courseplay)"/>
|
||||||
|
<text name="spu_field_reason_tooNarrow" text="%s too narrow: %.1f m < mowing width %.1f m"/>
|
||||||
|
<text name="spu_field_role_mower" text="mower"/>
|
||||||
|
<text name="spu_field_role_tedder" text="tedder"/>
|
||||||
|
<text name="spu_field_role_rake" text="rake"/>
|
||||||
|
<text name="spu_field_role_collector" text="loading wagon"/>
|
||||||
|
<text name="spu_field_plan_silage" text="Silage"/>
|
||||||
|
<text name="spu_field_plan_hay" text="Hay"/>
|
||||||
|
<text name="spu_field_plan_rake" text="rake"/>
|
||||||
|
<text name="spu_field_mode_auto" text="Auto"/>
|
||||||
|
<text name="spu_field_mode_manual" text="Manual"/>
|
||||||
|
<text name="spu_field_notMowable" text="not grass/clover"/>
|
||||||
|
<text name="spu_field_scanning" text="Loading fields ... (one field per second)"/>
|
||||||
|
<text name="spu_field_hint" text="Click a field to select it. Tick the machines in the field fleet at the bottom."/>
|
||||||
|
<text name="spu_field_showAll" text="Show all fields (%d hidden)"/>
|
||||||
|
<text name="spu_col_field" text="Field"/>
|
||||||
|
<text name="spu_col_crop" text="Crop"/>
|
||||||
|
<text name="spu_col_plan" text="Plan"/>
|
||||||
|
<text name="spu_col_mode" text="Mode"/>
|
||||||
|
<text name="spu_field_section" text="— Field F%d: %s —"/>
|
||||||
|
<text name="spu_field_plan" text="Plan"/>
|
||||||
|
<text name="spu_field_mode" text="Mode"/>
|
||||||
|
<text name="spu_field_rake" text="Rake the hay before collecting"/>
|
||||||
|
<text name="spu_field_marker" text=" Marker %s, %.0f m from the field"/>
|
||||||
|
<text name="spu_field_mowWidth" text=" Mowed at %.1f m — collecting must be at least as wide"/>
|
||||||
|
<text name="spu_field_section_store" text="— Force storage (else nearest silo with room) —"/>
|
||||||
|
<text name="spu_field_fieldSilo" text="field silo"/>
|
||||||
|
<text name="spu_field_noStore" text="no silo takes this field's goods"/>
|
||||||
|
<text name="spu_field_storeAuto" text="none chosen: nearest silo with room is used"/>
|
||||||
|
<text name="spu_field_fieldSiloNotEmptied" text="! Field silo %s is not emptied home — create an Out of building flow"/>
|
||||||
|
<text name="spu_field_section_fleet" text="— Field fleet (ticked = may be sent out) —"/>
|
||||||
|
<text name="spu_field_tooWideShort" text="!! over 50 m"/>
|
||||||
|
<text name="spu_field_noRigs" text="no vehicles with mower, tedder, rake or loading wagon"/>
|
||||||
|
<text name="spu_field_status" text="Fields in progress: %d of %d"/>
|
||||||
|
<text name="spu_field_startRequested" text="F%d starts when a machine is free"/>
|
||||||
<text name="spu_button_start" text="Start run"/>
|
<text name="spu_button_start" text="Start run"/>
|
||||||
<text name="spu_button_stop" text="Stop run"/>
|
<text name="spu_button_stop" text="Stop run"/>
|
||||||
<text name="spu_button_new" text="New run"/>
|
<text name="spu_button_new" text="New run"/>
|
||||||
|
|||||||
@@ -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 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")
|
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"))
|
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
|
||||||
os.exit(failures == 0 and 0 or 1)
|
os.exit(failures == 0 and 0 or 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user