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 #include "client.h"
23 
24 void CL_LogoutEffect (vec3_t org, int type);
25 void CL_ItemRespawnParticles (vec3_t org);
26 
27 #ifdef QMAX
28 void addParticleLight (cparticle_t *p,
29 		       float light, float lightvel,
30 		       float lcol0, float lcol1, float lcol2);
31 void CL_ParticleBulletDecal (vec3_t org, vec3_t dir, float size);
32 void CL_ItemRespawnParticles (vec3_t org);
33 
34 void CL_GunSmokeEffect (vec3_t org, vec3_t dir);
35 
36 trace_t CL_Trace (vec3_t start, vec3_t end, float size, int contentmask);
37 #endif
38 
39 static vec3_t avelocities [NUMVERTEXNORMALS];
40 
41 extern	struct model_s	*cl_mod_smoke;
42 extern	struct model_s	*cl_mod_flash;
43 
44 /*
45 ==============================================================
46 
47 LIGHT STYLE MANAGEMENT
48 
49 ==============================================================
50 */
51 
52 typedef struct
53 {
54 	int		length;
55 	float	value[3];
56 	float	map[MAX_QPATH];
57 } clightstyle_t;
58 
59 clightstyle_t	cl_lightstyle[MAX_LIGHTSTYLES];
60 int			lastofs;
61 
62 cparticle_t	*active_particles, *free_particles;
63 cparticle_t	particles[MAX_PARTICLES];
64 
65 int			cl_numparticles = MAX_PARTICLES;
66 
67 #ifdef QMAX
setupParticle(float angle0,float angle1,float angle2,float org0,float org1,float org2,float vel0,float vel1,float vel2,float accel0,float accel1,float accel2,float color0,float color1,float color2,float colorvel0,float colorvel1,float colorvel2,float alpha,float alphavel,float size,float sizevel,int image,int flags,void (* think)(cparticle_t * p,vec3_t org,vec3_t angle,float * alpha,float * size,int * image,float * time),qboolean thinknext)68 cparticle_t *setupParticle (
69 			float angle0,		float angle1,		float angle2,
70 			float org0,			float org1,			float org2,
71 			float vel0,			float vel1,			float vel2,
72 			float accel0,		float accel1,		float accel2,
73 			float color0,		float color1,		float color2,
74 			float colorvel0,	float colorvel1,	float colorvel2,
75 			float alpha,		float alphavel,
76 			float size,			float sizevel,
77 			int	image,
78 			int flags,
79 			void (*think)(cparticle_t *p, vec3_t org, vec3_t angle, float *alpha, float *size, int *image, float *time),
80 			qboolean thinknext)
81 {
82 	int j;
83 	cparticle_t	*p = NULL;
84 
85 	if (!free_particles)
86 		return NULL;
87 	p = free_particles;
88 	free_particles = p->next;
89 	p->next = active_particles;
90 	active_particles = p;
91 
92 	p->start = p->time = cl.time;
93 
94 	p->angle[0]=angle0;
95 	p->angle[1]=angle1;
96 	p->angle[2]=angle2;
97 
98 	p->org[0]=org0;
99 	p->org[1]=org1;
100 	p->org[2]=org2;
101 
102 	p->vel[0]=vel0;
103 	p->vel[1]=vel1;
104 	p->vel[2]=vel2;
105 
106 	p->accel[0]=accel0;
107 	p->accel[1]=accel1;
108 	p->accel[2]=accel2;
109 
110 	p->color[0]=color0;
111 	p->color[1]=color1;
112 	p->color[2]=color2;
113 
114 	p->colorvel[0]=colorvel0;
115 	p->colorvel[1]=colorvel1;
116 	p->colorvel[2]=colorvel2;
117 
118 	p->alpha=alpha;
119 	p->alphavel=alphavel;
120 	p->size=size;
121 	p->sizevel=sizevel;
122 
123 	p->image=image;
124 	p->flags=flags;
125 
126 	p->src_ent=0;
127 	p->dst_ent=0;
128 
129 	if (think)
130 		p->think=think;
131 	else
132 		p->think=NULL;
133 	p->thinknext=thinknext;
134 
135 	for (j=0;j<P_LIGHTS_MAX;j++)
136 	{
137 		cplight_t *plight = &p->lights[j];
138 		plight->isactive = false;
139 		plight->light = 0;
140 		plight->lightvel = 0;
141 		plight->lightcol[0] = 0;
142 		plight->lightcol[1] = 0;
143 		plight->lightcol[2] = 0;
144 	}
145 
146 	return p;
147 }
148 #endif
149 
150 /*
151 ================
152 CL_ClearLightStyles
153 ================
154 */
CL_ClearLightStyles(void)155 void CL_ClearLightStyles (void)
156 {
157 	memset (cl_lightstyle, 0, sizeof(cl_lightstyle));
158 	lastofs = -1;
159 }
160 
161 /*
162 ================
163 CL_RunLightStyles
164 ================
165 */
CL_RunLightStyles(void)166 void CL_RunLightStyles (void)
167 {
168 	int		ofs;
169 	int		i;
170 	clightstyle_t	*ls;
171 
172 	ofs = cl.time / 100;
173 	if (ofs == lastofs)
174 		return;
175 	lastofs = ofs;
176 
177 	for (i=0,ls=cl_lightstyle ; i<MAX_LIGHTSTYLES ; i++, ls++)
178 	{
179 		if (!ls->length)
180 		{
181 			ls->value[0] = ls->value[1] = ls->value[2] = 1.0;
182 			continue;
183 		}
184 		if (ls->length == 1)
185 			ls->value[0] = ls->value[1] = ls->value[2] = ls->map[0];
186 		else
187 			ls->value[0] = ls->value[1] = ls->value[2] = ls->map[ofs%ls->length];
188 	}
189 }
190 
191 
CL_SetLightstyle(int i)192 void CL_SetLightstyle (int i)
193 {
194 	char	*s;
195 	int		j, k;
196 
197 	s = cl.configstrings[i+CS_LIGHTS];
198 
199 	j = strlen (s);
200 	if (j >= MAX_QPATH)
201 		Com_Error (ERR_DROP, "svc_lightstyle length=%i", j);
202 
203 	cl_lightstyle[i].length = j;
204 
205 	for (k=0 ; k<j ; k++)
206 		cl_lightstyle[i].map[k] = (float)(s[k]-'a')/(float)('m'-'a');
207 }
208 
209 /*
210 ================
211 CL_AddLightStyles
212 ================
213 */
CL_AddLightStyles(void)214 void CL_AddLightStyles (void)
215 {
216 	int		i;
217 	clightstyle_t	*ls;
218 
219 	for (i=0,ls=cl_lightstyle ; i<MAX_LIGHTSTYLES ; i++, ls++)
220 		V_AddLightStyle (i, ls->value[0], ls->value[1], ls->value[2]);
221 }
222 
223 /*
224 ==============================================================
225 
226 DLIGHT MANAGEMENT
227 
228 ==============================================================
229 */
230 
231 cdlight_t		cl_dlights[MAX_DLIGHTS];
232 
233 /*
234 ================
235 CL_ClearDlights
236 ================
237 */
CL_ClearDlights(void)238 void CL_ClearDlights (void)
239 {
240 	memset (cl_dlights, 0, sizeof(cl_dlights));
241 }
242 
243 /*
244 ===============
245 CL_AllocDlight
246 
247 ===============
248 */
CL_AllocDlight(int key)249 cdlight_t *CL_AllocDlight (int key)
250 {
251 	int		i;
252 	cdlight_t	*dl;
253 
254 // first look for an exact key match
255 	if (key)
256 	{
257 		dl = cl_dlights;
258 		for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
259 		{
260 			if (dl->key == key)
261 			{
262 				memset (dl, 0, sizeof(*dl));
263 				dl->key = key;
264 				return dl;
265 			}
266 		}
267 	}
268 
269 // then look for anything else
270 	dl = cl_dlights;
271 	for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
272 	{
273 		if (dl->die < cl.time)
274 		{
275 			memset (dl, 0, sizeof(*dl));
276 			dl->key = key;
277 			return dl;
278 		}
279 	}
280 
281 	dl = &cl_dlights[0];
282 	memset (dl, 0, sizeof(*dl));
283 	dl->key = key;
284 	return dl;
285 }
286 
287 /*
288 ===============
289 CL_NewDlight
290 ===============
291 */
CL_NewDlight(int key,float x,float y,float z,float radius,float time)292 void CL_NewDlight (int key, float x, float y, float z, float radius, float time)
293 {
294 	cdlight_t	*dl;
295 
296 	dl = CL_AllocDlight (key);
297 	dl->origin[0] = x;
298 	dl->origin[1] = y;
299 	dl->origin[2] = z;
300 	dl->radius = radius;
301 	dl->die = cl.time + time;
302 }
303 
304 
305 /*
306 ===============
307 CL_RunDLights
308 
309 ===============
310 */
CL_RunDLights(void)311 void CL_RunDLights (void)
312 {
313 	int			i;
314 	cdlight_t	*dl;
315 
316 	dl = cl_dlights;
317 	for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
318 	{
319 		if (!dl->radius)
320 			continue;
321 
322 		if (dl->die < cl.time)
323 		{
324 			dl->radius = 0;
325 			return;
326 		}
327 		dl->radius -= cls.frametime*dl->decay;
328 		if (dl->radius < 0)
329 			dl->radius = 0;
330 	}
331 }
332 
333 /*
334 ==============
335 CL_ParseMuzzleFlash
336 ==============
337 */
CL_ParseMuzzleFlash(void)338 void CL_ParseMuzzleFlash (void)
339 {
340 	vec3_t		fv, rv;
341 	cdlight_t	*dl;
342 	int			i, weapon;
343 	centity_t	*pl;
344 	int			silenced;
345 	float		volume;
346 	char		soundname[64];
347 
348 	i = MSG_ReadShort (&net_message);
349 	if (i < 1 || i >= MAX_EDICTS)
350 		Com_Error (ERR_DROP, "CL_ParseMuzzleFlash: bad entity");
351 
352 	weapon = MSG_ReadByte (&net_message);
353 	silenced = weapon & MZ_SILENCED;
354 	weapon &= ~MZ_SILENCED;
355 
356 	pl = &cl_entities[i];
357 
358 	dl = CL_AllocDlight (i);
359 	VectorCopy (pl->current.origin,  dl->origin);
360 	AngleVectors (pl->current.angles, fv, rv, NULL);
361 	VectorMA (dl->origin, 18, fv, dl->origin);
362 	VectorMA (dl->origin, 16, rv, dl->origin);
363 	if (silenced)
364 		dl->radius = 100 + (rand()&31);
365 	else
366 		dl->radius = 200 + (rand()&31);
367 	dl->minlight = 32;
368 	dl->die = cl.time; // + 0.1;
369 
370 	if (silenced)
371 		volume = 0.2;
372 	else
373 		volume = 1;
374 
375 	switch (weapon)
376 	{
377 	case MZ_BLASTER:
378 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
379 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0);
380 		break;
381 	case MZ_BLUEHYPERBLASTER:
382 		dl->color[0] = 0;dl->color[1] = 0;dl->color[2] = 1;
383 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0);
384 		break;
385 	case MZ_HYPERBLASTER:
386 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
387 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/hyprbf1a.wav"), volume, ATTN_NORM, 0);
388 		break;
389 	case MZ_MACHINEGUN:
390 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
391 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
392 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
393 		break;
394 	case MZ_SHOTGUN:
395 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
396 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/shotgf1b.wav"), volume, ATTN_NORM, 0);
397 		S_StartSound (NULL, i, CHAN_AUTO,   S_RegisterSound("weapons/shotgr1b.wav"), volume, ATTN_NORM, 0.1);
398 		break;
399 	case MZ_SSHOTGUN:
400 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
401 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/sshotf1b.wav"), volume, ATTN_NORM, 0);
402 		break;
403 	case MZ_CHAINGUN1:
404 		dl->radius = 200 + (rand()&31);
405 		dl->color[0] = 1;dl->color[1] = 0.25;dl->color[2] = 0;
406 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
407 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
408 		break;
409 	case MZ_CHAINGUN2:
410 		dl->radius = 225 + (rand()&31);
411 		dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0;
412 		dl->die = cl.time  + 0.1;	// long delay
413 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
414 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
415 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
416 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.05);
417 		break;
418 	case MZ_CHAINGUN3:
419 		dl->radius = 250 + (rand()&31);
420 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
421 		dl->die = cl.time  + 0.1;	// long delay
422 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
423 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0);
424 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
425 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.033);
426 		Com_sprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
427 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound(soundname), volume, ATTN_NORM, 0.066);
428 		break;
429 	case MZ_RAILGUN:
430 		dl->color[0] = 0.5;dl->color[1] = 0.5;dl->color[2] = 1.0;
431 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/railgf1a.wav"), volume, ATTN_NORM, 0);
432 		break;
433 	case MZ_ROCKET:
434 		dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2;
435 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/rocklf1a.wav"), volume, ATTN_NORM, 0);
436 		S_StartSound (NULL, i, CHAN_AUTO,   S_RegisterSound("weapons/rocklr1b.wav"), volume, ATTN_NORM, 0.1);
437 		break;
438 	case MZ_GRENADE:
439 		dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0;
440 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), volume, ATTN_NORM, 0);
441 		S_StartSound (NULL, i, CHAN_AUTO,   S_RegisterSound("weapons/grenlr1b.wav"), volume, ATTN_NORM, 0.1);
442 		break;
443 	case MZ_BFG:
444 		dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0;
445 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/bfg__f1y.wav"), volume, ATTN_NORM, 0);
446 		break;
447 
448 	case MZ_LOGIN:
449 		dl->color[0] = 0;dl->color[1] = 1; dl->color[2] = 0;
450 		dl->die = cl.time + 1.0;
451 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0);
452 		CL_LogoutEffect (pl->current.origin, weapon);
453 		break;
454 	case MZ_LOGOUT:
455 		dl->color[0] = 1;dl->color[1] = 0; dl->color[2] = 0;
456 		dl->die = cl.time + 1.0;
457 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0);
458 		CL_LogoutEffect (pl->current.origin, weapon);
459 		break;
460 	case MZ_RESPAWN:
461 		dl->color[0] = 1;dl->color[1] = 1; dl->color[2] = 0;
462 		dl->die = cl.time + 1.0;
463 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/grenlf1a.wav"), 1, ATTN_NORM, 0);
464 		CL_LogoutEffect (pl->current.origin, weapon);
465 		break;
466 	// RAFAEL
467 	case MZ_PHALANX:
468 		dl->color[0] = 1;dl->color[1] = 0.5; dl->color[2] = 0.5;
469 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/plasshot.wav"), volume, ATTN_NORM, 0);
470 		break;
471 	// RAFAEL
472 	case MZ_IONRIPPER:
473 		dl->color[0] = 1;dl->color[1] = 0.5; dl->color[2] = 0.5;
474 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/rippfire.wav"), volume, ATTN_NORM, 0);
475 		break;
476 
477 // ======================
478 // PGM
479 	case MZ_ETF_RIFLE:
480 		dl->color[0] = 0.9;dl->color[1] = 0.7;dl->color[2] = 0;
481 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/nail1.wav"), volume, ATTN_NORM, 0);
482 		break;
483 	case MZ_SHOTGUN2:
484 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
485 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/shotg2.wav"), volume, ATTN_NORM, 0);
486 		break;
487 	case MZ_HEATBEAM:
488 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
489 		dl->die = cl.time + 100;
490 //		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/bfg__l1a.wav"), volume, ATTN_NORM, 0);
491 		break;
492 	case MZ_BLASTER2:
493 		dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0;
494 		// FIXME - different sound for blaster2 ??
495 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/blastf1a.wav"), volume, ATTN_NORM, 0);
496 		break;
497 	case MZ_TRACKER:
498 		// negative flashes handled the same in gl/soft until CL_AddDLights
499 		dl->color[0] = -1;dl->color[1] = -1;dl->color[2] = -1;
500 		S_StartSound (NULL, i, CHAN_WEAPON, S_RegisterSound("weapons/disint2.wav"), volume, ATTN_NORM, 0);
501 		break;
502 	case MZ_NUKE1:
503 		dl->color[0] = 1;dl->color[1] = 0;dl->color[2] = 0;
504 		dl->die = cl.time + 100;
505 		break;
506 	case MZ_NUKE2:
507 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
508 		dl->die = cl.time + 100;
509 		break;
510 	case MZ_NUKE4:
511 		dl->color[0] = 0;dl->color[1] = 0;dl->color[2] = 1;
512 		dl->die = cl.time + 100;
513 		break;
514 	case MZ_NUKE8:
515 		dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 1;
516 		dl->die = cl.time + 100;
517 		break;
518 // PGM
519 // ======================
520 	}
521 }
522 
523 
524 /*
525 ==============
526 CL_ParseMuzzleFlash2
527 ==============
528 */
CL_ParseMuzzleFlash2(void)529 void CL_ParseMuzzleFlash2 (void)
530 {
531 	int			ent;
532 	vec3_t		origin;
533 	int			flash_number;
534 	cdlight_t	*dl;
535 	vec3_t		forward, right;
536 	char		soundname[64];
537 
538 	ent = MSG_ReadShort (&net_message);
539 	if (ent < 1 || ent >= MAX_EDICTS)
540 		Com_Error (ERR_DROP, "CL_ParseMuzzleFlash2: bad entity");
541 
542 	flash_number = MSG_ReadByte (&net_message);
543 
544 	// locate the origin
545 	AngleVectors (cl_entities[ent].current.angles, forward, right, NULL);
546 	origin[0] = cl_entities[ent].current.origin[0] + forward[0] * monster_flash_offset[flash_number][0] + right[0] * monster_flash_offset[flash_number][1];
547 	origin[1] = cl_entities[ent].current.origin[1] + forward[1] * monster_flash_offset[flash_number][0] + right[1] * monster_flash_offset[flash_number][1];
548 	origin[2] = cl_entities[ent].current.origin[2] + forward[2] * monster_flash_offset[flash_number][0] + right[2] * monster_flash_offset[flash_number][1] + monster_flash_offset[flash_number][2];
549 
550 	dl = CL_AllocDlight (ent);
551 	VectorCopy (origin,  dl->origin);
552 	dl->radius = 200 + (rand()&31);
553 	dl->minlight = 32;
554 	dl->die = cl.time;	// + 0.1;
555 
556 	switch (flash_number)
557 	{
558 	case MZ2_INFANTRY_MACHINEGUN_1:
559 	case MZ2_INFANTRY_MACHINEGUN_2:
560 	case MZ2_INFANTRY_MACHINEGUN_3:
561 	case MZ2_INFANTRY_MACHINEGUN_4:
562 	case MZ2_INFANTRY_MACHINEGUN_5:
563 	case MZ2_INFANTRY_MACHINEGUN_6:
564 	case MZ2_INFANTRY_MACHINEGUN_7:
565 	case MZ2_INFANTRY_MACHINEGUN_8:
566 	case MZ2_INFANTRY_MACHINEGUN_9:
567 	case MZ2_INFANTRY_MACHINEGUN_10:
568 	case MZ2_INFANTRY_MACHINEGUN_11:
569 	case MZ2_INFANTRY_MACHINEGUN_12:
570 	case MZ2_INFANTRY_MACHINEGUN_13:
571 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
572 		CL_ParticleEffect (origin, vec3_origin, 0, 40);
573 		CL_SmokeAndFlash(origin);
574 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("infantry/infatck1.wav"), 1, ATTN_NORM, 0);
575 		break;
576 
577 	case MZ2_SOLDIER_MACHINEGUN_1:
578 	case MZ2_SOLDIER_MACHINEGUN_2:
579 	case MZ2_SOLDIER_MACHINEGUN_3:
580 	case MZ2_SOLDIER_MACHINEGUN_4:
581 	case MZ2_SOLDIER_MACHINEGUN_5:
582 	case MZ2_SOLDIER_MACHINEGUN_6:
583 	case MZ2_SOLDIER_MACHINEGUN_7:
584 	case MZ2_SOLDIER_MACHINEGUN_8:
585 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
586 		CL_ParticleEffect (origin, vec3_origin, 0, 40);
587 		CL_SmokeAndFlash(origin);
588 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("soldier/solatck3.wav"), 1, ATTN_NORM, 0);
589 		break;
590 
591 	case MZ2_GUNNER_MACHINEGUN_1:
592 	case MZ2_GUNNER_MACHINEGUN_2:
593 	case MZ2_GUNNER_MACHINEGUN_3:
594 	case MZ2_GUNNER_MACHINEGUN_4:
595 	case MZ2_GUNNER_MACHINEGUN_5:
596 	case MZ2_GUNNER_MACHINEGUN_6:
597 	case MZ2_GUNNER_MACHINEGUN_7:
598 	case MZ2_GUNNER_MACHINEGUN_8:
599 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
600 		CL_ParticleEffect (origin, vec3_origin, 0, 40);
601 		CL_SmokeAndFlash(origin);
602 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("gunner/gunatck2.wav"), 1, ATTN_NORM, 0);
603 		break;
604 
605 	case MZ2_ACTOR_MACHINEGUN_1:
606 	case MZ2_SUPERTANK_MACHINEGUN_1:
607 	case MZ2_SUPERTANK_MACHINEGUN_2:
608 	case MZ2_SUPERTANK_MACHINEGUN_3:
609 	case MZ2_SUPERTANK_MACHINEGUN_4:
610 	case MZ2_SUPERTANK_MACHINEGUN_5:
611 	case MZ2_SUPERTANK_MACHINEGUN_6:
612 	case MZ2_TURRET_MACHINEGUN:			// PGM
613 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
614 
615 		CL_ParticleEffect (origin, vec3_origin, 0, 40);
616 		CL_SmokeAndFlash(origin);
617 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("infantry/infatck1.wav"), 1, ATTN_NORM, 0);
618 		break;
619 
620 	case MZ2_BOSS2_MACHINEGUN_L1:
621 	case MZ2_BOSS2_MACHINEGUN_L2:
622 	case MZ2_BOSS2_MACHINEGUN_L3:
623 	case MZ2_BOSS2_MACHINEGUN_L4:
624 	case MZ2_BOSS2_MACHINEGUN_L5:
625 	case MZ2_CARRIER_MACHINEGUN_L1:		// PMM
626 	case MZ2_CARRIER_MACHINEGUN_L2:		// PMM
627 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
628 
629 		CL_ParticleEffect (origin, vec3_origin, 0, 40);
630 		CL_SmokeAndFlash(origin);
631 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("infantry/infatck1.wav"), 1, ATTN_NONE, 0);
632 		break;
633 
634 	case MZ2_SOLDIER_BLASTER_1:
635 	case MZ2_SOLDIER_BLASTER_2:
636 	case MZ2_SOLDIER_BLASTER_3:
637 	case MZ2_SOLDIER_BLASTER_4:
638 	case MZ2_SOLDIER_BLASTER_5:
639 	case MZ2_SOLDIER_BLASTER_6:
640 	case MZ2_SOLDIER_BLASTER_7:
641 	case MZ2_SOLDIER_BLASTER_8:
642 	case MZ2_TURRET_BLASTER:			// PGM
643 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
644 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("soldier/solatck2.wav"), 1, ATTN_NORM, 0);
645 		break;
646 
647 	case MZ2_FLYER_BLASTER_1:
648 	case MZ2_FLYER_BLASTER_2:
649 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
650 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("flyer/flyatck3.wav"), 1, ATTN_NORM, 0);
651 		break;
652 
653 	case MZ2_MEDIC_BLASTER_1:
654 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
655 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("medic/medatck1.wav"), 1, ATTN_NORM, 0);
656 		break;
657 
658 	case MZ2_HOVER_BLASTER_1:
659 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
660 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("hover/hovatck1.wav"), 1, ATTN_NORM, 0);
661 		break;
662 
663 	case MZ2_FLOAT_BLASTER_1:
664 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
665 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("floater/fltatck1.wav"), 1, ATTN_NORM, 0);
666 		break;
667 
668 	case MZ2_SOLDIER_SHOTGUN_1:
669 	case MZ2_SOLDIER_SHOTGUN_2:
670 	case MZ2_SOLDIER_SHOTGUN_3:
671 	case MZ2_SOLDIER_SHOTGUN_4:
672 	case MZ2_SOLDIER_SHOTGUN_5:
673 	case MZ2_SOLDIER_SHOTGUN_6:
674 	case MZ2_SOLDIER_SHOTGUN_7:
675 	case MZ2_SOLDIER_SHOTGUN_8:
676 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
677 		CL_SmokeAndFlash(origin);
678 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("soldier/solatck1.wav"), 1, ATTN_NORM, 0);
679 		break;
680 
681 	case MZ2_TANK_BLASTER_1:
682 	case MZ2_TANK_BLASTER_2:
683 	case MZ2_TANK_BLASTER_3:
684 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
685 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("tank/tnkatck3.wav"), 1, ATTN_NORM, 0);
686 		break;
687 
688 	case MZ2_TANK_MACHINEGUN_1:
689 	case MZ2_TANK_MACHINEGUN_2:
690 	case MZ2_TANK_MACHINEGUN_3:
691 	case MZ2_TANK_MACHINEGUN_4:
692 	case MZ2_TANK_MACHINEGUN_5:
693 	case MZ2_TANK_MACHINEGUN_6:
694 	case MZ2_TANK_MACHINEGUN_7:
695 	case MZ2_TANK_MACHINEGUN_8:
696 	case MZ2_TANK_MACHINEGUN_9:
697 	case MZ2_TANK_MACHINEGUN_10:
698 	case MZ2_TANK_MACHINEGUN_11:
699 	case MZ2_TANK_MACHINEGUN_12:
700 	case MZ2_TANK_MACHINEGUN_13:
701 	case MZ2_TANK_MACHINEGUN_14:
702 	case MZ2_TANK_MACHINEGUN_15:
703 	case MZ2_TANK_MACHINEGUN_16:
704 	case MZ2_TANK_MACHINEGUN_17:
705 	case MZ2_TANK_MACHINEGUN_18:
706 	case MZ2_TANK_MACHINEGUN_19:
707 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
708 		CL_ParticleEffect (origin, vec3_origin, 0, 40);
709 		CL_SmokeAndFlash(origin);
710 		Com_sprintf(soundname, sizeof(soundname), "tank/tnkatk2%c.wav", 'a' + rand() % 5);
711 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound(soundname), 1, ATTN_NORM, 0);
712 		break;
713 
714 	case MZ2_CHICK_ROCKET_1:
715 	case MZ2_TURRET_ROCKET:			// PGM
716 		dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2;
717 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("chick/chkatck2.wav"), 1, ATTN_NORM, 0);
718 		break;
719 
720 	case MZ2_TANK_ROCKET_1:
721 	case MZ2_TANK_ROCKET_2:
722 	case MZ2_TANK_ROCKET_3:
723 		dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2;
724 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("tank/tnkatck1.wav"), 1, ATTN_NORM, 0);
725 		break;
726 
727 	case MZ2_SUPERTANK_ROCKET_1:
728 	case MZ2_SUPERTANK_ROCKET_2:
729 	case MZ2_SUPERTANK_ROCKET_3:
730 	case MZ2_BOSS2_ROCKET_1:
731 	case MZ2_BOSS2_ROCKET_2:
732 	case MZ2_BOSS2_ROCKET_3:
733 	case MZ2_BOSS2_ROCKET_4:
734 	case MZ2_CARRIER_ROCKET_1:
735 //	case MZ2_CARRIER_ROCKET_2:
736 //	case MZ2_CARRIER_ROCKET_3:
737 //	case MZ2_CARRIER_ROCKET_4:
738 		dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0.2;
739 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("tank/rocket.wav"), 1, ATTN_NORM, 0);
740 		break;
741 
742 	case MZ2_GUNNER_GRENADE_1:
743 	case MZ2_GUNNER_GRENADE_2:
744 	case MZ2_GUNNER_GRENADE_3:
745 	case MZ2_GUNNER_GRENADE_4:
746 		dl->color[0] = 1;dl->color[1] = 0.5;dl->color[2] = 0;
747 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("gunner/gunatck3.wav"), 1, ATTN_NORM, 0);
748 		break;
749 
750 	case MZ2_GLADIATOR_RAILGUN_1:
751 	// PMM
752 	case MZ2_CARRIER_RAILGUN:
753 	case MZ2_WIDOW_RAIL:
754 	// pmm
755 		dl->color[0] = 0.5;dl->color[1] = 0.5;dl->color[2] = 1.0;
756 		break;
757 
758 // --- Xian's shit starts ---
759 	case MZ2_MAKRON_BFG:
760 		dl->color[0] = 0.5;dl->color[1] = 1 ;dl->color[2] = 0.5;
761 		//S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("makron/bfg_fire.wav"), 1, ATTN_NORM, 0);
762 		break;
763 
764 	case MZ2_MAKRON_BLASTER_1:
765 	case MZ2_MAKRON_BLASTER_2:
766 	case MZ2_MAKRON_BLASTER_3:
767 	case MZ2_MAKRON_BLASTER_4:
768 	case MZ2_MAKRON_BLASTER_5:
769 	case MZ2_MAKRON_BLASTER_6:
770 	case MZ2_MAKRON_BLASTER_7:
771 	case MZ2_MAKRON_BLASTER_8:
772 	case MZ2_MAKRON_BLASTER_9:
773 	case MZ2_MAKRON_BLASTER_10:
774 	case MZ2_MAKRON_BLASTER_11:
775 	case MZ2_MAKRON_BLASTER_12:
776 	case MZ2_MAKRON_BLASTER_13:
777 	case MZ2_MAKRON_BLASTER_14:
778 	case MZ2_MAKRON_BLASTER_15:
779 	case MZ2_MAKRON_BLASTER_16:
780 	case MZ2_MAKRON_BLASTER_17:
781 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
782 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("makron/blaster.wav"), 1, ATTN_NORM, 0);
783 		break;
784 
785 	case MZ2_JORG_MACHINEGUN_L1:
786 	case MZ2_JORG_MACHINEGUN_L2:
787 	case MZ2_JORG_MACHINEGUN_L3:
788 	case MZ2_JORG_MACHINEGUN_L4:
789 	case MZ2_JORG_MACHINEGUN_L5:
790 	case MZ2_JORG_MACHINEGUN_L6:
791 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
792 		CL_ParticleEffect (origin, vec3_origin, 0, 40);
793 		CL_SmokeAndFlash(origin);
794 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("boss3/xfire.wav"), 1, ATTN_NORM, 0);
795 		break;
796 
797 	case MZ2_JORG_MACHINEGUN_R1:
798 	case MZ2_JORG_MACHINEGUN_R2:
799 	case MZ2_JORG_MACHINEGUN_R3:
800 	case MZ2_JORG_MACHINEGUN_R4:
801 	case MZ2_JORG_MACHINEGUN_R5:
802 	case MZ2_JORG_MACHINEGUN_R6:
803 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
804 		CL_ParticleEffect (origin, vec3_origin, 0, 40);
805 		CL_SmokeAndFlash(origin);
806 		break;
807 
808 	case MZ2_JORG_BFG_1:
809 		dl->color[0] = 0.5;dl->color[1] = 1 ;dl->color[2] = 0.5;
810 		break;
811 
812 	case MZ2_BOSS2_MACHINEGUN_R1:
813 	case MZ2_BOSS2_MACHINEGUN_R2:
814 	case MZ2_BOSS2_MACHINEGUN_R3:
815 	case MZ2_BOSS2_MACHINEGUN_R4:
816 	case MZ2_BOSS2_MACHINEGUN_R5:
817 	case MZ2_CARRIER_MACHINEGUN_R1:			// PMM
818 	case MZ2_CARRIER_MACHINEGUN_R2:			// PMM
819 
820 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
821 
822 		CL_ParticleEffect (origin, vec3_origin, 0, 40);
823 		CL_SmokeAndFlash(origin);
824 		break;
825 
826 // ======
827 // ROGUE
828 	case MZ2_STALKER_BLASTER:
829 	case MZ2_DAEDALUS_BLASTER:
830 	case MZ2_MEDIC_BLASTER_2:
831 	case MZ2_WIDOW_BLASTER:
832 	case MZ2_WIDOW_BLASTER_SWEEP1:
833 	case MZ2_WIDOW_BLASTER_SWEEP2:
834 	case MZ2_WIDOW_BLASTER_SWEEP3:
835 	case MZ2_WIDOW_BLASTER_SWEEP4:
836 	case MZ2_WIDOW_BLASTER_SWEEP5:
837 	case MZ2_WIDOW_BLASTER_SWEEP6:
838 	case MZ2_WIDOW_BLASTER_SWEEP7:
839 	case MZ2_WIDOW_BLASTER_SWEEP8:
840 	case MZ2_WIDOW_BLASTER_SWEEP9:
841 	case MZ2_WIDOW_BLASTER_100:
842 	case MZ2_WIDOW_BLASTER_90:
843 	case MZ2_WIDOW_BLASTER_80:
844 	case MZ2_WIDOW_BLASTER_70:
845 	case MZ2_WIDOW_BLASTER_60:
846 	case MZ2_WIDOW_BLASTER_50:
847 	case MZ2_WIDOW_BLASTER_40:
848 	case MZ2_WIDOW_BLASTER_30:
849 	case MZ2_WIDOW_BLASTER_20:
850 	case MZ2_WIDOW_BLASTER_10:
851 	case MZ2_WIDOW_BLASTER_0:
852 	case MZ2_WIDOW_BLASTER_10L:
853 	case MZ2_WIDOW_BLASTER_20L:
854 	case MZ2_WIDOW_BLASTER_30L:
855 	case MZ2_WIDOW_BLASTER_40L:
856 	case MZ2_WIDOW_BLASTER_50L:
857 	case MZ2_WIDOW_BLASTER_60L:
858 	case MZ2_WIDOW_BLASTER_70L:
859 	case MZ2_WIDOW_RUN_1:
860 	case MZ2_WIDOW_RUN_2:
861 	case MZ2_WIDOW_RUN_3:
862 	case MZ2_WIDOW_RUN_4:
863 	case MZ2_WIDOW_RUN_5:
864 	case MZ2_WIDOW_RUN_6:
865 	case MZ2_WIDOW_RUN_7:
866 	case MZ2_WIDOW_RUN_8:
867 		dl->color[0] = 0;dl->color[1] = 1;dl->color[2] = 0;
868 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("tank/tnkatck3.wav"), 1, ATTN_NORM, 0);
869 		break;
870 
871 	case MZ2_WIDOW_DISRUPTOR:
872 		dl->color[0] = -1;dl->color[1] = -1;dl->color[2] = -1;
873 		S_StartSound (NULL, ent, CHAN_WEAPON, S_RegisterSound("weapons/disint2.wav"), 1, ATTN_NORM, 0);
874 		break;
875 
876 	case MZ2_WIDOW_PLASMABEAM:
877 	case MZ2_WIDOW2_BEAMER_1:
878 	case MZ2_WIDOW2_BEAMER_2:
879 	case MZ2_WIDOW2_BEAMER_3:
880 	case MZ2_WIDOW2_BEAMER_4:
881 	case MZ2_WIDOW2_BEAMER_5:
882 	case MZ2_WIDOW2_BEAM_SWEEP_1:
883 	case MZ2_WIDOW2_BEAM_SWEEP_2:
884 	case MZ2_WIDOW2_BEAM_SWEEP_3:
885 	case MZ2_WIDOW2_BEAM_SWEEP_4:
886 	case MZ2_WIDOW2_BEAM_SWEEP_5:
887 	case MZ2_WIDOW2_BEAM_SWEEP_6:
888 	case MZ2_WIDOW2_BEAM_SWEEP_7:
889 	case MZ2_WIDOW2_BEAM_SWEEP_8:
890 	case MZ2_WIDOW2_BEAM_SWEEP_9:
891 	case MZ2_WIDOW2_BEAM_SWEEP_10:
892 	case MZ2_WIDOW2_BEAM_SWEEP_11:
893 		dl->radius = 300 + (rand()&100);
894 		dl->color[0] = 1;dl->color[1] = 1;dl->color[2] = 0;
895 		dl->die = cl.time + 200;
896 		break;
897 // ROGUE
898 // ======
899 
900 // --- Xian's shit ends ---
901 
902 	}
903 }
904 
905 
906 /*
907 ===============
908 CL_AddDLights
909 
910 ===============
911 */
CL_AddDLights(void)912 void CL_AddDLights (void)
913 {
914 	int			i;
915 	cdlight_t	*dl;
916 
917 	dl = cl_dlights;
918 
919 //=====
920 //PGM
921 	if(vidref_val == VIDREF_GL)
922 	{
923 		for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
924 		{
925 			if (!dl->radius)
926 				continue;
927 			V_AddLight (dl->origin, dl->radius,
928 				dl->color[0], dl->color[1], dl->color[2]);
929 		}
930 	}
931 	else
932 	{
933 		for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
934 		{
935 			if (!dl->radius)
936 				continue;
937 
938 			// negative light in software. only black allowed
939 			if ((dl->color[0] < 0) || (dl->color[1] < 0) || (dl->color[2] < 0))
940 			{
941 				dl->radius = -(dl->radius);
942 				dl->color[0] = 1;
943 				dl->color[1] = 1;
944 				dl->color[2] = 1;
945 			}
946 			V_AddLight (dl->origin, dl->radius,
947 				dl->color[0], dl->color[1], dl->color[2]);
948 		}
949 	}
950 //PGM
951 //=====
952 }
953 
954 
955 
956 /*
957 ==============================================================
958 
959 PARTICLE MANAGEMENT
960 
961 ==============================================================
962 */
963 
964 /*
965 // THIS HAS BEEN RELOCATED TO CLIENT.H
966 typedef struct particle_s
967 {
968 	struct particle_s	*next;
969 
970 	float		time;
971 
972 	vec3_t		org;
973 	vec3_t		vel;
974 	vec3_t		accel;
975 	float		color;
976 	float		colorvel;
977 	float		alpha;
978 	float		alphavel;
979 } cparticle_t;
980 
981 
982 #define	PARTICLE_GRAVITY	40
983 */
984 
985 
986 /*
987 ===============
988 CL_ClearParticles
989 ===============
990 */
CL_ClearParticles(void)991 void CL_ClearParticles (void)
992 {
993 	int		i;
994 
995 	free_particles = &particles[0];
996 	active_particles = NULL;
997 
998 	for (i=0 ;i<cl_numparticles ; i++)
999 		particles[i].next = &particles[i+1];
1000 	particles[cl_numparticles-1].next = NULL;
1001 }
1002 
1003 
1004 /*
1005 ===============
1006 CL_ParticleEffect
1007 
1008 Wall impact puffs
1009 ===============
1010 */
CL_ParticleEffect(vec3_t org,vec3_t dir,int color,int count)1011 void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count)
1012 {
1013 	int			i, j;
1014 	cparticle_t	*p;
1015 	float		d;
1016 
1017 	for (i=0 ; i<count ; i++)
1018 	{
1019 		if (!free_particles)
1020 			return;
1021 		p = free_particles;
1022 		free_particles = p->next;
1023 		p->next = active_particles;
1024 		active_particles = p;
1025 
1026 		p->time = cl.time;
1027 #ifdef QMAX
1028 		p->color[0] = color + (rand()&7);
1029 		p->color[1] = color + (rand()&7);
1030 		p->color[2] = color + (rand()&7);
1031 #else
1032 		p->color = color + (rand()&7);
1033 #endif
1034 		d = rand()&31;
1035 		for (j=0 ; j<3 ; j++)
1036 		{
1037 			p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
1038 			p->vel[j] = crand()*20;
1039 		}
1040 
1041 		p->accel[0] = p->accel[1] = 0;
1042 		p->accel[2] = -PARTICLE_GRAVITY;
1043 		p->alpha = 1.0;
1044 
1045 		p->alphavel = -1.0 / (0.5 + frand()*0.3);
1046 	}
1047 }
1048 
1049 
1050 /*
1051 ===============
1052 CL_ParticleEffect2
1053 ===============
1054 */
CL_ParticleEffect2(vec3_t org,vec3_t dir,int color,int count)1055 void CL_ParticleEffect2 (vec3_t org, vec3_t dir, int color, int count)
1056 {
1057 	int			i, j;
1058 	cparticle_t	*p;
1059 	float		d;
1060 
1061 	for (i=0 ; i<count ; i++)
1062 	{
1063 		if (!free_particles)
1064 			return;
1065 		p = free_particles;
1066 		free_particles = p->next;
1067 		p->next = active_particles;
1068 		active_particles = p;
1069 
1070 		p->time = cl.time;
1071 #ifdef QMAX
1072 		p->color[0] = color;
1073 		p->color[1] = color;
1074 		p->color[2] = color;
1075 #else
1076 		p->color = color;
1077 #endif
1078 
1079 		d = rand()&7;
1080 		for (j=0 ; j<3 ; j++)
1081 		{
1082 			p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
1083 			p->vel[j] = crand()*20;
1084 		}
1085 
1086 		p->accel[0] = p->accel[1] = 0;
1087 		p->accel[2] = -PARTICLE_GRAVITY;
1088 		p->alpha = 1.0;
1089 
1090 		p->alphavel = -1.0 / (0.5 + frand()*0.3);
1091 	}
1092 }
1093 
1094 
1095 // RAFAEL
1096 /*
1097 ===============
1098 CL_ParticleEffect3
1099 ===============
1100 */
CL_ParticleEffect3(vec3_t org,vec3_t dir,int color,int count)1101 void CL_ParticleEffect3 (vec3_t org, vec3_t dir, int color, int count)
1102 {
1103 	int			i, j;
1104 	cparticle_t	*p;
1105 	float		d;
1106 
1107 	for (i=0 ; i<count ; i++)
1108 	{
1109 		if (!free_particles)
1110 			return;
1111 		p = free_particles;
1112 		free_particles = p->next;
1113 		p->next = active_particles;
1114 		active_particles = p;
1115 
1116 		p->time = cl.time;
1117 #ifdef QMAX
1118 		p->color[0] = color;
1119 		p->color[1] = color;
1120 		p->color[2] = color;
1121 #else
1122 		p->color = color;
1123 #endif
1124 
1125 		d = rand()&7;
1126 		for (j=0 ; j<3 ; j++)
1127 		{
1128 			p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
1129 			p->vel[j] = crand()*20;
1130 		}
1131 
1132 		p->accel[0] = p->accel[1] = 0;
1133 		p->accel[2] = PARTICLE_GRAVITY;
1134 		p->alpha = 1.0;
1135 
1136 		p->alphavel = -1.0 / (0.5 + frand()*0.3);
1137 	}
1138 }
1139 
1140 /*
1141 ===============
1142 CL_TeleporterParticles
1143 ===============
1144 */
CL_TeleporterParticles(entity_state_t * ent)1145 void CL_TeleporterParticles (entity_state_t *ent)
1146 {
1147 	int			i, j;
1148 	cparticle_t	*p;
1149 
1150 	for (i=0 ; i<8 ; i++)
1151 	{
1152 		if (!free_particles)
1153 			return;
1154 		p = free_particles;
1155 		free_particles = p->next;
1156 		p->next = active_particles;
1157 		active_particles = p;
1158 
1159 		p->time = cl.time;
1160 #ifdef QMAX
1161 		p->color[0] = 0xdb;
1162 		p->color[1] = 0xdb;
1163 		p->color[2] = 0xdb;
1164 #else
1165 		p->color = 0xdb;
1166 #endif
1167 
1168 		for (j=0 ; j<2 ; j++)
1169 		{
1170 			p->org[j] = ent->origin[j] - 16 + (rand()&31);
1171 			p->vel[j] = crand()*14;
1172 		}
1173 
1174 		p->org[2] = ent->origin[2] - 8 + (rand()&7);
1175 		p->vel[2] = 80 + (rand()&7);
1176 
1177 		p->accel[0] = p->accel[1] = 0;
1178 		p->accel[2] = -PARTICLE_GRAVITY;
1179 		p->alpha = 1.0;
1180 
1181 		p->alphavel = -0.5;
1182 	}
1183 }
1184 
1185 
1186 /*
1187 ===============
1188 CL_LogoutEffect
1189 
1190 ===============
1191 */
CL_LogoutEffect(vec3_t org,int type)1192 void CL_LogoutEffect (vec3_t org, int type)
1193 {
1194 	int			i, j;
1195 	cparticle_t	*p;
1196 
1197 	for (i=0 ; i<500 ; i++)
1198 	{
1199 		if (!free_particles)
1200 			return;
1201 		p = free_particles;
1202 		free_particles = p->next;
1203 		p->next = active_particles;
1204 		active_particles = p;
1205 
1206 		p->time = cl.time;
1207 
1208 #ifndef QMAX
1209 		if (type == MZ_LOGIN)
1210 			p->color = 0xd0 + (rand()&7);	// green
1211 		else if (type == MZ_LOGOUT)
1212 			p->color = 0x40 + (rand()&7);	// red
1213 		else
1214 			p->color = 0xe0 + (rand()&7);	// yellow
1215 #endif
1216 
1217 		p->org[0] = org[0] - 16 + frand()*32;
1218 		p->org[1] = org[1] - 16 + frand()*32;
1219 		p->org[2] = org[2] - 24 + frand()*56;
1220 
1221 		for (j=0 ; j<3 ; j++)
1222 			p->vel[j] = crand()*20;
1223 
1224 		p->accel[0] = p->accel[1] = 0;
1225 		p->accel[2] = -PARTICLE_GRAVITY;
1226 		p->alpha = 1.0;
1227 
1228 		p->alphavel = -1.0 / (1.0 + frand()*0.3);
1229 	}
1230 }
1231 
1232 
1233 /*
1234 ===============
1235 CL_ItemRespawnParticles
1236 
1237 ===============
1238 */
CL_ItemRespawnParticles(vec3_t org)1239 void CL_ItemRespawnParticles (vec3_t org)
1240 {
1241 	int			i, j;
1242 	cparticle_t	*p;
1243 
1244 	for (i=0 ; i<64 ; i++)
1245 	{
1246 		if (!free_particles)
1247 			return;
1248 		p = free_particles;
1249 		free_particles = p->next;
1250 		p->next = active_particles;
1251 		active_particles = p;
1252 
1253 		p->time = cl.time;
1254 #ifndef QMAX
1255 		p->color = 0xd4 + (rand()&3);	// green
1256 #endif
1257 		p->org[0] = org[0] + crand()*8;
1258 		p->org[1] = org[1] + crand()*8;
1259 		p->org[2] = org[2] + crand()*8;
1260 
1261 		for (j=0 ; j<3 ; j++)
1262 			p->vel[j] = crand()*8;
1263 
1264 		p->accel[0] = p->accel[1] = 0;
1265 		p->accel[2] = -PARTICLE_GRAVITY*0.2;
1266 		p->alpha = 1.0;
1267 
1268 		p->alphavel = -1.0 / (1.0 + frand()*0.3);
1269 	}
1270 }
1271 
1272 
1273 /*
1274 ===============
1275 CL_ExplosionParticles
1276 ===============
1277 */
CL_ExplosionParticles(vec3_t org)1278 void CL_ExplosionParticles (vec3_t org)
1279 {
1280 	int			i, j;
1281 	cparticle_t	*p;
1282 
1283 	for (i=0 ; i<256 ; i++)
1284 	{
1285 		if (!free_particles)
1286 			return;
1287 		p = free_particles;
1288 		free_particles = p->next;
1289 		p->next = active_particles;
1290 		active_particles = p;
1291 
1292 		p->time = cl.time;
1293 		p->color = 0xe0 + (rand()&7);
1294 		for (j=0 ; j<3 ; j++)
1295 		{
1296 			p->org[j] = org[j] + ((rand()%32)-16);
1297 			p->vel[j] = (rand()%384)-192;
1298 		}
1299 
1300 		p->accel[0] = p->accel[1] = 0;
1301 		p->accel[2] = -PARTICLE_GRAVITY;
1302 		p->alpha = 1.0;
1303 
1304 		p->alphavel = -0.8 / (0.5 + frand()*0.3);
1305 	}
1306 }
1307 
1308 /*
1309 ===============
1310 CL_BigTeleportParticles
1311 ===============
1312 */
CL_BigTeleportParticles(vec3_t org)1313 void CL_BigTeleportParticles (vec3_t org)
1314 {
1315 	int			i;
1316 	cparticle_t	*p;
1317 	float		angle, dist;
1318 	static int colortable[4] = {2*8,13*8,21*8,18*8};
1319 
1320 	for (i=0 ; i<4096 ; i++)
1321 	{
1322 		if (!free_particles)
1323 			return;
1324 		p = free_particles;
1325 		free_particles = p->next;
1326 		p->next = active_particles;
1327 		active_particles = p;
1328 
1329 		p->time = cl.time;
1330 #ifndef QMAX
1331 		p->color = colortable[rand()&3];
1332 #endif
1333 		angle = M_PI*2*(rand()&1023)/1023.0;
1334 		dist = rand()&31;
1335 		p->org[0] = org[0] + cos(angle)*dist;
1336 		p->vel[0] = cos(angle)*(70+(rand()&63));
1337 		p->accel[0] = -cos(angle)*100;
1338 
1339 		p->org[1] = org[1] + sin(angle)*dist;
1340 		p->vel[1] = sin(angle)*(70+(rand()&63));
1341 		p->accel[1] = -sin(angle)*100;
1342 
1343 		p->org[2] = org[2] + 8 + (rand()%90);
1344 		p->vel[2] = -100 + (rand()&31);
1345 		p->accel[2] = PARTICLE_GRAVITY*4;
1346 		p->alpha = 1.0;
1347 
1348 		p->alphavel = -0.3 / (0.5 + frand()*0.3);
1349 	}
1350 }
1351 
1352 
1353 /*
1354 ===============
1355 CL_BlasterParticles
1356 
1357 Wall impact puffs
1358 ===============
1359 */
CL_BlasterParticles(vec3_t org,vec3_t dir)1360 void CL_BlasterParticles (vec3_t org, vec3_t dir)
1361 {
1362 	int			i, j;
1363 	cparticle_t	*p;
1364 	float		d;
1365 	int			count;
1366 
1367 	count = 40;
1368 	for (i=0 ; i<count ; i++)
1369 	{
1370 		if (!free_particles)
1371 			return;
1372 		p = free_particles;
1373 		free_particles = p->next;
1374 		p->next = active_particles;
1375 		active_particles = p;
1376 
1377 		p->time = cl.time;
1378 #ifndef QMAX
1379 		p->color = 0xe0 + (rand()&7);
1380 #endif
1381 		d = rand()&15;
1382 		for (j=0 ; j<3 ; j++)
1383 		{
1384 			p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
1385 			p->vel[j] = dir[j] * 30 + crand()*40;
1386 		}
1387 
1388 		p->accel[0] = p->accel[1] = 0;
1389 		p->accel[2] = -PARTICLE_GRAVITY;
1390 		p->alpha = 1.0;
1391 
1392 		p->alphavel = -1.0 / (0.5 + frand()*0.3);
1393 	}
1394 }
1395 
1396 
1397 /*
1398 ===============
1399 CL_BlasterTrail
1400 
1401 ===============
1402 */
CL_BlasterTrail(vec3_t start,vec3_t end)1403 void CL_BlasterTrail (vec3_t start, vec3_t end)
1404 {
1405 	vec3_t		move;
1406 	vec3_t		vec;
1407 	float		len;
1408 	int			j;
1409 	cparticle_t	*p;
1410 	int			dec;
1411 
1412 	VectorCopy (start, move);
1413 	VectorSubtract (end, start, vec);
1414 	len = VectorNormalize (vec);
1415 
1416 	dec = 5;
1417 	VectorScale (vec, 5, vec);
1418 
1419 	// FIXME: this is a really silly way to have a loop
1420 	while (len > 0)
1421 	{
1422 		len -= dec;
1423 
1424 		if (!free_particles)
1425 			return;
1426 		p = free_particles;
1427 		free_particles = p->next;
1428 		p->next = active_particles;
1429 		active_particles = p;
1430 		VectorClear (p->accel);
1431 
1432 		p->time = cl.time;
1433 
1434 		p->alpha = 1.0;
1435 		p->alphavel = -1.0 / (0.3+frand()*0.2);
1436 #ifndef QMAX
1437 		p->color = 0xe0;
1438 #endif
1439 		for (j=0 ; j<3 ; j++)
1440 		{
1441 			p->org[j] = move[j] + crand();
1442 			p->vel[j] = crand()*5;
1443 			p->accel[j] = 0;
1444 		}
1445 
1446 		VectorAdd (move, vec, move);
1447 	}
1448 }
1449 
1450 /*
1451 ===============
1452 CL_QuadTrail
1453 
1454 ===============
1455 */
CL_QuadTrail(vec3_t start,vec3_t end)1456 void CL_QuadTrail (vec3_t start, vec3_t end)
1457 {
1458 	vec3_t		move;
1459 	vec3_t		vec;
1460 	float		len;
1461 	int			j;
1462 	cparticle_t	*p;
1463 	int			dec;
1464 
1465 	VectorCopy (start, move);
1466 	VectorSubtract (end, start, vec);
1467 	len = VectorNormalize (vec);
1468 
1469 	dec = 5;
1470 	VectorScale (vec, 5, vec);
1471 
1472 	while (len > 0)
1473 	{
1474 		len -= dec;
1475 
1476 		if (!free_particles)
1477 			return;
1478 		p = free_particles;
1479 		free_particles = p->next;
1480 		p->next = active_particles;
1481 		active_particles = p;
1482 		VectorClear (p->accel);
1483 
1484 		p->time = cl.time;
1485 
1486 		p->alpha = 1.0;
1487 		p->alphavel = -1.0 / (0.8+frand()*0.2);
1488 #ifndef QMAX
1489 		p->color = 115;
1490 #endif
1491 		for (j=0 ; j<3 ; j++)
1492 		{
1493 			p->org[j] = move[j] + crand()*16;
1494 			p->vel[j] = crand()*5;
1495 			p->accel[j] = 0;
1496 		}
1497 
1498 		VectorAdd (move, vec, move);
1499 	}
1500 }
1501 
1502 /*
1503 ===============
1504 CL_FlagTrail
1505 
1506 ===============
1507 */
1508 #ifdef QMAX
CL_FlagTrail(vec3_t start,vec3_t end,boolean isred)1509 void CL_FlagTrail (vec3_t start, vec3_t end, boolean isred)
1510 #else
1511 void CL_FlagTrail (vec3_t start, vec3_t end, float color)
1512 #endif
1513 {
1514 	vec3_t		move;
1515 	vec3_t		vec;
1516 	float		len;
1517 	int			j;
1518 	cparticle_t	*p;
1519 	int			dec;
1520 
1521 	VectorCopy (start, move);
1522 	VectorSubtract (end, start, vec);
1523 	len = VectorNormalize (vec);
1524 
1525 	dec = 5;
1526 	VectorScale (vec, 5, vec);
1527 
1528 	while (len > 0)
1529 	{
1530 		len -= dec;
1531 
1532 		if (!free_particles)
1533 			return;
1534 		p = free_particles;
1535 		free_particles = p->next;
1536 		p->next = active_particles;
1537 		active_particles = p;
1538 		VectorClear (p->accel);
1539 
1540 		p->time = cl.time;
1541 
1542 		p->alpha = 1.0;
1543 		p->alphavel = -1.0 / (0.8+frand()*0.2);
1544 #ifndef QMAX
1545 		p->color = color;
1546 #endif
1547 		for (j=0 ; j<3 ; j++)
1548 		{
1549 			p->org[j] = move[j] + crand()*16;
1550 			p->vel[j] = crand()*5;
1551 			p->accel[j] = 0;
1552 		}
1553 
1554 		VectorAdd (move, vec, move);
1555 	}
1556 }
1557 
1558 /*
1559 ===============
1560 CL_DiminishingTrail
1561 
1562 ===============
1563 */
CL_DiminishingTrail(vec3_t start,vec3_t end,centity_t * old,int flags)1564 void CL_DiminishingTrail (vec3_t start, vec3_t end, centity_t *old, int flags)
1565 {
1566 	vec3_t		move;
1567 	vec3_t		vec;
1568 	float		len;
1569 	int			j;
1570 	cparticle_t	*p;
1571 	float		dec;
1572 	float		orgscale;
1573 	float		velscale;
1574 
1575 	VectorCopy (start, move);
1576 	VectorSubtract (end, start, vec);
1577 	len = VectorNormalize (vec);
1578 
1579 	dec = 0.5;
1580 	VectorScale (vec, dec, vec);
1581 
1582 	if (old->trailcount > 900)
1583 	{
1584 		orgscale = 4;
1585 		velscale = 15;
1586 	}
1587 	else if (old->trailcount > 800)
1588 	{
1589 		orgscale = 2;
1590 		velscale = 10;
1591 	}
1592 	else
1593 	{
1594 		orgscale = 1;
1595 		velscale = 5;
1596 	}
1597 
1598 	while (len > 0)
1599 	{
1600 		len -= dec;
1601 
1602 		if (!free_particles)
1603 			return;
1604 
1605 		// drop less particles as it flies
1606 		if ((rand()&1023) < old->trailcount)
1607 		{
1608 			p = free_particles;
1609 			free_particles = p->next;
1610 			p->next = active_particles;
1611 			active_particles = p;
1612 			VectorClear (p->accel);
1613 
1614 			p->time = cl.time;
1615 
1616 			if (flags & EF_GIB)
1617 			{
1618 				p->alpha = 1.0;
1619 				p->alphavel = -1.0 / (1+frand()*0.4);
1620 #ifndef QMAX
1621 				p->color = 0xe8 + (rand()&7);
1622 #endif
1623 				for (j=0 ; j<3 ; j++)
1624 				{
1625 					p->org[j] = move[j] + crand()*orgscale;
1626 					p->vel[j] = crand()*velscale;
1627 					p->accel[j] = 0;
1628 				}
1629 				p->vel[2] -= PARTICLE_GRAVITY;
1630 			}
1631 			else if (flags & EF_GREENGIB)
1632 			{
1633 				p->alpha = 1.0;
1634 				p->alphavel = -1.0 / (1+frand()*0.4);
1635 #ifndef QMAX
1636 				p->color = 0xdb + (rand()&7);
1637 #endif
1638 				for (j=0; j< 3; j++)
1639 				{
1640 					p->org[j] = move[j] + crand()*orgscale;
1641 					p->vel[j] = crand()*velscale;
1642 					p->accel[j] = 0;
1643 				}
1644 				p->vel[2] -= PARTICLE_GRAVITY;
1645 			}
1646 			else
1647 			{
1648 				p->alpha = 1.0;
1649 				p->alphavel = -1.0 / (1+frand()*0.2);
1650 #ifndef QMAX
1651 				p->color = 4 + (rand()&7);
1652 #endif
1653 				for (j=0 ; j<3 ; j++)
1654 				{
1655 					p->org[j] = move[j] + crand()*orgscale;
1656 					p->vel[j] = crand()*velscale;
1657 				}
1658 				p->accel[2] = 20;
1659 			}
1660 		}
1661 
1662 		old->trailcount -= 5;
1663 		if (old->trailcount < 100)
1664 			old->trailcount = 100;
1665 		VectorAdd (move, vec, move);
1666 	}
1667 }
1668 
MakeNormalVectors(vec3_t forward,vec3_t right,vec3_t up)1669 void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up)
1670 {
1671 	float		d;
1672 
1673 	// this rotate and negat guarantees a vector
1674 	// not colinear with the original
1675 	right[1] = -forward[0];
1676 	right[2] = forward[1];
1677 	right[0] = forward[2];
1678 
1679 	d = DotProduct (right, forward);
1680 	VectorMA (right, -d, forward, right);
1681 	VectorNormalize (right);
1682 	CrossProduct (right, forward, up);
1683 }
1684 
1685 /*
1686 ===============
1687 CL_RocketTrail
1688 
1689 ===============
1690 */
CL_RocketTrail(vec3_t start,vec3_t end,centity_t * old)1691 void CL_RocketTrail (vec3_t start, vec3_t end, centity_t *old)
1692 {
1693 	vec3_t		move;
1694 	vec3_t		vec;
1695 	float		len;
1696 	int			j;
1697 	cparticle_t	*p;
1698 	float		dec;
1699 
1700 	// smoke
1701 	CL_DiminishingTrail (start, end, old, EF_ROCKET);
1702 
1703 	// fire
1704 	VectorCopy (start, move);
1705 	VectorSubtract (end, start, vec);
1706 	len = VectorNormalize (vec);
1707 
1708 	dec = 1;
1709 	VectorScale (vec, dec, vec);
1710 
1711 	while (len > 0)
1712 	{
1713 		len -= dec;
1714 
1715 		if (!free_particles)
1716 			return;
1717 
1718 		if ( (rand()&7) == 0)
1719 		{
1720 			p = free_particles;
1721 			free_particles = p->next;
1722 			p->next = active_particles;
1723 			active_particles = p;
1724 
1725 			VectorClear (p->accel);
1726 			p->time = cl.time;
1727 
1728 			p->alpha = 1.0;
1729 			p->alphavel = -1.0 / (1+frand()*0.2);
1730 #ifndef QMAX
1731 			p->color = 0xdc + (rand()&3);
1732 #endif
1733 			for (j=0 ; j<3 ; j++)
1734 			{
1735 				p->org[j] = move[j] + crand()*5;
1736 				p->vel[j] = crand()*20;
1737 			}
1738 			p->accel[2] = -PARTICLE_GRAVITY;
1739 		}
1740 		VectorAdd (move, vec, move);
1741 	}
1742 }
1743 
1744 /*
1745 ===============
1746 CL_RailTrail
1747 
1748 ===============
1749 */
CL_RailTrail(vec3_t start,vec3_t end)1750 void CL_RailTrail (vec3_t start, vec3_t end)
1751 {
1752 	vec3_t		move;
1753 	vec3_t		vec;
1754 	float		len;
1755 	int			j;
1756 	cparticle_t	*p;
1757 	float		dec;
1758 	vec3_t		right, up;
1759 	int			i;
1760 	float		d, c, s;
1761 	vec3_t		dir;
1762 	byte		clr = 0x74;
1763 
1764 	VectorCopy (start, move);
1765 	VectorSubtract (end, start, vec);
1766 	len = VectorNormalize (vec);
1767 
1768 	MakeNormalVectors (vec, right, up);
1769 
1770 	for (i=0 ; i<len ; i++)
1771 	{
1772 		if (!free_particles)
1773 			return;
1774 
1775 		p = free_particles;
1776 		free_particles = p->next;
1777 		p->next = active_particles;
1778 		active_particles = p;
1779 
1780 		p->time = cl.time;
1781 		VectorClear (p->accel);
1782 
1783 		d = i * 0.1;
1784 		c = cos(d);
1785 		s = sin(d);
1786 
1787 		VectorScale (right, c, dir);
1788 		VectorMA (dir, s, up, dir);
1789 
1790 		p->alpha = 1.0;
1791 		p->alphavel = -1.0 / (1+frand()*0.2);
1792 #ifndef QMAX
1793 		p->color = clr + (rand()&7);
1794 #endif
1795 		for (j=0 ; j<3 ; j++)
1796 		{
1797 			p->org[j] = move[j] + dir[j]*3;
1798 			p->vel[j] = dir[j]*6;
1799 		}
1800 
1801 		VectorAdd (move, vec, move);
1802 	}
1803 
1804 	dec = 0.75;
1805 	VectorScale (vec, dec, vec);
1806 	VectorCopy (start, move);
1807 
1808 	while (len > 0)
1809 	{
1810 		len -= dec;
1811 
1812 		if (!free_particles)
1813 			return;
1814 		p = free_particles;
1815 		free_particles = p->next;
1816 		p->next = active_particles;
1817 		active_particles = p;
1818 
1819 		p->time = cl.time;
1820 		VectorClear (p->accel);
1821 
1822 		p->alpha = 1.0;
1823 		p->alphavel = -1.0 / (0.6+frand()*0.2);
1824 #ifndef QMAX
1825 		p->color = 0x0 + (rand()&15);
1826 #endif
1827 		for (j=0 ; j<3 ; j++)
1828 		{
1829 			p->org[j] = move[j] + crand()*3;
1830 			p->vel[j] = crand()*3;
1831 			p->accel[j] = 0;
1832 		}
1833 
1834 		VectorAdd (move, vec, move);
1835 	}
1836 }
1837 
1838 // RAFAEL
1839 /*
1840 ===============
1841 CL_IonripperTrail
1842 ===============
1843 */
CL_IonripperTrail(vec3_t start,vec3_t ent)1844 void CL_IonripperTrail (vec3_t start, vec3_t ent)
1845 {
1846 	vec3_t	move;
1847 	vec3_t	vec;
1848 	float	len;
1849 	int		j;
1850 	cparticle_t *p;
1851 	int		dec;
1852 	int     left = 0;
1853 
1854 	VectorCopy (start, move);
1855 	VectorSubtract (ent, start, vec);
1856 	len = VectorNormalize (vec);
1857 
1858 	dec = 5;
1859 	VectorScale (vec, 5, vec);
1860 
1861 	while (len > 0)
1862 	{
1863 		len -= dec;
1864 
1865 		if (!free_particles)
1866 			return;
1867 		p = free_particles;
1868 		free_particles = p->next;
1869 		p->next = active_particles;
1870 		active_particles = p;
1871 		VectorClear (p->accel);
1872 
1873 		p->time = cl.time;
1874 		p->alpha = 0.5;
1875 		p->alphavel = -1.0 / (0.3 + frand() * 0.2);
1876 #ifndef QMAX
1877 		p->color = 0xe4 + (rand()&3);
1878 #endif
1879 		for (j=0; j<3; j++)
1880 		{
1881 			p->org[j] = move[j];
1882 			p->accel[j] = 0;
1883 		}
1884 		if (left)
1885 		{
1886 			left = 0;
1887 			p->vel[0] = 10;
1888 		}
1889 		else
1890 		{
1891 			left = 1;
1892 			p->vel[0] = -10;
1893 		}
1894 
1895 		p->vel[1] = 0;
1896 		p->vel[2] = 0;
1897 
1898 		VectorAdd (move, vec, move);
1899 	}
1900 }
1901 
1902 
1903 /*
1904 ===============
1905 CL_BubbleTrail
1906 
1907 ===============
1908 */
CL_BubbleTrail(vec3_t start,vec3_t end)1909 void CL_BubbleTrail (vec3_t start, vec3_t end)
1910 {
1911 	vec3_t		move;
1912 	vec3_t		vec;
1913 	float		len;
1914 	int			i, j;
1915 	cparticle_t	*p;
1916 	float		dec;
1917 
1918 	VectorCopy (start, move);
1919 	VectorSubtract (end, start, vec);
1920 	len = VectorNormalize (vec);
1921 
1922 	dec = 32;
1923 	VectorScale (vec, dec, vec);
1924 
1925 	for (i=0 ; i<len ; i+=dec)
1926 	{
1927 		if (!free_particles)
1928 			return;
1929 
1930 		p = free_particles;
1931 		free_particles = p->next;
1932 		p->next = active_particles;
1933 		active_particles = p;
1934 
1935 		VectorClear (p->accel);
1936 		p->time = cl.time;
1937 
1938 		p->alpha = 1.0;
1939 		p->alphavel = -1.0 / (1+frand()*0.2);
1940 #ifndef QMAX
1941 		p->color = 4 + (rand()&7);
1942 #endif
1943 		for (j=0 ; j<3 ; j++)
1944 		{
1945 			p->org[j] = move[j] + crand()*2;
1946 			p->vel[j] = crand()*5;
1947 		}
1948 		p->vel[2] += 6;
1949 
1950 		VectorAdd (move, vec, move);
1951 	}
1952 }
1953 
1954 
1955 /*
1956 ===============
1957 CL_FlyParticles
1958 ===============
1959 */
1960 
1961 #define	BEAMLENGTH			16
CL_FlyParticles(vec3_t origin,int count)1962 void CL_FlyParticles (vec3_t origin, int count)
1963 {
1964 	int			i;
1965 	cparticle_t	*p;
1966 	float		angle;
1967 	float		sr, sp, sy, cr, cp, cy;
1968 	vec3_t		forward;
1969 	float		dist = 64;
1970 	float		ltime;
1971 
1972 
1973 	if (count > NUMVERTEXNORMALS)
1974 		count = NUMVERTEXNORMALS;
1975 
1976 	if (!avelocities[0][0])
1977 	{
1978 		for (i=0 ; i<NUMVERTEXNORMALS*3 ; i++)
1979 			avelocities[0][i] = (rand()&255) * 0.01;
1980 	}
1981 
1982 
1983 	ltime = (float)cl.time / 1000.0;
1984 	for (i=0 ; i<count ; i+=2)
1985 	{
1986 		angle = ltime * avelocities[i][0];
1987 		sy = sin(angle);
1988 		cy = cos(angle);
1989 		angle = ltime * avelocities[i][1];
1990 		sp = sin(angle);
1991 		cp = cos(angle);
1992 		angle = ltime * avelocities[i][2];
1993 		sr = sin(angle);
1994 		cr = cos(angle);
1995 
1996 		forward[0] = cp*cy;
1997 		forward[1] = cp*sy;
1998 		forward[2] = -sp;
1999 
2000 		if (!free_particles)
2001 			return;
2002 		p = free_particles;
2003 		free_particles = p->next;
2004 		p->next = active_particles;
2005 		active_particles = p;
2006 
2007 		p->time = cl.time;
2008 
2009 		dist = sin(ltime + i)*64;
2010 		p->org[0] = origin[0] + bytedirs[i][0]*dist + forward[0]*BEAMLENGTH;
2011 		p->org[1] = origin[1] + bytedirs[i][1]*dist + forward[1]*BEAMLENGTH;
2012 		p->org[2] = origin[2] + bytedirs[i][2]*dist + forward[2]*BEAMLENGTH;
2013 
2014 		VectorClear (p->vel);
2015 		VectorClear (p->accel);
2016 
2017 #ifndef QMAX
2018 		p->color = 0;
2019 		p->colorvel = 0;
2020 #endif
2021 		p->alpha = 1;
2022 		p->alphavel = -100;
2023 	}
2024 }
2025 
CL_FlyEffect(centity_t * ent,vec3_t origin)2026 void CL_FlyEffect (centity_t *ent, vec3_t origin)
2027 {
2028 	int		n;
2029 	int		count;
2030 	int		starttime;
2031 
2032 	if (ent->fly_stoptime < cl.time)
2033 	{
2034 		starttime = cl.time;
2035 		ent->fly_stoptime = cl.time + 60000;
2036 	}
2037 	else
2038 	{
2039 		starttime = ent->fly_stoptime - 60000;
2040 	}
2041 
2042 	n = cl.time - starttime;
2043 	if (n < 20000)
2044 		count = n * 162 / 20000.0;
2045 	else
2046 	{
2047 		n = ent->fly_stoptime - cl.time;
2048 		if (n < 20000)
2049 			count = n * 162 / 20000.0;
2050 		else
2051 			count = 162;
2052 	}
2053 
2054 	CL_FlyParticles (origin, count);
2055 }
2056 
2057 
2058 /*
2059 ===============
2060 CL_BfgParticles
2061 ===============
2062 */
2063 
2064 #define	BEAMLENGTH			16
CL_BfgParticles(entity_t * ent)2065 void CL_BfgParticles (entity_t *ent)
2066 {
2067 	int			i;
2068 	cparticle_t	*p;
2069 	float		angle;
2070 	float		sr, sp, sy, cr, cp, cy;
2071 	vec3_t		forward;
2072 	float		dist = 64;
2073 	vec3_t		v;
2074 	float		ltime;
2075 
2076 	if (!avelocities[0][0])
2077 	{
2078 		for (i=0 ; i<NUMVERTEXNORMALS*3 ; i++)
2079 			avelocities[0][i] = (rand()&255) * 0.01;
2080 	}
2081 
2082 
2083 	ltime = (float)cl.time / 1000.0;
2084 	for (i=0 ; i<NUMVERTEXNORMALS ; i++)
2085 	{
2086 		angle = ltime * avelocities[i][0];
2087 		sy = sin(angle);
2088 		cy = cos(angle);
2089 		angle = ltime * avelocities[i][1];
2090 		sp = sin(angle);
2091 		cp = cos(angle);
2092 		angle = ltime * avelocities[i][2];
2093 		sr = sin(angle);
2094 		cr = cos(angle);
2095 
2096 		forward[0] = cp*cy;
2097 		forward[1] = cp*sy;
2098 		forward[2] = -sp;
2099 
2100 		if (!free_particles)
2101 			return;
2102 		p = free_particles;
2103 		free_particles = p->next;
2104 		p->next = active_particles;
2105 		active_particles = p;
2106 
2107 		p->time = cl.time;
2108 
2109 		dist = sin(ltime + i)*64;
2110 		p->org[0] = ent->origin[0] + bytedirs[i][0]*dist + forward[0]*BEAMLENGTH;
2111 		p->org[1] = ent->origin[1] + bytedirs[i][1]*dist + forward[1]*BEAMLENGTH;
2112 		p->org[2] = ent->origin[2] + bytedirs[i][2]*dist + forward[2]*BEAMLENGTH;
2113 
2114 		VectorClear (p->vel);
2115 		VectorClear (p->accel);
2116 
2117 		VectorSubtract (p->org, ent->origin, v);
2118 		dist = VectorLength(v) / 90.0;
2119 #ifndef QMAX
2120 		p->color = floor (0xd0 + dist * 7);
2121 		p->colorvel = 0;
2122 #endif
2123 		p->alpha = 1.0 - dist;
2124 		p->alphavel = -100;
2125 	}
2126 }
2127 
2128 
2129 /*
2130 ===============
2131 CL_TrapParticles
2132 ===============
2133 */
2134 // RAFAEL
CL_TrapParticles(entity_t * ent)2135 void CL_TrapParticles (entity_t *ent)
2136 {
2137 	vec3_t		move;
2138 	vec3_t		vec;
2139 	vec3_t		start, end;
2140 	float		len;
2141 	int			j;
2142 	cparticle_t	*p;
2143 	int			dec;
2144 
2145 	ent->origin[2]-=14;
2146 	VectorCopy (ent->origin, start);
2147 	VectorCopy (ent->origin, end);
2148 	end[2]+=64;
2149 
2150 	VectorCopy (start, move);
2151 	VectorSubtract (end, start, vec);
2152 	len = VectorNormalize (vec);
2153 
2154 	dec = 5;
2155 	VectorScale (vec, 5, vec);
2156 
2157 	// FIXME: this is a really silly way to have a loop
2158 	while (len > 0)
2159 	{
2160 		len -= dec;
2161 
2162 		if (!free_particles)
2163 			return;
2164 		p = free_particles;
2165 		free_particles = p->next;
2166 		p->next = active_particles;
2167 		active_particles = p;
2168 		VectorClear (p->accel);
2169 
2170 		p->time = cl.time;
2171 
2172 		p->alpha = 1.0;
2173 		p->alphavel = -1.0 / (0.3+frand()*0.2);
2174 #ifndef QMAX
2175 		p->color = 0xe0;
2176 #endif
2177 		for (j=0 ; j<3 ; j++)
2178 		{
2179 			p->org[j] = move[j] + crand();
2180 			p->vel[j] = crand()*15;
2181 			p->accel[j] = 0;
2182 		}
2183 		p->accel[2] = PARTICLE_GRAVITY;
2184 
2185 		VectorAdd (move, vec, move);
2186 	}
2187 
2188 	{
2189 
2190 
2191 	int			i, j, k;
2192 	cparticle_t	*p;
2193 	float		vel;
2194 	vec3_t		dir;
2195 	vec3_t		org;
2196 
2197 
2198 	ent->origin[2]+=14;
2199 	VectorCopy (ent->origin, org);
2200 
2201 
2202 	for (i=-2 ; i<=2 ; i+=4)
2203 		for (j=-2 ; j<=2 ; j+=4)
2204 			for (k=-2 ; k<=4 ; k+=4)
2205 			{
2206 				if (!free_particles)
2207 					return;
2208 				p = free_particles;
2209 				free_particles = p->next;
2210 				p->next = active_particles;
2211 				active_particles = p;
2212 
2213 				p->time = cl.time;
2214 #ifndef QMAX
2215 				p->color = 0xe0 + (rand()&3);
2216 #endif
2217 				p->alpha = 1.0;
2218 				p->alphavel = -1.0 / (0.3 + (rand()&7) * 0.02);
2219 
2220 				p->org[0] = org[0] + i + ((rand()&23) * crand());
2221 				p->org[1] = org[1] + j + ((rand()&23) * crand());
2222 				p->org[2] = org[2] + k + ((rand()&23) * crand());
2223 
2224 				dir[0] = j * 8;
2225 				dir[1] = i * 8;
2226 				dir[2] = k * 8;
2227 
2228 				VectorNormalize (dir);
2229 				vel = 50 + (rand()&63);
2230 				VectorScale (dir, vel, p->vel);
2231 
2232 				p->accel[0] = p->accel[1] = 0;
2233 				p->accel[2] = -PARTICLE_GRAVITY;
2234 			}
2235 	}
2236 }
2237 
2238 
2239 /*
2240 ===============
2241 CL_BFGExplosionParticles
2242 ===============
2243 */
2244 //FIXME combined with CL_ExplosionParticles
CL_BFGExplosionParticles(vec3_t org)2245 void CL_BFGExplosionParticles (vec3_t org)
2246 {
2247 	int			i, j;
2248 	cparticle_t	*p;
2249 
2250 	for (i=0 ; i<256 ; i++)
2251 	{
2252 		if (!free_particles)
2253 			return;
2254 		p = free_particles;
2255 		free_particles = p->next;
2256 		p->next = active_particles;
2257 		active_particles = p;
2258 
2259 		p->time = cl.time;
2260 #ifndef QMAX
2261 		p->color = 0xd0 + (rand()&7);
2262 #endif
2263 		for (j=0 ; j<3 ; j++)
2264 		{
2265 			p->org[j] = org[j] + ((rand()%32)-16);
2266 			p->vel[j] = (rand()%384)-192;
2267 		}
2268 
2269 		p->accel[0] = p->accel[1] = 0;
2270 		p->accel[2] = -PARTICLE_GRAVITY;
2271 		p->alpha = 1.0;
2272 
2273 		p->alphavel = -0.8 / (0.5 + frand()*0.3);
2274 	}
2275 }
2276 
2277 
2278 /*
2279 ===============
2280 CL_TeleportParticles
2281 
2282 ===============
2283 */
CL_TeleportParticles(vec3_t org)2284 void CL_TeleportParticles (vec3_t org)
2285 {
2286 	int			i, j, k;
2287 	cparticle_t	*p;
2288 	float		vel;
2289 	vec3_t		dir;
2290 
2291 	for (i=-16 ; i<=16 ; i+=4)
2292 		for (j=-16 ; j<=16 ; j+=4)
2293 			for (k=-16 ; k<=32 ; k+=4)
2294 			{
2295 				if (!free_particles)
2296 					return;
2297 				p = free_particles;
2298 				free_particles = p->next;
2299 				p->next = active_particles;
2300 				active_particles = p;
2301 
2302 				p->time = cl.time;
2303 #ifndef QMAX
2304 				p->color = 7 + (rand()&7);
2305 #endif
2306 				p->alpha = 1.0;
2307 				p->alphavel = -1.0 / (0.3 + (rand()&7) * 0.02);
2308 
2309 				p->org[0] = org[0] + i + (rand()&3);
2310 				p->org[1] = org[1] + j + (rand()&3);
2311 				p->org[2] = org[2] + k + (rand()&3);
2312 
2313 				dir[0] = j*8;
2314 				dir[1] = i*8;
2315 				dir[2] = k*8;
2316 
2317 				VectorNormalize (dir);
2318 				vel = 50 + (rand()&63);
2319 				VectorScale (dir, vel, p->vel);
2320 
2321 				p->accel[0] = p->accel[1] = 0;
2322 				p->accel[2] = -PARTICLE_GRAVITY;
2323 			}
2324 }
2325 
2326 
2327 /*
2328 ===============
2329 CL_AddParticles
2330 ===============
2331 */
CL_AddParticles(void)2332 void CL_AddParticles (void)
2333 {
2334 	cparticle_t		*p, *next;
2335 	float			alpha;
2336 	float			time, time2;
2337 	vec3_t			org;
2338 	int				color;
2339 	cparticle_t		*active, *tail;
2340 
2341 	active = NULL;
2342 	tail = NULL;
2343 
2344 	for (p=active_particles ; p ; p=next)
2345 	{
2346 		next = p->next;
2347 
2348 		// PMM - added INSTANT_PARTICLE handling for heat beam
2349 		if (p->alphavel != INSTANT_PARTICLE)
2350 		{
2351 			time = (cl.time - p->time)*0.001;
2352 			alpha = p->alpha + time*p->alphavel;
2353 			if (alpha <= 0)
2354 			{	// faded out
2355 				p->next = free_particles;
2356 				free_particles = p;
2357 				continue;
2358 			}
2359 		}
2360 		else
2361 		{
2362 			time = 0.0f;
2363 			alpha = p->alpha;
2364 		}
2365 
2366 		p->next = NULL;
2367 		if (!tail)
2368 			active = tail = p;
2369 		else
2370 		{
2371 			tail->next = p;
2372 			tail = p;
2373 		}
2374 
2375 		if (alpha > 1.0)
2376 			alpha = 1;
2377 #ifndef QMAX
2378 		color = p->color;
2379 #endif
2380 		time2 = time*time;
2381 
2382 		org[0] = p->org[0] + p->vel[0]*time + p->accel[0]*time2;
2383 		org[1] = p->org[1] + p->vel[1]*time + p->accel[1]*time2;
2384 		org[2] = p->org[2] + p->vel[2]*time + p->accel[2]*time2;
2385 
2386 		V_AddParticle (org, color, alpha);
2387 		// PMM
2388 		if (p->alphavel == INSTANT_PARTICLE)
2389 		{
2390 			p->alphavel = 0.0;
2391 			p->alpha = 0.0;
2392 		}
2393 	}
2394 
2395 	active_particles = active;
2396 }
2397 
2398 
2399 /*
2400 ==============
2401 CL_EntityEvent
2402 
2403 An entity has just been parsed that has an event value
2404 
2405 the female events are there for backwards compatability
2406 ==============
2407 */
2408 extern struct sfx_s	*cl_sfx_footsteps[4];
2409 
CL_EntityEvent(entity_state_t * ent)2410 void CL_EntityEvent (entity_state_t *ent)
2411 {
2412 	switch (ent->event)
2413 	{
2414 	case EV_ITEM_RESPAWN:
2415 		S_StartSound (NULL, ent->number, CHAN_WEAPON, S_RegisterSound("items/respawn1.wav"), 1, ATTN_IDLE, 0);
2416 		CL_ItemRespawnParticles (ent->origin);
2417 		break;
2418 	case EV_PLAYER_TELEPORT:
2419 		S_StartSound (NULL, ent->number, CHAN_WEAPON, S_RegisterSound("misc/tele1.wav"), 1, ATTN_IDLE, 0);
2420 		CL_TeleportParticles (ent->origin);
2421 		break;
2422 	case EV_FOOTSTEP:
2423 		if (cl_footsteps->value)
2424 			S_StartSound (NULL, ent->number, CHAN_BODY, cl_sfx_footsteps[rand()&3], 1, ATTN_NORM, 0);
2425 		break;
2426 	case EV_FALLSHORT:
2427 		S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("player/land1.wav"), 1, ATTN_NORM, 0);
2428 		break;
2429 	case EV_FALL:
2430 		S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("*fall2.wav"), 1, ATTN_NORM, 0);
2431 		break;
2432 	case EV_FALLFAR:
2433 		S_StartSound (NULL, ent->number, CHAN_AUTO, S_RegisterSound ("*fall1.wav"), 1, ATTN_NORM, 0);
2434 		break;
2435 	}
2436 }
2437 
2438 
2439 /*
2440 ==============
2441 CL_ClearEffects
2442 
2443 ==============
2444 */
CL_ClearEffects(void)2445 void CL_ClearEffects (void)
2446 {
2447 	CL_ClearParticles ();
2448 	CL_ClearDlights ();
2449 	CL_ClearLightStyles ();
2450 }
2451 
2452 
2453 #ifdef QMAX
2454 extern	struct model_s	*cl_mod_smoke;
2455 extern	struct model_s	*cl_mod_flash;
2456 
2457 //here i convert old 256 color to RGB -- hax0r l337
2458 const byte default_pal[768] =
2459 {
2460 0,0,0,15,15,15,31,31,31,47,47,47,63,63,63,75,75,75,91,91,91,107,107,107,123,123,123,139,139,139,155,155,155,171,171,171,187,187,187,203,203,203,219,219,219,235,235,235,99,75,35,91,67,31,83,63,31,79,59,27,71,55,27,63,47,
2461 23,59,43,23,51,39,19,47,35,19,43,31,19,39,27,15,35,23,15,27,19,11,23,15,11,19,15,7,15,11,7,95,95,111,91,91,103,91,83,95,87,79,91,83,75,83,79,71,75,71,63,67,63,59,59,59,55,55,51,47,47,47,43,43,39,
2462 39,39,35,35,35,27,27,27,23,23,23,19,19,19,143,119,83,123,99,67,115,91,59,103,79,47,207,151,75,167,123,59,139,103,47,111,83,39,235,159,39,203,139,35,175,119,31,147,99,27,119,79,23,91,59,15,63,39,11,35,23,7,167,59,43,
2463 159,47,35,151,43,27,139,39,19,127,31,15,115,23,11,103,23,7,87,19,0,75,15,0,67,15,0,59,15,0,51,11,0,43,11,0,35,11,0,27,7,0,19,7,0,123,95,75,115,87,67,107,83,63,103,79,59,95,71,55,87,67,51,83,63,
2464 47,75,55,43,67,51,39,63,47,35,55,39,27,47,35,23,39,27,19,31,23,15,23,15,11,15,11,7,111,59,23,95,55,23,83,47,23,67,43,23,55,35,19,39,27,15,27,19,11,15,11,7,179,91,79,191,123,111,203,155,147,215,187,183,203,
2465 215,223,179,199,211,159,183,195,135,167,183,115,151,167,91,135,155,71,119,139,47,103,127,23,83,111,19,75,103,15,67,91,11,63,83,7,55,75,7,47,63,7,39,51,0,31,43,0,23,31,0,15,19,0,7,11,0,0,0,139,87,87,131,79,79,
2466 123,71,71,115,67,67,107,59,59,99,51,51,91,47,47,87,43,43,75,35,35,63,31,31,51,27,27,43,19,19,31,15,15,19,11,11,11,7,7,0,0,0,151,159,123,143,151,115,135,139,107,127,131,99,119,123,95,115,115,87,107,107,79,99,99,
2467 71,91,91,67,79,79,59,67,67,51,55,55,43,47,47,35,35,35,27,23,23,19,15,15,11,159,75,63,147,67,55,139,59,47,127,55,39,119,47,35,107,43,27,99,35,23,87,31,19,79,27,15,67,23,11,55,19,11,43,15,7,31,11,7,23,
2468 7,0,11,0,0,0,0,0,119,123,207,111,115,195,103,107,183,99,99,167,91,91,155,83,87,143,75,79,127,71,71,115,63,63,103,55,55,87,47,47,75,39,39,63,35,31,47,27,23,35,19,15,23,11,7,7,155,171,123,143,159,111,135,151,99,
2469 123,139,87,115,131,75,103,119,67,95,111,59,87,103,51,75,91,39,63,79,27,55,67,19,47,59,11,35,47,7,27,35,0,19,23,0,11,15,0,0,255,0,35,231,15,63,211,27,83,187,39,95,167,47,95,143,51,95,123,51,255,255,255,255,255,
2470 211,255,255,167,255,255,127,255,255,83,255,255,39,255,235,31,255,215,23,255,191,15,255,171,7,255,147,0,239,127,0,227,107,0,211,87,0,199,71,0,183,59,0,171,43,0,155,31,0,143,23,0,127,15,0,115,7,0,95,0,0,71,0,0,47,
2471 0,0,27,0,0,239,0,0,55,55,255,255,0,0,0,0,255,43,43,35,27,27,23,19,19,15,235,151,127,195,115,83,159,87,51,123,63,27,235,211,199,199,171,155,167,139,119,135,107,87,159,91,83
2472 };
2473 
2474 //this initializes all particle images - mods play with this...
SetParticleImages(void)2475 void SetParticleImages (void)
2476 {
2477 	//tgas
2478 	re.SetParticlePicture(particle_generic,		"particles/basic.tga");
2479 	re.SetParticlePicture(particle_smoke,		"particles/smoke.tga");
2480 	re.SetParticlePicture(particle_blood,		"particles/blood.tga");
2481 	re.SetParticlePicture(particle_blooddrop,	"particles/blood_drop.tga");
2482 	re.SetParticlePicture(particle_blooddrip,	"particles/blood_drip.tga");
2483 	re.SetParticlePicture(particle_redblood,	"particles/blood_red.tga");
2484 	re.SetParticlePicture(particle_bubble,		"particles/bubble.tga");
2485 	re.SetParticlePicture(particle_lensflare,	"particles/lensflare.tga");
2486 	re.SetParticlePicture(particle_inferno,		"particles/inferno.tga");
2487 	re.SetParticlePicture(particle_footprint,	"particles/footprint.tga");
2488 	re.SetParticlePicture(particle_blaster,		"particles/blaster.tga");
2489 
2490 	//jpgs
2491 	re.SetParticlePicture(particle_shield,		"particles/shield.jpg");
2492 	re.SetParticlePicture(particle_beam,		"particles/beam.jpg");
2493 	re.SetParticlePicture(particle_lightning,	"particles/lightning.jpg");
2494 	re.SetParticlePicture(particle_lightflare,	"particles/lightflare.jpg");
2495 
2496 	//animations
2497 		//explosion
2498 		re.SetParticlePicture(particle_rexplosion1,	"particles/r_explod_1.tga");
2499 		re.SetParticlePicture(particle_rexplosion2,	"particles/r_explod_2.tga");
2500 		re.SetParticlePicture(particle_rexplosion3,	"particles/r_explod_3.tga");
2501 		re.SetParticlePicture(particle_rexplosion4,	"particles/r_explod_4.tga");
2502 		re.SetParticlePicture(particle_rexplosion5,	"particles/r_explod_5.tga");
2503 		re.SetParticlePicture(particle_rexplosion6,	"particles/r_explod_6.tga");
2504 		re.SetParticlePicture(particle_rexplosion7,	"particles/r_explod_7.tga");
2505 
2506 		re.SetParticlePicture(particle_dexplosion1,	"particles/d_explod_1.tga");
2507 		re.SetParticlePicture(particle_dexplosion2,	"particles/d_explod_2.tga");
2508 		re.SetParticlePicture(particle_dexplosion3,	"particles/d_explod_3.tga");
2509 
2510 }
2511 
2512 /*
2513 ===============
2514 CL_Explosion_Particle
2515 
2516 BOOM!
2517 ===============
2518 */
2519 
pExplosionThink(cparticle_t * p,vec3_t org,vec3_t angle,float * alpha,float * size,int * image,float * time)2520 void pExplosionThink (cparticle_t *p, vec3_t org, vec3_t angle, float *alpha, float *size, int *image, float *time)
2521 {
2522 
2523 	if (*alpha>.85)
2524 		*image = particle_rexplosion1;
2525 	else if (*alpha>.7)
2526 		*image = particle_rexplosion2;
2527 	else if (*alpha>.5)
2528 		*image = particle_rexplosion3;
2529 	else if (*alpha>.4)
2530 		*image = particle_rexplosion4;
2531 	else if (*alpha>.25)
2532 		*image = particle_rexplosion5;
2533 	else if (*alpha>.1)
2534 		*image = particle_rexplosion6;
2535 	else
2536 		*image = particle_rexplosion7;
2537 
2538 	*alpha *= 3.0;
2539 
2540 	if (*alpha > 1.0)
2541 		*alpha = 1;
2542 
2543 	p->thinknext = true;
2544 }
2545 
2546 #define EXPLODESTAININTESITY 75
CL_Explosion_Particle(vec3_t org,float size,qboolean large,qboolean rocket)2547 void CL_Explosion_Particle (vec3_t org, float size, qboolean large, qboolean rocket)
2548 {
2549 	cparticle_t *p;
2550 
2551 	if (large)
2552 	{
2553 		if (size)
2554 		{
2555 			re.AddStain(org, size, -EXPLODESTAININTESITY,-EXPLODESTAININTESITY,-EXPLODESTAININTESITY);
2556 		}
2557 		else
2558 		{
2559 			if (rocket)
2560 				re.AddStain(org, 45, -EXPLODESTAININTESITY,-EXPLODESTAININTESITY,-EXPLODESTAININTESITY);
2561 			else
2562 				re.AddStain(org, 65, -EXPLODESTAININTESITY,-EXPLODESTAININTESITY,-EXPLODESTAININTESITY);
2563 		}
2564 
2565 		p = setupParticle (
2566 					0,		0,		0,
2567 					org[0],	org[1],	org[2],
2568 					0,		0,		0,
2569 					0,		0,		0,
2570 					255,	255,	255,
2571 					0,		0,		0,
2572 					1,		(0.5+random()*0.5) * (rocket)? -2 : -1.5,
2573 					(size!=0)?size:(150-(!rocket)?75:0),	0,
2574 					particle_rexplosion1, //whatever :p
2575 					PART_DEPTHHACK_SHORT,
2576 					pExplosionThink, true);
2577 
2578 		if (p)
2579 		{	//smooth color blend :D
2580 			float lightsize = (large)? 1.0 : 0.75;
2581 
2582 			addParticleLight (p,
2583 						lightsize*250, 0,
2584 						1, 1, 1);
2585 			addParticleLight (p,
2586 						lightsize*265, 0,
2587 						1, 0.75, 0);
2588 			addParticleLight (p,
2589 						lightsize*285, 0,
2590 						1, 0.25, 0);
2591 			addParticleLight (p,
2592 						lightsize*300, 0,
2593 						1, 0, 0);
2594 		}
2595 	}
2596 /*	else //volumizers
2597 	{
2598 		setupParticle (
2599 					0,		0,		0,
2600 					org[0],	org[1],	org[2],
2601 					0,		0,		0,
2602 					0,		0,		0,
2603 					255,	175,	100,
2604 					0,		0,		0,
2605 					1,		1 * (rocket)? -1.5 : -1.25,
2606 					(size!=0)?size:(150-(!rocket)?75:0), 0,
2607 					particle_inferno,
2608 					0,
2609 					NULL,0);
2610 	}*/
2611 }
2612 
addParticleLight(cparticle_t * p,float light,float lightvel,float lcol0,float lcol1,float lcol2)2613 void addParticleLight (cparticle_t *p,
2614 				  float light, float lightvel,
2615 				  float lcol0, float lcol1, float lcol2)
2616 {
2617 	int i;
2618 
2619 	for (i=0; i<P_LIGHTS_MAX; i++)
2620 	{
2621 		cplight_t *plight = &p->lights[i];
2622 		if (!plight->isactive)
2623 		{
2624 			plight->isactive = true;
2625 			plight->light = light;
2626 			plight->lightvel = lightvel;
2627 			plight->lightcol[0] = lcol0;
2628 			plight->lightcol[1] = lcol1;
2629 			plight->lightcol[2] = lcol2;
2630 			return;
2631 		}
2632 	}
2633 }
2634 
2635 /*
2636 ===============
2637 CL_BlasterParticles
2638 
2639 Wall impact puffs
2640 ===============
2641 */
2642 #define pBlasterMaxSize 5
pBlasterThink(cparticle_t * p,vec3_t org,vec3_t angle,float * alpha,float * size,int * image,float * time)2643 void pBlasterThink (cparticle_t *p, vec3_t org, vec3_t angle, float *alpha, float *size, int *image, float *time)
2644 {
2645 	int i;
2646 	vec3_t len;
2647 	VectorSubtract(p->angle, org, len);
2648 
2649 	*size *= (float)(pBlasterMaxSize/VectorLength(len)) * 1.0/((4-*size));
2650 	if (*size > pBlasterMaxSize)
2651 		*size = pBlasterMaxSize;
2652 
2653 	p->thinknext = true;
2654 }
2655 
CL_BlasterParticlesMax(vec3_t org,vec3_t dir,int count)2656 void CL_BlasterParticlesMax (vec3_t org, vec3_t dir, int count)
2657 {
2658 	int			i;
2659 	float		d;
2660 	float speed = .75;
2661 
2662 	for (i=0 ; i<count ; i++)
2663 	{
2664 		d = rand()&5;
2665 		setupParticle (
2666 			org[0],	org[1],	org[2],
2667 			org[0]+((rand()&5)-2)+d*dir[0],	org[1]+((rand()&5)-2)+d*dir[1],	org[2]+((rand()&5)-2)+d*dir[2],
2668 			(dir[0]*75 + crand()*20)*speed,	(dir[1]*75 + crand()*20)*speed,	(dir[2]*75 + crand()*20)*speed,
2669 			0,		0,		0,
2670 			255,		150,		50,
2671 			0,	-90,	-30,
2672 			1,		-1.0 / (0.5 + frand()*0.3),
2673 			4,			-1,
2674 			particle_generic,
2675 			PART_GRAVITY,
2676 			pBlasterThink,true);
2677 	}
2678 }
2679 #endif
2680