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