fix(markarbejde): afgrøde og vækststadie fra field.fieldState (spillets marktilstand); getFieldDataAtWorldPosition's 2. værdi er jord-bits, ikke vækst — F108 majs = bar jord; høstet mark vises som 'stub (afgrøde)' (v1.28.7.0)

This commit is contained in:
2026-09-26 12:38:25 +02:00
parent 36f381fc36
commit abbe40da01
9 changed files with 73 additions and 14 deletions
+21 -8
View File
@@ -153,6 +153,15 @@ end
ADFields.SAMPLE_DIRECTIONS = 16
-- field.fieldState (FS25, bekræftet i AI-Bonde via aifProbe): {fruitIndex|nil, growthState} eller nil
-- når spillet ikke har tilstanden (så bruges punkt-afstemningen).
function ADFields.readFieldState(field)
local state = field ~= nil and field.fieldState or nil
if type(state) ~= "table" or type(state.fruitTypeIndex) ~= "number" then return nil end
local fruitIndex = state.fruitTypeIndex > 0 and state.fruitTypeIndex or nil
return {fruitIndex = fruitIndex, growthState = fruitIndex ~= nil and state.growthState or nil}
end
-- Markens omrids som {{x, z}, ...}. FS25: field:getDensityMapPolygon():getVerticesList() (flad liste
-- x1, z1, x2, z2 ... — som Courseplay); ældre: polygonPoints (noder). Tom liste hvis intet findes.
function ADFields.readPolygon(field)
@@ -243,7 +252,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 = {}, growthVotes = {},
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}}}
local info = {id = fieldId, field = field, points = scan.points, verts = {}, mowable = false, readyRatio = 0}
scan.info = info
@@ -289,7 +298,15 @@ end
-- Når afgrøden kendes: klar-andel, vækststadie og jord pr. punkt (én opgave pr. punkt).
function ADFields.scanPerFruit(scan)
local info = scan.info
info.fruitIndex = winner(scan.fruitVotes)
-- spillets egen marktilstand (som fields.xml) er sandheden; punkt-afstemningen er reserve.
-- (getFieldDataAtWorldPosition giver isOnField, densityBits, groundType — IKKE vækststadie)
local state = ADFields.readFieldState(info.field)
info.growthState = state ~= nil and state.growthState or nil
if state ~= nil then
info.fruitIndex = state.fruitIndex
else
info.fruitIndex = winner(scan.fruitVotes)
end
local fruitIndex = info.fruitIndex
local settings = missionSettings()
scan.settings = settings
@@ -301,11 +318,6 @@ function ADFields.scanPerFruit(scan)
if okA and anyPixels then scan.anySum = scan.anySum + anyPixels 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
local okG, _, state = pcall(function()
local y = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, 1, z)
return FSDensityMapUtil.getFieldDataAtWorldPosition(x, y, z)
end)
if okG and type(state) == "number" then vote(scan.growthVotes, state) end
end
end)
push(scan, function()
@@ -345,11 +357,12 @@ local function finishScan(adEnv, scan)
info.cropTitle = fillType ~= nil and fillType.title or (fruit ~= nil and fruit.name) or "?"
end
info.kind = ADFields.classify(info.fruitIndex, info.mowable, info.readyRatio)
info.phase = fruit ~= nil and ADFields.growthPhase(winner(scan.growthVotes), fruit) or nil
info.phase = fruit ~= nil and ADFields.growthPhase(info.growthState, fruit) or nil
info.growing = info.fruitIndex ~= nil and ADFields.isGrowing(info.phase, info.anyPixels, info.readyRatio)
-- høstet stub eller visnet afgrøde er i praksis en bar mark (klargøring/såning)
if info.kind == "harvest" and (info.phase == "cut" or info.phase == "withered" or info.phase == "none") then
info.kind = "bare"
info.stubbleOf = info.phase == "cut" and info.cropTitle or nil
end
local settings = scan.settings or missionSettings()
for key, sum in pairs(scan.soil) do