123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523 |
- #ifdef PRECOMPILEDHEADERS
- #include "Tactical All.h"
- #else
- #include "math.h"
- #include <stdio.h>
- #include <errno.h>
- #include "worlddef.h"
- #include "renderworld.h"
- #include "vsurface.h"
- #include "Render Dirty.h"
- #include "sysutil.h"
- #include "container.h"
- #include "wcheck.h"
- #include "video.h"
- #include "vobject_blitters.h"
- #include "faces.h"
- #include "utilities.h"
- #include "overhead.h"
- #include "gap.h"
- #include "Soldier Profile.h"
- #include "Bullets.h"
- #include "los.h"
- #include "worldman.h"
- #include "random.h"
- #include "GameSettings.h"
- #include "FileMan.h"
- #endif
- // Defines
- #define NUM_BULLET_SLOTS 50
- // GLOBAL FOR FACES LISTING
- BULLET gBullets[ NUM_BULLET_SLOTS ];
- UINT32 guiNumBullets = 0;
- INT32 GetFreeBullet(void)
- {
- UINT32 uiCount;
- for(uiCount=0; uiCount < guiNumBullets; uiCount++)
- {
- if((gBullets[uiCount].fAllocated==FALSE) )
- return((INT32)uiCount);
- }
- if(guiNumBullets < NUM_BULLET_SLOTS )
- return((INT32)guiNumBullets++);
- return(-1);
- }
- void RecountBullets(void)
- {
- INT32 uiCount;
- for(uiCount=guiNumBullets-1; (uiCount >=0) ; uiCount--)
- {
- if( ( gBullets[uiCount].fAllocated ) )
- {
- guiNumBullets=(UINT32)(uiCount+1);
- return;
- }
- }
- guiNumBullets = 0;
- }
- INT32 CreateBullet( UINT8 ubFirerID, BOOLEAN fFake, UINT16 usFlags )
- {
- INT32 iBulletIndex;
- BULLET *pBullet;
- if( ( iBulletIndex = GetFreeBullet() )==(-1) )
- return(-1);
- memset(&gBullets[ iBulletIndex ], 0, sizeof( BULLET ) );
- pBullet = &gBullets[ iBulletIndex ];
- pBullet->iBullet = iBulletIndex;
- pBullet->fAllocated = TRUE;
- pBullet->fLocated = FALSE;
- pBullet->ubFirerID = ubFirerID;
- pBullet->usFlags = usFlags;
- pBullet->usLastStructureHit = 0;
- if (fFake)
- {
- pBullet->fReal = FALSE;
- }
- else
- {
- pBullet->fReal = TRUE;
- }
- return( iBulletIndex );
- }
- 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 = (INT16)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 ].bStatus[0];
- }
- // 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 );
- }
- }
- }
- }
- void RemoveBullet( INT32 iBullet )
- {
- CHECKV( iBullet < NUM_BULLET_SLOTS );
- // 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 ) );
- 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();
- }
- }
- void LocateBullet( INT32 iBulletIndex )
- {
- if ( gGameSettings.fOptions[ TOPTION_SHOW_MISSES ] )
- {
- // Check if a bad guy fired!
- if ( gBullets[ iBulletIndex ].ubFirerID != NOBODY )
- {
- if ( MercPtrs[ gBullets[ iBulletIndex ].ubFirerID ]->bSide == gbPlayerNum )
- {
- if ( !gBullets[ iBulletIndex ].fLocated )
- {
- gBullets[ iBulletIndex ].fLocated = TRUE;
- //Only if we are in turnbased and noncombat
- if ( gTacticalStatus.uiFlags & TURNBASED && (gTacticalStatus.uiFlags & INCOMBAT) )
- {
- LocateGridNo( (INT16)gBullets[ iBulletIndex ].sGridNo );
- }
- }
- }
- }
- }
- }
- 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 ) )
- {
- }
- else
- {
- RemoveStruct( gBullets[ uiCount ].sGridNo, BULLETTILE1 );
- RemoveStruct( gBullets[ uiCount ].sGridNo, BULLETTILE2 );
- }
- }
- 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
- {
- 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 ) );
- // Display shadow
- 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( );
- }
- }
- BULLET *GetBulletPtr( INT32 iBullet )
- {
- BULLET *pBullet;
- CHECKN( iBullet < NUM_BULLET_SLOTS );
- pBullet = &gBullets[ iBullet ];
- return( pBullet );
- }
- void AddMissileTrail( BULLET *pBullet, FIXEDPT qCurrX, FIXEDPT qCurrY, FIXEDPT qCurrZ )
- {
- ANITILE_PARAMS AniParams;
- // If we are a small missle, don't show
- if ( pBullet->usFlags & ( BULLET_FLAG_SMALL_MISSILE | BULLET_FLAG_FLAME | BULLET_FLAG_CREATURE_SPIT ) )
- {
- if ( pBullet->iLoop < 5 )
- {
- return;
- }
- }
- // If we are a small missle, don't show
- if ( pBullet->usFlags & ( BULLET_FLAG_TANK_CANNON ) )
- {
- //if ( pBullet->iLoop < 40 )
- //{
- return;
- //}
- }
- memset( &AniParams, 0, sizeof( ANITILE_PARAMS ) );
- AniParams.sGridNo = (INT16)pBullet->sGridNo;
- AniParams.ubLevelID = ANI_STRUCT_LEVEL;
- AniParams.sDelay = (INT16)( 100 + Random( 100 ) );
- AniParams.sStartFrame = 0;
- AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_ALWAYS_TRANSLUCENT;
- AniParams.sX = FIXEDPT_TO_INT32( qCurrX );
- AniParams.sY = FIXEDPT_TO_INT32( qCurrY );
- AniParams.sZ = CONVERT_HEIGHTUNITS_TO_PIXELS( FIXEDPT_TO_INT32( qCurrZ ) );
- if ( pBullet->usFlags & ( BULLET_FLAG_MISSILE | BULLET_FLAG_TANK_CANNON ) )
- {
- strcpy( AniParams.zCachedFile, "TILECACHE\\MSLE_SMK.STI" );
- }
- else if ( pBullet->usFlags & ( BULLET_FLAG_SMALL_MISSILE ) )
- {
- strcpy( AniParams.zCachedFile, "TILECACHE\\MSLE_SMA.STI" );
- }
- else if ( pBullet->usFlags & ( BULLET_FLAG_CREATURE_SPIT ) )
- {
- strcpy( AniParams.zCachedFile, "TILECACHE\\MSLE_SPT.STI" );
- }
- else if ( pBullet->usFlags & ( BULLET_FLAG_FLAME ) )
- {
- strcpy( AniParams.zCachedFile, "TILECACHE\\FLMTHR2.STI" );
- AniParams.sDelay = (INT16)( 100 );
- }
- CreateAnimationTile( &AniParams );
- }
- BOOLEAN SaveBulletStructureToSaveGameFile( HWFILE hFile )
- {
- UINT32 uiNumBytesWritten;
- UINT16 usCnt;
- UINT32 uiBulletCount=0;
- //loop through and count the number of bullets
- for( usCnt=0; usCnt<NUM_BULLET_SLOTS; usCnt++ )
- {
- //if the bullet is active, save it
- if( gBullets[ usCnt ].fAllocated )
- {
- uiBulletCount++;
- }
- }
- //Save the number of Bullets in the array
- FileWrite( hFile, &uiBulletCount, sizeof( UINT32 ), &uiNumBytesWritten );
- if( uiNumBytesWritten != sizeof( UINT32 ) )
- {
- return( FALSE );
- }
- if( uiBulletCount != 0 )
- {
- for( usCnt=0; usCnt<NUM_BULLET_SLOTS; usCnt++ )
- {
- //if the bullet is active, save it
- if( gBullets[ usCnt ].fAllocated )
- {
- //Save the the Bullet structure
- FileWrite( hFile, &gBullets[usCnt], sizeof( BULLET ), &uiNumBytesWritten );
- if( uiNumBytesWritten != sizeof( BULLET ) )
- {
- return( FALSE );
- }
- }
- }
- }
- return( TRUE );
- }
- BOOLEAN LoadBulletStructureFromSavedGameFile( HWFILE hFile )
- {
- UINT32 uiNumBytesRead;
- UINT16 usCnt;
- //make sure the bullets are not allocated
- memset( gBullets, 0, NUM_BULLET_SLOTS * sizeof( BULLET ) );
- //Load the number of Bullets in the array
- FileRead( hFile, &guiNumBullets, sizeof( UINT32 ), &uiNumBytesRead );
- if( uiNumBytesRead != sizeof( UINT32 ) )
- {
- return( FALSE );
- }
- for( usCnt=0; usCnt<guiNumBullets; usCnt++ )
- {
- //Load the the Bullet structure
- FileRead( hFile, &gBullets[usCnt], sizeof( BULLET ), &uiNumBytesRead );
- if( uiNumBytesRead != sizeof( BULLET ) )
- {
- return( FALSE );
- }
- //Set some parameters
- gBullets[usCnt].uiLastUpdate = 0;
- if( gBullets[usCnt].ubFirerID != NOBODY )
- gBullets[usCnt].pFirer = &Menptr[ gBullets[usCnt].ubFirerID ];
- else
- gBullets[usCnt].pFirer = NULL;
- gBullets[usCnt].pAniTile = NULL;
- gBullets[usCnt].pShadowAniTile = NULL;
- gBullets[usCnt].iBullet = usCnt;
- HandleBulletSpecialFlags( gBullets[usCnt].iBullet );
- }
- return( TRUE );
- }
- void StopBullet( INT32 iBullet )
- {
- gBullets[ iBullet ].usFlags |= BULLET_STOPPED;
- RemoveStruct( gBullets[ iBullet ].sGridNo, BULLETTILE1 );
- RemoveStruct( gBullets[ iBullet ].sGridNo, BULLETTILE2 );
- }
- void DeleteAllBullets( )
- {
- UINT32 uiCount;
- for ( uiCount = 0; uiCount < guiNumBullets; uiCount++ )
- {
- if ( gBullets[ uiCount ].fAllocated)
- {
- // Remove from old position
- RemoveBullet( uiCount );
- gBullets[ uiCount ].fAllocated = FALSE;
- }
- }
- RecountBullets( );
- }
|