Ejemplo n.º 1
0
void HaltMoveForSoldierOutOfPoints(SOLDIERTYPE *pSoldier)
{
	// If a special move, ignore this!
	if ( ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_SPECIALMOVE ) )
	{
		return;
	}

	// record that this merc can no longer animate and why...
	AdjustNoAPToFinishMove( pSoldier, TRUE );

	// We'll keep his action intact though...
	DebugAI( String("NO AP TO FINISH MOVE for %d (%d APs left)",pSoldier->ubID, pSoldier->bActionPoints) );

	// if this dude is under AI right now, then pass the baton to someone else
	if (pSoldier->uiStatusFlags & SOLDIER_UNDERAICONTROL)
	{
		#ifdef TESTAICONTROL
			DebugAI( String("Ending turn for %d because out of APs for movement", pSoldier->ubID ) );
		#endif

		EndAIGuysTurn(pSoldier);
	}
}
Ejemplo n.º 2
0
int TryToResumeMovement(SOLDIERTYPE *pSoldier, INT16 sGridno)
{
	UINT8 ubGottaCancel = FALSE;
	UINT8 ubSuccess = FALSE;


	// have to make sure the old destination is still legal (somebody may
	// have occupied the destination gridno in the meantime!)
	if (LegalNPCDestination(pSoldier,sGridno,ENSURE_PATH,WATEROK,0))
	{
#ifdef DEBUGDECISIONS
		DebugAI( String( "%d CONTINUES MOVEMENT to gridno %d...\n",pSoldier->ubID,gridno ) );
#endif

		pSoldier->bPathStored = TRUE;	// optimization - Ian

		// make him go to it (needed to continue movement across multiple turns)
		NewDest(pSoldier,sGridno);

		ubSuccess = TRUE;
	 
		// make sure that it worked (check that pSoldier->sDestination == pSoldier->sGridNo)
		if (pSoldier->sDestination == sGridno)
		{
			ubSuccess = TRUE;
		}
		else
		{
#ifdef BETAVERSION
			sprintf(tempstr,"TryToResumeMovement: ERROR - NewDest failed for %s, action CANCELED",pSoldier->name);

#ifdef RECORDNET
			fprintf(NetDebugFile,"\n\t%s\n",tempstr);
#endif

			PopMessage(tempstr);
			SaveGame(ERROR_SAVE);
#endif

			// must work even for escorted civs, can't just set the flag
			CancelAIAction(pSoldier,FORCE);
		}

  }
 else
  {
		// don't black-list anything here, this situation can come up quite
		// legally if another soldier gets in the way between turns

#ifdef BETAVERSION
		sprintf(tempstr,"TryToResumeMovement: %d can't continue to gridno %d, no longer legal!",pSoldier->ubID,gridno);

#ifdef RECORDNET
		fprintf(NetDebugFile,"\n\t%s\n",tempstr);
#endif

#ifdef DEBUGDECISIONS
		AIPopMessage(tempstr);
#endif

#endif


		if (!pSoldier->bUnderEscort)
		{
			CancelAIAction(pSoldier,DONTFORCE);	// no need to force this
		}
		else
		{
			// this is an escorted NPC, don't want to just completely stop
			// moving, try to find a nearby "next best" destination if possible
			pSoldier->usActionData = GoAsFarAsPossibleTowards(pSoldier,sGridno,pSoldier->bAction);

			// if it's not possible to get any closer
			if (pSoldier->usActionData == NOWHERE)
			{
				ubGottaCancel = TRUE;
			}
			else
			{
				// change his desired destination to this new one
				sGridno = pSoldier->usActionData;

				// GoAsFar... sets pathStored TRUE only if he could go all the way

				// make him go to it (needed to continue movement across multiple turns)
				NewDest(pSoldier,sGridno);


				// make sure that it worked (check that pSoldier->sDestination == pSoldier->sGridNo)
				if (pSoldier->sDestination == sGridno)
					ubSuccess = TRUE;
				else
					ubGottaCancel = TRUE;
			}

			if (ubGottaCancel)
			{
				// can't get close, gotta abort the movement!
				CancelAIAction(pSoldier,FORCE);

				// tell the player doing the escorting that civilian has stopped
				//EscortedMoveCanceled(pSoldier,COMMUNICATE);
			}
		}
	}

	return(ubSuccess);
}
Ejemplo n.º 3
0
BUILDING * GenerateBuilding( INT16 sDesiredSpot )
{
	UINT32	uiLoop;
	INT16		sTempGridNo, sNextTempGridNo, sVeryTemporaryGridNo;
	INT16		sStartGridNo, sCurrGridNo, sPrevGridNo = NOWHERE, sRightGridNo;
	INT8		bDirection, bTempDirection;
	BOOLEAN	fFoundDir, fFoundWall;
	UINT32	uiChanceIn = ROOF_LOCATION_CHANCE; // chance of a location being considered
	INT16		sWallGridNo;
	INT8		bDesiredOrientation;
	INT8		bSkipSpots = 0;
	SOLDIERTYPE 	FakeSoldier;
	BUILDING *		pBuilding;
	UINT8					ubBuildingID = 0;

	pBuilding = CreateNewBuilding( &ubBuildingID );
	if (!pBuilding)
	{
		return( NULL );
	}

	// set up fake soldier for location testing
	memset( &FakeSoldier, 0, sizeof( SOLDIERTYPE ) );
	FakeSoldier.sGridNo = sDesiredSpot;
	FakeSoldier.bLevel = 1;
	FakeSoldier.bTeam = 1;

#ifdef ROOF_DEBUG
	memset( gsCoverValue, 0x7F, sizeof( INT16 ) * WORLD_MAX );
#endif

	// Set reachable 
	RoofReachableTest( sDesiredSpot, ubBuildingID );

	// From sGridNo, search until we find a spot that isn't part of the building
	bDirection = NORTHWEST;
	sTempGridNo = sDesiredSpot;
	// using diagonal directions to hopefully prevent picking a 
	// spot that 
	while( (gpWorldLevelData[ sTempGridNo ].uiFlags & MAPELEMENT_REACHABLE ) )
	{
		sNextTempGridNo = NewGridNo( sTempGridNo, DirectionInc( bDirection ) );
		if ( sTempGridNo == sNextTempGridNo )
		{
			// hit edge of map!??!
			return( NULL );
		}
		else
		{
			sTempGridNo = sNextTempGridNo;
		}
	} 

	// we've got our spot
	sStartGridNo = sTempGridNo;

	sCurrGridNo = sStartGridNo;
	sVeryTemporaryGridNo = NewGridNo( sCurrGridNo, DirectionInc( EAST ) );
	if ( gpWorldLevelData[ sVeryTemporaryGridNo ].uiFlags & MAPELEMENT_REACHABLE )
	{
		// go north first
		bDirection = NORTH;
	}
	else
	{
		// go that way (east)
		bDirection = EAST;
	}

	gpWorldLevelData[ sStartGridNo ].ubExtFlags[0] |= MAPELEMENT_EXT_ROOFCODE_VISITED;

	while( 1 )
	{

		// if point to (2 clockwise) is not part of building and is not visited,
		// or is starting point, turn!
		sRightGridNo = NewGridNo( sCurrGridNo, DirectionInc( gTwoCDirection[ bDirection ] ) );
		sTempGridNo = sRightGridNo;
		if ( ( ( !(gpWorldLevelData[ sTempGridNo ].uiFlags & MAPELEMENT_REACHABLE) && !(gpWorldLevelData[ sTempGridNo ].ubExtFlags[0] & MAPELEMENT_EXT_ROOFCODE_VISITED) ) || (sTempGridNo == sStartGridNo) ) && (sCurrGridNo != sStartGridNo) )
		{
			bDirection = gTwoCDirection[ bDirection ];
			// try in that direction
			continue;
		}

		// if spot ahead is part of building, turn
		sTempGridNo = NewGridNo( sCurrGridNo, DirectionInc( bDirection ) );
		if ( gpWorldLevelData[ sTempGridNo ].uiFlags & MAPELEMENT_REACHABLE )
		{
			// first search for a spot that is neither part of the building or visited

			// we KNOW that the spot in the original direction is blocked, so only loop 3 times
			bTempDirection = gTwoCDirection[ bDirection ];
			fFoundDir = FALSE;
			for ( uiLoop = 0; uiLoop < 3; uiLoop++ )
			{
				sTempGridNo = NewGridNo( sCurrGridNo, DirectionInc( bTempDirection ) );
				if ( !(gpWorldLevelData[ sTempGridNo ].uiFlags & MAPELEMENT_REACHABLE) && !(gpWorldLevelData[ sTempGridNo ].ubExtFlags[0] & MAPELEMENT_EXT_ROOFCODE_VISITED) )
				{
					// this is the way to go!
					fFoundDir = TRUE;
					break;
				}
				bTempDirection = gTwoCDirection[ bTempDirection ];
			}
			if (!fFoundDir)
			{
				// now search for a spot that is just not part of the building
				bTempDirection = gTwoCDirection[ bDirection ];
				fFoundDir = FALSE;
				for ( uiLoop = 0; uiLoop < 3; uiLoop++ )
				{
					sTempGridNo = NewGridNo( sCurrGridNo, DirectionInc( bTempDirection ) );
					if ( !(gpWorldLevelData[ sTempGridNo ].uiFlags & MAPELEMENT_REACHABLE) )
					{
						// this is the way to go!
						fFoundDir = TRUE;
						break;
					}
					bTempDirection = gTwoCDirection[ bTempDirection ];
				}
				if (!fFoundDir)
				{
					// WTF is going on?
					return( NULL );
				}
			}
			bDirection = bTempDirection;
			// try in that direction
			continue;
		}

		// move ahead
		sPrevGridNo = sCurrGridNo;
		sCurrGridNo = sTempGridNo;
		sRightGridNo = NewGridNo( sCurrGridNo, DirectionInc( gTwoCDirection[ bDirection ] ) );

#ifdef ROOF_DEBUG
		if (gsCoverValue[sCurrGridNo] == 0x7F7F)
		{
			gsCoverValue[sCurrGridNo] = 1;
		}
		else if (gsCoverValue[sCurrGridNo] >= 0)
		{
			gsCoverValue[sCurrGridNo]++;
		}

		DebugAI( String( "Roof code visits %d", sCurrGridNo ) );
#endif

		if (sCurrGridNo == sStartGridNo)
		{
			// done
			break;
		}

		if ( !(gpWorldLevelData[ sCurrGridNo ].ubExtFlags[0] & MAPELEMENT_EXT_ROOFCODE_VISITED) )
		{
			gpWorldLevelData[ sCurrGridNo ].ubExtFlags[0] |= MAPELEMENT_EXT_ROOFCODE_VISITED;

			// consider this location as possible climb gridno		
			// there must be a regular wall adjacent to this for us to consider it a 
			// climb gridno

			// if the direction is east or north, the wall would be in our gridno;
			// if south or west, the wall would be in the gridno two clockwise
			fFoundWall = FALSE;

			switch( bDirection )
			{
				case NORTH:
					sWallGridNo = sCurrGridNo;
					bDesiredOrientation = OUTSIDE_TOP_RIGHT;
					break;
				case EAST:
					sWallGridNo = sCurrGridNo;
					bDesiredOrientation = OUTSIDE_TOP_LEFT;
					break;
				case SOUTH:
					sWallGridNo = (INT16) ( sCurrGridNo + DirectionInc( gTwoCDirection[ bDirection ] ) );
					bDesiredOrientation = OUTSIDE_TOP_RIGHT;
					break;
				case WEST:
					sWallGridNo = (INT16) ( sCurrGridNo + DirectionInc( gTwoCDirection[ bDirection ] ) );
					bDesiredOrientation = OUTSIDE_TOP_LEFT;
					break;
				default:
					// what the heck?
					return( NULL );
			}

			if (bDesiredOrientation == OUTSIDE_TOP_LEFT)
			{
				if (WallExistsOfTopLeftOrientation( sWallGridNo ))
				{
					fFoundWall = TRUE;
				}
			}
			else 
			{
				if (WallExistsOfTopRightOrientation( sWallGridNo ))
				{
					fFoundWall = TRUE;
				}
			}

			if (fFoundWall)
			{
				if (bSkipSpots > 0)
				{
					bSkipSpots--;
				}
				else if ( Random( uiChanceIn ) == 0 )
				{		
					// don't consider people as obstacles
					if ( NewOKDestination( &FakeSoldier, sCurrGridNo, FALSE, 0 ) )
					{
						pBuilding->sUpClimbSpots[ pBuilding->ubNumClimbSpots ] = sCurrGridNo;
						pBuilding->sDownClimbSpots[ pBuilding->ubNumClimbSpots ] = sRightGridNo;
						pBuilding->ubNumClimbSpots++;

						if ( pBuilding->ubNumClimbSpots == MAX_CLIMBSPOTS_PER_BUILDING)
						{
							// gotta stop!
							return( pBuilding );
						}

						// if location is added as a spot, reset uiChanceIn
						uiChanceIn = ROOF_LOCATION_CHANCE;
#ifdef ROOF_DEBUG
						gsCoverValue[sCurrGridNo] = 99;
#endif
						// skip the next spot
						bSkipSpots = 1;
					}
					else
					{
						// if location is not added, 100% chance of handling next location
						// and the next until we can add one
						uiChanceIn = 1;					
	
					}
				}
				else
				{
					// didn't pick this location, so increase chance that next location 
					// will be considered
					if (uiChanceIn > 2)
					{
						uiChanceIn--;
					}
				}

			}
			else
			{
				// can't select this spot
				if ( (sPrevGridNo != NOWHERE) && (pBuilding->ubNumClimbSpots > 0) )
				{
					if ( pBuilding->sDownClimbSpots[ pBuilding->ubNumClimbSpots - 1 ] == sCurrGridNo )
					{
						// unselect previous spot
						pBuilding->ubNumClimbSpots--;
						// overwrote a selected spot so go into automatic selection for later
						uiChanceIn = 1;
#ifdef ROOF_DEBUG
						// reset marker
						gsCoverValue[sPrevGridNo] = 1;
#endif
					}
				}

				// skip the next gridno
				bSkipSpots = 1;
			}

		}

	}

	// at end could prune # of locations if there are too many

/*
#ifdef ROOF_DEBUG
	SetRenderFlags( RENDER_FLAG_FULL );
	RenderWorld();
	RenderCoverDebug( );
	InvalidateScreen( );
	EndFrameBufferRender();
	RefreshScreen( NULL );
#endif
*/

	return( pBuilding );
}