Example #1
0
BOOLEAN CanSoldierReachGridNoInGivenTileLimit( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT16 sMaxTiles, INT8 bLevel )
{
	INT32 iNumTiles;
	INT16	sActionGridNo;
	UINT8	ubDirection;

	if ( pSoldier->bLevel != bLevel )
	{
		return( FALSE );
	}

	sActionGridNo =  FindAdjacentGridEx( pSoldier, sGridNo, &ubDirection, NULL, FALSE, FALSE );

	if ( sActionGridNo == -1 )
	{
		sActionGridNo = sGridNo;		
	}

	if ( sActionGridNo == pSoldier->sGridNo )
	{
		return( TRUE );
	}

	iNumTiles = FindBestPath( pSoldier, sActionGridNo, pSoldier->bLevel, WALKING, NO_COPYROUTE, PATH_IGNORE_PERSON_AT_DEST );

	if ( iNumTiles <= sMaxTiles && iNumTiles != 0 )
	{
		return( TRUE );
	}
	else
	{
		return( FALSE );
	}
}
Example #2
0
BOOLEAN FullPatientCheck( SOLDIERTYPE * pPatient )
{
	UINT8						cnt;
	SOLDIERTYPE *		pSoldier;

	if ( CanCharacterAutoBandageTeammate( pPatient ) )
	{
		// can bandage self!
		return( TRUE );
	}

	if ( pPatient->pathing.bLevel != 0 )
	{	// look for a clear spot for jumping up

		// special "closest" search that ignores climb spots IF they are occupied by non-medics
		return( FindAutobandageClimbPoint( pPatient->sGridNo, TRUE ) );
	}
	else
	{
		// run though the list of chars on team
		cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
		for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++)
		{
			// can this character help out?
			if ( CanCharacterAutoBandageTeammate( pSoldier ) == TRUE )
			{
				// can this guy path to the patient?
				if ( pSoldier->pathing.bLevel == 0 )
				{
					// do a regular path check
					if ( FindBestPath( pSoldier, pPatient->sGridNo, 0, WALKING, NO_COPYROUTE, PATH_THROUGH_PEOPLE ) )
					{
						return( TRUE );
					}
				}
				else
				{
					// if on different levels, assume okay
					return( TRUE );
				}
			}
		}
	}
	return( FALSE );
}
Example #3
0
int LegalNPCDestination(SOLDIERTYPE *pSoldier, INT16 sGridno, UINT8 ubPathMode, UINT8 ubWaterOK, UINT8 fFlags)
{
	BOOLEAN fSkipTilesWithMercs;
 
	if ((sGridno < 0) || (sGridno >= GRIDSIZE))
  {
#ifdef RECORDNET
   fprintf(NetDebugFile,"LegalNPC->sDestination: ERROR - rcvd invalid gridno %d",gridno);
#endif

#ifdef BETAVERSION
   NumMessage("LegalNPC->sDestination: ERROR - rcvd invalid gridno ",gridno);
#endif

   return(FALSE);
  }

	// return false if gridno on different level from merc
	if ( GridNoOnVisibleWorldTile( pSoldier->sGridNo ) && gpWorldLevelData[ pSoldier->sGridNo ].sHeight != gpWorldLevelData[ sGridno ].sHeight )
	{
		return( FALSE );
	}


	// skip mercs if turnbased and adjacent AND not doing an IGNORE_PATH check (which is used almost exclusively by GoAsFarAsPossibleTowards)
	fSkipTilesWithMercs = (gfTurnBasedAI && ubPathMode != IGNORE_PATH && SpacesAway( pSoldier->sGridNo, sGridno ) == 1 );

 // if this gridno is an OK destination
 // AND the gridno is NOT in a tear-gassed tile when we have no gas mask
 // AND someone is NOT already standing there
 // AND we're NOT already standing at that gridno
 // AND the gridno hasn't been black-listed for us

 // Nov 28 98: skip people in destination tile if in turnbased
 if ( ( NewOKDestination(pSoldier, sGridno, fSkipTilesWithMercs, pSoldier->bLevel ) ) &&
				( !InGas( pSoldier, sGridno ) ) &&
				( sGridno != pSoldier->sGridNo ) &&
				( sGridno != pSoldier->sBlackList ) )
 /*
 if ( ( NewOKDestination(pSoldier, sGridno, FALSE, pSoldier->bLevel ) ) &&
				( !(gpWorldLevelData[ sGridno ].ubExtFlags[0] & (MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS)) || ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK || pSoldier->inv[ HEAD2POS ].usItem == GASMASK ) ) &&
				( sGridno != pSoldier->sGridNo ) &&
				( sGridno != pSoldier->sBlackList ) )*/
 /*
 if ( ( NewOKDestination(pSoldier,sGridno,ALLPEOPLE, pSoldier->bLevel ) ) &&
				( !(gpWorldLevelData[ sGridno ].ubExtFlags[0] & (MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS)) || ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK || pSoldier->inv[ HEAD2POS ].usItem == GASMASK ) ) &&
				( sGridno != pSoldier->sGridNo ) &&
				( sGridno != pSoldier->sBlackList ) )
				*/
   {
    
	  // if water's a problem, and gridno is in a water tile (bridges are OK)
		if (!ubWaterOK && Water(sGridno))
		  return(FALSE);

    // passed all checks, now try to make sure we can get there!
    switch (ubPathMode)
     {
      // if finding a path wasn't asked for (could have already been done,
      // for example), don't bother
      case IGNORE_PATH     :	return(TRUE);

      case ENSURE_PATH     :	if ( FindBestPath( pSoldier, sGridno, pSoldier->bLevel, WALKING, COPYROUTE, fFlags ) )
															{
			   												return(TRUE);        // legal destination
															}
      												else // got this far, but found no clear path,
															{
																// so test fails
        												return(FALSE);
															}
															// *** NOTE: movement mode hardcoded to WALKING !!!!!
			case ENSURE_PATH_COST:	return(PlotPath(pSoldier,sGridno,FALSE,FALSE,FALSE,WALKING,FALSE,FALSE,0));

      default              :
#ifdef BETAVERSION
			     NumMessage("LegalNPC->sDestination: ERROR - illegal pathMode = ",ubPathMode);
#endif
			     return(FALSE);
     }
   }
 else  // something failed - didn't even have to test path
   return(FALSE);       	// illegal destination
}
Example #4
0
UINT16 FindRandomGridNoFromSweetSpot( SOLDIERTYPE *pSoldier, INT16 sSweetGridNo, INT8 ubRadius, UINT8 *pubDirection )
{
	INT16		sX, sY;
	INT16		sGridNo;
	INT32					leftmost;
	BOOLEAN	fFound = FALSE;
	UINT32		cnt = 0;
	SOLDIERTYPE soldier;
	UINT8 ubSaveNPCAPBudget;
	UINT8 ubSaveNPCDistLimit;
	UINT8	ubBestDirection=0;
	INT16  sTop, sBottom;
	INT16  sLeft, sRight;
	INT16  cnt1, cnt2;
	UINT8	 ubRoomNum;

	//Save AI pathing vars.  changing the distlimit restricts how 
	//far away the pathing will consider.
	ubSaveNPCAPBudget = gubNPCAPBudget;
	ubSaveNPCDistLimit = gubNPCDistLimit;
	gubNPCAPBudget = 0;
	gubNPCDistLimit = ubRadius;

	//create dummy soldier, and use the pathing to determine which nearby slots are
	//reachable.
	memset( &soldier, 0, sizeof( SOLDIERTYPE ) );
	soldier.bLevel = 0;
	soldier.bTeam = 1;
	soldier.sGridNo = sSweetGridNo;

	sTop		= ubRadius;
	sBottom = -ubRadius;
	sLeft   = - ubRadius;
	sRight  = ubRadius;

	// ATE: CHECK FOR BOUNDARIES!!!!!!
	for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
	{
		leftmost = ( ( sSweetGridNo + ( WORLD_COLS * cnt1 ) )/ WORLD_COLS ) * WORLD_COLS;

		for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
		{
			sGridNo = sSweetGridNo + ( WORLD_COLS * cnt1 ) + cnt2;
			if( sGridNo >=0 && sGridNo < WORLD_MAX && sGridNo >= leftmost && sGridNo < ( leftmost + WORLD_COLS ) )
			{
				gpWorldLevelData[ sGridNo ].uiFlags &= (~MAPELEMENT_REACHABLE);
			}
		}
	}

	//Now, find out which of these gridnos are reachable 
	//(use the fake soldier and the pathing settings)
	FindBestPath( &soldier, NOWHERE, 0, WALKING, COPYREACHABLE, ( PATH_IGNORE_PERSON_AT_DEST | PATH_THROUGH_PEOPLE ) );

	do
	{
		sX = (UINT16)Random( ubRadius );
		sY = (UINT16)Random( ubRadius );

		leftmost = ( ( sSweetGridNo + ( WORLD_COLS * sY ) )/ WORLD_COLS ) * WORLD_COLS;

		sGridNo = sSweetGridNo + ( WORLD_COLS * sY ) + sX;

		if ( sGridNo >=0 && sGridNo < WORLD_MAX && 
				 sGridNo >= leftmost && sGridNo < ( leftmost + WORLD_COLS ) 
				&& gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REACHABLE )
		{
			// Go on sweet stop
			if ( NewOKDestination( pSoldier, sGridNo, TRUE , pSoldier->bLevel) )
			{
				// If we are a crow, we need this additional check
				if ( pSoldier->ubBodyType == CROW )
				{
					if ( !InARoom( sGridNo, &ubRoomNum ) )
					{
						fFound = TRUE;
					}
				}
				else
				{
					fFound = TRUE;
				}
			}
		}

		cnt++;

		if ( cnt > 2000 )
		{
			return( NOWHERE );
		}

	} while( !fFound );

	// Set direction to center of map!
	*pubDirection =  (UINT8)GetDirectionToGridNoFromGridNo( sGridNo, ( ( ( WORLD_ROWS / 2 ) * WORLD_COLS ) + ( WORLD_COLS / 2 ) ) );

	gubNPCAPBudget = ubSaveNPCAPBudget;
	gubNPCDistLimit = ubSaveNPCDistLimit;

	return( sGridNo );

}
Example #5
0
UINT16 FindGridNoFromSweetSpotWithStructDataFromSoldier( SOLDIERTYPE *pSoldier, UINT16 usAnimState, INT8 ubRadius, UINT8 *pubDirection, BOOLEAN fClosestToMerc, SOLDIERTYPE *pSrcSoldier )
{
	INT16  sTop, sBottom;
	INT16  sLeft, sRight;
	INT16  cnt1, cnt2, cnt3;
	INT16		sGridNo;
	INT32		uiRange, uiLowestRange = 999999;
	INT16		sLowestGridNo=-1;
	INT32					leftmost;
	BOOLEAN	fFound = FALSE;
	UINT8 ubSaveNPCAPBudget;
	UINT8 ubSaveNPCDistLimit;
	UINT8	ubBestDirection=0;
	INT16 sSweetGridNo;
	SOLDIERTYPE soldier;
	
	sSweetGridNo = pSrcSoldier->sGridNo;


	//Save AI pathing vars.  changing the distlimit restricts how 
	//far away the pathing will consider.
	ubSaveNPCAPBudget = gubNPCAPBudget;
	ubSaveNPCDistLimit = gubNPCDistLimit;
	gubNPCAPBudget = 0;
	gubNPCDistLimit = ubRadius;

	//create dummy soldier, and use the pathing to determine which nearby slots are
	//reachable.
	memset( &soldier, 0, sizeof( SOLDIERTYPE ) );
	soldier.bLevel = 0;
	soldier.bTeam = 1;
	soldier.sGridNo = sSweetGridNo;

	sTop		= ubRadius;
	sBottom = -ubRadius;
	sLeft   = - ubRadius;
	sRight  = ubRadius;

	//clear the mapelements of potential residue MAPELEMENT_REACHABLE flags
	//in the square region.
	// ATE: CHECK FOR BOUNDARIES!!!!!!
	for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
	{
		leftmost = ( ( sSweetGridNo + ( WORLD_COLS * cnt1 ) )/ WORLD_COLS ) * WORLD_COLS;

		for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
		{
			sGridNo = sSweetGridNo + ( WORLD_COLS * cnt1 ) + cnt2;
			if( sGridNo >=0 && sGridNo < WORLD_MAX && sGridNo >= leftmost && sGridNo < ( leftmost + WORLD_COLS ) )
			{
				gpWorldLevelData[ sGridNo ].uiFlags &= (~MAPELEMENT_REACHABLE);
			}
		}
	}

	//Now, find out which of these gridnos are reachable 
	FindBestPath( &soldier, NOWHERE, 0, WALKING, COPYREACHABLE, ( PATH_IGNORE_PERSON_AT_DEST | PATH_THROUGH_PEOPLE ) );
	
	uiLowestRange = 999999;	

	for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
	{
		leftmost = ( ( sSweetGridNo + ( WORLD_COLS * cnt1 ) )/ WORLD_COLS ) * WORLD_COLS;

		for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
		{
			sGridNo = sSweetGridNo + ( WORLD_COLS * cnt1 ) + cnt2;
			if( sGridNo >=0 && sGridNo < WORLD_MAX && sGridNo >= leftmost && sGridNo < ( leftmost + WORLD_COLS ) 
				&& gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REACHABLE )
			{
				// Go on sweet stop
				if ( NewOKDestination( pSoldier, sGridNo, TRUE, pSoldier->bLevel ) )
				{
					BOOLEAN fDirectionFound = FALSE;
					UINT16	usOKToAddStructID;
					STRUCTURE_FILE_REF * pStructureFileRef;
					UINT16							 usAnimSurface;

					if ( fClosestToMerc != 3 )
					{
						if ( pSoldier->pLevelNode != NULL && pSoldier->pLevelNode->pStructureData != NULL )
						{
							usOKToAddStructID = pSoldier->pLevelNode->pStructureData->usStructureID;
						}
						else
						{
							usOKToAddStructID = INVALID_STRUCTURE_ID;
						}

						// Get animation surface...
			 			usAnimSurface = DetermineSoldierAnimationSurface( pSoldier, usAnimState );
						// Get structure ref...
						pStructureFileRef = GetAnimationStructureRef( pSoldier->ubID, usAnimSurface, usAnimState );

						// Check each struct in each direction
						for( cnt3 = 0; cnt3 < 8; cnt3++ )
						{
							if (OkayToAddStructureToWorld( (INT16)sGridNo, pSoldier->bLevel, &(pStructureFileRef->pDBStructureRef[gOneCDirection[ cnt3 ]]), usOKToAddStructID ) )
							{
								fDirectionFound = TRUE;
								break;
							}

						}
					}
					else
					{
						fDirectionFound = TRUE;
						cnt3 = (UINT8)Random( 8 );
					}

					if ( fDirectionFound )
					{
						if ( fClosestToMerc == 1 )
						{
							uiRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sGridNo );
						}
						else if ( fClosestToMerc == 2 )
						{
							uiRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sGridNo ) + GetRangeInCellCoordsFromGridNoDiff( sSweetGridNo, sGridNo );
						}
						else
						{
							//uiRange = GetRangeInCellCoordsFromGridNoDiff( sSweetGridNo, sGridNo );
							uiRange = abs((sSweetGridNo / MAXCOL) - (sGridNo / MAXCOL)) +
								abs((sSweetGridNo % MAXROW) - (sGridNo % MAXROW));
						}

						if ( uiRange < uiLowestRange || (uiRange == uiLowestRange && PythSpacesAway( pSoldier->sGridNo, sGridNo ) < PythSpacesAway( pSoldier->sGridNo, sLowestGridNo ) ) )
						{
							ubBestDirection = (UINT8)cnt3;
							sLowestGridNo		= sGridNo;
							uiLowestRange		= uiRange;
							fFound = TRUE;
						}
					}
				}
			}
		}
	}
	gubNPCAPBudget = ubSaveNPCAPBudget;
	gubNPCDistLimit = ubSaveNPCDistLimit;
	if ( fFound )
	{
		// Set direction we chose...
		*pubDirection = ubBestDirection;

		return( sLowestGridNo );
	}
	else
	{
		return( NOWHERE );
	}
}
Example #6
0
//Kris:  modified to actually path from sweetspot to gridno.  Previously, it only checked if the
//destination was sittable (though it was possible that that location would be trapped.
UINT16 FindGridNoFromSweetSpot( SOLDIERTYPE *pSoldier, INT16 sSweetGridNo, INT8 ubRadius, UINT8 *pubDirection )
{
	INT16  sTop, sBottom;
	INT16  sLeft, sRight;
	INT16  cnt1, cnt2;
	INT16		sGridNo;
	INT32		uiRange, uiLowestRange = 999999;
	INT16		sLowestGridNo=-1;
	INT32					leftmost;
	BOOLEAN	fFound = FALSE;
	SOLDIERTYPE soldier;
	UINT8 ubSaveNPCAPBudget;
	UINT8 ubSaveNPCDistLimit;

	//Save AI pathing vars.  changing the distlimit restricts how 
	//far away the pathing will consider.
	ubSaveNPCAPBudget = gubNPCAPBudget;
	ubSaveNPCDistLimit = gubNPCDistLimit;
	gubNPCAPBudget = 0;
	gubNPCDistLimit = ubRadius;

	//create dummy soldier, and use the pathing to determine which nearby slots are
	//reachable.
	memset( &soldier, 0, sizeof( SOLDIERTYPE ) );
	soldier.bLevel = 0;
	soldier.bTeam = 1;
	soldier.sGridNo = sSweetGridNo;
 
	sTop		= ubRadius;
	sBottom = -ubRadius;
	sLeft   = - ubRadius;
	sRight  = ubRadius;

	//clear the mapelements of potential residue MAPELEMENT_REACHABLE flags
	//in the square region.
	// ATE: CHECK FOR BOUNDARIES!!!!!!
	for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
	{
		leftmost = ( ( sSweetGridNo + ( WORLD_COLS * cnt1 ) )/ WORLD_COLS ) * WORLD_COLS;

		for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
		{
			sGridNo = sSweetGridNo + ( WORLD_COLS * cnt1 ) + cnt2;
			if( sGridNo >=0 && sGridNo < WORLD_MAX && sGridNo >= leftmost && sGridNo < ( leftmost + WORLD_COLS ) )
			{
				gpWorldLevelData[ sGridNo ].uiFlags &= (~MAPELEMENT_REACHABLE);
			}
		}
	}

	//Now, find out which of these gridnos are reachable 
	//(use the fake soldier and the pathing settings)
	FindBestPath( &soldier, NOWHERE, 0, WALKING, COPYREACHABLE, ( PATH_IGNORE_PERSON_AT_DEST | PATH_THROUGH_PEOPLE ) );
	
	uiLowestRange = 999999;	

	for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
	{
		leftmost = ( ( sSweetGridNo + ( WORLD_COLS * cnt1 ) )/ WORLD_COLS ) * WORLD_COLS;

		for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
		{
			sGridNo = sSweetGridNo + ( WORLD_COLS * cnt1 ) + cnt2;
			if( sGridNo >=0 && sGridNo < WORLD_MAX && sGridNo >= leftmost && sGridNo < ( leftmost + WORLD_COLS ) 
				&& gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REACHABLE )
			{
				// Go on sweet stop
				if ( NewOKDestination( pSoldier, sGridNo, TRUE, pSoldier->bLevel ) )
				{
					// ATE: INstead of using absolute range, use the path cost!
				  //uiRange = PlotPath( &soldier, sGridNo, NO_COPYROUTE, NO_PLOT, TEMPORARY, WALKING, NOT_STEALTH, FORWARD, 50 );
					uiRange = CardinalSpacesAway( sSweetGridNo, sGridNo );
					
				//	if ( uiRange == 0 )
				//	{
				//		uiRange = 999999;
				//	}

					if ( uiRange < uiLowestRange )
					{
						sLowestGridNo = sGridNo;
						uiLowestRange = uiRange;
						fFound = TRUE;
					}
				}
			}
		}
	}
	gubNPCAPBudget = ubSaveNPCAPBudget;
	gubNPCDistLimit = ubSaveNPCDistLimit;
	if ( fFound )
	{
		// Set direction to center of map!
		*pubDirection =  (UINT8)GetDirectionToGridNoFromGridNo( sLowestGridNo, ( ( ( WORLD_ROWS / 2 ) * WORLD_COLS ) + ( WORLD_COLS / 2 ) ) );
		return( sLowestGridNo );
	}
	else
	{
		return( NOWHERE );
	}
}
Example #7
0
float CPathFinder::FindBestPathToRadius(std::vector<float3>& posPath, float3& startPos, float radiusAroundTarget, const float3& target) {
	std::vector<float3> posTargets;
	posTargets.push_back(target);
	float dist = FindBestPath(posPath, startPos, radiusAroundTarget, posTargets);
	return dist;
}
Example #8
0
BOOLEAN HandleNextTileWaiting( SOLDIERTYPE *pSoldier )
{
	// Buddy is waiting to continue his path
	INT8		bBlocked, bPathBlocked;
	INT16		sCost;
	INT16   sNewGridNo, sCheckGridNo;
	UINT8		ubDirection, bCauseDirection;
	UINT8		ubPerson;
	UINT8		fFlags = 0;

 
	if ( pSoldier->fDelayedMovement )
	{
		if ( TIMECOUNTERDONE( pSoldier->NextTileCounter, NEXT_TILE_CHECK_DELAY ) )
		{
			RESETTIMECOUNTER( pSoldier->NextTileCounter, NEXT_TILE_CHECK_DELAY );

			// Get direction from gridno...
			bCauseDirection = (INT8)GetDirectionToGridNoFromGridNo( pSoldier->sGridNo, pSoldier->sDelayedMovementCauseGridNo );

			bBlocked = TileIsClear( pSoldier, bCauseDirection, pSoldier->sDelayedMovementCauseGridNo, pSoldier->bLevel );

			// If we are waiting for a temp blockage.... continue to wait
			if ( pSoldier->fDelayedMovement >= 100 &&  bBlocked == MOVE_TILE_TEMP_BLOCKED )
			{
				// ATE: Increment 1
				pSoldier->fDelayedMovement++;

				// Are we close enough to give up? ( and are a pc )
				if ( pSoldier->fDelayedMovement > 120 )
				{
					// Quit...
					SetFinalTile( pSoldier, pSoldier->sGridNo, TRUE );
					pSoldier->fDelayedMovement = FALSE;
				}
				return( TRUE );
			}

			// Try new path if anything but temp blockage!
			if ( bBlocked != MOVE_TILE_TEMP_BLOCKED )
			{
				// Set to normal delay
				if ( pSoldier->fDelayedMovement >= 100 && pSoldier->fDelayedMovement != 150 )
				{
					pSoldier->fDelayedMovement = 1;
				}

				// Default to pathing through people
				fFlags = PATH_THROUGH_PEOPLE;

				// Now, if we are in the state where we are desparently trying to get out...
				// Use other flag
				// CJC: path-through-people includes ignoring person at dest
				/*
				if ( pSoldier->fDelayedMovement >= 150 )
				{
					fFlags = PATH_IGNORE_PERSON_AT_DEST;
				}
				*/

				// Check destination first!
				if ( pSoldier->sAbsoluteFinalDestination == pSoldier->sFinalDestination )
				{
					// on last lap of scripted move, make sure we get to final dest
					sCheckGridNo = pSoldier->sAbsoluteFinalDestination;					
				}
				else if (!NewOKDestination( pSoldier, pSoldier->sFinalDestination, TRUE, pSoldier->bLevel ))
				{
					if ( pSoldier->fDelayedMovement >= 150 )
					{
						// OK, look around dest for the first one!
						sCheckGridNo = FindGridNoFromSweetSpot( pSoldier, pSoldier->sFinalDestination, 6, &ubDirection );

						if ( sCheckGridNo == NOWHERE )
						{
							// If this is nowhere, try harder!
							sCheckGridNo = FindGridNoFromSweetSpot( pSoldier, pSoldier->sFinalDestination, 16, &ubDirection );
						}
					}
					else
					{
						// OK, look around dest for the first one!
						sCheckGridNo = FindGridNoFromSweetSpotThroughPeople( pSoldier, pSoldier->sFinalDestination, 6, &ubDirection );

						if ( sCheckGridNo == NOWHERE )
						{
							// If this is nowhere, try harder!
							sCheckGridNo = FindGridNoFromSweetSpotThroughPeople( pSoldier, pSoldier->sFinalDestination, 16, &ubDirection );
						}
					}
				}
				else
				{
					sCheckGridNo = pSoldier->sFinalDestination;
				}

				// Try another path to destination
				// ATE: Allow path to exit grid!
				if ( pSoldier->ubWaitActionToDo == 1 && gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO )
				{
					gfPlotPathToExitGrid = TRUE;
				}

				sCost = (INT16) FindBestPath( pSoldier, sCheckGridNo, pSoldier->bLevel, pSoldier->usUIMovementMode, NO_COPYROUTE, fFlags );
				gfPlotPathToExitGrid = FALSE;
				
				// Can we get there
				if ( sCost > 0 )
				{
					// Is the next tile blocked too?
					sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( (UINT8)guiPathingData[ 0 ] ) );

					bPathBlocked = TileIsClear( pSoldier, (UINT8)guiPathingData[ 0 ], sNewGridNo, pSoldier->bLevel );

					if ( bPathBlocked == MOVE_TILE_STATIONARY_BLOCKED )
					{
						// Try to path around everyone except dest person

						if ( pSoldier->ubWaitActionToDo == 1 && gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO )
						{
							gfPlotPathToExitGrid = TRUE;
						}

						sCost = (INT16) FindBestPath( pSoldier, sCheckGridNo, pSoldier->bLevel, pSoldier->usUIMovementMode, NO_COPYROUTE, PATH_IGNORE_PERSON_AT_DEST );

						gfPlotPathToExitGrid = FALSE;

						// Is the next tile in this new path blocked too?
						sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( (UINT8)guiPathingData[ 0 ] ) );

						bPathBlocked = TileIsClear( pSoldier, (UINT8)guiPathingData[ 0 ], sNewGridNo, pSoldier->bLevel );

						// now working with a path which does not go through people				
						pSoldier->ubDelayedMovementFlags &= (~DELAYED_MOVEMENT_FLAG_PATH_THROUGH_PEOPLE);
					}
					else
					{
						// path through people worked fine
						if ( pSoldier->fDelayedMovement < 150 )
						{
							pSoldier->ubDelayedMovementFlags |= DELAYED_MOVEMENT_FLAG_PATH_THROUGH_PEOPLE;
						}
					}

					// Are we clear?
					if ( bPathBlocked == MOVE_TILE_CLEAR )
					{
						// Go for it path!
						if ( pSoldier->ubWaitActionToDo == 1 && gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO )
						{
							gfPlotPathToExitGrid = TRUE;
						}

						//pSoldier->fDelayedMovement = FALSE;
						// ATE: THis will get set in EENT_GetNewSoldierPath....
						pSoldier->usActionData = sCheckGridNo;

						pSoldier->bPathStored = FALSE;

						EVENT_GetNewSoldierPath( pSoldier, sCheckGridNo, pSoldier->usUIMovementMode );
						gfPlotPathToExitGrid = FALSE;

						return( TRUE );
					}
				}

				pSoldier->fDelayedMovement++;

				if ( pSoldier->fDelayedMovement == 99 )
				{
					// Cap at 99
					pSoldier->fDelayedMovement = 99;
				}

				// Do we want to force a swap?
				if (pSoldier->fDelayedMovement == 3 && (pSoldier->sAbsoluteFinalDestination != NOWHERE || gTacticalStatus.fAutoBandageMode) )
				{
					// with person who is in the way?
					ubPerson = WhoIsThere2( pSoldier->sDelayedMovementCauseGridNo, pSoldier->bLevel );

					// if either on a mission from god, or two AI guys not on stationary...
					if ( ubPerson != NOBODY && ( pSoldier->ubQuoteRecord != 0 || ( pSoldier->bTeam != gbPlayerNum && pSoldier->bOrders != STATIONARY && MercPtrs[ ubPerson ]->bTeam != gbPlayerNum && MercPtrs[ ubPerson ]->bOrders != STATIONARY ) || (pSoldier->bTeam == gbPlayerNum && gTacticalStatus.fAutoBandageMode && !(MercPtrs[ ubPerson ]->bTeam == CIV_TEAM && MercPtrs[ ubPerson ]->bOrders == STATIONARY ) ) ) )
					{					
						// Swap now!
						//MercPtrs[ ubPerson ]->fBlockedByAnotherMerc = FALSE;

						// Restore final dest....
						//MercPtrs[ ubPerson ]->sFinalDestination = sTempDestGridNo;

						// Swap merc positions.....
						SwapMercPositions( pSoldier, MercPtrs[ ubPerson ] );
						
						// With these two guys swapped, we should try to continue on our way....				
						pSoldier->fDelayedMovement = FALSE;

						// We must calculate the path here so that we can give it the "through people" parameter
						if ( gTacticalStatus.fAutoBandageMode && pSoldier->sAbsoluteFinalDestination == NOWHERE )
						{
							FindBestPath( pSoldier, pSoldier->sFinalDestination, pSoldier->bLevel, pSoldier->usUIMovementMode, COPYROUTE, PATH_THROUGH_PEOPLE );
						}
						else if ( pSoldier->sAbsoluteFinalDestination != NOWHERE && !FindBestPath( pSoldier, pSoldier->sAbsoluteFinalDestination, pSoldier->bLevel, pSoldier->usUIMovementMode, COPYROUTE, PATH_THROUGH_PEOPLE ) )
						{
							// check to see if we're there now!
							if ( pSoldier->sGridNo == pSoldier->sAbsoluteFinalDestination )
							{
								NPCReachedDestination( pSoldier, FALSE );
								pSoldier->bNextAction = AI_ACTION_WAIT;
								pSoldier->usNextActionData = 500;
								return( TRUE );
							}
						}
						pSoldier->bPathStored = TRUE;

						EVENT_GetNewSoldierPath( pSoldier, pSoldier->sAbsoluteFinalDestination, pSoldier->usUIMovementMode );
						//EVENT_GetNewSoldierPath( MercPtrs[ ubPerson ], MercPtrs[ ubPerson ]->sFinalDestination, MercPtrs[ ubPerson ]->usUIMovementMode );					
					}

				}

				// Are we close enough to give up? ( and are a pc )
				if ( pSoldier->fDelayedMovement > 20 && pSoldier->fDelayedMovement != 150)
				{
					if ( PythSpacesAway( pSoldier->sGridNo, pSoldier->sFinalDestination ) < 5 && pSoldier->bTeam == gbPlayerNum )
					{
						// Quit...
						SetFinalTile( pSoldier, pSoldier->sGridNo, FALSE );
						pSoldier->fDelayedMovement = FALSE;
					}
				}

				// Are we close enough to give up? ( and are a pc )
				if ( pSoldier->fDelayedMovement > 170 )
				{
					if ( PythSpacesAway( pSoldier->sGridNo, pSoldier->sFinalDestination ) < 5 && pSoldier->bTeam == gbPlayerNum )
					{
						// Quit...
						SetFinalTile( pSoldier, pSoldier->sGridNo, FALSE );
						pSoldier->fDelayedMovement = FALSE;
					}
				}

			}
		}
	}
	return( TRUE );
}