feat(marker): mål-afgrøde pr. mark ('vælg mark + afgrøde, glem den') + brug alle ledige maskiner (standard)

This commit is contained in:
2026-09-26 01:24:28 +02:00
parent 944e61d1a8
commit af71548b0b
11 changed files with 209 additions and 17 deletions
+50 -3
View File
@@ -42,7 +42,7 @@ KNOWN_STAGES.careLiming = true
local DEFAULT_PLAN = {
mode = "manual", product = "auto", rake = false, rigs = 1, unloaders = 1,
mulch = false, lime = true, soil = "auto", sow = false, sowFruit = "", roll = false,
fertilize = true, weed = true,
fertilize = true, weed = true, targetFruit = "", prepAfterMow = false,
}
local SOIL_VALUES = {auto = true, cultivate = true, plow = true, none = true}
local PRODUCTS = {auto = true, silage = true, hay = true, harvest = true}
@@ -123,9 +123,51 @@ function ADFieldModel.workStages(plan, kind, needs)
if product == "hay" then table.insert(stages, "tedding") end
if plan.rake then table.insert(stages, "raking") end
table.insert(stages, "collecting")
-- mål-afgrøde på en slåmark med en anden afgrøde: efter sidste slæt klargøres og sås målet
if plan.prepAfterMow then
for _, stage in ipairs(ADFieldModel.prepStages(plan, needs)) do table.insert(stages, stage) end
end
return stages
end
-- Mål-afgrøde ("vælg mark + afgrøde, glem den"): planen udfyldes ud fra hvad der står på marken nu.
-- Står målet der allerede som slåafgrøde (græs -> græs): bare slå igen og igen. Ellers: høst/slå det der
-- står, klargør og så målet. Kører altid automatisk. Uden mål returneres planen uændret.
function ADFieldModel.applyTarget(plan, kind, currentFruit)
local copy = copyPlan(plan)
if copy.targetFruit == nil or copy.targetFruit == "" then return copy end
copy.mode = "auto"
copy.sowFruit = copy.targetFruit
if kind == "mowable" then
copy.prepAfterMow = currentFruit ~= copy.targetFruit
copy.sow = copy.prepAfterMow
else
copy.prepAfterMow = false
copy.sow = true
end
return copy
end
-- Vælg mål-afgrøde fra menuen ("" = ingen). Med mål kører marken automatisk; en færdig/klar mark sættes
-- til venter, så den kan starte forfra. Uden mål: tilbage til manuel.
function ADFieldModel.setTarget(field, fruitName)
local copy = copyField(field)
copy.plan.targetFruit = fruitName or ""
copy.plan.mode = copy.plan.targetFruit ~= "" and "auto" or "manual"
if not ADFieldModel.isWorking(field) and field.stage == "done" then
copy.stage = "idle"
end
return copy
end
-- Bar mark med mål-afgrøde starter selv klargøring + såning, når målet kan sås nu.
function ADFieldModel.shouldStartBare(field, kind, plantableNow)
if field.plan.targetFruit == nil or field.plan.targetFruit == "" then return false end
-- kun fra idle: efter egen såning står marken "done" (nysået kan læses som bar) — ingen dobbelt-såning
if kind ~= "bare" or field.stage ~= "idle" then return false end
return plantableNow == true
end
-- Krævet bredde for et sæt: kun læssevognen uden riv skal dække slåmaskinens baner.
function ADFieldModel.requiredWidth(field, role)
if role == "collector" and not field.plan.rake then
@@ -210,9 +252,11 @@ local function freshCycle(copy)
end
-- Første trin i kæden. En tom kæde (bar mark uden jordbehandling eller såning) -> færdig.
function ADFieldModel.start(field, kind, needs)
-- currentFruit (valgfri): afgrøden på marken nu; med mål-afgrøde udfyldes planen ud fra den.
function ADFieldModel.start(field, kind, needs, currentFruit)
local copy = copyField(field)
local stages = ADFieldModel.workStages(field.plan, kind, needs)
copy.plan = ADFieldModel.applyTarget(copy.plan, kind, currentFruit)
local stages = ADFieldModel.workStages(copy.plan, kind, needs)
copy.stage = stages[1] or "done"
copy.kind = kind or "mowable"
freshCycle(copy)
@@ -379,6 +423,7 @@ function ADFieldModel.toRecord(field)
rigs = plan.rigs, unloaders = plan.unloaders, mulch = flag(plan.mulch), lime = flag(plan.lime),
soil = plan.soil, sow = flag(plan.sow), sowFruit = plan.sowFruit or "", roll = flag(plan.roll),
fertilize = flag(plan.fertilize), weed = flag(plan.weed),
targetFruit = plan.targetFruit or "", prepAfterMow = flag(plan.prepAfterMow),
kind = field.kind or "", lastFruit = field.lastFruit or "", care = table.concat(care, " "),
mowWidth = field.mowWidth or 0,
mowVehicle = field.mowVehicleId or "",
@@ -415,6 +460,8 @@ function ADFieldModel.fromRecord(record)
plan.roll = readFlag(record.roll, false)
plan.fertilize = readFlag(record.fertilize, true)
plan.weed = readFlag(record.weed, true)
plan.targetFruit = record.targetFruit or ""
plan.prepAfterMow = readFlag(record.prepAfterMow, false)
field.kind = readText(record.kind)
field.lastFruit = readText(record.lastFruit)
for stage, runs in string.gmatch(record.care or "", "(%w+)=(%d+)") do field.careRuns[stage] = tonumber(runs) end