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 ); } } } }
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 /*| BULLET_FLAG_TRACER*/ ) ) { if ( pBullet->iLoop < 5 ) { return; } } // HEADROCK HAM B2.5: Created new bullet flag that tells us whether this specific bullet is a tracer. // The condition now reads that flag and creates a lightshow only for tracer bullets. This flag is only // used if the new Tracer System is on. //if (fTracer == TRUE) if ((gGameExternalOptions.ubRealisticTracers > 0 && gGameExternalOptions.ubNumBulletsPerTracer > 0 && pBullet->fTracer == TRUE) || (gGameExternalOptions.ubRealisticTracers == 0 && fTracer == TRUE)) { 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 = 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 ); } //else if ( pBullet->usFlags & ( BULLET_FLAG_TRACER ) ) // HEADROCK HAM B2.5: Created new bullet flag that tells us whether this specific bullet is a tracer. // The condition now reads that flag and creates a lightshow only for tracer bullets. This flag is only // used if the new Tracer System is on. // else if (fTracer == TRUE) else if ((gGameExternalOptions.ubRealisticTracers > 0 && gGameExternalOptions.ubNumBulletsPerTracer > 0 && pBullet->fTracer == TRUE) || (gGameExternalOptions.ubRealisticTracers == 0 && fTracer == TRUE)) { INT16 sXPos, sYPos; strcpy( AniParams.zCachedFile, "TILECACHE\\BULLET_TRACER.STI" ); AniParams.uiFlags |= ANITILE_LIGHT; AniParams.sDelay = 10000; // Test this out if (!pBullet->pAniTile) { pBullet->pAniTile = CreateAnimationTile( &AniParams ); } ConvertGridNoToCenterCellXY( pBullet->sGridNo, &sXPos, &sYPos ); LightSpritePosition( pBullet->pAniTile->lightSprite, (INT16)(sXPos/CELL_X_SIZE), (INT16)(sYPos/CELL_Y_SIZE)); #if 0 if ( pBullet->pFirer->pathing.bLevel > 0 ) // if firer on roof then { if ( FindBuilding(AniParams.sGridNo) != NULL ) // if this spot is still within the building's grid area { LightSpritePower( pBullet->pAniTile->lightSprite, FALSE); } } #endif return; } CreateAnimationTile( &AniParams ); }
// Add smoke to gridno // ( Replacement algorithm uses distance away ) void AddSmokeEffectToTile( INT32 iSmokeEffectID, INT8 bType, INT16 sGridNo, INT8 bLevel ) { ANITILE_PARAMS AniParams; ANITILE *pAniTile; SMOKEEFFECT *pSmoke; BOOLEAN fDissipating = FALSE; pSmoke = &gSmokeEffectData[ iSmokeEffectID ]; if ( ( pSmoke->ubDuration - pSmoke->bAge ) < 2 ) { fDissipating = TRUE; // Remove old one... RemoveSmokeEffectFromTile( sGridNo, bLevel ); } // If smoke effect exists already.... stop if ( gpWorldLevelData[ sGridNo ].ubExtFlags[ bLevel ] & ANY_SMOKE_EFFECT ) { return; } // OK, Create anitile.... memset( &AniParams, 0, sizeof( ANITILE_PARAMS ) ); AniParams.sGridNo = sGridNo; if ( bLevel == 0 ) { AniParams.ubLevelID = ANI_STRUCT_LEVEL; } else { AniParams.ubLevelID = ANI_ONROOF_LEVEL; } AniParams.sDelay = (INT16)( 300 + Random( 300 ) ); if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) ) { AniParams.sStartFrame = (INT16)0; } else { AniParams.sStartFrame = (INT16)Random( 5 ); } // Bare bones flags are... // AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_OPTIMIZEFORSMOKEEFFECT | ANITILE_SMOKE_EFFECT | ANITILE_LOOPING; //AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_SMOKE_EFFECT | ANITILE_LOOPING; if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) ) { AniParams.uiFlags = ANITILE_PAUSED | ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_SMOKE_EFFECT | ANITILE_LOOPING; } else { AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD | ANITILE_SMOKE_EFFECT | ANITILE_LOOPING | ANITILE_ALWAYS_TRANSLUCENT; } AniParams.sX = CenterX( sGridNo ); AniParams.sY = CenterY( sGridNo ); AniParams.sZ = (INT16)0; // Use the right graphic based on type.. switch( bType ) { case NORMAL_SMOKE_EFFECT: if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) ) { strcpy( AniParams.zCachedFile, "TILECACHE\\smkechze.STI" ); } else { if ( fDissipating ) { strcpy( AniParams.zCachedFile, "TILECACHE\\smalsmke.STI" ); } else { strcpy( AniParams.zCachedFile, "TILECACHE\\SMOKE.STI" ); } } break; case TEARGAS_SMOKE_EFFECT: if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) ) { strcpy( AniParams.zCachedFile, "TILECACHE\\tearchze.STI" ); } else { if ( fDissipating ) { strcpy( AniParams.zCachedFile, "TILECACHE\\smaltear.STI" ); } else { strcpy( AniParams.zCachedFile, "TILECACHE\\TEARGAS.STI" ); } } break; case MUSTARDGAS_SMOKE_EFFECT: if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) ) { strcpy( AniParams.zCachedFile, "TILECACHE\\mustchze.STI" ); } else { if ( fDissipating ) { strcpy( AniParams.zCachedFile, "TILECACHE\\smalmust.STI" ); } else { strcpy( AniParams.zCachedFile, "TILECACHE\\MUSTARD2.STI" ); } } break; case CREATURE_SMOKE_EFFECT: if ( !( gGameSettings.fOptions[ TOPTION_ANIMATE_SMOKE ] ) ) { strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" ); } else { if ( fDissipating ) { strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" ); } else { strcpy( AniParams.zCachedFile, "TILECACHE\\spit_gas.STI" ); } } break; } // Create tile... pAniTile = CreateAnimationTile( &AniParams ); // Set world flags gpWorldLevelData[ sGridNo ].ubExtFlags[ bLevel ] |= FromSmokeTypeToWorldFlags( bType ); // All done... // Re-draw..... :( SetRenderFlags(RENDER_FLAG_FULL); }