//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &color - 
//-----------------------------------------------------------------------------
void C_TEAntlionDust::GetDustColor( Vector &color )
{
	trace_t	tr;
	UTIL_TraceLine( m_vecOrigin+Vector(0,0,1), m_vecOrigin+Vector(0,0,-32), 
		MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr );

	if ( tr.fraction < 1.0f )
	{
		GetColorForSurface( &tr, &color );
	}
	else
	{
		//Fill in a fallback
		color = g_AntlionDustColor;
	}
}
Example #2
0
static void PerformNewCustomEffects( const Vector &vecOrigin, trace_t &tr, const Vector &shotDir, int iMaterial, int iScale, int nFlags )
{
    bool bNoFlecks = !r_drawflecks.GetBool();
    if ( !bNoFlecks )
    {
        bNoFlecks = ( ( nFlags & FLAGS_CUSTIOM_EFFECTS_NOFLECKS ) != 0  );
    }

    // Compute the impact effect name
    const ImpactEffect_t &effect = s_pImpactEffect[ iMaterial - 'A' ];
    const char *pImpactName = effect.m_pName;
    if ( bNoFlecks && effect.m_pNameNoFlecks )
    {
        pImpactName = effect.m_pNameNoFlecks;
    }
    if ( !pImpactName )
        return;

    CSmartPtr<CNewParticleEffect> pEffect = CNewParticleEffect::Create( NULL, pImpactName );
    if ( !pEffect->IsValid() )
        return;

    Vector	vecReflect;
    float	flDot = DotProduct( shotDir, tr.plane.normal );
    VectorMA( shotDir, -2.0f * flDot, tr.plane.normal, vecReflect );

    Vector vecShotBackward;
    VectorMultiply( shotDir, -1.0f, vecShotBackward );

    Vector vecImpactPoint = ( tr.fraction != 1.0f ) ? tr.endpos : vecOrigin;
    // Other games round m_vOrigin to nearest integer, so I guess we can afford skipping this check.
#ifdef HL2_CLIENT_DLL
    Assert( VectorsAreEqual( vecOrigin, tr.endpos, 1e-1 ) );
#endif
    SetImpactControlPoint( pEffect.GetObject(), 0, vecImpactPoint, tr.plane.normal, tr.m_pEnt );
    SetImpactControlPoint( pEffect.GetObject(), 1, vecImpactPoint, vecReflect,		tr.m_pEnt );
    SetImpactControlPoint( pEffect.GetObject(), 2, vecImpactPoint, vecShotBackward,	tr.m_pEnt );
    pEffect->SetControlPoint( 3, Vector( iScale, iScale, iScale ) );
    if ( pEffect->m_pDef->ReadsControlPoint( 4 ) )
    {
        Vector vecColor;
        GetColorForSurface( &tr, &vecColor );
        pEffect->SetControlPoint( 4, vecColor );
    }
}
void FX_DustImpact( const Vector &origin, trace_t *tr, float flScale )
{
	//
	// PC version
	//

	VPROF_BUDGET( "FX_DustImpact", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
	Vector	offset;
	float	spread = 0.2f;
	
	CSmartPtr<CDustParticle> pSimple = CDustParticle::Create( "dust" );
	pSimple->SetSortOrigin( origin );

	// Three types of particle, ideally we want 4 of each.
	float fNumParticles = 4.0f * g_pParticleSystemMgr->ParticleThrottleScaling();
	int nParticles1 = (int)( 0.50f + fNumParticles );
	int nParticles2 = (int)( 0.83f + fNumParticles );		// <-- most visible particle type.
	int nParticles3 = (int)( 0.17f + fNumParticles );

	SimpleParticle	*pParticle;

	Vector	color;
	float	colorRamp;

	GetColorForSurface( tr, &color );

	// To get a decent spread even when scaling down the number of particles...
	const static int nParticleIdArray[4] = {3,1,2,0};

	int i;
	for ( i = 0; i < nParticles1; i++ )
	{
		int nId = nParticleIdArray[i];

		pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[0], origin );

		if ( pParticle != NULL )
		{
			pParticle->m_flLifetime = 0.0f;
			pParticle->m_flDieTime	= random->RandomFloat( 0.5f, 1.0f );

			pParticle->m_vecVelocity.Random( -spread, spread );
			pParticle->m_vecVelocity += ( tr->plane.normal * random->RandomFloat( 1.0f, 6.0f ) );
			
			VectorNormalize( pParticle->m_vecVelocity );

			float	fForce = random->RandomFloat( 250, 500 ) * nId;

			// scaled
			pParticle->m_vecVelocity *= fForce * flScale;
			
			colorRamp = random->RandomFloat( 0.75f, 1.25f );

			pParticle->m_uchColor[0]	= MIN( 1.0f, color[0] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[1]	= MIN( 1.0f, color[1] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[2]	= MIN( 1.0f, color[2] * colorRamp ) * 255.0f;
			
			// scaled
			pParticle->m_uchStartSize	= ( unsigned char )( flScale * random->RandomInt( 3, 4 ) * (nId+1) );

			// scaled
			pParticle->m_uchEndSize		= ( unsigned char )( flScale * pParticle->m_uchStartSize * 4 );
			
			pParticle->m_uchStartAlpha	= random->RandomInt( 32, 255 );
			pParticle->m_uchEndAlpha	= 0;
			
			pParticle->m_flRoll			= random->RandomInt( 0, 360 );
			pParticle->m_flRollDelta	= random->RandomFloat( -8.0f, 8.0f );
		}
	}			

	//Dust specs
	for ( i = 0; i < nParticles2; i++ )
	{
		int nId = nParticleIdArray[i];

		pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin );

		if ( pParticle != NULL )
		{
			pParticle->m_flLifetime = 0.0f;
			pParticle->m_flDieTime	= random->RandomFloat( 0.25f, 0.75f );

			pParticle->m_vecVelocity.Random( -spread, spread );
			pParticle->m_vecVelocity += ( tr->plane.normal * random->RandomFloat( 1.0f, 6.0f ) );
			
			VectorNormalize( pParticle->m_vecVelocity );

			float	fForce = random->RandomFloat( 250, 500 ) * nId;

			pParticle->m_vecVelocity *= fForce;
			
			colorRamp = random->RandomFloat( 0.75f, 1.25f );

			pParticle->m_uchColor[0]	= MIN( 1.0f, color[0] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[1]	= MIN( 1.0f, color[1] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[2]	= MIN( 1.0f, color[2] * colorRamp ) * 255.0f;
			
			pParticle->m_uchStartSize	= random->RandomInt( 2, 4 ) * (nId+1);
			pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 2;
			
			pParticle->m_uchStartAlpha	= 255;
			pParticle->m_uchEndAlpha	= 0;
			
			pParticle->m_flRoll			= random->RandomInt( 0, 360 );
			pParticle->m_flRollDelta	= random->RandomFloat( -2.0f, 2.0f );
		}
	}

	//Impact hit
	for ( i = 0; i < nParticles3; i++ )
	{
		//int nId = nParticleIdArray[i];

		pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[0], origin );

		if ( pParticle != NULL )
		{
			offset = origin;
			offset[0] += random->RandomFloat( -8.0f, 8.0f );
			offset[1] += random->RandomFloat( -8.0f, 8.0f );

			pParticle->m_flLifetime = 0.0f;
			pParticle->m_flDieTime	= random->RandomFloat( 0.5f, 1.0f );

			spread = 1.0f;

			pParticle->m_vecVelocity.Random( -spread, spread );
			pParticle->m_vecVelocity += tr->plane.normal;
			
			VectorNormalize( pParticle->m_vecVelocity );

			float	fForce = random->RandomFloat( 0, 50 );

			pParticle->m_vecVelocity *= fForce;
			
			colorRamp = random->RandomFloat( 0.75f, 1.25f );

			pParticle->m_uchColor[0]	= MIN( 1.0f, color[0] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[1]	= MIN( 1.0f, color[1] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[2]	= MIN( 1.0f, color[2] * colorRamp ) * 255.0f;
			
			pParticle->m_uchStartSize	= random->RandomInt( 1, 4 );
			pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 4;
			
			pParticle->m_uchStartAlpha	= random->RandomInt( 32, 64 );
			pParticle->m_uchEndAlpha	= 0;
			
			pParticle->m_flRoll			= random->RandomInt( 0, 360 );
			pParticle->m_flRollDelta	= random->RandomFloat( -16.0f, 16.0f );
		}
	}			
}
//-----------------------------------------------------------------------------
// Purpose: Debris flecks caused by impacts
// Input  : origin - start
//			*trace - trace information
//			*materialName - material hit
//			materialType - type of material hit
//-----------------------------------------------------------------------------
void FX_DebrisFlecks( const Vector& origin, trace_t *tr, char materialType, int iScale, bool bNoFlecks )
{
	VPROF_BUDGET( "FX_DebrisFlecks", VPROF_BUDGETGROUP_PARTICLE_RENDERING );

	if ( !fx_drawimpactdebris.GetBool() )
		return;

#ifdef _XBOX

	//
	// XBox version
	//

	Vector	offset;
	float	spread = 0.2f;

	CSmartPtr<CDustParticle> pSimple = CDustParticle::Create( "dust" );
	pSimple->SetSortOrigin( origin );
	
	// Lock the bbox
	pSimple->GetBinding().SetBBox( origin - ( Vector( 16, 16, 16 ) * iScale ), origin + ( Vector( 16, 16, 16 ) * iScale ) );

	// Get the color of the surface we've impacted
	Vector	color;
	float	colorRamp;
	GetColorForSurface( tr, &color );

	int i;
	SimpleParticle	*pParticle;
	for ( i = 0; i < 4; i++ )
	{
		if ( i == 3 )
		{
			pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin );
		}
		else
		{
			pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[0], origin );
		}

		if ( pParticle != NULL )
		{
			pParticle->m_flLifetime = 0.0f;
			pParticle->m_flDieTime	= random->RandomFloat( 0.5f, 1.0f );

			pParticle->m_vecVelocity.Random( -spread, spread );
			pParticle->m_vecVelocity += ( tr->plane.normal * random->RandomFloat( 1.0f, 6.0f ) );

			VectorNormalize( pParticle->m_vecVelocity );

			float	fForce = random->RandomFloat( 250, 500 ) * i * 0.5f;

			// scaled
			pParticle->m_vecVelocity *= fForce * iScale;

			// Ramp the color
			colorRamp = random->RandomFloat( 0.5f, 1.25f );
			pParticle->m_uchColor[0]	= MIN( 1.0f, color[0] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[1]	= MIN( 1.0f, color[1] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[2]	= MIN( 1.0f, color[2] * colorRamp ) * 255.0f;

			// scaled
			pParticle->m_uchStartSize	= (iScale*0.5f) * random->RandomInt( 3, 4 ) * (i+1);

			// scaled
			pParticle->m_uchEndSize		= (iScale*0.5f) * pParticle->m_uchStartSize * 4;

			pParticle->m_uchStartAlpha	= random->RandomInt( 200, 255 );
			pParticle->m_uchEndAlpha	= 0;

			pParticle->m_flRoll			= random->RandomInt( 0, 360 );
			pParticle->m_flRollDelta	= random->RandomFloat( -1.0f, 1.0f );
		}
	}			

	// Covers the impact spot with flecks
	pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_DustPuff2, origin );

	if ( pParticle != NULL )
	{
		offset = origin;
		offset[0] += random->RandomFloat( -8.0f, 8.0f );
		offset[1] += random->RandomFloat( -8.0f, 8.0f );

		pParticle->m_flLifetime = 0.0f;
		pParticle->m_flDieTime	= random->RandomFloat( 0.5f, 1.0f );

		spread = 1.0f;

		pParticle->m_vecVelocity.Init();

		colorRamp = random->RandomFloat( 0.5f, 1.25f );

		pParticle->m_uchColor[0]	= MIN( 1.0f, color[0] * colorRamp ) * 255.0f;
		pParticle->m_uchColor[1]	= MIN( 1.0f, color[1] * colorRamp ) * 255.0f;
		pParticle->m_uchColor[2]	= MIN( 1.0f, color[2] * colorRamp ) * 255.0f;

		pParticle->m_uchStartSize	= random->RandomInt( 4, 8 );
		pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 4;

		pParticle->m_uchStartAlpha	= random->RandomInt( 64, 128 );
		pParticle->m_uchEndAlpha	= 0;

		pParticle->m_flRoll			= random->RandomInt( 0, 360 );
		pParticle->m_flRollDelta	= random->RandomFloat( -0.1f, 0.1f );
	}

#else

	//
	// PC version
	//

	Vector	color;
	GetColorForSurface( tr, &color );

	if ( !bNoFlecks )
	{
		CreateFleckParticles( origin, color, tr, materialType, iScale );
	}

	//
	// Dust trail
	//
	Vector	offset = tr->endpos + ( tr->plane.normal * 2.0f );

	SimpleParticle newParticle;

	int i;
	for ( i = 0; i < 2; i++ )
	{
		newParticle.m_Pos = offset;

		newParticle.m_flLifetime	= 0.0f;
		newParticle.m_flDieTime	= 1.0f;

		Vector dir;
		dir[0] = tr->plane.normal[0] + random->RandomFloat( -0.8f, 0.8f );
		dir[1] = tr->plane.normal[1] + random->RandomFloat( -0.8f, 0.8f );
		dir[2] = tr->plane.normal[2] + random->RandomFloat( -0.8f, 0.8f );

		newParticle.m_uchStartSize	= random->RandomInt( 2, 4 ) * iScale;
		newParticle.m_uchEndSize	= newParticle.m_uchStartSize * 8 * iScale;

		newParticle.m_vecVelocity = dir * random->RandomFloat( 2.0f, 24.0f )*(i+1);
		newParticle.m_vecVelocity[2] -= random->RandomFloat( 8.0f, 32.0f )*(i+1);

		newParticle.m_uchStartAlpha	= random->RandomInt( 100, 200 );
		newParticle.m_uchEndAlpha	= 0;

		newParticle.m_flRoll			= random->RandomFloat( 0, 360 );
		newParticle.m_flRollDelta	= random->RandomFloat( -1, 1 );

		float colorRamp = random->RandomFloat( 0.5f, 1.25f );

		newParticle.m_uchColor[0] = MIN( 1.0f, color[0]*colorRamp )*255.0f;
		newParticle.m_uchColor[1] = MIN( 1.0f, color[1]*colorRamp )*255.0f;
		newParticle.m_uchColor[2] = MIN( 1.0f, color[2]*colorRamp )*255.0f;

		AddSimpleParticle( &newParticle, g_Mat_DustPuff[0] );
	}


	for ( i = 0; i < 4; i++ )
	{
		newParticle.m_Pos = offset;

		newParticle.m_flLifetime	= 0.0f;
		newParticle.m_flDieTime	= random->RandomFloat( 0.25f, 0.5f );

		Vector dir;
		dir[0] = tr->plane.normal[0] + random->RandomFloat( -0.8f, 0.8f );
		dir[1] = tr->plane.normal[1] + random->RandomFloat( -0.8f, 0.8f );
		dir[2] = tr->plane.normal[2] + random->RandomFloat( -0.8f, 0.8f );

		newParticle.m_uchStartSize	= random->RandomInt( 1, 4 );
		newParticle.m_uchEndSize	= newParticle.m_uchStartSize * 4;

		newParticle.m_vecVelocity = dir * random->RandomFloat( 8.0f, 32.0f );
		newParticle.m_vecVelocity[2] -= random->RandomFloat( 8.0f, 64.0f );

		newParticle.m_uchStartAlpha	= 255;
		newParticle.m_uchEndAlpha	= 0;

		newParticle.m_flRoll			= random->RandomFloat( 0, 360 );
		newParticle.m_flRollDelta	= random->RandomFloat( -2.0f, 2.0f );

		float colorRamp = random->RandomFloat( 0.5f, 1.25f );

		newParticle.m_uchColor[0] = MIN( 1.0f, color[0]*colorRamp )*255.0f;
		newParticle.m_uchColor[1] = MIN( 1.0f, color[1]*colorRamp )*255.0f;
		newParticle.m_uchColor[2] = MIN( 1.0f, color[2]*colorRamp )*255.0f;

		AddSimpleParticle( &newParticle, g_Mat_BloodPuff[0] );
	}

	//
	// Bullet hole capper
	//
	newParticle.m_Pos = offset;

	newParticle.m_flLifetime		= 0.0f;
	newParticle.m_flDieTime		= random->RandomFloat( 1.0f, 1.5f );

	Vector dir;
	dir[0] = tr->plane.normal[0] + random->RandomFloat( -0.8f, 0.8f );
	dir[1] = tr->plane.normal[1] + random->RandomFloat( -0.8f, 0.8f );
	dir[2] = tr->plane.normal[2] + random->RandomFloat( -0.8f, 0.8f );

	newParticle.m_uchStartSize	= random->RandomInt( 4, 8 );
	newParticle.m_uchEndSize		= newParticle.m_uchStartSize * 4.0f;

	newParticle.m_vecVelocity = dir * random->RandomFloat( 2.0f, 24.0f );
	newParticle.m_vecVelocity[2] = random->RandomFloat( -2.0f, 2.0f );

	newParticle.m_uchStartAlpha	= random->RandomInt( 100, 200 );
	newParticle.m_uchEndAlpha	= 0;

	newParticle.m_flRoll			= random->RandomFloat( 0, 360 );
	newParticle.m_flRollDelta	= random->RandomFloat( -2, 2 );

	float colorRamp = random->RandomFloat( 0.5f, 1.25f );

	newParticle.m_uchColor[0] = MIN( 1.0f, color[0]*colorRamp )*255.0f;
	newParticle.m_uchColor[1] = MIN( 1.0f, color[1]*colorRamp )*255.0f;
	newParticle.m_uchColor[2] = MIN( 1.0f, color[2]*colorRamp )*255.0f;

	AddSimpleParticle( &newParticle, g_Mat_DustPuff[0] );

#endif
}
//-----------------------------------------------------------------------------
// Purpose: Dust impact
// Input  : &origin - position
//			&tr - trace information
//-----------------------------------------------------------------------------
void FX_DustImpact( const Vector &origin, trace_t *tr, int iScale )
{
	if ( !fx_drawimpactdust.GetBool() )
		return;

#ifdef _XBOX

	//
	// XBox version
	//

	VPROF_BUDGET( "FX_DustImpact", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
	Vector	offset;
	float	spread = 0.2f;

	CSmartPtr<CDustParticle> pSimple = CDustParticle::Create( "dust" );
	pSimple->SetSortOrigin( origin );
	pSimple->GetBinding().SetBBox( origin - ( Vector( 32, 32, 32 ) * iScale ), origin + ( Vector( 32, 32, 32 ) * iScale ) );

	Vector	color;
	float	colorRamp;
	GetColorForSurface( tr, &color );

	int i;
	SimpleParticle *pParticle;
	for ( i = 0; i < 4; i++ )
	{
		// Last puff is gritty (hides end)
		if ( i == 3 )
		{
			pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin );
		}
		else
		{
			pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[0], origin );
		}

		if ( pParticle != NULL )
		{
			pParticle->m_flLifetime = 0.0f;

			pParticle->m_vecVelocity.Random( -spread, spread );
			pParticle->m_vecVelocity += ( tr->plane.normal * random->RandomFloat( 1.0f, 6.0f ) );

			VectorNormalize( pParticle->m_vecVelocity );

			float	fForce = random->RandomFloat( 250, 500 ) * i;

			// scaled
			pParticle->m_vecVelocity *= fForce * iScale;

			colorRamp = random->RandomFloat( 0.75f, 1.25f );

			pParticle->m_uchColor[0]	= min( 1.0f, color[0] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[1]	= min( 1.0f, color[1] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[2]	= min( 1.0f, color[2] * colorRamp ) * 255.0f;

			// scaled
			pParticle->m_uchStartSize	= iScale * random->RandomInt( 3, 4 ) * (i+1);

			// scaled
			pParticle->m_uchEndSize		= iScale * pParticle->m_uchStartSize * 4;

			pParticle->m_uchStartAlpha	= random->RandomInt( 32, 255 );
			pParticle->m_uchEndAlpha	= 0;

			pParticle->m_flRoll			= random->RandomInt( 0, 360 );

			if ( i == 3 )
			{
				pParticle->m_flRollDelta = random->RandomFloat( -0.1f, 0.1f );
				pParticle->m_flDieTime	= 0.5f;
			}
			else
			{
				pParticle->m_flRollDelta = random->RandomFloat( -8.0f, 8.0f );
				pParticle->m_flDieTime	= random->RandomFloat( 0.5f, 1.0f );
			}
		}
	}			

	//Impact hit
	pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_DustPuff, origin );

	if ( pParticle != NULL )
	{
		offset = origin;
		offset[0] += random->RandomFloat( -8.0f, 8.0f );
		offset[1] += random->RandomFloat( -8.0f, 8.0f );

		pParticle->m_flLifetime = 0.0f;
		pParticle->m_flDieTime	= random->RandomFloat( 0.5f, 1.0f );

		pParticle->m_vecVelocity.Init();

		colorRamp = random->RandomFloat( 0.75f, 1.25f );
		pParticle->m_uchColor[0]	= min( 1.0f, color[0] * colorRamp ) * 255.0f;
		pParticle->m_uchColor[1]	= min( 1.0f, color[1] * colorRamp ) * 255.0f;
		pParticle->m_uchColor[2]	= min( 1.0f, color[2] * colorRamp ) * 255.0f;

		pParticle->m_uchStartSize	= random->RandomInt( 4, 8 );
		pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 4;

		pParticle->m_uchStartAlpha	= random->RandomInt( 32, 64 );
		pParticle->m_uchEndAlpha	= 0;

		pParticle->m_flRoll			= random->RandomInt( 0, 360 );
		pParticle->m_flRollDelta	= random->RandomFloat( -1.0f, 1.0f );
	}

#else
	FX_DustImpact( origin, tr, (float)iScale );
#endif // _XBOX
}
void FX_DustImpact( const Vector &origin, trace_t *tr, float flScale )
{
	//
	// PC version
	//

	VPROF_BUDGET( "FX_DustImpact", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
	Vector	offset;
	float	spread = 0.2f;
	
	CSmartPtr<CDustParticle> pSimple = CDustParticle::Create( "dust" );
	pSimple->SetSortOrigin( origin );

	SimpleParticle	*pParticle;

	Vector	color;
	float	colorRamp;

	GetColorForSurface( tr, &color );

	int i;
	for ( i = 0; i < 4; i++ )
	{
		pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[0], origin );

		if ( pParticle != NULL )
		{
			pParticle->m_flLifetime = 0.0f;
			pParticle->m_flDieTime	= random->RandomFloat( 0.5f, 1.0f );

			pParticle->m_vecVelocity.Random( -spread, spread );
			pParticle->m_vecVelocity += ( tr->plane.normal * random->RandomFloat( 1.0f, 6.0f ) );
			
			VectorNormalize( pParticle->m_vecVelocity );

			float	fForce = random->RandomFloat( 250, 500 ) * i;

			// scaled
			pParticle->m_vecVelocity *= fForce * flScale;
			
			colorRamp = random->RandomFloat( 0.75f, 1.25f );

			pParticle->m_uchColor[0]	= min( 1.0f, color[0] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[1]	= min( 1.0f, color[1] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[2]	= min( 1.0f, color[2] * colorRamp ) * 255.0f;
			
			// scaled
			pParticle->m_uchStartSize	= ( unsigned char )( flScale * random->RandomInt( 3, 4 ) * (i+1) );

			// scaled
			pParticle->m_uchEndSize		= ( unsigned char )( flScale * pParticle->m_uchStartSize * 4 );
			
			pParticle->m_uchStartAlpha	= random->RandomInt( 32, 255 );
			pParticle->m_uchEndAlpha	= 0;
			
			pParticle->m_flRoll			= random->RandomInt( 0, 360 );
			pParticle->m_flRollDelta	= random->RandomFloat( -8.0f, 8.0f );
		}
	}			

	//Dust specs
	for ( i = 0; i < 4; i++ )
	{
		pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin );

		if ( pParticle != NULL )
		{
			pParticle->m_flLifetime = 0.0f;
			pParticle->m_flDieTime	= random->RandomFloat( 0.25f, 0.75f );

			pParticle->m_vecVelocity.Random( -spread, spread );
			pParticle->m_vecVelocity += ( tr->plane.normal * random->RandomFloat( 1.0f, 6.0f ) );
			
			VectorNormalize( pParticle->m_vecVelocity );

			float	fForce = random->RandomFloat( 250, 500 ) * i;

			pParticle->m_vecVelocity *= fForce;
			
			colorRamp = random->RandomFloat( 0.75f, 1.25f );

			pParticle->m_uchColor[0]	= min( 1.0f, color[0] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[1]	= min( 1.0f, color[1] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[2]	= min( 1.0f, color[2] * colorRamp ) * 255.0f;
			
			pParticle->m_uchStartSize	= random->RandomInt( 2, 4 ) * (i+1);
			pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 2;
			
			pParticle->m_uchStartAlpha	= 255;
			pParticle->m_uchEndAlpha	= 0;
			
			pParticle->m_flRoll			= random->RandomInt( 0, 360 );
			pParticle->m_flRollDelta	= random->RandomFloat( -2.0f, 2.0f );
		}
	}

	//Impact hit
	for ( i = 0; i < 4; i++ )
	{
		pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[0], origin );

		if ( pParticle != NULL )
		{
			offset = origin;
			offset[0] += random->RandomFloat( -8.0f, 8.0f );
			offset[1] += random->RandomFloat( -8.0f, 8.0f );

			pParticle->m_flLifetime = 0.0f;
			pParticle->m_flDieTime	= random->RandomFloat( 0.5f, 1.0f );

			spread = 1.0f;

			pParticle->m_vecVelocity.Random( -spread, spread );
			pParticle->m_vecVelocity += tr->plane.normal;
			
			VectorNormalize( pParticle->m_vecVelocity );

			float	fForce = random->RandomFloat( 0, 50 );

			pParticle->m_vecVelocity *= fForce;
			
			colorRamp = random->RandomFloat( 0.75f, 1.25f );

			pParticle->m_uchColor[0]	= min( 1.0f, color[0] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[1]	= min( 1.0f, color[1] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[2]	= min( 1.0f, color[2] * colorRamp ) * 255.0f;
			
			pParticle->m_uchStartSize	= random->RandomInt( 1, 4 );
			pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 4;
			
			pParticle->m_uchStartAlpha	= random->RandomInt( 32, 64 );
			pParticle->m_uchEndAlpha	= 0;
			
			pParticle->m_flRoll			= random->RandomInt( 0, 360 );
			pParticle->m_flRollDelta	= random->RandomFloat( -16.0f, 16.0f );
		}
	}			
}
Example #7
0
//-----------------------------------------------------------------------------
// Purpose: Debris flecks caused by impacts
// Input  : origin - start
//			*trace - trace information
//			*materialName - material hit
//			materialType - type of material hit
//-----------------------------------------------------------------------------
void FX_DebrisFlecks(const Vector& origin, trace_t *tr, char materialType, int iScale, bool bNoFlecks)
{
    VPROF_BUDGET("FX_DebrisFlecks", VPROF_BUDGETGROUP_PARTICLE_RENDERING);

    if (!fx_drawimpactdebris.GetBool())
        return;
    //
    // PC version
    //

    Vector	color;
    GetColorForSurface(tr, &color);

    if (!bNoFlecks)
    {
        CreateFleckParticles(origin, color, tr, materialType, iScale);
    }

    //
    // Dust trail
    //
    Vector	offset = tr->endpos + (tr->plane.normal * 2.0f);

    SimpleParticle newParticle;

    int i;
    for (i = 0; i < 2; i++)
    {
        newParticle.m_Pos = offset;

        newParticle.m_flLifetime = 0.0f;
        newParticle.m_flDieTime = 1.0f;

        Vector dir;
        dir[0] = tr->plane.normal[0] + random->RandomFloat(-0.8f, 0.8f);
        dir[1] = tr->plane.normal[1] + random->RandomFloat(-0.8f, 0.8f);
        dir[2] = tr->plane.normal[2] + random->RandomFloat(-0.8f, 0.8f);

        newParticle.m_uchStartSize = random->RandomInt(2, 4) * iScale;
        newParticle.m_uchEndSize = newParticle.m_uchStartSize * 8 * iScale;

        newParticle.m_vecVelocity = dir * random->RandomFloat(2.0f, 24.0f)*(i + 1);
        newParticle.m_vecVelocity[2] -= random->RandomFloat(8.0f, 32.0f)*(i + 1);

        newParticle.m_uchStartAlpha = random->RandomInt(100, 200);
        newParticle.m_uchEndAlpha = 0;

        newParticle.m_flRoll = random->RandomFloat(0, 360);
        newParticle.m_flRollDelta = random->RandomFloat(-1, 1);

        float colorRamp = random->RandomFloat(0.5f, 1.25f);

        newParticle.m_uchColor[0] = MIN(1.0f, color[0] * colorRamp)*255.0f;
        newParticle.m_uchColor[1] = MIN(1.0f, color[1] * colorRamp)*255.0f;
        newParticle.m_uchColor[2] = MIN(1.0f, color[2] * colorRamp)*255.0f;

        AddSimpleParticle(&newParticle, g_Mat_DustPuff[0]);
    }


    for (i = 0; i < 4; i++)
    {
        newParticle.m_Pos = offset;

        newParticle.m_flLifetime = 0.0f;
        newParticle.m_flDieTime = random->RandomFloat(0.25f, 0.5f);

        Vector dir;
        dir[0] = tr->plane.normal[0] + random->RandomFloat(-0.8f, 0.8f);
        dir[1] = tr->plane.normal[1] + random->RandomFloat(-0.8f, 0.8f);
        dir[2] = tr->plane.normal[2] + random->RandomFloat(-0.8f, 0.8f);

        newParticle.m_uchStartSize = random->RandomInt(1, 4);
        newParticle.m_uchEndSize = newParticle.m_uchStartSize * 4;

        newParticle.m_vecVelocity = dir * random->RandomFloat(8.0f, 32.0f);
        newParticle.m_vecVelocity[2] -= random->RandomFloat(8.0f, 64.0f);

        newParticle.m_uchStartAlpha = 255;
        newParticle.m_uchEndAlpha = 0;

        newParticle.m_flRoll = random->RandomFloat(0, 360);
        newParticle.m_flRollDelta = random->RandomFloat(-2.0f, 2.0f);

        float colorRamp = random->RandomFloat(0.5f, 1.25f);

        newParticle.m_uchColor[0] = MIN(1.0f, color[0] * colorRamp)*255.0f;
        newParticle.m_uchColor[1] = MIN(1.0f, color[1] * colorRamp)*255.0f;
        newParticle.m_uchColor[2] = MIN(1.0f, color[2] * colorRamp)*255.0f;

        AddSimpleParticle(&newParticle, g_Mat_BloodPuff[0]);
    }

    //
    // Bullet hole capper
    //
    newParticle.m_Pos = offset;

    newParticle.m_flLifetime = 0.0f;
    newParticle.m_flDieTime = random->RandomFloat(1.0f, 1.5f);

    Vector dir;
    dir[0] = tr->plane.normal[0] + random->RandomFloat(-0.8f, 0.8f);
    dir[1] = tr->plane.normal[1] + random->RandomFloat(-0.8f, 0.8f);
    dir[2] = tr->plane.normal[2] + random->RandomFloat(-0.8f, 0.8f);

    newParticle.m_uchStartSize = random->RandomInt(4, 8);
    newParticle.m_uchEndSize = newParticle.m_uchStartSize * 4.0f;

    newParticle.m_vecVelocity = dir * random->RandomFloat(2.0f, 24.0f);
    newParticle.m_vecVelocity[2] = random->RandomFloat(-2.0f, 2.0f);

    newParticle.m_uchStartAlpha = random->RandomInt(100, 200);
    newParticle.m_uchEndAlpha = 0;

    newParticle.m_flRoll = random->RandomFloat(0, 360);
    newParticle.m_flRollDelta = random->RandomFloat(-2, 2);

    float colorRamp = random->RandomFloat(0.5f, 1.25f);

    newParticle.m_uchColor[0] = MIN(1.0f, color[0] * colorRamp)*255.0f;
    newParticle.m_uchColor[1] = MIN(1.0f, color[1] * colorRamp)*255.0f;
    newParticle.m_uchColor[2] = MIN(1.0f, color[2] * colorRamp)*255.0f;

    AddSimpleParticle(&newParticle, g_Mat_DustPuff[0]);
}
//-----------------------------------------------------------------------------
// Purpose: Build impact
//-----------------------------------------------------------------------------
void FX_BuildImpact( const Vector &origin, const QAngle &vecAngles, const Vector &vecNormal, float flScale, bool bGround = false, CBaseEntity *pIgnore = NULL )
{
	Vector	offset;
	float	spread = 0.1f;
	
	CSmartPtr<CDustParticle> pSimple = CDustParticle::Create( "dust" );
	pSimple->SetSortOrigin( origin );

	SimpleParticle	*pParticle;

	Vector color( 0.35, 0.35, 0.35 );
	float  colorRamp;

	// If we're hitting the ground, try and get the ground color
	if ( bGround )
	{
		trace_t	tr;
		UTIL_TraceLine( origin, origin + Vector(0,0,-32), MASK_SHOT, pIgnore, COLLISION_GROUP_NONE, &tr );
		GetColorForSurface( &tr, &color );
	}

	int iNumPuffs = 8;
	for ( int i = 0; i < iNumPuffs; i++ )
	{
		QAngle vecTemp = vecAngles;
		vecTemp[YAW] += (360 / iNumPuffs) * i;
		Vector vecForward;
		AngleVectors( vecTemp, &vecForward );

		pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "particle/particle_smokegrenade" ), origin );

		if ( pParticle != NULL )
		{
			pParticle->m_flLifetime = 0.0f;
			pParticle->m_flDieTime	= RandomFloat( 0.5f, 1.0f );

			pParticle->m_vecVelocity.Random( -spread, spread );
			pParticle->m_vecVelocity += ( vecForward * RandomFloat( 1.0f, 6.0f ) );
			
			VectorNormalize( pParticle->m_vecVelocity );

			float	fForce = RandomFloat( 500, 750 );

			// scaled
			pParticle->m_vecVelocity *= fForce * flScale;
			
			colorRamp = RandomFloat( 0.75f, 1.25f );
			pParticle->m_uchColor[0]	= min( 1.0f, color[0] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[1]	= min( 1.0f, color[1] * colorRamp ) * 255.0f;
			pParticle->m_uchColor[2]	= min( 1.0f, color[2] * colorRamp ) * 255.0f;
			
			// scaled
			pParticle->m_uchStartSize	= flScale * RandomInt( 15, 20 );

			// scaled
			pParticle->m_uchEndSize		= flScale * pParticle->m_uchStartSize * 4;
			
			pParticle->m_uchStartAlpha	= RandomInt( 32, 255 );
			pParticle->m_uchEndAlpha	= 0;
			
			pParticle->m_flRoll			= RandomInt( 0, 360 );
			pParticle->m_flRollDelta	= RandomFloat( -8.0f, 8.0f );
		}
	}			
}
void FX_DebrisFlecks( Vector& origin, trace_t *trace, char materialType, int iScale )
{
	VPROF_BUDGET( "FX_DebrisFlecks", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
	Vector	spawnOffset	= trace->endpos + ( trace->plane.normal * 1.0f );

	CSmartPtr<CFleckParticles> fleckEmitter = CFleckParticles::Create( "FX_DebrisFlecks" );

	if ( !fleckEmitter )
		return;

	fleckEmitter->SetSortOrigin( spawnOffset );

	// Handle increased scale
	float flMaxSpeed = FLECK_MAX_SPEED * iScale;
	float flAngularSpray = max( 0.2, FLECK_ANGULAR_SPRAY - ( (float)iScale * 0.2f) ); // More power makes the spray more controlled

	//Setup our collision information
	fleckEmitter->m_ParticleCollision.Setup( spawnOffset, &trace->plane.normal, flAngularSpray, FLECK_MIN_SPEED, flMaxSpeed, FLECK_GRAVITY, FLECK_DAMPEN );

	PMaterialHandle	hMaterial[2];
	
	switch ( materialType )
	{
	case CHAR_TEX_CONCRETE:
	default:
		hMaterial[0] = fleckEmitter->GetPMaterial( "effects/fleck_cement1" );
		hMaterial[1] = fleckEmitter->GetPMaterial( "effects/fleck_cement2" );
		break;
	}

	Vector	dir, end;
	
	Vector	color;
	float	colorRamp;

	GetColorForSurface( trace, &color );

	int	numFlecks = random->RandomInt( 4, 16 ) * iScale;

	FleckParticle	*pFleckParticle;

	//Dump out flecks
	int i;
	for ( i = 0; i < numFlecks; i++ )
	{
		pFleckParticle = (FleckParticle *) fleckEmitter->AddParticle( sizeof(FleckParticle), hMaterial[random->RandomInt(0,1)], spawnOffset );

		if ( pFleckParticle == NULL )
			break;

		pFleckParticle->m_flLifetime	= 0.0f;
		pFleckParticle->m_flDieTime		= 3.0f;

		dir[0] = trace->plane.normal[0] + random->RandomFloat( -flAngularSpray, flAngularSpray );
		dir[1] = trace->plane.normal[1] + random->RandomFloat( -flAngularSpray, flAngularSpray );
		dir[2] = trace->plane.normal[2] + random->RandomFloat( -flAngularSpray, flAngularSpray );

		pFleckParticle->m_uchSize		= random->RandomInt( 1, 2 );

		pFleckParticle->m_vecVelocity	= dir * ( random->RandomFloat( FLECK_MIN_SPEED, flMaxSpeed) * ( 3 - pFleckParticle->m_uchSize ) );
		
		pFleckParticle->m_flRoll		= random->RandomFloat( 0, 360 );
		pFleckParticle->m_flRollDelta	= random->RandomFloat( 0, 360 );

		colorRamp = random->RandomFloat( 0.75f, 1.25f );

		pFleckParticle->m_uchColor[0] = min( 1.0f, color[0]*colorRamp )*255.0f;
		pFleckParticle->m_uchColor[1] = min( 1.0f, color[1]*colorRamp )*255.0f;
		pFleckParticle->m_uchColor[2] = min( 1.0f, color[2]*colorRamp )*255.0f;
	}

	//
	// Dust trail
	//
	Vector	offset = trace->endpos + ( trace->plane.normal * 2.0f );

	SimpleParticle newParticle;
	hMaterial[0] = g_ParticleMgr.GetPMaterial( "particle/particle_smokegrenade" );

	for ( i = 0; i < 2; i++ )
	{
		newParticle.m_Pos = offset;

		newParticle.m_flLifetime	= 0.0f;
		newParticle.m_flDieTime	= 1.0f;
		
		dir[0] = trace->plane.normal[0] + random->RandomFloat( -0.8f, 0.8f );
		dir[1] = trace->plane.normal[1] + random->RandomFloat( -0.8f, 0.8f );
		dir[2] = trace->plane.normal[2] + random->RandomFloat( -0.8f, 0.8f );

		newParticle.m_uchStartSize	= random->RandomInt( 2, 4 ) * iScale;
		newParticle.m_uchEndSize	= newParticle.m_uchStartSize * 8 * iScale;

		newParticle.m_vecVelocity = dir * random->RandomFloat( 2.0f, 24.0f )*(i+1);
		newParticle.m_vecVelocity[2] -= random->RandomFloat( 8.0f, 32.0f )*(i+1);

		newParticle.m_uchStartAlpha	= random->RandomInt( 100, 200 );
		newParticle.m_uchEndAlpha	= 0;
		
		newParticle.m_flRoll			= random->RandomFloat( 0, 360 );
		newParticle.m_flRollDelta	= random->RandomFloat( -1, 1 );

		colorRamp = random->RandomFloat( 0.5f, 1.25f );

		newParticle.m_uchColor[0] = min( 1.0f, color[0]*colorRamp )*255.0f;
		newParticle.m_uchColor[1] = min( 1.0f, color[1]*colorRamp )*255.0f;
		newParticle.m_uchColor[2] = min( 1.0f, color[2]*colorRamp )*255.0f;

		AddSimpleParticle( &newParticle, hMaterial[0] );
	}

	for ( i = 0; i < 4; i++ )
	{
		newParticle.m_Pos = offset;

		newParticle.m_flLifetime	= 0.0f;
		newParticle.m_flDieTime	= random->RandomFloat( 0.25f, 0.5f );
		
		dir[0] = trace->plane.normal[0] + random->RandomFloat( -0.8f, 0.8f );
		dir[1] = trace->plane.normal[1] + random->RandomFloat( -0.8f, 0.8f );
		dir[2] = trace->plane.normal[2] + random->RandomFloat( -0.8f, 0.8f );

		newParticle.m_uchStartSize	= random->RandomInt( 1, 4 );
		newParticle.m_uchEndSize	= newParticle.m_uchStartSize * 4;

		newParticle.m_vecVelocity = dir * random->RandomFloat( 8.0f, 32.0f );
		newParticle.m_vecVelocity[2] -= random->RandomFloat( 8.0f, 64.0f );

		newParticle.m_uchStartAlpha	= 255;
		newParticle.m_uchEndAlpha	= 0;
		
		newParticle.m_flRoll			= random->RandomFloat( 0, 360 );
		newParticle.m_flRollDelta	= random->RandomFloat( -2.0f, 2.0f );

		colorRamp = random->RandomFloat( 0.5f, 1.25f );

		newParticle.m_uchColor[0] = min( 1.0f, color[0]*colorRamp )*255.0f;
		newParticle.m_uchColor[1] = min( 1.0f, color[1]*colorRamp )*255.0f;
		newParticle.m_uchColor[2] = min( 1.0f, color[2]*colorRamp )*255.0f;

		AddSimpleParticle( &newParticle, g_ParticleMgr.GetPMaterial("effects/blood") );
	}

	//
	// Bullet hole capper
	//
	newParticle.m_Pos = offset;

	newParticle.m_flLifetime		= 0.0f;
	newParticle.m_flDieTime		= random->RandomFloat( 1.0f, 1.5f );

	dir[0] = trace->plane.normal[0] + random->RandomFloat( -0.8f, 0.8f );
	dir[1] = trace->plane.normal[1] + random->RandomFloat( -0.8f, 0.8f );
	dir[2] = trace->plane.normal[2] + random->RandomFloat( -0.8f, 0.8f );

	newParticle.m_uchStartSize	= random->RandomInt( 4, 8 );
	newParticle.m_uchEndSize		= newParticle.m_uchStartSize * 4.0f;

	newParticle.m_vecVelocity = dir * random->RandomFloat( 2.0f, 24.0f );
	newParticle.m_vecVelocity[2] = random->RandomFloat( -2.0f, 2.0f );

	newParticle.m_uchStartAlpha	= random->RandomInt( 100, 200 );
	newParticle.m_uchEndAlpha	= 0;
	
	newParticle.m_flRoll			= random->RandomFloat( 0, 360 );
	newParticle.m_flRollDelta	= random->RandomFloat( -2, 2 );

	colorRamp = random->RandomFloat( 0.5f, 1.25f );

	newParticle.m_uchColor[0] = min( 1.0f, color[0]*colorRamp )*255.0f;
	newParticle.m_uchColor[1] = min( 1.0f, color[1]*colorRamp )*255.0f;
	newParticle.m_uchColor[2] = min( 1.0f, color[2]*colorRamp )*255.0f;

	AddSimpleParticle( &newParticle, hMaterial[0] );
}