@@ -1573,6 +1573,12 @@ function AIDriveStrategyUnloadCombine:onPathfindingDoneToWaitingCombine(controll
15731573 self :debug (' Pathfinding to waiting combine successful' )
15741574 course :adjustForReversing (math.max (1 , - AIUtil .getDirectionNodeToReverserNodeOffset (self .vehicle )))
15751575 self :startCourse (course , 1 )
1576+ -- Record the combine's position now so driveToCombine() can detect if it has moved
1577+ -- significantly and needs a re-path. Also reset the check timer so the first periodic
1578+ -- check fires 5 s after we start driving, not immediately.
1579+ local cX , _ , cZ = getWorldTranslation (self :getPipeOffsetReferenceNode ())
1580+ self .combinePositionAtApproachStart = { x = cX , z = cZ }
1581+ self .lastCombinePositionCheckTime = g_time
15761582 self :setNewState (self .states .DRIVING_TO_COMBINE )
15771583 return true
15781584 else
@@ -1966,6 +1972,49 @@ function AIDriveStrategyUnloadCombine:driveToCombine()
19661972
19671973 self :getCombineStrategy ():reconfirmRendezvous ()
19681974
1975+ -- If the combine has moved significantly since the current approach course was generated,
1976+ -- re-pathfind to its new position so we don't drive to an empty spot.
1977+ -- Guards keep this infrequent and fast:
1978+ -- • only check every 5 s (cheap distance math)
1979+ -- • skip if remaining course < 20 m (almost there — let proximity handling finish)
1980+ -- • skip if already within 25 m of the combine (driveBesideCombine takes over soon)
1981+ -- • only trigger when the combine has actually moved ≥ 30 m (genuine relocation)
1982+ -- Uses a capped iteration count (defaultMaxIterations) so the A* search completes in
1983+ -- well under a second on any field size, minimising the WAITING_FOR_PATHFINDER stop.
1984+ if g_time - (self .lastCombinePositionCheckTime or 0 ) > 5000 then
1985+ self .lastCombinePositionCheckTime = g_time
1986+ local remainingDist = self .course :getDistanceToLastWaypoint (self .course :getCurrentWaypointIx ())
1987+ local distToCombine = self :getDistanceFromCombine ()
1988+ if remainingDist > 20 and distToCombine > 25 then
1989+ local cX , _ , cZ = getWorldTranslation (self :getPipeOffsetReferenceNode ())
1990+ local lastX = self .combinePositionAtApproachStart and self .combinePositionAtApproachStart .x or cX
1991+ local lastZ = self .combinePositionAtApproachStart and self .combinePositionAtApproachStart .z or cZ
1992+ local moved = MathUtil .vector2Length (cX - lastX , cZ - lastZ )
1993+ if moved >= 30 then
1994+ local xOffset , zOffset = self :getPipeOffset (self .combineToUnload )
1995+ zOffset = - self :getCombinesMeasuredBackDistance () - 3
1996+ self :debug (' driveToCombine: combine moved %.1f m, re-pathfinding to new position' , moved )
1997+ self .combinePositionAtApproachStart = { x = cX , z = cZ }
1998+ -- Fast re-path: cap iterations at the default (avoids multi-second searches on
1999+ -- large fields) and ignore the combine as an obstacle so the path finds the gap
2000+ -- behind it rather than routing around the vehicle body.
2001+ local context = PathfinderContext (self .vehicle )
2002+ context :maxFruitPercent (self :getMaxFruitPercent (self :getPipeOffsetReferenceNode (), xOffset , zOffset ))
2003+ context :offFieldPenalty (self :getOffFieldPenalty (self .combineToUnload ))
2004+ context :useFieldNum (CpFieldUtil .getFieldNumUnderVehicle (self .combineToUnload ))
2005+ context :areaToAvoid (self :getCombineStrategy ():getAreaToAvoid ())
2006+ context :vehiclesToIgnore ({ self .combineToUnload })
2007+ context :maxIterations (HybridAStar .defaultMaxIterations )
2008+ self .pathfinderController :registerListeners (self , self .onPathfindingDoneToWaitingCombine ,
2009+ self .onPathfindingFailedToMovingTarget , self .onPathfindingObstacleAtStart )
2010+ self .pathfinderController :findPathToNode (context , self :getPipeOffsetReferenceNode (),
2011+ xOffset or 0 , zOffset or 0 , 3 )
2012+ self :setNewState (self .states .WAITING_FOR_PATHFINDER )
2013+ return
2014+ end
2015+ end
2016+ end
2017+
19692018 -- towards the end of the course we start checking if we can already switch to unload
19702019 if self .course :getDistanceToLastWaypoint (self .course :getCurrentWaypointIx ()) < 15 and
19712020 self :isOkToStartUnloadingCombine () then
0 commit comments