|
|
1.1 root 1: // cl_tent.c -- client side temporary entities
2:
3: #include "client.h"
4:
5: typedef enum
6: {
7: ex_free, ex_explosion, ex_misc, ex_flash, ex_mflash, ex_poly
8: } exptype_t;
9:
10: typedef struct
11: {
12: exptype_t type;
13: entity_t ent;
14:
15: int frames;
16: float light;
17: vec3_t lightcolor;
18: float start;
19: int baseframe;
20: } explosion_t;
21:
22:
23:
24: #define MAX_EXPLOSIONS 32
25: explosion_t cl_explosions[MAX_EXPLOSIONS];
26:
27:
28: #define MAX_BEAMS 32
29: typedef struct
30: {
31: int entity;
32: struct model_s *model;
33: int endtime;
34: vec3_t offset;
35: vec3_t start, end;
36: } beam_t;
37: beam_t cl_beams[MAX_BEAMS];
38:
39:
40: #define MAX_LASERS 32
41: typedef struct
42: {
43: entity_t ent;
44: int endtime;
45: } laser_t;
46: laser_t cl_lasers[MAX_LASERS];
47:
48:
49: void CL_BlasterParticles (vec3_t org, vec3_t dir);
50: void CL_ExplosionParticles (vec3_t org);
51: void CL_BFGExplosionParticles (vec3_t org);
52:
53: struct sfx_s *cl_sfx_ric1;
54: struct sfx_s *cl_sfx_ric2;
55: struct sfx_s *cl_sfx_ric3;
56: struct sfx_s *cl_sfx_lashit;
57: struct sfx_s *cl_sfx_spark5;
58: struct sfx_s *cl_sfx_spark6;
59: struct sfx_s *cl_sfx_spark7;
60: struct sfx_s *cl_sfx_railg;
61: struct sfx_s *cl_sfx_rockexp;
62: struct sfx_s *cl_sfx_grenexp;
63: struct sfx_s *cl_sfx_watrexp;
64:
65: struct sfx_s *cl_sfx_footsteps[4];
66:
67: struct model_s *cl_mod_explode;
68: struct model_s *cl_mod_smoke;
69: struct model_s *cl_mod_flash;
70: struct model_s *cl_mod_parasite_segment;
71: struct model_s *cl_mod_grapple_cable;
72: struct model_s *cl_mod_parasite_tip;
73: struct model_s *cl_mod_explo4;
74: struct model_s *cl_mod_bfg_explo;
75: struct model_s *cl_mod_powerscreen;
76:
77: /*
78: =================
79: CL_RegisterTEntSounds
80: =================
81: */
82: void CL_RegisterTEntSounds (void)
83: {
84: int i;
85: char name[MAX_QPATH];
86:
87: cl_sfx_ric1 = S_RegisterSound ("world/ric1.wav");
88: cl_sfx_ric2 = S_RegisterSound ("world/ric2.wav");
89: cl_sfx_ric3 = S_RegisterSound ("world/ric3.wav");
90: cl_sfx_lashit = S_RegisterSound("weapons/lashit.wav");
91: cl_sfx_spark5 = S_RegisterSound ("world/spark5.wav");
92: cl_sfx_spark6 = S_RegisterSound ("world/spark6.wav");
93: cl_sfx_spark7 = S_RegisterSound ("world/spark7.wav");
94: cl_sfx_railg = S_RegisterSound ("weapons/railgf1a.wav");
95: cl_sfx_rockexp = S_RegisterSound ("weapons/rocklx1a.wav");
96: cl_sfx_grenexp = S_RegisterSound ("weapons/grenlx1a.wav");
97: cl_sfx_watrexp = S_RegisterSound ("weapons/xpld_wat.wav");
98:
99: S_RegisterSound ("player/land1.wav");
100:
101: S_RegisterSound ("player/fall2.wav");
102: S_RegisterSound ("player/fall1.wav");
103:
104: for (i=0 ; i<4 ; i++)
105: {
106: Com_sprintf (name, sizeof(name), "player/step%i.wav", i+1);
107: cl_sfx_footsteps[i] = S_RegisterSound (name);
108: }
109: }
110:
111: /*
112: =================
113: CL_RegisterTEntModels
114: =================
115: */
116: void CL_RegisterTEntModels (void)
117: {
118: cl_mod_explode = re.RegisterModel ("models/objects/explode/tris.md2");
119: cl_mod_smoke = re.RegisterModel ("models/objects/smoke/tris.md2");
120: cl_mod_flash = re.RegisterModel ("models/objects/flash/tris.md2");
121: cl_mod_parasite_segment = re.RegisterModel ("models/monsters/parasite/segment/tris.md2");
122: cl_mod_grapple_cable = re.RegisterModel ("models/ctf/segment/tris.md2");
123: cl_mod_parasite_tip = re.RegisterModel ("models/monsters/parasite/tip/tris.md2");
124: cl_mod_explo4 = re.RegisterModel ("models/objects/r_explode/tris.md2");
125: cl_mod_bfg_explo = re.RegisterModel ("sprites/s_bfg2.sp2");
126: cl_mod_powerscreen = re.RegisterModel ("models/items/armor/effect/tris.md2");
127:
128: re.RegisterModel ("models/objects/laser/tris.md2");
129: re.RegisterModel ("models/objects/grenade2/tris.md2");
130: re.RegisterModel ("models/weapons/v_machn/tris.md2");
131: re.RegisterModel ("models/weapons/v_handgr/tris.md2");
132: re.RegisterModel ("models/weapons/v_shotg2/tris.md2");
133: re.RegisterModel ("models/objects/gibs/bone/tris.md2");
134: re.RegisterModel ("models/objects/gibs/sm_meat/tris.md2");
135: re.RegisterModel ("models/objects/gibs/bone2/tris.md2");
136:
137: re.RegisterPic ("w_machinegun");
138: re.RegisterPic ("a_bullets");
139: re.RegisterPic ("i_health");
140: re.RegisterPic ("a_grenades");
141: }
142:
143: /*
144: =================
145: CL_ClearTEnts
146: =================
147: */
148: void CL_ClearTEnts (void)
149: {
150: memset (cl_beams, 0, sizeof(cl_beams));
151: memset (cl_explosions, 0, sizeof(cl_explosions));
152: memset (cl_lasers, 0, sizeof(cl_lasers));
153: }
154:
155: /*
156: =================
157: CL_AllocExplosion
158: =================
159: */
160: explosion_t *CL_AllocExplosion (void)
161: {
162: int i;
163: int time;
164: int index;
165:
166: for (i=0 ; i<MAX_EXPLOSIONS ; i++)
167: {
168: if (cl_explosions[i].type == ex_free)
169: {
170: memset (&cl_explosions[i], 0, sizeof (cl_explosions[i]));
171: return &cl_explosions[i];
172: }
173: }
174: // find the oldest explosion
175: time = cl.time;
176: index = 0;
177:
178: for (i=0 ; i<MAX_EXPLOSIONS ; i++)
179: if (cl_explosions[i].start < time)
180: {
181: time = cl_explosions[i].start;
182: index = i;
183: }
184: memset (&cl_explosions[index], 0, sizeof (cl_explosions[index]));
185: return &cl_explosions[index];
186: }
187:
188: /*
189: =================
190: CL_SmokeAndFlash
191: =================
192: */
193: void CL_SmokeAndFlash(vec3_t origin)
194: {
195: explosion_t *ex;
196:
197: ex = CL_AllocExplosion ();
198: VectorCopy (origin, ex->ent.origin);
199: ex->type = ex_misc;
200: ex->frames = 4;
201: ex->ent.flags = RF_TRANSLUCENT;
202: ex->start = cl.frame.servertime - 100;
203: ex->ent.model = cl_mod_smoke;
204:
205: ex = CL_AllocExplosion ();
206: VectorCopy (origin, ex->ent.origin);
207: ex->type = ex_flash;
208: ex->ent.flags = RF_FULLBRIGHT;
209: ex->frames = 2;
210: ex->start = cl.frame.servertime - 100;
211: ex->ent.model = cl_mod_flash;
212: }
213:
214: /*
215: =================
216: CL_ParseParticles
217: =================
218: */
219: void CL_ParseParticles (void)
220: {
221: int color, count;
222: vec3_t pos, dir;
223:
224: MSG_ReadPos (&net_message, pos);
225: MSG_ReadDir (&net_message, dir);
226:
227: color = MSG_ReadByte (&net_message);
228:
229: count = MSG_ReadByte (&net_message);
230:
231: CL_ParticleEffect (pos, dir, color, count);
232: }
233:
234: /*
235: =================
236: CL_ParseBeam
237: =================
238: */
239: int CL_ParseBeam (struct model_s *model)
240: {
241: int ent;
242: vec3_t start, end;
243: beam_t *b;
244: int i;
245:
246: ent = MSG_ReadShort (&net_message);
247:
248: MSG_ReadPos (&net_message, start);
249: MSG_ReadPos (&net_message, end);
250:
251: // override any beam with the same entity
252: for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
253: if (b->entity == ent)
254: {
255: b->entity = ent;
256: b->model = model;
257: b->endtime = cl.time + 200;
258: VectorCopy (start, b->start);
259: VectorCopy (end, b->end);
260: VectorClear (b->offset);
261: return ent;
262: }
263:
264: // find a free beam
265: for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
266: {
267: if (!b->model || b->endtime < cl.time)
268: {
269: b->entity = ent;
270: b->model = model;
271: b->endtime = cl.time + 200;
272: VectorCopy (start, b->start);
273: VectorCopy (end, b->end);
274: VectorClear (b->offset);
275: return ent;
276: }
277: }
278: Com_Printf ("beam list overflow!\n");
279: return ent;
280: }
281:
282: /*
283: =================
284: CL_ParseBeam2
285: =================
286: */
287: int CL_ParseBeam2 (struct model_s *model)
288: {
289: int ent;
290: vec3_t start, end, offset;
291: beam_t *b;
292: int i;
293:
294: ent = MSG_ReadShort (&net_message);
295:
296: MSG_ReadPos (&net_message, start);
297: MSG_ReadPos (&net_message, end);
298: MSG_ReadPos (&net_message, offset);
299:
300: // override any beam with the same entity
301: for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
302: if (b->entity == ent)
303: {
304: b->entity = ent;
305: b->model = model;
306: b->endtime = cl.time + 200;
307: VectorCopy (start, b->start);
308: VectorCopy (end, b->end);
309: VectorCopy (offset, b->offset);
310: return ent;
311: }
312:
313: // find a free beam
314: for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
315: {
316: if (!b->model || b->endtime < cl.time)
317: {
318: b->entity = ent;
319: b->model = model;
320: b->endtime = cl.time + 200;
321: VectorCopy (start, b->start);
322: VectorCopy (end, b->end);
323: VectorCopy (offset, b->offset);
324: return ent;
325: }
326: }
327: Com_Printf ("beam list overflow!\n");
328: return ent;
329: }
330:
331: /*
332: =================
333: CL_ParseLaser
334: =================
335: */
336: void CL_ParseLaser (int colors)
337: {
338: vec3_t start;
339: vec3_t end;
340: laser_t *l;
341: int i;
342:
343: MSG_ReadPos (&net_message, start);
344: MSG_ReadPos (&net_message, end);
345:
346: for (i=0, l=cl_lasers ; i< MAX_LASERS ; i++, l++)
347: {
348: if (l->endtime < cl.time)
349: {
350: l->ent.flags = RF_TRANSLUCENT | RF_BEAM;
351: VectorCopy (start, l->ent.origin);
352: VectorCopy (end, l->ent.oldorigin);
353: l->ent.alpha = 0.30;
354: l->ent.skinnum = (colors >> ((rand() % 4)*8)) & 0xff;
355: l->ent.model = NULL;
356: l->ent.frame = 4;
357: l->endtime = cl.time + 100;
358: return;
359: }
360: }
361: }
362:
363:
364: /*
365: =================
366: CL_ParseTEnt
367: =================
368: */
369: static byte splash_color[] = {0x00, 0xe0, 0xb0, 0x50, 0xd0, 0xe0, 0xe8};
370:
371: void CL_ParseTEnt (void)
372: {
373: int type;
374: vec3_t pos, pos2, dir;
375: explosion_t *ex;
376: int cnt;
377: int color;
378: int r;
379: int ent;
380:
381: type = MSG_ReadByte (&net_message);
382:
383: switch (type)
384: {
385: case TE_BLOOD: // bullet hitting flesh
386: MSG_ReadPos (&net_message, pos);
387: MSG_ReadDir (&net_message, dir);
388: CL_ParticleEffect (pos, dir, 0xe8, 60);
389: break;
390:
391: case TE_GUNSHOT: // bullet hitting wall
392: case TE_SPARKS:
393: case TE_BULLET_SPARKS:
394: MSG_ReadPos (&net_message, pos);
395: MSG_ReadDir (&net_message, dir);
396: if (type == TE_GUNSHOT)
397: CL_ParticleEffect (pos, dir, 0, 40);
398: else
399: CL_ParticleEffect (pos, dir, 0xe0, 6);
400:
401: if (type != TE_SPARKS)
402: {
403: CL_SmokeAndFlash(pos);
404:
405: // impact sound
406: cnt = rand()&15;
407: if (cnt == 1)
408: S_StartSound (pos, 0, 0, cl_sfx_ric1, 1, ATTN_NORM, 0);
409: else if (cnt == 2)
410: S_StartSound (pos, 0, 0, cl_sfx_ric2, 1, ATTN_NORM, 0);
411: else if (cnt == 3)
412: S_StartSound (pos, 0, 0, cl_sfx_ric3, 1, ATTN_NORM, 0);
413: }
414:
415: break;
416:
417: case TE_SCREEN_SPARKS:
418: case TE_SHIELD_SPARKS:
419: MSG_ReadPos (&net_message, pos);
420: MSG_ReadDir (&net_message, dir);
421: if (type == TE_SCREEN_SPARKS)
422: CL_ParticleEffect (pos, dir, 0xd0, 40);
423: else
424: CL_ParticleEffect (pos, dir, 0xb0, 40);
425: //FIXME : replace or remove this sound
426: S_StartSound (pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
427: break;
428:
429: case TE_SHOTGUN: // bullet hitting wall
430: MSG_ReadPos (&net_message, pos);
431: MSG_ReadDir (&net_message, dir);
432: CL_ParticleEffect (pos, dir, 0, 20);
433: CL_SmokeAndFlash(pos);
434: break;
435:
436: case TE_SPLASH: // bullet hitting water
437: cnt = MSG_ReadByte (&net_message);
438: MSG_ReadPos (&net_message, pos);
439: MSG_ReadDir (&net_message, dir);
440: r = MSG_ReadByte (&net_message);
441: if (r > 6)
442: color = 0x00;
443: else
444: color = splash_color[r];
445: CL_ParticleEffect (pos, dir, color, cnt);
446:
447: if (r == SPLASH_SPARKS)
448: {
449: r = rand() & 3;
450: if (r == 0)
451: S_StartSound (pos, 0, 0, cl_sfx_spark5, 1, ATTN_STATIC, 0);
452: else if (r == 1)
453: S_StartSound (pos, 0, 0, cl_sfx_spark6, 1, ATTN_STATIC, 0);
454: else
455: S_StartSound (pos, 0, 0, cl_sfx_spark7, 1, ATTN_STATIC, 0);
456: }
457: break;
458:
459: case TE_LASER_SPARKS:
460: cnt = MSG_ReadByte (&net_message);
461: MSG_ReadPos (&net_message, pos);
462: MSG_ReadDir (&net_message, dir);
463: color = MSG_ReadByte (&net_message);
464: CL_ParticleEffect2 (pos, dir, color, cnt);
465: break;
466:
467: case TE_BLASTER: // blaster hitting wall
468: MSG_ReadPos (&net_message, pos);
469: MSG_ReadDir (&net_message, dir);
470: CL_BlasterParticles (pos, dir);
471:
472: ex = CL_AllocExplosion ();
473: VectorCopy (pos, ex->ent.origin);
474: ex->ent.angles[0] = acos(dir[2])/M_PI*180;
475: ex->ent.angles[2] = atan2(dir[1], dir[0])/M_PI*180;
476: ex->type = ex_misc;
477: ex->ent.flags = RF_FULLBRIGHT|RF_TRANSLUCENT;
478: ex->start = cl.frame.servertime - 100;
479: ex->light = 150;
480: ex->lightcolor[0] = 1;
481: ex->lightcolor[1] = 1;
482: ex->ent.model = cl_mod_explode;
483: ex->frames = 4;
484: S_StartSound (pos, 0, 0, cl_sfx_lashit, 1, ATTN_NORM, 0);
485: break;
486:
487: case TE_RAILTRAIL: // railgun effect
488: MSG_ReadPos (&net_message, pos);
489: MSG_ReadPos (&net_message, pos2);
490: CL_RailTrail (pos, pos2);
491: S_StartSound (pos2, 0, 0, cl_sfx_railg, 1, ATTN_NORM, 0);
492: break;
493:
494: case TE_PLASMATRAIL:
495: MSG_ReadPos (&net_message, pos);
496: MSG_ReadPos (&net_message, pos2);
497: CL_PlasmaTrail (pos, pos2);
498: S_StartSound (pos2, 0, 0, cl_sfx_railg, 1, ATTN_NORM, 0);
499: break;
500:
501: case TE_EXPLOSION2:
502: case TE_GRENADE_EXPLOSION:
503: case TE_GRENADE_EXPLOSION_WATER:
504: MSG_ReadPos (&net_message, pos);
505:
506: ex = CL_AllocExplosion ();
507: VectorCopy (pos, ex->ent.origin);
508: ex->type = ex_poly;
509: ex->ent.flags = RF_FULLBRIGHT;
510: ex->start = cl.frame.servertime - 100;
511: ex->light = 350;
512: ex->lightcolor[0] = 1.0;
513: ex->lightcolor[1] = 0.5;
514: ex->lightcolor[2] = 0.5;
515: ex->ent.model = cl_mod_explo4;
516: ex->frames = 19;
517: ex->baseframe = 30;
518: ex->ent.angles[1] = rand() % 360;
519: CL_ExplosionParticles (pos);
520: if (type == TE_GRENADE_EXPLOSION_WATER)
521: S_StartSound (pos, 0, 0, cl_sfx_watrexp, 1, ATTN_NORM, 0);
522: else
523: S_StartSound (pos, 0, 0, cl_sfx_grenexp, 1, ATTN_NORM, 0);
524: break;
525:
526: case TE_EXPLOSION1:
527: case TE_ROCKET_EXPLOSION:
528: case TE_ROCKET_EXPLOSION_WATER:
529: MSG_ReadPos (&net_message, pos);
530:
531: ex = CL_AllocExplosion ();
532: VectorCopy (pos, ex->ent.origin);
533: ex->type = ex_poly;
534: ex->ent.flags = RF_FULLBRIGHT;
535: ex->start = cl.frame.servertime - 100;
536: ex->light = 350;
537: ex->lightcolor[0] = 1.0;
538: ex->lightcolor[1] = 0.5;
539: ex->lightcolor[2] = 0.5;
540: ex->ent.angles[1] = rand() % 360;
541: ex->ent.model = cl_mod_explo4;
542: if (frand() < 0.5)
543: ex->baseframe = 15;
544: ex->frames = 15;
545: CL_ExplosionParticles (pos);
546: if (type == TE_ROCKET_EXPLOSION_WATER)
547: S_StartSound (pos, 0, 0, cl_sfx_watrexp, 1, ATTN_NORM, 0);
548: else
549: S_StartSound (pos, 0, 0, cl_sfx_rockexp, 1, ATTN_NORM, 0);
550: break;
551:
552: case TE_BFG_EXPLOSION:
553: MSG_ReadPos (&net_message, pos);
554: ex = CL_AllocExplosion ();
555: VectorCopy (pos, ex->ent.origin);
556: ex->type = ex_poly;
557: ex->ent.flags = RF_FULLBRIGHT;
558: ex->start = cl.frame.servertime - 100;
559: ex->light = 350;
560: ex->lightcolor[0] = 0.0;
561: ex->lightcolor[1] = 1.0;
562: ex->lightcolor[2] = 0.0;
563: ex->ent.model = cl_mod_bfg_explo;
564: ex->ent.flags |= RF_TRANSLUCENT;
565: ex->ent.alpha = 0.30;
566: ex->frames = 4;
567: break;
568:
569: case TE_BFG_BIGEXPLOSION:
570: MSG_ReadPos (&net_message, pos);
571: CL_BFGExplosionParticles (pos);
572: break;
573:
574: case TE_BFG_LASER:
575: CL_ParseLaser (0xd0d1d2d3);
576: break;
577:
578: case TE_BUBBLETRAIL:
579: MSG_ReadPos (&net_message, pos);
580: MSG_ReadPos (&net_message, pos2);
581: CL_BubbleTrail (pos, pos2);
582: break;
583:
584: case TE_PARASITE_ATTACK:
585: case TE_MEDIC_CABLE_ATTACK:
586: ent = CL_ParseBeam (cl_mod_parasite_segment);
587: break;
588:
589: case TE_BOSSTPORT: // boss teleporting to station
590: MSG_ReadPos (&net_message, pos);
591: CL_BigTeleportParticles (pos);
592: S_StartSound (pos, 0, 0, S_RegisterSound ("misc/bigtele.wav"), 1, ATTN_NONE, 0);
593: break;
594:
595: case TE_GRAPPLE_CABLE:
596: ent = CL_ParseBeam2 (cl_mod_grapple_cable);
597: break;
598:
599: case TE_WELDING_SPARKS:
600: cnt = MSG_ReadByte (&net_message);
601: MSG_ReadPos (&net_message, pos);
602: MSG_ReadDir (&net_message, dir);
603: color = MSG_ReadByte (&net_message);
604: CL_ParticleEffect2 (pos, dir, color, cnt);
605:
606: ex = CL_AllocExplosion ();
607: VectorCopy (pos, ex->ent.origin);
608: ex->type = ex_flash;
609: // note to self
610: // we need a better no draw flag
611: ex->ent.flags = RF_BEAM;
612: ex->start = cl.frame.servertime - 0.1;
613: ex->light = 100 + (rand()%75);
614: ex->lightcolor[0] = 1.0;
615: ex->lightcolor[1] = 1.0;
616: ex->lightcolor[2] = 0.3;
617: ex->ent.model = cl_mod_flash;
618: ex->frames = 2;
619: break;
620:
621: case TE_GREENBLOOD:
622: MSG_ReadPos (&net_message, pos);
623: MSG_ReadDir (&net_message, dir);
624: CL_ParticleEffect2 (pos, dir, 0xc0, 30);
625: break;
626:
627: default:
628: Com_Error (ERR_DROP, "CL_ParseTEnt: bad type");
629: }
630: }
631:
632: /*
633: =================
634: CL_AddBeams
635: =================
636: */
637: void CL_AddBeams (void)
638: {
639: int i,j;
640: beam_t *b;
641: vec3_t dist, org;
642: float d;
643: entity_t ent;
644: float yaw, pitch;
645: float forward;
646:
647: // update beams
648: for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
649: {
650: if (!b->model || b->endtime < cl.time)
651: continue;
652:
653: // if coming from the player, update the start position
654: if (b->entity == cl.playernum+1) // entity 0 is the world
655: {
656: VectorCopy (cl.refdef.vieworg, b->start);
657: b->start[2] -= 22; // adjust for view height
658: }
659:
660: VectorAdd (b->start, b->offset, org);
661:
662: // calculate pitch and yaw
663: VectorSubtract (b->end, org, dist);
664:
665: if (dist[1] == 0 && dist[0] == 0)
666: {
667: yaw = 0;
668: if (dist[2] > 0)
669: pitch = 90;
670: else
671: pitch = 270;
672: }
673: else
674: {
675: yaw = (int) (atan2(dist[1], dist[0]) * 180 / M_PI);
676: if (yaw < 0)
677: yaw += 360;
678:
679: forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]);
680: pitch = (int) (atan2(dist[2], forward) * -180 / M_PI);
681: if (pitch < 0)
682: pitch += 360;
683: }
684:
685: // add new entities for the beams
686: d = VectorNormalize(dist);
687: memset (&ent, 0, sizeof(ent));
688: while (d > 0)
689: {
690: VectorCopy (org, ent.origin);
691: ent.model = b->model;
692: ent.angles[0] = pitch;
693: ent.angles[1] = yaw;
694: ent.angles[2] = rand()%360;
695:
696: V_AddEntity (&ent);
697:
698: for (j=0 ; j<3 ; j++)
699: org[j] += dist[j]*30;
700: d -= 30;
701: }
702: }
703:
704: }
705:
706: /*
707: =================
708: CL_AddExplosions
709: =================
710: */
711: void CL_AddExplosions (void)
712: {
713: entity_t *ent;
714: int i;
715: explosion_t *ex;
716: float frac;
717: int f;
718:
719: memset (&ent, 0, sizeof(ent));
720:
721: for (i=0, ex=cl_explosions ; i< MAX_EXPLOSIONS ; i++, ex++)
722: {
723: if (ex->type == ex_free)
724: continue;
725: frac = (cl.time - ex->start)/100.0;
726: f = floor(frac);
727:
728: ent = &ex->ent;
729:
730: switch (ex->type)
731: {
732: case ex_mflash:
733: if (f >= ex->frames-1)
734: ex->type = ex_free;
735: break;
736: case ex_misc:
737: if (f >= ex->frames-1)
738: {
739: ex->type = ex_free;
740: break;
741: }
742: ent->alpha = 1.0 - frac/(ex->frames-1);
743: break;
744: case ex_flash:
745: if (f >= 1)
746: {
747: ex->type = ex_free;
748: break;
749: }
750: ent->alpha = 1.0;
751: break;
752: case ex_poly:
753: if (f >= ex->frames-1)
754: {
755: ex->type = ex_free;
756: break;
757: }
758:
759: ent->alpha = (16.0 - (float)f)/16.0;
760:
761: if (f < 10)
762: {
763: ent->skinnum = (f>>1);
764: if (ent->skinnum < 0)
765: ent->skinnum = 0;
766: }
767: else
768: {
769: ent->flags |= RF_TRANSLUCENT;
770: if (f < 13)
771: ent->skinnum = 5;
772: else
773: ent->skinnum = 6;
774: }
775: break;
776: }
777:
778: if (ex->type == ex_free)
779: continue;
780: if (ex->light)
781: {
782: V_AddLight (ent->origin, ex->light*ent->alpha,
783: ex->lightcolor[0], ex->lightcolor[1], ex->lightcolor[2]);
784: }
785:
786: VectorCopy (ent->origin, ent->oldorigin);
787:
788: if (f < 0)
789: f = 0;
790: ent->frame = ex->baseframe + f + 1;
791: ent->oldframe = ex->baseframe + f;
792: ent->backlerp = 1.0 - cl.lerpfrac;
793:
794: V_AddEntity (ent);
795: }
796: }
797:
798:
799: /*
800: =================
801: CL_AddLasers
802: =================
803: */
804: void CL_AddLasers (void)
805: {
806: laser_t *l;
807: int i;
808:
809: for (i=0, l=cl_lasers ; i< MAX_LASERS ; i++, l++)
810: {
811: if (l->endtime >= cl.time)
812: V_AddEntity (&l->ent);
813: }
814: }
815:
816:
817: /*
818: =================
819: CL_AddTEnts
820: =================
821: */
822: void CL_AddTEnts (void)
823: {
824: CL_AddBeams ();
825: CL_AddExplosions ();
826: CL_AddLasers ();
827: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.