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