From 59e18acc9c9b3768126276fc9ef94cc2c62d13f2 Mon Sep 17 00:00:00 2001 From: masterdraco Date: Mon, 28 Sep 2026 19:57:02 +0200 Subject: [PATCH] =?UTF-8?q?fix(markarbejde):=20kultivering/pl=C3=B8jning?= =?UTF-8?q?=20m=C3=A5les=20p=C3=A5=20jorden=20=E2=80=94=20er=20=E2=89=A595?= =?UTF-8?q?=20%=20af=20marken=20klargjort/pl=C3=B8jet,=20g=C3=A5r=20trinne?= =?UTF-8?q?t=20videre=20uden=20at=20sende=20maskinen=20ud=20igen=20(ogs?= =?UTF-8?q?=C3=A5=20efter=20genindl=C3=A6sning;=20F17=20blev=20kultiveret?= =?UTF-8?q?=203=20gange)=20(v1.50.3.0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FS25_ADSmartPickup/adFieldJobs.lua | 11 ++++++++ FS25_ADSmartPickup/adFields.lua | 40 +++++++++++++++++++++++++++++- FS25_ADSmartPickup/modDesc.xml | 2 +- tests/test_adFieldJobs.lua | 18 ++++++++++++++ tests/test_adFields.lua | 10 ++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) diff --git a/FS25_ADSmartPickup/adFieldJobs.lua b/FS25_ADSmartPickup/adFieldJobs.lua index 81c35b1..2968159 100644 --- a/FS25_ADSmartPickup/adFieldJobs.lua +++ b/FS25_ADSmartPickup/adFieldJobs.lua @@ -34,6 +34,11 @@ ADFieldJobs.ACTIVE_PHASES = {fetching = true, driving = true, starting = true, w ADFieldJobs.REGROW_RATIO = 0.1 -- Trin efter høsten der ødelægger/ignorerer en stående afgrøde. +-- Klargøring der kan måles på jorden: trin -> info-felt (andel af marken). Kultivering er gjort når jorden er +-- klargjort (kultiveret/pløjet/såbed/stubbearbejdet); pløjning først når den er pløjet. +ADFieldJobs.GROUND_PREP_STAGES = {cultivating = "prepared", plowing = "plowed"} +ADFieldJobs.PREPARED_DONE_RATIO = 0.95 + ADFieldJobs.PREP_STAGES = {strawCollecting = true, baling = true, baleCollecting = true, mulching = true, liming = true, plowing = true, cultivating = true, sowing = true, rolling = true} @@ -190,6 +195,12 @@ function ADFieldJobs.decide(field, info, assignments, now, env) if active == 0 then -- afgrøden er væk (sluppet undervejs, genindlæst, eller færdig): videre if isCropStage and cropGone(field.stage, info) then return {action = "advance"} end + -- klargøringen er allerede gjort (målt på jorden): videre — også efter genindlæsning, hvor + -- opgaven ikke er husket (in-game 28/9: F17 blev kultiveret 3 gange) + local groundKey = ADFieldJobs.GROUND_PREP_STAGES[field.stage] + if groundKey ~= nil and info ~= nil and type(info[groundKey]) == "number" and info[groundKey] >= ADFieldJobs.PREPARED_DONE_RATIO then + return {action = "advance"} + end if finished > 0 then local maxPasses = ADFieldJobs.MAX_PASSES * ADFieldModel.maxRigs(field.stage, field.plan) if not isCropStage or finished >= maxPasses then return {action = "advance"} end diff --git a/FS25_ADSmartPickup/adFields.lua b/FS25_ADSmartPickup/adFields.lua index da84168..acdd561 100644 --- a/FS25_ADSmartPickup/adFields.lua +++ b/FS25_ADSmartPickup/adFields.lua @@ -192,6 +192,38 @@ function ADFields.readFieldState(field) noFieldGround = type(state.groundType) == "number" and state.groundType == groundNone} end +-- Jordtyper der tæller som klargjort til såning (stubbearbejdet, kultiveret, såbed, pløjet). +ADFields.PREPARED_GROUNDS = {"STUBBLE_TILLAGE", "CULTIVATED", "SEEDBED", "PLOWED", "ROLLED_SEEDBED"} + +-- value = jordtypens tæthedsværdi i et punkt; values = {[typenavn] = værdi}. -> klargjort, pløjet (nil: ukendt) +function ADFields.classifyGround(value, values) + if value == nil or values == nil then return nil, nil end + -- ingen markjord (bygget over / uden for marken): tæller ikke med i andelen + if values.NONE ~= nil and values.NONE == value then return nil, nil end + local prepared = false + for _, name in ipairs(ADFields.PREPARED_GROUNDS) do + if values[name] ~= nil and values[name] == value then prepared = true end + end + return prepared, values.PLOWED ~= nil and values.PLOWED == value +end + +-- Spillets tæthedsværdier for jordtyperne (FieldGroundType -> værdi i GROUND_TYPE-kanalen). +function ADFields.groundValues() + if ADFields.groundValueCache ~= nil then return ADFields.groundValueCache or nil end + local system = g_currentMission ~= nil and g_currentMission.fieldGroundSystem or nil + if type(FieldGroundType) ~= "table" or system == nil then return nil end + local values = {} + for _, name in ipairs({"NONE", "STUBBLE_TILLAGE", "CULTIVATED", "SEEDBED", "PLOWED", "ROLLED_SEEDBED"}) do + local groundType = FieldGroundType[name] + if groundType ~= nil then + local ok, value = pcall(function() return system:getFieldGroundValue(groundType) end) + values[name] = ok and type(value) == "number" and value or groundType + end + end + ADFields.groundValueCache = values + return values +end + -- Kan marken dyrkes? Nej hvis spillet siger "ingen markjord" (groundType NONE: bygget over — gårdsplads, -- stald, biogasanlæg), eller hvis intet prøvepunkt ligger på markjord. En markensilo i et hjørne ændrer -- intet: resten af marken er stadig markjord. @@ -318,7 +350,7 @@ end local function newScan(adEnv, entry) local field, fieldId = entry.field, entry.id local scan = {id = fieldId, queue = {}, head = 1, tail = 0, points = {}, fruitVotes = {}, - anySum = 0, readySum = 0, immatureSum = 0, totalSum = 0, soil = {fert = {0, 0}, lime = {0, 0}, plowLevel = {0, 0}, weed = {0, 0}}} + anySum = 0, readySum = 0, immatureSum = 0, totalSum = 0, soil = {fert = {0, 0}, lime = {0, 0}, plowLevel = {0, 0}, weed = {0, 0}, prepared = {0, 0}, plowed = {0, 0}}} local info = {id = fieldId, field = field, points = scan.points, verts = {}, mowable = false, readyRatio = 0} scan.info = info -- 1) polygon og kandidatpunkter (centroid + halvvejs mod op til 8 hjørner) @@ -413,6 +445,12 @@ function ADFields.scanPerFruit(scan) plowLevel = readDensity(FieldDensityMap.PLOW_LEVEL, x, z), weed = settings.weedsEnabled and readWeed(x, z) or nil, } + -- klargjort/pløjet jord i punktet (kun på markjord): klargøringstrin der allerede er gjort går videre + local prepared, plowed = ADFields.classifyGround(readDensity(FieldDensityMap.GROUND_TYPE, x, z), ADFields.groundValues()) + if prepared ~= nil then + readings.prepared = prepared and 1 or 0 + readings.plowed = plowed and 1 or 0 + end for key, value in pairs(readings) do if value ~= nil then scan.soil[key][1] = scan.soil[key][1] + value diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index f53184a..356f70a 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.50.2.0 + 1.50.3.0 <en>AD Smart Pickup</en> diff --git a/tests/test_adFieldJobs.lua b/tests/test_adFieldJobs.lua index 324e2cc..f3c12d1 100644 --- a/tests/test_adFieldJobs.lua +++ b/tests/test_adFieldJobs.lua @@ -200,5 +200,23 @@ end -- pulje: en traktor der henter et redskab tæller som i gang (ellers sendes endnu en ud) check("pulje: henter -> ingenting", J.decide(mowing, info, {{phase = "fetching"}}, 0).action, "none") +-- JP: klargøring der allerede er gjort (fx efter genindlæsning) går videre uden at sende maskinen ud igen +-- (in-game 28/9: F17 blev kultiveret 3 gange — opgaver gemmes ikke, så "færdig" blev aldrig set) +local cultField = M.with(M.newField(17), {stage = "cultivating", kind = "bare", plan = {mode = "auto"}}) +local cultInfo = {id = 17, markerId = 5, kind = "bare", readyRatio = 0, needs = {}} +cultInfo.prepared = 0.98 +check("JP kultiveret -> videre", J.decide(cultField, cultInfo, {}, 0).action, "advance") +cultInfo.prepared = 0.4 +check("JP halvt kultiveret -> send maskine", J.decide(cultField, cultInfo, {}, 0).action, "dispatch") +cultInfo.prepared = nil +check("JP ukendt jord -> som før (send)", J.decide(cultField, cultInfo, {}, 0).action, "dispatch") +cultInfo.prepared = 0.98 +check("JP kultivator i gang -> vent på den", J.decide(cultField, cultInfo, {{phase = "working", stage = "cultivating"}}, 0).action, "none") +local plowField = M.with(cultField, {stage = "plowing"}) +check("JP kultiveret er ikke pløjet -> send plov", J.decide(plowField, cultInfo, {}, 0).action, "dispatch") +cultInfo.plowed = 0.97 +check("JP pløjet -> videre", J.decide(plowField, cultInfo, {}, 0).action, "advance") +local sowField = M.with(cultField, {stage = "sowing"}) +check("JP såning berøres ikke af klargjort jord", J.decide(sowField, cultInfo, {}, 0).action ~= "advance", true) print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1) diff --git a/tests/test_adFields.lua b/tests/test_adFields.lua index 72c6db5..969369c 100644 --- a/tests/test_adFields.lua +++ b/tests/test_adFields.lua @@ -78,5 +78,15 @@ check("F9 fase klar", F.growthPhase(6, potato), "ready") check("F9 toppet klar", F.growthPhase(10, potato), "ready") check("F9 ingen forberedelse", F.isPreparable(6, {minPreparingGrowthState = -1}), false) +-- jordtype -> klargjort/pløjet (værdierne kommer fra spillets fieldGroundSystem) +local groundValues = {STUBBLE_TILLAGE = 1, CULTIVATED = 2, SEEDBED = 3, PLOWED = 4, ROLLED_SEEDBED = 5, SOWN = 6} +local function cls(v) local p, pl = ADFields.classifyGround(v, groundValues) return tostring(p) .. "|" .. tostring(pl) end +check("jord: pløjet", cls(4), "true|true") +check("jord: kultiveret", cls(2), "true|false") +check("jord: stubbearbejdet", cls(1), "true|false") +check("jord: sået", cls(6), "false|false") +check("jord: ukendt værdi", cls(nil), "nil|nil") +groundValues.NONE = 0 +check("jord: ingen markjord tæller ikke med", cls(0), "nil|nil") print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1)