Exemplo n.º 1
0
void RemoveBullet( INT32 iBullet )
{
	CHECKV( iBullet < NUM_BULLET_SLOTS );

	//afp-start
	// remove any tail first if exists
	for (int i = 0; i < BULLET_TRACER_MAX_LENGTH; i++)
		if (gBullets[iBullet].pNodes[i] != NULL)
		{
			RemoveStructFromLevelNode(gBullets[ iBullet ].sGridNo, gBullets[iBullet].pNodes[i]);
			gBullets[iBullet].pNodes[i] = NULL;
		}
	//afp-end
	// decrease soldier's bullet count

	if (gBullets[ iBullet ].fReal)
	{
		// set to be deleted at next update
		gBullets[ iBullet ].fToDelete = TRUE;

		// decrement reference to bullet in the firer
//		gBullets[ iBullet ].pFirer->bBulletsLeft--;
//		DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("!!!!!!! Ending bullet, bullets left %d", gBullets[ iBullet ].pFirer->bBulletsLeft ) );
//		DebugAttackBusy( String( "Deleting a bullet for %d.	Total count now %d\n", gBullets[ iBullet].ubFirerID, gBullets[ iBullet ].pFirer->bBulletsLeft) );
		// Nah, just decrement the attack busy count and be done with it
		DebugAttackBusy( String( "Deleting a bullet for %d.\n", gBullets[ iBullet].ubFirerID ) );
		// HEADROCK HAM 5: Fragments do not need reducing.
		if (gBullets[iBullet].fFragment == false)
		{
			ReduceAttackBusyCount( );
		}

		// if ( gBullets[ iBullet ].usFlags & ( BULLET_FLAG_KNIFE ) )
		// {
		// Delete ani tile
		if ( gBullets[ iBullet ].pAniTile != NULL )
		{
			DeleteAniTile( gBullets[ iBullet ].pAniTile );
			gBullets[ iBullet ].pAniTile = NULL;
		}

		// Delete shadow
		// if ( gBullets[ iBullet ].usFlags & ( BULLET_FLAG_KNIFE ) )
		// {
		if ( gBullets[ iBullet ].pShadowAniTile != NULL )
		{
			DeleteAniTile( gBullets[ iBullet ].pShadowAniTile );
			gBullets[ iBullet ].pShadowAniTile = NULL;
		}
//	}
//		}
	}
	else
	{
		// delete this fake bullet right away!
		gBullets[ iBullet ].fAllocated = FALSE;
		RecountBullets();
	}
}
Exemplo n.º 2
0
void UpdateBullets( )
{
	UINT32					uiCount;
	LEVELNODE				*pNode;
	BOOLEAN					fDeletedSome = FALSE;

	for ( uiCount = 0; uiCount < guiNumBullets; uiCount++ )
	{
		if ( gBullets[ uiCount ].fAllocated)
		{
			if (gBullets[ uiCount ].fReal && !( gBullets[ uiCount ].usFlags & BULLET_STOPPED ) )
			{
				// there are duplicate checks for deletion in case the bullet is deleted by shooting
				// someone at point blank range, in the first MoveBullet call in the FireGun code
				if ( gBullets[ uiCount ].fToDelete )
				{
					// Remove from old position
					gBullets[ uiCount ].fAllocated = FALSE;
					fDeletedSome = TRUE;
					continue;
				}

				//if ( !( gGameSettings.fOptions[ TOPTION_HIDE_BULLETS ] ) )
				{
					// ALRIGHTY, CHECK WHAT TYPE OF BULLET WE ARE

					if ( gBullets[ uiCount ].usFlags & ( BULLET_FLAG_CREATURE_SPIT | BULLET_FLAG_KNIFE | BULLET_FLAG_MISSILE | BULLET_FLAG_SMALL_MISSILE | BULLET_FLAG_TANK_CANNON | BULLET_FLAG_FLAME /*| BULLET_FLAG_TRACER*/ ) )
					{
					}
					else
					{
						RemoveStruct( gBullets[ uiCount ].sGridNo, BULLETTILE1 );
						RemoveStruct( gBullets[ uiCount ].sGridNo, BULLETTILE2 );
					}
				}
				//afp-start
				// remove old tail first if exists
				FIXEDPT lastX = gBullets[uiCount].qCurrX;
				FIXEDPT lastY = gBullets[uiCount].qCurrY;
				FIXEDPT lastZ = gBullets[uiCount].qCurrZ;
				for (int i = 0; i < BULLET_TRACER_MAX_LENGTH; i++)
					if (gBullets[uiCount].pNodes[i] != NULL)
					{
						RemoveStructFromLevelNode(gBullets[ uiCount ].sGridNo, gBullets[uiCount].pNodes[i]);
						gBullets[uiCount].pNodes[i] = NULL;
					}
				//afp-end

				MoveBullet( uiCount );
				if ( gBullets[ uiCount ].fToDelete )
				{
					// Remove from old position
					gBullets[ uiCount ].fAllocated = FALSE;
					fDeletedSome = TRUE;
					continue;
				}

				if ( gBullets[ uiCount ].usFlags & BULLET_STOPPED )
				{
					continue;
				}

				// Display bullet
				//if ( !( gGameSettings.fOptions[ TOPTION_HIDE_BULLETS ] ) )
				{
					if ( gBullets[ uiCount ].usFlags & ( BULLET_FLAG_KNIFE ) )
					{
						if ( gBullets[ uiCount ].pAniTile != NULL )
						{
							gBullets[ uiCount ].pAniTile->sRelativeX	= (INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrX );
							gBullets[ uiCount ].pAniTile->sRelativeY	= (INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrY );
							gBullets[ uiCount ].pAniTile->pLevelNode->sRelativeZ	= (INT16) CONVERT_HEIGHTUNITS_TO_PIXELS( FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrZ ) );

							if ( gBullets[ uiCount ].usFlags & ( BULLET_FLAG_KNIFE ) )
							{
								gBullets[ uiCount ].pShadowAniTile->sRelativeX	= (INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrX );
								gBullets[ uiCount ].pShadowAniTile->sRelativeY	= (INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrY );
							}

						}
					}
					// Are we a missle?
					else if ( gBullets[ uiCount ].usFlags & ( BULLET_FLAG_MISSILE | BULLET_FLAG_SMALL_MISSILE | BULLET_FLAG_TANK_CANNON | BULLET_FLAG_FLAME | BULLET_FLAG_CREATURE_SPIT ) )
					{
					}
					/*
					else if ( gBullets[ uiCount ].usFlags & ( BULLET_FLAG_TRACER ) )
					{
						ManLooksForOtherTeams(gBullets[ uiCount ].pFirer);
					}
					*/
					/*
					else if (fTracer == TRUE)
					{
						ManLooksForOtherTeams(gBullets[ uiCount ].pFirer);
					}
					*/
					
					else
					{
						pNode = AddStructToTail( gBullets[ uiCount ].sGridNo, BULLETTILE1 );
						pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL;
						pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
						pNode->uiFlags |= ( LEVELNODE_USEABSOLUTEPOS | LEVELNODE_IGNOREHEIGHT );
						pNode->sRelativeX	= (INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrX );
						pNode->sRelativeY	= (INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrY );
						pNode->sRelativeZ = (INT16) CONVERT_HEIGHTUNITS_TO_PIXELS( FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrZ ) );

						//afp-start - add new tail /tracer
						// HEADROCK HAM 5: No tail for fragments.				
						if (gGameSettings.fOptions[TOPTION_ALTERNATE_BULLET_GRAPHICS] && gBullets[ uiCount ].fFragment == false)	
						{
  							if ((lastX != 0)  || (lastY != 0))
							{
								// qIncrX can be used to calculate slope and make the tracer longer if necessary
								PointsPath((INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrX),
									(INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrY), 
									(INT16) FIXEDPT_TO_INT32( lastX), 
									(INT16) FIXEDPT_TO_INT32( lastY));

								// compute valid points allong the fire line
								int pointsCount = 0;
								for (int i = 0; i < BULLET_TRACER_MAX_LENGTH; i++)
								{	
									pointsCount = i;
									if (gXPATH[i] == 0)
										if (gYPATH[i] == 0)
											break;
								}
								if (pointsCount <= 0)
									pointsCount = 30;


								for (int i = 0; i < BULLET_TRACER_MAX_LENGTH; i++)
								{
									if (gXPATH[i] == 0)
										if (gYPATH[i] == 0)
											break;
									
									// add all points along the path between bullets as bullets
									pNode = AddStructToTail( gBullets[ uiCount ].sGridNo, BULLETTILE1 );
									pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL;
									pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
									pNode->uiFlags |= ( LEVELNODE_USEABSOLUTEPOS | LEVELNODE_IGNOREHEIGHT );
									pNode->sRelativeX	= gXPATH[i];
									pNode->sRelativeY	= gYPATH[i];
									FIXEDPT relativeZ = lastZ - ((i + 1) * ((gBullets[ uiCount ].qCurrZ - lastZ) / (pointsCount)));
									pNode->sRelativeZ = (INT16) CONVERT_HEIGHTUNITS_TO_PIXELS( FIXEDPT_TO_INT32( relativeZ));
									
									// store structure pointer to clear image at the next bullet position
									gBullets[uiCount].pNodes[i] = pNode;
								}
							}
						}
						//afp-end
						// Display shadow
						// afp - no more shadow if tracer enabled
						if (!gGameSettings.fOptions[TOPTION_ALTERNATE_BULLET_GRAPHICS])	
						{
							pNode = AddStructToTail( gBullets[ uiCount ].sGridNo, BULLETTILE2 );
							pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL;
							pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
							pNode->uiFlags |= ( LEVELNODE_USEABSOLUTEPOS | LEVELNODE_IGNOREHEIGHT );
							pNode->sRelativeX	= (INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrX );
							pNode->sRelativeY	= (INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrY );
							pNode->sRelativeZ = (INT16)gpWorldLevelData[ gBullets[ uiCount ].sGridNo ].sHeight;
						}
					}
				}
			}
			else
			{
				if ( gBullets[ uiCount ].fToDelete )
				{
					gBullets[ uiCount ].fAllocated = FALSE;
					fDeletedSome = TRUE;
				}
			}
		}
	}

	if ( fDeletedSome )
	{
		RecountBullets( );
	}
}
Exemplo n.º 3
0
void DeleteAniTile( ANITILE *pAniTile )
{
	ANITILE				*pAniNode				= NULL;
	ANITILE				*pOldAniNode		= NULL;
	TILE_ELEMENT	*TileElem;

	pAniNode = pAniTileHead;

	while( pAniNode!= NULL )
	{
		if ( pAniNode == pAniTile )
		{
			// OK, set links
			// Check for head or tail
			if ( pOldAniNode == NULL )
			{
				// It's the head
				pAniTileHead = pAniTile->pNext;
			}
			else
			{
				pOldAniNode->pNext = pAniNode->pNext;
			}

			if ( !(pAniNode->uiFlags & ANITILE_EXISTINGTILE  ) )
			{

				// Delete memory assosiated with item
				switch( pAniNode->ubLevelID )
				{
					case ANI_STRUCT_LEVEL:
						
						RemoveStructFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode );
						break;

					case ANI_SHADOW_LEVEL:
						
						RemoveShadowFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode );
						break;

					case ANI_OBJECT_LEVEL:
						
						RemoveObject( pAniNode->sGridNo, pAniNode->usTileIndex );
						break;

					case ANI_ROOF_LEVEL:
						
						RemoveRoof( pAniNode->sGridNo, pAniNode->usTileIndex );
						break;

					case ANI_ONROOF_LEVEL:
						
						RemoveOnRoof( pAniNode->sGridNo, pAniNode->usTileIndex );
						break;

					case ANI_TOPMOST_LEVEL:
						
						RemoveTopmostFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode );
						break;

				}

				if ( ( pAniNode->uiFlags & ANITILE_CACHEDTILE ) )
				{
					RemoveCachedTile( pAniNode->sCachedTileID );
				}

				if ( pAniNode->uiFlags & ANITILE_EXPLOSION )
				{
					// Talk to the explosion data...
					RemoveExplosionData( pAniNode->uiUserData3 );

					if ( !gfExplosionQueueActive )
					{
						// turn on sighting again
						// the explosion queue handles all this at the end of the queue
						gTacticalStatus.uiFlags &= (~DISALLOW_SIGHT);
					}

          // Freeup attacker from explosion
		      DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., EXPLOSION effect gone off") );
		      ReduceAttackBusyCount( (UINT8)pAniNode->ubUserData2, FALSE );

				}


				if ( pAniNode->uiFlags & ANITILE_RELEASE_ATTACKER_WHEN_DONE )
				{
					// First delete the bullet!
					RemoveBullet( pAniNode->uiUserData3 );
					
					DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - miss finished animation") );
					FreeUpAttacker( (UINT8) pAniNode->ubAttackerMissed );					
				}

			}
			else
			{
				TileElem = &( gTileDatabase[ pAniNode->usTileIndex ] );

				// OK, update existing tile usIndex....
				Assert( TileElem->pAnimData != NULL );
				pAniNode->pLevelNode->usIndex = TileElem->pAnimData->pusFrames[ pAniNode->pLevelNode->sCurrentFrame ];

				// OK, set our frame data back to zero....
				pAniNode->pLevelNode->sCurrentFrame = 0;
				
				// Set some flags to write to Z / update save buffer
				// pAniNode->pLevelNode->uiFlags |=( LEVELNODE_LASTDYNAMIC | LEVELNODE_UPDATESAVEBUFFERONCE );
				pAniNode->pLevelNode->uiFlags &= ~( LEVELNODE_DYNAMIC | LEVELNODE_USEZ | LEVELNODE_ANIMATION );

				if (pAniNode->uiFlags & ANITILE_DOOR)
				{
					// unset door busy!
					DOOR_STATUS * pDoorStatus;

					pDoorStatus = GetDoorStatus( pAniNode->sGridNo );
					if (pDoorStatus)
					{
						pDoorStatus->ubFlags &= ~(DOOR_BUSY);
					}

					if ( GridNoOnScreen( pAniNode->sGridNo ) )
					{
						SetRenderFlags(RENDER_FLAG_FULL);
					}

				}
			}

			MemFree( pAniNode );
			return;
		}

		pOldAniNode = pAniNode;
		pAniNode		= pAniNode->pNext;

	}


}