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
24 extern void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up);
25
26 cparticle_t *setupParticle (
27 float angle0, float angle1, float angle2,
28 float org0, float org1, float org2,
29 float vel0, float vel1, float vel2,
30 float accel0, float accel1, float accel2,
31 float color0, float color1, float color2,
32 float colorvel0, float colorvel1, float colorvel2,
33 float alpha, float alphavel,
34 int blendfunc_src, int blendfunc_dst,
35 float size, float sizevel,
36 int image,
37 int flags,
38 void (*think)(cparticle_t *p, vec3_t org, vec3_t angle, float *alpha, float *size, int *image, float *time),
39 qboolean thinknext);
40
41 /*
42 ======
43 vectoangles2 - this is duplicated in the game DLL, but I need it here.
44 ======
45 */
vectoangles2(vec3_t value1,vec3_t angles)46 void vectoangles2 (vec3_t value1, vec3_t angles)
47 {
48 float forward;
49 float yaw, pitch;
50
51 if (value1[1] == 0 && value1[0] == 0)
52 {
53 yaw = 0;
54 if (value1[2] > 0)
55 pitch = 90;
56 else
57 pitch = 270;
58 }
59 else
60 {
61 // PMM - fixed to correct for pitch of 0
62 if (value1[0])
63 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
64 else if (value1[1] > 0)
65 yaw = 90;
66 else
67 yaw = 270;
68
69 if (yaw < 0)
70 yaw += 360;
71
72 forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]);
73 pitch = (atan2(value1[2], forward) * 180 / M_PI);
74 if (pitch < 0)
75 pitch += 360;
76 }
77
78 angles[PITCH] = -pitch;
79 angles[YAW] = yaw;
80 angles[ROLL] = 0;
81 }
82
83 //=============
84 //=============
CL_Flashlight(int ent,vec3_t pos)85 void CL_Flashlight (int ent, vec3_t pos)
86 {
87 cdlight_t *dl;
88
89 dl = CL_AllocDlight (ent);
90 VectorCopy (pos, dl->origin);
91 dl->radius = 400;
92 dl->minlight = 250;
93 dl->die = cl.time + 100;
94 dl->color[0] = dl->color[1] = dl->color[2] = 1;
95 }
96
97 /*
98 ======
99 CL_ColorFlash - flash of light
100 ======
101 */
CL_ColorFlash(vec3_t pos,int ent,int intensity,float r,float g,float b)102 void CL_ColorFlash (vec3_t pos, int ent, int intensity, float r, float g, float b)
103 {
104 cdlight_t *dl;
105
106 dl = CL_AllocDlight (ent);
107 VectorCopy (pos, dl->origin);
108 dl->radius = intensity;
109 dl->minlight = 250;
110 dl->die = cl.time + 100;
111 dl->color[0] = r;
112 dl->color[1] = g;
113 dl->color[2] = b;
114 }
115
116
117 /*
118 ======
119 CL_DebugTrail
120 ======
121 */
CL_DebugTrail(vec3_t start,vec3_t end)122 void CL_DebugTrail (vec3_t start, vec3_t end)
123 {
124 vec3_t move;
125 vec3_t vec;
126 float len;
127 float dec;
128 vec3_t right, up;
129
130 VectorCopy (start, move);
131 VectorSubtract (end, start, vec);
132 len = VectorNormalize (vec);
133
134 MakeNormalVectors (vec, right, up);
135
136 dec = 2;
137 VectorScale (vec, dec, vec);
138 VectorCopy (start, move);
139
140 while (len > 0)
141 {
142 len -= dec;
143
144 setupParticle (
145 0, 0, 0,
146 move[0], move[1], move[2],
147 0, 0, 0,
148 0, 0, 0,
149 50, 50, 255,
150 0, 0, 0,
151 1, -0.75,
152 GL_SRC_ALPHA, GL_ONE,
153 7.5, 0,
154 particle_generic,
155 0,
156 NULL,0);
157
158 VectorAdd (move, vec, move);
159 }
160
161 }
162
CL_ForceWall(vec3_t start,vec3_t end,int color8)163 void CL_ForceWall (vec3_t start, vec3_t end, int color8)
164 {
165 vec3_t move;
166 vec3_t vec;
167 float len;
168 vec3_t color = { color8red(color8), color8green(color8), color8blue(color8)};
169
170 VectorCopy (start, move);
171 VectorSubtract (end, start, vec);
172 len = VectorNormalize (vec);
173
174 VectorScale (vec, 4, vec);
175
176 // FIXME: this is a really silly way to have a loop
177 while (len > 0)
178 {
179 len -= 4;
180
181 if (frand() > 0.3)
182 setupParticle (
183 0, 0, 0,
184 move[0] + crand()*3, move[1] + crand()*3, move[2] + crand()*3,
185 0, 0, -40 - (crand()*10),
186 0, 0, 0,
187 color[0]+5, color[1]+5, color[2]+5,
188 0, 0, 0,
189 1, -1.0 / (3.0+frand()*0.5),
190 GL_SRC_ALPHA, GL_ONE,
191 5, 0,
192 particle_generic,
193 0,
194 NULL,0);
195
196 VectorAdd (move, vec, move);
197 }
198 }
199
200
201
202 /*
203 ===============
204 CL_BubbleTrail2 (lets you control the # of bubbles by setting the distance between the spawns)
205
206 ===============
207 */
CL_BubbleTrail2(vec3_t start,vec3_t end,int dist)208 void CL_BubbleTrail2 (vec3_t start, vec3_t end, int dist)
209 {
210 vec3_t move;
211 vec3_t vec;
212 float len;
213 int i;
214 float dec, size;
215
216 VectorCopy (start, move);
217 VectorSubtract (end, start, vec);
218 len = VectorNormalize (vec);
219
220 dec = dist;
221 VectorScale (vec, dec, vec);
222
223 for (i=0 ; i<len ; i+=dec)
224 {
225 size = (frand()>0.25)? 1 : (frand()>0.5) ? 2 : (frand()>0.75) ? 3 : 4;
226
227 setupParticle (
228 0, 0, 0,
229 move[0]+crand()*2, move[1]+crand()*2, move[2]+crand()*2,
230 crand()*5, crand()*5, crand()*5+6,
231 0, 0, 0,
232 255, 255, 255,
233 0, 0, 0,
234 0.75, -1.0 / (1 + frand() * 0.2),
235 GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
236 size, 1,
237 particle_bubble,
238 PART_SHADED,
239 NULL,0);
240
241 VectorAdd (move, vec, move);
242 }
243 }
244
CL_Heatbeam(vec3_t start,vec3_t forward)245 void CL_Heatbeam (vec3_t start, vec3_t forward)
246 {
247 vec3_t move;
248 vec3_t vec;
249 float len;
250 vec3_t right, up;
251 int i;
252 float c, s;
253 vec3_t dir;
254 float ltime;
255 float step = 32.0, rstep;
256 float start_pt;
257 float rot;
258 float variance;
259 vec3_t end;
260
261 VectorMA (start, 4096, forward, end);
262
263 VectorCopy (start, move);
264 VectorSubtract (end, start, vec);
265 len = VectorNormalize (vec);
266
267 // FIXME - pmm - these might end up using old values?
268 // MakeNormalVectors (vec, right, up);
269 VectorCopy (cl.v_right, right);
270 VectorCopy (cl.v_up, up);
271
272 VectorMA (move, -0.5, right, move);
273 VectorMA (move, -0.5, up, move);
274
275 ltime = (float) cl.time/1000.0;
276 start_pt = fmod(ltime*96.0,step);
277 VectorMA (move, start_pt, vec, move);
278
279 VectorScale (vec, step, vec);
280
281 // Com_Printf ("%f\n", ltime);
282 rstep = M_PI/10.0;
283 for (i=start_pt ; i<len ; i+=step)
284 {
285 if (i>step*5) // don't bother after the 5th ring
286 break;
287
288 for (rot = 0; rot < M_PI*2; rot += rstep)
289 {
290 variance = 0.5;
291 c = cos(rot)*variance;
292 s = sin(rot)*variance;
293
294 // trim it so it looks like it's starting at the origin
295 if (i < 10)
296 {
297 VectorScale (right, c*(i/10.0), dir);
298 VectorMA (dir, s*(i/10.0), up, dir);
299 }
300 else
301 {
302 VectorScale (right, c, dir);
303 VectorMA (dir, s, up, dir);
304 }
305
306 setupParticle (
307 0, 0, 0,
308 move[0]+dir[0]*3, move[1]+dir[1]*3, move[2]+dir[2]*3,
309 0, 0, 0,
310 0, 0, 0,
311 200+rand()*50, 200+rand()*25, rand()*50,
312 0, 0, 0,
313 0.5, -1000.0,
314 GL_SRC_ALPHA, GL_ONE,
315 3, 1,
316 particle_blaster,
317 0,
318 NULL,0);
319 }
320 VectorAdd (move, vec, move);
321 }
322 }
323
324 /*
325 ===============
326 CL_ParticleSteamEffect
327
328 Puffs with velocity along direction, with some randomness thrown in
329 ===============
330 */
CL_ParticleSteamEffect(vec3_t org,vec3_t dir,int color8,int count,int magnitude)331 void CL_ParticleSteamEffect (vec3_t org, vec3_t dir, int color8, int count, int magnitude)
332 {
333 int i;
334 cparticle_t *p;
335 float d;
336 vec3_t r, u;
337 vec3_t color = { color8red(color8), color8green(color8), color8blue(color8)};
338
339 // vectoangles2 (dir, angle_dir);
340 // AngleVectors (angle_dir, f, r, u);
341
342 MakeNormalVectors (dir, r, u);
343
344 for (i=0 ; i<count ; i++)
345 {
346 p = setupParticle (
347 0, 0, 0,
348 org[0]+magnitude*0.1*crand(), org[1]+magnitude*0.1*crand(), org[2]+magnitude*0.1*crand(),
349 0, 0, 0,
350 0, 0, 0,
351 color[0], color[1], color[2],
352 0, 0, 0,
353 0.5, -1.0 / (0.5 + frand()*0.3),
354 GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
355 4, -2,
356 particle_smoke,
357 0,
358 NULL,0);
359
360 if (!p)
361 return;
362
363 VectorScale (dir, magnitude, p->vel);
364 d = crand()*magnitude/3;
365 VectorMA (p->vel, d, r, p->vel);
366 d = crand()*magnitude/3;
367 VectorMA (p->vel, d, u, p->vel);
368 }
369 }
370
CL_ParticleSteamEffect2(cl_sustain_t * self)371 void CL_ParticleSteamEffect2 (cl_sustain_t *self)
372 //vec3_t org, vec3_t dir, int color, int count, int magnitude)
373 {
374 int i;
375 cparticle_t *p;
376 float d;
377 vec3_t r, u;
378 vec3_t dir;
379 int index;
380
381 // vectoangles2 (dir, angle_dir);
382 // AngleVectors (angle_dir, f, r, u);
383
384 VectorCopy (self->dir, dir);
385 MakeNormalVectors (dir, r, u);
386
387 for (i=0 ; i<self->count ; i++)
388 {
389 index = rand()&255;
390 p = setupParticle (
391 0, 0, 0,
392 self->org[0] + self->magnitude*0.1*crand(), self->org[1] + self->magnitude*0.1*crand(), self->org[2] + self->magnitude*0.1*crand(),
393 0, 0, 0,
394 0, 0, 0,
395 index, index, index,
396 0, 0, 0,
397 1.0, -1.0 / (0.5 + frand()*0.3),
398 GL_SRC_ALPHA, GL_ONE,
399 4, 0,
400 particle_smoke,
401 PART_GRAVITY,
402 NULL,0);
403
404 if (!p)
405 return;
406
407 VectorScale (dir, self->magnitude, p->vel);
408 d = crand()*self->magnitude/3;
409 VectorMA (p->vel, d, r, p->vel);
410 d = crand()*self->magnitude/3;
411 VectorMA (p->vel, d, u, p->vel);
412 }
413 self->nextthink += self->thinkinterval;
414 }
415
416 /*
417 ===============
418 CL_TrackerTrail
419 ===============
420 */
CL_TrackerTrail(vec3_t start,vec3_t end)421 void CL_TrackerTrail (vec3_t start, vec3_t end)
422 {
423 vec3_t move;
424 vec3_t vec;
425 vec3_t forward,right,up,angle_dir;
426 float len;
427 cparticle_t *p;
428 int dec;
429 float dist;
430
431 VectorCopy (start, move);
432 VectorSubtract (end, start, vec);
433 len = VectorNormalize (vec);
434
435 VectorCopy(vec, forward);
436 vectoangles2 (forward, angle_dir);
437 AngleVectors (angle_dir, forward, right, up);
438
439 dec = 3;
440 VectorScale (vec, 3, vec);
441
442 // FIXME: this is a really silly way to have a loop
443 while (len > 0)
444 {
445 len -= dec;
446
447 p = setupParticle (
448 0, 0, 0,
449 0, 0, 0,
450 0, 0, 5,
451 0, 0, 0,
452 0, 0, 0,
453 0, 0, 0,
454 1.0, -2.0,
455 GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
456 2, 0,
457 particle_generic,
458 0,
459 NULL,0);
460
461 if (!p)
462 return;
463
464 dist = DotProduct(move, forward);
465 VectorMA(move, 8 * cos(dist), up, p->org);
466
467 VectorAdd (move, vec, move);
468 }
469 }
470
CL_Tracker_Shell(vec3_t origin)471 void CL_Tracker_Shell(vec3_t origin)
472 {
473 vec3_t dir;
474 int i;
475 cparticle_t *p;
476
477 for(i=0;i<300;i++)
478 {
479 p = setupParticle (
480 0, 0, 0,
481 0, 0, 0,
482 0, 0, 0,
483 0, 0, 0,
484 0, 0, 0,
485 0, 0, 0,
486 1.0, -2.0,
487 GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
488 2, 0,
489 particle_generic,
490 0,
491 NULL,0);
492
493 if (!p)
494 return;
495
496 dir[0] = crand();
497 dir[1] = crand();
498 dir[2] = crand();
499 VectorNormalize(dir);
500 VectorMA(origin, 40, dir, p->org);
501 }
502 }
503
CL_MonsterPlasma_Shell(vec3_t origin)504 void CL_MonsterPlasma_Shell(vec3_t origin)
505 {
506 vec3_t dir;
507 int i;
508 cparticle_t *p;
509
510 for(i=0;i<40;i++)
511 {
512 p = setupParticle (
513 0, 0, 0,
514 0, 0, 0,
515 0, 0, 0,
516 0, 0, 0,
517 0, 0, 0,
518 0, 0, 0,
519 1.0, 0,
520 GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
521 2, 0,
522 particle_generic,
523 PART_INSTANT,
524 NULL,0);
525
526 if (!p)
527 return;
528
529 dir[0] = crand();
530 dir[1] = crand();
531 dir[2] = crand();
532 VectorNormalize(dir);
533
534 VectorMA(origin, 10, dir, p->org);
535 }
536 }
537
CL_Widowbeamout(cl_sustain_t * self)538 void CL_Widowbeamout (cl_sustain_t *self)
539 {
540 vec3_t dir;
541 int i;
542 cparticle_t *p;
543 float ratio;
544
545 ratio = 1.0 - (((float)self->endtime - (float)cl.time)/2100.0);
546
547 for(i=0;i<300;i++)
548 {
549 p = setupParticle (
550 0, 0, 0,
551 0, 0, 0,
552 0, 0, 0,
553 0, 0, 0,
554 0, 0, 0,
555 0, 0, 0,
556 1.0, 0,
557 GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
558 2, 0,
559 particle_generic,
560 PART_INSTANT,
561 NULL,0);
562
563 if (!p)
564 return;
565
566 dir[0] = crand();
567 dir[1] = crand();
568 dir[2] = crand();
569 VectorNormalize(dir);
570
571 VectorMA(self->org, (45.0 * ratio), dir, p->org);
572 }
573 }
574
CL_Nukeblast(cl_sustain_t * self)575 void CL_Nukeblast (cl_sustain_t *self)
576 {
577 vec3_t dir;
578 int i;
579 cparticle_t *p;
580 static int colortable0[4] = {255, 215, 185, 150};
581 static int colortable1[4] = {255, 215, 185, 150};
582 static int colortable2[4] = {255, 255, 255, 255};
583 float ratio, size;
584 int index;
585 int colors[][3] =
586 {
587 250, 250, 255,
588 200, 225, 255,
589 150, 175, 255,
590 100, 100, 255,
591 0
592 };
593
594 ratio = 1.0 - (((float)self->endtime - (float)cl.time)/1000.0);
595 size = ratio*ratio;
596
597 for(i=0;i<256;i++)
598 {
599 index = rand()&3;
600 p = setupParticle (
601 0, 0, 0,
602 0, 0, 0,
603 0, 0, 0,
604 0, 0, 0,
605 colors[index][0], colors[index][1], colors[index][2],
606 0, 0, 0,
607 1-size, 0,
608 GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
609 3*(0.5+ratio*0.5), -1,
610 particle_generic,
611 PART_DIRECTION|PART_INSTANT,
612 NULL,0);
613
614 if (!p)
615 return;
616
617 VectorSet(dir, crandom(), crandom(), crandom());
618 VectorNormalize(dir);
619
620 VectorScale(dir, 50.0*size, p->angle);
621 VectorCopy(self->org, p->org);
622 }
623 }
624
CL_WidowSplash(vec3_t org)625 void CL_WidowSplash (vec3_t org)
626 {
627 static int colortable[4] = {2*8,13*8,21*8,18*8};
628 int i;
629 cparticle_t *p;
630 vec3_t dir;
631
632 for (i=0 ; i<256 ; i++)
633 {
634 p = setupParticle (
635 0, 0, 0,
636 0, 0, 0,
637 0, 0, 0,
638 0, 0, 0,
639 rand()&255, rand()&255, rand()&255,
640 0, 0, 0,
641 1.0, -0.8 / (0.5 + frand()*0.3),
642 GL_SRC_ALPHA, GL_ONE,
643 3, 0,
644 particle_generic,
645 0,
646 NULL,0);
647
648 if (!p)
649 return;
650
651 dir[0] = crand();
652 dir[1] = crand();
653 dir[2] = crand();
654 VectorNormalize(dir);
655 VectorMA(org, 45.0, dir, p->org);
656 VectorMA(vec3_origin, 40.0, dir, p->vel);
657 }
658
659 }
660
CL_Tracker_Explode(vec3_t origin)661 void CL_Tracker_Explode(vec3_t origin)
662 {
663 vec3_t dir, backdir;
664 int i;
665 cparticle_t *p;
666
667 for(i=0;i<300;i++)
668 {
669 p = setupParticle (
670 0, 0, 0,
671 0, 0, 0,
672 0, 0, 0,
673 0, 0, 20,
674 0, 0, 0,
675 0, 0, 0,
676 1.0, -1.0,
677 GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
678 1.5, 0,
679 particle_generic,
680 0,
681 NULL,0);
682
683 if (!p)
684 return;
685
686 dir[0] = crand();
687 dir[1] = crand();
688 dir[2] = crand();
689 VectorNormalize(dir);
690 VectorScale(dir, -1, backdir);
691
692 VectorMA(origin, 64, dir, p->org);
693 VectorScale(backdir, 64, p->vel);
694 }
695
696 }
697
698 /*
699 ===============
700 CL_TagTrail
701
702 ===============
703 */
CL_TagTrail(vec3_t start,vec3_t end,int color8)704 void CL_TagTrail (vec3_t start, vec3_t end, int color8)
705 {
706 vec3_t move;
707 vec3_t vec;
708 float len;
709 int dec;
710 vec3_t color = { color8red(color8), color8green(color8), color8blue(color8)};
711
712 VectorCopy (start, move);
713 VectorSubtract (end, start, vec);
714 len = VectorNormalize (vec);
715
716 dec = 5;
717 VectorScale (vec, 5, vec);
718
719 while (len >= 0)
720 {
721 len -= dec;
722
723 setupParticle (
724 0, 0, 0,
725 move[0] + crand()*16, move[1] + crand()*16, move[2] + crand()*16,
726 crand()*5, crand()*5, crand()*5,
727 0, 0, 20,
728 color[0], color[1], color[2],
729 0, 0, 0,
730 1.0, -1.0 / (0.8+frand()*0.2),
731 GL_SRC_ALPHA, GL_ONE,
732 1.5, 0,
733 particle_generic,
734 0,
735 NULL,0);
736
737 VectorAdd (move, vec, move);
738 }
739 }
740
741 /*
742 ===============
743 CL_ColorExplosionParticles
744 ===============
745 */
CL_ColorExplosionParticles(vec3_t org,int color8,int run)746 void CL_ColorExplosionParticles (vec3_t org, int color8, int run)
747 {
748 int i;
749 vec3_t color = { color8red(color8), color8green(color8), color8blue(color8)};
750
751 for (i=0 ; i<128 ; i++)
752 {
753 setupParticle (
754 0, 0, 0,
755 org[0] + ((rand()%32)-16), org[1] + ((rand()%32)-16), org[2] + ((rand()%32)-16),
756 (rand()%256)-128, (rand()%256)-128, (rand()%256)-128,
757 0, 0, 20,
758 color[0] + (rand() % run), color[1] + (rand() % run), color[2] + (rand() % run),
759 0, 0, 0,
760 1.0, -0.4 / (0.6 + frand()*0.2),
761 GL_SRC_ALPHA, GL_ONE,
762 2, 1,
763 particle_generic,
764 0,
765 NULL,0);
766 }
767 }
768
769 /*
770 ===============
771 CL_ParticleSmokeEffect - like the steam effect, but unaffected by gravity
772 ===============
773 */
774
pRotateThink(cparticle_t * p,vec3_t org,vec3_t angle,float * alpha,float * size,int * image,float * time)775 void pRotateThink (cparticle_t *p, vec3_t org, vec3_t angle, float *alpha, float *size, int *image, float *time)
776 {
777 angle[2] = angle[0] + *time*angle[1] + *time**time*angle[2];
778 p->thinknext=true;
779 }
780
CL_ParticleSmokeEffect(vec3_t org,vec3_t dir,float size,float alpha)781 void CL_ParticleSmokeEffect (vec3_t org, vec3_t dir, float size, float alpha)
782 {
783 setupParticle (
784 crand()*180, crand()*100, 0,
785 org[0], org[1], org[2],
786 dir[0], dir[1], dir[2],
787 0, 0, 10,
788 255, 255, 255,
789 0, 0, 0,
790 alpha, -2.0,
791 GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
792 size, 5,
793 particle_smoke,
794 PART_SHADED|PART_OVERBRIGHT,
795 pRotateThink,true);
796 }
797
798 /*
799 ===============
800 CL_BlasterParticles2
801
802 Wall impact puffs (Green)
803 ===============
804 */
805 #define pBlasterMaxSize 5
pBlaster2Think(cparticle_t * p,vec3_t org,vec3_t angle,float * alpha,float * size,int * image,float * time)806 void pBlaster2Think (cparticle_t *p, vec3_t org, vec3_t angle, float *alpha, float *size, int *image, float *time)
807 {
808 vec3_t len;
809 VectorSubtract(p->angle, org, len);
810
811 *size *= (float)(pBlasterMaxSize/VectorLength(len)) * 1.0/((4-*size));
812 if (*size > pBlasterMaxSize)
813 *size = pBlasterMaxSize;
814
815 p->thinknext = true;
816 }
CL_BlasterParticles2(vec3_t org,vec3_t dir,unsigned int color)817 void CL_BlasterParticles2 (vec3_t org, vec3_t dir, unsigned int color)
818 {
819 int i;
820 float d;
821 int count;
822 float speed = .75;
823
824 count = 40;
825 for (i=0 ; i<count ; i++)
826 {
827 d = rand()&5;
828 setupParticle (
829 org[0], org[1], org[2],
830 org[0]+((rand()&5)-2)+d*dir[0], org[1]+((rand()&5)-2)+d*dir[1], org[2]+((rand()&5)-2)+d*dir[2],
831 (dir[0]*50 + crand()*20)*speed, (dir[1]*50 + crand()*20)*speed, (dir[2]*50 + crand()*20)*speed,
832 0, 0, 0,
833 50, 235, 50,
834 -10, 0, -10,
835 1, -1.0 / (0.5 + frand()*0.3),
836 GL_SRC_ALPHA, GL_ONE,
837 4, -6,
838 particle_generic,
839 PART_GRAVITY,
840 pBlaster2Think,true);
841 }
842 }
843
844 /*
845 ===============
846 CL_BlasterTrail2
847
848 Green!
849 ===============
850 */
CL_BlasterTrail2(vec3_t start,vec3_t end)851 void CL_BlasterTrail2 (vec3_t start, vec3_t end)
852 {
853 vec3_t move;
854 vec3_t vec;
855 float len;
856 int dec;
857
858 VectorCopy (start, move);
859 VectorSubtract (end, start, vec);
860 len = VectorNormalize (vec);
861
862 dec = 5;
863 VectorScale (vec, 5, vec);
864
865 // FIXME: this is a really silly way to have a loop
866 while (len > 0)
867 {
868 len -= dec;
869
870 setupParticle (
871 0, 0, 0,
872 move[0] + crand(), move[1] + crand(), move[2] + crand(),
873 crand()*5, crand()*5, crand()*5,
874 0, 0, 0,
875 50, 235, 50,
876 -10, 0, -10,
877 1, -1.0 / (0.5 + frand()*0.3),
878 GL_SRC_ALPHA, GL_ONE,
879 4, -6,
880 particle_generic,
881 0,
882 NULL,0);
883
884 VectorAdd (move, vec, move);
885 }
886 }
887