mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Fix: incorrect path rebuilding in RebuildWayPointsForGroupPath(), incorrect GroupAtFinalDestination() detection (by sun_alf)
* RebuildWayPointsForGroupPath(): incorrect manipulations with 'iOldDelta' and 'iDelta' lead to skipping a node in 'pHeadOfPath' and to assertion failure as a result: AssertMsg( FALSE, String( "Invalid DIAGONAL waypoint being added for groupID %d. AM-0", pGroup->ubGroupID ) ); * GroupAtFinalDestination(): should take into account the amount of WayPoints, otherwise multiple visiting of a sector is not possible (group end up in that sector at first entrance): if( ( pGroup->ubSectorX == wp->x ) && ( pGroup->ubSectorY == wp->y ) ) git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@9348 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -4783,7 +4783,7 @@ BOOLEAN GroupAtFinalDestination( GROUP *pGroup )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if we're there
|
// if we're there
|
||||||
if( ( pGroup->ubSectorX == wp->x ) && ( pGroup->ubSectorY == wp->y ) )
|
if( ( GetLengthOfPath(pGroup->pWaypoints) <= 1 ) && ( pGroup->ubSectorX == wp->x ) && ( pGroup->ubSectorY == wp->y ) )
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1658,9 +1658,6 @@ void VerifyAllMercsInGroupAreOnSameSquad( GROUP *pGroup )
|
|||||||
|
|
||||||
void RebuildWayPointsForGroupPath( PathStPtr pHeadOfPath, INT16 sMvtGroup )
|
void RebuildWayPointsForGroupPath( PathStPtr pHeadOfPath, INT16 sMvtGroup )
|
||||||
{
|
{
|
||||||
INT32 iDelta = 0;
|
|
||||||
INT32 iOldDelta = 0;
|
|
||||||
BOOLEAN fFirstNode = TRUE;
|
|
||||||
PathStPtr pNode = pHeadOfPath;
|
PathStPtr pNode = pHeadOfPath;
|
||||||
GROUP *pGroup = NULL;
|
GROUP *pGroup = NULL;
|
||||||
WAYPOINT *wp = NULL;
|
WAYPOINT *wp = NULL;
|
||||||
@@ -1700,7 +1697,7 @@ void RebuildWayPointsForGroupPath( PathStPtr pHeadOfPath, INT16 sMvtGroup )
|
|||||||
|
|
||||||
|
|
||||||
// if group has no path planned at all
|
// if group has no path planned at all
|
||||||
if( ( pNode == NULL ) || ( pNode->pNext == NULL ) )
|
if ( pNode == NULL )
|
||||||
{
|
{
|
||||||
// and it's a player group, and it's between sectors
|
// 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!
|
// NOTE: AI groups never reverse direction between sectors, Kris cheats & teleports them back to their current sector!
|
||||||
@@ -1714,44 +1711,36 @@ void RebuildWayPointsForGroupPath( PathStPtr pHeadOfPath, INT16 sMvtGroup )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// if we're currently between sectors
|
UINT32 uiCurrentSectorId = CALCULATE_STRATEGIC_INDEX(pGroup->ubSectorX, pGroup->ubSectorY);
|
||||||
if( pGroup->fBetweenSectors )
|
UINT32 uiTargetSectorId = pGroup->fBetweenSectors ? CALCULATE_STRATEGIC_INDEX(pGroup->ubNextX, pGroup->ubNextY) : INVALID_STRATEGIC_INDEX;
|
||||||
{
|
UINT32 uiPrevNodeSectorId = INVALID_STRATEGIC_INDEX; // relates to path node, not to the group we work with
|
||||||
// figure out which direction we're already going in (Otherwise iOldDelta starts at 0)
|
|
||||||
iOldDelta = CALCULATE_STRATEGIC_INDEX( pGroup->ubNextX, pGroup->ubNextY ) - CALCULATE_STRATEGIC_INDEX( pGroup->ubSectorX, pGroup->ubSectorY );
|
|
||||||
}
|
|
||||||
|
|
||||||
// build a brand new list of waypoints, one for initial direction, and another for every "direction change" thereafter
|
// build a brand new list of waypoints, one for initial direction, and another for every "direction change" thereafter
|
||||||
while( pNode->pNext )
|
while (pNode != NULL)
|
||||||
{
|
{
|
||||||
iDelta = pNode->pNext->uiSectorId - pNode->uiSectorId;
|
Assert(uiPrevNodeSectorId != pNode->uiSectorId);
|
||||||
Assert( iDelta != 0 ); // same sector should never repeat in the path list
|
uiPrevNodeSectorId = pNode->uiSectorId;
|
||||||
|
|
||||||
// Waypoints are only added at "pivot points" - whenever there is a change in orthogonal direction.
|
// if we are between sectors, we have to skip the first waypoint to the place we are already going to.
|
||||||
// If we're NOT currently between sectors, iOldDelta will start off at 0, which means that the first node can't be
|
if (pGroup->fBetweenSectors && pNode->uiSectorId == uiTargetSectorId)
|
||||||
// added as a waypoint. This is what we want - for stationary mercs, the first node in a path is the CURRENT sector.
|
{
|
||||||
if( ( iOldDelta != 0 ) && ( iDelta != iOldDelta ) )
|
uiTargetSectorId = INVALID_STRATEGIC_INDEX; // reset to invalid so that it won't enter this branch anymore
|
||||||
|
}
|
||||||
|
else if (pNode->uiSectorId == uiCurrentSectorId) // also skip this first waypoint as we are already in
|
||||||
|
{
|
||||||
|
uiCurrentSectorId = INVALID_STRATEGIC_INDEX; // reset to invalid so that it won't enter this branch anymore
|
||||||
|
}
|
||||||
|
else // everything is OK, add this strategic sector as a waypoint
|
||||||
{
|
{
|
||||||
// add this strategic sector as a waypoint
|
|
||||||
AddWaypointStrategicIDToPGroup(pGroup, pNode->uiSectorId);
|
AddWaypointStrategicIDToPGroup(pGroup, pNode->uiSectorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remember this delta
|
|
||||||
iOldDelta = iDelta;
|
|
||||||
|
|
||||||
pNode = pNode->pNext;
|
pNode = pNode->pNext;
|
||||||
fFirstNode = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// there must have been at least one next node, or we would have bailed out on "no path" earlier
|
|
||||||
Assert( !fFirstNode );
|
|
||||||
|
|
||||||
// the final destination sector - always add a waypoint for it
|
|
||||||
AddWaypointStrategicIDToPGroup( pGroup, pNode->uiSectorId );
|
|
||||||
|
|
||||||
// at this point, the final sector in the path must be identical to this group's last waypoint
|
// at this point, the final sector in the path must be identical to this group's last waypoint
|
||||||
wp = GetFinalWaypoint( pGroup );
|
wp = GetFinalWaypoint( pGroup );
|
||||||
|
pNode = GetLastNodeOfPath( pHeadOfPath );
|
||||||
AssertMsg( wp, "Path exists, but no waypoints were added! AM-0" );
|
AssertMsg( wp, "Path exists, but no waypoints were added! AM-0" );
|
||||||
AssertMsg( pNode->uiSectorId == ( UINT32 ) CALCULATE_STRATEGIC_INDEX( wp->x, wp->y ), "Last waypoint differs from final path sector! AM-0" );
|
AssertMsg( pNode->uiSectorId == ( UINT32 ) CALCULATE_STRATEGIC_INDEX( wp->x, wp->y ), "Last waypoint differs from final path sector! AM-0" );
|
||||||
|
|
||||||
@@ -1951,6 +1940,17 @@ INT32 GetLengthOfPath( PathStPtr pHeadPath )
|
|||||||
return( iLength );
|
return( iLength );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INT32 GetLengthOfPath( WAYPOINT* pHeadWaypoint )
|
||||||
|
{
|
||||||
|
INT32 iLength = 0;
|
||||||
|
while (pHeadWaypoint)
|
||||||
|
{
|
||||||
|
pHeadWaypoint = pHeadWaypoint->next;
|
||||||
|
iLength++;
|
||||||
|
}
|
||||||
|
return iLength;
|
||||||
|
}
|
||||||
|
|
||||||
INT32 GetLengthOfMercPath( SOLDIERTYPE *pSoldier )
|
INT32 GetLengthOfMercPath( SOLDIERTYPE *pSoldier )
|
||||||
{
|
{
|
||||||
PathStPtr pNode = NULL;
|
PathStPtr pNode = NULL;
|
||||||
@@ -2218,3 +2218,17 @@ void AddSectorToFrontOfMercPath( PathStPtr *ppMercPath, UINT8 ubSectorX, UINT8 u
|
|||||||
|
|
||||||
*ppMercPath = pNode;
|
*ppMercPath = pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PathStPtr GetLastNodeOfPath(PathStPtr pNode)
|
||||||
|
{
|
||||||
|
if (pNode)
|
||||||
|
{
|
||||||
|
while (pNode->pNext)
|
||||||
|
{
|
||||||
|
pNode = pNode->pNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pNode;
|
||||||
|
}
|
||||||
@@ -113,6 +113,7 @@ BOOLEAN MoveGroupToOriginalSector( UINT8 ubGroupID );
|
|||||||
|
|
||||||
// get length of path
|
// get length of path
|
||||||
INT32 GetLengthOfPath( PathStPtr pHeadPath );
|
INT32 GetLengthOfPath( PathStPtr pHeadPath );
|
||||||
|
INT32 GetLengthOfPath( WAYPOINT* pHeadWaypoint );
|
||||||
INT32 GetLengthOfMercPath( SOLDIERTYPE *pSoldier );
|
INT32 GetLengthOfMercPath( SOLDIERTYPE *pSoldier );
|
||||||
|
|
||||||
// is the path empty?
|
// is the path empty?
|
||||||
@@ -121,6 +122,8 @@ BOOLEAN CheckIfPathIsEmpty( PathStPtr pHeadPath );
|
|||||||
PathStPtr GetSoldierMercPathPtr( SOLDIERTYPE *pSoldier );
|
PathStPtr GetSoldierMercPathPtr( SOLDIERTYPE *pSoldier );
|
||||||
PathStPtr GetGroupMercPathPtr( GROUP *pGroup );
|
PathStPtr GetGroupMercPathPtr( GROUP *pGroup );
|
||||||
|
|
||||||
|
PathStPtr GetLastNodeOfPath( PathStPtr pNode );
|
||||||
|
|
||||||
UINT8 GetSoldierGroupId( SOLDIERTYPE *pSoldier );
|
UINT8 GetSoldierGroupId( SOLDIERTYPE *pSoldier );
|
||||||
|
|
||||||
// clears this groups strategic movement (mercpaths and waypoints), include those in the vehicle structs(!)
|
// clears this groups strategic movement (mercpaths and waypoints), include those in the vehicle structs(!)
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ extern BOOLEAN gfUseAlternateMap;
|
|||||||
#define CALCULATE_STRATEGIC_INDEX( x, y ) ( x + ( y * MAP_WORLD_X ) )
|
#define CALCULATE_STRATEGIC_INDEX( x, y ) ( x + ( y * MAP_WORLD_X ) )
|
||||||
#define GET_X_FROM_STRATEGIC_INDEX( i ) ( i % MAP_WORLD_X )
|
#define GET_X_FROM_STRATEGIC_INDEX( i ) ( i % MAP_WORLD_X )
|
||||||
#define GET_Y_FROM_STRATEGIC_INDEX( i ) ( i / MAP_WORLD_X )
|
#define GET_Y_FROM_STRATEGIC_INDEX( i ) ( i / MAP_WORLD_X )
|
||||||
|
#define INVALID_STRATEGIC_INDEX ( 0 )
|
||||||
|
|
||||||
// macros to convert between the 2 different sector numbering systems
|
// macros to convert between the 2 different sector numbering systems
|
||||||
#define SECTOR_INFO_TO_STRATEGIC_INDEX( i ) ( CALCULATE_STRATEGIC_INDEX ( SECTORX( i ), SECTORY( i ) ) )
|
#define SECTOR_INFO_TO_STRATEGIC_INDEX( i ) ( CALCULATE_STRATEGIC_INDEX ( SECTORX( i ), SECTORY( i ) ) )
|
||||||
|
|||||||
Reference in New Issue
Block a user