diff --git a/FS25_ADSmartPickup/adFieldJobs.lua b/FS25_ADSmartPickup/adFieldJobs.lua index b3dd037..a5dfa1b 100644 --- a/FS25_ADSmartPickup/adFieldJobs.lua +++ b/FS25_ADSmartPickup/adFieldJobs.lua @@ -28,6 +28,9 @@ ADFieldJobs.loaded = false ADFieldJobs.ACTIVE_PHASES = {driving = true, starting = true, waitingCourse = true, working = true} +-- 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 + -- ---- ren beslutning ---- -- Er afgrøden taget (trin med afgrøde)? Slåning: under 50 % står. Høst: marken er bar eller under 50 %. @@ -89,6 +92,11 @@ function ADFieldJobs.decide(field, info, assignments, now, env) local maxPasses = ADFieldJobs.MAX_PASSES * ADFieldModel.maxRigs(field.stage, field.plan) if not isCropStage or finished >= maxPasses then return {action = "advance"} end end + -- slåning uden maskine på en halvt slået mark: vent til genvæksten er fuldt udvokset igen + -- (et hjørne Courseplay efterlod i samme omgang, finished > 0, slås straks) + if field.stage == "mowing" and finished == 0 and info ~= nil and (info.immatureRatio or 0) > ADFieldJobs.REGROW_RATIO then + return {action = "wait", reason = "regrowing"} + end if not hasMarker then return {action = "wait"} end if (field.retryAt or 0) > now then return {action = "none"} end if raining and ADFieldModel.isWeatherSensitive(field.stage, field.plan, kind) then @@ -262,9 +270,10 @@ local function stepField(adEnv, info, env) ADFieldJobs.notify(string.format("F%d %s", info.id, g_i18n ~= nil and g_i18n:getText("spu_field_notice_done") or "done"), false) end ADFieldJobs.save() - elseif decision.action == "wait" and decision.reason == "rain" then - if field.reason == nil or field.reason.key ~= "spu_field_reason_rain" then - ADFieldJobs.note(info.id, {reason = {key = "spu_field_reason_rain"}}) + elseif decision.action == "wait" and decision.reason ~= nil then + local key = "spu_field_reason_" .. decision.reason + if field.reason == nil or field.reason.key ~= key then + ADFieldJobs.note(info.id, {reason = {key = key}}) end elseif decision.action == "dispatch" then ADFieldWork.dispatch(adEnv, field, info, decision) diff --git a/FS25_ADSmartPickup/adFields.lua b/FS25_ADSmartPickup/adFields.lua index c651d8e..df12dc3 100644 --- a/FS25_ADSmartPickup/adFields.lua +++ b/FS25_ADSmartPickup/adFields.lua @@ -59,6 +59,24 @@ function ADFields.growthPhase(state, fruit) return "cut" end +-- Fuldt udvokset stadie for en slåafgrøde: græs er "høstbart" allerede i mellemhøjde (halv ydelse, +-- Dakota-græs: greenMiddle 3 < harvestReady 4 < harvestReady2 5), så slåning venter til stadiet efter +-- det første høstbare, når afgrøden har flere. nil = ukendte grænser (ingen ekstra krav). +function ADFields.primeState(fruit) + if fruit == nil then return nil end + local minReady = fruit.minHarvestingGrowthState or fruit.minHarvestGrowthState + if minReady == nil then return nil end + local maxReady = fruit.maxHarvestingGrowthState or fruit.maxHarvestGrowthState or minReady + if maxReady > minReady then return minReady + 1 end + return minReady +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 + return growthState >= prime +end + -- Vokser marken? Fasen vinder; ukendt fase -> der er voksende afgrøde (getFruitArea) og den er ikke klar. function ADFields.isGrowing(phase, anyPixels, readyRatio) if phase ~= nil then return phase == "growing" end @@ -290,7 +308,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, soil = {fert = {0, 0}, lime = {0, 0}, plowLevel = {0, 0}, weed = {0, 0}}} + anySum = 0, readySum = 0, immatureSum = 0, soil = {fert = {0, 0}, lime = {0, 0}, plowLevel = {0, 0}, weed = {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) @@ -348,14 +366,25 @@ function ADFields.scanPerFruit(scan) local fruitIndex = info.fruitIndex local settings = missionSettings() scan.settings = settings + -- 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 + if fruitIndex ~= nil and ADFields.getMowable()[fruitIndex] ~= nil then + prime = ADFields.primeState(g_fruitTypeManager:getFruitTypeByIndex(fruitIndex)) + end for _, point in ipairs(scan.points) do push(scan, function() local x, z = point.x, point.z if fruitIndex ~= nil then - local okA, _, anyPixels = pcall(FSDensityMapUtil.getFruitArea, fruitIndex, x - 2, z - 2, x + 2, z, x, z + 2, true, true) - if okA and anyPixels then scan.anySum = scan.anySum + anyPixels end + local okA, _, anyPixels, _, pointState = pcall(FSDensityMapUtil.getFruitArea, fruitIndex, x - 2, z - 2, x + 2, z, x, z + 2, true, true) + if okA and anyPixels then + scan.anySum = scan.anySum + anyPixels + 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) - if okR and readyPixels then scan.readySum = scan.readySum + readyPixels end + if okR and readyPixels and ADFields.isPrime(okA and pointState or nil, prime) then + scan.readySum = scan.readySum + readyPixels + end end end) push(scan, function() @@ -387,6 +416,7 @@ local function finishScan(adEnv, scan) local fruit = nil if info.fruitIndex ~= nil then info.readyRatio = scan.anySum > 0 and scan.readySum / scan.anySum or 0 + info.immatureRatio = scan.anySum > 0 and scan.immatureSum / scan.anySum or 0 info.anyPixels = scan.anySum fruit = g_fruitTypeManager:getFruitTypeByIndex(info.fruitIndex) info.fruitName = fruit ~= nil and fruit.name or nil diff --git a/FS25_ADSmartPickup/l10n/l10n_da.xml b/FS25_ADSmartPickup/l10n/l10n_da.xml index 2a7e67c..57a282b 100644 --- a/FS25_ADSmartPickup/l10n/l10n_da.xml +++ b/FS25_ADSmartPickup/l10n/l10n_da.xml @@ -60,6 +60,7 @@ + @@ -173,6 +174,7 @@ + diff --git a/FS25_ADSmartPickup/l10n/l10n_en.xml b/FS25_ADSmartPickup/l10n/l10n_en.xml index d8018dc..f232a4f 100644 --- a/FS25_ADSmartPickup/l10n/l10n_en.xml +++ b/FS25_ADSmartPickup/l10n/l10n_en.xml @@ -60,6 +60,7 @@ + @@ -173,6 +174,7 @@ + diff --git a/FS25_ADSmartPickup/modDesc.xml b/FS25_ADSmartPickup/modDesc.xml index 34577b1..caae4cb 100644 --- a/FS25_ADSmartPickup/modDesc.xml +++ b/FS25_ADSmartPickup/modDesc.xml @@ -1,7 +1,7 @@ masterdraco - 1.34.0.0 + 1.34.1.0 <en>AD Smart Pickup</en> diff --git a/tests/test_adFieldJobs.lua b/tests/test_adFieldJobs.lua index 38e9db7..875c73c 100644 --- a/tests/test_adFieldJobs.lua +++ b/tests/test_adFieldJobs.lua @@ -98,5 +98,12 @@ check("J12 bar + ikke såtid -> intet", J.decide(bareTarget, bareInfo, {}, 0, {p check("J12 bar uden markør -> vent", J.decide(bareTarget, {id = 90, kind = "bare"}, {}, 0, canSow).action, "wait") check("J12 voksende mark med mål -> lad den vokse", J.decide(bareTarget, {id = 90, markerId = 9, kind = "harvest", growing = true, readyRatio = 0.3}, {}, 0, canSow).action, "none") +-- J13: afbrudt slåning efter genindlæsning (in-game 27/9 F90): genvækst i mellemhøjde -> vent; hjørne efter en tur -> slå straks +local regrowing = {id = 90, markerId = 9, mowable = true, readyRatio = 0.5, immatureRatio = 0.5} +local dRegrow = J.decide(mowing, regrowing, {}, 0) +check("J13 genvækst -> vent", dRegrow.action, "wait"); check("J13 grund", dRegrow.reason, "regrowing") +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") + 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 d67cbf2..2bdbf18 100644 --- a/tests/test_adFields.lua +++ b/tests/test_adFields.lua @@ -61,5 +61,14 @@ check("F7 reserve: voksende pixels", F.isGrowing(nil, 50, 0.2), true) check("F7 reserve: ingen pixels (stub)", F.isGrowing(nil, 0, 0), false) check("F7 reserve: klar", F.isGrowing(nil, 50, 0.95), false) +-- F8: slåafgrøde fuldt udvokset (Dakota-græs 3 = mellemhøjde, 4-5 = fuld) +check("F8 prime græs", F.primeState({minHarvestingGrowthState = 3, maxHarvestingGrowthState = 5}), 4) +check("F8 prime ét klar-stadie", F.primeState({minHarvestingGrowthState = 6, maxHarvestingGrowthState = 6}), 6) +check("F8 prime ukendt", F.primeState({}), nil) +check("F8 mellemhøjde tæller ikke", F.isPrime(3, 4), false) +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) + print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1)