fix(markarbejde): utoppede kartofler (forberedelige stadier) tæller som høstklare; klargøring på en mark med uhøstet afgrøde spoles tilbage til klar (F16) (v1.34.2.0)

This commit is contained in:
2026-09-27 09:09:08 +02:00
parent 307676004e
commit 5274925f2a
5 changed files with 46 additions and 2 deletions
+15
View File
@@ -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)
+16 -1
View File
@@ -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
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<modDesc descVersion="107">
<author>masterdraco</author>
<version>1.34.1.0</version>
<version>1.34.2.0</version>
<title>
<en>AD Smart Pickup</en>
</title>
+6
View File
@@ -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)
+8
View File
@@ -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)