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( ( pGroup->ubSectorX == wp->x ) && ( pGroup->ubSectorY == wp->y ) )
|
||||
if( ( GetLengthOfPath(pGroup->pWaypoints) <= 1 ) && ( pGroup->ubSectorX == wp->x ) && ( pGroup->ubSectorY == wp->y ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1658,9 +1658,6 @@ void VerifyAllMercsInGroupAreOnSameSquad( GROUP *pGroup )
|
||||
|
||||
void RebuildWayPointsForGroupPath( PathStPtr pHeadOfPath, INT16 sMvtGroup )
|
||||
{
|
||||
INT32 iDelta = 0;
|
||||
INT32 iOldDelta = 0;
|
||||
BOOLEAN fFirstNode = TRUE;
|
||||
PathStPtr pNode = pHeadOfPath;
|
||||
GROUP *pGroup = NULL;
|
||||
WAYPOINT *wp = NULL;
|
||||
@@ -1700,7 +1697,7 @@ void RebuildWayPointsForGroupPath( PathStPtr pHeadOfPath, INT16 sMvtGroup )
|
||||
|
||||
|
||||
// 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
|
||||
// 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
|
||||
if( pGroup->fBetweenSectors )
|
||||
{
|
||||
// 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 );
|
||||
}
|
||||
UINT32 uiCurrentSectorId = CALCULATE_STRATEGIC_INDEX(pGroup->ubSectorX, pGroup->ubSectorY);
|
||||
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
|
||||
|
||||
// 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( iDelta != 0 ); // same sector should never repeat in the path list
|
||||
Assert(uiPrevNodeSectorId != pNode->uiSectorId);
|
||||
uiPrevNodeSectorId = pNode->uiSectorId;
|
||||
|
||||
// Waypoints are only added at "pivot points" - whenever there is a change in orthogonal direction.
|
||||
// If we're NOT currently between sectors, iOldDelta will start off at 0, which means that the first node can't be
|
||||
// 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 ) )
|
||||
// if we are between sectors, we have to skip the first waypoint to the place we are already going to.
|
||||
if (pGroup->fBetweenSectors && pNode->uiSectorId == uiTargetSectorId)
|
||||
{
|
||||
// add this strategic sector as a waypoint
|
||||
AddWaypointStrategicIDToPGroup( pGroup, pNode->uiSectorId );
|
||||
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
|
||||
{
|
||||
AddWaypointStrategicIDToPGroup(pGroup, pNode->uiSectorId);
|
||||
}
|
||||
|
||||
// remember this delta
|
||||
iOldDelta = iDelta;
|
||||
|
||||
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
|
||||
wp = GetFinalWaypoint( pGroup );
|
||||
pNode = GetLastNodeOfPath( pHeadOfPath );
|
||||
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" );
|
||||
|
||||
@@ -1951,6 +1940,17 @@ INT32 GetLengthOfPath( PathStPtr pHeadPath )
|
||||
return( iLength );
|
||||
}
|
||||
|
||||
INT32 GetLengthOfPath( WAYPOINT* pHeadWaypoint )
|
||||
{
|
||||
INT32 iLength = 0;
|
||||
while (pHeadWaypoint)
|
||||
{
|
||||
pHeadWaypoint = pHeadWaypoint->next;
|
||||
iLength++;
|
||||
}
|
||||
return iLength;
|
||||
}
|
||||
|
||||
INT32 GetLengthOfMercPath( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
PathStPtr pNode = NULL;
|
||||
@@ -2218,3 +2218,17 @@ void AddSectorToFrontOfMercPath( PathStPtr *ppMercPath, UINT8 ubSectorX, UINT8 u
|
||||
|
||||
*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
|
||||
INT32 GetLengthOfPath( PathStPtr pHeadPath );
|
||||
INT32 GetLengthOfPath( WAYPOINT* pHeadWaypoint );
|
||||
INT32 GetLengthOfMercPath( SOLDIERTYPE *pSoldier );
|
||||
|
||||
// is the path empty?
|
||||
@@ -121,6 +122,8 @@ BOOLEAN CheckIfPathIsEmpty( PathStPtr pHeadPath );
|
||||
PathStPtr GetSoldierMercPathPtr( SOLDIERTYPE *pSoldier );
|
||||
PathStPtr GetGroupMercPathPtr( GROUP *pGroup );
|
||||
|
||||
PathStPtr GetLastNodeOfPath( PathStPtr pNode );
|
||||
|
||||
UINT8 GetSoldierGroupId( SOLDIERTYPE *pSoldier );
|
||||
|
||||
// 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 GET_X_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
|
||||
#define SECTOR_INFO_TO_STRATEGIC_INDEX( i ) ( CALCULATE_STRATEGIC_INDEX ( SECTORX( i ), SECTORY( i ) ) )
|
||||
|
||||
Reference in New Issue
Block a user