From 5274925f2a5d32243191c72f4e7efdbb61fb61a6 Mon Sep 17 00:00:00 2001 From: masterdraco Date: Sun, 27 Sep 2026 09:09:08 +0200 Subject: [PATCH] =?UTF-8?q?fix(markarbejde):=20utoppede=20kartofler=20(for?= =?UTF-8?q?beredelige=20stadier)=20t=C3=A6ller=20som=20h=C3=B8stklare;=20k?= =?UTF-8?q?larg=C3=B8ring=20p=C3=A5=20en=20mark=20med=20uh=C3=B8stet=20afg?= =?UTF-8?q?r=C3=B8de=20spoles=20tilbage=20til=20klar=20(F16)=20(v1.34.2.0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FS25_ADSmartPickup/adFieldJobs.lua | 15 +++++++++++++++ FS25_ADSmartPickup/adFields.lua | 17 ++++++++++++++++- FS25_ADSmartPickup/modDesc.xml | 2 +- tests/test_adFieldJobs.lua | 6 ++++++ tests/test_adFields.lua | 8 ++++++++ 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/FS25_ADSmartPickup/adFieldJobs.lua b/FS25_ADSmartPickup/adFieldJobs.lua index a5dfa1b..f8ca234 100644 --- a/FS25_ADSmartPickup/adFieldJobs.lua +++ b/FS25_ADSmartPickup/adFieldJobs.lua @@ -31,6 +31,10 @@ ADFieldJobs.ACTIVE_PHASES = {driving = true, starting = true, waitingCourse = tr -- Andel græs i mellemhøjde (høstbart, men halv ydelse) der får en afbrudt slåning til at vente. ADFieldJobs.REGROW_RATIO = 0.1 +-- Trin efter høsten der ødelægger/ignorerer en stående afgrøde. +ADFieldJobs.PREP_STAGES = {strawCollecting = true, baling = true, baleCollecting = true, mulching = true, liming = true, + plowing = true, cultivating = true, sowing = true, rolling = true} + -- ---- ren beslutning ---- -- Er afgrøden taget (trin med afgrøde)? Slåning: under 50 % står. Høst: marken er bar eller under 50 %. @@ -65,6 +69,12 @@ function ADFieldJobs.decide(field, info, assignments, now, env) return {action = "start"} end end + -- klargøring på en mark hvor afgrøden står uhøstet: tilbage til klar (in-game 27/9 F16: kartofler + -- blev regnet som høstet, og marken stod til kultivering med afgrøden i jorden) + if ADFieldJobs.PREP_STAGES[field.stage] and info ~= nil and info.kind == "harvest" and info.phase == "ready" + and (info.readyRatio or 0) >= ADFieldModel.READY_RATIO then + return {action = "rewind"} + end if not ADFieldModel.isWorking(field) then local care = ADFieldModel.careNeed(field, info) if care == nil then return {action = "none"} end @@ -256,6 +266,11 @@ local function stepField(adEnv, info, env) ADFieldJobs.setField(started) ADFieldJobs.log(info.id, "starter (%s: %s)", tostring(info.kind), started.stage) ADFieldJobs.save() + elseif decision.action == "rewind" then + ADFieldJobs.setField(ADFieldModel.with(field, {stage = "ready", retryAt = 0, reason = false})) + ADFieldWork.windDownHelpers(adEnv, info.id, field.stage) + ADFieldJobs.log(info.id, "%s -> ready: afgrøden står stadig uhøstet (%.0f %% klar)", field.stage, (info.readyRatio or 0) * 100) + ADFieldJobs.save() elseif decision.action == "care" then ADFieldJobs.setField(ADFieldModel.startCare(field, decision.stage)) ADFieldJobs.log(info.id, "pleje: %s", decision.stage) diff --git a/FS25_ADSmartPickup/adFields.lua b/FS25_ADSmartPickup/adFields.lua index df12dc3..5291aa7 100644 --- a/FS25_ADSmartPickup/adFields.lua +++ b/FS25_ADSmartPickup/adFields.lua @@ -50,6 +50,7 @@ end function ADFields.growthPhase(state, fruit) if state == nil or fruit == nil then return nil end if state == 0 then return "none" end + if ADFields.isPreparable(state, fruit) then return "ready" end if fruit.cutState ~= nil and fruit.cutState ~= 0 and state == fruit.cutState then return "cut" end if fruit.witheredState ~= nil and state == fruit.witheredState then return "withered" end local minReady = fruit.minHarvestingGrowthState or fruit.minHarvestGrowthState @@ -71,6 +72,15 @@ function ADFields.primeState(fruit) return minReady end +-- Kan stadiet "forberedes" (toppes)? Dakota-kartofler: "harvestReady" er kun forberedelig — først det +-- toppede stadie er høstklart, men skærebord med topper (Ropa rrXL9) tager begge i ét drag. +function ADFields.isPreparable(state, fruit) + if fruit == nil or type(state) ~= "number" or state <= 0 then return false end + local minPrep, maxPrep = fruit.minPreparingGrowthState, fruit.maxPreparingGrowthState + if type(minPrep) ~= "number" or minPrep <= 0 then return false end + return state >= minPrep and state <= (type(maxPrep) == "number" and maxPrep >= minPrep and maxPrep or minPrep) +end + -- Tæller punktets klar-pixels? Kun når stadiet (4. værdi fra getFruitArea) er fuldt udvokset. function ADFields.isPrime(growthState, prime) if prime == nil or type(growthState) ~= "number" or growthState <= 0 then return true end @@ -369,8 +379,9 @@ function ADFields.scanPerFruit(scan) -- slåafgrøder: genvækst i mellemhøjde tæller ikke som klar (in-game 27/9: halvt slået F90 blev -- klippet igen i mellemhøjde) local prime = nil + local fruitDesc = fruitIndex ~= nil and g_fruitTypeManager:getFruitTypeByIndex(fruitIndex) or nil if fruitIndex ~= nil and ADFields.getMowable()[fruitIndex] ~= nil then - prime = ADFields.primeState(g_fruitTypeManager:getFruitTypeByIndex(fruitIndex)) + prime = ADFields.primeState(fruitDesc) end for _, point in ipairs(scan.points) do push(scan, function() @@ -382,6 +393,10 @@ function ADFields.scanPerFruit(scan) if not ADFields.isPrime(pointState, prime) then scan.immatureSum = scan.immatureSum + anyPixels end end local okR, _, readyPixels = pcall(FSDensityMapUtil.getFruitArea, fruitIndex, x - 2, z - 2, x + 2, z, x, z + 2, false, false) + -- utoppede kartofler tæller som klar (in-game 27/9 F16: klar-andel 0 -> sprang høsten over) + if okA and anyPixels and ADFields.isPreparable(pointState, fruitDesc) then + okR, readyPixels = true, math.max(readyPixels or 0, anyPixels) + end if okR and readyPixels and ADFields.isPrime(okA and pointState or nil, prime) then scan.readySum = scan.readySum + readyPixels end diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index caae4cb..8ec4501 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.34.1.0 + 1.34.2.0 <en>AD Smart Pickup</en> diff --git a/tests/test_adFieldJobs.lua b/tests/test_adFieldJobs.lua index 875c73c..43d4c58 100644 --- a/tests/test_adFieldJobs.lua +++ b/tests/test_adFieldJobs.lua @@ -105,5 +105,11 @@ check("J13 genvækst -> vent", dRegrow.action, "wait"); check("J13 grund", dRegr check("J13 genvækst men tur færdig -> slå hjørnet", J.decide(mowing, regrowing, {{phase = "finished"}}, 0).action, "dispatch") check("J13 halvt slået uden genvækst -> slå resten", J.decide(mowing, {id = 90, markerId = 9, mowable = true, readyRatio = 0.6, immatureRatio = 0}, {}, 0).action, "dispatch") +-- J14: kultivering på en mark med uhøstede kartofler (in-game 27/9 F16) -> tilbage til klar; rest efter høst -> ikke +local cultivatingField = M.with(auto, {stage = "cultivating", kind = "harvest"}) +check("J14 uhøstet -> spol tilbage", J.decide(cultivatingField, {id = 16, markerId = 9, kind = "harvest", phase = "ready", readyRatio = 1}, {}, 0).action, "rewind") +check("J14 høstrest 30 % -> kultiver", J.decide(cultivatingField, {id = 16, markerId = 9, kind = "harvest", phase = "ready", readyRatio = 0.3}, {}, 0).action ~= "rewind", true) +check("J14 stub -> kultiver", J.decide(cultivatingField, {id = 16, markerId = 9, kind = "bare", phase = "cut", readyRatio = 0}, {}, 0).action ~= "rewind", 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 2bdbf18..72c6db5 100644 --- a/tests/test_adFields.lua +++ b/tests/test_adFields.lua @@ -70,5 +70,13 @@ check("F8 fuld højde tæller", F.isPrime(5, 4), true) check("F8 ukendt stadie tæller", F.isPrime(nil, 4), true) check("F8 ingen krav", F.isPrime(3, nil), true) +-- F9: kartofler (Dakota): 6 = klar men kun forberedelig, 10 = toppet (høstklar) +local potato = {minHarvestingGrowthState = 10, maxHarvestingGrowthState = 10, minPreparingGrowthState = 6, maxPreparingGrowthState = 6, witheredState = 7, cutState = 8} +check("F9 utoppet er forberedelig", F.isPreparable(6, potato), true) +check("F9 voksende ikke", F.isPreparable(5, potato), false) +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) + print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1)