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