Example #1
0
void C_SteamJet::UpdateLightingRamp()
{
	if( VectorsAreEqual( m_vLastRampUpdatePos, GetAbsOrigin(), 0.1 ) && 
		QAnglesAreEqual( m_vLastRampUpdateAngles, GetAbsAngles(), 0.1 ) )
	{
		return;
	}

	m_vLastRampUpdatePos = GetAbsOrigin();
	m_vLastRampUpdateAngles = GetAbsAngles();

	// Sample the world lighting where we think the particles will be.
	Vector forward, right, up;
	AngleVectors(GetAbsAngles(), &forward, &right, &up);

	// Legacy env_steamjet entities faced left instead of forward.
	if (m_bFaceLeft)
	{
		Vector temp = forward;
		forward = -right;
		right = temp;
	}

	Vector startPos = GetAbsOrigin();
	Vector endPos = GetAbsOrigin() + forward * (m_Speed * m_Lifetime);

	for(int iRamp=0; iRamp < STEAMJET_NUMRAMPS; iRamp++)
	{
		float t = (float)iRamp / (STEAMJET_NUMRAMPS-1);
		Vector vTestPos = startPos + (endPos - startPos) * t;
		
		Vector *pRamp = &m_Ramps[iRamp];
		*pRamp = WorldGetLightForPoint(vTestPos, false);
		
		if ( IsEmissive() )
		{
			pRamp->x += (m_clrRender->r/255.0f);
			pRamp->y += (m_clrRender->g/255.0f);
			pRamp->z += (m_clrRender->b/255.0f);

			pRamp->x = clamp( pRamp->x, 0.0f, 1.0f );
			pRamp->y = clamp( pRamp->y, 0.0f, 1.0f );
			pRamp->z = clamp( pRamp->z, 0.0f, 1.0f );
		}
		else
		{
			pRamp->x *= (m_clrRender->r/255.0f);
			pRamp->y *= (m_clrRender->g/255.0f);
			pRamp->z *= (m_clrRender->b/255.0f);
		}

		// Renormalize?
		float maxVal = max(pRamp->x, max(pRamp->y, pRamp->z));
		if(maxVal > 1)
		{
			*pRamp = *pRamp / maxVal;
		}
	}
}
Example #2
0
//-----------------------------------------------------------------------------
// Spew out dust!
//-----------------------------------------------------------------------------
void FX_Dust( const Vector &vecOrigin, const Vector &vecDirection, float flSize, float flSpeed )
{
	VPROF_BUDGET( "FX_Dust", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
	
	int	numPuffs = (flSize*0.5f);

	if ( numPuffs < 1 )
		numPuffs = 1;
	if ( numPuffs > 32 )
		numPuffs = 32;

	float speed = flSpeed * 0.1f;

	if ( speed < 0 )
		speed = 1.0f;
	if (speed > 48.0f )
		speed = 48.0f;

	//FIXME: Better sampling area
	Vector offset = vecOrigin + ( vecDirection * flSize );

	//Find area ambient light color and use it to tint smoke
	Vector	worldLight = WorldGetLightForPoint( offset, true );

	// Throw puffs
	SimpleParticle particle;
	for ( int i = 0; i < numPuffs; i++ )
	{
		offset.Random( -(flSize*0.25f), flSize*0.25f );
		offset += vecOrigin + ( vecDirection * flSize );

		particle.m_Pos = offset;
		particle.m_flLifetime = 0.0f;
		particle.m_flDieTime  = random->RandomFloat( 0.4f, 1.0f );
		
		particle.m_vecVelocity = vecDirection * random->RandomFloat( speed*0.5f, speed ) * i;
		particle.m_vecVelocity[2] = 0.0f;

		int	color = random->RandomInt( 48, 64 );

		particle.m_uchColor[0] = (color+16) + ( worldLight[0] * (float) color );
		particle.m_uchColor[1] = (color+8) + ( worldLight[1] * (float) color );
		particle.m_uchColor[2] = color + ( worldLight[2] * (float) color );

		particle.m_uchStartAlpha= random->RandomInt( 64, 128 );
		particle.m_uchEndAlpha	= 0;
		particle.m_uchStartSize = random->RandomInt( 2, 8 );
		particle.m_uchEndSize	= random->RandomInt( 24, 48 );
		particle.m_flRoll		= random->RandomInt( 0, 360 );
		particle.m_flRollDelta	= random->RandomFloat( -0.5f, 0.5f );

		AddSimpleParticle( &particle, g_Mat_DustPuff[random->RandomInt(0,1)] );
	}
}
Example #3
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &data - 
//-----------------------------------------------------------------------------
void WheelDustCallback( const CEffectData &data )
{
	CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" );
	pSimple->SetSortOrigin( data.m_vOrigin );
	pSimple->SetNearClip( 32, 64 );

	SimpleParticle	*pParticle;

	Vector	offset;

	//FIXME: Better sampling area
	offset = data.m_vOrigin + ( data.m_vNormal * data.m_flScale );
	
	//Find area ambient light color and use it to tint smoke
	Vector	worldLight = WorldGetLightForPoint( offset, true );

	//Throw puffs
	offset.Random( -(data.m_flScale*16.0f), data.m_flScale*16.0f );
	offset.z = 0.0f;
	offset += data.m_vOrigin + ( data.m_vNormal * data.m_flScale );

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

	if ( pParticle != NULL )
	{			
		pParticle->m_flLifetime		= 0.0f;
		pParticle->m_flDieTime		= random->RandomFloat( 0.25f, 0.5f );
		
		pParticle->m_vecVelocity = RandomVector( -1.0f, 1.0f );
		VectorNormalize( pParticle->m_vecVelocity );
		pParticle->m_vecVelocity[2] += random->RandomFloat( 16.0f, 32.0f ) * (data.m_flScale*2.0f);

		int	color = random->RandomInt( 100, 150 );

		pParticle->m_uchColor[0] = 16 + ( worldLight[0] * (float) color );
		pParticle->m_uchColor[1] = 8 + ( worldLight[1] * (float) color );
		pParticle->m_uchColor[2] = ( worldLight[2] * (float) color );

		pParticle->m_uchStartAlpha	= random->RandomInt( 64.0f*data.m_flScale, 128.0f*data.m_flScale );
		pParticle->m_uchEndAlpha	= 0;
		pParticle->m_uchStartSize	= random->RandomInt( 16, 24 ) * data.m_flScale;
		pParticle->m_uchEndSize		= random->RandomInt( 32, 48 ) * data.m_flScale;
		pParticle->m_flRoll			= random->RandomInt( 0, 360 );
		pParticle->m_flRollDelta	= random->RandomFloat( -2.0f, 2.0f );
	}
}
Example #4
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &origin - 
//			&normal - 
//			scale - 
//			r - 
//			g - 
//			b - 
//			flags - 
//-----------------------------------------------------------------------------
void FX_BloodSpray( const Vector &origin, const Vector &normal, float scale, unsigned char r, unsigned char g, unsigned char b, int flags )
{
	if ( UTIL_IsLowViolence() )
		return;

	//debugoverlay->AddLineOverlay( origin, origin + normal * 72, 255, 255, 255, true, 10 ); 

	Vector offset;
	float spread	= 0.2f;
	
	//Find area ambient light color and use it to tint smoke
	Vector worldLight = WorldGetLightForPoint( origin, true );
	Vector color = Vector( (float)(worldLight[0] * r) / 255.0f, (float)(worldLight[1] * g) / 255.0f, (float)(worldLight[2] * b) / 255.0f );
	float colorRamp;

	int i;

	Vector	offDir;

	Vector right;
	Vector up;

	if (normal != Vector(0, 0, 1) )
	{
		right = normal.Cross( Vector(0, 0, 1) );
		up = right.Cross( normal );
	}
	else
	{
		right = Vector(0, 0, 1);
		up = right.Cross( normal );
	}

	//
	// Dump out drops
	//
	if (flags & FX_BLOODSPRAY_DROPS)
	{
		TrailParticle *tParticle;

		CSmartPtr<CTrailParticles> pTrailEmitter = CTrailParticles::Create( "blooddrops" );
		if ( !pTrailEmitter )
			return;

		pTrailEmitter->SetSortOrigin( origin );

		// Partial gravity on blood drops.
		pTrailEmitter->SetGravity( 600.0 ); 

		pTrailEmitter->GetBinding().SetBBox( origin - Vector( 32, 32, 32 ), origin + Vector( 32, 32, 32 ) );
		pTrailEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN );
		pTrailEmitter->SetVelocityDampen( 0.2f );

		PMaterialHandle	hMaterial = ParticleMgr()->GetPMaterial( "effects/blood_drop" );

		//
		// Long stringy drops of blood.
		//
		for ( i = 0; i < 14; i++ )
		{
			// Originate from within a circle 'scale' inches in diameter.
			offset = origin;
			offset += right * random->RandomFloat( -0.5f, 0.5f ) * scale;
			offset += up * random->RandomFloat( -0.5f, 0.5f ) * scale;

			tParticle = (TrailParticle *) pTrailEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset );

			if ( tParticle == NULL )
				break;

			tParticle->m_flLifetime	= 0.0f;

			offDir = normal + RandomVector( -0.3f, 0.3f );

			tParticle->m_vecVelocity = offDir * random->RandomFloat( 4.0f * scale, 40.0f * scale );
			tParticle->m_vecVelocity[2] += random->RandomFloat( 4.0f, 16.0f ) * scale;

			tParticle->m_flWidth		= random->RandomFloat( 0.125f, 0.275f ) * scale;
			tParticle->m_flLength		= random->RandomFloat( 0.02f, 0.03f ) * scale;
			tParticle->m_flDieTime		= random->RandomFloat( 0.5f, 1.0f );

			FloatToColor32( tParticle->m_color, color[0], color[1], color[2], 1.0f );
		}

		//
		// Shorter droplets.
		//
		for ( i = 0; i < 24; i++ )
		{
			// Originate from within a circle 'scale' inches in diameter.
			offset = origin;
			offset += right * random->RandomFloat( -0.5f, 0.5f ) * scale;
			offset += up * random->RandomFloat( -0.5f, 0.5f ) * scale;

			tParticle = (TrailParticle *) pTrailEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset );

			if ( tParticle == NULL )
				break;

			tParticle->m_flLifetime	= 0.0f;

			offDir = normal + RandomVector( -1.0f, 1.0f );
			offDir[2] += random->RandomFloat(0, 1.0f);

			tParticle->m_vecVelocity = offDir * random->RandomFloat( 2.0f * scale, 25.0f * scale );
			tParticle->m_vecVelocity[2] += random->RandomFloat( 4.0f, 16.0f ) * scale;

			tParticle->m_flWidth		= random->RandomFloat( 0.25f, 0.375f ) * scale;
			tParticle->m_flLength		= random->RandomFloat( 0.0025f, 0.005f ) * scale;
			tParticle->m_flDieTime		= random->RandomFloat( 0.5f, 1.0f );

			FloatToColor32( tParticle->m_color, color[0], color[1], color[2], 1.0f );
		}
	}

	if ((flags & FX_BLOODSPRAY_GORE) || (flags & FX_BLOODSPRAY_CLOUD))
	{
		CSmartPtr<CBloodSprayEmitter> pSimple = CBloodSprayEmitter::Create( "bloodgore" );
		if ( !pSimple )
			return;

		pSimple->SetSortOrigin( origin );
		pSimple->SetGravity( 0 );

		PMaterialHandle	hMaterial;

		//
		// Tight blossom of blood at the center.
		//
		if (flags & FX_BLOODSPRAY_GORE)
		{
			hMaterial = ParticleMgr()->GetPMaterial( "effects/blood_gore" );

			SimpleParticle *pParticle;

			for ( i = 0; i < 6; i++ )
			{
				// Originate from within a circle 'scale' inches in diameter.
				offset = origin + ( 0.5 * scale * normal );
				offset += right * random->RandomFloat( -0.5f, 0.5f ) * scale;
				offset += up * random->RandomFloat( -0.5f, 0.5f ) * scale;

				pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), hMaterial, offset );

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

					spread = 0.2f;
					pParticle->m_vecVelocity.Random( -spread, spread );
					pParticle->m_vecVelocity += normal * random->RandomInt( 10, 100 );
					//VectorNormalize( pParticle->m_vecVelocity );

					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->RandomFloat( scale * 0.25, scale );
					pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 2;
					
					pParticle->m_uchStartAlpha	= random->RandomInt( 200, 255 );
					pParticle->m_uchEndAlpha	= 0;
					
					pParticle->m_flRoll			= random->RandomInt( 0, 360 );
					pParticle->m_flRollDelta	= 0.0f;
				}
			}
		}

		//
		// Diffuse cloud just in front of the exit wound.
		//
		if (flags & FX_BLOODSPRAY_CLOUD)
		{
			hMaterial = ParticleMgr()->GetPMaterial( "effects/blood_puff" );

			SimpleParticle *pParticle;

			for ( i = 0; i < 6; i++ )
			{
				// Originate from within a circle '2 * scale' inches in diameter.
				offset = origin + ( scale * normal );
				offset += right * random->RandomFloat( -1, 1 ) * scale;
				offset += up * random->RandomFloat( -1, 1 ) * scale;

				pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), hMaterial, offset );

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

					spread = 0.5f;
					pParticle->m_vecVelocity.Random( -spread, spread );
					pParticle->m_vecVelocity += normal * random->RandomInt( 100, 200 );

					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->RandomFloat( scale * 1.5f, scale * 2.0f );
					pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 4;
					
					pParticle->m_uchStartAlpha	= random->RandomInt( 80, 128 );
					pParticle->m_uchEndAlpha	= 0;
					
					pParticle->m_flRoll			= random->RandomInt( 0, 360 );
					pParticle->m_flRollDelta	= 0.0f;
				}
			}
		}
	}

	// TODO: Play a sound?
	//CLocalPlayerFilter filter;
	//C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, CHAN_VOICE, "Physics.WaterSplash", 1.0, ATTN_NORM, 0, 100, &origin );
}
Example #5
0
//-----------------------------------------------------------------------------
// Purpose: Used for bullets hitting bleeding surfaces
// Input  : origin - 
//			normal - 
//			scale - This parameter is not currently used
//-----------------------------------------------------------------------------
void FX_BloodBulletImpact( const Vector &origin, const Vector &normal, float scale /*NOTE: Unused!*/, unsigned char r, unsigned char g, unsigned char b )
{
	if ( UTIL_IsLowViolence() )
		return;

	Vector offset;
	
	//Find area ambient light color and use it to tint smoke
	Vector worldLight = WorldGetLightForPoint( origin, true );
	
	if ( gpGlobals->maxClients > 1 )
	{
		worldLight = Vector( 1.0, 1.0, 1.0 );
		r = 96;
		g = 0;
		b = 10;
	}

	Vector color = Vector( (float)(worldLight[0] * r) / 255.0f, (float)(worldLight[1] * g) / 255.0f, (float)(worldLight[2] * b) / 255.0f );
	float colorRamp;

	Vector	offDir;

	CSmartPtr<CBloodSprayEmitter> pSimple = CBloodSprayEmitter::Create( "bloodgore" );
	if ( !pSimple )
		return;

	pSimple->SetSortOrigin( origin );
	pSimple->SetGravity( 200 );
	
	// Setup a bounding box to contain the particles without (stops auto-updating)
	pSimple->GetBinding().SetBBox( origin - Vector( 16, 16, 16 ), origin + Vector( 16, 16, 16 ) );

	// Cache the material if we haven't already
	if ( g_Blood_Core == NULL )
	{
		g_Blood_Core = ParticleMgr()->GetPMaterial( "effects/blood_core" );
	}

	SimpleParticle *pParticle;

	Vector	dir = normal * RandomVector( -0.5f, 0.5f );

	offset = origin + ( 2.0f * normal );

	pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Blood_Core, offset );

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

		pParticle->m_vecVelocity	= dir * random->RandomFloat( 16.0f, 32.0f );
		pParticle->m_vecVelocity[2] -= random->RandomFloat( 8.0f, 16.0f );

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

		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 );
		pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 8;
	
		pParticle->m_uchStartAlpha	= 255;
		pParticle->m_uchEndAlpha	= 0;
		
		pParticle->m_flRoll			= random->RandomInt( 0, 360 );
		pParticle->m_flRollDelta	= 0.0f;
	}

	// Cache the material if we haven't already
	if ( g_Blood_Gore == NULL )
	{
		g_Blood_Gore = ParticleMgr()->GetPMaterial( "effects/blood_gore" );
	}

	for ( int i = 0; i < 4; i++ )
	{
		offset = origin + ( 2.0f * normal );

		pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Blood_Gore, offset );

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

			pParticle->m_vecVelocity	= dir * random->RandomFloat( 16.0f, 32.0f )*(i+1);
			pParticle->m_vecVelocity[2] -= random->RandomFloat( 32.0f, 64.0f )*(i+1);

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

			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 );
			pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 4;
		
			pParticle->m_uchStartAlpha	= 255;
			pParticle->m_uchEndAlpha	= 0;
			
			pParticle->m_flRoll			= random->RandomInt( 0, 360 );
			pParticle->m_flRollDelta	= 0.0f;
		}
	}

	//
	// Dump out drops
	//
	TrailParticle *tParticle;

	CSmartPtr<CTrailParticles> pTrailEmitter = CTrailParticles::Create( "blooddrops" );
	if ( !pTrailEmitter )
		return;

	pTrailEmitter->SetSortOrigin( origin );

	// Partial gravity on blood drops
	pTrailEmitter->SetGravity( 400.0 ); 
	
	// Enable simple collisions with nearby surfaces
	pTrailEmitter->Setup(origin, &normal, 1, 10, 100, 400, 0.2, 0 );

	if ( g_Blood_Drops == NULL )
	{
		g_Blood_Drops = ParticleMgr()->GetPMaterial( "effects/blood_drop" );
	}

	//
	// Shorter droplets
	//
	for ( int i = 0; i < 8; i++ )
	{
		// Originate from within a circle 'scale' inches in diameter
		offset = origin;

		tParticle = (TrailParticle *) pTrailEmitter->AddParticle( sizeof(TrailParticle), g_Blood_Drops, offset );

		if ( tParticle == NULL )
			break;

		tParticle->m_flLifetime	= 0.0f;

		offDir = RandomVector( -1.0f, 1.0f );

		tParticle->m_vecVelocity = offDir * random->RandomFloat( 64.0f, 128.0f );

		tParticle->m_flWidth		= random->RandomFloat( 0.5f, 2.0f );
		tParticle->m_flLength		= random->RandomFloat( 0.05f, 0.15f );
		tParticle->m_flDieTime		= random->RandomFloat( 0.25f, 0.5f );

		FloatToColor32( tParticle->m_color, color[0], color[1], color[2], 1.0f );
	}

	// TODO: Play a sound?
	//CLocalPlayerFilter filter;
	//C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, CHAN_VOICE, "Physics.WaterSplash", 1.0, ATTN_NORM, 0, 100, &origin );
}
Example #6
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_BaseExplosionEffect::CreateCore( void )
{
	if ( m_fFlags & TE_EXPLFLAG_NOFIREBALL )
		return;

	Vector	offset;
	int		i;

	//Spread constricts as force rises
	float force = m_flForce;

	//Cap our force
	if ( force < EXPLOSION_FORCE_MIN )
		force = EXPLOSION_FORCE_MIN;
	
	if ( force > EXPLOSION_FORCE_MAX )
		force = EXPLOSION_FORCE_MAX;

	float spread = 1.0f - (0.15f*force);

	SimpleParticle	*pParticle;

	CSmartPtr<CExplosionParticle> pSimple = CExplosionParticle::Create( "exp_smoke" );
	pSimple->SetSortOrigin( m_vecOrigin );
	pSimple->SetNearClip( 64, 128 );

	pSimple->GetBinding().SetBBox( m_vecOrigin - Vector( 128, 128, 128 ), m_vecOrigin + Vector( 128, 128, 128 ) );
	
	if ( m_Material_Smoke == NULL )
	{
		m_Material_Smoke = g_Mat_DustPuff[1];
	}

	//FIXME: Better sampling area
	offset = m_vecOrigin + ( m_vecDirection * 32.0f );

	//Find area ambient light color and use it to tint smoke
	Vector worldLight = WorldGetLightForPoint( offset, true );
	
	Vector	tint;
	float	luminosity;
	if ( worldLight == vec3_origin )
	{
		tint = vec3_origin;
		luminosity = 0.0f;
	}
	else
	{
		UTIL_GetNormalizedColorTintAndLuminosity( worldLight, &tint, &luminosity );
	}

	// We only take a portion of the tint
	tint = (tint * 0.25f)+(Vector(0.75f,0.75f,0.75f));
	
	// Rescale to a character range
	luminosity *= 255;

	if ( (m_fFlags & TE_EXPLFLAG_NOFIREBALLSMOKE) == 0 )
	{
		//
		// Smoke - basic internal filler
		//

		for ( i = 0; i < 4; i++ )
		{
			pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), m_Material_Smoke, m_vecOrigin );

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

	#ifdef INVASION_CLIENT_DLL
				pParticle->m_flDieTime	= random->RandomFloat( 0.5f, 1.0f );
	#endif
	#ifdef _XBOX
				pParticle->m_flDieTime	= 1.0f;
	#else
				pParticle->m_flDieTime	= random->RandomFloat( 2.0f, 3.0f );
	#endif

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

				float	fForce = random->RandomFloat( 1, 750 ) * force;

				//Scale the force down as we fall away from our main direction
				ScaleForceByDeviation( pParticle->m_vecVelocity, m_vecDirection, spread, &fForce );

				pParticle->m_vecVelocity *= fForce;
				
				#if __EXPLOSION_DEBUG
				debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 );
				#endif

				int nColor = random->RandomInt( luminosity*0.5f, luminosity );
				pParticle->m_uchColor[0] = ( worldLight[0] * nColor );
				pParticle->m_uchColor[1] = ( worldLight[1] * nColor );
				pParticle->m_uchColor[2] = ( worldLight[2] * nColor );
				
				pParticle->m_uchStartSize	= 72;
				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 );
			}
		}


		//
		// Inner core
		//

#ifndef _XBOX

		for ( i = 0; i < 8; i++ )
		{
			offset.Random( -16.0f, 16.0f );
			offset += m_vecOrigin;

			pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), m_Material_Smoke, offset );

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

	#ifdef INVASION_CLIENT_DLL
				pParticle->m_flDieTime	= random->RandomFloat( 0.5f, 1.0f );
	#else
				pParticle->m_flDieTime	= random->RandomFloat( 0.5f, 1.0f );
	#endif

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

				float	fForce = random->RandomFloat( 1, 2000 ) * force;

				//Scale the force down as we fall away from our main direction
				ScaleForceByDeviation( pParticle->m_vecVelocity, m_vecDirection, spread, &fForce );

				pParticle->m_vecVelocity *= fForce;
				
				#if __EXPLOSION_DEBUG
				debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 );
				#endif

				int nColor = random->RandomInt( luminosity*0.5f, luminosity );
				pParticle->m_uchColor[0] = ( worldLight[0] * nColor );
				pParticle->m_uchColor[1] = ( worldLight[1] * nColor );
				pParticle->m_uchColor[2] = ( worldLight[2] * nColor );
						
				pParticle->m_uchStartSize	= random->RandomInt( 32, 64 );
				pParticle->m_uchEndSize		= pParticle->m_uchStartSize * 2;

				pParticle->m_uchStartAlpha	= random->RandomFloat( 128, 255 );
				pParticle->m_uchEndAlpha	= 0;
				
				pParticle->m_flRoll			= random->RandomInt( 0, 360 );
				pParticle->m_flRollDelta	= random->RandomFloat( -8.0f, 8.0f );
			}
		}
#endif // !_XBOX

		//
		// Ground ring
		//

		Vector	vRight, vUp;
		VectorVectors( m_vecDirection, vRight, vUp );

		Vector	forward;

#ifndef INVASION_CLIENT_DLL

#ifndef _XBOX 
		int	numRingSprites = 32;
#else
		int	numRingSprites = 8;
#endif

		float flIncr = (2*M_PI) / (float) numRingSprites; // Radians
		float flYaw = 0.0f;

		for ( i = 0; i < numRingSprites; i++ )
		{
			flYaw += flIncr;
			SinCos( flYaw, &forward.y, &forward.x );
			forward.z = 0.0f;

			offset = ( RandomVector( -4.0f, 4.0f ) + m_vecOrigin ) + ( forward * random->RandomFloat( 8.0f, 16.0f ) );

			pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), m_Material_Smoke, offset );

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

				pParticle->m_vecVelocity = forward;
			
				float	fForce = random->RandomFloat( 500, 2000 ) * force;

				//Scale the force down as we fall away from our main direction
				ScaleForceByDeviation( pParticle->m_vecVelocity, pParticle->m_vecVelocity, spread, &fForce );

				pParticle->m_vecVelocity *= fForce;
				
				#if __EXPLOSION_DEBUG
				debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 );
				#endif

				int nColor = random->RandomInt( luminosity*0.5f, luminosity );
				pParticle->m_uchColor[0] = ( worldLight[0] * nColor );
				pParticle->m_uchColor[1] = ( worldLight[1] * nColor );
				pParticle->m_uchColor[2] = ( worldLight[2] * nColor );

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

				pParticle->m_uchStartAlpha	= random->RandomFloat( 16, 32 );
				pParticle->m_uchEndAlpha	= 0;
				
				pParticle->m_flRoll			= random->RandomInt( 0, 360 );
				pParticle->m_flRollDelta	= random->RandomFloat( -8.0f, 8.0f );
			}
		}
#endif
	}

#ifndef _XBOX

	//
	// Embers
	//

	if ( m_Material_Embers[0] == NULL )
	{
		m_Material_Embers[0] = pSimple->GetPMaterial( "effects/fire_embers1" );
	}

	if ( m_Material_Embers[1] == NULL )
	{
		m_Material_Embers[1] = pSimple->GetPMaterial( "effects/fire_embers2" );
	}

	for ( i = 0; i < 16; i++ )
	{
		offset.Random( -32.0f, 32.0f );
		offset += m_vecOrigin;

		pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), m_Material_Embers[random->RandomInt(0,1)], offset );

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

			pParticle->m_vecVelocity.Random( -spread*2, spread*2 );
			pParticle->m_vecVelocity += m_vecDirection;
			
			VectorNormalize( pParticle->m_vecVelocity );

			float	fForce = random->RandomFloat( 1.0f, 400.0f );

			//Scale the force down as we fall away from our main direction
			float	vDev = ScaleForceByDeviation( pParticle->m_vecVelocity, m_vecDirection, spread );

			pParticle->m_vecVelocity *= fForce * ( 16.0f * (vDev*vDev*0.5f) );
			
			#if __EXPLOSION_DEBUG
			debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 );
			#endif

			int nColor = random->RandomInt( 192, 255 );
			pParticle->m_uchColor[0]	= pParticle->m_uchColor[1] = pParticle->m_uchColor[2] = nColor;
			
			pParticle->m_uchStartSize	= random->RandomInt( 8, 16 ) * vDev;

			pParticle->m_uchStartSize	= clamp( pParticle->m_uchStartSize, 4, 32 );

			pParticle->m_uchEndSize		= pParticle->m_uchStartSize;
			
			pParticle->m_uchStartAlpha	= 255;
			pParticle->m_uchEndAlpha	= 0;
			
			pParticle->m_flRoll			= random->RandomInt( 0, 360 );
			pParticle->m_flRollDelta	= random->RandomFloat( -8.0f, 8.0f );
		}
	}
#endif // !_XBOX

	//
	// Fireballs
	//

	if ( m_Material_FireCloud == NULL )
	{
		m_Material_FireCloud = pSimple->GetPMaterial( "effects/fire_cloud2" );
	}

#ifndef _XBOX
	int numFireballs = 32;
#else
	int numFireballs = 16;
#endif

	for ( i = 0; i < numFireballs; i++ )
	{
		offset.Random( -48.0f, 48.0f );
		offset += m_vecOrigin;

		pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), m_Material_FireCloud, offset );

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

			pParticle->m_vecVelocity.Random( -spread*0.75f, spread*0.75f );
			pParticle->m_vecVelocity += m_vecDirection;
			
			VectorNormalize( pParticle->m_vecVelocity );

			float	fForce = random->RandomFloat( 400.0f, 800.0f );

			//Scale the force down as we fall away from our main direction
			float	vDev = ScaleForceByDeviation( pParticle->m_vecVelocity, m_vecDirection, spread );

			pParticle->m_vecVelocity *= fForce * ( 16.0f * (vDev*vDev*0.5f) );

			#if __EXPLOSION_DEBUG
			debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 );
			#endif

			int nColor = random->RandomInt( 128, 255 );
			pParticle->m_uchColor[0]	= pParticle->m_uchColor[1] = pParticle->m_uchColor[2] = nColor;
			
			pParticle->m_uchStartSize	= random->RandomInt( 32, 85 ) * vDev;

			pParticle->m_uchStartSize	= clamp( pParticle->m_uchStartSize, 32, 85 );

			pParticle->m_uchEndSize		= (int)((float)pParticle->m_uchStartSize * 1.5f);
			
			pParticle->m_uchStartAlpha	= 255;
			pParticle->m_uchEndAlpha	= 0;
			
			pParticle->m_flRoll			= random->RandomInt( 0, 360 );
			pParticle->m_flRollDelta	= random->RandomFloat( -16.0f, 16.0f );
		}
	}
}
Example #7
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &origin - 
//			&normal - 
//			scale - 
//-----------------------------------------------------------------------------
void StriderBlood( const Vector &origin, const Vector &normal, float scale )
{
	VPROF_BUDGET( "StriderBlood", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
	
	//Find area ambient light color and use it to tint smoke
	Vector worldLight = WorldGetLightForPoint( origin, true );
	Vector	tint;
	float	luminosity;
	UTIL_GetNormalizedColorTintAndLuminosity( worldLight, &tint, &luminosity );

	// We only take a portion of the tint
	tint = (tint * 0.25f)+(Vector(0.75f,0.75f,0.75f));

	// Rescale to a character range
	luminosity = MAX( 200, luminosity*255 );

	CSmartPtr<CSplashParticle> pSimple = CSplashParticle::Create( "splish" );
	pSimple->SetSortOrigin( origin );

	int i;
	float	flScale = scale / 8.0f;

	PMaterialHandle	hMaterial = ParticleMgr()->GetPMaterial( "effects/slime1" );

	float	length = 0.2f;
	Vector	vForward, vRight, vUp;
	Vector	offDir;

	TrailParticle	*tParticle;

	CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create( "splash" );

	if ( !sparkEmitter )
		return;

	sparkEmitter->SetSortOrigin( origin );
	sparkEmitter->m_ParticleCollision.SetGravity( 600.0f );
	sparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN );
	sparkEmitter->SetVelocityDampen( 2.0f );

	//Dump out drops
	Vector	offset;
	for ( i = 0; i < 64; i++ )
	{
		offset = origin;
		offset[0] += random->RandomFloat( -8.0f, 8.0f ) * flScale;
		offset[1] += random->RandomFloat( -8.0f, 8.0f ) * flScale;
		offset[2] += random->RandomFloat( -8.0f, 8.0f ) * flScale;

		tParticle = (TrailParticle *) sparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset );

		if ( tParticle == NULL )
			break;

		tParticle->m_flLifetime	= 0.0f;
		tParticle->m_flDieTime	= 1.0f;

		offDir = normal + RandomVector( -1.0f, 1.0f );

		tParticle->m_vecVelocity = offDir * random->RandomFloat( BLOOD_MIN_SPEED * flScale * 2.0f, BLOOD_MAX_SPEED * flScale * 2.0f );
		tParticle->m_vecVelocity[2] += random->RandomFloat( 8.0f, 32.0f ) * flScale;

		tParticle->m_flWidth		= random->RandomFloat( 20.0f, 26.0f ) * flScale;
		tParticle->m_flLength		= random->RandomFloat( length*0.5f, length ) * flScale;

		int nColor = random->RandomInt( luminosity*0.75f, luminosity );
		tParticle->m_color.r = nColor * tint.x;
		tParticle->m_color.g = nColor * tint.y;
		tParticle->m_color.b = nColor * tint.z;
		tParticle->m_color.a = 255;
	}
}