diff --git a/modDesc.xml b/modDesc.xml
index a24cfce9b..c31156b7e 100644
--- a/modDesc.xml
+++ b/modDesc.xml
@@ -404,6 +404,10 @@ Changelog 8.1.0.3
+
+
+
+
@@ -451,6 +455,7 @@ Changelog 8.1.0.3
+
diff --git a/scripts/gui/pages/CpCourseGeneratorFrame.lua b/scripts/gui/pages/CpCourseGeneratorFrame.lua
index cac6840d1..036be5ddf 100644
--- a/scripts/gui/pages/CpCourseGeneratorFrame.lua
+++ b/scripts/gui/pages/CpCourseGeneratorFrame.lua
@@ -35,14 +35,17 @@ CpCourseGeneratorFrame = {
CONTEXT_ACTIONS = {
ENTER_VEHICLE = 1,
CREATE_JOB = 2,
- START_JOB = 3,
- STOP_JOB = 4,
- GENERATE_COURSE = 5,
- DELETE_CUSTOM_FIELD = 6,
- RENAME_CUSTOM_FIELD = 7,
- EDIT_CUSTOM_FIELD = 8,
- DRAW_CUSTOM_FIELD = 9,
- HOTSPOT_SELECT_ALL = 10
+ --- These three show up in the create job button list in this order, which is also
+ --- the usual work flow: set the positions, generate the course, start the job.
+ SET_POSITIONS_TO_VEHICLE = 3,
+ GENERATE_COURSE = 4,
+ START_JOB = 5,
+ STOP_JOB = 6,
+ DELETE_CUSTOM_FIELD = 7,
+ RENAME_CUSTOM_FIELD = 8,
+ EDIT_CUSTOM_FIELD = 9,
+ DRAW_CUSTOM_FIELD = 10,
+ HOTSPOT_SELECT_ALL = 11
},
AI_MODE_OVERVIEW = 1,
AI_MODE_CREATE = 2,
@@ -945,6 +948,63 @@ function CpCourseGeneratorFrame:getIsPicking()
return self.isPickingRotation or self.isPickingLocation
end
+--- Sets the target position (the position the helper drives to first, with the vehicle's direction)
+--- and the field/silo position of the job currently being created to the vehicle's position, so
+--- these don't have to be picked on the map when standing on the field already.
+function CpCourseGeneratorFrame:setJobPositionsToVehiclePosition()
+ local vehicle = self.currentJobVehicle
+ if self.currentJob == nil or vehicle == nil or vehicle.rootNode == nil or self:getIsPicking() then
+ return
+ end
+ local x, _, z = getWorldTranslation(vehicle.rootNode)
+ local dirX, _, dirZ = localDirectionToWorld(vehicle.rootNode, 0, 0, 1)
+ local angle = MathUtil.getYRotationFromDirection(dirX, dirZ)
+ local changed = false
+ for _, element in ipairs(self.currentJobElements) do
+ local parameter = element.aiParameter
+ if parameter and parameter.is_a and parameter:is_a(CpAIParameterPosition) and parameter:getCanBeChanged() then
+ local positionType = parameter:getPositionType()
+ if positionType == CpAIParameterPositionAngle.POSITION_TYPES.DRIVE_TO then
+ parameter:setPosition(x, z)
+ if parameter.setAngle then
+ --- the target of the drive to task also has a direction, use the one the vehicle is facing
+ parameter:setAngle(angle)
+ end
+ changed = true
+ elseif positionType == CpAIParameterPositionAngle.POSITION_TYPES.FIELD_OR_SILO then
+ parameter:setPosition(x, z)
+ changed = true
+ end
+ end
+ end
+ if changed then
+ --- this also restarts the field boundary detection for the new field position
+ self:validateParameters()
+ self:updateParameterValueTexts()
+ end
+end
+
+--- Adds a button to the job parameter list, which sets the target and the field position
+--- to the vehicle's current position. It gets a group of its own so it is separated from
+--- the position rows above and isn't clicked by accident.
+function CpCourseGeneratorFrame:addSetPositionsToVehicleButton()
+ local titleElement = self.createTitleTemplate:clone(self.jobMenuLayout)
+ titleElement:setText(g_i18n:getText("CP_ai_page_positions_to_vehicle_title"))
+ --- Using the position parameter template, so the button looks and behaves exactly
+ --- like the position rows above it.
+ local element = self.createPositionTemplate:clone(self.jobMenuLayout)
+ FocusManager:loadElementFromCustomValues(element)
+ element:setText(g_i18n:getText("CP_ai_page_positions_to_vehicle"))
+ local invalidElement = element:getDescendantByName("invalid")
+ if invalidElement then
+ invalidElement:setVisible(false)
+ end
+ element.onClickCallback = function()
+ self:setJobPositionsToVehiclePosition()
+ end
+ return element
+end
+
function CpCourseGeneratorFrame:validateParameters()
local isValid = true
local errorText = ""
@@ -1153,7 +1213,7 @@ function CpCourseGeneratorFrame:getNumberOfItemsInSection(list, section)
end
if list == self.contextButtonList then
self.contextActionMapping = {}
- for index, action in pairs(self.contextActions) do
+ for index, action in ipairs(self.contextActions) do
if action.isActive and not action.actionOnly then
table.insert(self.contextActionMapping, index)
end
@@ -1165,7 +1225,7 @@ function CpCourseGeneratorFrame:getNumberOfItemsInSection(list, section)
end
if list == self.contextButtonCustomFieldList then
self.contextActionMapping = {}
- for index, action in pairs(self.contextActions) do
+ for index, action in ipairs(self.contextActions) do
if action.isActive and not action.actionOnly then
table.insert(self.contextActionMapping, index)
end
@@ -1455,6 +1515,12 @@ function CpCourseGeneratorFrame:initializeContextActions()
callback = self.onCreateJob,
isActive = false
},
+ [self.CONTEXT_ACTIONS.SET_POSITIONS_TO_VEHICLE] = {
+ text = g_i18n:getText("CP_ai_page_positions_to_vehicle"),
+ action = InputAction.CP_SET_POSITIONS_TO_VEHICLE,
+ callback = self.setJobPositionsToVehiclePosition,
+ isActive = false
+ },
[self.CONTEXT_ACTIONS.START_JOB] = {
text = g_i18n:getText("button_startJob"),
action = InputAction.MENU_EXTRA_1,
@@ -1547,6 +1613,9 @@ function CpCourseGeneratorFrame:updateContextActions()
end
end
self.contextActions[self.CONTEXT_ACTIONS.CREATE_JOB].isActive = self.canCreateJob and self.mode ~= self.AI_MODE_CREATE
+ self.contextActions[self.CONTEXT_ACTIONS.SET_POSITIONS_TO_VEHICLE].isActive =
+ self.mode == self.AI_MODE_CREATE and self.currentJob ~= nil and
+ self.currentJobVehicle ~= nil and not self:getIsPicking()
self.contextActions[self.CONTEXT_ACTIONS.START_JOB].isActive = self:getCanStartJob()
self.contextActions[self.CONTEXT_ACTIONS.STOP_JOB].isActive = self:getCanCancelJob() and self.mode ~= self.AI_MODE_CREATE
self.contextActions[self.CONTEXT_ACTIONS.GENERATE_COURSE].isActive = self:getCanGenerateFieldWorkCourse()
@@ -1765,11 +1834,27 @@ function CpCourseGeneratorFrame:setActiveJobTypeSelection(jobTypeIndex)
end
self.currentJob:applyCurrentState(self.currentJobVehicle, g_currentMission, farmId, false)
self.currentJobElements = {}
+ --- The button setting the positions to the vehicle position goes right below the field/silo
+ --- position, or below the target position for jobs without a field position (silo loader).
+ local buttonAnchorPositionType = nil
+ for _, group in ipairs(self.currentJob:getGroupedParameters()) do
+ for _, item in ipairs(group:getParameters()) do
+ local positionType = item.getPositionType and item:getPositionType()
+ if positionType == CpAIParameterPositionAngle.POSITION_TYPES.FIELD_OR_SILO then
+ buttonAnchorPositionType = positionType
+ elseif positionType == CpAIParameterPositionAngle.POSITION_TYPES.DRIVE_TO and
+ buttonAnchorPositionType == nil then
+ buttonAnchorPositionType = positionType
+ end
+ end
+ end
+ local isButtonAdded = false
for _, group in ipairs(self.currentJob:getGroupedParameters()) do
local titleElement = self.createTitleTemplate:clone(self.jobMenuLayout)
titleElement:setText(group:getTitle())
+ local isButtonAnchorGroup = false
for _, item in ipairs(group:getParameters()) do
local element = nil
local parameterType = item:getType()
@@ -1797,8 +1882,16 @@ function CpCourseGeneratorFrame:setActiveJobTypeSelection(jobTypeIndex)
end
element:setDisabled(not item:getCanBeChanged())
table.insert(self.currentJobElements, element)
+ if buttonAnchorPositionType ~= nil and item.getPositionType and
+ item:getPositionType() == buttonAnchorPositionType then
+ isButtonAnchorGroup = true
+ end
end
end
+ if isButtonAnchorGroup and not isButtonAdded then
+ self:addSetPositionsToVehicleButton()
+ isButtonAdded = true
+ end
end
self:validateParameters()
self:updateParameterValueTexts()
diff --git a/translations/translation_de.xml b/translations/translation_de.xml
index 6d6a9364e..e13796b80 100644
--- a/translations/translation_de.xml
+++ b/translations/translation_de.xml
@@ -108,6 +108,8 @@
+
+
@@ -1076,6 +1078,7 @@ Das Kreuz sollte jetzt, wie im Bild dargestellt, gelb sein.
+
diff --git a/translations/translation_en.xml b/translations/translation_en.xml
index 29744c145..f4096d35e 100644
--- a/translations/translation_en.xml
+++ b/translations/translation_en.xml
@@ -108,6 +108,8 @@
+
+
@@ -1092,6 +1094,7 @@ Now your selection should look similar to the image.
+