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:
@@ -37,3 +37,12 @@ function ADFieldView.soilParts(info)
|
||||
if (info.weed or 0) >= ADFieldModel.WEED_MIN then table.insert(parts, "weed") end
|
||||
return parts
|
||||
end
|
||||
|
||||
-- Afgrødekolonnen: høstet mark = "stub (Hvede)", bar mark = "bar jord", ellers afgrøden.
|
||||
function ADFieldView.cropText(info, getText)
|
||||
if info.kind == "bare" and info.stubbleOf ~= nil then
|
||||
return string.format(getText("spu_field_stubble"), tostring(info.stubbleOf))
|
||||
end
|
||||
if info.kind == "bare" then return getText("spu_field_bare") end
|
||||
return tostring(info.cropTitle or "-")
|
||||
end
|
||||
|
||||
@@ -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
|
||||
-- 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
|
||||
|
||||
@@ -109,7 +109,7 @@ function SmartPickupFrame:fieldCells(row)
|
||||
table.insert(names, ADRuns.vehicleLabel(assignment.vehicle))
|
||||
end
|
||||
local name = string.format("%s%sF%d", info.id == self.selectedFieldId and "> " or "", info.markerId == nil and "! " or "", info.id)
|
||||
local crop = info.kind == "bare" and self.i18n:getText("spu_field_bare") or (info.cropTitle or "-")
|
||||
local crop = ADFieldView.cropText(info, function(key) return self.i18n:getText(key) end)
|
||||
return {
|
||||
name, crop, self:fieldPlanText(field, info),
|
||||
self.i18n:getText(field.plan.mode == "auto" and "spu_field_mode_auto" or "spu_field_mode_manual"),
|
||||
@@ -190,7 +190,7 @@ function SmartPickupFrame:fillFieldDetail(adEnv, info)
|
||||
local field = ADFieldJobs.getField(info.id)
|
||||
local plan = field.plan
|
||||
local yesNo = {i18n:getText("ui_no"), i18n:getText("ui_yes")}
|
||||
local crop = info.kind == "bare" and i18n:getText("spu_field_bare") or tostring(info.cropTitle or "-")
|
||||
local crop = ADFieldView.cropText(info, function(key) return i18n:getText(key) end)
|
||||
self:addTextRow(string.format(i18n:getText("spu_field_section"), info.id, crop))
|
||||
local targetTexts, targetValues = self:sowFruitChoices("spu_field_target_none")
|
||||
self:addChoiceRow("fieldTarget", i18n:getText("spu_field_target"), targetTexts, targetValues, plan.targetFruit or "")
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
<text name="spu_field_fermenter" text="gæringssilo"/>
|
||||
<text name="spu_field_storeAutoSilage" text="intet valgt: nærmeste gæringssilo med plads, ellers nærmeste silo"/>
|
||||
<text name="spu_field_bare" text="bar jord"/>
|
||||
<text name="spu_field_stubble" text="stub (%s)"/>
|
||||
<text name="spu_field_careNeed" text="trænger til %s"/>
|
||||
<text name="spu_field_fertilize" text="Gød op til max (når afgrøden vokser)"/>
|
||||
<text name="spu_field_lime" text="Kalk når jorden trænger"/>
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
<text name="spu_field_fermenter" text="fermenting silo"/>
|
||||
<text name="spu_field_storeAutoSilage" text="none chosen: nearest fermenting silo with room, else nearest silo"/>
|
||||
<text name="spu_field_bare" text="bare soil"/>
|
||||
<text name="spu_field_stubble" text="stubble (%s)"/>
|
||||
<text name="spu_field_careNeed" text="needs %s"/>
|
||||
<text name="spu_field_fertilize" text="Fertilize to max (while the crop grows)"/>
|
||||
<text name="spu_field_lime" text="Lime when the soil needs it"/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<modDesc descVersion="107">
|
||||
<author>masterdraco</author>
|
||||
<version>1.28.6.0</version>
|
||||
<version>1.28.7.0</version>
|
||||
<title>
|
||||
<en>AD Smart Pickup</en>
|
||||
</title>
|
||||
|
||||
@@ -38,5 +38,12 @@ local parts = V.soilParts({lime = 0.2, fert = 1, fertMax = 2, weed = 3, needs =
|
||||
check("V5 dele", table.concat(parts, ","), "lime,plow,fert,weed")
|
||||
check("V5 intet", #V.soilParts({lime = 2, fert = 2, fertMax = 2, weed = 0, needs = {}}), 0)
|
||||
|
||||
-- cropText: høstet = stub (afgrøde), bar = bar jord, ellers afgrøden
|
||||
local texts = {spu_field_stubble = "stub (%s)", spu_field_bare = "bar jord"}
|
||||
local function T(key) return texts[key] end
|
||||
check("FVcrop stub", ADFieldView.cropText({kind = "bare", stubbleOf = "Hvede", cropTitle = "Hvede"}, T), "stub (Hvede)")
|
||||
check("FVcrop bar", ADFieldView.cropText({kind = "bare"}, T), "bar jord")
|
||||
check("FVcrop afgrøde", ADFieldView.cropText({kind = "harvest", cropTitle = "Majs"}, T), "Majs")
|
||||
|
||||
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
|
||||
os.exit(failures == 0 and 0 or 1)
|
||||
|
||||
@@ -15,7 +15,7 @@ local MAIZE = 10
|
||||
function getWorldTranslation() return 0, 0, 0 end
|
||||
function getTerrainHeightAtWorldPos() return 0 end
|
||||
-- markskiltet står i marken, men ved en stribe uden afgrøde (x > 1400)
|
||||
local function cropAt(x) return x <= 1400 and MAIZE or nil end
|
||||
function cropAt(x) return x <= 1400 and MAIZE or nil end
|
||||
FSDensityMapUtil = {
|
||||
getFieldDataAtWorldPosition = function() return 1, 2 end,
|
||||
getFruitTypeIndexAtWorldPos = function(x, z) return cropAt(x) end,
|
||||
@@ -56,5 +56,31 @@ check("PG3 majsen findes trods skiltet på bar stribe", info and info.fruitName,
|
||||
check("PG4 ikke bar mark", info and info.kind, "harvest")
|
||||
check("PG5 markør ved kanten findes (afstand til omridset)", info and info.markerId, 900)
|
||||
check("PG6 afstand = til kanten", info and info.markerDistance, 5)
|
||||
|
||||
-- PG7-9: field.fieldState er spillets sandhed (fields.xml: MAIZE growthState 2); jord-bits fra
|
||||
-- getFieldDataAtWorldPosition (2. værdi) er IKKE vækststadie. Høstet mark (cutState) = bar, vist som stub.
|
||||
|
||||
field.fieldState = {fruitTypeIndex = MAIZE, growthState = 2}
|
||||
FSDensityMapUtil.getFieldDataAtWorldPosition = function() return true, 0 end -- jord-bits 0 lignede "ingen vækst"
|
||||
local function rescan()
|
||||
ADFields.cache, ADFields.listCache, ADFields.activeScan, ADFields.lastScanStart = {}, nil, nil, nil
|
||||
for _ = 1, 2000 do
|
||||
if ADFields.getInfo(108) ~= nil then break end
|
||||
ADFields.scanStep(adEnv, 1, now)
|
||||
now = now + 16
|
||||
end
|
||||
return ADFields.getInfo(108)
|
||||
end
|
||||
info = rescan()
|
||||
check("PG7 majs i vækst (fieldState), ikke bar", info and info.kind, "harvest")
|
||||
check("PG7 fase vokser", info and info.phase, "growing")
|
||||
field.fieldState = {fruitTypeIndex = MAIZE, growthState = 9}
|
||||
info = rescan()
|
||||
check("PG8 høstet (cutState) = bar", info and info.kind, "bare")
|
||||
check("PG8 stub af majs", info and info.stubbleOf, "Majs")
|
||||
field.fieldState = {fruitTypeIndex = 0, growthState = 0}
|
||||
cropAt = function() return nil end
|
||||
info = rescan()
|
||||
check("PG9 ingen afgrøde = bar uden stub", info and info.kind .. "/" .. tostring(info.stubbleOf), "bare/nil")
|
||||
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
|
||||
os.exit(failures == 0 and 0 or 1)
|
||||
|
||||
@@ -17,7 +17,7 @@ function getWorldTranslation(node) local p = nodes[node]; return p[1], 0, p[2] e
|
||||
function getTerrainHeightAtWorldPos() return 0 end
|
||||
local calls = 0
|
||||
FSDensityMapUtil = {
|
||||
getFieldDataAtWorldPosition = function() calls = calls + 1; return 1, 6 end, -- på mark, vækststadie 6
|
||||
getFieldDataAtWorldPosition = function() calls = calls + 1; return true, 170 end, -- på mark (2. værdi = jord-bits, IKKE vækst)
|
||||
getFruitTypeIndexAtWorldPos = function() calls = calls + 1; return WHEAT end,
|
||||
getFruitArea = function(_, _, _, _, _, _, _, any) calls = calls + 1; return 0, any and 10 or 10 end,
|
||||
}
|
||||
@@ -30,7 +30,9 @@ g_fruitTypeManager = {
|
||||
}
|
||||
g_fillTypeManager = {getConverterDataByName = function() return {} end, getFillTypeNameByIndex = function() return "X" end}
|
||||
g_farmlandManager = {getFarmlandOwner = function() return 1 end}
|
||||
local field = {getId = function() return 7 end, farmland = {id = 70}, polygonPoints = {101, 102, 103, 104}, posX = 50, posZ = 50}
|
||||
-- spillets egen marktilstand (field.fieldState, som fields.xml): afgrøde + vækststadie
|
||||
local field = {getId = function() return 7 end, farmland = {id = 70}, polygonPoints = {101, 102, 103, 104}, posX = 50, posZ = 50,
|
||||
fieldState = {fruitTypeIndex = WHEAT, growthState = 6}}
|
||||
g_fieldManager = {getFields = function() return {field} end}
|
||||
g_currentMission = {terrainRootNode = 1, missionInfo = {}, fieldGroundSystem = {
|
||||
getDensityMapData = function() return 1, 0, 2 end, getMaxValue = function() return 2 end}}
|
||||
|
||||
Reference in New Issue
Block a user