aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/c_fire_smoke.h
blob: 9f7a94e11e5d49a6a0879a69db5603ceccd1a370 (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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef C_FIRE_SMOKE_H
#define C_FIRE_SMOKE_H

#include "particles_simple.h"
#include "tempent.h"
#include "glow_overlay.h"
#include "view.h"
#include "particle_litsmokeemitter.h"

class CFireOverlay;

class C_FireSprite : public C_Sprite
{
	DECLARE_CLASS( C_FireSprite, C_Sprite );

private:
	virtual int DrawModel( int flags )
	{
		if ( m_bFadeFromAbove )
		{
			// The sprites become less visible the more you look down or up at them
			Vector vToPos = GetLocalOrigin() - CurrentViewOrigin();
			VectorNormalize( vToPos );

			float fUpAmount = vToPos.z;

			int iAlpha = 255;

			if ( fUpAmount < -0.75f )
				iAlpha = 0;
			else if ( fUpAmount < -0.65f )
				iAlpha = 255 - (int)( ( fUpAmount + 0.65f ) * 10.0f * -255.0f );
			else if ( fUpAmount > 0.85f )
				iAlpha = 0;
			else if ( fUpAmount > 0.75f )
				iAlpha = 255 - (int)( ( fUpAmount - 0.75f ) * 10.0f * 255.0f );

			SetColor( iAlpha, iAlpha, iAlpha );
		}

		return BaseClass::DrawModel( flags );
	}

public:
	Vector	m_vecMoveDir;
	bool	m_bFadeFromAbove;
};

class C_FireFromAboveSprite : public C_Sprite
{
	DECLARE_CLASS( C_FireFromAboveSprite, C_Sprite );

	virtual int DrawModel( int flags )
	{
		// The sprites become more visible the more you look down or up at them
		Vector vToPos = GetLocalOrigin() - CurrentViewOrigin();
		VectorNormalize( vToPos );

		float fUpAmount = vToPos.z;

		int iAlpha = 0;

		if ( fUpAmount < -0.85f )
			iAlpha = 255;
		else if ( fUpAmount < -0.65f )
			iAlpha = (int)( ( fUpAmount + 0.65f ) * 5.0f * -255.0f );
		else if ( fUpAmount > 0.75f )
			iAlpha = 255;
		else if ( fUpAmount > 0.55f )
			iAlpha = (int)( ( fUpAmount - 0.55f ) * 5.0f * 255.0f );

		SetColor( iAlpha, iAlpha, iAlpha );

		return BaseClass::DrawModel( flags );
	}
};

#ifdef _XBOX
// XBox reduces the flame count
#define	NUM_CHILD_FLAMES	1
#else
#define	NUM_CHILD_FLAMES	4
#endif

#define	SMOKE_RISE_RATE		92.0f
#define	SMOKE_LIFETIME		2.0f
#define	EMBER_LIFETIME		2.0f

#define	FLAME_CHILD_SPREAD	64.0f
#define	FLAME_SOURCE_HEIGHT	128.0f
#define	FLAME_FROM_ABOVE_SOURCE_HEIGHT	32.0f

//==================================================
// C_FireSmoke
//==================================================

//NOTENOTE: Mirrored in dlls/fire_smoke.h
#define	bitsFIRESMOKE_NONE					0x00000000
#define	bitsFIRESMOKE_ACTIVE				0x00000001
#define	bitsFIRESMOKE_SMOKE					0x00000002
#define	bitsFIRESMOKE_SMOKE_COLLISION		0x00000004
#define	bitsFIRESMOKE_GLOW					0x00000008
#define	bitsFIRESMOKE_VISIBLE_FROM_ABOVE	0x00000010

#define	OVERLAY_MAX_VISIBLE_RANGE	512.0f


class C_FireSmoke : public C_BaseEntity
{
public:
	DECLARE_CLIENTCLASS();
	DECLARE_CLASS( C_FireSmoke, C_BaseEntity );

	C_FireSmoke();
	~C_FireSmoke();

	void	Start( void );
	void	Simulate( void );

	void	StartClientOnly( void );
	void	RemoveClientOnly( void );

protected:
	void	Update( void );
	void	UpdateAnimation( void );
	void	UpdateScale( void );
	void	UpdateFlames( void );
	void	AddFlames( void );
	void	SpawnSmoke( void );
	void	FindClipPlane( void );
	
//C_BaseEntity
public:

	virtual void	OnDataChanged( DataUpdateType_t updateType );
	virtual bool	ShouldDraw();

	float GetScale( void ) const { return m_flScaleRegister;	}
	
//From the server
public:
	float	m_flStartScale;
	float	m_flScale;
	float	m_flScaleTime;
	int		m_nFlags;
	int		m_nFlameModelIndex;
	int		m_nFlameFromAboveModelIndex;

//Client-side only
public:
	float	m_flScaleRegister;
	float	m_flScaleStart;
	float	m_flScaleEnd;
	float	m_flScaleTimeStart;
	float	m_flScaleTimeEnd;
	float	m_flChildFlameSpread;

	VPlane	m_planeClip;
	float	m_flClipPerc;
	bool	m_bClipTested;

	bool	m_bFadingOut;

protected:

	void	UpdateEffects( void );

	//CSmartPtr<CEmberEffect> m_pEmberEmitter;
	CSmartPtr<CLitSmokeEmitter> m_pSmokeEmitter;

	C_FireSprite			m_entFlames[NUM_CHILD_FLAMES];
	C_FireFromAboveSprite	m_entFlamesFromAbove[NUM_CHILD_FLAMES];
	float					m_entFlameScales[NUM_CHILD_FLAMES];

	TimedEvent			m_tParticleSpawn;

	CFireOverlay		*m_pFireOverlay;

	// New Particle Fire Effect
	CNewParticleEffect *m_hEffect;
private:
	C_FireSmoke( const C_FireSmoke & );
};

//Fire overlay
class CFireOverlay : public CGlowOverlay
{
public:
	
	//Constructor
	CFireOverlay( C_FireSmoke *owner )
	{
		m_pOwner	= owner;
		m_flScale	= 0.0f;
		m_nGUID		= random->RandomInt( -999999, 999999 );
	}

	//-----------------------------------------------------------------------------
	// Purpose: Generate a flicker value
	// Output : scalar value
	//-----------------------------------------------------------------------------
	float GetFlickerScale( void )
	{
		float	result = 0.0f;

		float	time = Helper_GetTime() + m_nGUID;

		result = sin( time * 1000.0f );
		result += 0.5f * sin( time * 2000.0f );
		result -= 0.5f * cos( time * 8000.0f );
		
		return result;
	}

	//-----------------------------------------------------------------------------
	// Purpose: Update the overlay
	//-----------------------------------------------------------------------------
	virtual bool Update( void )
	{
		if ( m_pOwner == NULL )
			return false;

		float scale	 = m_pOwner->GetScale();
		float dscale = scale - m_flScale;

		m_vPos[2] += dscale * FLAME_SOURCE_HEIGHT;
		m_flScale = scale;

		scale *= 0.75f;

		float flickerScale = GetFlickerScale();

		float newScale = scale + ( scale * flickerScale * 0.1f );

		m_Sprites[0].m_flHorzSize = ( newScale * 0.2f ) + ( m_Sprites[0].m_flHorzSize * 0.8f );
		m_Sprites[0].m_flVertSize = m_Sprites[0].m_flHorzSize * 1.5f;
		
		float	cameraDistance = ( CurrentViewOrigin() - (m_pOwner->GetAbsOrigin())).Length();

		C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
		if ( local )
		{
			cameraDistance *= local->GetFOVDistanceAdjustFactor();
		}

		if ( cameraDistance > OVERLAY_MAX_VISIBLE_RANGE )
			cameraDistance = OVERLAY_MAX_VISIBLE_RANGE;

		float alpha = 1.0f - ( cameraDistance / OVERLAY_MAX_VISIBLE_RANGE );

		Vector	newColor = m_vBaseColors[0] + ( m_vBaseColors[0] * flickerScale * 0.5f );
		m_Sprites[0].m_vColor = ( newColor * 0.1f ) + ( m_Sprites[0].m_vColor * 0.9f ) * alpha;

		return true;
	}

public:

	C_FireSmoke	*m_pOwner;
	Vector		m_vBaseColors[MAX_SUN_LAYERS];
	float		m_flScale;
	int			m_nGUID;
};

//
// Entity flame, client-side implementation
//

#define	NUM_FLAMELETS	5

class C_EntityFlame : public C_BaseEntity
{
public:
	DECLARE_CLIENTCLASS();
	DECLARE_CLASS( C_EntityFlame, C_BaseEntity );

	C_EntityFlame( void );
	~C_EntityFlame( void );

	virtual void	Simulate( void );
	virtual void	UpdateOnRemove( void );
	virtual void	OnDataChanged( DataUpdateType_t updateType );
	virtual void	ClientThink( void );

	CNewParticleEffect *m_hEffect;
	EHANDLE				m_hEntAttached;		// The entity that we are burning (attached to).
	EHANDLE				m_hOldAttached;

protected:

	void	CreateEffect( void );
	void	StopEffect( void );
};

#endif //C_FIRE_SMOKE_H