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