예제 #1
0
BOOLEAN FindAutobandageClimbPoint( INT32 sDesiredGridNo, BOOLEAN fClimbUp )
{
	// checks for existance of location to climb up to building, not occupied by a medic
	BUILDING *	pBuilding;
	UINT8				ubNumClimbSpots;
	UINT8 ubLoop;
	UINT8				ubWhoIsThere;

	pBuilding = FindBuilding( sDesiredGridNo );
	if (!pBuilding)
	{
		return( FALSE );
	}

	ubNumClimbSpots = pBuilding->ubNumClimbSpots;

	for ( ubLoop = 0; ubLoop < ubNumClimbSpots; ubLoop++ )
	{
		ubWhoIsThere = WhoIsThere2( pBuilding->sUpClimbSpots[ ubLoop ], 1 );
		if ( ubWhoIsThere != NOBODY && !CanCharacterAutoBandageTeammate( MercPtrs[ ubWhoIsThere ] ) )
		{
			continue;
		}
		ubWhoIsThere = WhoIsThere2( pBuilding->sDownClimbSpots[ ubLoop ], 0 );
		if ( ubWhoIsThere != NOBODY && !CanCharacterAutoBandageTeammate( MercPtrs[ ubWhoIsThere ] ) )
		{
			continue;
		}
		return( TRUE );
	}

	return( FALSE );
}
예제 #2
0
BOOLEAN CheckOnBoxers( void )
{
	UINT32					uiLoop;
	UINT8						ubID;

	// repick boxer IDs every time
	if ( gubBoxerID[0] == NOBODY )
	{
		// get boxer soldier IDs!
		for( uiLoop = 0; uiLoop < NUM_BOXERS; uiLoop++ )
		{
			ubID = WhoIsThere2( gsBoxerGridNo[ uiLoop ], 0 );

			// WANNE: Safty check!
			if (ubID < TOTAL_SOLDIERS)
			{
				if ( FindObjClass( MercPtrs[ ubID ], IC_WEAPON ) == NO_SLOT &&
					IS_MERC_BODY_TYPE( MercPtrs[ ubID ] ) )
				{
					// no weapon and not a civilian so this guy is a boxer
					gubBoxerID[ uiLoop ] = ubID;
				}
			}
		}
	}

	if ( gubBoxerID[ 0 ] == NOBODY && gubBoxerID[ 1 ] == NOBODY && gubBoxerID[ 2 ] == NOBODY )
	{
		return( FALSE );
	}

	return( TRUE );
}
예제 #3
0
BOOLEAN IsRepairableStructAtGridNo( INT16 sGridNo, UINT8 *pubID )
{
	UINT8 ubMerc;

	// OK, first look for a vehicle....
	ubMerc = WhoIsThere2( sGridNo, 0 );

	if ( pubID != NULL )
	{
		(*pubID) = ubMerc;
	}

	if ( ubMerc != NOBODY )
	{
		if ( MercPtrs[ ubMerc ]->uiStatusFlags & SOLDIER_VEHICLE )
		{
			return( 2 );
		}
	}
	// Then for over a robot....

	// then for SAM site....
	if ( DoesSAMExistHere( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, sGridNo ) )
	{
		return( 3 );
	}


	return( FALSE );
}
예제 #4
0
void SearchForOtherMembersWithinPitRadiusAndMakeThemFall( INT16 sGridNo, INT16 sRadius )
{
	INT16 x, y, sNewGridNo;
	UINT8	ubID;
	SOLDIERTYPE *pSoldier;


	PlayJA2Sample( CAVE_COLLAPSE, RATE_11025, SoundVolume( HIGHVOLUME, sGridNo ), 1, SoundDir( sGridNo ) );
	for( y = -sRadius; y <= sRadius; y++ ) for( x = -sRadius; x <= sRadius; x++ )
	{
		sNewGridNo = sGridNo + y * WORLD_COLS + x;
		//Validate gridno location, and check if there are any mercs here.  If there are
		//any mercs, we want them to fall below.  The exitgrid already exists at this location
		if( GridNoOnVisibleWorldTile( sNewGridNo ) )
		{

			// Check if buddy exists here.....
			ubID = WhoIsThere2( sNewGridNo, 0 );

			if ( ubID != NOBODY )
			{
				// OK, make guy fall...
				// Set data to look for exit grid....
				pSoldier = MercPtrs[ ubID ];

				pSoldier->uiPendingActionData4 = sNewGridNo;

				EVENT_InitNewSoldierAnim( pSoldier, FALL_INTO_PIT, 0 , FALSE );
			}			
		}
	}
}
예제 #5
0
void OutputDebugInfoForTurnBasedNextTileWaiting( SOLDIERTYPE * pSoldier )
{
	if ( (gTacticalStatus.uiFlags & INCOMBAT) && (pSoldier->usPathDataSize > 0) )
	{
		UINT32	uiLoop;
		UINT16	usTemp;
		UINT16	usNewGridNo;

		usNewGridNo = NewGridNo( pSoldier->sGridNo, DirectionInc( (UINT8)pSoldier->usPathingData[ pSoldier->usPathIndex ] ) );

		// provide more info!!
		DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("  Soldier path size %d, index %d", pSoldier->usPathDataSize, pSoldier->usPathIndex ) );
		DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("  Who is at blocked gridno: %d", WhoIsThere2( usNewGridNo, pSoldier->bLevel ) ) );

		for ( uiLoop = 0; uiLoop < pSoldier->usPathDataSize; uiLoop++ )
		{
			if ( uiLoop > pSoldier->usPathIndex )
			{					
				usTemp = NewGridNo( usTemp, DirectionInc( (UINT8)pSoldier->usPathingData[ uiLoop ] ) );
				DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("  Soldier path[%d]: %d == gridno %d", uiLoop, pSoldier->usPathingData[uiLoop], usTemp ) );
			}
			else if ( uiLoop == pSoldier->usPathIndex )
			{
				usTemp = usNewGridNo;
				DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("  Soldier path[%d]: %d == gridno %d", uiLoop, pSoldier->usPathingData[uiLoop], usTemp ) );
			}
			else
			{
				DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("  Soldier path[%d]: %d", uiLoop, pSoldier->usPathingData[uiLoop] ) );
			}
		}

	}
}
예제 #6
0
void SetDelayedTileWaiting( SOLDIERTYPE *pSoldier, INT16 sCauseGridNo, INT8 bValue )
{
	UINT8		ubPerson;

	// Cancel AI Action
	// CancelAIAction( pSoldier, TRUE );

	pSoldier->fDelayedMovement = bValue;
	pSoldier->sDelayedMovementCauseGridNo = sCauseGridNo;

	RESETTIMECOUNTER( pSoldier->NextTileCounter, NEXT_TILE_CHECK_DELAY );

	// ATE: Now update realtime movement speed....
	// check if guy exists here...
	ubPerson = WhoIsThere2( sCauseGridNo, pSoldier->bLevel );

	// There may not be anybody there, but it's reserved by them!
	if ( ( gpWorldLevelData[ sCauseGridNo ].uiFlags & MAPELEMENT_MOVEMENT_RESERVED ) )
	{
		ubPerson = gpWorldLevelData[ sCauseGridNo ].ubReservedSoldierID;
	}

	if ( ubPerson != NOBODY )
	{
		// if they are our own team members ( both )
		if ( MercPtrs[ ubPerson ]->bTeam == gbPlayerNum && pSoldier->bTeam == gbPlayerNum )
		{
			// Here we have another guy.... save his stats so we can use them for
			// speed determinations....
			pSoldier->bOverrideMoveSpeed = ubPerson;
			pSoldier->fUseMoverrideMoveSpeed = TRUE;
		}
	}
}
예제 #7
0
INT16 FindClosestClimbPoint( INT16 sStartGridNo, INT16 sDesiredGridNo, BOOLEAN fClimbUp )
{
	BUILDING *	pBuilding;
	UINT8				ubNumClimbSpots;
	INT16 *			psClimbSpots;
	UINT8				ubLoop;
	INT16				sDistance, sClosestDistance = 1000, sClosestSpot= NOWHERE;

	pBuilding = FindBuilding( sDesiredGridNo );
	if (!pBuilding)
	{
		return( NOWHERE );
	}

	ubNumClimbSpots = pBuilding->ubNumClimbSpots;

	if (fClimbUp)
	{
		psClimbSpots = pBuilding->sUpClimbSpots;
	}
	else
	{
		psClimbSpots = pBuilding->sDownClimbSpots;
	}

	for ( ubLoop = 0; ubLoop < ubNumClimbSpots; ubLoop++ )
	{
		if ( (WhoIsThere2( pBuilding->sUpClimbSpots[ ubLoop ], 0 ) == NOBODY)
			&& (WhoIsThere2( pBuilding->sDownClimbSpots[ ubLoop ], 1 ) == NOBODY) )
		{
			sDistance = PythSpacesAway( sStartGridNo, psClimbSpots[ ubLoop ] );
			if (sDistance < sClosestDistance )
			{
				sClosestDistance = sDistance;
				sClosestSpot = psClimbSpots[ ubLoop ];
			}
		}
	}

	return( sClosestSpot );
}
예제 #8
0
BOOLEAN BoxerExists( void )
{
	UINT32	uiLoop;

	for( uiLoop = 0; uiLoop < NUM_BOXERS; ++uiLoop )
	{
		if ( WhoIsThere2( gsBoxerGridNo[ uiLoop ], 0 ) != NOBODY )
		{
			return( TRUE );
		}
	}
	return( FALSE );
}
예제 #9
0
void
SkillSelection::Functions( UINT32 aVal )
{
	Cancel();

	SOLDIERTYPE * pSoldier = NULL;

	GetSoldier( &pSoldier, gusSelectedSoldier );

	if ( pSoldier == NULL )
		return;
	
	UINT8 ubID = WhoIsThere2(sTraitsMenuTargetGridNo, 0 );

	pSoldier->UseSkill(aVal, sTraitsMenuTargetGridNo, ubID);
		
	Cancel();
	gTraitSelection.Cancel();
}
예제 #10
0
BOOLEAN IsRefuelableStructAtGridNo( INT16 sGridNo, UINT8 *pubID )
{
	UINT8 ubMerc;

	// OK, first look for a vehicle....
	ubMerc = WhoIsThere2( sGridNo, 0 );

	if ( pubID != NULL )
	{
		(*pubID) = ubMerc;
	}

	if ( ubMerc != NOBODY )
	{
		if ( MercPtrs[ ubMerc ]->uiStatusFlags & SOLDIER_VEHICLE )
		{
			return( TRUE );
		}
	}
	return( FALSE );
}
예제 #11
0
INT8 FindBestPatient( SOLDIERTYPE * pSoldier, BOOLEAN * pfDoClimb )
{
	UINT8						cnt, cnt2;
	INT32						bBestPriority = 0, sBestAdjGridNo = NOWHERE;
	INT32						sPatientGridNo = NOWHERE, sBestPatientGridNo = NOWHERE;
	INT16						sShortestPath = 1000, sPathCost, sOtherMedicPathCost;
	SOLDIERTYPE *		pPatient;
	SOLDIERTYPE *		pBestPatient = NULL;
	SOLDIERTYPE *		pOtherMedic;
	INT8						bPatientPriority;
	UINT8						ubDirection;
	INT32 sAdjustedGridNo, sAdjacentGridNo, sOtherAdjacentGridNo;
	INT32						sClimbGridNo, sBestClimbGridNo = NOWHERE, sShortestClimbPath = 1000;
	BOOLEAN					fClimbingNecessary;

	gubGlobalPathFlags = PATH_THROUGH_PEOPLE;

	// search for someone who needs aid
	cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
	for ( pPatient = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; cnt++,pPatient++)
	{
		if ( !(pPatient->bActive) || !(pPatient->bInSector) )
		{
			continue; // NEXT!!!
		}

		if (pPatient->stats.bLife > 0 && pPatient->bBleeding && pPatient->ubServiceCount == 0)
		{
			if (pPatient->stats.bLife < OKLIFE)
			{
				bPatientPriority = 3;
			}
			else if (pPatient->stats.bLife < OKLIFE * 2)
			{
				bPatientPriority = 2;
			}
			else
			{
				bPatientPriority = 1;
			}

			if (bPatientPriority >= bBestPriority)
			{
				if ( !ClimbingNecessary( pSoldier, pPatient->sGridNo, pPatient->pathing.bLevel ) )
				{

					sPatientGridNo = pPatient->sGridNo;
					sAdjacentGridNo = FindAdjacentGridEx( pSoldier, sPatientGridNo, &ubDirection, &sAdjustedGridNo, FALSE, FALSE );
					if ( sAdjacentGridNo == -1 && gAnimControl[ pPatient->usAnimState ].ubEndHeight == ANIM_PRONE )
					{
						// prone; could be the base tile is inaccessible but the rest isn't...
						for ( cnt2 = 0; cnt2 < NUM_WORLD_DIRECTIONS; cnt2++ )
						{
							sPatientGridNo = pPatient->sGridNo + DirectionInc( cnt2 );
							if ( WhoIsThere2( sPatientGridNo, pPatient->pathing.bLevel ) == pPatient->ubID )
							{
								// patient is also here, try this location
								sAdjacentGridNo = FindAdjacentGridEx( pSoldier, sPatientGridNo, &ubDirection, &sAdjustedGridNo, FALSE, FALSE );
								if ( sAdjacentGridNo != -1 )
								{
									break;
								}
							}
						}
					}

					if (sAdjacentGridNo != -1)
					{
						if (sAdjacentGridNo == pSoldier->sGridNo)
						{
							sPathCost = 1;
						}
						else
						{
							sPathCost = PlotPath( pSoldier, sAdjacentGridNo, FALSE, FALSE, FALSE, RUNNING, FALSE, FALSE, 0);
						}

						if ( sPathCost != 0 )
						{
							// we can get there... can anyone else?

							if ( pPatient->ubAutoBandagingMedic != NOBODY && pPatient->ubAutoBandagingMedic != pSoldier->ubID )
							{
								// only switch to this patient if our distance is closer than
								// the other medic's
								pOtherMedic = MercPtrs[ pPatient->ubAutoBandagingMedic ];
								sOtherAdjacentGridNo = FindAdjacentGridEx( pOtherMedic, sPatientGridNo, &ubDirection, &sAdjustedGridNo, FALSE, FALSE );
								if (sOtherAdjacentGridNo != -1)
								{

									if (sOtherAdjacentGridNo == pOtherMedic->sGridNo)
									{
										sOtherMedicPathCost = 1;
									}
									else
									{
										sOtherMedicPathCost = PlotPath( pOtherMedic, sOtherAdjacentGridNo, FALSE, FALSE, FALSE, RUNNING, FALSE, FALSE, 0);
									}

									if (sPathCost >= sOtherMedicPathCost)
									{
										// this patient is best served by the merc moving to them now
										continue;
									}
								}
							}

							if (bPatientPriority == bBestPriority)
							{
								// compare path distances
								if ( sPathCost > sShortestPath )
								{
									continue;
								}
							}


							sShortestPath = sPathCost;
							pBestPatient = pPatient;
							sBestPatientGridNo = sPatientGridNo;
							bBestPriority = bPatientPriority;
							sBestAdjGridNo = sAdjacentGridNo;

						}
					}

				}
				else
				{
					sClimbGridNo = NOWHERE;
					// see if guy on another building etc and we need to climb somewhere
					sPathCost = EstimatePathCostToLocation( pSoldier, pPatient->sGridNo, pPatient->pathing.bLevel, FALSE, &fClimbingNecessary, &sClimbGridNo );
					// if we can get there
					if ( sPathCost != 0 && fClimbingNecessary && sPathCost < sShortestClimbPath )
					{
						sBestClimbGridNo = sClimbGridNo;
						sShortestClimbPath = sPathCost;
					}

				}

			}

		}
	}

	gubGlobalPathFlags = 0;

	if (pBestPatient)
	{
		if (pBestPatient->ubAutoBandagingMedic != NOBODY)
		{
			// cancel that medic
			CancelAIAction( MercPtrs[ pBestPatient->ubAutoBandagingMedic ], TRUE );
		}
		pBestPatient->ubAutoBandagingMedic = pSoldier->ubID;
		*pfDoClimb = FALSE;
		if ( CardinalSpacesAway( pSoldier->sGridNo, sBestPatientGridNo ) == 1 )
		{
			pSoldier->aiData.usActionData = sBestPatientGridNo;
			return( AI_ACTION_GIVE_AID );
		}
		else
		{
			pSoldier->aiData.usActionData = sBestAdjGridNo;
			return( AI_ACTION_GET_CLOSER );
		}
	}	
	else if (!TileIsOutOfBounds(sBestClimbGridNo))
	{
		*pfDoClimb = TRUE;
		pSoldier->aiData.usActionData = sBestClimbGridNo;
		return( AI_ACTION_MOVE_TO_CLIMB );
	}
	else
	{
		return( AI_ACTION_NONE );
	}
}
예제 #12
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 );
}
예제 #13
0
INT8 TileIsClear( SOLDIERTYPE *pSoldier, INT8 bDirection,  INT16 sGridNo, INT8 bLevel )
{
	UINT8		ubPerson;
	INT16		sTempDestGridNo;
	INT16		sNewGridNo;
	BOOLEAN	fSwapInDoor = FALSE;

	if ( sGridNo == NOWHERE )
	{
		return( MOVE_TILE_CLEAR );
	}

	ubPerson = WhoIsThere2( sGridNo, bLevel );


	if ( ubPerson != NO_SOLDIER )
	{
		// If this us?
		if ( ubPerson != pSoldier->ubID )
		{
			// OK, set flag indicating we are blocked by a merc....
			if ( pSoldier->bTeam != gbPlayerNum ) // CJC: shouldn't this be in all cases???
		//if ( 0 )
			{
				pSoldier->fBlockedByAnotherMerc = TRUE;
				// Set direction we were trying to goto
				pSoldier->bBlockedByAnotherMercDirection = bDirection;

				// Are we only temporarily blocked?
				// Check if our final destination is = our gridno
				if ( ( MercPtrs[ ubPerson ]->sFinalDestination == MercPtrs[ ubPerson ]->sGridNo )  )
				{
					return( MOVE_TILE_STATIONARY_BLOCKED );
				}
				else
				{
					// OK, if buddy who is blocking us is trying to move too...
					// And we are in opposite directions...
					if ( MercPtrs[ ubPerson ]->fBlockedByAnotherMerc && MercPtrs[ ubPerson ]->bBlockedByAnotherMercDirection == gOppositeDirection[ bDirection ] )
					{
						// OK, try and get a path around buddy....
						// We have to temporarily make buddy stopped...
						sTempDestGridNo = MercPtrs[ ubPerson ]->sFinalDestination;
						MercPtrs[ ubPerson ]->sFinalDestination = MercPtrs[ ubPerson ]->sGridNo;

						if ( PlotPath( pSoldier, pSoldier->sFinalDestination, NO_COPYROUTE, NO_PLOT, TEMPORARY, pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints ) )
						{
							pSoldier->bPathStored = FALSE;
							// OK, make guy go here...
							EVENT_GetNewSoldierPath( pSoldier, pSoldier->sFinalDestination, pSoldier->usUIMovementMode );
							// Restore final dest....
							MercPtrs[ ubPerson ]->sFinalDestination = sTempDestGridNo;
							pSoldier->fBlockedByAnotherMerc = FALSE;

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

							return( TileIsClear( pSoldier, (UINT8)guiPathingData[ 0 ], sNewGridNo, pSoldier->bLevel ) );
						} 
						else
						{

								// Not for multi-tiled things...
								if ( !( pSoldier->uiStatusFlags & SOLDIER_MULTITILE ) )
								{
									// Is the next movement cost for a door?
									if ( DoorTravelCost( pSoldier, sGridNo, gubWorldMovementCosts[ sGridNo ][ bDirection ][ pSoldier->bLevel ], (BOOLEAN)( pSoldier->bTeam == gbPlayerNum ), NULL ) == TRAVELCOST_DOOR )
									{
										fSwapInDoor = TRUE;
									}

									// If we are to swap and we're near a door, open door first and then close it...?


									// 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, they should try and continue on their way....
									// Start them both again along their way...
									EVENT_GetNewSoldierPath( pSoldier, pSoldier->sFinalDestination, pSoldier->usUIMovementMode );
									EVENT_GetNewSoldierPath( MercPtrs[ ubPerson ], MercPtrs[ ubPerson ]->sFinalDestination, MercPtrs[ ubPerson ]->usUIMovementMode );					
								}
						}
					}
					return( MOVE_TILE_TEMP_BLOCKED );
				}
			}
			else
			{
				//return( MOVE_TILE_STATIONARY_BLOCKED );
				// ATE: OK, put some smartshere...
				// If we are waiting for more than a few times, change to stationary...
				if ( MercPtrs[ ubPerson ]->fDelayedMovement >= 105 )
				{
					// Set to special 'I want to walk through people' value
					pSoldier->fDelayedMovement = 150;

					return( MOVE_TILE_STATIONARY_BLOCKED );
				}
				if ( MercPtrs[ ubPerson ]->sGridNo == MercPtrs[ ubPerson ]->sFinalDestination )
				{
					return( MOVE_TILE_STATIONARY_BLOCKED );
				}
				return( MOVE_TILE_TEMP_BLOCKED );
			}
		}
	}

	if ( ( gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_MOVEMENT_RESERVED ) )
	{
		if ( gpWorldLevelData[ sGridNo ].ubReservedSoldierID != pSoldier->ubID )
		{
			return( MOVE_TILE_TEMP_BLOCKED );
		}
	}

	// Are we clear of structs?
	if ( !NewOKDestination( pSoldier, sGridNo, FALSE, pSoldier->bLevel ) )
	{
			// ATE: Fence cost is an exclusiuon here....
			if ( gubWorldMovementCosts[ sGridNo ][ bDirection ][ pSoldier->bLevel ] != TRAVELCOST_FENCE )
			{
				// ATE: HIdden structs - we do something here... reveal it!
				if ( gubWorldMovementCosts[ sGridNo ][ bDirection ][ pSoldier->bLevel ] == TRAVELCOST_HIDDENOBSTACLE )
				{
					gpWorldLevelData[ sGridNo ].uiFlags|=MAPELEMENT_REVEALED;
					gpWorldLevelData[ sGridNo ].uiFlags|=MAPELEMENT_REDRAW;
					SetRenderFlags(RENDER_FLAG_MARKED);
					RecompileLocalMovementCosts( (UINT16)sGridNo );
				}

				// Unset flag for blocked by soldier...
				pSoldier->fBlockedByAnotherMerc = FALSE;
				return( MOVE_TILE_STATIONARY_BLOCKED );
			}
			else
			{
#if 0
				// Check if there is a reserved marker here at least....
				sNewGridNo = NewGridNo( sGridNo, DirectionInc( bDirection ) );

				if ( ( gpWorldLevelData[ sNewGridNo ].uiFlags & MAPELEMENT_MOVEMENT_RESERVED ) )
				{
					if ( gpWorldLevelData[ sNewGridNo ].ubReservedSoldierID != pSoldier->ubID )
					{
						return( MOVE_TILE_TEMP_BLOCKED );
					}
				}
#endif
			}
	}

	// Unset flag for blocked by soldier...
	pSoldier->fBlockedByAnotherMerc = FALSE;

	return( MOVE_TILE_CLEAR );

}