@@ -928,7 +928,7 @@ function AIDriveStrategyUnloadCombine:handleChopperTurn(harvester)
928928
929929 -- since we are taking care of staying away, ask the chopper to ignore us
930930 local harvesterStrategy = self :getCombineStrategy ()
931- if harvesterStrategy then harvesterStrategy :requestToIgnoreProximity (self .vehicle ) end
931+ harvesterStrategy :requestToIgnoreProximity (self .vehicle )
932932
933933 local d , dx , dz = self :getDistanceFromCombine (harvester )
934934 local combineSpeed = harvester .lastSpeedReal * 3600
@@ -946,12 +946,12 @@ function AIDriveStrategyUnloadCombine:handleChopperTurn(harvester)
946946 -- stay closer when still discharging
947947 if sameDirection then
948948 -- reverse speed is controlled around combine's speed
949- dReference = ( harvesterStrategy and harvesterStrategy :isDischarging () ) and dz or dz - 3
949+ dReference = harvesterStrategy :isDischarging () and dz or dz - 3
950950 speed = combineSpeed + CpMathUtil .clamp (self .targetDistanceBehindChopper - dReference , - combineSpeed ,
951951 self .settings .reverseSpeed :getValue () * 1.5 )
952952 else
953953 -- reverse speed only depends on distance from the combine, stop when at working width
954- speed = CpMathUtil .clamp (( harvesterStrategy and harvesterStrategy :getWorkWidth () or 6 ) - d , 0 ,
954+ speed = CpMathUtil .clamp (harvesterStrategy :getWorkWidth () - d , 0 ,
955955 self .settings .reverseSpeed :getValue () * 1.5 )
956956 end
957957 else
@@ -2166,27 +2166,6 @@ function AIDriveStrategyUnloadCombine:unloadMovingCombine()
21662166 self .followingCourseOffset = self :getFollowingCourseOffset (self .combineToUnload )
21672167 self .followCourse :setOffset (self .followingCourseOffset , 0 )
21682168
2169- -- NOTE: For manually-driven combines we do NOT refresh the follow course.
2170- -- driveBesideCombine() computes the steering goal point directly from the pipe reference
2171- -- node every frame (see the isManual branch there), so the course is never consulted for
2172- -- steering. This prevents any possibility of angle lock, stale courses, or backward
2173- -- courses produced by synthesising a follow course from the combine's live position.
2174- --
2175- -- Because the placeholder follow course is deliberately static while steering happens
2176- -- off a live pipe reference, the cart WILL drift far away from the placeholder course as
2177- -- the combine curves or S-turns. The PPC's off-track shutdown would see that drift and
2178- -- kill the CP helper. Keep the check continuously disabled while a manual combine is the
2179- -- unload target. We use 5000 ms (much longer than any realistic frame interval) so there
2180- -- is no risk of a brief re-enable window between ticks.
2181- do
2182- local combineStrategy = self :getCombineStrategy ()
2183- if combineStrategy and combineStrategy .isManualProxy and combineStrategy :isManualProxy () then
2184- if self .ppc and self .ppc .disableStopWhenOffTrack then
2185- self .ppc :disableStopWhenOffTrack (5000 )
2186- end
2187- end
2188- end
2189-
21902169 if self :changeToUnloadWhenTrailerFull () then
21912170 return
21922171 end
@@ -2198,22 +2177,18 @@ function AIDriveStrategyUnloadCombine:unloadMovingCombine()
21982177 -- The farmer is in full control: ignore fill level, alignment, turning state, etc.
21992178 -- Stay under the pipe until the proxy's isUnloadFinished() fires (pipe closed for 2s)
22002179 -- or the grain cart's own trailer fills up (handled by changeToUnloadWhenTrailerFull above).
2201- if combineStrategy .isManualProxy and combineStrategy :isManualProxy () then
2180+ -- The cart will drift from the static placeholder course as the combine curves — disable the
2181+ -- PPC off-track check for the duration (5000 ms >> any realistic frame interval).
2182+ if combineStrategy .isManualProxy then
2183+ self .ppc :disableStopWhenOffTrack (5000 )
22022184 self :debugSparse (' unloadMovingCombine (manual): isDischarging=%s' ,
2203- tostring (combineStrategy . isDischarging and combineStrategy :isDischarging ()))
2185+ tostring (combineStrategy :isDischarging ()))
22042186 return gx , gz
22052187 end
22062188
22072189 -- when the combine is empty, stop and wait for next combine (unless this can't work without an unloader nearby)
2208- local fillPct = combineStrategy :getFillLevelPercentage ()
2209- local isDischarging = combineStrategy .isDischarging and combineStrategy :isDischarging ()
2210- local isUnloadFinished = combineStrategy .isUnloadFinished and combineStrategy :isUnloadFinished ()
2211- self :debugSparse (' unloadMovingCombine: fillPct=%.2f isDischarging=%s isUnloadFinished=%s' ,
2212- fillPct , tostring (isDischarging ), tostring (isUnloadFinished ))
2213- -- Don't exit on fill level while the combine is still actively discharging — the pipe hasn't
2214- -- closed yet and we'd leave with grain still flowing. Wait for discharge to stop first.
2215- if fillPct <= 0.1 and not isDischarging and not combineStrategy :alwaysNeedsUnloader () then
2216- self :debug (' unloadMovingCombine: EXIT - combine empty (fillPct=%.2f) and not discharging, finishing unloading.' , fillPct )
2190+ if combineStrategy :getFillLevelPercentage () <= 0.1 and not combineStrategy :alwaysNeedsUnloader () then
2191+ self :debug (' Combine empty, finish unloading.' )
22172192 self :onUnloadingMovingCombineFinished (combineStrategy )
22182193 return
22192194 end
@@ -2376,13 +2351,14 @@ function AIDriveStrategyUnloadCombine:onBlockingVehicle(blockingVehicle, isBack)
23762351 -- TODO: maybe a generic getTrailer() ?
23772352 local referenceObject = AIUtil .getImplementOrVehicleWithSpecialization (self .vehicle , Trailer ) or
23782353 AIUtil .getImplementOrVehicleWithSpecialization (self .vehicle , HookLiftTrailer ) or self .vehicle
2379- if AIDriveStrategyCombineCourse .isActiveCpCombine (blockingVehicle ) then
2354+ local isManualBlocker = blockingVehicle .cpIsManualCombineCallingUnloader and blockingVehicle :cpIsManualCombineCallingUnloader ()
2355+ if AIDriveStrategyCombineCourse .isActiveCpCombine (blockingVehicle ) or isManualBlocker then
23802356 -- except we are blocking our buddy, so set up a course parallel to the combine's direction,
23812357 -- with an offset from the combine that makes sure we are clear. Use the trailer's root node (and not
23822358 -- the tractor's) as when we reversing, it is easier when the trailer remains on the same side of the combine
23832359 local dx , _ , _ = localToLocal (referenceObject .rootNode , blockingVehicle :getAIDirectionNode (), 0 , 0 , 0 )
23842360 local blockingStrategy = blockingVehicle :getCpDriveStrategy () or (blockingVehicle .cpGetManualCombineProxy and blockingVehicle :cpGetManualCombineProxy ())
2385- local blockingWorkWidth = blockingStrategy and blockingStrategy :getWorkWidth () or 6
2361+ local blockingWorkWidth = blockingStrategy :getWorkWidth ()
23862362 local xOffset = self .vehicle .size .width / 2 + blockingWorkWidth / 2 + 2
23872363 xOffset = dx > 0 and xOffset or - xOffset
23882364 self :setNewState (self .states .MOVING_AWAY_FROM_OTHER_VEHICLE )
0 commit comments