Particles In Code

This page details the management of "Orange Box" particles in C++ code. It does not cover the old, hard-coded particle tech.
== Precaching ==
Particle systems must be precached before they can be used. This can be achieved by listing the PCF file containing them in particles_manifest.txt and utilizing the function PrecacheParticleSystem() in code. As an alternative all particle effects within a PCF can be precached by adding a '!' character as a prefix to the path used in particles_manifest.txt.
Precache via code:
PrecacheParticleSystem( "your_particle_effect_name" );
Precache via script:
particles_manifest
{
	"file"		"!particles/blood_impact.pcf"	// all effects will be precached on map spawn
	"file"		"particles/fire_01.pcf"		// effects contained in this file will have to be precached manually
	[...]
}
== Shared ==
=== Dispatching ===
When dispatched from the server, the particle systems will be networked as temporary entities.
#include "particle_parse.h"
// Create at world co-ords
DispatchParticleEffect( "my_particle", vecOrigin, angAngles, pOwnerEntity )
// Create at model attachment
DispatchParticleEffect( "my_particle", ParticleAttachment_t, pOwner, iAttachment, bResetAllParticlesOnEntity )
* See also ParticleAttachment_t, below.
* vecStart, taken by some overloads of DispatchParticleEffect(), defines the location of control point 1. If you don't specify vecStart, the value of vecOrigin is used instead.
=== Destroying ===
; StopParticleEffects( CBaseEntity* )
: Stops all effects on the given entity.
== Client ==
=== Creating ===
For more control over the effect, a particle system can be created by a new CNewParticleEffect object and managed through the owning entity's ParticleProp() accessor:
#include "particles_new.h"
C_MyEntity::MessWithParticles()
{
	// Create a new system
	CNewParticleEffect* pEffect = ParticleProp()->Create( "my_particles", PATTACH_ABSORIGIN );
	
	// System already exists
	CNewParticleEffect* pEffect = ParticleProp()->FindEffect( "my_particles" );
}
Particles_new.h must also be #included here.
Alternatively, you can hook into particle creation events:
void C_MyEntity::OnNewParticleEffect( const char* pszParticleName, CNewParticleEffect* pNewParticleEffect )
{
	if ( V_strcmp(pszParticleName, "target_effect_name") == 0 )
	{
		// Do something
	}
}
=== Control points ===
When dispatching an effect from the server you can define the location of control points 0 (with vecOrigin) and 1 (with vecStart).
On the client, you can configure the location, rotation and parent entity of any CP with these CNewParticleEffect functions:
; SetControlPoint( Vector )
: Arbitrary set the CP's value.
; SetControlPointEntity( CBaseEntity* )
: Follow the given entity's origin. 
; SetControlPointOrientation( QAngle )
; SetControlPointRightVector()
; SetControlPointForwardVector()
; SetControlPointUpVector()
: Set orientation with a QAngle or a series of Vectors.
=== Destroying ===
; StopParticleEffects( CBaseEntity* )
: Stops all effects on the given entity.
; ParticleProp()->StopParticlesInvolving( CBaseEntity* )
: Stops all effects with a control point attached to the given entity. 
; ParticleProp()->StopParticlesNamed( const char* )
: Stops all effects with the given system name. 
; CNewParticleEffect::StopEmission( bool bInfiniteOnly, bool bRemoveAllParticles, bool bWakeOnStop)
: Stops the current particle system, without removing it. 
== ParticleAttachment_t ==
One of these values is passed when dispatching or creating an effect:
; PATTACH_ABSORIGIN
; PATTACH_ABSORIGIN_FOLLOW
: Spawn at (and optionally follow) the entity's origin.
; PATTACH_POINT
; PATTACH_POINT_FOLLOW
: Spawn at (and optionally follow) an attachment point on the entity's model.
; PATTACH_CUSTOMORIGIN
: Spawn at a given origin.
; PATTACH_WORLDORIGIN
: Don't associate with an entity at all. Use with caution - could easily cause memory leaks.
Category:Particle System
Category:Programming