aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/sdk/c_sdk_env_sparkler.cpp
blob: 7e4cb62cfcc36b578285842e2e83a2fb9402313c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: A simple test entity for creating special effects
//
//=============================================================================

#include "cbase.h"
#include "c_te_effect_dispatch.h"
#include "particles_simple.h"

// Declare the sparkler entity for the client-side
class C_Sparkler : public C_BaseEntity
{
public:
	DECLARE_CLIENTCLASS();
	DECLARE_CLASS( C_Sparkler, C_BaseEntity );

	virtual void OnDataChanged( DataUpdateType_t updateType );	// Called when data changes on the server
	virtual void ClientThink( void );							// Client-side think function for the entity

private:
	bool	m_bEmit;	// Determines whether or not we should emit particles
	float	m_flScale;	// Size of the effect
	
	CSmartPtr<CSimpleEmitter>	m_hEmitter;			// Particle emitter for this entity
	PMaterialHandle				m_hMaterial;		// Material handle used for this entity's particles
	TimedEvent					m_tParticleTimer;	// Timer used to control particle emission rate
};

// Declare the data-table for server/client communication
IMPLEMENT_CLIENTCLASS_DT( C_Sparkler, DT_Sparkler, CSparkler )
	RecvPropInt( RECVINFO( m_bEmit ) ),	// Boolean state from the server
	RecvPropFloat( RECVINFO( m_flScale ) ),
END_RECV_TABLE()

//-----------------------------------------------------------------------------
// Purpose: Called when data changes on the server
//-----------------------------------------------------------------------------
void C_Sparkler::OnDataChanged( DataUpdateType_t updateType )
{
	// NOTE: We MUST call the base classes' implementation of this function
	BaseClass::OnDataChanged( updateType );
	
	// Setup our entity's particle system on creation
	if ( updateType == DATA_UPDATE_CREATED )
	{
		// Creat the emitter
		m_hEmitter = CSimpleEmitter::Create( "env_sparkler" );

		// Obtain a reference handle to our particle's desired material
		if ( m_hEmitter.IsValid() )
		{
			m_hMaterial = m_hEmitter->GetPMaterial( "effects/yellowflare" );
		}

		// Spawn 128 particles per second
		m_tParticleTimer.Init( 128 );

		// Call our ClientThink() function once every client frame
		SetNextClientThink( CLIENT_THINK_ALWAYS );
	}
}

//-----------------------------------------------------------------------------
// Purpose: Client-side think function for the entity
//-----------------------------------------------------------------------------
void C_Sparkler::ClientThink( void )
{
	// We must have a valid emitter
	if ( m_hEmitter == NULL )
		return;

	// We must be allowed to emit particles by the server
	if ( m_bEmit == false )
		return;

	SimpleParticle *pParticle;

	float curTime = gpGlobals->frametime;

	// Add as many particles as required this frame
	while ( m_tParticleTimer.NextEvent( curTime ) )
	{
		// Create the particle
		pParticle = m_hEmitter->AddSimpleParticle( m_hMaterial, GetAbsOrigin() );

		if ( pParticle == NULL )
			return;

		// Setup our size
		pParticle->m_uchStartSize = (unsigned char) m_flScale;
		pParticle->m_uchEndSize = 0;

		// Setup our roll
		pParticle->m_flRoll = random->RandomFloat( 0, 2*M_PI );
		pParticle->m_flRollDelta = random->RandomFloat( -DEG2RAD( 180 ), DEG2RAD( 180 ) );

		// Set our color
		pParticle->m_uchColor[0] = 255;
		pParticle->m_uchColor[1] = 255;
		pParticle->m_uchColor[2] = 255;

		// Setup our alpha values
		pParticle->m_uchStartAlpha = 255;
		pParticle->m_uchEndAlpha = 255;
		
		// Obtain a random direction
		Vector velocity = RandomVector( -1.0f, 1.0f );
		VectorNormalize( velocity );

		// Obtain a random speed
		float speed = random->RandomFloat( 4.0f, 8.0f ) * m_flScale;

		// Set our velocity
		pParticle->m_vecVelocity = velocity * speed;

		// Die in a short range of time
		pParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );
	}
}

// ============================================================================
//
//   Dispatch Effect version
//
// ============================================================================

//-----------------------------------------------------------------------------
// Purpose: Callback to create a sparkle effect on the client
// Input  : &data - information about the effect
//-----------------------------------------------------------------------------
void SparkleCallback( const CEffectData &data )
{
	// Create a simple particle emitter
	CSmartPtr<CSimpleEmitter> pSparkleEmitter = CSimpleEmitter::Create( "Sparkle" );

	if ( pSparkleEmitter == NULL )
		return;

	// Make local versions of our passed in data
	Vector	origin = data.m_vOrigin;
	float	scale = data.m_flScale;

	// Set our sort origin to make the system cull properly
	pSparkleEmitter->SetSortOrigin( origin );

	// Find the material handle we wish to use for these particles
	PMaterialHandle hMaterial = pSparkleEmitter->GetPMaterial( "effects/yellowflare" );

	SimpleParticle *pParticle;

	// Make a group of particles in the world
	for ( int i = 0; i < 64; i++ )
	{
		// Create a particle
		pParticle = pSparkleEmitter->AddSimpleParticle( hMaterial, origin );

		if ( pParticle == NULL )
			return;

		// Set our sizes
		pParticle->m_uchStartSize = (unsigned char) scale;
		pParticle->m_uchEndSize = 0;

		// Set our roll
		pParticle->m_flRoll = random->RandomFloat( 0, 2*M_PI );
		pParticle->m_flRollDelta = random->RandomFloat( -DEG2RAD( 180 ), DEG2RAD( 180 ) );

		// Set our color
		pParticle->m_uchColor[0] = 255;	// Red
		pParticle->m_uchColor[1] = 255;	// Green
		pParticle->m_uchColor[2] = 255;	// Blue

		// Set our alpha
		pParticle->m_uchStartAlpha = 0;
		pParticle->m_uchEndAlpha = 255;
		
		// Create a random vector
		Vector velocity = RandomVector( -1.0f, 1.0f );
		VectorNormalize( velocity );

		// Find a random speed for the particle
		float speed = random->RandomFloat( 4.0f, 8.0f ) * scale;

		// Build and set the velocity of the particle
		pParticle->m_vecVelocity = velocity * speed;

		// Declare our lifetime
		pParticle->m_flDieTime = 1.0f;
	}
}

// This links our server-side call to a client-side function
DECLARE_CLIENT_EFFECT( "Sparkle", SparkleCallback );