vkQuake2 doxygen  1.0 dev
cl_newfx.c
Go to the documentation of this file.
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_newfx.c -- MORE entity effects parsing and management
21 
22 #include "client.h"
23 
26 extern int cl_numparticles;
27 extern cvar_t *vid_ref;
28 
30 
31 
32 /*
33 ======
34 vectoangles2 - this is duplicated in the game DLL, but I need it here.
35 ======
36 */
37 void vectoangles2 (vec3_t value1, vec3_t angles)
38 {
39  float forward;
40  float yaw, pitch;
41 
42  if (value1[1] == 0 && value1[0] == 0)
43  {
44  yaw = 0;
45  if (value1[2] > 0)
46  pitch = 90;
47  else
48  pitch = 270;
49  }
50  else
51  {
52  // PMM - fixed to correct for pitch of 0
53  if (value1[0])
54  yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
55  else if (value1[1] > 0)
56  yaw = 90;
57  else
58  yaw = 270;
59 
60  if (yaw < 0)
61  yaw += 360;
62 
63  forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]);
64  pitch = (atan2(value1[2], forward) * 180 / M_PI);
65  if (pitch < 0)
66  pitch += 360;
67  }
68 
69  angles[PITCH] = -pitch;
70  angles[YAW] = yaw;
71  angles[ROLL] = 0;
72 }
73 
74 //=============
75 //=============
76 void CL_Flashlight (int ent, vec3_t pos)
77 {
78  cdlight_t *dl;
79 
80  dl = CL_AllocDlight (ent);
81  VectorCopy (pos, dl->origin);
82  dl->radius = 400;
83  dl->minlight = 250;
84  dl->die = cl.time + 100;
85  dl->color[0] = 1;
86  dl->color[1] = 1;
87  dl->color[2] = 1;
88 }
89 
90 /*
91 ======
92 CL_ColorFlash - flash of light
93 ======
94 */
95 void CL_ColorFlash (vec3_t pos, int ent, int intensity, float r, float g, float b)
96 {
97  cdlight_t *dl;
98 
99  if((vidref_val == VIDREF_SOFT) && ((r < 0) || (g<0) || (b<0)))
100  {
101  intensity = -intensity;
102  r = -r;
103  g = -g;
104  b = -b;
105  }
106 
107  dl = CL_AllocDlight (ent);
108  VectorCopy (pos, dl->origin);
109  dl->radius = intensity;
110  dl->minlight = 250;
111  dl->die = cl.time + 100;
112  dl->color[0] = r;
113  dl->color[1] = g;
114  dl->color[2] = b;
115 }
116 
117 
118 /*
119 ======
120 CL_DebugTrail
121 ======
122 */
123 void CL_DebugTrail (vec3_t start, vec3_t end)
124 {
125  vec3_t move;
126  vec3_t vec;
127  float len;
128 // int j;
129  cparticle_t *p;
130  float dec;
131  vec3_t right, up;
132 // int i;
133 // float d, c, s;
134 // vec3_t dir;
135 
136  VectorCopy (start, move);
137  VectorSubtract (end, start, vec);
138  len = VectorNormalize (vec);
139 
140  MakeNormalVectors (vec, right, up);
141 
142 // VectorScale(vec, RT2_SKIP, vec);
143 
144 // dec = 1.0;
145 // dec = 0.75;
146  dec = 3;
147  VectorScale (vec, dec, vec);
148  VectorCopy (start, move);
149 
150  while (len > 0)
151  {
152  len -= dec;
153 
154  if (!free_particles)
155  return;
156  p = free_particles;
157  free_particles = p->next;
158  p->next = active_particles;
159  active_particles = p;
160 
161  p->time = cl.time;
162  VectorClear (p->accel);
163  VectorClear (p->vel);
164  p->alpha = 1.0;
165  p->alphavel = -0.1;
166 // p->alphavel = 0;
167  p->color = 0x74 + (rand()&7);
168  VectorCopy (move, p->org);
169 /*
170  for (j=0 ; j<3 ; j++)
171  {
172  p->org[j] = move[j] + crand()*2;
173  p->vel[j] = crand()*3;
174  p->accel[j] = 0;
175  }
176 */
177  VectorAdd (move, vec, move);
178  }
179 
180 }
181 
182 /*
183 ===============
184 CL_SmokeTrail
185 ===============
186 */
187 void CL_SmokeTrail (vec3_t start, vec3_t end, int colorStart, int colorRun, int spacing)
188 {
189  vec3_t move;
190  vec3_t vec;
191  float len;
192  int j;
193  cparticle_t *p;
194 
195  VectorCopy (start, move);
196  VectorSubtract (end, start, vec);
197  len = VectorNormalize (vec);
198 
199  VectorScale (vec, spacing, vec);
200 
201  // FIXME: this is a really silly way to have a loop
202  while (len > 0)
203  {
204  len -= spacing;
205 
206  if (!free_particles)
207  return;
208  p = free_particles;
209  free_particles = p->next;
210  p->next = active_particles;
211  active_particles = p;
212  VectorClear (p->accel);
213 
214  p->time = cl.time;
215 
216  p->alpha = 1.0;
217  p->alphavel = -1.0 / (1+frand()*0.5);
218  p->color = colorStart + (rand() % colorRun);
219  for (j=0 ; j<3 ; j++)
220  {
221  p->org[j] = move[j] + crand()*3;
222  p->accel[j] = 0;
223  }
224  p->vel[2] = 20 + crand()*5;
225 
226  VectorAdd (move, vec, move);
227  }
228 }
229 
230 void CL_ForceWall (vec3_t start, vec3_t end, int color)
231 {
232  vec3_t move;
233  vec3_t vec;
234  float len;
235  int j;
236  cparticle_t *p;
237 
238  VectorCopy (start, move);
239  VectorSubtract (end, start, vec);
240  len = VectorNormalize (vec);
241 
242  VectorScale (vec, 4, vec);
243 
244  // FIXME: this is a really silly way to have a loop
245  while (len > 0)
246  {
247  len -= 4;
248 
249  if (!free_particles)
250  return;
251 
252  if (frand() > 0.3)
253  {
254  p = free_particles;
255  free_particles = p->next;
256  p->next = active_particles;
257  active_particles = p;
258  VectorClear (p->accel);
259 
260  p->time = cl.time;
261 
262  p->alpha = 1.0;
263  p->alphavel = -1.0 / (3.0+frand()*0.5);
264  p->color = color;
265  for (j=0 ; j<3 ; j++)
266  {
267  p->org[j] = move[j] + crand()*3;
268  p->accel[j] = 0;
269  }
270  p->vel[0] = 0;
271  p->vel[1] = 0;
272  p->vel[2] = -40 - (crand()*10);
273  }
274 
275  VectorAdd (move, vec, move);
276  }
277 }
278 
279 void CL_FlameEffects (centity_t *ent, vec3_t origin)
280 {
281  int n, count;
282  int j;
283  cparticle_t *p;
284 
285  count = rand() & 0xF;
286 
287  for(n=0;n<count;n++)
288  {
289  if (!free_particles)
290  return;
291 
292  p = free_particles;
293  free_particles = p->next;
294  p->next = active_particles;
295  active_particles = p;
296 
297  VectorClear (p->accel);
298  p->time = cl.time;
299 
300  p->alpha = 1.0;
301  p->alphavel = -1.0 / (1+frand()*0.2);
302  p->color = 226 + (rand() % 4);
303  for (j=0 ; j<3 ; j++)
304  {
305  p->org[j] = origin[j] + crand()*5;
306  p->vel[j] = crand()*5;
307  }
308  p->vel[2] = crand() * -10;
309  p->accel[2] = -PARTICLE_GRAVITY;
310  }
311 
312  count = rand() & 0x7;
313 
314  for(n=0;n<count;n++)
315  {
316  if (!free_particles)
317  return;
318  p = free_particles;
319  free_particles = p->next;
320  p->next = active_particles;
321  active_particles = p;
322  VectorClear (p->accel);
323 
324  p->time = cl.time;
325 
326  p->alpha = 1.0;
327  p->alphavel = -1.0 / (1+frand()*0.5);
328  p->color = 0 + (rand() % 4);
329  for (j=0 ; j<3 ; j++)
330  {
331  p->org[j] = origin[j] + crand()*3;
332  }
333  p->vel[2] = 20 + crand()*5;
334  }
335 
336 }
337 
338 
339 /*
340 ===============
341 CL_GenericParticleEffect
342 ===============
343 */
344 void CL_GenericParticleEffect (vec3_t org, vec3_t dir, int color, int count, int numcolors, int dirspread, float alphavel)
345 {
346  int i, j;
347  cparticle_t *p;
348  float d;
349 
350  for (i=0 ; i<count ; i++)
351  {
352  if (!free_particles)
353  return;
354  p = free_particles;
355  free_particles = p->next;
356  p->next = active_particles;
357  active_particles = p;
358 
359  p->time = cl.time;
360  if (numcolors > 1)
361  p->color = color + (rand() & numcolors);
362  else
363  p->color = color;
364 
365  d = rand() & dirspread;
366  for (j=0 ; j<3 ; j++)
367  {
368  p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
369  p->vel[j] = crand()*20;
370  }
371 
372  p->accel[0] = p->accel[1] = 0;
373  p->accel[2] = -PARTICLE_GRAVITY;
374 // VectorCopy (accel, p->accel);
375  p->alpha = 1.0;
376 
377  p->alphavel = -1.0 / (0.5 + frand()*alphavel);
378 // p->alphavel = alphavel;
379  }
380 }
381 
382 /*
383 ===============
384 CL_BubbleTrail2 (lets you control the # of bubbles by setting the distance between the spawns)
385 
386 ===============
387 */
388 void CL_BubbleTrail2 (vec3_t start, vec3_t end, int dist)
389 {
390  vec3_t move;
391  vec3_t vec;
392  float len;
393  int i, j;
394  cparticle_t *p;
395  float dec;
396 
397  VectorCopy (start, move);
398  VectorSubtract (end, start, vec);
399  len = VectorNormalize (vec);
400 
401  dec = dist;
402  VectorScale (vec, dec, vec);
403 
404  for (i=0 ; i<len ; i+=dec)
405  {
406  if (!free_particles)
407  return;
408 
409  p = free_particles;
410  free_particles = p->next;
411  p->next = active_particles;
412  active_particles = p;
413 
414  VectorClear (p->accel);
415  p->time = cl.time;
416 
417  p->alpha = 1.0;
418  p->alphavel = -1.0 / (1+frand()*0.1);
419  p->color = 4 + (rand()&7);
420  for (j=0 ; j<3 ; j++)
421  {
422  p->org[j] = move[j] + crand()*2;
423  p->vel[j] = crand()*10;
424  }
425  p->org[2] -= 4;
426 // p->vel[2] += 6;
427  p->vel[2] += 20;
428 
429  VectorAdd (move, vec, move);
430  }
431 }
432 
433 //#define CORKSCREW 1
434 //#define DOUBLE_SCREW 1
435 #define RINGS 1
436 //#define SPRAY 1
437 
438 #ifdef CORKSCREW
439 void CL_Heatbeam (vec3_t start, vec3_t end)
440 {
441  vec3_t move;
442  vec3_t vec;
443  float len;
444  int j,k;
445  cparticle_t *p;
446  vec3_t right, up;
447  int i;
448  float d, c, s;
449  vec3_t dir;
450  float ltime;
451  float step = 5.0;
452 
453  VectorCopy (start, move);
454  VectorSubtract (end, start, vec);
455  len = VectorNormalize (vec);
456 
457 // MakeNormalVectors (vec, right, up);
459  VectorCopy (cl.v_up, up);
460  VectorMA (move, -1, right, move);
461  VectorMA (move, -1, up, move);
462 
463  VectorScale (vec, step, vec);
464  ltime = (float) cl.time/1000.0;
465 
466 // for (i=0 ; i<len ; i++)
467  for (i=0 ; i<len ; i+=step)
468  {
469  d = i * 0.1 - fmod(ltime,16.0)*M_PI;
470  c = cos(d)/1.75;
471  s = sin(d)/1.75;
472 #ifdef DOUBLE_SCREW
473  for (k=-1; k<2; k+=2)
474  {
475 #else
476  k=1;
477 #endif
478  if (!free_particles)
479  return;
480 
481  p = free_particles;
482  free_particles = p->next;
483  p->next = active_particles;
484  active_particles = p;
485 
486  p->time = cl.time;
487  VectorClear (p->accel);
488 
489  p->alpha = 0.5;
490  // p->alphavel = -1.0 / (1+frand()*0.2);
491  // only last one frame!
493  // p->color = 0x74 + (rand()&7);
494 // p->color = 223 - (rand()&7);
495  p->color = 223;
496 // p->color = 240;
497 
498  // trim it so it looks like it's starting at the origin
499  if (i < 10)
500  {
501  VectorScale (right, c*(i/10.0)*k, dir);
502  VectorMA (dir, s*(i/10.0)*k, up, dir);
503  }
504  else
505  {
506  VectorScale (right, c*k, dir);
507  VectorMA (dir, s*k, up, dir);
508  }
509 
510  for (j=0 ; j<3 ; j++)
511  {
512  p->org[j] = move[j] + dir[j]*3;
513  // p->vel[j] = dir[j]*6;
514  p->vel[j] = 0;
515  }
516 #ifdef DOUBLE_SCREW
517  }
518 #endif
519  VectorAdd (move, vec, move);
520  }
521 }
522 #endif
523 #ifdef RINGS
524 //void CL_Heatbeam (vec3_t start, vec3_t end)
526 {
527  vec3_t move;
528  vec3_t vec;
529  float len;
530  int j;
531  cparticle_t *p;
532  vec3_t right, up;
533  int i;
534  float c, s;
535  vec3_t dir;
536  float ltime;
537  float step = 32.0, rstep;
538  float start_pt;
539  float rot;
540  float variance;
541  vec3_t end;
542 
543  VectorMA (start, 4096, forward, end);
544 
545  VectorCopy (start, move);
546  VectorSubtract (end, start, vec);
547  len = VectorNormalize (vec);
548 
549  // FIXME - pmm - these might end up using old values?
550 // MakeNormalVectors (vec, right, up);
552  VectorCopy (cl.v_up, up);
553  if (vidref_val == VIDREF_GL)
554  { // GL mode
555  VectorMA (move, -0.5, right, move);
556  VectorMA (move, -0.5, up, move);
557  }
558  // otherwise assume SOFT
559 
560  ltime = (float) cl.time/1000.0;
561  start_pt = fmod(ltime*96.0,step);
562  VectorMA (move, start_pt, vec, move);
563 
564  VectorScale (vec, step, vec);
565 
566 // Com_Printf ("%f\n", ltime);
567  rstep = M_PI/10.0;
568  for (i=start_pt ; i<len ; i+=step)
569  {
570  if (i>step*5) // don't bother after the 5th ring
571  break;
572 
573  for (rot = 0; rot < M_PI*2; rot += rstep)
574  {
575 
576  if (!free_particles)
577  return;
578 
579  p = free_particles;
580  free_particles = p->next;
581  p->next = active_particles;
582  active_particles = p;
583 
584  p->time = cl.time;
585  VectorClear (p->accel);
586 // rot+= fmod(ltime, 12.0)*M_PI;
587 // c = cos(rot)/2.0;
588 // s = sin(rot)/2.0;
589 // variance = 0.4 + ((float)rand()/(float)RAND_MAX) *0.2;
590  variance = 0.5;
591  c = cos(rot)*variance;
592  s = sin(rot)*variance;
593 
594  // trim it so it looks like it's starting at the origin
595  if (i < 10)
596  {
597  VectorScale (right, c*(i/10.0), dir);
598  VectorMA (dir, s*(i/10.0), up, dir);
599  }
600  else
601  {
602  VectorScale (right, c, dir);
603  VectorMA (dir, s, up, dir);
604  }
605 
606  p->alpha = 0.5;
607  // p->alphavel = -1.0 / (1+frand()*0.2);
608  p->alphavel = -1000.0;
609  // p->color = 0x74 + (rand()&7);
610  p->color = 223 - (rand()&7);
611  for (j=0 ; j<3 ; j++)
612  {
613  p->org[j] = move[j] + dir[j]*3;
614  // p->vel[j] = dir[j]*6;
615  p->vel[j] = 0;
616  }
617  }
618  VectorAdd (move, vec, move);
619  }
620 }
621 #endif
622 #ifdef SPRAY
623 void CL_Heatbeam (vec3_t start, vec3_t end)
624 {
625  vec3_t move;
626  vec3_t vec;
627  float len;
628  int j;
629  cparticle_t *p;
631  int i;
632  float d, c, s;
633  vec3_t dir;
634  float ltime;
635  float step = 32.0, rstep;
636  float start_pt;
637  float rot;
638 
639  VectorCopy (start, move);
640  VectorSubtract (end, start, vec);
641  len = VectorNormalize (vec);
642 
643 // MakeNormalVectors (vec, right, up);
646  VectorCopy (cl.v_up, up);
647  VectorMA (move, -0.5, right, move);
648  VectorMA (move, -0.5, up, move);
649 
650  for (i=0; i<8; i++)
651  {
652  if (!free_particles)
653  return;
654 
655  p = free_particles;
656  free_particles = p->next;
657  p->next = active_particles;
658  active_particles = p;
659 
660  p->time = cl.time;
661  VectorClear (p->accel);
662 
663  d = crand()*M_PI;
664  c = cos(d)*30;
665  s = sin(d)*30;
666 
667  p->alpha = 1.0;
668  p->alphavel = -5.0 / (1+frand());
669  p->color = 223 - (rand()&7);
670 
671  for (j=0 ; j<3 ; j++)
672  {
673  p->org[j] = move[j];
674  }
675  VectorScale (vec, 450, p->vel);
676  VectorMA (p->vel, c, right, p->vel);
677  VectorMA (p->vel, s, up, p->vel);
678  }
679 /*
680 
681  ltime = (float) cl.time/1000.0;
682  start_pt = fmod(ltime*16.0,step);
683  VectorMA (move, start_pt, vec, move);
684 
685  VectorScale (vec, step, vec);
686 
687 // Com_Printf ("%f\n", ltime);
688  rstep = M_PI/12.0;
689  for (i=start_pt ; i<len ; i+=step)
690  {
691  if (i>step*5) // don't bother after the 5th ring
692  break;
693 
694  for (rot = 0; rot < M_PI*2; rot += rstep)
695  {
696  if (!free_particles)
697  return;
698 
699  p = free_particles;
700  free_particles = p->next;
701  p->next = active_particles;
702  active_particles = p;
703 
704  p->time = cl.time;
705  VectorClear (p->accel);
706 // rot+= fmod(ltime, 12.0)*M_PI;
707 // c = cos(rot)/2.0;
708 // s = sin(rot)/2.0;
709  c = cos(rot)/1.5;
710  s = sin(rot)/1.5;
711 
712  // trim it so it looks like it's starting at the origin
713  if (i < 10)
714  {
715  VectorScale (right, c*(i/10.0), dir);
716  VectorMA (dir, s*(i/10.0), up, dir);
717  }
718  else
719  {
720  VectorScale (right, c, dir);
721  VectorMA (dir, s, up, dir);
722  }
723 
724  p->alpha = 0.5;
725  // p->alphavel = -1.0 / (1+frand()*0.2);
726  p->alphavel = -1000.0;
727  // p->color = 0x74 + (rand()&7);
728  p->color = 223 - (rand()&7);
729  for (j=0 ; j<3 ; j++)
730  {
731  p->org[j] = move[j] + dir[j]*3;
732  // p->vel[j] = dir[j]*6;
733  p->vel[j] = 0;
734  }
735  }
736  VectorAdd (move, vec, move);
737  }
738 */
739 }
740 #endif
741 
742 /*
743 ===============
744 CL_ParticleSteamEffect
745 
746 Puffs with velocity along direction, with some randomness thrown in
747 ===============
748 */
749 void CL_ParticleSteamEffect (vec3_t org, vec3_t dir, int color, int count, int magnitude)
750 {
751  int i, j;
752  cparticle_t *p;
753  float d;
754  vec3_t r, u;
755 
756 // vectoangles2 (dir, angle_dir);
757 // AngleVectors (angle_dir, f, r, u);
758 
759  MakeNormalVectors (dir, r, u);
760 
761  for (i=0 ; i<count ; i++)
762  {
763  if (!free_particles)
764  return;
765  p = free_particles;
766  free_particles = p->next;
767  p->next = active_particles;
768  active_particles = p;
769 
770  p->time = cl.time;
771  p->color = color + (rand()&7);
772 
773  for (j=0 ; j<3 ; j++)
774  {
775  p->org[j] = org[j] + magnitude*0.1*crand();
776 // p->vel[j] = dir[j]*magnitude;
777  }
778  VectorScale (dir, magnitude, p->vel);
779  d = crand()*magnitude/3;
780  VectorMA (p->vel, d, r, p->vel);
781  d = crand()*magnitude/3;
782  VectorMA (p->vel, d, u, p->vel);
783 
784  p->accel[0] = p->accel[1] = 0;
785  p->accel[2] = -PARTICLE_GRAVITY/2;
786  p->alpha = 1.0;
787 
788  p->alphavel = -1.0 / (0.5 + frand()*0.3);
789  }
790 }
791 
793 //vec3_t org, vec3_t dir, int color, int count, int magnitude)
794 {
795  int i, j;
796  cparticle_t *p;
797  float d;
798  vec3_t r, u;
799  vec3_t dir;
800 
801 // vectoangles2 (dir, angle_dir);
802 // AngleVectors (angle_dir, f, r, u);
803 
804  VectorCopy (self->dir, dir);
805  MakeNormalVectors (dir, r, u);
806 
807  for (i=0 ; i<self->count ; i++)
808  {
809  if (!free_particles)
810  return;
811  p = free_particles;
812  free_particles = p->next;
813  p->next = active_particles;
814  active_particles = p;
815 
816  p->time = cl.time;
817  p->color = self->color + (rand()&7);
818 
819  for (j=0 ; j<3 ; j++)
820  {
821  p->org[j] = self->org[j] + self->magnitude*0.1*crand();
822 // p->vel[j] = dir[j]*magnitude;
823  }
824  VectorScale (dir, self->magnitude, p->vel);
825  d = crand()*self->magnitude/3;
826  VectorMA (p->vel, d, r, p->vel);
827  d = crand()*self->magnitude/3;
828  VectorMA (p->vel, d, u, p->vel);
829 
830  p->accel[0] = p->accel[1] = 0;
831  p->accel[2] = -PARTICLE_GRAVITY/2;
832  p->alpha = 1.0;
833 
834  p->alphavel = -1.0 / (0.5 + frand()*0.3);
835  }
836  self->nextthink += self->thinkinterval;
837 }
838 
839 /*
840 ===============
841 CL_TrackerTrail
842 ===============
843 */
844 void CL_TrackerTrail (vec3_t start, vec3_t end, int particleColor)
845 {
846  vec3_t move;
847  vec3_t vec;
848  vec3_t forward,right,up,angle_dir;
849  float len;
850  int j;
851  cparticle_t *p;
852  int dec;
853  float dist;
854 
855  VectorCopy (start, move);
856  VectorSubtract (end, start, vec);
857  len = VectorNormalize (vec);
858 
859  VectorCopy(vec, forward);
860  vectoangles2 (forward, angle_dir);
861  AngleVectors (angle_dir, forward, right, up);
862 
863  dec = 3;
864  VectorScale (vec, 3, vec);
865 
866  // FIXME: this is a really silly way to have a loop
867  while (len > 0)
868  {
869  len -= dec;
870 
871  if (!free_particles)
872  return;
873  p = free_particles;
874  free_particles = p->next;
875  p->next = active_particles;
876  active_particles = p;
877  VectorClear (p->accel);
878 
879  p->time = cl.time;
880 
881  p->alpha = 1.0;
882  p->alphavel = -2.0;
883  p->color = particleColor;
884  dist = DotProduct(move, forward);
885  VectorMA(move, 8 * cos(dist), up, p->org);
886  for (j=0 ; j<3 ; j++)
887  {
888 // p->org[j] = move[j] + crand();
889  p->vel[j] = 0;
890  p->accel[j] = 0;
891  }
892  p->vel[2] = 5;
893 
894  VectorAdd (move, vec, move);
895  }
896 }
897 
899 {
900  vec3_t dir;
901  int i;
902  cparticle_t *p;
903 
904  for(i=0;i<300;i++)
905  {
906  if (!free_particles)
907  return;
908  p = free_particles;
909  free_particles = p->next;
910  p->next = active_particles;
911  active_particles = p;
912  VectorClear (p->accel);
913 
914  p->time = cl.time;
915 
916  p->alpha = 1.0;
918  p->color = 0;
919 
920  dir[0] = crand();
921  dir[1] = crand();
922  dir[2] = crand();
923  VectorNormalize(dir);
924 
925  VectorMA(origin, 40, dir, p->org);
926  }
927 }
928 
930 {
931  vec3_t dir;
932  int i;
933  cparticle_t *p;
934 
935  for(i=0;i<40;i++)
936  {
937  if (!free_particles)
938  return;
939  p = free_particles;
940  free_particles = p->next;
941  p->next = active_particles;
942  active_particles = p;
943  VectorClear (p->accel);
944 
945  p->time = cl.time;
946 
947  p->alpha = 1.0;
949  p->color = 0xe0;
950 
951  dir[0] = crand();
952  dir[1] = crand();
953  dir[2] = crand();
954  VectorNormalize(dir);
955 
956  VectorMA(origin, 10, dir, p->org);
957 // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p->org);
958  }
959 }
960 
962 {
963  vec3_t dir;
964  int i;
965  cparticle_t *p;
966  static int colortable[4] = {2*8,13*8,21*8,18*8};
967  float ratio;
968 
969  ratio = 1.0 - (((float)self->endtime - (float)cl.time)/2100.0);
970 
971  for(i=0;i<300;i++)
972  {
973  if (!free_particles)
974  return;
975  p = free_particles;
976  free_particles = p->next;
977  p->next = active_particles;
978  active_particles = p;
979  VectorClear (p->accel);
980 
981  p->time = cl.time;
982 
983  p->alpha = 1.0;
985  p->color = colortable[rand()&3];
986 
987  dir[0] = crand();
988  dir[1] = crand();
989  dir[2] = crand();
990  VectorNormalize(dir);
991 
992  VectorMA(self->org, (45.0 * ratio), dir, p->org);
993 // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p->org);
994  }
995 }
996 
998 {
999  vec3_t dir;
1000  int i;
1001  cparticle_t *p;
1002  static int colortable[4] = {110, 112, 114, 116};
1003  float ratio;
1004 
1005  ratio = 1.0 - (((float)self->endtime - (float)cl.time)/1000.0);
1006 
1007  for(i=0;i<700;i++)
1008  {
1009  if (!free_particles)
1010  return;
1011  p = free_particles;
1012  free_particles = p->next;
1013  p->next = active_particles;
1014  active_particles = p;
1015  VectorClear (p->accel);
1016 
1017  p->time = cl.time;
1018 
1019  p->alpha = 1.0;
1021  p->color = colortable[rand()&3];
1022 
1023  dir[0] = crand();
1024  dir[1] = crand();
1025  dir[2] = crand();
1026  VectorNormalize(dir);
1027 
1028  VectorMA(self->org, (200.0 * ratio), dir, p->org);
1029 // VectorMA(origin, 10*(((rand () & 0x7fff) / ((float)0x7fff))), dir, p->org);
1030  }
1031 }
1032 
1034 {
1035  static int colortable[4] = {2*8,13*8,21*8,18*8};
1036  int i;
1037  cparticle_t *p;
1038  vec3_t dir;
1039 
1040  for (i=0 ; i<256 ; i++)
1041  {
1042  if (!free_particles)
1043  return;
1044  p = free_particles;
1045  free_particles = p->next;
1046  p->next = active_particles;
1047  active_particles = p;
1048 
1049  p->time = cl.time;
1050  p->color = colortable[rand()&3];
1051 
1052  dir[0] = crand();
1053  dir[1] = crand();
1054  dir[2] = crand();
1055  VectorNormalize(dir);
1056  VectorMA(org, 45.0, dir, p->org);
1057  VectorMA(vec3_origin, 40.0, dir, p->vel);
1058 
1059  p->accel[0] = p->accel[1] = 0;
1060  p->alpha = 1.0;
1061 
1062  p->alphavel = -0.8 / (0.5 + frand()*0.3);
1063  }
1064 
1065 }
1066 
1068 {
1069  vec3_t dir, backdir;
1070  int i;
1071  cparticle_t *p;
1072 
1073  for(i=0;i<300;i++)
1074  {
1075  if (!free_particles)
1076  return;
1077  p = free_particles;
1078  free_particles = p->next;
1079  p->next = active_particles;
1080  active_particles = p;
1081  VectorClear (p->accel);
1082 
1083  p->time = cl.time;
1084 
1085  p->alpha = 1.0;
1086  p->alphavel = -1.0;
1087  p->color = 0;
1088 
1089  dir[0] = crand();
1090  dir[1] = crand();
1091  dir[2] = crand();
1092  VectorNormalize(dir);
1093  VectorScale(dir, -1, backdir);
1094 
1095  VectorMA(origin, 64, dir, p->org);
1096  VectorScale(backdir, 64, p->vel);
1097  }
1098 
1099 }
1100 
1101 /*
1102 ===============
1103 CL_TagTrail
1104 
1105 ===============
1106 */
1107 void CL_TagTrail (vec3_t start, vec3_t end, float color)
1108 {
1109  vec3_t move;
1110  vec3_t vec;
1111  float len;
1112  int j;
1113  cparticle_t *p;
1114  int dec;
1115 
1116  VectorCopy (start, move);
1117  VectorSubtract (end, start, vec);
1118  len = VectorNormalize (vec);
1119 
1120  dec = 5;
1121  VectorScale (vec, 5, vec);
1122 
1123  while (len >= 0)
1124  {
1125  len -= dec;
1126 
1127  if (!free_particles)
1128  return;
1129  p = free_particles;
1130  free_particles = p->next;
1131  p->next = active_particles;
1132  active_particles = p;
1133  VectorClear (p->accel);
1134 
1135  p->time = cl.time;
1136 
1137  p->alpha = 1.0;
1138  p->alphavel = -1.0 / (0.8+frand()*0.2);
1139  p->color = color;
1140  for (j=0 ; j<3 ; j++)
1141  {
1142  p->org[j] = move[j] + crand()*16;
1143  p->vel[j] = crand()*5;
1144  p->accel[j] = 0;
1145  }
1146 
1147  VectorAdd (move, vec, move);
1148  }
1149 }
1150 
1151 /*
1152 ===============
1153 CL_ColorExplosionParticles
1154 ===============
1155 */
1156 void CL_ColorExplosionParticles (vec3_t org, int color, int run)
1157 {
1158  int i, j;
1159  cparticle_t *p;
1160 
1161  for (i=0 ; i<128 ; i++)
1162  {
1163  if (!free_particles)
1164  return;
1165  p = free_particles;
1166  free_particles = p->next;
1167  p->next = active_particles;
1168  active_particles = p;
1169 
1170  p->time = cl.time;
1171  p->color = color + (rand() % run);
1172 
1173  for (j=0 ; j<3 ; j++)
1174  {
1175  p->org[j] = org[j] + ((rand()%32)-16);
1176  p->vel[j] = (rand()%256)-128;
1177  }
1178 
1179  p->accel[0] = p->accel[1] = 0;
1180  p->accel[2] = -PARTICLE_GRAVITY;
1181  p->alpha = 1.0;
1182 
1183  p->alphavel = -0.4 / (0.6 + frand()*0.2);
1184  }
1185 }
1186 
1187 /*
1188 ===============
1189 CL_ParticleSmokeEffect - like the steam effect, but unaffected by gravity
1190 ===============
1191 */
1192 void CL_ParticleSmokeEffect (vec3_t org, vec3_t dir, int color, int count, int magnitude)
1193 {
1194  int i, j;
1195  cparticle_t *p;
1196  float d;
1197  vec3_t r, u;
1198 
1199  MakeNormalVectors (dir, r, u);
1200 
1201  for (i=0 ; i<count ; i++)
1202  {
1203  if (!free_particles)
1204  return;
1205  p = free_particles;
1206  free_particles = p->next;
1207  p->next = active_particles;
1208  active_particles = p;
1209 
1210  p->time = cl.time;
1211  p->color = color + (rand()&7);
1212 
1213  for (j=0 ; j<3 ; j++)
1214  {
1215  p->org[j] = org[j] + magnitude*0.1*crand();
1216 // p->vel[j] = dir[j]*magnitude;
1217  }
1218  VectorScale (dir, magnitude, p->vel);
1219  d = crand()*magnitude/3;
1220  VectorMA (p->vel, d, r, p->vel);
1221  d = crand()*magnitude/3;
1222  VectorMA (p->vel, d, u, p->vel);
1223 
1224  p->accel[0] = p->accel[1] = p->accel[2] = 0;
1225  p->alpha = 1.0;
1226 
1227  p->alphavel = -1.0 / (0.5 + frand()*0.3);
1228  }
1229 }
1230 
1231 /*
1232 ===============
1233 CL_BlasterParticles2
1234 
1235 Wall impact puffs (Green)
1236 ===============
1237 */
1238 void CL_BlasterParticles2 (vec3_t org, vec3_t dir, unsigned int color)
1239 {
1240  int i, j;
1241  cparticle_t *p;
1242  float d;
1243  int count;
1244 
1245  count = 40;
1246  for (i=0 ; i<count ; i++)
1247  {
1248  if (!free_particles)
1249  return;
1250  p = free_particles;
1251  free_particles = p->next;
1252  p->next = active_particles;
1253  active_particles = p;
1254 
1255  p->time = cl.time;
1256  p->color = color + (rand()&7);
1257 
1258  d = rand()&15;
1259  for (j=0 ; j<3 ; j++)
1260  {
1261  p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
1262  p->vel[j] = dir[j] * 30 + crand()*40;
1263  }
1264 
1265  p->accel[0] = p->accel[1] = 0;
1266  p->accel[2] = -PARTICLE_GRAVITY;
1267  p->alpha = 1.0;
1268 
1269  p->alphavel = -1.0 / (0.5 + frand()*0.3);
1270  }
1271 }
1272 
1273 /*
1274 ===============
1275 CL_BlasterTrail2
1276 
1277 Green!
1278 ===============
1279 */
1280 void CL_BlasterTrail2 (vec3_t start, vec3_t end)
1281 {
1282  vec3_t move;
1283  vec3_t vec;
1284  float len;
1285  int j;
1286  cparticle_t *p;
1287  int dec;
1288 
1289  VectorCopy (start, move);
1290  VectorSubtract (end, start, vec);
1291  len = VectorNormalize (vec);
1292 
1293  dec = 5;
1294  VectorScale (vec, 5, vec);
1295 
1296  // FIXME: this is a really silly way to have a loop
1297  while (len > 0)
1298  {
1299  len -= dec;
1300 
1301  if (!free_particles)
1302  return;
1303  p = free_particles;
1304  free_particles = p->next;
1305  p->next = active_particles;
1306  active_particles = p;
1307  VectorClear (p->accel);
1308 
1309  p->time = cl.time;
1310 
1311  p->alpha = 1.0;
1312  p->alphavel = -1.0 / (0.3+frand()*0.2);
1313  p->color = 0xd0;
1314  for (j=0 ; j<3 ; j++)
1315  {
1316  p->org[j] = move[j] + crand();
1317  p->vel[j] = crand()*5;
1318  p->accel[j] = 0;
1319  }
1320 
1321  VectorAdd (move, vec, move);
1322  }
1323 }
CL_SmokeTrail
void CL_SmokeTrail(vec3_t start, vec3_t end, int colorStart, int colorRun, int spacing)
Definition: cl_newfx.c:187
particle_s::vel
vec3_t vel
Definition: client.h:364
YAW
#define YAW
Definition: q_shared.h:73
CL_WidowSplash
void CL_WidowSplash(vec3_t org)
Definition: cl_newfx.c:1033
VectorSubtract
#define VectorSubtract(a, b, c)
Definition: q_shared.h:163
cdlight_t::radius
float radius
Definition: client.h:300
client_state_t::v_forward
vec3_t v_forward
Definition: client.h:133
CL_ForceWall
void CL_ForceWall(vec3_t start, vec3_t end, int color)
Definition: cl_newfx.c:230
particle_s::time
float time
Definition: client.h:361
client_state_t::v_up
vec3_t v_up
Definition: client.h:133
cl_sustain
Definition: client.h:327
particle_s::accel
vec3_t accel
Definition: client.h:365
CL_AllocDlight
cdlight_t * CL_AllocDlight(int key)
Definition: cl_fx.c:149
frand
float frand(void)
Definition: common.c:1375
cdlight_t::die
float die
Definition: client.h:301
cdlight_t
Definition: client.h:295
CL_ParticleSmokeEffect
void CL_ParticleSmokeEffect(vec3_t org, vec3_t dir, int color, int count, int magnitude)
Definition: cl_newfx.c:1192
VectorScale
void VectorScale(vec3_t in, vec_t scale, vec3_t out)
Definition: q_shared.c:782
VectorClear
#define VectorClear(a)
Definition: q_shared.h:166
i
int i
Definition: q_shared.c:305
CL_Tracker_Shell
void CL_Tracker_Shell(vec3_t origin)
Definition: cl_newfx.c:898
particle_s::org
vec3_t org
Definition: client.h:363
PITCH
#define PITCH
Definition: q_shared.h:72
CL_DebugTrail
void CL_DebugTrail(vec3_t start, vec3_t end)
Definition: cl_newfx.c:123
CL_GenericParticleEffect
void CL_GenericParticleEffect(vec3_t org, vec3_t dir, int color, int count, int numcolors, int dirspread, float alphavel)
Definition: cl_newfx.c:344
M_PI
#define M_PI
Definition: q_shared.h:142
free_particles
cparticle_t * free_particles
Definition: cl_newfx.c:24
CL_Heatbeam
void CL_Heatbeam(vec3_t start, vec3_t forward)
Definition: cl_newfx.c:525
cvar_s
Definition: q_shared.h:324
intensity
cvar_t * intensity
Definition: gl_image.c:31
vectoangles2
void vectoangles2(vec3_t value1, vec3_t angles)
Definition: cl_newfx.c:37
MakeNormalVectors
void MakeNormalVectors(vec3_t forward, vec3_t right, vec3_t up)
Definition: cl_fx.c:1534
j
GLint j
Definition: qgl_win.c:150
particle_s::next
struct particle_s * next
Definition: client.h:359
CL_Widowbeamout
void CL_Widowbeamout(cl_sustain_t *self)
Definition: cl_newfx.c:961
AngleVectors
void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition: q_shared.c:93
active_particles
cparticle_t * active_particles
Definition: cl_fx.c:885
particle_s::alphavel
float alphavel
Definition: client.h:369
u
static int u
Definition: r_part.c:472
particle_s
Definition: client.h:357
r
GLdouble GLdouble r
Definition: qgl_win.c:336
VIDREF_GL
#define VIDREF_GL
Definition: q_shared.h:1203
centity_t
Definition: client.h:55
ROLL
#define ROLL
Definition: q_shared.h:74
forward
static vec3_t forward
Definition: p_view.c:29
CL_TagTrail
void CL_TagTrail(vec3_t start, vec3_t end, float color)
Definition: cl_newfx.c:1107
CL_TrackerTrail
void CL_TrackerTrail(vec3_t start, vec3_t end, int particleColor)
Definition: cl_newfx.c:844
CL_Flashlight
void CL_Flashlight(int ent, vec3_t pos)
Definition: cl_newfx.c:76
DotProduct
#define DotProduct(x, y)
Definition: q_shared.h:162
particle_s::alpha
float alpha
Definition: client.h:368
cdlight_t::color
vec3_t color
Definition: client.h:298
CL_ColorFlash
void CL_ColorFlash(vec3_t pos, int ent, int intensity, float r, float g, float b)
Definition: cl_newfx.c:95
VectorNormalize
vec_t VectorNormalize(vec3_t v)
Definition: q_shared.c:681
CL_MonsterPlasma_Shell
void CL_MonsterPlasma_Shell(vec3_t origin)
Definition: cl_newfx.c:929
VIDREF_SOFT
#define VIDREF_SOFT
Definition: q_shared.h:1204
CL_Tracker_Explode
void CL_Tracker_Explode(vec3_t origin)
Definition: cl_newfx.c:1067
client_state_t::time
int time
Definition: client.h:127
CL_ColorExplosionParticles
void CL_ColorExplosionParticles(vec3_t org, int color, int run)
Definition: cl_newfx.c:1156
CL_ParticleSteamEffect2
void CL_ParticleSteamEffect2(cl_sustain_t *self)
Definition: cl_newfx.c:792
VectorAdd
#define VectorAdd(a, b, c)
Definition: q_shared.h:164
s
static fixed16_t s
Definition: r_scan.c:30
CL_Nukeblast
void CL_Nukeblast(cl_sustain_t *self)
Definition: cl_newfx.c:997
client_state_t::v_right
vec3_t v_right
Definition: client.h:133
VectorCopy
#define VectorCopy(a, b)
Definition: q_shared.h:165
INSTANT_PARTICLE
#define INSTANT_PARTICLE
Definition: client.h:376
vec3_origin
vec3_t vec3_origin
Definition: q_shared.c:24
up
static vec3_t up
Definition: p_view.c:29
sqrt
double sqrt(double x)
VectorMA
void VectorMA(vec3_t veca, float scale, vec3_t vecb, vec3_t vecc)
Definition: q_shared.c:719
CL_FlameEffects
void CL_FlameEffects(centity_t *ent, vec3_t origin)
Definition: cl_newfx.c:279
cdlight_t::minlight
float minlight
Definition: client.h:303
particles
cparticle_t particles[MAX_PARTICLES]
Definition: cl_fx.c:887
CL_BubbleTrail2
void CL_BubbleTrail2(vec3_t start, vec3_t end, int dist)
Definition: cl_newfx.c:388
cdlight_t::origin
vec3_t origin
Definition: client.h:299
vid_ref
cvar_t * vid_ref
Definition: vid_dll.c:44
right
GLdouble right
Definition: qgl_win.c:159
CL_BlasterTrail2
void CL_BlasterTrail2(vec3_t start, vec3_t end)
Definition: cl_newfx.c:1280
CL_BlasterParticles2
void CL_BlasterParticles2(vec3_t org, vec3_t dir, unsigned int color)
Definition: cl_newfx.c:1238
crand
float crand(void)
Definition: common.c:1380
cl
client_state_t cl
Definition: cl_main.c:91
PARTICLE_GRAVITY
#define PARTICLE_GRAVITY
Definition: client.h:373
vec3_t
vec_t vec3_t[3]
Definition: q_shared.h:134
vidref_val
int vidref_val
Definition: cl_ents.c:28
client.h
cl_numparticles
int cl_numparticles
Definition: cl_fx.c:888
particle_s::color
float color
Definition: client.h:366
count
GLint GLsizei count
Definition: qgl_win.c:128
CL_ParticleSteamEffect
void CL_ParticleSteamEffect(vec3_t org, vec3_t dir, int color, int count, int magnitude)
Definition: cl_newfx.c:749
MAX_PARTICLES
#define MAX_PARTICLES
Definition: ref.h:27