From 8814291f1c46196963379a670ff2bfc4dc6fd0d5 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Mon, 15 Jun 2026 22:43:34 +0200 Subject: [PATCH 1/3] bugfix(pathfinder): Accurate unit movement destinations when unobstructed --- .../Source/GameLogic/AI/AIPathfind.cpp | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp b/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp index b8b68fb6861..a7ee7e107eb 100644 --- a/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp +++ b/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp @@ -5529,12 +5529,12 @@ Bool Pathfinder::adjustDestination(Object *obj, const LocomotorSet& locomotorSet Bool center; getRadiusAndCenter(obj, iRadius, center); ICoord2D cell; - Coord3D adjustDest = *dest; + Coord3D cellDest = *dest; if (!center) { - adjustDest.x += PATHFIND_CELL_SIZE_F/2; - adjustDest.y += PATHFIND_CELL_SIZE_F/2; + cellDest.x += PATHFIND_CELL_SIZE_F/2; + cellDest.y += PATHFIND_CELL_SIZE_F/2; } - worldToCell( &adjustDest, &cell ); + worldToCell( &cellDest, &cell ); PathfindLayerEnum layer = TheTerrainLogic->getLayerForDestination(dest); if (groupDest) { layer = TheTerrainLogic->getLayerForDestination(groupDest); @@ -5543,9 +5543,24 @@ Bool Pathfinder::adjustDestination(Object *obj, const LocomotorSet& locomotorSet Int i = cell.x; Int j = cell.y; // Check the center cell - if (checkForAdjust(obj, locomotorSet, isHuman, i,j, layer, iRadius, center, dest, groupDest)) { +#if RETAIL_COMPATIBLE_CRC + if (checkForAdjust(obj, locomotorSet, isHuman, i, j, layer, iRadius, center, dest, groupDest)) { + return true; + } +#else + Coord3D adjustDest = *dest; + if (checkForAdjust(obj, locomotorSet, isHuman, i, j, layer, iRadius, center, &adjustDest, groupDest)) { + // TheSuperHackers @fix stephanmeesters 15/06/2026 Destination adjustment always snaps to the nearest grid cell + // even when no adjustment is necessary because there are no obstructions. For single units this adjustment + // can be skipped in order to provide more predictable movement, which is especially noticeable for chinooks. + const Bool singleUnit = obj && obj->getGroup() && obj->getGroup()->getCount() == 1; + const Bool useExactDestination = isHuman && singleUnit; + if (!useExactDestination) { + *dest = adjustDest; + } return true; } +#endif // TheSuperHackers @info Expanding counter-clockwise spiral search around center cell C. Each full lap walks right->up->left->down. // After every pair of directions (right+up, then left+down) length of the segment grows by 1. From e6fbda2f5c620d50cb0edab36f3f825e932a1fe8 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:57:22 +0200 Subject: [PATCH 2/3] Use RETAIL_COMPATIBLE_PATHFINDING --- Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp b/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp index a7ee7e107eb..238ee09ba25 100644 --- a/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp +++ b/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp @@ -5543,7 +5543,7 @@ Bool Pathfinder::adjustDestination(Object *obj, const LocomotorSet& locomotorSet Int i = cell.x; Int j = cell.y; // Check the center cell -#if RETAIL_COMPATIBLE_CRC +#if RETAIL_COMPATIBLE_PATHFINDING if (checkForAdjust(obj, locomotorSet, isHuman, i, j, layer, iRadius, center, dest, groupDest)) { return true; } From 4c1f782f53c622525e51c213adc6cabf18295719 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Wed, 17 Jun 2026 13:15:56 +0200 Subject: [PATCH 3/3] Process review comments --- Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp b/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp index 238ee09ba25..ec3b1271829 100644 --- a/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp +++ b/Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp @@ -5550,9 +5550,9 @@ Bool Pathfinder::adjustDestination(Object *obj, const LocomotorSet& locomotorSet #else Coord3D adjustDest = *dest; if (checkForAdjust(obj, locomotorSet, isHuman, i, j, layer, iRadius, center, &adjustDest, groupDest)) { - // TheSuperHackers @fix stephanmeesters 15/06/2026 Destination adjustment always snaps to the nearest grid cell + // TheSuperHackers @bugfix stephanmeesters 15/06/2026 Destination adjustment always snaps to the nearest grid cell // even when no adjustment is necessary because there are no obstructions. For single units this adjustment - // can be skipped in order to provide more predictable movement, which is especially noticeable for chinooks. + // can be skipped in order to provide more accurate movement, which is especially noticeable for chinooks. const Bool singleUnit = obj && obj->getGroup() && obj->getGroup()->getCount() == 1; const Bool useExactDestination = isHuman && singleUnit; if (!useExactDestination) {