1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 // cl_fx.c -- entity effects parsing and management
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include "client.h"
27 #include "ref_gl/r_image.h"
28 #include "ref_gl/qgl.h"
29 
30 extern particle_t	particles[MAX_PARTICLES];
31 extern int			cl_numparticles;
32 extern cvar_t		*vid_ref;
33 
34 extern void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up);
35 
36 void CL_LogoutEffect (vec3_t org, int type);
37 void CL_ItemRespawnParticles (vec3_t org);
38 void CL_TeleportParticles (vec3_t start);
39 
40 static vec3_t avelocities [NUMVERTEXNORMALS];
41 
42 /*
43 ==============================================================
44 
45 LIGHT STYLE MANAGEMENT
46 
47 ==============================================================
48 */
49 
50 typedef struct
51 {
52 	int		length;
53 	float	value[3];
54 	float	map[MAX_QPATH];
55 } clightstyle_t;
56 
57 clightstyle_t	cl_lightstyle[MAX_LIGHTSTYLES];
58 int			lastofs;
59 
60 /*
61 ================
62 CL_ClearLightStyles
63 ================
64 */
CL_ClearLightStyles(void)65 void CL_ClearLightStyles (void)
66 {
67 	memset (cl_lightstyle, 0, sizeof(cl_lightstyle));
68 	lastofs = -1;
69 }
70 
71 /*
72 ================
73 CL_RunLightStyles
74 ================
75 */
CL_RunLightStyles(void)76 void CL_RunLightStyles (void)
77 {
78 	int		ofs;
79 	int		i;
80 	clightstyle_t	*ls;
81 
82 	ofs = cl.time / 25;
83 	if (ofs == lastofs)
84 		return;
85 	lastofs = ofs;
86 
87 	for (i=0,ls=cl_lightstyle ; i<MAX_LIGHTSTYLES ; i++, ls++)
88 	{
89 		if (!ls->length || !cl_flicker->integer)
90 		{
91 			ls->value[0] = ls->value[1] = ls->value[2] = 1.0;
92 			continue;
93 		}
94 		if (ls->length == 1)
95 			ls->value[0] = ls->value[1] = ls->value[2] = ls->map[0];
96 		else
97 		{
98 			// nonlinear interpolation of the lightstyles for smoothness while
99 			// still preserving some "jaggedness"
100 			float a, b, dist;
101 			a = ls->map[(ofs/4)%ls->length];
102 			b = ls->map[(ofs/4+1)%ls->length];
103 			dist = (float)(ofs%4)/4.0f;
104 			if (dist != 0.75)
105 				dist = 0;
106 			ls->value[0] = ls->value[1] = ls->value[2] = a+(b-a)*dist;
107 		}
108 	}
109 }
110 
111 
CL_SetLightstyle(int i)112 void CL_SetLightstyle (int i)
113 {
114 	char	*s;
115 	int		j, k;
116 
117 	s = cl.configstrings[i+CS_LIGHTS];
118 
119 	j = strlen (s);
120 	if (j >= MAX_QPATH)
121 		Com_Error (ERR_DROP, "svc_lightstyle length=%i", j);
122 
123 	cl_lightstyle[i].length = j;
124 
125 	for (k=0 ; k<j ; k++)
126 		cl_lightstyle[i].map[k] = (float)(s[k]-'a')/(float)('m'-'a');
127 }
128 
129 /*
130 ================
131 CL_AddLightStyles
132 ================
133 */
CL_AddLightStyles(void)134 void CL_AddLightStyles (void)
135 {
136 	int		i;
137 	clightstyle_t	*ls;
138 
139 	for (i=0,ls=cl_lightstyle ; i<MAX_LIGHTSTYLES ; i++, ls++)
140 		V_AddLightStyle (i, ls->value[0], ls->value[1], ls->value[2]);
141 }
142 
143 /*
144 ==============================================================
145 
146 DLIGHT MANAGEMENT
147 
148 ==============================================================
149 */
150 
151 cdlight_t		cl_dlights[MAX_DLIGHTS];
152 
153 /*
154 ================
155 CL_ClearDlights
156 ================
157 */
CL_ClearDlights(void)158 void CL_ClearDlights (void)
159 {
160 	memset (cl_dlights, 0, sizeof(cl_dlights));
161 }
162 
163 /*
164 ===============
165 CL_AllocDlight
166 
167 ===============
168 */
CL_AllocDlight(int key)169 cdlight_t *CL_AllocDlight (int key)
170 {
171 	int		i;
172 	cdlight_t	*dl;
173 
174 // first look for an exact key match
175 	if (key)
176 	{
177 		dl = cl_dlights;
178 		for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
179 		{
180 			if (dl->key == key)
181 			{
182 				memset (dl, 0, sizeof(*dl));
183 				dl->key = key;
184 				return dl;
185 			}
186 		}
187 	}
188 
189 // then look for anything else
190 	dl = cl_dlights;
191 	for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
192 	{
193 		if (dl->die < cl.time)
194 		{
195 			memset (dl, 0, sizeof(*dl));
196 			dl->key = key;
197 			return dl;
198 		}
199 	}
200 
201 	dl = &cl_dlights[0];
202 	memset (dl, 0, sizeof(*dl));
203 	dl->key = key;
204 	return dl;
205 }
206 
207 /*
208 ===============
209 CL_NewDlight
210 ===============
211 */
CL_NewDlight(int key,float x,float y,float z,float radius,float time)212 void CL_NewDlight (int key, float x, float y, float z, float radius, float time)
213 {
214 	cdlight_t	*dl;
215 
216 	dl = CL_AllocDlight (key);
217 	dl->origin[0] = x;
218 	dl->origin[1] = y;
219 	dl->origin[2] = z;
220 	dl->radius = radius;
221 	dl->die = cl.time + time;
222 }
223 
224 
225 /*
226 ===============
227 CL_RunDLights
228 
229 ===============
230 */
CL_RunDLights(void)231 void CL_RunDLights (void)
232 {
233 	int			i;
234 	cdlight_t	*dl;
235 
236 	dl = cl_dlights;
237 	for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
238 	{
239 		if (!dl->radius)
240 			continue;
241 
242 		if (dl->die < cl.time)
243 		{
244 			dl->radius = 0;
245 			return;
246 		}
247 		dl->radius -= cls.frametime*dl->decay;
248 		if (dl->radius < 0)
249 			dl->radius = 0;
250 	}
251 }
252 
RotateForNormal(vec3_t normal,vec3_t result)253 void RotateForNormal(vec3_t normal, vec3_t result){
254 	float forward, pitch, yaw;
255 
256 	forward = sqrt(normal[0] * normal[0] + normal[1] * normal[1]);
257 	pitch = (int)(atan2(normal[2], forward) * 180 / M_PI);
258 	yaw = (int)(atan2(normal[1], normal[0]) * 180 / M_PI);
259 
260 	if(pitch < 0)
261 		pitch += 360;
262 
263 	result[PITCH] = -pitch;
264 	result[YAW] =  yaw;
265 }
266 
vectoanglerolled(vec3_t value1,float angleyaw,vec3_t angles)267 void vectoanglerolled (vec3_t value1, float angleyaw, vec3_t angles)
268 {
269 	float	forward, yaw, pitch;
270 
271 	yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
272 	forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]);
273 	pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
274 
275 	if (pitch < 0)
276 		pitch += 360;
277 
278 	angles[PITCH] = -pitch;
279 	angles[YAW] =  yaw;
280 	angles[ROLL] = -angleyaw;
281 }
282 
283 /*
284 ==============
285 CL_ParseMuzzleFlash
286 ==============
287 */
CL_ParseMuzzleFlash(void)288 void CL_ParseMuzzleFlash (void)
289 {
290 	vec3_t		fv, rv, shell_brass, dir, up;
291 	cdlight_t	*dl;
292 	int			i, j, weapon;
293 	centity_t	*pl;
294 	int			silenced;
295 	float		volume;
296 	char		soundname[64];
297 
298 	i = MSG_ReadShort (&net_message);
299 	if (i < 1 || i >= MAX_EDICTS)
300 		Com_Error (ERR_DROP, "CL_ParseMuzzleFlash: bad entity");
301 
302 	weapon = MSG_ReadByte (&net_message);
303 	silenced = weapon & MZ_SILENCED;
304 	weapon &= ~MZ_SILENCED;
305 
306 	pl = &cl_entities[i];
307 
308 	dl = CL_AllocDlight (i);
309 	VectorCopy (pl->current.origin,  dl->origin);
310 	AngleVectors (pl->current.angles, fv, rv, up);
311 	VectorMA (dl->origin, 18, fv, dl->origin);
312 	VectorMA (dl->origin, 16, rv, dl->origin);
313 	if (silenced)
314 		dl->radius = 100 + (rand()&31);
315 	else
316 		dl->radius = 200 + (rand()&31);
317 	dl->minlight = 32;
318 	dl->die = cl.time; // + 0.1;
319 
320 	if (silenced)
321 		volume = 0.2;
322 	else
323 		volume = 1;
324 
325 	VectorMA(pl->current.origin, 10, fv, shell_brass);
326 	VectorMA(shell_brass, 6, rv, shell_brass);
327 	VectorMA(shell_brass, 21, up, shell_brass);
328 
329 	for (j = 0; j < 3; j++)
330 		dir[j] = fv[j] + rv[j] + up[j] * 2;
331 
332 	// NOTE: sounds started here are subject to PVS rather than PHS
333 	//  which results in these sounds not being heard when others
334 	//  in same location can be heard
335 	switch (weapon)
336 	{
337 	case MZ_BLASTER:
338 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
339 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0);
340 		break;
341 	case MZ_HYPERBLASTER:
342 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
343 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0);
344 		break;
345 	case MZ_MACHINEGUN:
346 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
347 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
348 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
349 		break;
350 	case MZ_SHOTGUN:
351 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
352 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/shotgf1b.wav"), volume, ATTN_NORM, 0);
353 		//[no file] S_StartSound (NULL, i, CHAN_AUTO,   S_RegisterSound("weapons/shotgr1b.wav"), volume, ATTN_NORM, 0.1);
354 		break;
355 	case MZ_SSHOTGUN:
356 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
357 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/sshotf1b.wav"), volume, ATTN_NORM, 0);
358 		break;
359 	case MZ_CHAINGUN1:
360 		dl->radius = 200 + (rand()&31);
361 		dl->color[0] = 1;dl->color[1] = 0.25;dl->color[2] = 0;
362 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
363 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
364 		CL_BrassShells(shell_brass, dir, 1);
365 		break;
366 	case MZ_CHAINGUN2:
367 		dl->radius = 225 + (rand()&31);
368 		dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0;
369 		dl->die = cl.time  + 0.1;	// long delay
370 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
371 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
372 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
373 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.05);
374 		CL_BrassShells(shell_brass, dir, 1);
375 		break;
376 	case MZ_CHAINGUN3:
377 		dl->radius = 250 + (rand()&31);
378 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
379 		dl->die = cl.time  + 0.1;	// long delay
380 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
381 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
382 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
383 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.033);
384 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
385 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.066);
386 		CL_BrassShells(shell_brass, dir, 1);
387 		break;
388 	case MZ_RAILGUN:
389 		dl->color[0] = 0.5;dl->color[1] = 0.5;dl->color[2] = 1.0;
390 //		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/railgf1a.wav"), volume, ATTN_NORM, 0);
391 		break;
392 	case MZ_ROCKET:
393 		dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2;
394 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/rocklf1a.wav"), volume, ATTN_NORM, 0);
395 		S_StartSound (NULL, i, CHAN_AUTO,   S_RegisterSound("weapons/rocklr1b.wav"), volume, ATTN_NORM, 0.1);
396 		break;
397 	case MZ_GRENADE:
398 		dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0;
399 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), volume, ATTN_NORM, 0);
400 		S_StartSound (NULL, i, CHAN_AUTO,   S_RegisterSound("weapons/grenlr1b.wav"), volume, ATTN_NORM, 0.1);
401 		break;
402 	case MZ_BFG:
403 		dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0;
404 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/bfg__f1y.wav"), volume, ATTN_NORM, 0);
405 		break;
406 
407 	case MZ_LOGIN:
408 		dl->color[0] = 0;dl->color[1] = 1; dl->color[2] = 0;
409 		dl->die = cl.time + 1.0;
410 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0);
411 		//CL_LogoutEffect (pl->current.origin, weapon);
412 		CL_TeleportParticles (pl->current.origin);
413 		break;
414 	case MZ_LOGOUT:
415 		dl->color[0] = 1;dl->color[1] = 0; dl->color[2] = 0;
416 		dl->die = cl.time + 1.0;
417 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0);
418 		CL_LogoutEffect (pl->current.origin, weapon);
419 		break;
420 	case MZ_RESPAWN:
421 		dl->color[0] = 1;dl->color[1] = 1; dl->color[2] = 0;
422 		dl->die = cl.time + 1.0;
423 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0);
424 		CL_LogoutEffect (pl->current.origin, weapon);
425 		break;
426 	}
427 }
428 
429 
430 /*
431 ===============
432 CL_AddDLights
433 
434 ===============
435 */
CL_AddDLights(void)436 void CL_AddDLights (void)
437 {
438 	int			i;
439 	cdlight_t	*dl;
440 
441 	dl = cl_dlights;
442 
443 //=====
444 //PGM
445 	for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
446 	{
447 		if (!dl->radius)
448 			continue;
449 		V_AddLight (dl->origin, dl->radius,
450 			dl->color[0], dl->color[1], dl->color[2]);
451 	}
452 //PGM
453 //=====
454 }
455 
456 
457 
458 /*
459 ==============================================================
460 
461 PARTICLE MANAGEMENT
462 
463 ==============================================================
464 */
465 
466 particle_t	*active_particles, *free_particles;
467 
468 particle_t	particles[MAX_PARTICLES];
469 int			cl_numparticles = MAX_PARTICLES;
470 
addParticleLight(particle_t * p,float light,float lightvel,float lcol0,float lcol1,float lcol2)471 void addParticleLight (particle_t *p, float light, float lightvel, float lcol0, float lcol1, float lcol2)
472 {
473 	int i;
474 
475 	for (i=0; i<P_LIGHTS_MAX; i++)
476 	{
477 		cplight_t *plight = &p->lights[i];
478 
479 		if (!plight->isactive)
480 		{
481 			plight->isactive = true;
482 			plight->light = light;
483 			plight->lightvel = lightvel;
484 			plight->lightcol[0] = lcol0;
485 			plight->lightcol[1] = lcol1;
486 			plight->lightcol[2] = lcol2;
487 			return;
488 		}
489 	}
490 }
491 /*
492 ===============
493 CL_ClearParticles
494 ===============
495 */
496 /*
497 Cl_ClearParticle
498 */
499 
CL_ClearParticles(void)500 void CL_ClearParticles (void)
501 {
502 	int		i;
503 
504 
505 	free_particles = &particles[0];
506 	active_particles = NULL;
507 
508 	for (i=0 ;i<cl_numparticles ; i++)
509 		particles[i].next = &particles[i+1];
510 	particles[cl_numparticles-1].next = NULL;
511 }
512 
new_particle(void)513 static inline particle_t *new_particle (void)
514 {
515 	particle_t	*p;
516 	int j;
517 
518 	if (!free_particles)
519 		return NULL;
520 
521 	p = free_particles;
522 	free_particles = p->next;
523 	p->next = active_particles;
524 	p->type = 0;
525 	p->image = NULL;
526 	p->blenddst = 0;
527 	p->blendsrc = 0;
528 	p->scalevel = 0;
529 	p->time = cl.time;
530 	for(j=0; j<3; j++)
531 		p->angle[j]=0;
532 
533 	for (j=0;j<P_LIGHTS_MAX;j++)
534 	{
535 		cplight_t *plight = &p->lights[j];
536 		plight->isactive = false;
537 		plight->light = 0;
538 		plight->lightvel = 0;
539 		plight->lightcol[0] = 0;
540 		plight->lightcol[1] = 0;
541 		plight->lightcol[2] = 0;
542 	}
543 	p->fromsustainedeffect = false;
544 	p->chain_prev = NULL;
545 
546 	return (active_particles = p);
547 }
548 
getColor(void)549 float getColor(void)
550 {
551 	float color;
552 
553 	switch(cl_disbeamclr->integer) {
554 	case 0:
555 	default:
556 		color = 0xd6; //bright green
557 		break;
558 	case 1:
559 		color = 0x74; //blue
560 		break;
561 	case 2:
562 		color = 0x40; //red
563 		break;
564 	case 3:
565 		color = 0xe0; //yellow
566 		break;
567 	case 4:
568 		color = 0xff; //purple
569 		break;
570 	}
571 	return color;
572 }
573 
getColorvec(vec3_t colorvec)574 void getColorvec(vec3_t colorvec)
575 {
576 	switch(cl_disbeamclr->integer) {
577 	case 0:
578 	default:
579 		colorvec[0] = 0; //bright green
580 		colorvec[1] = 1;
581 		colorvec[2] = 0.6;
582 		break;
583 	case 1:
584 		colorvec[0] = 0; //blue
585 		colorvec[1] = 0.5;
586 		colorvec[2] = 0.7;
587 		break;
588 	case 2:
589 		colorvec[0] = 0.6; //red
590 		colorvec[1] = 0;
591 		colorvec[2] = 0;
592 		break;
593 	case 3:
594 		colorvec[0] = 0.7; //yellow
595 		colorvec[1] = 0.7;
596 		colorvec[2] = 0;
597 		break;
598 	case 4:
599 		colorvec[0] = 0.7; //purple
600 		colorvec[1] = 0;
601 		colorvec[2] = 0.7;
602 		break;
603 	}
604 }
605 
606 /*
607 ===============
608 CL_ParticleEffect
609 
610 Wall impact puffs
611 ===============
612 */
CL_ParticleEffect(vec3_t org,vec3_t dir,int color,int count)613 void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count)
614 {
615 	int			i, j;
616 	particle_t	*p;
617 	float		d;
618 
619 	if((color == 450 || color == 550) && cl_noblood->value)
620 		return;
621 
622 	for (i=0 ; i<count ; i++)
623 	{
624 		if (!(p = new_particle()))
625 			return;
626 
627 		d = rand()&31;
628 		for (j=0 ; j<3 ; j++)
629 		{
630 			p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
631 			p->vel[j] = crand()*50;
632 		}
633 
634 		p->accel[0] = p->accel[1] = 0;
635 		p->accel[2] = -PARTICLE_GRAVITY;
636 
637 		if (color == 425)		// gunshots: FIXME should be using type
638 		{
639 			p->type = PARTICLE_STANDARD;
640 			p->image = r_pufftexture;
641 			p->blendsrc = GL_SRC_ALPHA;
642 			p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
643 			p->scale = 4 + (rand()&2);
644 			p->scalevel = 0;
645 			p->alpha = 0.2;
646 			p->alphavel = -1.0 / (1.5 + frand()*0.3);
647 			p->accel[2] = PARTICLE_GRAVITY;
648 		}
649 		else if (color == 450)
650 		{
651 			p->type = PARTICLE_STANDARD;
652 			p->image = r_bloodtexture;
653 			p->blendsrc = GL_SRC_ALPHA;
654 			p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
655 			p->alpha = 0.2;
656 			p->alphavel = -1.0 / (4.5 + frand()*0.3);
657 			p->color = 0xe8;
658 			p->scale = 6;
659 			p->scalevel = 0;
660 		}
661 		else if (color == 550)
662 		{
663 			p->type = PARTICLE_STANDARD;
664 			p->image = r_bloodtexture;
665 			p->blendsrc = GL_SRC_ALPHA;
666 			p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
667 			p->alpha = 0.2;
668 			p->alphavel = -1.0 / (4.5 + frand()*0.3);
669 			p->color = 0xd0 + (rand()&3);
670 			p->scale = 6;
671 			p->scalevel = 0;
672 		}
673 		else
674 		{
675 			p->type = PARTICLE_NONE;
676 			p->image = r_particletexture;
677 			p->blendsrc = GL_SRC_ALPHA;
678 			p->blenddst = GL_ONE;
679 			p->scale = 1;
680 			p->scalevel = 0;
681 			p->alpha = 1.0;
682 			p->color = color;
683 			p->alphavel = -1.0 / (0.5 + frand()*0.3);
684 		}
685 
686 
687 	}
688 }
689 
690 
691 /*
692 ===============
693 CL_ParticleEffect2
694 ===============
695 */
CL_ParticleEffect2(vec3_t org,vec3_t dir,int color,int count)696 void CL_ParticleEffect2 (vec3_t org, vec3_t dir, int color, int count)
697 {
698 	int			i, j;
699 	particle_t	*p;
700 	float		d;
701 
702 	for (i=0 ; i<count ; i++)
703 	{
704 		if (!(p = new_particle()))
705 			return;
706 
707 		p->type = PARTICLE_STANDARD;
708 		p->image = r_particletexture;
709 		p->blendsrc = GL_SRC_ALPHA;
710 		p->blenddst = GL_ONE;
711 		p->scale = 1;
712 		p->scalevel = 0;
713 
714 		p->color = color;
715 
716 		d = rand()&7;
717 		for (j=0 ; j<3 ; j++)
718 		{
719 			p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
720 			p->vel[j] = crand()*20;
721 		}
722 
723 		p->accel[0] = p->accel[1] = 0;
724 		p->accel[2] = -PARTICLE_GRAVITY;
725 		p->alpha = 1.0;
726 
727 		p->alphavel = -1.0 / (0.5 + frand()*0.3);
728 	}
729 }
730 
731 /*
732 ===============
733 CL_BulletSparks
734 ===============
735 */
CL_BulletSparks(vec3_t org,vec3_t dir)736 void CL_BulletSparks (vec3_t org, vec3_t dir)
737 {
738 	int			i, j, k;
739 	float		inc, scale, nudge;
740 	particle_t	*p;
741 	particle_t	*pr;
742 	particle_t	*center;
743 
744 	for( i=0; i<3; i++) {
745 		nudge = frand();
746 		if(nudge < 0.5)
747 			dir[i] += frand();
748 		else
749 			dir[i] -= frand();
750 	}
751 
752 	//draw a fatter glow at the impact point
753 	if(!(p = new_particle()))
754 		return;
755 
756 	p->type = PARTICLE_STANDARD;
757 	p->image = r_particletexture;
758 	p->blendsrc = GL_SRC_ALPHA;
759 	p->blenddst = GL_ONE;
760 	p->scale = 1;
761 	p->scalevel = 0;
762 
763 	p->color = 0xe0 + (rand()&2);
764 	for (j=0 ; j<3 ; j++)
765 	{
766 		p->org[j] = org[j];
767 		p->vel[j] = 0;
768 	}
769 	p->accel[0] = p->accel[1] = p->accel[2] = 0;
770 	p->alpha = .5;
771 
772 	p->alphavel = -1.0 / (3 + frand()*0.3);
773 	center = p;
774 
775 	//shoot off sparks
776 
777 	VectorNormalize(dir);
778 
779 	for( k=0; k<2; k++) {
780 
781 		scale = frand()*3.0;
782 		pr = NULL;
783 
784 		i = 0;
785 		for (inc=1.0 ; inc<2.0 ; inc+=0.25, i++)
786 		{
787 			if (!(p = new_particle()))
788 				return;
789 
790 			p->color = 0xe0 + (rand()&2);
791 			p->type = PARTICLE_CHAINED;
792 			p->image = r_raintexture;
793 			p->blendsrc = GL_SRC_ALPHA;
794 			p->blenddst = GL_ONE;
795 			p->scale = 1.25*scale/inc;
796 			p->scalevel = 0;
797 
798 			for (j=0 ; j<3 ; j++)
799 			{
800 				p->org[j] = org[j] + i*(-1.25*scale)*dir[j];
801 				p->vel[j] = 60*dir[j];
802 			}
803 
804 			p->accel[0] = 0;
805 			p->accel[1] = 0;
806 			p->accel[2] = -(PARTICLE_GRAVITY)/(.5*inc);
807 			p->alpha = .5;
808 
809 			p->alphavel = -1.0 / (2.5 + frand()*0.3);
810 
811 			if (pr)
812 			{
813 				p->chain_prev = pr;
814 			}
815 			pr = p;
816 		}
817 	}
818 }
819 
820 /*
821 ===============
822 CL_SplashEffect
823 ===============
824 */
825 
CL_SplashEffect(vec3_t org,vec3_t dir,int color,int count)826 void CL_SplashEffect (vec3_t org, vec3_t dir, int color, int count)
827 {
828 	int			i, j, k;
829 	float		scale, nudge;
830 	particle_t	*p;
831 	vec3_t		angle;
832 
833 	//draw rings that expand outward
834 	if(!(p = new_particle()))
835 		return;
836 	p->type = PARTICLE_RAISEDDECAL;
837 	p->image = r_splashtexture;
838 	p->blendsrc = GL_DST_COLOR;
839 	p->blenddst = GL_SRC_COLOR;
840 	p->scale = 1;
841 	p->scalevel = 8;
842 	p->color = 0 + (rand() & 1);
843 
844 	VectorScale(dir, -1, angle);
845 	RotateForNormal(angle, p->angle);
846 	p->angle[ROLL] = rand() % 360;
847 	VectorAdd(org, dir, p->org);
848 
849 	for (j=0 ; j<3 ; j++)
850 	{
851 		p->org[j] = org[j];
852 		p->vel[j] = 0;
853 	}
854 	p->accel[0] = p->accel[1] = p->accel[2] = 0;
855 	p->alpha = .1;
856 
857 	p->alphavel = -0.1 / (1 + frand()*0.3);
858 
859 
860 	for( k=0; k<count/4; k++) {
861 
862 		for( i=0; i<3; i++) {
863 			nudge = frand();
864 			if(nudge < 0.5)
865 				dir[i] += frand()/2;
866 			else
867 				dir[i] -= frand()/2;
868 		}
869 
870 		VectorNormalize(dir);
871 		scale = frand();
872 
873 		//shoot off small plume of water
874 		i = 0;
875 		for (i=0; i<count/2; i++)
876 		{
877 			if (!(p = new_particle()))
878 				return;
879 
880 			p->color = color - (rand()&2);
881 			p->type = PARTICLE_VERT;
882 			p->image = r_splash2texture;
883 			p->blendsrc = GL_SRC_ALPHA;
884 			p->blenddst = GL_ONE;
885 			p->scale = 4*(rand()&8);
886 			p->scalevel = 2;
887 
888 			for (j=0; j<3; j++)
889 			{
890 				p->org[j] = org[j] + 10*dir[j];
891 				p->vel[j] = 60*dir[j];
892 			}
893 			p->org[2]+=32;
894 
895 			p->accel[0] = 0;
896 			p->accel[1] = 0;
897 			p->accel[2] = -(PARTICLE_GRAVITY)/0.5;
898 			p->alpha = .5;
899 
900 			p->alphavel = -1.0 / (1.5 + frand()*0.3);
901 		}
902 	}
903 }
904 /*
905 ===============
906 CL_LaserSparks
907 ===============
908 */
CL_LaserSparks(vec3_t org,vec3_t dir,int color,int count)909 void CL_LaserSparks (vec3_t org, vec3_t dir, int color, int count)
910 {
911 	int			i, j, k;
912 	float		inc, scale, nudge;
913 	particle_t	*p;
914 
915 	for( i=0; i<3; i++) {
916 		nudge = frand();
917 		if(nudge < 0.5)
918 			dir[i] += frand();
919 		else
920 			dir[i] -= frand();
921 	}
922 
923 	//shoot off sparks
924 	for( k=0; k<2; k++) {
925 
926 		VectorNormalize(dir);
927 
928 		scale = frand();
929 
930 		i = 0;
931 		for (inc=1.0 ; inc<2.0 ; inc+=0.1, i++)
932 		{
933 			if (!(p = new_particle()))
934 				return;
935 
936 			p->color = color + (rand()&2);
937 			p->type = PARTICLE_STANDARD;
938 			p->image = r_particletexture;
939 			p->blendsrc = GL_SRC_ALPHA;
940 			p->blenddst = GL_ONE;
941 			p->scale = 1.5*scale/inc;
942 			p->scalevel = 0;
943 
944 			for (j=0 ; j<3 ; j++)
945 			{
946 				p->org[j] = org[j] + i*(-1.5*scale)*dir[j];
947 				p->vel[j] = 60*dir[j];
948 			}
949 
950 			p->accel[0] = 0;
951 			p->accel[1] = 0;
952 			p->accel[2] = -(PARTICLE_GRAVITY)/(.5*inc);
953 			p->alpha = .5;
954 
955 			p->alphavel = -1.0 / (1.5 + frand()*0.3);
956 		}
957 	}
958 }
959 
960 /*
961 ===============
962 CL_LogoutEffect
963 
964 ===============
965 */
CL_LogoutEffect(vec3_t org,int type)966 void CL_LogoutEffect (vec3_t org, int type)
967 {
968 	int			i, j;
969 	particle_t	*p;
970 
971 	for (i=0 ; i<500 ; i++)
972 	{
973 		if (!(p = new_particle()))
974 			return;
975 
976 		p->type = PARTICLE_STANDARD;
977 		p->scale = 1;
978 		p->image = r_particletexture;
979 		p->blendsrc = GL_SRC_ALPHA;
980 		p->blenddst = GL_ONE;
981 
982 		if (type == MZ_LOGIN)
983 			p->color = 0xd0 + (rand()&7);	// green
984 		else if (type == MZ_LOGOUT)
985 			p->color = 0x40 + (rand()&7);	// red
986 		else
987 			p->color = 0xe0 + (rand()&7);	// yellow
988 
989 		p->org[0] = org[0] - 16 + frand()*32;
990 		p->org[1] = org[1] - 16 + frand()*32;
991 		p->org[2] = org[2] - 24 + frand()*56;
992 
993 		for (j=0 ; j<3 ; j++)
994 			p->vel[j] = crand()*20;
995 
996 		p->accel[0] = p->accel[1] = 0;
997 		p->accel[2] = -PARTICLE_GRAVITY;
998 		p->alpha = 1.0;
999 
1000 		p->alphavel = -1.0 / (1.0 + frand()*0.3);
1001 	}
1002 }
1003 
1004 
1005 /*
1006 ===============
1007 CL_ItemRespawnParticles
1008 
1009 ===============
1010 */
CL_ItemRespawnParticles(vec3_t org)1011 void CL_ItemRespawnParticles (vec3_t org)
1012 {
1013 	int			i, j;
1014 	particle_t	*p;
1015 
1016 	for (i=0 ; i<64 ; i++)
1017 	{
1018 		if (!(p = new_particle()))
1019 			return;
1020 
1021 		p->color = 0x74 + (rand()&7);
1022 		p->scale = 12 + (rand()&7) ;
1023 		p->scalevel = 0;
1024 		p->type = PARTICLE_STANDARD;
1025 		p->image = r_explosiontexture;
1026 		p->blendsrc = GL_SRC_ALPHA;
1027 		p->blenddst = GL_ONE;
1028 		p->org[0] = org[0] + crand()*16;
1029 		p->org[1] = org[1] + crand()*16;
1030 		p->org[2] = org[2] + crand()*16;
1031 
1032 		for (j=0 ; j<3 ; j++)
1033 			p->vel[j] = crand()*8;
1034 
1035 		p->accel[0] = p->accel[1] = 0;
1036 		p->accel[2] = -PARTICLE_GRAVITY*0.2;
1037 		p->alpha = .3;
1038 
1039 		p->alphavel = -1.0 / (1.0 + frand()*0.3);
1040 
1041 		if (i < 4)
1042 			addParticleLight (p,
1043 						p->scale*30, 10,
1044 					0, 1, 1);
1045 
1046 	}
1047 }
1048 
1049 /*
1050 ===============
1051 CL_ExplosionParticles - new version -
1052 ===============
1053 */
1054 extern int r_drawing_fbeffect;
1055 extern int	r_fbFxType;
1056 extern float r_fbeffectTime;
1057 extern vec3_t r_explosionOrigin;
1058 extern float rs_realtime;
CL_ExplosionParticles(vec3_t org)1059 void CL_ExplosionParticles (vec3_t org)
1060 {
1061 	int			i, j, k;
1062 	particle_t	*p;
1063 
1064 	//for glsl framebuffer distortion effects
1065 	if(!r_drawing_fbeffect && cl_explosiondist->value) {
1066 		r_fbFxType = 1; //EXPLOSION
1067 		r_drawing_fbeffect = true;
1068 		VectorCopy(org, r_explosionOrigin);
1069 		r_fbeffectTime = rs_realtime;
1070 	}
1071 
1072 	for (i=0 ; i<7; i++)
1073 	{
1074 		for (k = 0; k<(12-i); k++) {
1075 		if (!(p = new_particle()))
1076 			return;
1077 
1078 			for (j=0 ; j<3 ; j++)
1079 			{
1080 				p->org[j] = org[j] + ((rand()%16)-8);
1081 				p->vel[j] = 0;
1082 			}
1083 			p->type = PARTICLE_STANDARD;
1084 			p->accel[0] = p->accel[1] = p->accel[2] = 0;
1085 			p->alpha = 0.2;
1086 			p->scale = 6;
1087 			p->scalevel = 52;
1088 			p->color = 0xd9 + (rand()&7);
1089 			p->alphavel = -1.0 / (1 + i + k/5);
1090 			p->blendsrc = GL_SRC_ALPHA;
1091 			p->blenddst = GL_ONE;
1092 			switch(i) {
1093 				case 0:
1094 					p->image = r_explosion1texture;
1095 					break;
1096 				case 1:
1097 					p->image = r_explosion2texture;
1098 					break;
1099 				case 2:
1100 					p->image = r_explosion3texture;
1101 					break;
1102 				case 3:
1103 					p->image = r_explosion4texture;
1104 					p->blendsrc = GL_SRC_ALPHA;
1105 					p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
1106 					break;
1107 				case 4:
1108 					p->image = r_explosion5texture;
1109 					break;
1110 				case 5:
1111 					p->image = r_explosion6texture;
1112 					p->blendsrc = GL_SRC_ALPHA;
1113 					p->blenddst = GL_ONE;
1114 					break;
1115 				case 6:
1116 					p->image = r_explosion7texture;
1117 					break;
1118 				default:
1119 					p->image = r_explosion1texture;
1120 					break;
1121 			}
1122 			if (p && i < 4)
1123 				addParticleLight (p,
1124 						p->scale*50*i, 0,
1125 					.4, .4, 0.1);
1126 		}
1127 	}
1128 
1129 	//place a big shock wave effect
1130 	if (!(p = new_particle()))
1131 			return;
1132 	p->alpha = 1.0;
1133 	p->alphavel = -2.0;
1134 	p->type = PARTICLE_FLAT;
1135 	p->image = r_explosion5texture;
1136 	p->blendsrc = GL_SRC_ALPHA;
1137 	p->blenddst = GL_ONE;
1138 	p->color = 0xd9 + (rand()&7);
1139 	p->scale = 12 + (rand()&4) ;
1140 	p->scalevel = 100;
1141 	for(j = 0; j < 3; j++) {
1142 		p->org[j] = org[j];
1143 		p->vel[j] = 0;
1144 		p->accel[j] = 0;
1145 	}
1146 
1147 	//add smoke
1148 	for (i=0 ; i<7; i++)
1149 	{
1150 
1151 		if (!(p = new_particle()))
1152 			return;
1153 
1154 		for (j=0 ; j<3 ; j++)
1155 		{
1156 			p->org[j] = org[j] + ((rand()%32)-16);
1157 			p->vel[j] = 0;
1158 		}
1159 		p->type = PARTICLE_STANDARD;
1160 		p->accel[0] = p->accel[1] = p->accel[2] = 0;
1161 		p->alpha = 0.2;
1162 		p->alphavel = -2.0 / (30+frand()*1.4); //smoke lingers longer
1163 
1164 		p->blendsrc = GL_SRC_ALPHA;
1165 		p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
1166 		p->scale = 1 + (rand()&4);
1167 		p->scalevel = 12.0;
1168 		p->color = 1 + (rand()&10);
1169 		p->accel[2] = 10;
1170 
1171 		p->image = r_smoketexture;
1172 
1173 	}
1174 }
1175 
1176 /*
1177 ===============
1178 CL_MuzzleParticles - changed this to a smoke effect in 6.06
1179 ===============
1180 */
CL_MuzzleParticles(vec3_t org)1181 void CL_MuzzleParticles (vec3_t org)
1182 {
1183 	int			i, j;
1184 	particle_t	*p;
1185 
1186 	for ( i = 0; i < 4; i++)
1187 	{
1188 		if (!(p = new_particle()))
1189 			return;
1190 
1191 		for (j=0 ; j<3 ; j++)
1192 		{
1193 			p->org[j] = org[j] + crand()*1;
1194 			p->vel[j] = crand()*5;
1195 		}
1196 
1197 		p->alphavel = -1.0 / (30+frand()*1.4); //smoke lingers longer
1198 		p->alpha = .07;
1199 		p->type = PARTICLE_STANDARD;
1200 		p->image = r_smoketexture;
1201 		p->blendsrc = GL_SRC_ALPHA;
1202 		p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
1203 		p->scale = 1 + (rand()&4);
1204 		p->scalevel = 12.0;
1205 		p->color = 15;
1206 		p->accel[2] = 20;
1207 	}
1208 
1209 }
1210 /*
1211 ===============
1212 CL_MuzzleParticles - Blue
1213 ===============
1214 */
CL_BlueMuzzleParticles(vec3_t org)1215 void CL_BlueMuzzleParticles (vec3_t org)
1216 {
1217 	int			i, j;
1218 	particle_t	*p;
1219 
1220 	for ( i = 0; i < 4; i++)
1221 	{
1222 		if (!(p = new_particle()))
1223 			return;
1224 
1225 		p->type = PARTICLE_STANDARD;
1226 		p->image = r_cflashtexture;
1227 		p->scale = 16 + (rand()&7);
1228 		p->blendsrc = GL_SRC_ALPHA;
1229 		p->blenddst = GL_ONE;
1230 		for (j=0 ; j<3 ; j++)
1231 		{
1232 			p->org[j] = org[j] + ((rand()%2)-1);
1233 			p->vel[j] = 0;
1234 		}
1235 		p->accel[0] = p->accel[1] = 0;
1236 		p->accel[2] = 0;
1237 		p->alpha = 0.4;
1238 		p->color = 0x74;
1239 
1240 		p->alphavel = -2.8 / (0.5 + frand()*0.3);
1241 	}
1242 
1243 }
1244 
1245 /*
1246 ===============
1247 CL_MuzzleFlashParticle
1248 ===============
1249 */
1250 extern cvar_t *r_lefthand;
CL_MuzzleFlashParticle(vec3_t org,vec3_t angles,qboolean from_client)1251 void CL_MuzzleFlashParticle (vec3_t org, vec3_t angles, qboolean from_client)
1252 {
1253 	int			j;
1254 	particle_t	*p;
1255 	vec3_t		mflashorg, vforward, vright, vup, vec;
1256 	float		rightoffset, len;
1257 
1258 	if(!from_client) {
1259 		VectorSubtract (org, cl.refdef.vieworg, vec);
1260 		len = VectorNormalize (vec);
1261 		if(len < 128)
1262 			return;
1263 	}
1264 
1265 	VectorCopy(org, mflashorg);
1266 	for (j=0 ; j<3 ; j++)
1267 	{
1268 		mflashorg[j] = mflashorg[j] + ((rand()%2)-1);
1269 
1270 	}
1271 
1272 	if(from_client) {
1273 		AngleVectors (angles, vforward, vright, vup);
1274 
1275 		if (r_lefthand->value == 1.0F)
1276 			rightoffset = -2.4;
1277 		else
1278 			rightoffset = 2.4;
1279 
1280 		VectorMA(mflashorg, 24, vforward, mflashorg);
1281 		VectorMA(mflashorg, rightoffset, vright, mflashorg);
1282 		VectorMA(mflashorg, -2.5, vup, mflashorg);
1283 	}
1284 
1285 	if (!(p = new_particle()))
1286 		return;
1287 
1288 	p->type = PARTICLE_STANDARD;
1289 	p->image = r_bflashtexture;
1290 	p->scale = 7 + (rand()&4);
1291 	p->blendsrc = GL_SRC_ALPHA;
1292 	p->blenddst = GL_ONE;
1293 	for (j=0 ; j<3 ; j++)
1294 	{
1295 		p->org[j] = mflashorg[j];
1296 		p->vel[j] = 0;
1297 	}
1298 	p->accel[0] = p->accel[1] = 0;
1299 	p->accel[2] = 0;
1300 	p->alpha = 0.8;
1301 	p->color = 0xd9;
1302 	p->alphavel = -100;
1303 
1304 }
1305 
CL_PlasmaFlashParticle(vec3_t org,vec3_t angles,qboolean from_client)1306 void CL_PlasmaFlashParticle (vec3_t org, vec3_t angles, qboolean from_client)
1307 {
1308 	int			i, j;
1309 	particle_t	*p;
1310 	vec3_t		mflashorg, vforward, vright, vup, vec;
1311 	float		rightoffset, len, color;
1312 
1313 	if(!from_client) {
1314 		VectorSubtract (org, cl.refdef.vieworg, vec);
1315 		len = VectorNormalize (vec);
1316 		if(len < 128)
1317 			return;
1318 	}
1319 
1320 	VectorCopy(org, mflashorg);
1321 	for (j=0 ; j<3 ; j++)
1322 	{
1323 		mflashorg[j] = mflashorg[j] + ((rand()%2)-1);
1324 
1325 	}
1326 
1327 	if(from_client) {
1328 		AngleVectors (angles, vforward, vright, vup);
1329 
1330 		if (r_lefthand->value == 1.0F)
1331 			rightoffset = -4.4;
1332 		else
1333 			rightoffset = 4.4;
1334 
1335 		VectorMA(mflashorg, 24, vforward, mflashorg);
1336 		VectorMA(mflashorg, rightoffset, vright, mflashorg);
1337 		VectorMA(mflashorg, -4.5, vup, mflashorg);
1338 	}
1339 
1340 	//muzzleflash
1341 	color = getColor();
1342     for(i = 0; i < 3; i++) {
1343 
1344         if (!(p = new_particle()))
1345             return;
1346         p->alpha = 0.4;
1347         p->alphavel = -2.8 / (0.6+frand()*0.2);
1348         p->blenddst = GL_ONE;
1349         p->blendsrc = GL_SRC_ALPHA;
1350         p->image = r_cflashtexture;
1351         p->scale = 20/(i+1);
1352         p->type = PARTICLE_STANDARD;
1353         p->scalevel = 12;
1354         p->color = color;
1355         for (j=0 ; j<3 ; j++)
1356 		{
1357 			p->org[j] = mflashorg[j];
1358 			p->vel[j] = 0;
1359 			p->accel[j] = 0;
1360 		}
1361     }
1362 
1363 }
1364 /*
1365 ===============
1366 CL_SmartMuzzle
1367 ===============
1368 */
CL_SmartMuzzle(vec3_t org)1369 void CL_SmartMuzzle (vec3_t org)
1370 {
1371 	int			i, j;
1372 	particle_t	*p;
1373 
1374 	for ( i = 0; i < 3; i++)
1375 	{
1376 		if (!(p = new_particle()))
1377 			return;
1378 
1379 		p->type = PARTICLE_STANDARD;
1380 		p->image = r_leaderfieldtexture;
1381 		p->scale = 24 + (rand()&2);
1382 		p->color = 0xff;
1383 		p->blendsrc = GL_SRC_ALPHA;
1384 		p->blenddst = GL_ONE;
1385 
1386 		for (j=0 ; j<3 ; j++)
1387 		{
1388 			p->org[j] = org[j] + ((rand()%2)-1);
1389 			p->vel[j] = 0;
1390 		}
1391 		p->accel[0] = p->accel[1] = 0;
1392 		p->accel[2] = 0;
1393 		p->alpha = 0.7;
1394 
1395 		p->alphavel = -2.8 / (0.5 + frand()*0.3);
1396 	}
1397 
1398 }
1399 
1400 /*
1401 ===============
1402 CL_SmartMuzzle
1403 ===============
1404 */
CL_Voltage(vec3_t org)1405 void CL_Voltage (vec3_t org)
1406 {
1407 	int			i, j;
1408 	particle_t	*p;
1409 
1410 	for ( i = 0; i < 3; i++)
1411 	{
1412 		if (!(p = new_particle()))
1413 			return;
1414 
1415 		p->type = PARTICLE_STANDARD;
1416 		p->image = r_voltagetexture;
1417 		p->scale = 14 + (rand()&14);
1418 		p->color = 0xff;
1419 		p->blendsrc = GL_SRC_ALPHA;
1420 		p->blenddst = GL_ONE;
1421 
1422 		for (j=0 ; j<3 ; j++)
1423 		{
1424 			p->org[j] = org[j] + ((rand()%2)-1);
1425 			p->vel[j] = 0;
1426 		}
1427 		p->accel[0] = p->accel[1] = 0;
1428 		p->accel[2] = 0;
1429 		p->alpha = 0.7;
1430 
1431 		p->alphavel = -2.8 / (0.5 + frand()*0.3);
1432 	}
1433 
1434 }
1435 /*
1436 ===============
1437 CL_Deathfield
1438 ===============
1439 */
CL_Deathfield(vec3_t org,int type)1440 void CL_Deathfield (vec3_t org, int type)
1441 {
1442 	int			j;
1443 	particle_t	*p;
1444 
1445 	if (!(p = new_particle()))
1446 		return;
1447 
1448 	p->type = PARTICLE_STANDARD;
1449 	if(type)
1450 		p->image = r_deathfieldtexture2;
1451 	else
1452 		p->image = r_deathfieldtexture;
1453 	p->blendsrc = GL_SRC_ALPHA;
1454 	p->blenddst = GL_ONE;
1455 	for (j=0 ; j<3 ; j++)
1456 	{
1457 		p->org[j] = org[j] + ((rand()%2)-1);
1458 		p->vel[j] = 0;
1459 	}
1460 	p->accel[0] = p->accel[1] = 0;
1461 	p->accel[2] = 0;
1462 	p->alpha = 1.5;
1463 	p->scale = 10 + (rand()&2);
1464 	p->scalevel = 12;
1465 	p->color = 0x72;
1466 	p->accel[0] = p->accel[1] = 0;
1467 	p->accel[2] = PARTICLE_GRAVITY;
1468 	p->alphavel = -1.28 / (2.0 + frand()*0.3);
1469 }
1470 
1471 /*
1472 ===============
1473 CL_SayIcon
1474 
1475 Displays an icon above a player when talking
1476 ===============
1477 */
1478 
CL_SayIcon(vec3_t org)1479 void CL_SayIcon(vec3_t org)
1480 {
1481 	particle_t *p;
1482 	int j;
1483 
1484 	if(!(p = new_particle()))
1485 		return;
1486 
1487 	p->type = PARTICLE_STANDARD;
1488 	p->image = r_sayicontexture;
1489 	p->scale = 5;
1490 	p->scalevel = 0;
1491 	p->color = 15;
1492 	p->blendsrc = GL_SRC_ALPHA;
1493 	p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
1494 	for(j=0; j<3; j++)
1495 	{
1496 		p->org[j] = org[j];
1497 		p->vel[j] = 0;
1498 		p->accel[j] = 0;
1499 	}
1500 	p->org[2]+=40;
1501 	p->alpha = 0.9;
1502 
1503 	p->alphavel = -0.5;
1504 }
1505 
1506 
1507 /*
1508 ===============
1509 CL_DustParticles
1510 ===============
1511 */
CL_DustParticles(vec3_t org)1512 void CL_DustParticles (vec3_t org)
1513 {
1514 	int			i, j;
1515 	particle_t	*p;
1516 
1517 	for (i=0 ; i<64 ; i++)
1518 	{
1519 		if (!(p = new_particle()))
1520 			return;
1521 
1522 		p->type = PARTICLE_STANDARD;
1523 		p->image = r_pufftexture;
1524 		p->blendsrc = GL_SRC_ALPHA;
1525 		p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
1526 		p->scale = 4 + (rand()&2);
1527 		p->color = 15;
1528 		p->scalevel = 1.5;
1529 		for (j=0 ; j<3 ; j++)
1530 		{
1531 			p->org[j] = org[j] + ((rand()%4)-2);
1532 			p->vel[j] = (rand()%88)-44;
1533 		}
1534 
1535 		p->accel[0] = p->accel[1] = 0;
1536 		p->accel[2] = -PARTICLE_GRAVITY;
1537 		p->alpha = 0.5;
1538 
1539 		p->alphavel = -0.8 / (0.5 + frand()*0.3);
1540 	}
1541 }
1542 
1543 /*
1544 ===============
1545 CL_BigTeleportParticles
1546 ===============
1547 */
CL_BigTeleportParticles(vec3_t org)1548 void CL_BigTeleportParticles (vec3_t org)
1549 {
1550 	int			i, j;
1551 	particle_t	*p;
1552 
1553 	for (i=1 ; i<3 ; i++)
1554 	{
1555 		if (!(p = new_particle()))
1556 			return;
1557 
1558 		if(i == 1)
1559 			p->type = PARTICLE_ROTATINGROLL;
1560 		else
1561 			p->type = PARTICLE_STANDARD;
1562 		p->image = r_leaderfieldtexture;
1563 		p->scale = 16*i + (rand()&7);
1564 		p->blendsrc = GL_SRC_ALPHA;
1565 		p->blenddst = GL_ONE;
1566 		if(i>1)
1567 			p->color = 0xd4;
1568 		else
1569 			p->color = 0x74;
1570 		p->scalevel = 30;
1571 		for (j=0 ; j<3 ; j++)
1572 		{
1573 			p->org[j] = org[j];
1574 			p->vel[j] = 0;
1575 		}
1576 		p->accel[0] = p->accel[1] = 0;
1577 		p->accel[2] = 0;
1578 		p->alpha = 0.5;
1579 
1580 		p->alphavel = -0.9 / (0.5 + frand()*0.3);
1581 
1582 		addParticleLight (p,
1583 						p->scale*(2+(rand()&5)), 0,
1584 					0, .6, 0.4);
1585 	}
1586 }
1587 /*
1588 ===============
1589 CL_HealthParticles
1590 ===============
1591 */
CL_SmallHealthParticles(vec3_t org)1592 void CL_SmallHealthParticles (vec3_t org)
1593 {
1594 	particle_t	*p;
1595 	float		angle, dist;
1596 
1597 	if (!(p = new_particle()))
1598 			return;
1599 
1600 	p->type = PARTICLE_STANDARD;
1601 	p->image = r_cflashtexture;
1602 	p->scale = 10 + (rand()&7);
1603 	p->blendsrc = GL_SRC_ALPHA;
1604 	p->blenddst = GL_ONE;
1605 	p->color = 0xd4 + (rand() & 1);
1606 
1607 	angle = M_PI*2*(rand()&1023)/1023.0;
1608 	dist = rand()&5;
1609 	p->org[0] = org[0] + cos(angle)*dist;
1610 	p->vel[0] = cos(angle)*(6+(rand()&6));
1611 	p->accel[0] = -cos(angle)*6;
1612 
1613 	p->org[1] = org[1] + sin(angle)*dist;
1614 	p->vel[1] = sin(angle)*(6+(rand()&6));
1615 	p->accel[1] = -sin(angle)*100;
1616 
1617 	p->org[2] = org[2] + 8 + (rand()%10);
1618 	p->vel[2] = -10 + (rand()&6);
1619 	p->accel[2] = PARTICLE_GRAVITY*10;
1620 	p->alpha = 0.2;
1621 
1622 	p->alphavel = -2.6 / (0.5 + frand()*0.3);
1623 
1624 }
CL_MedHealthParticles(vec3_t org)1625 void CL_MedHealthParticles (vec3_t org)
1626 {
1627 	particle_t	*p;
1628 	float		angle, dist;
1629 
1630 	if (!(p = new_particle()))
1631 			return;
1632 
1633 	p->type = PARTICLE_STANDARD;
1634 	p->image = r_cflashtexture;
1635 	p->scale = 10 + (rand()&7);
1636 	p->blendsrc = GL_SRC_ALPHA;
1637 	p->blenddst = GL_ONE;
1638 	p->color = 0x74 + (rand() & 1);
1639 
1640 	angle = M_PI*2*(rand()&1023)/1023.0;
1641 	dist = rand()&5;
1642 	p->org[0] = org[0] + cos(angle)*dist;
1643 	p->vel[0] = cos(angle)*(6+(rand()&6));
1644 	p->accel[0] = -cos(angle)*6;
1645 
1646 	p->org[1] = org[1] + sin(angle)*dist;
1647 	p->vel[1] = sin(angle)*(6+(rand()&6));
1648 	p->accel[1] = -sin(angle)*100;
1649 
1650 	p->org[2] = org[2] + 8 + (rand()%10);
1651 	p->vel[2] = -10 + (rand()&6);
1652 	p->accel[2] = PARTICLE_GRAVITY*10;
1653 	p->alpha = 0.3;
1654 
1655 	p->alphavel = -2.6 / (0.5 + frand()*0.3);
1656 
1657 }
CL_LargeHealthParticles(vec3_t org)1658 void CL_LargeHealthParticles (vec3_t org)
1659 {
1660 	particle_t	*p;
1661 	float		angle, dist;
1662 
1663 	if (!(p = new_particle()))
1664 			return;
1665 
1666 	p->type = PARTICLE_STANDARD;
1667 	p->image = r_cflashtexture;
1668 	p->scale = 10 + (rand()&7);
1669 	p->blendsrc = GL_SRC_ALPHA;
1670 	p->blenddst = GL_ONE;
1671 	p->color = 0xff + (rand() & 1);
1672 
1673 	angle = M_PI*2*(rand()&1023)/1023.0;
1674 	dist = rand()&5;
1675 	p->org[0] = org[0] + cos(angle)*dist;
1676 	p->vel[0] = cos(angle)*(6+(rand()&6));
1677 	p->accel[0] = -cos(angle)*6;
1678 
1679 	p->org[1] = org[1] + sin(angle)*dist;
1680 	p->vel[1] = sin(angle)*(6+(rand()&6));
1681 	p->accel[1] = -sin(angle)*100;
1682 
1683 	p->org[2] = org[2] + 8 + (rand()%10);
1684 	p->vel[2] = -10 + (rand()&6);
1685 	p->accel[2] = PARTICLE_GRAVITY*10;
1686 	p->alpha = 0.3;
1687 
1688 	p->alphavel = -2.6 / (0.5 + frand()*0.3);
1689 
1690 }
1691 /*
1692 ===============
1693 CL_BlasterParticles
1694 
1695 Wall impact puffs for standard blaster.
1696 ===============
1697 */
CL_BlasterParticles(vec3_t org,vec3_t dir)1698 void CL_BlasterParticles (vec3_t org, vec3_t dir)
1699 {
1700 	int			i, j;
1701 	particle_t	*p;
1702 	float d;
1703 	for (i=0 ; i<16 ; i++)
1704 	{
1705 		if (!(p = new_particle()))
1706 			return;
1707 
1708 		p->type = PARTICLE_STANDARD;
1709 		p->image = r_cflashtexture;
1710 		p->blendsrc = GL_SRC_ALPHA;
1711 		p->blenddst = GL_ONE;
1712 		p->color = 0x74;
1713 		p->scale = (.75 * (i+1)) + (rand()&2);
1714 		p->scalevel = 12;
1715 		d = rand()&7;
1716 		for (j=0 ; j<3 ; j++)
1717 		{
1718 			p->org[j] = org[j]  +  d*dir[j];
1719 			p->vel[j] = 0;
1720 			p->accel[j] = 0;
1721 		}
1722 		p->alpha = 0.3;
1723 
1724 		p->alphavel = -8.8 / ((i*2) + frand()*0.3);
1725 
1726 		if (i > 4)
1727 			addParticleLight (p,
1728 					p->scale*25, 50,
1729 				0, .8, 1);
1730 	}
1731 }
1732 
1733 /*
1734 ===============
1735 CL_BlasterBall
1736 
1737 ===============
1738 */
CL_BlasterBall(vec3_t start,vec3_t end)1739 void CL_BlasterBall (vec3_t start, vec3_t end)
1740 {
1741 	vec3_t		move;
1742 	vec3_t		vec;
1743 	float		len;
1744 	int			j;
1745 	particle_t	*p;
1746 
1747 	VectorCopy (start, move);
1748 	VectorSubtract (end, start, vec);
1749 	len = VectorNormalize (vec);
1750 
1751 	VectorScale (vec, 5, vec);
1752 
1753 	if (!(p = new_particle()))
1754 		return;
1755 
1756 	p->alpha = 1;
1757 	p->alphavel = INSTANT_PARTICLE;
1758 	p->type = PARTICLE_ROTATINGROLL;
1759 	p->image = r_shottexture;
1760 	p->scale = 8;
1761 	p->angle[1] = cl.refdef.viewangles[0];
1762 	p->angle[0] = sin(len);
1763 	p->angle[2] = cl.refdef.viewangles[2];
1764 	p->blendsrc = GL_SRC_ALPHA;
1765 	p->blenddst = GL_ONE;
1766 	p->color = 0x72;
1767 
1768 	for (j=0 ; j<3 ; j++)
1769 	{
1770 		p->org[j] = move[j];
1771 		p->vel[j] = 0;
1772 		p->accel[j] = 0;
1773 	}
1774 
1775 	if (!(p = new_particle()))
1776 		return;
1777 
1778 	p->alpha = .95;
1779 	p->alphavel = INSTANT_PARTICLE;
1780 	p->type = PARTICLE_STANDARD;
1781 	p->image = r_cflashtexture;
1782 	p->scale = 15+5*frand();
1783 	p->blendsrc = GL_ONE;
1784 	p->blenddst = GL_ONE;
1785 	p->color = 0x79;
1786 
1787 	for (j=0 ; j<3 ; j++)
1788 	{
1789 		p->org[j] = move[j];
1790 		p->vel[j] = 0;
1791 		p->accel[j] = 0;
1792 	}
1793 }
1794 
1795 /*
1796 ===============
1797 Team Lights
1798 
1799 ===============
1800 */
1801 
CL_BlueTeamLight(vec3_t pos)1802 void CL_BlueTeamLight(vec3_t pos)
1803 {
1804 
1805 	int			i,j;
1806 	particle_t	*p;
1807 
1808 	if(!server_is_team && !cl_dmlights->value)
1809 		return;
1810 
1811 	for(i=1; i<3; i++) {
1812 		if (!(p = new_particle()))
1813 			return;
1814 
1815 		VectorClear (p->accel);
1816 
1817 		p->alpha = .7;
1818 		p->type = PARTICLE_STANDARD;
1819 		p->image = r_flaretexture;
1820 		p->blendsrc = GL_ONE;
1821 		p->blenddst = GL_ONE;
1822 		if (server_is_team)
1823 			p->color = 0x74;
1824 		else
1825 			p->color = 0xd3;
1826 		p->scale = 10*i;
1827 		p->alphavel = INSTANT_PARTICLE;
1828 		for (j=0 ; j<3 ; j++)
1829 		{
1830 			p->org[j] = pos[j];
1831 			p->vel[j] = 0;
1832 			p->accel[j] = 0;
1833 		}
1834 	}
1835 }
CL_RedTeamLight(vec3_t pos)1836 void CL_RedTeamLight(vec3_t pos)
1837 {
1838 
1839 	int			j,i;
1840 	particle_t	*p;
1841 
1842 	for(i=1; i<3; i++) {
1843 		if (!(p = new_particle()))
1844 			return;
1845 
1846 		VectorClear (p->accel);
1847 
1848 		p->alpha = .7;
1849 		p->type = PARTICLE_STANDARD;
1850 		p->image = r_flaretexture;
1851 		p->blendsrc = GL_ONE;
1852 		p->blenddst = GL_ONE;
1853 		p->color = 0xe8;
1854 		p->scale = 10*i;
1855 		p->alphavel = INSTANT_PARTICLE;
1856 		for (j=0 ; j<3 ; j++)
1857 		{
1858 			p->org[j] = pos[j];
1859 			p->vel[j] = 0;
1860 			p->accel[j] = 0;
1861 		}
1862 	}
1863 }
CL_FlagEffects(vec3_t pos,qboolean team)1864 void CL_FlagEffects(vec3_t pos, qboolean team)
1865 {
1866 
1867 	int			i;
1868 	particle_t	*p;
1869 	float		dist, angle;
1870 
1871 	if (!(p = new_particle()))
1872 		return;
1873 
1874 	VectorClear (p->accel);
1875 
1876 	p->alpha = 1.0;
1877 	p->type = PARTICLE_ROTATINGYAW;
1878 	p->image = r_flagtexture;
1879 	p->blendsrc = GL_ONE;
1880 	p->blenddst = GL_ONE;
1881 	if(team)
1882 		p->color = 0x74;
1883 	else
1884 		p->color = 0xe8;
1885 	p->scale = 15;
1886 	p->alphavel = INSTANT_PARTICLE;
1887 	for (i=0 ; i<3 ; i++)
1888 	{
1889 		p->org[i] = pos[i];
1890 		p->vel[i] = 0;
1891 		p->accel[i] = 0;
1892 	}
1893 	p->org[2] += 64;
1894 
1895 
1896 
1897 	if (!(p = new_particle()))
1898 			return;
1899 
1900 	p->type = PARTICLE_STANDARD;
1901 	p->image = r_cflashtexture;
1902 	p->scale = 20 + (rand()&7);
1903 	p->blendsrc = GL_ONE;
1904 	p->blenddst = GL_ONE;
1905 	if(team)
1906 		p->color = 0x74;
1907 	else
1908 		p->color = 0xe8;
1909 
1910 	angle = M_PI*2*(rand()&1023)/1023.0;
1911 	dist = rand()&5;
1912 	p->org[0] = pos[0] + cos(angle)*dist;
1913 	p->vel[0] = cos(angle)*(6+(rand()&6));
1914 	p->accel[0] = -cos(angle)*6;
1915 
1916 	p->org[1] = pos[1] + sin(angle)*dist;
1917 	p->vel[1] = sin(angle)*(6+(rand()&6));
1918 	p->accel[1] = -sin(angle)*100;
1919 
1920 	p->org[2] = pos[2] + 56 + (rand()%10);
1921 	p->vel[2] = -10 + (rand()&6);
1922 	p->accel[2] = PARTICLE_GRAVITY*10;
1923 	p->alpha = 0.2;
1924 
1925 	p->alphavel = -50 / (0.5 + frand()*0.3);
1926 }
1927 
1928 /*
1929 ===============
1930 CL_BloodSplatter - simple blood effects
1931 ===============
1932 */
1933 
CL_BloodSplatter(vec3_t pos,vec3_t pos2,int color,int blend)1934 void CL_BloodSplatter ( vec3_t pos, vec3_t pos2, int color, int blend )
1935 {
1936 	particle_t *p;
1937 	vec3_t		v;
1938 	int			j;
1939 	trace_t	trace;
1940 	static vec3_t mins = { -1, -1, -1 };
1941     static vec3_t maxs = { 1, 1, 1 };
1942 
1943 	//trace to see if impact occurs with nearby brush
1944 	trace = CL_Trace ( pos, mins, maxs, pos2, -1, MASK_SOLID, true, NULL);
1945 	if(trace.contents) { //hit a brush
1946 
1947 		if(!(p = new_particle()))
1948 			return;
1949 
1950 		p->image = r_bloodtexture;
1951 		p->color = color + (rand() & 1);
1952 		p->type = PARTICLE_DECAL;
1953 		p->blendsrc = GL_SRC_ALPHA;
1954 		if(blend) //glowing blood
1955 			p->blenddst = GL_ONE;
1956 		else
1957 			p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
1958 		p->scale = 2;
1959 		p->scalevel = 0;
1960 
1961 		VectorScale(trace.plane.normal, -1, v);
1962 		RotateForNormal(v, p->angle);
1963 		p->angle[ROLL] = rand() % 360;
1964 		VectorAdd(pos2, trace.plane.normal, p->org);
1965 
1966 		p->alpha = 0.7;
1967 		p->alphavel = -0.2 / (2.0 + frand() * 0.3);
1968 		for (j=0 ; j<3 ; j++)
1969 		{
1970 				p->accel[j] = 0;
1971 				p->vel[j] = 0;
1972 		}
1973 	}
1974 }
1975 
1976 /*
1977 ===============
1978 CL_DiminishingTrail
1979 
1980 ===============
1981 */
CL_DiminishingTrail(vec3_t start,vec3_t end,centity_t * old,int flags)1982 void CL_DiminishingTrail (vec3_t start, vec3_t end, centity_t *old, int flags)
1983 {
1984 	vec3_t		move;
1985 	vec3_t		vec;
1986 	float		len;
1987 	int			j;
1988 	particle_t	*p;
1989 	float		dec;
1990 	float		orgscale;
1991 	float		velscale;
1992 
1993 	if (((flags & EF_GIB) || (flags & EF_GREENGIB)) && cl_noblood->value)
1994 		return;
1995 
1996 	VectorCopy (start, move);
1997 	VectorSubtract (end, start, vec);
1998 	len = VectorNormalize (vec);
1999 
2000 	dec = 2.5;
2001 	VectorScale (vec, dec, vec);
2002 
2003 	if (old->trailcount > 900)
2004 	{
2005 		orgscale = 4;
2006 		velscale = 15;
2007 	}
2008 	else if (old->trailcount > 800)
2009 	{
2010 		orgscale = 2;
2011 		velscale = 10;
2012 	}
2013 	else
2014 	{
2015 		orgscale = 1;
2016 		velscale = 5;
2017 	}
2018 
2019 	// add stains if moving
2020 	if ( len && !cl_noblood->value ) {
2021 		if ( flags & EF_GIB ) {
2022 			CL_BloodSplatter(start, end, 0xe8, 0);
2023 		} else if ( flags & EF_GREENGIB ) {
2024 			CL_BloodSplatter(start, end, 0xd0, 1);
2025 		}
2026 	}
2027 
2028 	while (len > 0)
2029 	{
2030 		len -= dec;
2031 
2032 		if (!free_particles)
2033 			return;
2034 
2035 		// drop less particles as it flies
2036 		if ((rand()&1023) < old->trailcount)
2037 		{
2038 			if (!(p = new_particle()))
2039 				return;
2040 
2041 			if (flags & EF_GIB)
2042 			{
2043 				p->alpha = .6;//1.0;
2044 				p->alphavel = -1.0 / (1+frand()*0.4);
2045 				p->type = PARTICLE_STANDARD;
2046 				p->image = r_bloodtexture;
2047 				p->blendsrc = GL_SRC_ALPHA;
2048 				p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
2049 				p->color = 0xe8;
2050 				p->scale = 6;
2051 				p->scalevel = 1.5;
2052 				for (j=0 ; j<3 ; j++)
2053 				{
2054 					p->org[j] = move[j] + crand()*orgscale;
2055 					p->vel[j] = crand()*velscale;
2056 					p->accel[j] = 0;
2057 				}
2058 				p->vel[2] -= PARTICLE_GRAVITY;
2059 			}
2060 			else if (flags & EF_GREENGIB)
2061 			{
2062 				p->alpha = .6;
2063 				p->alphavel = -1.0 / (1+frand()*0.4);
2064 				p->type = PARTICLE_STANDARD;
2065 				p->image = r_bloodtexture;
2066 				p->blendsrc = GL_SRC_ALPHA;
2067 				p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
2068 				p->color = 0xd0+ (rand()&3);
2069 				p->scale = 6;
2070 				p->scalevel = 1.5;
2071 				for (j=0; j< 3; j++)
2072 				{
2073 					p->org[j] = move[j] + crand()*orgscale;
2074 					p->vel[j] = crand()*velscale;
2075 					p->accel[j] = 0;
2076 				}
2077 				p->vel[2] -= PARTICLE_GRAVITY;
2078 			}
2079 			else
2080 			{
2081 				dec = 10; //less smoke
2082 				for (j=0 ; j<3 ; j++)
2083 				{
2084 					p->org[j] = move[j] + crand()*orgscale;
2085 					p->vel[j] = crand()*velscale;
2086 				}
2087 
2088 				p->alphavel = -1.0 / (10+frand()*1.4); //smoke lingers longer
2089 				p->alpha = .07;
2090 				p->type = PARTICLE_STANDARD;
2091 				p->image = r_smoketexture;
2092 				p->blendsrc = GL_SRC_ALPHA;
2093 				p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
2094 				p->scale = 1 + (rand()&4);
2095 				p->scalevel = 15.0;
2096 				p->color = 15;
2097 				p->accel[2] = 20;
2098 			}
2099 		}
2100 
2101 		old->trailcount -= 5;
2102 		if (old->trailcount < 100)
2103 			old->trailcount = 100;
2104 		VectorAdd (move, vec, move);
2105 	}
2106 }
2107 
MakeNormalVectors(vec3_t forward,vec3_t right,vec3_t up)2108 void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up)
2109 {
2110 	float		d;
2111 
2112 	// this rotate and negat guarantees a vector
2113 	// not colinear with the original
2114 	right[1] = -forward[0];
2115 	right[2] = forward[1];
2116 	right[0] = forward[2];
2117 
2118 	d = DotProduct (right, forward);
2119 	VectorMA (right, -d, forward, right);
2120 	VectorNormalize (right);
2121 	CrossProduct (right, forward, up);
2122 }
2123 
2124 /*
2125 ===============
2126 CL_RocketTrail
2127 
2128 ===============
2129 */
CL_RocketTrail(vec3_t start,vec3_t end,centity_t * old)2130 void CL_RocketTrail (vec3_t start, vec3_t end, centity_t *old)
2131 {
2132 
2133 	// smoke
2134 	CL_DiminishingTrail (start, end, old, EF_ROCKET);
2135 
2136 }
2137 
CL_BlasterTrail(vec3_t start,vec3_t end,centity_t * old)2138 void CL_BlasterTrail (vec3_t start, vec3_t end, centity_t *old)
2139 {
2140 	vec3_t		move;
2141 	vec3_t		vec;
2142 	float		len;
2143 	int			j;
2144 	particle_t	*p;
2145 	float		dec;
2146 
2147 	VectorCopy (start, move);
2148 	VectorSubtract (end, start, vec);
2149 	len = VectorNormalize (vec);
2150 
2151 	dec = 20;
2152 	VectorScale (vec, dec, vec);
2153 
2154 	while (len > 0)
2155 	{
2156 		len -= dec;
2157 
2158 		if ( (rand()&6) == 0)
2159 		{
2160 			if (!(p = new_particle()))
2161 				return;
2162 
2163 			VectorClear (p->accel);
2164 			p->color = 0xd0 + (rand()&2);
2165 			p->scale = 2 + (rand()&7);
2166 			p->scalevel = 5;
2167 			p->alpha = .3;
2168 			p->alphavel = -1.0 / (3+frand()*0.2);
2169 			p->type = PARTICLE_STANDARD;
2170 			p->image = r_cflashtexture;
2171 			p->blendsrc = GL_SRC_ALPHA;
2172 			p->blenddst = GL_ONE;
2173 			for (j=0 ; j<3 ; j++)
2174 			{
2175 				p->org[j] = move[j] + crand()*2;
2176 				p->vel[j] = crand()*2;
2177 			}
2178 			p->accel[2] = 0;
2179 		}
2180 		VectorAdd (move, vec, move);
2181 
2182 	}
2183 }
2184 
CL_ShipExhaust(vec3_t start,vec3_t end,centity_t * old)2185 void CL_ShipExhaust (vec3_t start, vec3_t end, centity_t *old)
2186 {
2187 	vec3_t		move;
2188 	vec3_t		vec;
2189 	float		len;
2190 	int			j;
2191 	particle_t	*p;
2192 	float		dec;
2193 
2194 	VectorCopy (start, move);
2195 	VectorSubtract (end, start, vec);
2196 	len = VectorNormalize (vec);
2197 
2198 	dec = 3;
2199 	VectorScale (vec, dec, vec);
2200 
2201 	while (len > 0)
2202 	{
2203 		len -= dec;
2204 
2205 		if ( (rand()&6) == 0)
2206 		{
2207 			if (!(p = new_particle()))
2208 				return;
2209 
2210 			VectorClear (p->accel);
2211 			p->color = 0xc0 + (rand()&2);
2212 			p->scale = 2 + (rand()&7);
2213 			p->scalevel = 5;
2214 			p->alpha = .3;
2215 			p->alphavel = -1.0 / (3+frand()*0.2);
2216 			p->type = PARTICLE_STANDARD;
2217 			p->image = r_explosiontexture;
2218 			p->blendsrc = GL_SRC_ALPHA;
2219 			p->blenddst = GL_ONE;
2220 			for (j=0 ; j<3 ; j++)
2221 			{
2222 				p->org[j] = move[j] + crand()*2;
2223 				p->vel[j] = crand()*2;
2224 			}
2225 			p->accel[2] = 0;
2226 		}
2227 		VectorAdd (move, vec, move);
2228 
2229 	}
2230 }
2231 
CL_RocketExhaust(vec3_t start,vec3_t end,centity_t * old)2232 void CL_RocketExhaust (vec3_t start, vec3_t end, centity_t *old)
2233 {
2234 	vec3_t		move;
2235 	vec3_t		vec;
2236 	float		len;
2237 	int			j;
2238 	particle_t	*p;
2239 
2240 	VectorCopy (start, move);
2241 	VectorSubtract (end, start, vec);
2242 	len = VectorNormalize (vec);
2243 
2244 	VectorScale (vec, 5, vec);
2245 
2246 	if (!(p = new_particle()))
2247 		return;
2248 
2249 	VectorClear (p->accel);
2250 
2251 	p->alpha = .3;
2252 	p->alphavel = INSTANT_PARTICLE;
2253 	p->type = PARTICLE_ROTATINGROLL;
2254 	p->image = r_bflashtexture;
2255 	p->scale = 5;
2256 	p->angle[0] = cl.refdef.viewangles[0];
2257 	p->angle[1] = cl.refdef.viewangles[1];
2258 	p->angle[2] = cl.refdef.viewangles[2];
2259 
2260 	p->blendsrc = GL_SRC_ALPHA;
2261 	p->blenddst = GL_ONE;
2262 	p->color = 0xc0 + (rand()&2);
2263 	for (j=0 ; j<3 ; j++)
2264 	{
2265 		p->org[j] = move[j];
2266 		p->vel[j] = 0;
2267 		p->accel[j] = 0;
2268 	}
2269 
2270 	if (!(p = new_particle()))
2271 		return;
2272 
2273 	VectorClear (p->accel);
2274 
2275 	p->alpha = .7;
2276 	p->alphavel = INSTANT_PARTICLE;
2277 	p->type = PARTICLE_STANDARD;
2278 	p->image = r_bflashtexture;
2279 	p->scale = 5;
2280 	p->angle[0] = cl.refdef.viewangles[0];
2281 	p->angle[1] = cl.refdef.viewangles[1];
2282 	p->angle[2] = cl.refdef.viewangles[2];
2283 
2284 	p->blendsrc = GL_SRC_ALPHA;
2285 	p->blenddst = GL_ONE;
2286 	p->color = 0xc0 + (rand()&2);
2287 	for (j=0 ; j<3 ; j++)
2288 	{
2289 		p->org[j] = move[j];
2290 		p->vel[j] = 0;
2291 		p->accel[j] = 0;
2292 	}
2293 
2294 	if (!(p = new_particle()))
2295 		return;
2296 
2297 	VectorClear (p->accel);
2298 
2299 	p->alpha = .7;
2300 	p->alphavel = INSTANT_PARTICLE;
2301 	p->type = PARTICLE_STANDARD;
2302 	p->image = r_flaretexture;
2303 	p->scale = 10;
2304 	p->angle[0] = cl.refdef.viewangles[0];
2305 	p->angle[1] = cl.refdef.viewangles[1];
2306 	p->angle[2] = cl.refdef.viewangles[2];
2307 
2308 	p->blendsrc = GL_ONE;
2309 	p->blenddst = GL_ONE;
2310 	p->color = 0xc0 + (rand()&2);
2311 	for (j=0 ; j<3 ; j++)
2312 	{
2313 		p->org[j] = move[j];
2314 		p->vel[j] = 0;
2315 		p->accel[j] = 0;
2316 	}
2317 
2318 	VectorAdd (move, vec, move);
2319 }
2320 
2321 /*
2322 ===============
2323 Wall Impacts
2324 
2325 ===============
2326 */
2327 
CL_BulletMarks(vec3_t org,vec3_t dir)2328 void CL_BulletMarks(vec3_t org, vec3_t dir){
2329 	particle_t *p;
2330 	vec3_t		v;
2331 	int			j;
2332 
2333 	if(!(p = new_particle()))
2334 		return;
2335 
2336 	p->image = r_bulletnormal;
2337 	p->color = 0 + (rand() & 1);
2338 	p->type = PARTICLE_RAISEDDECAL;
2339 	p->blendsrc = GL_DST_COLOR;
2340 	p->blenddst = GL_SRC_COLOR;
2341 
2342 	VectorScale(dir, -1, v);
2343 	RotateForNormal(v, p->angle);
2344 	p->angle[ROLL] = rand() % 360;
2345 	VectorAdd(org, dir, p->org);
2346 
2347 	p->scale = .5;
2348 	p->alpha = 0.5;
2349 	p->alphavel = -0.2 / (2.0 + frand() * 0.3);
2350 	for (j=0 ; j<3 ; j++)
2351 	{
2352 		p->accel[j] = 0;
2353 		p->vel[j] = 0;
2354 	}
2355 }
CL_BeamgunMark(vec3_t org,vec3_t dir,float dur,qboolean isDis)2356 void CL_BeamgunMark(vec3_t org, vec3_t dir, float dur, qboolean isDis){
2357 	particle_t *p;
2358 	vec3_t		v;
2359 	int			j;
2360 	float		color;
2361 	vec3_t		colorvec;
2362 
2363 	if(isDis)
2364 		color = getColor();
2365 	else
2366 		color = 0xd4;
2367 
2368 	if(!(p = new_particle()))
2369 		return;
2370 
2371 	p->image = r_bullettexture;
2372 	p->color = color + (rand() & 1);
2373 	p->type = PARTICLE_DECAL;
2374 	p->blendsrc = GL_SRC_ALPHA;
2375 	p->blenddst = GL_ONE;
2376 	p->scale = .75;
2377 	p->scalevel = 0;
2378 
2379 	VectorScale(dir, -1, v);
2380 	RotateForNormal(v, p->angle);
2381 	p->angle[ROLL] = rand() % 360;
2382 	VectorAdd(org, dir, p->org);
2383 
2384 	p->alpha = 0.5;
2385 	p->alphavel = -dur / (2.0 + frand() * 0.3);
2386 	for (j=0 ; j<3 ; j++)
2387 	{
2388 			p->accel[j] = 0;
2389 			p->vel[j] = 0;
2390 	}
2391 	if(!(p = new_particle()))
2392 		return;
2393 
2394 	p->image = r_bullettexture;
2395 	p->color = color + (rand() & 1);
2396 	p->type = PARTICLE_DECAL;
2397 	p->blendsrc = GL_SRC_ALPHA;
2398 	p->blenddst = GL_ONE;
2399 	p->scale = 1.5;
2400 	p->scalevel = 0;
2401 
2402 	VectorScale(dir, -1, v);
2403 	RotateForNormal(v, p->angle);
2404 	p->angle[ROLL] = rand() % 360;
2405 	VectorAdd(org, dir, p->org);
2406 
2407 	p->alpha = 0.5;
2408 	p->alphavel = -dur / (2.0 + frand() * 0.3);
2409 	for (j=0 ; j<3 ; j++)
2410 	{
2411 			p->accel[j] = 0;
2412 			p->vel[j] = 0;
2413 	}
2414 
2415 	//add small shockwave effect
2416 	if(!(p = new_particle()))
2417 		return;
2418 
2419 	p->image = r_hittexture;
2420 	p->color = color + (rand() & 1);
2421 	p->type = PARTICLE_DECAL;
2422 	p->blendsrc = GL_SRC_ALPHA;
2423 	p->blenddst = GL_ONE;
2424 	p->scale = .1;
2425 	p->scalevel = 10;
2426 
2427 	VectorScale(dir, -1, v);
2428 	RotateForNormal(v, p->angle);
2429 	p->angle[ROLL] = rand() % 360;
2430 	VectorAdd(org, dir, p->org);
2431 
2432 	p->alpha = 1.0;
2433 	p->alphavel = -2.0;
2434 	for (j=0 ; j<3 ; j++)
2435 	{
2436 			p->accel[j] = 0;
2437 			p->vel[j] = 0;
2438 	}
2439 
2440 	if(isDis)
2441 		getColorvec(colorvec);
2442 	else {
2443 		colorvec[0] = 0; //bright green
2444 		colorvec[1] = 1;
2445 		colorvec[2] = 0.2;
2446 	}
2447 
2448 	addParticleLight (p,
2449 			isDis ? 120:80, 5,
2450 			colorvec[0], colorvec[1], colorvec[2]);
2451 }
2452 
CL_BlasterMark(vec3_t org,vec3_t dir)2453 void CL_BlasterMark(vec3_t org, vec3_t dir){
2454 	particle_t *p;
2455 	vec3_t		v;
2456 	int			j;
2457 
2458 	if(!(p = new_particle()))
2459 		return;
2460 
2461 	p->image = r_bullettexture;
2462 	p->color = 0x74 + (rand() & 1);
2463 	p->type = PARTICLE_DECAL;
2464 	p->blendsrc = GL_SRC_ALPHA;
2465 	p->blenddst = GL_ONE;
2466 	p->scale = .75;
2467 	p->scalevel = 0;
2468 
2469 	VectorScale(dir, -1, v);
2470 	RotateForNormal(v, p->angle);
2471 	p->angle[ROLL] = rand() % 360;
2472 	VectorAdd(org, dir, p->org);
2473 
2474 	p->alpha = 0.7;
2475 	p->alphavel = -0.4 / (2.0 + frand() * 0.3);
2476 	for (j=0 ; j<3 ; j++)
2477 	{
2478 			p->accel[j] = 0;
2479 			p->vel[j] = 0;
2480 	}
2481 	if(!(p = new_particle()))
2482 		return;
2483 
2484 	p->image = r_bullettexture;
2485 	p->color = 0x74 + (rand() & 1);
2486 	p->type = PARTICLE_DECAL;
2487 	p->blendsrc = GL_SRC_ALPHA;
2488 	p->blenddst = GL_ONE;
2489 	p->scale = 1.5;
2490 	p->scalevel = 0;
2491 
2492 	VectorScale(dir, -1, v);
2493 	RotateForNormal(v, p->angle);
2494 	p->angle[ROLL] = rand() % 360;
2495 	VectorAdd(org, dir, p->org);
2496 
2497 	p->alpha = 0.5;
2498 	p->alphavel = -0.4 / (2.0 + frand() * 0.3);
2499 	for (j=0 ; j<3 ; j++)
2500 	{
2501 			p->accel[j] = 0;
2502 			p->vel[j] = 0;
2503 	}
2504 }
2505 
CL_VaporizerMarks(vec3_t org,vec3_t dir)2506 void CL_VaporizerMarks(vec3_t org, vec3_t dir){
2507 	particle_t *p;
2508 	vec3_t		v, forward, right, up;
2509 	int			i,j;
2510 	float		scatter;
2511 
2512 	for(i = 0; i < 6; i ++) {
2513 		if(!(p = new_particle()))
2514 			return;
2515 
2516 		p->image = r_bullettexture;
2517 		p->color = 0xd4 + (rand()&7);
2518 		p->type = PARTICLE_DECAL;
2519 		p->blendsrc = GL_SRC_ALPHA;
2520 		p->blenddst = GL_ONE;
2521 		p->scale = .75;
2522 		p->scalevel = 0;
2523 
2524 		VectorScale(dir, -1, v);
2525 		RotateForNormal(v, p->angle);
2526 		p->angle[ROLL] = rand() % 360;
2527 		VectorAdd(org, dir, p->org);
2528 
2529 		AngleVectors(p->angle, forward, right, up);
2530 
2531 		scatter = ((rand()%8)-4);
2532 		VectorMA(p->org, scatter, up, p->org);
2533 
2534 		p->alpha = 0.7;
2535 		p->alphavel = -0.4 / (2.0 + frand() * 0.3);
2536 		for (j=0 ; j<3 ; j++)
2537 		{
2538 				p->accel[j] = 0;
2539 				p->vel[j] = 0;
2540 		}
2541 		if(!(p = new_particle()))
2542 			return;
2543 
2544 		p->image = r_bullettexture;
2545 		p->color = 0x74 + (rand()&7);
2546 		p->type = PARTICLE_DECAL;
2547 		p->blendsrc = GL_SRC_ALPHA;
2548 		p->blenddst = GL_ONE;
2549 		p->scale = 1.5;
2550 		p->scalevel = 0;
2551 
2552 		VectorScale(dir, -1, v);
2553 		RotateForNormal(v, p->angle);
2554 		p->angle[ROLL] = rand() % 360;
2555 		VectorAdd(org, dir, p->org);
2556 
2557 		VectorMA(p->org, scatter, up, p->org);
2558 
2559 		p->alpha = 0.5;
2560 		p->alphavel = -0.4 / (2.0 + frand() * 0.3);
2561 		for (j=0 ; j<3 ; j++)
2562 		{
2563 				p->accel[j] = 0;
2564 				p->vel[j] = 0;
2565 		}
2566 	}
2567 }
2568 
2569 /*
2570 ===============
2571 Particle Beams
2572 
2573 ===============
2574 */
2575 
2576 //this is the length of each piece...
2577 #define RAILTRAILSPACE 20
2578 #define LASERTRAILSPACE 10
2579 
CL_DisruptorBeam(vec3_t start,vec3_t end)2580 void CL_DisruptorBeam (vec3_t start, vec3_t end)
2581 {
2582 	vec3_t		move;
2583 	vec3_t		vec, point, last, vec2;
2584 	float		len, color;
2585 	vec3_t		right, up;
2586 	particle_t	*p;
2587 	int			i,j;
2588 	float		v;
2589 
2590 	color = getColor();
2591 
2592 	VectorSubtract (end, start, vec);
2593 	len = VectorNormalize (vec);
2594 	VectorCopy (vec, point);
2595 
2596 	MakeNormalVectors (vec, right, up);
2597 	VectorCopy (vec, vec2);
2598 	VectorScale (vec, RAILTRAILSPACE, vec);
2599 	VectorCopy (start, move);
2600 
2601 	for (i = 0; len>0; len -= RAILTRAILSPACE, i+=100)
2602 	{
2603 		VectorCopy (move, last);
2604 		VectorAdd (move, vec, move);
2605 
2606 		if (!(p = new_particle()))
2607 				return;
2608 
2609 		p->alpha = 1;
2610 		p->alphavel = -1.0 - (len/(float)i);
2611 		p->blenddst = GL_ONE;
2612 		p->blendsrc = GL_SRC_ALPHA;
2613 
2614 		v = frand();
2615 		if(v < 0.2)
2616 			p->image = r_dis3texture;
2617 		else if(v < 0.5)
2618 			p->image = r_dis2texture;
2619 		else
2620 			p->image = r_dis1texture;
2621 
2622 		p->scale = 4;
2623 		VectorCopy(move, p->angle);
2624 		p->type = PARTICLE_BEAM;
2625 		p->scalevel = 0;
2626 
2627 		p->color = color;
2628 
2629 		for (j=0 ; j<3 ; j++)
2630 		{
2631 			p->org[j] = last[j];
2632 			p->vel[j] = 0;
2633 			p->accel[j] = 0;
2634 		}
2635 	}
2636 }
2637 
CL_LaserBeam(vec3_t start,vec3_t end)2638 void CL_LaserBeam (vec3_t start, vec3_t end)
2639 {
2640 
2641 	vec3_t		move;
2642 	vec3_t		vec, point, last, vec2;
2643 	float		len;
2644 	vec3_t		right, up;
2645 	particle_t	*p, *pr;
2646 	int			i,j;
2647 
2648 	VectorSubtract (end, start, vec);
2649 	len = VectorNormalize (vec);
2650 	VectorCopy (vec, point);
2651 
2652 	MakeNormalVectors (vec, right, up);
2653 	VectorCopy (vec, vec2);
2654 	VectorScale (vec, RAILTRAILSPACE, vec);
2655 	VectorCopy (start, move);
2656 
2657 	//muzzleflash
2658 	VectorScale (vec2, -RAILTRAILSPACE/2, vec2);
2659 	VectorAdd(start, vec2, start);
2660 	for(i = 0; i < 3; i++) {
2661 
2662 		if (!(p = new_particle()))
2663 			return;
2664 		p->alpha = 0.9;
2665 		p->alphavel = -2.8 / (0.6+frand()*0.2);
2666 		p->blenddst = GL_ONE;
2667 		p->blendsrc = GL_SRC_ALPHA;
2668 		p->image = r_cflashtexture;
2669 		p->scale = 12/(i+1);
2670 		for(j=0; j< 3; j++)
2671 			p->angle[j] = 0;
2672 		p->type = PARTICLE_STANDARD;
2673 		p->scalevel = 8;
2674 		p->color = 0xd4;
2675 		for (j=0 ; j<3 ; j++)
2676 		{
2677 			p->org[j] = start[j];
2678 			p->vel[j] = 0;
2679 			p->accel[j] = 0;
2680 		}
2681 	}
2682 
2683 	//Dummy particle that won't get drawn -- the first particle in a chain is
2684 	//always skipped.
2685 	if (!(pr = new_particle ()))
2686 		return;
2687 	pr->alpha = 0.9;
2688 	pr->alphavel = -2.8;
2689 	pr->scale = 4;
2690 	pr->scalevel = 0;
2691 	VectorCopy (start, pr->org);
2692 	VectorClear (pr->vel);
2693 	VectorClear (pr->accel);
2694 	pr->type = PARTICLE_CHAINED;
2695 	pr->color = 0xd4;
2696 	pr->image = r_beam2texture;
2697 
2698 	if (!(p = new_particle()))
2699 		return;
2700 
2701 	p->alpha = 0.9;
2702 	p->alphavel = -2.8;
2703 	p->blenddst = GL_ONE;
2704 	p->blendsrc = GL_SRC_ALPHA;
2705 
2706 	p->image = r_beam2texture;
2707 	p->scale = 4;
2708 	VectorCopy(move, p->angle);
2709 	p->type = PARTICLE_CHAINED;
2710 	p->scalevel = 0;
2711 
2712 	p->color = 0xd4;
2713 	p->chain_prev = pr;
2714 
2715 	for (j=0 ; j<3 ; j++)
2716 	{
2717 		p->org[j] = end[j];
2718 		p->vel[j] = 0;
2719 		p->accel[j] = 0;
2720 	}
2721 
2722 	for (; len>0; len -= RAILTRAILSPACE)
2723 	{
2724 		VectorCopy (move, last);
2725 		VectorAdd (move, vec, move);
2726 
2727 		if (len > 40)
2728 			continue;
2729 
2730 		if (!(p = new_particle()))
2731 				return;
2732 
2733 		p->alpha = 0.9;
2734 		p->alphavel = -2.8;
2735 		p->blenddst = GL_ONE;
2736 		p->blendsrc = GL_SRC_ALPHA;
2737 		p->image = r_flaretexture;
2738 		p->scale = 24;
2739 		for(j=0; j< 3; j++)
2740 			p->angle[j] = 0;
2741 		p->type = PARTICLE_STANDARD;
2742 		p->scalevel = 12;
2743 		p->color = 0xd4;
2744 
2745 		for (j=0 ; j<3 ; j++)
2746 		{
2747 			p->org[j] = last[j];
2748 			p->vel[j] = 0;
2749 			p->accel[j] = 0;
2750 		}
2751 	}
2752 }
CL_BlasterBeam(vec3_t start,vec3_t end)2753 void CL_BlasterBeam (vec3_t start, vec3_t end)
2754 {
2755 
2756 	vec3_t		move;
2757 	vec3_t		vec, point, vec2;
2758 	float		len;
2759 	vec3_t		right, up;
2760 	particle_t	*p, *pr;
2761 	int			i,j;
2762 
2763 	VectorSubtract (end, start, vec);
2764 	len = VectorNormalize (vec);
2765 	VectorCopy (vec, point);
2766 
2767 	MakeNormalVectors (vec, right, up);
2768 	VectorCopy (vec, vec2);
2769 	VectorScale (vec, LASERTRAILSPACE, vec);
2770 	VectorCopy (start, move);
2771 
2772 
2773 	//puff of blue gas
2774 	VectorScale (vec2, -LASERTRAILSPACE/2, vec2);
2775 	VectorAdd(start, vec2, start);
2776 	for(i = 0; i < 6; i++) {
2777 
2778 		if (!(p = new_particle()))
2779 			return;
2780 		p->alpha = 0.9;
2781 		p->alphavel = -1.8 / (0.6+frand()*0.2);
2782 		p->blenddst = GL_ONE;
2783 		p->blendsrc = GL_SRC_ALPHA;
2784 		p->image = r_cflashtexture;
2785 		p->scale = 8/(i+1);
2786 		for(j=0; j< 3; j++)
2787 			p->angle[j] = 0;
2788 		p->type = PARTICLE_STANDARD;
2789 		p->scalevel = 4;
2790 		p->color = 0x74;
2791 		for (j=0 ; j<3 ; j++)
2792 		{
2793 			p->org[j] = start[j];
2794 			p->vel[j] = 0;
2795 			p->accel[j] = 0;
2796 		}
2797 	}
2798 
2799 	//Dummy particle that won't get drawn -- the first particle in a chain is
2800 	//always skipped.
2801 	if (!(pr = new_particle ()))
2802 		return;
2803 	pr->alpha = 0.9;
2804 	pr->alphavel = -1.8;
2805 	pr->scale = 2;
2806 	pr->scalevel = 0;
2807 	VectorCopy (start, pr->org);
2808 	VectorClear (pr->vel);
2809 	VectorClear (pr->accel);
2810 	pr->type = PARTICLE_CHAINED;
2811 	pr->color = 0x74;
2812 	pr->image = r_beam2texture;
2813 
2814 	for (i = 0; i < 3; i++)
2815 	{
2816 		if (!(p = new_particle()))
2817 			return;
2818 
2819 		p->alpha = 0.9;
2820 		p->alphavel = -1.8;
2821 		p->blenddst = GL_ONE;
2822 		p->blendsrc = GL_SRC_ALPHA;
2823 
2824 		p->image = r_beam2texture;
2825 		p->scale = 2;
2826 		VectorCopy(move, p->angle);
2827 		p->type = PARTICLE_CHAINED;
2828 		p->scalevel = 0;
2829 
2830 		p->color = 0x74;
2831 		p->chain_prev = pr;
2832 
2833 		for (j=0 ; j<3 ; j++)
2834 		{
2835 			p->org[j] = end[j];
2836 			p->vel[j] = 0;
2837 			p->accel[j] = 0;
2838 		}
2839 	}
2840 }
2841 
2842 #define VAPORIZORTRAILSPACE 20
2843 
CL_VaporizerBeam(vec3_t start,vec3_t end)2844 void CL_VaporizerBeam (vec3_t start, vec3_t end)
2845 {
2846 	vec3_t		move;
2847 	vec3_t		vec, point, last, vec2;
2848 	float		len;
2849 	vec3_t		right, up;
2850 	particle_t	*p;
2851 	int			i,j;
2852 
2853 	VectorSubtract (end, start, vec);
2854 	len = VectorNormalize (vec);
2855 	VectorCopy (vec, point);
2856 
2857 	MakeNormalVectors (vec, right, up);
2858 	VectorCopy (vec, vec2);
2859 	VectorScale (vec, VAPORIZORTRAILSPACE, vec);
2860 	VectorCopy (start, move);
2861 
2862 	//muzzleflash
2863 	VectorScale (vec2, -VAPORIZORTRAILSPACE/2, vec2);
2864 	VectorAdd(start, vec2, start);
2865 	for(i = 0; i < 8; i++) {
2866 
2867 		if (!(p = new_particle()))
2868 			return;
2869 		p->alpha = 0.9;
2870 		p->alphavel = -.8 / (0.6+frand()*0.2);
2871 		p->blenddst = GL_ONE;
2872 		p->blendsrc = GL_SRC_ALPHA;
2873 		p->image = r_leaderfieldtexture;
2874 		p->scale = 24/(i+1);
2875 		for(j=0; j< 3; j++)
2876 			p->angle[j] = 0;
2877 		p->type = PARTICLE_STANDARD;
2878 		p->scalevel = 12;
2879 		p->color = 0x74 + (rand()&12);;
2880 		for (j=0 ; j<3 ; j++)
2881 		{
2882 			p->org[j] = start[j];
2883 			p->vel[j] = 0;
2884 			p->accel[j] = 0;
2885 		}
2886 	}
2887 
2888 	for (; len>0; len -= VAPORIZORTRAILSPACE)
2889 	{
2890 		VectorCopy (move, last);
2891 		VectorAdd (move, vec, move);
2892 
2893 		for(i = 0; i < 3; i++) {
2894 			if (!(p = new_particle()))
2895 					return;
2896 
2897 			p->alpha = 1;
2898 			p->alphavel = -.8 / (0.6+frand()*0.2);
2899 			p->blenddst = GL_ONE;
2900 			p->blendsrc = GL_SRC_ALPHA;
2901 			p->image = r_beam2texture;
2902 			p->scale = 4;
2903 			VectorCopy(move, p->angle);
2904 			p->type = PARTICLE_BEAM;
2905 			p->scalevel = 0;
2906 
2907 			p->color = 0x74 + (rand()&7);
2908 
2909 			for (j=0 ; j<3 ; j++)
2910 			{
2911 				p->org[j] = last[j];
2912 				p->vel[j] = 0;
2913 				p->accel[j] = 0;
2914 			}
2915 		}
2916 		//do lightning effects
2917 		if (!(p = new_particle()))
2918 				return;
2919 
2920 		p->alpha = 1;
2921 		p->alphavel = -.8 / (0.6+frand()*0.2);
2922 		p->blenddst = GL_ONE;
2923 		p->blendsrc = GL_SRC_ALPHA;
2924 		p->image = r_beam3texture;
2925 		p->scale = 4;
2926 		VectorCopy(move, p->angle);
2927 		p->type = PARTICLE_BEAM;
2928 		p->scalevel = 0;
2929 
2930 		p->color = 0x74;
2931 
2932 		for (j=0 ; j<3 ; j++)
2933 		{
2934 			p->org[j] = last[j];
2935 			p->vel[j] = 0;
2936 			p->accel[j] = 0;
2937 		}
2938 
2939 	}
2940 
2941 }
2942 
CL_NewLightning(vec3_t start,vec3_t end)2943 void CL_NewLightning (vec3_t start, vec3_t end)
2944 {
2945 	vec3_t		move;
2946 	vec3_t		vec;
2947 	float		len;
2948 	int			j;
2949 	particle_t	*p;
2950 	particle_t	*pr = NULL;
2951 	float		dec;
2952 	vec3_t		right, up;
2953 	int			i;
2954 	float		skewx, skewy, skewz;
2955 	float		x, y, z;
2956 	// byte		clr = 0xd4;
2957 
2958 	VectorCopy (start, move);
2959 	VectorSubtract (end, start, vec);
2960 	len = VectorNormalize (vec);
2961 
2962 	MakeNormalVectors (vec, right, up);
2963 
2964 	dec = .75;
2965 	VectorScale (vec, dec, vec);
2966 	VectorCopy (start, move);
2967 	skewx = skewy = skewz = .1;
2968 	i = 0;
2969 	x = y = z = 0;
2970 
2971 	while (len > 0)
2972 	{
2973 		len -= dec;
2974 		i++;
2975 
2976 		if (!(p = new_particle()))
2977 			return;
2978 
2979 		VectorClear (p->accel);
2980 
2981 		x++;
2982 		y++;
2983 		z++;
2984 
2985 		// somehow increment x,y,z in random direction
2986 		if (i > 10)//reset
2987 		{
2988 			i = 0;
2989 			x = y = z = 0;
2990 			if (frand() < 0.5)
2991 				skewx = skewx * -1;
2992 			if (frand() < 0.5)
2993 				skewy = skewy * -1;
2994 			if (frand() < 0.5)
2995 				skewz = skewz * -1;
2996 		}
2997 
2998 		p->org[0] = move[0] + skewx * ++x;
2999 		p->org[1] = move[1] + skewy * ++y;
3000 		p->org[2] = move[2] + skewz * ++z;
3001 
3002 		p->alpha = 1.2;
3003 		p->alphavel = -3.33;
3004 		p->type = PARTICLE_CHAINED;
3005 		p->image = r_raintexture;
3006 		p->blendsrc = GL_SRC_ALPHA;
3007 		p->blenddst = GL_ONE;
3008 		p->scale = 1 + (rand()&2);
3009 		p->scalevel = 0;
3010 		p->color = 0xff;
3011 		for (j=0 ; j<3 ; j++)
3012 		{
3013 			p->vel[j] = 0;
3014 			p->accel[j] = 0;
3015 		}
3016 		if (len < 4)
3017 			addParticleLight (p,
3018 						p->scale*75, 0,
3019 					.25, 0, .3);
3020 		VectorAdd (p->org, vec, move);
3021 		if (pr)
3022 		{
3023 			p->chain_prev = pr;
3024 		}
3025 		pr = p;
3026 	}
3027 
3028 }
3029 
CL_RedBlasterBeam(vec3_t start,vec3_t end)3030 void CL_RedBlasterBeam (vec3_t start, vec3_t end)
3031 {
3032 
3033 	vec3_t		move;
3034 	vec3_t		vec, point, last, vec2;
3035 	float		len;
3036 	vec3_t		right, up;
3037 	particle_t	*p;
3038 	int			i,j;
3039 
3040 	VectorCopy (start, move);
3041 	VectorSubtract (end, start, vec);
3042 	len = VectorNormalize (vec);
3043 	VectorCopy (vec, point);
3044 
3045 	MakeNormalVectors (vec, right, up);
3046 	VectorCopy (vec, vec2);
3047 	VectorScale (vec, LASERTRAILSPACE, vec);
3048 	VectorCopy (start, move);
3049 
3050 
3051 	//puff of blue gas
3052 	VectorScale (vec2, -LASERTRAILSPACE/2, vec2);
3053 	VectorAdd(start, vec2, start);
3054 	for(i = 0; i < 6; i++) {
3055 
3056 		if (!(p = new_particle()))
3057 			return;
3058 		p->alpha = 0.9;
3059 		p->alphavel = -1.8 / (0.6+frand()*0.2);
3060 		p->blenddst = GL_ONE;
3061 		p->blendsrc = GL_SRC_ALPHA;
3062 		p->image = r_cflashtexture;
3063 		p->scale = 8/(i+1);
3064 		for(j=0; j< 3; j++)
3065 			p->angle[j] = 0;
3066 		p->type = PARTICLE_STANDARD;
3067 		p->scalevel = 4;
3068 		p->color = 0xe8;
3069 		for (j=0 ; j<3 ; j++)
3070 		{
3071 			p->org[j] = start[j];
3072 			p->vel[j] = 0;
3073 			p->accel[j] = 0;
3074 		}
3075 	}
3076 
3077 	for (; len>0; len -= LASERTRAILSPACE)
3078 	{
3079 		VectorCopy (move, last);
3080 		VectorAdd (move, vec, move);
3081 
3082 		for(i = 0; i < 3; i++) {
3083 			if (!(p = new_particle()))
3084 					return;
3085 
3086 			p->alpha = 0.9;
3087 			p->alphavel = -1.8;
3088 			p->blenddst = GL_ONE;
3089 			p->blendsrc = GL_SRC_ALPHA;
3090 
3091 			p->image = r_beam2texture;
3092 			p->scale = 2;
3093 			VectorCopy(move, p->angle);
3094 			p->type = PARTICLE_BEAM;
3095 			p->scalevel = 0;
3096 
3097 			p->color = 0xe8;
3098 
3099 			for (j=0 ; j<3 ; j++)
3100 			{
3101 				p->org[j] = last[j];
3102 				p->vel[j] = 0;
3103 				p->accel[j] = 0;
3104 			}
3105 		}
3106 	}
3107 
3108 }
3109 /*
3110 ===============
3111 CL_BubbleTrail
3112 
3113 ===============
3114 */
CL_BubbleTrail(vec3_t start,vec3_t end)3115 void CL_BubbleTrail (vec3_t start, vec3_t end)
3116 {
3117 	vec3_t		move;
3118 	vec3_t		vec;
3119 	float		len;
3120 	int			i, j;
3121 	particle_t	*p;
3122 	float		dec;
3123 
3124 	VectorCopy (start, move);
3125 	VectorSubtract (end, start, vec);
3126 	len = VectorNormalize (vec);
3127 
3128 	dec = 32;
3129 	VectorScale (vec, dec, vec);
3130 
3131 	for (i=0 ; i<len ; i+=dec)
3132 	{
3133 		if (!(p = new_particle()))
3134 			return;
3135 
3136 		VectorClear (p->accel);
3137 
3138 		p->alpha = 1.0;
3139 		p->alphavel = -1.0 / (1+frand()*0.2);
3140 		p->color = 4 + (rand()&7);
3141 		p->type = PARTICLE_STANDARD;
3142 		p->image = r_bubbletexture;
3143 		p->scale = 2 + (rand()&2);
3144 		p->blendsrc = GL_SRC_ALPHA;
3145 		p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
3146 
3147 		for (j=0 ; j<3 ; j++)
3148 		{
3149 			p->org[j] = move[j] + crand()*2;
3150 			p->vel[j] = crand()*5;
3151 		}
3152 		p->vel[2] += 6;
3153 
3154 		VectorAdd (move, vec, move);
3155 	}
3156 }
3157 
3158 /*
3159 ===============
3160 CL_BFGExplosionParticles
3161 ===============
3162 */
3163 
CL_BFGExplosionParticles(vec3_t org)3164 void CL_BFGExplosionParticles (vec3_t org)
3165 {
3166 	int			i, j;
3167 	particle_t	*p;
3168 
3169 	//for glsl framebuffer distortion effects
3170 	if(!r_drawing_fbeffect && cl_explosiondist->value) {
3171 		r_fbFxType = 1; //EXPLOSION
3172 		r_drawing_fbeffect = true;
3173 		VectorCopy(org, r_explosionOrigin);
3174 		r_fbeffectTime = rs_realtime;
3175 	}
3176 
3177 	for (i=0 ; i<32 ; i++)
3178 	{
3179 		if (!(p = new_particle()))
3180 			return;
3181 
3182 		for (j=0 ; j<3 ; j++)
3183 		{
3184 			p->org[j] = org[j] + ((rand()%62)-32);
3185 			p->vel[j] = (rand()%32)-16;
3186 		}
3187 
3188 		p->accel[0] = p->accel[1] = 5+(rand()&7);
3189 		p->accel[2] = 5+(rand()&7);
3190 		p->scale = (24 + (rand()&2));
3191 		p->scalevel = 24;
3192 		p->type = PARTICLE_STANDARD;
3193 		p->image = r_explosiontexture;
3194 		p->blendsrc = GL_SRC_ALPHA;
3195 		p->blenddst = GL_ONE;
3196 		p->color = 0x74 + (rand()&7);
3197 		p->alpha = 0.4;
3198 
3199 		p->alphavel = -0.8 / (2.5 + frand()*0.3);
3200 		if (i > 28)
3201 			addParticleLight (p,
3202 						p->scale*(15+(rand()&5)), 10,
3203 					0, 0.6, 0.5);
3204 	}
3205 
3206 	//place a big shock wave effect
3207 	if (!(p = new_particle()))
3208 			return;
3209 	p->alpha = 1.0;
3210 	p->alphavel = -1.0;
3211 	p->type = PARTICLE_FLAT;
3212 	p->image = r_hittexture;
3213 	p->blendsrc = GL_SRC_ALPHA;
3214 	p->blenddst = GL_ONE;
3215 	p->color = 0x74 + (rand()&7);
3216 	p->scale = 24 + (rand()&4) ;
3217 	p->scalevel = 100;
3218 	for(j = 0; j < 3; j++) {
3219 		p->org[j] = org[j];
3220 		p->vel[j] = 0;
3221 		p->accel[j] = 0;
3222 	}
3223 }
3224 
3225 /*
3226 ===============
3227 CL_TeleportParticles
3228 
3229 ===============
3230 */
CL_TeleportParticles(vec3_t orig_start)3231 void CL_TeleportParticles (vec3_t orig_start)
3232 {
3233 	vec3_t		move;
3234 	vec3_t		vec;
3235 	vec3_t		start;
3236 	vec3_t		end;
3237 	float		len;
3238 	int			j;
3239 	particle_t	*p;
3240 	int			i;
3241 	vec3_t		pos1, pos2, v;
3242 	float		step = 16.0;
3243 	// static vec3_t mins = { -1, -1, -1 };
3244     // static vec3_t maxs = { 1, 1, 1 };
3245 
3246 	//make a copy to prevent modifying an important vector
3247 	VectorCopy(orig_start, start);
3248 	VectorCopy(start, pos1);
3249 	pos2[2] = 1;
3250 	pos2[0] = pos2[1] = 0;
3251 	pos1[2] -= 32;
3252 
3253 	if(!(p = new_particle()))
3254 		return;
3255 
3256 	p->image = r_logotexture;
3257 	p->color = 0x74 + (rand()&7);
3258 	p->type = PARTICLE_DECAL;
3259 	p->blendsrc = GL_SRC_ALPHA;
3260 	p->blenddst = GL_ONE;
3261 	p->scale = 4;
3262 	p->scalevel = 0;
3263 
3264 	VectorScale(pos2, -1, v);
3265 	RotateForNormal(v, p->angle);
3266 	p->angle[ROLL] = rand() % 360;
3267 	VectorCopy( pos1, p->org);
3268 
3269 	p->alpha = 0.7;
3270 	p->alphavel = -0.15;
3271 	for (j=0 ; j<3 ; j++)
3272 	{
3273 		p->accel[j] = 0;
3274 		p->vel[j] = 0;
3275 	}
3276 
3277 	//place a big shock wave effect
3278 	if (!(p = new_particle()))
3279 			return;
3280 
3281 	p->alpha = 1.0;
3282 	p->alphavel = -.250;
3283 	p->type = PARTICLE_DECAL;
3284 	p->image = r_explosion5texture;
3285 	p->blendsrc = GL_SRC_ALPHA;
3286 	p->blenddst = GL_ONE;
3287 	p->color = 0x74 + (rand()&7);
3288 	p->scale = 1 + (rand()&4) ;
3289 	p->scalevel = 4;
3290 	VectorScale(pos2, -1, v);
3291 	RotateForNormal(v, p->angle);
3292 	p->angle[ROLL] = rand() % 360;
3293 	VectorCopy( pos1, p->org);
3294 	for(j = 0; j < 3; j++) {
3295 		p->vel[j] = 0;
3296 		p->accel[j] = 0;
3297 	}
3298 
3299 	VectorCopy (start, move);
3300 	VectorCopy (start, end);
3301 	end[2] += 32;
3302 	start[2] -= 48;
3303 	VectorSubtract (end, start, vec);
3304 	len = VectorNormalize (vec);
3305 
3306 	for (i=0 ; i<len ; i+=step)
3307 	{
3308 
3309 		if (!(p = new_particle()))
3310 			return;
3311 
3312 		VectorClear (p->accel);
3313 
3314 
3315 		p->alpha = 1.0;
3316 		p->alphavel = -2.5 / (2+frand()*0.2);
3317 		p->type = PARTICLE_FLAT;
3318 		p->image = r_hittexture;
3319 		p->blendsrc = GL_ONE;
3320 		p->blenddst = GL_ONE;
3321 		p->color = 0x74 + (rand()&7);
3322 		p->scale = 24 + (rand()&4) ;
3323 		p->scalevel = 0;
3324 		for(j = 0; j < 3; j++) {
3325 			p->org[j] = start[j];
3326 			p->vel[j] = 0;
3327 		}
3328 		p->vel[2] = PARTICLE_GRAVITY*2;
3329 		if (i < 1)
3330 		addParticleLight (p,
3331 					p->scale, 10,
3332 				0, 1, 1);
3333 
3334 		start[2] += 16;
3335 	}
3336 }
3337 
3338 #define WEATHER_PARTICLES 2048
3339 static int weather_particles;
3340 extern unsigned r_weather;
3341 
3342 /*
3343 Cl_WeatherEffects - originally adopted from Jay Dolan's Q2W
3344 */
Cl_WeatherEffects()3345 void Cl_WeatherEffects()
3346 {
3347 	int i, j, k;
3348 	vec3_t start, end;
3349 	trace_t tr;
3350 	float ceiling;
3351 	particle_t *p;
3352 
3353 	if(!r_weather)
3354 		return;
3355 
3356 	i = weather_particles;  // we count up from current particles
3357 	p = NULL;  // so that we add the right amount
3358 
3359 	k = 0;
3360 
3361 	if(r_weather == 5)
3362 	{
3363 		while(i++ < WEATHER_PARTICLES && k++ < 1)
3364 		{
3365 			VectorCopy(cl.refdef.vieworg, start);
3366 			start[0] = start[0] + (rand() % 5096) - 2048;
3367 			start[1] = start[1] + (rand() % 5096) - 2048;
3368 
3369 			VectorCopy(start, end);
3370 			end[2] += 8192;
3371 
3372 			// trace up looking for sky
3373 			tr = CM_BoxTrace(start, end, vec3_origin, vec3_origin, 0, MASK_SHOT);
3374 
3375 			if(!(tr.surface->flags & SURF_SKY))
3376 				continue;
3377 
3378 			// drop down somewhere between sky and player
3379 			ceiling = tr.endpos[2] > start[2] + 1024 ? start[2] + 1024 : tr.endpos[2];
3380 			tr.endpos[2] = tr.endpos[2] - ((ceiling - start[2]) * frand());
3381 
3382 			if (!(p = new_particle()))
3383 				return;
3384 
3385 			VectorCopy(tr.endpos, p->org);
3386 			p->org[2] -= 1;
3387 
3388 			VectorCopy(start, end);
3389 			end[2] -= 8192;
3390 
3391 			tr = CM_BoxTrace(p->org, end, vec3_origin, vec3_origin, 0, MASK_ALL);
3392 
3393 			if(!tr.surface)  // this shouldn't happen
3394 				VectorCopy(start, p->end);
3395 			else
3396 				VectorCopy(tr.endpos, p->end);
3397 
3398 			p->type = PARTICLE_FLUTTERWEATHER;
3399 			// setup the particles
3400 			//trash
3401 			p->image = r_trashtexture;
3402 			p->vel[2] = -80;
3403 			p->accel[2] = 0;
3404 			p->alpha = 0.9;
3405 			p->alphavel = 0;
3406 			p->color = 8;
3407 			p->scale = 12;
3408 			p->scalevel = 0;
3409 			p->blendsrc = GL_SRC_ALPHA;
3410 			p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
3411 
3412 			for(j = 0; j < 2; j++)
3413 			{
3414 				p->vel[j] = crand() * 40;
3415 				p->accel[j] = crand() * 50;
3416 			}
3417 			weather_particles++;
3418 		}
3419 	}
3420 	else if(r_weather == 3 || r_weather == 4)
3421 	{
3422 		while(i++ < WEATHER_PARTICLES && k++ < 2)
3423 		{
3424 			VectorCopy(cl.refdef.vieworg, start);
3425 			start[0] = start[0] + (rand() % 2048) - 1024;
3426 			start[1] = start[1] + (rand() % 2048) - 1024;
3427 
3428 			VectorCopy(start, end);
3429 			end[2] += 8192;
3430 
3431 			// trace up looking for sky
3432 			tr = CM_BoxTrace(start, end, vec3_origin, vec3_origin, 0, MASK_SHOT);
3433 
3434 			if(!(tr.surface->flags & SURF_SKY))
3435 				continue;
3436 
3437 			// drop down somewhere between sky and player
3438 			ceiling = tr.endpos[2] > start[2] + 1024 ? start[2] + 1024 : tr.endpos[2];
3439 			tr.endpos[2] = tr.endpos[2] - ((ceiling - start[2]) * frand());
3440 
3441 			if (!(p = new_particle()))
3442 				return;
3443 
3444 			VectorCopy(tr.endpos, p->org);
3445 			p->org[2] -= 1;
3446 
3447 			VectorCopy(start, end);
3448 			end[2] -= 8192;
3449 
3450 			tr = CM_BoxTrace(p->org, end, vec3_origin, vec3_origin, 0, MASK_ALL);
3451 
3452 			if(!tr.surface)  // this shouldn't happen
3453 				VectorCopy(start, p->end);
3454 			else
3455 				VectorCopy(tr.endpos, p->end);
3456 
3457 			// setup the particles
3458 			if(r_weather == 3) //leaves
3459 			{
3460 				p->type = PARTICLE_FLUTTERWEATHER;
3461 				p->image = r_leaftexture;
3462 				p->vel[2] = -80;
3463 				p->accel[2] = 0;
3464 				p->alpha = 0.9;
3465 				p->alphavel = 0;
3466 				p->color = 8;
3467 				p->scale = 2;
3468 				p->scalevel = 0;
3469 				p->blendsrc = GL_SRC_ALPHA;
3470 				p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
3471 			}
3472 			else if(r_weather == 4) //embers
3473 			{
3474 				p->type = PARTICLE_WEATHER;
3475 				p->image = r_particletexture;
3476 				p->vel[2] = -80;
3477 				p->accel[2] = 0;
3478 				p->alpha = 0.9;
3479 				p->alphavel = frand() * -1;
3480 				p->color = 0xe8;
3481 				p->scale = 2;
3482 				p->scalevel = 0;
3483 				p->blendsrc = GL_SRC_ALPHA;
3484 				p->blenddst = GL_ONE;
3485 			}
3486 			for(j = 0; j < 2; j++)
3487 			{
3488 				p->vel[j] = crand() * 25;
3489 				p->accel[j] = crand() * 50;
3490 			}
3491 			weather_particles++;
3492 		}
3493 	}
3494 	else
3495 	{
3496 		while(i++ < WEATHER_PARTICLES && k++ < 25)
3497 		{
3498 			VectorCopy(cl.refdef.vieworg, start);
3499 			start[0] = start[0] + (rand() % 2048) - 1024;
3500 			start[1] = start[1] + (rand() % 2048) - 1024;
3501 
3502 			VectorCopy(start, end);
3503 			end[2] += 8192;
3504 
3505 			// trace up looking for sky
3506 			tr = CM_BoxTrace(start, end, vec3_origin, vec3_origin, 0, MASK_SHOT);
3507 
3508 			if(!(tr.surface->flags & SURF_SKY))
3509 				continue;
3510 
3511 			// drop down somewhere between sky and player
3512 			ceiling = tr.endpos[2] > start[2] + 1024 ? start[2] + 1024 : tr.endpos[2];
3513 			tr.endpos[2] = tr.endpos[2] - ((ceiling - start[2]) * frand());
3514 
3515 			if (!(p = new_particle()))
3516 				return;
3517 
3518 			VectorCopy(tr.endpos, p->org);
3519 			p->org[2] -= 1;
3520 
3521 			VectorCopy(start, end);
3522 			end[2] -= 8192;
3523 
3524 			tr = CM_BoxTrace(p->org, end, vec3_origin, vec3_origin, 0, MASK_ALL);
3525 
3526 			if(!tr.surface)  // this shouldn't happen
3527 				VectorCopy(start, p->end);
3528 			else
3529 				VectorCopy(tr.endpos, p->end);
3530 
3531 			p->type = PARTICLE_WEATHER;
3532 			// setup the particles
3533 			if(r_weather == 1) //rain
3534 			{
3535 				p->image = r_raintexture;
3536 				p->vel[2] = -800;
3537 				p->accel[2] = 0;
3538 				p->alpha = 0.3;
3539 				p->alphavel = frand() * -1;
3540 				p->color = 8;
3541 				p->scale = 6;
3542 				p->scalevel = 0;
3543 			}
3544 			else if(r_weather == 2) //snow
3545 			{
3546 				p->image = r_particletexture;
3547 				p->vel[2] = -120;
3548 				p->accel[2] = 0;
3549 				p->alpha = 0.8;
3550 				p->alphavel = frand() * -1;
3551 				p->color = 8;
3552 				p->scale = 1;
3553 				p->scalevel = 0;
3554 			}
3555 			p->blendsrc = GL_SRC_ALPHA;
3556 			p->blenddst = GL_ONE;
3557 
3558 			for(j = 0; j < 2; j++)
3559 			{
3560 				p->vel[j] = crand() * 2;
3561 				p->accel[j] = crand() * 2;
3562 			}
3563 			weather_particles++;
3564 		}
3565 	}
3566 }
3567 
3568 /*
3569 Powered up effects
3570 */
3571 
3572 #define	BEAMLENGTH			16
CL_PoweredEffects(vec3_t origin)3573 void CL_PoweredEffects (vec3_t origin)
3574 {
3575 	int			i;
3576 	particle_t	*p;
3577 	float		angle;
3578 	float		sr, sp, sy, cr, cp, cy;
3579 	vec3_t		forward;
3580 	float		dist = 64;
3581 	float		ltime;
3582 
3583 	if (!avelocities[0][0])
3584 	{
3585 		for (i=0 ; i<NUMVERTEXNORMALS*3 ; i++)
3586 			avelocities[0][i] = (rand()&255) * 0.01;
3587 	}
3588 
3589 	ltime = (float)cl.time / 1000.0;
3590 	for (i=0 ; i<32 ; i+=2)
3591 	{
3592 		angle = ltime * avelocities[i][0];
3593 		sy = sin(angle);
3594 		cy = cos(angle);
3595 		angle = ltime * avelocities[i][1];
3596 		sp = sin(angle);
3597 		cp = cos(angle);
3598 		angle = ltime * avelocities[i][2];
3599 		sr = sin(angle);
3600 		cr = cos(angle);
3601 
3602 		forward[0] = cp*cy;
3603 		forward[1] = cp*sy;
3604 		forward[2] = -sp;
3605 
3606 		if (!(p = new_particle()))
3607 			return;
3608 
3609 		dist = sin(ltime + i)*32;
3610 		p->org[0] = origin[0] + bytedirs[i][0]*dist + forward[0]*BEAMLENGTH;
3611 		p->org[1] = origin[1] + bytedirs[i][1]*dist + forward[1]*BEAMLENGTH;
3612 		p->org[2] = origin[2] + bytedirs[i][2]*dist + forward[2]*BEAMLENGTH;
3613 
3614 		VectorClear (p->vel);
3615 		VectorClear (p->accel);
3616 
3617 		p->type = PARTICLE_STANDARD;
3618 		p->image = r_logotexture;
3619 		p->blendsrc = GL_ONE;
3620 		p->blenddst = GL_ONE;
3621 		p->scale = 2;
3622 		p->scalevel = 2;
3623 		p->color = 0xd4;
3624 
3625 		p->alpha = .7;
3626 		p->alphavel = -50 / (0.5 + frand()*0.3);
3627 	}
3628 }
3629 
3630 /*
3631 ======
3632 vectoangles2 - this is duplicated in the game DLL, but I need it here.
3633 ======
3634 */
vectoangles2(vec3_t value1,vec3_t angles)3635 void vectoangles2 (vec3_t value1, vec3_t angles)
3636 {
3637 	float	forward;
3638 	float	yaw, pitch;
3639 
3640 	if (value1[1] == 0 && value1[0] == 0)
3641 	{
3642 		yaw = 0;
3643 		if (value1[2] > 0)
3644 			pitch = 90;
3645 		else
3646 			pitch = 270;
3647 	}
3648 	else
3649 	{
3650 	// PMM - fixed to correct for pitch of 0
3651 		if (value1[0])
3652 			yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
3653 		else if (value1[1] > 0)
3654 			yaw = 90;
3655 		else
3656 			yaw = 270;
3657 
3658 		if (yaw < 0)
3659 			yaw += 360;
3660 
3661 		forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]);
3662 		pitch = (atan2(value1[2], forward) * 180 / M_PI);
3663 		if (pitch < 0)
3664 			pitch += 360;
3665 	}
3666 
3667 	angles[PITCH] = -pitch;
3668 	angles[YAW] = yaw;
3669 	angles[ROLL] = 0;
3670 }
3671 
3672 /*
3673 ===============
3674 CL_SmokeTrail
3675 ===============
3676 */
CL_SmokeTrail(vec3_t start,vec3_t end,int colorStart,int colorRun,int spacing)3677 void CL_SmokeTrail (vec3_t start, vec3_t end, int colorStart, int colorRun, int spacing)
3678 {
3679 	vec3_t		move;
3680 	vec3_t		vec;
3681 	float		len;
3682 	int			j;
3683 	particle_t	*p;
3684 
3685 	VectorCopy (start, move);
3686 	VectorSubtract (end, start, vec);
3687 	len = VectorNormalize (vec);
3688 
3689 	VectorScale (vec, spacing, vec);
3690 
3691 	// FIXME: this is a really silly way to have a loop
3692 	while (len > 0)
3693 	{
3694 		len -= spacing;
3695 
3696 		if (!(p = new_particle()))
3697 			return;
3698 		VectorClear (p->accel);
3699 
3700 		p->alpha = 1.0;
3701 		p->alphavel = -1.0 / (1+frand()*0.5);
3702 		p->color = colorStart + (rand() % colorRun);
3703 		for (j=0 ; j<3 ; j++)
3704 		{
3705 			p->org[j] = move[j] + crand()*3;
3706 			p->accel[j] = 0;
3707 		}
3708 		p->vel[2] = 20 + crand()*5;
3709 
3710 		VectorAdd (move, vec, move);
3711 	}
3712 }
3713 
3714 /*
3715 ===============
3716 CL_ParticleSteamEffect
3717 
3718 Puffs with velocity along direction, with some randomness thrown in
3719 ===============
3720 */
3721 
CL_ParticleSteamEffect(cl_sustain_t * self)3722 void CL_ParticleSteamEffect (cl_sustain_t *self)
3723 {
3724 	int			i, j;
3725 	particle_t	*p;
3726 	float		d;
3727 	vec3_t		r, u;
3728 	vec3_t		dir;
3729 
3730 	VectorCopy (self->dir, dir);
3731 	MakeNormalVectors (dir, r, u);
3732 
3733 	for (i=0 ; i<2 ; i++)
3734 	{
3735 		if (!(p = new_particle()))
3736 			return;
3737 
3738 		p->type = PARTICLE_STANDARD;
3739 		p->image = r_pufftexture;
3740 		p->blendsrc = GL_SRC_ALPHA;
3741 		p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
3742 		p->scale = 4 + (rand()&2);
3743 		p->scalevel = 10;
3744 		p->color = self->color;
3745 
3746 		for (j=0 ; j<3 ; j++)
3747 		{
3748 			p->org[j] = self->org[j] + self->magnitude*0.1*crand();
3749 		}
3750 		VectorScale (dir, self->magnitude, p->vel);
3751 		d = crand()*self->magnitude/3;
3752 		VectorMA (p->vel, d, r, p->vel);
3753 		d = crand()*self->magnitude/3;
3754 		VectorMA (p->vel, d, u, p->vel);
3755 
3756 		p->accel[0] = p->accel[1] = 0;
3757 		p->accel[2] = -PARTICLE_GRAVITY/2;
3758 		p->alpha = 0.1;
3759 
3760 		p->alphavel = -1.0 / (6.5 + frand()*0.3);
3761 
3762 		p->fromsustainedeffect = true;
3763 	}
3764 	self->nextthink += self->thinkinterval;
3765 }
CL_ParticleFireEffect2(cl_sustain_t * self)3766 void CL_ParticleFireEffect2 (cl_sustain_t *self)
3767 {
3768 	int			i, j;
3769 	particle_t	*p;
3770 	float		d;
3771 	vec3_t		r, u;
3772 	vec3_t		dir;
3773 
3774 	VectorCopy (self->dir, dir);
3775 	MakeNormalVectors (dir, r, u);
3776 
3777 	for (i=0 ; i<1 ; i++)
3778 	{
3779 		if (!(p = new_particle()))
3780 			return;
3781 
3782 		p->type = PARTICLE_STANDARD;
3783 		p->image = r_explosiontexture;
3784 		p->blendsrc = GL_SRC_ALPHA;
3785 		p->blenddst = GL_ONE;
3786 		p->color = 0xe0;
3787 		p->scale = 24 + (rand()&7);
3788 		p->scalevel = 4;
3789 		for (j=0 ; j<3 ; j++)
3790 		{
3791 			p->org[j] = self->org[j] + self->magnitude*0.1*crand();
3792 
3793 		}
3794 		p->vel[2] = 100;
3795 		VectorScale (dir, self->magnitude, p->vel);
3796 		d = crand()*self->magnitude/3;
3797 		VectorMA (p->vel, d, r, p->vel);
3798 		d = crand()*self->magnitude/3;
3799 		VectorMA (p->vel, d, u, p->vel);
3800 
3801 		p->accel[0] = p->accel[1] = 0;
3802 		p->accel[2] = -PARTICLE_GRAVITY/3;
3803 		p->alpha = 0.03;
3804 
3805 		p->alphavel = -.015 / (0.8 + frand()*0.3);
3806 
3807 		p->fromsustainedeffect = true;
3808 	}
3809 	self->nextthink += self->thinkinterval;
3810 }
CL_ParticleSmokeEffect2(cl_sustain_t * self)3811 void CL_ParticleSmokeEffect2 (cl_sustain_t *self)
3812 {
3813 	int			i, j;
3814 	particle_t	*p;
3815 	float		d;
3816 	vec3_t		r, u;
3817 	vec3_t		dir;
3818 
3819 	VectorCopy (self->dir, dir);
3820 	MakeNormalVectors (dir, r, u);
3821 
3822 	for (i=0 ; i<self->count ; i++)
3823 	{
3824 		if (!(p = new_particle()))
3825 			return;
3826 
3827 		p->type = PARTICLE_STANDARD;
3828 		p->image = r_smoketexture;
3829 		p->blendsrc = GL_SRC_ALPHA;
3830 		p->blenddst = GL_ONE_MINUS_SRC_ALPHA;
3831 		p->scale = 6 + (rand()&7);
3832 		p->color = 14;
3833 		p->scalevel = 4.5;
3834 		for (j=0 ; j<3 ; j++)
3835 		{
3836 			p->org[j] = self->org[j] + self->magnitude*0.1*crand();
3837 		}
3838 		p->vel[2] = 10;
3839 		VectorScale (dir, self->magnitude, p->vel);
3840 		d = crand()*self->magnitude/3;
3841 		VectorMA (p->vel, d, r, p->vel);
3842 		d = crand()*self->magnitude/3;
3843 		VectorMA (p->vel, d, u, p->vel);
3844 
3845 		p->accel[0] = p->accel[1] = 0;
3846 		p->accel[2] = -PARTICLE_GRAVITY/3;
3847 		p->alpha = 0.03;
3848 
3849 		p->alphavel = -.015 / (7.8 + frand()*0.3);
3850 
3851 		p->fromsustainedeffect = true;
3852 	}
3853 	self->nextthink += self->thinkinterval;
3854 }
3855 
3856 /*
3857 ===============
3858 CL_AddParticles
3859 ===============
3860 */
CL_AddParticles(void)3861 void CL_AddParticles (void)
3862 {
3863 	particle_t		*p, *next;
3864 	float			light;
3865 	float			time = 0.0f;
3866 	particle_t		*active, *tail;
3867 	int				i;
3868 
3869 	Cl_WeatherEffects();
3870 
3871 	active = NULL;
3872 	tail = NULL;
3873 
3874 	for (p=active_particles ; p ; p=next)
3875 	{
3876 		next = p->next;
3877 
3878 		// PMM - added INSTANT_PARTICLE handling for heat beam
3879 		if (p->alphavel != INSTANT_PARTICLE)
3880 		{
3881 			time = (cl.time - p->time)*0.001;
3882 			p->current_alpha = p->alpha + time*p->alphavel;
3883 			if (p->current_alpha <= 0)
3884 			{	// faded out
3885 				if(p->type == PARTICLE_WEATHER || p->type == PARTICLE_FLUTTERWEATHER)
3886 					weather_particles--;
3887 				p->next = free_particles;
3888 				free_particles = p;
3889 				continue;
3890 			}
3891 		}
3892 		else
3893 		{
3894 			p->current_alpha = p->alpha;
3895 			p->alpha = p->alphavel = 0.0;
3896 		}
3897 		if(p->scalevel > 1) {
3898 			time = (cl.time - p->time)*0.001;
3899 			p->current_scale = p->scale + time * p->scalevel;
3900 		}
3901 		else
3902 			p->current_scale = p->scale;
3903 
3904         if (p->colorvel != 0) {
3905             time = (cl.time - p->time)*0.001;
3906             p->current_color = (p->color + time * p->colorvel);
3907         } else
3908             p->current_color = p->color;
3909 
3910 		if(p->current_scale > 64)
3911 			p->current_scale = 64; //don't want them getting too large.
3912 		if(p->current_scale < 0)
3913 		    p->current_scale = 0;
3914 
3915 		if(p->current_color < 0)
3916 		    p->current_color = 0;
3917 
3918 		// update origin
3919 		for(i = 0; i < 3; i++) {
3920 			p->current_origin[i] = p->org[i] + p->vel[i]*time + p->accel[i]*(time*time);
3921 		}
3922 
3923 		// free up weather particles that have hit the ground
3924 		if(p->type == PARTICLE_WEATHER || p->type == PARTICLE_FLUTTERWEATHER)
3925 		{
3926 			if (p->current_origin[2] <= p->end[2]){
3927 				p->next = free_particles;
3928 				free_particles = p;
3929 				weather_particles--;
3930 				continue;
3931 			}
3932 		}
3933 
3934 		// some weather particles flutter around as they fall
3935 		if (p->type == PARTICLE_FLUTTERWEATHER)
3936 		{
3937 			// An accurate-looking model of particle rotation is to model the
3938 			// particle as a sphere rotating on a surface (or a circle on each
3939 			// axis.) If the particle was a marble moving on some hypothetical
3940 			// 3D tabletop, how many degrees in each direction has it rotated
3941 			// since it was spawned?
3942 			float circumference;
3943 			vec3_t distance;
3944 
3945 			// Use a slightly larger radius so it rotates slower.
3946 			circumference = 2.0*M_PI*(3.5*p->current_scale);
3947 
3948 			VectorSubtract (p->current_origin, p->org, distance);
3949 			VectorScale (distance, 360.0/circumference, p->angle);
3950 		}
3951 
3952 		p->next = NULL;
3953 		if (!tail)
3954 			active = tail = p;
3955 		else
3956 		{
3957 			tail->next = p;
3958 			tail = p;
3959 		}
3960 
3961 		if (p->current_alpha > 1.0)
3962 			p->current_alpha = 1;
3963 
3964 		for (i=0;i<P_LIGHTS_MAX;i++)
3965 		{
3966 			const cplight_t *plight = &p->lights[i];
3967 			if (plight->isactive && !p->fromsustainedeffect)
3968 			{
3969 				light = plight->light*p->current_alpha*2.0 + plight->lightvel*time;
3970 				V_AddLight (p->current_origin, light, plight->lightcol[0], plight->lightcol[1], plight->lightcol[2]);
3971 			}
3972 		}
3973 
3974 		// hack a scale up to keep particles from disapearing
3975         p->dist = ( p->current_origin[0] - r_origin[0] ) * vpn[0] +
3976                 ( p->current_origin[1] - r_origin[1] ) * vpn[1] +
3977                 ( p->current_origin[2] - r_origin[2] ) * vpn[2];
3978 
3979         if (p->type != PARTICLE_CHAINED && p->dist < 0)
3980             continue;
3981         else if (p->dist >= 40)
3982             p->dist = 2 + p->dist * 0.004;
3983         else
3984             p->dist = 2;
3985 
3986         if ((p->type == PARTICLE_CHAINED && true) != (p->chain_prev && true))
3987         	continue;
3988 
3989         if (p->type == PARTICLE_CHAINED && p->chain_prev) {
3990         	vec3_t span, delta;
3991         	VectorSubtract (p->current_origin, p->chain_prev->current_origin, span);
3992         	VectorSubtract (r_origin, p->current_origin, delta);
3993         	CrossProduct (span, delta, p->current_pspan);
3994         	VectorNormalize (p->current_pspan);
3995         	VectorScale (p->current_pspan, p->dist*p->current_scale, p->current_pspan);
3996         }
3997 
3998 		V_AddParticle (p);
3999 	}
4000 
4001 	active_particles = active;
4002 }
4003 
4004 
4005 /*
4006 ==============
4007 CL_EntityEvent
4008 
4009 An entity has just been parsed that has an event value
4010 
4011 the female events are there for backwards compatability
4012 ==============
4013 */
4014 extern struct sfx_s	*cl_sfx_footsteps[4];
4015 extern struct sfx_s *cl_sfx_metal_footsteps[4];
4016 
4017 //Knightmare- modified by Irritant
4018 /*
4019 ===============
4020 CL_Footsteps
4021 Plays appropriate footstep sound depending on surface flags of the ground surface.
4022 Since this is a replacement for plain Jane EV_FOOTSTEP, we already know
4023 the player is definitely on the ground when this is called.
4024 ===============
4025 */
4026 
CL_FootSteps(entity_state_t * ent,qboolean loud)4027 void CL_FootSteps (entity_state_t *ent, qboolean loud)
4028 {
4029    trace_t   tr;
4030    vec3_t   end;
4031    int      r;
4032    int      surface;
4033    struct sfx_s   *stepsound;
4034    float volume = 0.5;
4035 
4036    r = (rand()&3);
4037 
4038    VectorCopy(ent->origin,end);
4039    end[2] -= 64;
4040    tr = CL_PMSurfaceTrace (ent->origin,NULL,NULL,end,MASK_SOLID | MASK_WATER);
4041    if (!tr.surface)
4042       return;
4043    surface = tr.surface->flags;
4044    switch (surface)
4045    {
4046 	  case SURF_TRANS66:
4047       case SURF_TRANS33|SURF_TRANS66: //all metal grates in AA have these flags set
4048          stepsound = cl_sfx_metal_footsteps[r];
4049 	     break;
4050       default:
4051          stepsound = cl_sfx_footsteps[r];
4052          break;
4053    }
4054 
4055    volume = 1.0;
4056    S_StartSound (NULL, ent->number, CHAN_BODY, stepsound, volume, ATTN_NORM, 0);
4057 }
4058 
CL_WaterWade(entity_state_t * ent)4059 void CL_WaterWade (entity_state_t *ent)
4060 {
4061 	particle_t	*p;
4062 	trace_t   tr;
4063     vec3_t   end, angle;
4064 	int		j;
4065 
4066 	S_StartSound (NULL, ent->number, CHAN_BODY, S_RegisterSound("player/wade1.wav"), 1, ATTN_NORM, 0);
4067 
4068 	VectorCopy(ent->origin,end);
4069     end[2] -= 64;
4070     tr = CL_PMSurfaceTrace (ent->origin,NULL,NULL,end,MASK_SOLID | MASK_WATER);
4071     if (!tr.surface)
4072        return;
4073 
4074 	//draw rings that expand outward
4075 	if(!(p = new_particle()))
4076 		return;
4077 	p->type = PARTICLE_RAISEDDECAL;
4078 	p->image = r_splashtexture;
4079 	p->blendsrc = GL_DST_COLOR;
4080 	p->blenddst = GL_SRC_COLOR;
4081 	p->scale = 1;
4082 	p->scalevel = 8;
4083 	p->color = 0 + (rand() & 1);
4084 
4085 	VectorScale(tr.plane.normal, -1, angle);
4086 	RotateForNormal(angle, p->angle);
4087 	p->angle[ROLL] = rand() % 360;
4088 	VectorAdd(tr.endpos, tr.plane.normal, p->org);
4089 
4090 	for (j=0 ; j<3 ; j++)
4091 	{
4092 		p->org[j] = tr.endpos[j];
4093 		p->vel[j] = 0;
4094 	}
4095 	p->accel[0] = p->accel[1] = p->accel[2] = 0;
4096 	p->alpha = .1;
4097 
4098 	p->alphavel = -0.1 / (1 + frand()*0.3);
4099 }
4100 
CL_EntityEvent(entity_state_t * ent)4101 void CL_EntityEvent (entity_state_t *ent)
4102 {
4103 	switch (ent->event)
4104 	{
4105 	case EV_ITEM_RESPAWN:
4106 		S_StartSound (NULL, ent->number, CHAN_WEAPON, S_RegisterSound("items/respawn1.wav"), 1, ATTN_IDLE, 0);
4107 		CL_ItemRespawnParticles (ent->origin);
4108 		break;
4109 	case EV_PLAYER_TELEPORT:
4110 		S_StartSound (NULL, ent->number, CHAN_WEAPON, S_RegisterSound("misc/tele1.wav"), 1, ATTN_IDLE, 0);
4111 		CL_TeleportParticles (ent->origin);
4112 		break;
4113 	case EV_FOOTSTEP:
4114 		if (cl_footsteps->value)
4115 			CL_FootSteps (ent, false);
4116 		break;
4117 	case EV_WADE:
4118 		if (cl_footsteps->value)
4119 			CL_WaterWade ( ent );
4120 		break;
4121 	case EV_FALLSHORT:
4122 		S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("player/land1.wav"), 1, ATTN_NORM, 0);
4123 		break;
4124 	case EV_FALL:
4125 		S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("*fall2.wav"), 1, ATTN_NORM, 0);
4126 		break;
4127 	case EV_FALLFAR:
4128 		S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("*fall1.wav"), 1, ATTN_NORM, 0);
4129 		break;
4130 	}
4131 }
4132 
4133 
4134 /*
4135 ==============
4136 CL_ClearEffects
4137 
4138 ==============
4139 */
CL_ClearEffects(void)4140 void CL_ClearEffects (void)
4141 {
4142 	CL_ClearParticles ();
4143 	CL_ClearDlights ();
4144 	CL_ClearLightStyles ();
4145 	CL_ClearClEntities();
4146 }
4147