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