Example #1
0
void HandleBulletSpecialFlags( INT32 iBulletIndex )
{
	BULLET		*pBullet;
	ANITILE_PARAMS	AniParams;
	FLOAT		dX, dY;
	UINT8		ubDirection;

	pBullet = &( gBullets[ iBulletIndex ] );

	memset( &AniParams, 0, sizeof( ANITILE_PARAMS ) );

	if ( pBullet->fReal )
	{
		// Create ani tile if this is a spit!
		if ( pBullet->usFlags & ( BULLET_FLAG_KNIFE ) )
		{
			AniParams.sGridNo							= pBullet->sGridNo;
			AniParams.ubLevelID						= ANI_STRUCT_LEVEL;
			AniParams.sDelay							= 100;
			AniParams.sStartFrame					= 3;
			AniParams.uiFlags							= ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_LOOPING | ANITILE_USE_DIRECTION_FOR_START_FRAME;
			AniParams.sX									= FIXEDPT_TO_INT32( pBullet->qCurrX );
			AniParams.sY									= FIXEDPT_TO_INT32( pBullet->qCurrY );
			AniParams.sZ									= CONVERT_HEIGHTUNITS_TO_PIXELS( FIXEDPT_TO_INT32( pBullet->qCurrZ ) );

			if ( pBullet->usFlags & ( BULLET_FLAG_CREATURE_SPIT ) )
			{
				strcpy( AniParams.zCachedFile, "TILECACHE\\SPIT2.STI" );
			}
			else if ( pBullet->usFlags & ( BULLET_FLAG_KNIFE ) )
			{
				strcpy( AniParams.zCachedFile, "TILECACHE\\KNIFING.STI" );
				pBullet->ubItemStatus = pBullet->pFirer->inv[ HANDPOS ][0]->data.objectStatus;
			}

			// Get direction to use for this guy....
			dX = ( (FLOAT)( pBullet->qIncrX ) / FIXEDPT_FRACTIONAL_RESOLUTION );
			dY = ( (FLOAT)( pBullet->qIncrY ) / FIXEDPT_FRACTIONAL_RESOLUTION );

			ubDirection = atan8( 0, 0, (INT16)( dX * 100 ), (INT16)( dY * 100 ) );

			AniParams.uiUserData3					= ubDirection;

			pBullet->pAniTile = CreateAnimationTile( &AniParams );

			// IF we are anything that needs a shadow.. set it here....
			if ( pBullet->usFlags & ( BULLET_FLAG_KNIFE ) )
			{
				AniParams.ubLevelID						= ANI_SHADOW_LEVEL;
				AniParams.sZ									= 0;
				pBullet->pShadowAniTile				= CreateAnimationTile( &AniParams );
			}

		}
	}
}
Example #2
0
INT16 TrackScent( SOLDIERTYPE * pSoldier )
{
	// This function returns the best gridno to go to based on the scent being followed,
	// and the soldier (creature/animal)'s current direction (which is used to resolve
	// ties.
	INT32						iXDiff, iYDiff, iXIncr;
	INT32						iStart, iXStart, iYStart;
	INT32						iGridNo;
	INT8						bDir;
	INT32						iBestGridNo = NOWHERE;
	UINT8						ubBestDirDiff = 5, ubBestStrength = 0;
	UINT8						ubDirDiff, ubStrength;
	UINT8						ubSoughtSmell;
	MAP_ELEMENT *		pMapElement;

	iStart = pSoldier->sGridNo;
	iXStart = iStart % WORLD_COLS;
	iYStart = iStart / WORLD_COLS;

	if (CREATURE_OR_BLOODCAT( pSoldier ) ) // or bloodcats
	{
		// tracking humans; search the edges of a 7x7 square for the 
		// most promising tile
		ubSoughtSmell = HUMAN;
		for (iYDiff = -RADIUS; iYDiff < (RADIUS + 1); iYDiff++)
		{
			if (iYStart + iYDiff < 0)
			{
				// outside of map! might be on map further down...
				continue;
			}
			else if (iYStart + iYDiff > WORLD_ROWS)
			{
				// outside of bottom of map! abort!
				break;
			}
			if (iYDiff == -RADIUS || iYDiff == RADIUS)
			{
				iXIncr = 1;
			}
			else
			{
				// skip over the spots in the centre of the square
				iXIncr = RADIUS * 2;
			}
			for (iXDiff = -RADIUS; iXDiff < (RADIUS + 1); iXDiff += iXIncr)
			{
				iGridNo = iStart + iXDiff + iYDiff * WORLD_ROWS;
				if (abs( iGridNo % WORLD_ROWS - iXStart ) > RADIUS)
				{
					// wrapped across map!
					continue;
				}
				if (LegalNPCDestination(pSoldier,pSoldier->usActionData,ENSURE_PATH,WATEROK,0))
				{
					// check this location out
					pMapElement = &(gpWorldLevelData[iGridNo]);
					if (pMapElement->ubSmellInfo && (SMELL_TYPE( pMapElement->ubSmellInfo ) == ubSoughtSmell))
					{
						ubStrength = SMELL_STRENGTH( pMapElement->ubSmellInfo );
						if (ubStrength > ubBestStrength )
						{
							iBestGridNo = iGridNo;
							ubBestStrength = ubStrength;
							bDir = atan8( (INT16) iXStart, (INT16) iYStart, (INT16) (iXStart + iXDiff), (INT16) (iYStart + iYDiff) );
							// now convert it into a difference in degree between it and our current dir
							ubBestDirDiff = abs( pSoldier->bDirection - bDir );
							if (ubBestDirDiff > 4 ) // dir 0 compared with dir 6, for instance
							{
								ubBestDirDiff = 8 - ubBestDirDiff;
							}
						}
						else if (ubStrength == ubBestStrength)
						{
							if (iBestGridNo == NOWHERE)
							{
								// first place we've found with the same strength
								iBestGridNo = iGridNo;
								ubBestStrength = ubStrength;
							}
							else
							{
								// use directions to decide between the two
								// start by calculating direction to the new gridno
								bDir = atan8( (INT16) iXStart, (INT16) iYStart, (INT16) (iXStart + iXDiff), (INT16) (iYStart + iYDiff) );
								// now convert it into a difference in degree between it and our current dir
								ubDirDiff = abs( pSoldier->bDirection - bDir );
								if (ubDirDiff > 4 ) // dir 0 compared with dir 6, for instance
								{
									ubDirDiff = 8 - ubDirDiff;
								}
								if (ubDirDiff < ubBestDirDiff || ((ubDirDiff == ubBestDirDiff) && Random( 2 )))
								{
									// follow this trail as its closer to the one we're following!
									// (in the case of a tie, we tossed a coin)
									ubBestDirDiff = ubDirDiff;

								}
							}
						}	
					}
				}
			}
			// go on to next tile
		}
		// go on to next row
	}
	else
	{
		// who else can track? 
	}
	if (iBestGridNo != NOWHERE )
	{
		pSoldier->usActionData = (INT16) iBestGridNo;
		return( (INT16) iBestGridNo );
	}
	return( 0 );
}