From d936a183cfce96d250dfe42af48753bc509b7d36 Mon Sep 17 00:00:00 2001 From: Helge Neumann Date: Thu, 2 Jul 2026 18:16:25 +0200 Subject: [PATCH] Allow disabling the seeder unit of cultivators with seeder configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Horsch Finer 6 SL, Väderstad TopDown 600 and Dalbo Powerchain 800 gained a seeder unit configuration (vehicle type cultivatingSowingMachine) with game patch 1.8. Their sowing machine spec needs activation, so getAIRequiresTurnOn() returns true and Courseplay hid the optional sowing setting for them. The seeder unit was always turned on by the base game AI and could not be disabled, even when the user only wanted to cultivate (#989). Three changes: 1. The optional sowing setting is now also visible for implements that have both the SowingMachine and the Cultivator specialization. 2. While a CP job is running and sowing is disabled by the user, TurnOnVehicle.getAIRequiresTurnOn() returns false for these implements. Without this, TurnOnVehicle:getCanAIImplementContinueWork() fails for machines that require turning on but are turned off, so the driver would lower the implement and then stand still forever. The override intentionally checks the specializations directly instead of the setting's getIsDisabled(), as that would recurse back into getAIRequiresTurnOn() via isOptionalSowingMachineSettingVisible(). 3. needsRefilling() no longer asks for seeds when sowing is disabled or when the seed fill unit has capacity 0. Machines like the Finer 6 SL seeder unit have no real seed tank (capacity 0 means they can always consume, see SowingMachine:getSowingMachineCanConsume) and could never be refilled, so CP kept waiting for a refill that can't happen. Fixes #989 --- .../controllers/SowingMachineController.lua | 45 ++++++++++++++++--- scripts/specializations/CpVehicleSettings.lua | 15 +++++-- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/scripts/ai/controllers/SowingMachineController.lua b/scripts/ai/controllers/SowingMachineController.lua index 1286ac3d1..21153fd70 100644 --- a/scripts/ai/controllers/SowingMachineController.lua +++ b/scripts/ai/controllers/SowingMachineController.lua @@ -10,19 +10,19 @@ end function SowingMachineController:update() if not self.settings.optionalSowingMachineEnabled:getIsDisabled() then - if self.settings.optionalSowingMachineEnabled:getValue() then + if self.settings.optionalSowingMachineEnabled:getValue() then --- Makes sure the sowing machine get's turned on if not self.implement:getIsTurnedOn() then self.implement:setIsTurnedOn(true) end - else + else --- Makes sure the sowing machine is turned off if not needed. if self.implement:getIsTurnedOn() then self.implement:setIsTurnedOn(false) end end end - if self.sowingMachineSpec.showWrongFruitForMissionWarning then + if self.sowingMachineSpec.showWrongFruitForMissionWarning then self:debug("Wrong fruit type for mission selected!") self.vehicle:stopCurrentAIJob(AIMessageErrorWrongMissionFruitType.new()) end @@ -41,15 +41,50 @@ function SowingMachineController:onFinished() self.implement:setIsTurnedOn(false) end +--- While Courseplay is driving and sowing was disabled by the user, the machine stays turned off. +--- Without this override, TurnOnVehicle:getCanAIImplementContinueWork() fails for machines that +--- require turning on but are turned off, so the driver would lower the implement and then just +--- stand still, waiting forever (#989). +local function getAIRequiresTurnOn(implement, superFunc, ...) + --- Only for cultivators with a seeder unit configuration, like the Horsch Finer 6 SL. + --- The structural check must not go through the setting's getIsDisabled() here, as that + --- calls isOptionalSowingMachineSettingVisible(), which in turn calls getAIRequiresTurnOn(), + --- resulting in an infinite recursion. + if implement.spec_sowingMachine ~= nil and + SpecializationUtil.hasSpecialization(Cultivator, implement.specializations) then + local rootVehicle = implement.rootVehicle + if rootVehicle ~= nil and rootVehicle.getIsCpActive and rootVehicle:getIsCpActive() then + local setting = rootVehicle:getCpSettings().optionalSowingMachineEnabled + if not setting:getValue() then + return false + end + end + end + return superFunc(implement, ...) +end +TurnOnVehicle.getAIRequiresTurnOn = Utils.overwrittenFunction( + TurnOnVehicle.getAIRequiresTurnOn, getAIRequiresTurnOn) + ------------------------- --- Refill handling ------------------------- function SowingMachineController:needsRefilling() + if not self.settings.optionalSowingMachineEnabled:getIsDisabled() and + not self.settings.optionalSowingMachineEnabled:getValue() then + --- Sowing was disabled by the user, so no seeds are needed (#989). + return false + end + if self.implement:getFillUnitCapacity(self.sowingMachineSpec.fillUnitIndex) == 0 then + --- Sowing machines without a real seed tank (capacity 0), like the seeder unit + --- of the Horsch Finer 6 SL, don't consume seeds (see getSowingMachineCanConsume) + --- and therefore never need refilling (#989). + return false + end if not g_currentMission.missionInfo.helperBuySeeds then - if self.implement:getFillUnitFillLevel(self.sowingMachineSpec.fillUnitIndex) <= 0 then + if self.implement:getFillUnitFillLevel(self.sowingMachineSpec.fillUnitIndex) <= 0 then return ImplementController.needsRefilling(self) end end return false -end \ No newline at end of file +end diff --git a/scripts/specializations/CpVehicleSettings.lua b/scripts/specializations/CpVehicleSettings.lua index d9f89d754..d4eed5d44 100644 --- a/scripts/specializations/CpVehicleSettings.lua +++ b/scripts/specializations/CpVehicleSettings.lua @@ -358,12 +358,21 @@ end function CpVehicleSettings:isOptionalSowingMachineSettingVisible() local vehicles, found = AIUtil.getAllChildVehiclesWithSpecialization(self, SowingMachine) - return found and not vehicles[1]:getAIRequiresTurnOn() + if not found then + return false + end + if not vehicles[1]:getAIRequiresTurnOn() then + --- Passive sowing machines, for example a roller with a seeder configuration. + return true + end + --- Cultivators with a seeder unit configuration, like the Horsch Finer 6 SL, + --- are primarily cultivators, so sowing is optional for them as well, even + --- though their seeder unit needs to be turned on (#989). + return SpecializationUtil.hasSpecialization(Cultivator, vehicles[1].specializations) end function CpVehicleSettings:isOptionalSowingMachineSettingDisabled() - local vehicles, found = AIUtil.getAllChildVehiclesWithSpecialization(self, SowingMachine) - return not found or vehicles[1]:getAIRequiresTurnOn() + return not CpVehicleSettings.isOptionalSowingMachineSettingVisible(self) end