feat(marker): smalle standardmaskiner — vender/river i egen bredde, læssevogn følger rivens kursus; Riv også til ensilage (v1.23.0.0)
Brugerspørgsmål 25/9: få standardredskaber har 40,8 m. Vender og river kører hele marken i deres egen bredde; efter riv ligger skåret midt i banen, så læssevognen kopierer rivens kursus uden breddekrav. Uden riv kræver læssevognen stadig slåbredden (nu med hint 'sæt Riv til').
This commit is contained in:
@@ -14,8 +14,8 @@ ADFieldJobs.PLAYER_DRIVING_KMH = 3
|
||||
-- Courseplay kan efterlade hjørner på skæve marker: efter så mange færdige slå-ture går marken videre.
|
||||
ADFieldJobs.MAX_MOW_PASSES = 2
|
||||
ADFieldJobs.state = {fields = {}, fleet = {}, assignments = {}}
|
||||
-- mark-id -> kopi af slåmaskinens Courseplay-kursus (kun i hukommelsen; efter genindlæsning hentes det
|
||||
-- igen fra slåmaskinen, som CP selv gemmer kurset på)
|
||||
-- mark-id -> {mower = kursus, rake = kursus}: kopier af slåmaskinens/rivens Courseplay-kursus (kun i
|
||||
-- hukommelsen; efter genindlæsning hentes de fra maskinen, som CP selv gemmer kurset på)
|
||||
ADFieldJobs.courses = {}
|
||||
ADFieldJobs.timer = 0
|
||||
ADFieldJobs.now = 0
|
||||
@@ -246,7 +246,7 @@ end
|
||||
|
||||
local function dispatch(adEnv, field, info, role)
|
||||
local candidates = ADFieldJobs.getRigs(adEnv)
|
||||
local rig, reason, args = ADFieldFleet.pick(candidates, role, info.x, info.z, field.mowWidth)
|
||||
local rig, reason, args = ADFieldFleet.pick(candidates, role, info.x, info.z, ADFieldModel.requiredWidth(field, role))
|
||||
if rig == nil then
|
||||
note(field.id, {reason = {key = "spu_field_reason_" .. reason, role = role, args = args}})
|
||||
return
|
||||
@@ -258,18 +258,32 @@ local function dispatch(adEnv, field, info, role)
|
||||
note(field.id, {reason = false})
|
||||
end
|
||||
|
||||
-- Slåkurset for marken: gemt kopi, ellers slåmaskinens nuværende kursus (efter genindlæsning).
|
||||
local function mowCourse(adEnv, field)
|
||||
if ADFieldJobs.courses[field.id] ~= nil then return ADFieldJobs.courses[field.id] end
|
||||
if field.mowVehicleId == nil then return nil end
|
||||
-- Kurset som et trin skal genbruge ("mower"/"rake"): gemt kopi, ellers maskinens nuværende kursus
|
||||
-- (efter genindlæsning).
|
||||
local function sourceCourse(adEnv, field, source)
|
||||
local saved = ADFieldJobs.courses[field.id]
|
||||
if saved ~= nil and saved[source] ~= nil then return saved[source] end
|
||||
local vehicleId = source == "rake" and field.rakeVehicleId or field.mowVehicleId
|
||||
if vehicleId == nil then return nil end
|
||||
for _, vehicle in ipairs(ADRunsController.getFarmVehicles(adEnv)) do
|
||||
if ADRunsController.getVehicleId(vehicle) == field.mowVehicleId then
|
||||
if ADRunsController.getVehicleId(vehicle) == vehicleId then
|
||||
return ADCpBridge.getCourse(vehicle)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function rememberCourse(field, source, vehicle, vehicleId)
|
||||
local course = ADCpBridge.getCourse(vehicle)
|
||||
local ok, copy = false, nil
|
||||
if course ~= nil and course.copy ~= nil then ok, copy = pcall(course.copy, course) end
|
||||
ADFieldJobs.courses[field.id] = ADFieldJobs.courses[field.id] or {}
|
||||
ADFieldJobs.courses[field.id][source] = ok and copy or course
|
||||
if source == "rake" then
|
||||
note(field.id, {rakeVehicleId = vehicleId})
|
||||
end
|
||||
end
|
||||
|
||||
local function beginWork(adEnv, field, info, assignment)
|
||||
local vehicle = assignment.vehicle
|
||||
if assignment.role == "collector" then
|
||||
@@ -298,9 +312,10 @@ local function beginWork(adEnv, field, info, assignment)
|
||||
local point = info.points[1] or {x = info.x, z = info.z}
|
||||
assignment.phase = "starting"
|
||||
assignment.since = ADFieldJobs.now
|
||||
local course = assignment.role ~= "mower" and mowCourse(adEnv, field) or nil
|
||||
if assignment.role ~= "mower" and course == nil then
|
||||
log(field.id, "intet slåkursus kendt — Courseplay laver et nyt kursus til %s", assignment.role)
|
||||
local source = ADFieldModel.courseSource(field, assignment.role)
|
||||
local course = source ~= nil and sourceCourse(adEnv, field, source) or nil
|
||||
if source ~= nil and course == nil then
|
||||
log(field.id, "intet %s-kursus kendt — Courseplay laver et nyt kursus til %s", source, assignment.role)
|
||||
end
|
||||
local handle, err = ADCpBridge.start(vehicle, point.x, point.z, function(ok, reason)
|
||||
if ok then
|
||||
@@ -308,11 +323,11 @@ local function beginWork(adEnv, field, info, assignment)
|
||||
assignment.since = ADFieldJobs.now
|
||||
if assignment.role == "mower" then
|
||||
note(field.id, {mowWidth = assignment.width, mowVehicleId = assignment.vehicleId})
|
||||
local mowed = ADCpBridge.getCourse(vehicle)
|
||||
local copied = mowed ~= nil and mowed.copy ~= nil and select(2, pcall(mowed.copy, mowed)) or mowed
|
||||
ADFieldJobs.courses[field.id] = type(copied) == "table" and copied or mowed
|
||||
rememberCourse(field, "mower", vehicle, assignment.vehicleId)
|
||||
elseif assignment.role == "rake" then
|
||||
rememberCourse(field, "rake", vehicle, assignment.vehicleId)
|
||||
end
|
||||
log(field.id, "Courseplay startet (%s%s)", assignment.role, reason == "copied" and ", slåkursus kopieret" or "")
|
||||
log(field.id, "Courseplay startet (%s%s)", assignment.role, reason == "copied" and (", " .. tostring(source) .. "-kursus kopieret") or "")
|
||||
else
|
||||
release(assignment)
|
||||
note(field.id, {retryAt = ADFieldJobs.now + ADFieldModel.RETRY_MS, reason = {text = tostring(reason)}})
|
||||
|
||||
@@ -38,14 +38,30 @@ function ADFieldModel.newField(id)
|
||||
}
|
||||
end
|
||||
|
||||
-- Hø vendes; Riv kan vælges til både hø og ensilage (samler skårene midt i rivens baner, så også
|
||||
-- smalle standard-læssevogne kan tage dem).
|
||||
function ADFieldModel.workStages(plan)
|
||||
if plan.product == "hay" then
|
||||
if plan.rake then
|
||||
return {"mowing", "tedding", "raking", "collecting"}
|
||||
end
|
||||
return {"mowing", "tedding", "collecting"}
|
||||
local stages = {"mowing"}
|
||||
if plan.product == "hay" then table.insert(stages, "tedding") end
|
||||
if plan.rake then table.insert(stages, "raking") end
|
||||
table.insert(stages, "collecting")
|
||||
return stages
|
||||
end
|
||||
|
||||
-- Krævet bredde for et sæt: kun læssevognen uden riv skal dække slåmaskinens baner. Vender og river kører
|
||||
-- hele marken i deres egen bredde; efter riv ligger skåret midt i banen, så vognens bredde er ligegyldig.
|
||||
function ADFieldModel.requiredWidth(field, role)
|
||||
if role == "collector" and not field.plan.rake then
|
||||
return field.mowWidth
|
||||
end
|
||||
return {"mowing", "collecting"}
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Hvilket tidligere kursus sættet skal køre: læssevognen følger skårene (rivens kursus, ellers
|
||||
-- slåmaskinens); de andre laver deres eget i deres egen bredde.
|
||||
function ADFieldModel.courseSource(field, role)
|
||||
if role ~= "collector" then return nil end
|
||||
return field.plan.rake and "rake" or "mower"
|
||||
end
|
||||
|
||||
function ADFieldModel.roleFor(stage)
|
||||
@@ -93,6 +109,7 @@ function ADFieldModel.start(field)
|
||||
copy.reason = nil
|
||||
copy.mowWidth = nil
|
||||
copy.mowVehicleId = nil
|
||||
copy.rakeVehicleId = nil
|
||||
return copy
|
||||
end
|
||||
|
||||
@@ -158,6 +175,7 @@ function ADFieldModel.toRecord(field)
|
||||
rake = field.plan.rake and 1 or 0, store = table.concat(field.plan.storeBuildingIds, " "),
|
||||
mowWidth = field.mowWidth or 0,
|
||||
mowVehicle = field.mowVehicleId or "",
|
||||
rakeVehicle = field.rakeVehicleId or "",
|
||||
}
|
||||
end
|
||||
|
||||
@@ -170,5 +188,6 @@ function ADFieldModel.fromRecord(record)
|
||||
for id in string.gmatch(record.store or "", "%S+") do table.insert(field.plan.storeBuildingIds, id) end
|
||||
field.mowWidth = (record.mowWidth or 0) > 0 and record.mowWidth or nil
|
||||
field.mowVehicleId = record.mowVehicle ~= nil and record.mowVehicle ~= "" and record.mowVehicle or nil
|
||||
field.rakeVehicleId = record.rakeVehicle ~= nil and record.rakeVehicle ~= "" and record.rakeVehicle or nil
|
||||
return field
|
||||
end
|
||||
|
||||
@@ -29,6 +29,7 @@ function ADFieldStorage.save(state)
|
||||
xmlFile:setString(key .. "#store", record.store)
|
||||
xmlFile:setFloat(key .. "#mowWidth", record.mowWidth)
|
||||
xmlFile:setString(key .. "#mowVehicle", record.mowVehicle)
|
||||
xmlFile:setString(key .. "#rakeVehicle", record.rakeVehicle)
|
||||
index = index + 1
|
||||
end
|
||||
local vehicleIndex = 0
|
||||
@@ -53,6 +54,7 @@ function ADFieldStorage.load()
|
||||
mode = xmlFile:getString(key .. "#mode"), product = xmlFile:getString(key .. "#product"),
|
||||
rake = xmlFile:getInt(key .. "#rake"), store = xmlFile:getString(key .. "#store"),
|
||||
mowWidth = xmlFile:getFloat(key .. "#mowWidth"), mowVehicle = xmlFile:getString(key .. "#mowVehicle"),
|
||||
rakeVehicle = xmlFile:getString(key .. "#rakeVehicle"),
|
||||
})
|
||||
if field.id ~= nil then result.fields[field.id] = field end
|
||||
end)
|
||||
|
||||
@@ -36,7 +36,7 @@ end
|
||||
|
||||
function SmartPickupFrame:fieldPlanText(field)
|
||||
local text = self.i18n:getText(field.plan.product == "hay" and "spu_field_plan_hay" or "spu_field_plan_silage")
|
||||
if field.plan.product == "hay" and field.plan.rake then
|
||||
if field.plan.rake then
|
||||
text = text .. " + " .. self.i18n:getText("spu_field_plan_rake")
|
||||
end
|
||||
return text
|
||||
@@ -102,9 +102,7 @@ function SmartPickupFrame:fillFieldDetail(adEnv, info)
|
||||
local isHay = field.plan.product == "hay"
|
||||
self:addToggleRow("fieldProduct", i18n:getText("spu_field_plan"), {i18n:getText("spu_field_plan_silage"), i18n:getText("spu_field_plan_hay")}, isHay)
|
||||
self:addToggleRow("fieldMode", i18n:getText("spu_field_mode"), {i18n:getText("spu_field_mode_manual"), i18n:getText("spu_field_mode_auto")}, field.plan.mode == "auto")
|
||||
if isHay then
|
||||
self:addToggleRow("fieldRake", i18n:getText("spu_field_rake"), {i18n:getText("ui_no"), i18n:getText("ui_yes")}, field.plan.rake == true)
|
||||
end
|
||||
self:addToggleRow("fieldRake", i18n:getText("spu_field_rake"), {i18n:getText("ui_no"), i18n:getText("ui_yes")}, field.plan.rake == true)
|
||||
if info.markerId ~= nil then
|
||||
self:addTextRow(string.format(i18n:getText("spu_field_marker"), tostring(info.markerName), info.markerDistance or 0))
|
||||
else
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<text name="spu_field_reason_noRig" text="ingen %s med flueben i markflåden"/>
|
||||
<text name="spu_field_reason_allBusy" text="venter på ledig %s"/>
|
||||
<text name="spu_field_reason_tooWide" text="%s for bred: %.1f m > %.0f m (Courseplay)"/>
|
||||
<text name="spu_field_reason_tooNarrow" text="%s for smal: %.1f m < slåbredde %.1f m"/>
|
||||
<text name="spu_field_reason_tooNarrow" text="%s for smal: %.1f m < slåbredde %.1f m — sæt Riv til eller brug en bredere"/>
|
||||
<text name="spu_field_role_mower" text="slåmaskine"/>
|
||||
<text name="spu_field_role_tedder" text="vender"/>
|
||||
<text name="spu_field_role_rake" text="river"/>
|
||||
@@ -74,7 +74,7 @@
|
||||
<text name="spu_field_section" text="— Mark F%d: %s —"/>
|
||||
<text name="spu_field_plan" text="Plan"/>
|
||||
<text name="spu_field_mode" text="Kørsel"/>
|
||||
<text name="spu_field_rake" text="Riv høet sammen før opsamling"/>
|
||||
<text name="spu_field_rake" text="Riv skårene sammen før opsamling (gør smalle læssevogne brugbare)"/>
|
||||
<text name="spu_field_marker" text=" Markør %s, %.0f m fra marken"/>
|
||||
<text name="spu_field_mowWidth" text=" Slået med %.1f m — opsamling skal være mindst lige så bred"/>
|
||||
<text name="spu_field_section_store" text="— Tving lager (ellers nærmeste silo med plads) —"/>
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<text name="spu_field_reason_noRig" text="no %s ticked in the field fleet"/>
|
||||
<text name="spu_field_reason_allBusy" text="waiting for a free %s"/>
|
||||
<text name="spu_field_reason_tooWide" text="%s too wide: %.1f m > %.0f m (Courseplay)"/>
|
||||
<text name="spu_field_reason_tooNarrow" text="%s too narrow: %.1f m < mowing width %.1f m"/>
|
||||
<text name="spu_field_reason_tooNarrow" text="%s too narrow: %.1f m < mowing width %.1f m — turn on Rake or use a wider one"/>
|
||||
<text name="spu_field_role_mower" text="mower"/>
|
||||
<text name="spu_field_role_tedder" text="tedder"/>
|
||||
<text name="spu_field_role_rake" text="rake"/>
|
||||
@@ -74,7 +74,7 @@
|
||||
<text name="spu_field_section" text="— Field F%d: %s —"/>
|
||||
<text name="spu_field_plan" text="Plan"/>
|
||||
<text name="spu_field_mode" text="Mode"/>
|
||||
<text name="spu_field_rake" text="Rake the hay before collecting"/>
|
||||
<text name="spu_field_rake" text="Rake the swaths before collecting (lets narrow loading wagons collect)"/>
|
||||
<text name="spu_field_marker" text=" Marker %s, %.0f m from the field"/>
|
||||
<text name="spu_field_mowWidth" text=" Mowed at %.1f m — collecting must be at least as wide"/>
|
||||
<text name="spu_field_section_store" text="— Force storage (else nearest silo with room) —"/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<modDesc descVersion="107">
|
||||
<author>masterdraco</author>
|
||||
<version>1.22.0.0</version>
|
||||
<version>1.23.0.0</version>
|
||||
<title>
|
||||
<en>AD Smart Pickup</en>
|
||||
</title>
|
||||
|
||||
Reference in New Issue
Block a user