From 2747f9cee0780ac56d71aaf9cd1e0458d89b3ec0 Mon Sep 17 00:00:00 2001 From: rftr Date: Sat, 2 Apr 2022 04:27:02 +0000 Subject: [PATCH] Fix: Assertion failures on militia strategic commands (by sun_alf) * Discarding a route can result in failure"Path exists, but no waypoints were added! AM-0". * Waypoints can be not deleted upon arrival to final destination. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@9356 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Strategic/Strategic Movement.cpp | 59 ++++++++++++++++---------------- Strategic/Strategic Pathing.cpp | 2 +- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/Strategic/Strategic Movement.cpp b/Strategic/Strategic Movement.cpp index d5b0eb5df..67d0e69db 100644 --- a/Strategic/Strategic Movement.cpp +++ b/Strategic/Strategic Movement.cpp @@ -163,6 +163,18 @@ UINT8 NumberMercsInVehicleGroup( GROUP *pGroup ); // waiting for input from user BOOLEAN gfWaitingForInput = FALSE; +static WAYPOINT* GetWaypointAtIndex( WAYPOINT *waypoints, UINT8 index) +{ + WAYPOINT *wp = waypoints; + while ( index-- ) + { //Traverse through the waypoint list to the next waypoint ID + Assert( wp ); + wp = wp->next; + } + Assert( wp ); + return wp; +} + //Player grouping functions //......................... //Creates a new player group, returning the unique ID of that group. This is the first @@ -1435,7 +1447,6 @@ void DeployGroupToSector( GROUP *pGroup ) //at the next sector during a move and the area is clear. void CalculateNextMoveIntention( GROUP *pGroup ) { - INT32 i; WAYPOINT *wp; Assert( pGroup ); @@ -1463,14 +1474,7 @@ void CalculateNextMoveIntention( GROUP *pGroup ) */ //Determine if we are at a waypoint. - i = pGroup->ubNextWaypointID; - wp = pGroup->pWaypoints; - while( i-- ) - { //Traverse through the waypoint list to the next waypoint ID - Assert( wp ); - wp = wp->next; - } - Assert( wp ); + wp = GetWaypointAtIndex( pGroup->pWaypoints, pGroup->ubNextWaypointID ); //We have the next waypoint, now check if we are actually there. if( pGroup->ubSectorX == wp->x && pGroup->ubSectorY == wp->y ) @@ -2753,7 +2757,6 @@ void DelayEnemyGroupsIfPathsCross( GROUP *pPlayerGroup ) void InitiateGroupMovementToNextSector( GROUP *pGroup ) { INT32 dx, dy; - INT32 i; UINT8 ubDirection; UINT8 ubSector; WAYPOINT *wp; @@ -2762,15 +2765,8 @@ void InitiateGroupMovementToNextSector( GROUP *pGroup ) UINT32 uiSleepMinutes = 0; Assert( pGroup ); - i = pGroup->ubNextWaypointID; - wp = pGroup->pWaypoints; - while ( i-- ) - { - //Traverse through the waypoint list to the next waypoint ID - Assert( wp ); - wp = wp->next; - } - Assert( wp ); + + wp = GetWaypointAtIndex( pGroup->pWaypoints, pGroup->ubNextWaypointID ); // the sector we are currently in ubSector = (UINT8)SECTOR( pGroup->ubSectorX, pGroup->ubSectorY ); @@ -4782,8 +4778,19 @@ BOOLEAN GroupAtFinalDestination( GROUP *pGroup ) return TRUE; } - // if we're there - if( ( GetLengthOfPath(pGroup->pWaypoints) <= 1 ) && ( pGroup->ubSectorX == wp->x ) && ( pGroup->ubSectorY == wp->y ) ) + // Waypoints of OUR_TEAM are being processed in a different way than ENEMY/MILITIA_TEAM: + // waypoints are shortened on each OUR_TEAM's visit of a sector, while ENEMY/MILITIA_TEAM keeps waypoints + // intact and increments ubNextWaypointID instead. + // OUR_TEAM: at final waypoint, if there are only 1 left; + // others: at final waypoint, if ubNextWaypointID index points to the last waypoint in chain; + BOOLEAN bTeamSpecificCondition = FALSE; + if ( pGroup->usGroupTeam == OUR_TEAM ) + bTeamSpecificCondition = GetLengthOfPath( pGroup->pWaypoints ) <= 1; + else + bTeamSpecificCondition = GetWaypointAtIndex( pGroup->pWaypoints, pGroup->ubNextWaypointID ) == wp; + + // we're there, if at final waypoint and current sector == final wp sector + if ( bTeamSpecificCondition && (pGroup->ubSectorX == wp->x) && (pGroup->ubSectorY == wp->y)) { return TRUE; } @@ -4997,7 +5004,7 @@ void UpdatePersistantGroupsFromOldSave( UINT32 uiSavedGameVersion ) BOOLEAN GroupWillMoveThroughSector( GROUP *pGroup, UINT8 ubSectorX, UINT8 ubSectorY ) { WAYPOINT *wp; - INT32 i, dx, dy; + INT32 dx, dy; UINT8 ubOrigX, ubOrigY; Assert( pGroup ); @@ -5009,19 +5016,13 @@ BOOLEAN GroupWillMoveThroughSector( GROUP *pGroup, UINT8 ubSectorX, UINT8 ubSect ubOrigX = pGroup->ubSectorX; ubOrigY = pGroup->ubSectorY; - i = pGroup->ubNextWaypointID; wp = pGroup->pWaypoints; if( !wp ) { //This is a floating group!? return FALSE; } - while( i-- ) - { //Traverse through the waypoint list to the next waypoint ID - Assert( wp ); - wp = wp->next; - } - Assert( wp ); + wp = GetWaypointAtIndex( wp, pGroup->ubNextWaypointID ); while( wp ) diff --git a/Strategic/Strategic Pathing.cpp b/Strategic/Strategic Pathing.cpp index 657d11fa2..bed640ab9 100644 --- a/Strategic/Strategic Pathing.cpp +++ b/Strategic/Strategic Pathing.cpp @@ -1697,7 +1697,7 @@ void RebuildWayPointsForGroupPath( PathStPtr pHeadOfPath, INT16 sMvtGroup ) // if group has no path planned at all - if ( pNode == NULL ) + if ( pNode == NULL || pNode->pNext == NULL ) { // and it's a player group, and it's between sectors // NOTE: AI groups never reverse direction between sectors, Kris cheats & teleports them back to their current sector!