From 32a8b757485ff59f3c9fc83937660f6019f48a23 Mon Sep 17 00:00:00 2001 From: Flugente Date: Sun, 24 May 2015 14:09:48 +0000 Subject: [PATCH] - Fix: wrong final destination displayed for travelling militia - Fix: when ordering militia movement, data of another group's path can be erased - Fix: a militia groups's path isn't always destroyed if the group is deleted - Fix: unsafe pointer handling can result in a gamecrash when loading strategic AI data from a savegame - Fix: traveltime calculations do not correctly handle waypoints, resulting in possible crashes git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7876 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Strategic/Map Screen Interface Map.cpp | 2 +- Strategic/MilitiaSquads.cpp | 2 ++ Strategic/PreBattle Interface.cpp | 1 - Strategic/Strategic AI.cpp | 11 +++++++++-- Strategic/Strategic Movement.cpp | 13 +++++++++++++ Strategic/mapscreen.cpp | 2 +- 6 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Strategic/Map Screen Interface Map.cpp b/Strategic/Map Screen Interface Map.cpp index 8bd0e211..3e830ad1 100644 --- a/Strategic/Map Screen Interface Map.cpp +++ b/Strategic/Map Screen Interface Map.cpp @@ -7850,7 +7850,7 @@ void DisplayMilitiaGroupBox() INT16 finalsector = GetLastSectorIdInMilitiaGroupPath( pGroup->ubGroupID ); if ( finalsector > -1 ) { - GetShortSectorString( SECTORX( finalsector ), SECTORY( finalsector ), wFinalSectorName ); + GetShortSectorString( finalsector % MAP_WORLD_X, finalsector / MAP_WORLD_X, wFinalSectorName ); } else { diff --git a/Strategic/MilitiaSquads.cpp b/Strategic/MilitiaSquads.cpp index 3da041ad..77584233 100644 --- a/Strategic/MilitiaSquads.cpp +++ b/Strategic/MilitiaSquads.cpp @@ -2991,6 +2991,8 @@ void DissolveMilitiaGroup( UINT8 uGroupId ) if ( pGroup && pGroup->usGroupTeam == MILITIA_TEAM ) { + ClearMercPathsAndWaypointsForAllInGroup( pGroup ); + StrategicAddMilitiaToSector( pGroup->ubSectorX, pGroup->ubSectorY, GREEN_MILITIA, pGroup->pEnemyGroup->ubNumAdmins ); StrategicAddMilitiaToSector( pGroup->ubSectorX, pGroup->ubSectorY, REGULAR_MILITIA, pGroup->pEnemyGroup->ubNumTroops ); StrategicAddMilitiaToSector( pGroup->ubSectorX, pGroup->ubSectorY, ELITE_MILITIA, pGroup->pEnemyGroup->ubNumElites ); diff --git a/Strategic/PreBattle Interface.cpp b/Strategic/PreBattle Interface.cpp index cade9356..8508cb85 100644 --- a/Strategic/PreBattle Interface.cpp +++ b/Strategic/PreBattle Interface.cpp @@ -2120,7 +2120,6 @@ void RetreatAllInvolvedMilitiaGroups() GROUP* pDeleteGroup = pGroup; pGroup = pGroup->next; - ClearMercPathsAndWaypointsForAllInGroup( pDeleteGroup ); DissolveMilitiaGroup( pDeleteGroup->ubGroupID ); } else diff --git a/Strategic/Strategic AI.cpp b/Strategic/Strategic AI.cpp index b734f705..0007a988 100644 --- a/Strategic/Strategic AI.cpp +++ b/Strategic/Strategic AI.cpp @@ -2295,7 +2295,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic5"); SetThisSectorAsEnemyControlled( pGroup->ubSectorX, pGroup->ubSectorY, 0, TRUE ); RemovePGroup( pGroup ); RecalculateGarrisonWeight( i ); - + return TRUE; } } @@ -4198,8 +4198,15 @@ BOOLEAN LoadStrategicAI( HWFILE hFile ) pGroup->ubSectorY != gWorldSectorY || gbWorldSectorZ ) { + UINT8 groupid = pGroup->ubGroupID; + RepollSAIGroup( pGroup ); - ValidateGroup( pGroup ); + + // it is possible that the group gets destroyed inbetween, so recheck on that + pGroup = GetGroup( groupid ); + + if ( pGroup ) + ValidateGroup( pGroup ); } } } diff --git a/Strategic/Strategic Movement.cpp b/Strategic/Strategic Movement.cpp index 20370bbd..c1629609 100644 --- a/Strategic/Strategic Movement.cpp +++ b/Strategic/Strategic Movement.cpp @@ -3185,6 +3185,7 @@ INT32 CalculateTravelTimeOfGroup( GROUP *pGroup ) { INT32 iDelta; UINT32 uiEtaTime = 0; + INT32 i = 0; WAYPOINT *pNode = NULL; WAYPOINT pCurrent, pDest; // check if valid group @@ -3197,6 +3198,18 @@ INT32 CalculateTravelTimeOfGroup( GROUP *pGroup ) // set up next node pNode = pGroup->pWaypoints; + // Flugente: start with the next waypoint we travel to, not the first one in the list + i = pGroup->ubNextWaypointID; + while ( i-- ) + { + //Traverse through the waypoint list to the next waypoint ID + if( pNode ); + pNode = pNode->next; + } + + if ( !pNode ) + return uiEtaTime; + // now get the delta in current sector and next sector iDelta = ( INT32 )( SECTOR( pGroup->ubSectorX, pGroup->ubSectorY ) - SECTOR( pGroup->ubNextX, pGroup->ubNextY ) ); diff --git a/Strategic/mapscreen.cpp b/Strategic/mapscreen.cpp index 37e0b015..9b8df9a8 100644 --- a/Strategic/mapscreen.cpp +++ b/Strategic/mapscreen.cpp @@ -16760,7 +16760,7 @@ BOOLEAN MilitiaPlotStart( ) // if this group exists, is indeed militia but has no members, erase it and its path if ( pGroup && pGroup->usGroupTeam == MILITIA_TEAM && pGroup->ubGroupSize == 0 ) { - gMilitiaPath[groupid].path = ClearStrategicPathList( gMilitiaPath[groupid].path, groupid ); + gMilitiaPath[groupid].path = ClearStrategicPathList( gMilitiaPath[groupid].path, (UINT8)gMilitiaPath[groupid].sGroupid ); RemovePGroup( pGroup );