From 5bb1ad6ae08c6567f5836f6e9dc98a587d80f0e7 Mon Sep 17 00:00:00 2001 From: masterdraco Date: Sun, 27 Sep 2026 19:57:43 +0200 Subject: [PATCH] =?UTF-8?q?feat(markarbejde):=20h=C3=B8sten=20er=20f=C3=A6?= =?UTF-8?q?rdig=20men=20h=C3=B8steren=20har=20korn=20i=20tanken=20->=20CP?= =?UTF-8?q?=20genstartes=20og=20venter=20ved=20kursets=20ende,=20t=C3=B8mm?= =?UTF-8?q?evogn=20sendes=20ud,=20marken=20g=C3=A5r=20f=C3=B8rst=20videre?= =?UTF-8?q?=20n=C3=A5r=20tanken=20er=20tom=20(=C3=A9n=20gang=20pr.=20mark)?= =?UTF-8?q?=20(v1.43.0.0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FS25_ADSmartPickup/adFieldJobs.lua | 13 +++++++++++++ FS25_ADSmartPickup/adFieldWork.lua | 30 ++++++++++++++++++++++++++++++ FS25_ADSmartPickup/modDesc.xml | 2 +- tests/test_adFieldJobs.lua | 10 ++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/FS25_ADSmartPickup/adFieldJobs.lua b/FS25_ADSmartPickup/adFieldJobs.lua index 708498f..6024ca9 100644 --- a/FS25_ADSmartPickup/adFieldJobs.lua +++ b/FS25_ADSmartPickup/adFieldJobs.lua @@ -116,6 +116,13 @@ function ADFieldJobs.startTimedOut(elapsed, generating) return elapsed > (generating and ADFieldJobs.COURSE_GENERATE_MS or ADFieldJobs.START_MS) end +-- Høsten er færdig, men høsteren har korn i tanken: tøm den på marken før marken går videre (én gang pr. mark). +-- s = {fill, near, busy, controlled, tried} +ADFieldJobs.emptyAttempts = {} +function ADFieldJobs.shouldEmptyHarvester(s) + return (s.fill or 0) > 0 and s.near == true and not s.busy and not s.controlled and not s.tried +end + -- Beslutning for én mark. assignments = sæt på marken ({phase, stage, helper}); kun sæt på det aktuelle -- trin tæller (en aflæsningsvogn på vej hjem fra høsten forstyrrer ikke kultiveringen). -- env = {raining = bool}: vejrfølsomme trin (høst/slå/vend/riv/hø) sendes ikke ud i regn. @@ -379,6 +386,12 @@ local function stepField(adEnv, info, env) ADFieldJobs.log(info.id, "pleje: %s", decision.stage) ADFieldJobs.save() elseif decision.action == "advance" then + -- høsteren har stadig korn i tanken: CP genstartes og venter ved kursets ende, tømmevognene kommer + -- (marken bliver på høst til tanken er tom) — in-game 27/9 F15 + if field.stage == "harvesting" and ADFieldWork.tryEmptyHarvester ~= nil then + local okEmpty, emptying = pcall(ADFieldWork.tryEmptyHarvester, adEnv, field, info) + if okEmpty and emptying then return end + end local nextField = ADFieldModel.advance(field, info.needs) ADFieldJobs.setField(nextField) ADFieldJobs.forgetFinished(info.id) diff --git a/FS25_ADSmartPickup/adFieldWork.lua b/FS25_ADSmartPickup/adFieldWork.lua index 0b6c8f4..f486e1a 100644 --- a/FS25_ADSmartPickup/adFieldWork.lua +++ b/FS25_ADSmartPickup/adFieldWork.lua @@ -1019,6 +1019,36 @@ function ADFieldWork.autoNameFleet(adEnv) end end +-- Høsten er færdig, men den høster der høstede marken har korn i tanken og står ved marken: start dens CP-job igen +-- (sidste/nærmeste punkt), så CP venter ved kursets ende til tømmevognene har tømt den. Én gang pr. mark. +function ADFieldWork.tryEmptyHarvester(adEnv, field, info) + local vehicleId = field.harvestVehicleId + if vehicleId == nil or info == nil then return false end + local rig = nil + for _, candidate in ipairs(ADFieldWork.getRigs(adEnv)) do + if candidate.id == vehicleId then rig = candidate break end + end + if rig == nil then return false end + local fill = restLoad(adEnv, rig.vehicle) + local near = #(info.verts or {}) >= 3 and ADFieldJobs.insidePolygon(rig.x, rig.z, info.verts) + if not near and info.markerId ~= nil then + local wayPoint = adEnv.ADGraphManager:getWayPointById(info.markerId) + near = wayPoint ~= nil and math.sqrt((wayPoint.x - rig.x) ^ 2 + (wayPoint.z - rig.z) ^ 2) <= 100 + end + if not ADFieldJobs.shouldEmptyHarvester({fill = fill, near = near, busy = rig.busy, controlled = rig.controlled, + tried = ADFieldJobs.emptyAttempts[field.id] == true}) then + return false + end + ADFieldJobs.emptyAttempts[field.id] = true + local assignment = {vehicleId = rig.id, vehicle = rig.vehicle, fieldId = field.id, role = "harvester", stage = field.stage, + helper = false, phase = "driving", since = now(), width = rig.width, groupSize = 1, leader = true, + manual = rig.manual == true, emptying = true} + ADFieldJobs.state.assignments[rig.id] = assignment + log(field.id, "høsten er færdig, men '%s' har %.0f l i tanken — tømmes på marken, før marken går videre", tostring(rig.label), fill) + beginWork(adEnv, field, info, assignment) + return true +end + function ADFieldWork.follow(adEnv, assignment) local vehicle = assignment.vehicle -- Kun når spilleren selv KØRER (bevæger sig uden Courseplay/AutoDrive) slippes sættet — at sidde i diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index 671a063..15cae4f 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.42.6.0 + 1.43.0.0 <en>AD Smart Pickup</en> diff --git a/tests/test_adFieldJobs.lua b/tests/test_adFieldJobs.lua index 0a448e7..f654b7a 100644 --- a/tests/test_adFieldJobs.lua +++ b/tests/test_adFieldJobs.lua @@ -177,5 +177,15 @@ check("ST beregner stadig efter 90 s -> vent", ADFieldJobs.startTimedOut(90000, check("ST beregner over 5 min -> opgiv", ADFieldJobs.startTimedOut(301000, true), true) check("ST under 60 s -> vent", ADFieldJobs.startTimedOut(30000, false), false) + +-- shouldEmptyHarvester: høsten er færdig, men høsteren har korn i tanken og står ved marken -> tøm først +-- (in-game 27/9 F15: marken gik til halm med fuld tank, ingen tømmevogn kom) +check("EH korn i tanken ved marken -> tøm", ADFieldJobs.shouldEmptyHarvester({fill = 12000, near = true}), true) +check("EH tom tank -> videre", ADFieldJobs.shouldEmptyHarvester({fill = 0, near = true}), false) +check("EH langt væk -> videre", ADFieldJobs.shouldEmptyHarvester({fill = 12000, near = false}), false) +check("EH optaget -> videre", ADFieldJobs.shouldEmptyHarvester({fill = 12000, near = true, busy = true}), false) +check("EH spiller i -> videre", ADFieldJobs.shouldEmptyHarvester({fill = 12000, near = true, controlled = true}), false) +check("EH allerede forsøgt -> videre", ADFieldJobs.shouldEmptyHarvester({fill = 12000, near = true, tried = true}), false) + print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1)