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
+31 -3
View File
@@ -9,7 +9,8 @@ ADFieldJobs.LOG_PREFIX = "ADSmartPickup: "
ADFieldJobs.TICK_MS = 1000
-- Courseplay kan efterlade hjørner på skæve marker: efter så mange færdige ture pr. sæt går marken videre.
ADFieldJobs.MAX_PASSES = 2
ADFieldJobs.state = {fields = {}, fleet = {}, assignments = {}}
-- fleetMode: "all" = alle ledige maskiner (standard, "vælg og glem"), "ticked" = kun med flueben
ADFieldJobs.state = {fields = {}, fleet = {}, assignments = {}, fleetMode = "all"}
-- mark-id -> {mower = kursus, rake = kursus, <trin> = fælles multi-tool-kursus}: kopier (kun i hukommelsen;
-- efter genindlæsning hentes slå-/rivekurset fra maskinen, som CP selv gemmer kurset på)
ADFieldJobs.courses = {}
@@ -46,6 +47,14 @@ function ADFieldJobs.decide(field, info, assignments, now, env)
end
return {action = "start"}
end
-- mål-afgrøde på en bar mark: klargør og så så snart målet kan sås
if info ~= nil and info.kind == "bare" and field.plan.targetFruit ~= nil and field.plan.targetFruit ~= "" then
local plantable = env ~= nil and env.plantable ~= nil and env.plantable(field.plan.targetFruit) or false
if ADFieldModel.shouldStartBare(field, "bare", plantable) then
if not hasMarker then return {action = "wait"} end
return {action = "start"}
end
end
if not ADFieldModel.isWorking(field) then
local care = ADFieldModel.careNeed(field, info)
if care == nil then return {action = "none"} end
@@ -124,6 +133,7 @@ function ADFieldJobs.load()
local ok, loaded = pcall(ADFieldStorage.load)
if ok then
ADFieldJobs.state.fields, ADFieldJobs.state.fleet = loaded.fields, loaded.fleet
ADFieldJobs.state.fleetMode = loaded.fleetMode or "all"
else
Logging.warning(ADFieldJobs.LOG_PREFIX .. "marker kunne ikke indlæses: %s", tostring(loaded))
end
@@ -143,6 +153,17 @@ function ADFieldJobs.forceReady(id)
ADFieldJobs.setField(ADFieldModel.forceReady(ADFieldJobs.getField(id)))
end
function ADFieldJobs.setTarget(id, fruitName)
ADFieldJobs.setField(ADFieldModel.setTarget(ADFieldJobs.getField(id), fruitName))
ADFieldJobs.log(id, "mål-afgrøde: %s", fruitName ~= "" and fruitName or "ingen")
ADFieldJobs.save()
end
function ADFieldJobs.setFleetMode(mode)
ADFieldJobs.state.fleetMode = mode
ADFieldJobs.save()
end
function ADFieldJobs.toggleFleet(vehicleId)
ADFieldJobs.state.fleet = ADFieldFleet.toggle(ADFieldJobs.state.fleet, vehicleId)
ADFieldJobs.save()
@@ -192,7 +213,14 @@ function ADFieldJobs.environment()
local weather = g_currentMission.environment.weather
return weather ~= nil and weather.getIsRaining ~= nil and weather:getIsRaining() or false
end)
return {raining = ok and raining == true}
return {
raining = ok and raining == true,
-- kan afgrøden (navn) sås i den aktuelle periode?
plantable = function(name)
local fruit = g_fruitTypeManager ~= nil and g_fruitTypeManager:getFruitTypeByName(name) or nil
return fruit ~= nil and ADCpBridge.isPlantableNow(fruit.index)
end,
}
end
-- Seneste beslutning pr. mark (GUI viser pleje-behov og grunde).
@@ -206,7 +234,7 @@ local function stepField(adEnv, info)
local decision = ADFieldJobs.decide(field, info, assignments, ADFieldJobs.now, ADFieldJobs.environment())
ADFieldJobs.lastDecision[info.id] = decision
if decision.action == "start" then
local started = ADFieldModel.start(field, info.kind, info.needs)
local started = ADFieldModel.start(field, info.kind, info.needs, info.fruitName)
started.lastFruit = info.kind == "harvest" and info.fruitName or field.lastFruit
ADFieldJobs.setField(started)
ADFieldJobs.log(info.id, "starter (%s: %s)", tostring(info.kind), started.stage)