Ejemplo 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();
	}
}
Ejemplo n.º 2
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;

	}


}