|
|
1.1 root 1: // cl_parse.c -- parse a message received from the server
2:
3: #include "quakedef.h"
4:
5: char *svc_strings[] =
6: {
7: "svc_bad",
8: "svc_nop",
9: "svc_disconnect",
10: "svc_updatestat",
11: "svc_version", // [long] server version
12: "svc_setview", // [short] entity number
13: "svc_sound", // <see code>
14: "svc_time", // [float] server time
15: "svc_print", // [string] null terminated string
16: "svc_stufftext", // [string] stuffed into client's console buffer
17: // the string should be \n terminated
18: "svc_setangle", // [vec3] set the view angle to this absolute value
19:
20: "svc_serverinfo", // [long] version
21: // [string] signon string
22: // [string]..[0]model cache [string]...[0]sounds cache
23: // [string]..[0]item cache
24: "svc_lightstyle", // [byte] [string]
25: "svc_updatename", // [byte] [string]
26: "svc_updatefrags", // [byte] [short]
27: "svc_clientdata", // <shortbits + data>
28: "svc_stopsound", // <see code>
29: "svc_updatecolors", // [byte] [byte]
30: "svc_particle", // [vec3] <variable>
31: "svc_damage", // [byte] impact [byte] blood [vec3] from
32:
33: "svc_spawnstatic",
34: "OBSOLETE svc_spawnbinary",
35: "svc_spawnbaseline",
36:
37: "svc_temp_entity", // <variable>
38: "svc_setpause",
39: "svc_signonnum",
40: "svc_centerprint",
41: "svc_killedmonster",
42: "svc_foundsecret",
43: "svc_spawnstaticsound",
44: "svc_intermission"
45: };
46:
47: //=============================================================================
48:
49: /*
50: ===============
51: CL_EntityNum
52:
53: This error checks and tracks the total number of entities
54: ===============
55: */
56: entity_t *CL_EntityNum (int num)
57: {
58: if (num >= cl.num_entities)
59: {
60: if (num >= MAX_EDICTS)
61: Host_Error ("CL_EntityNum: %i is an invalid number",num);
62: while (cl.num_entities<=num)
63: {
64: cl_entities[cl.num_entities].colormap = vid.colormap;
65: cl.num_entities++;
66: }
67: }
68:
69: return &cl_entities[num];
70: }
71:
72:
73: /*
74: ==================
75: CL_ParseStartSoundPacket
76: ==================
77: */
78: void CL_ParseStartSoundPacket(void)
79: {
80: vec3_t pos;
81: int channel, ent;
82: int sound_num;
83: int volume;
84: int field_mask;
85: float attenuation;
86: int i;
87:
88: field_mask = MSG_ReadByte();
89:
90: if (field_mask & SND_VOLUME)
91: volume = MSG_ReadByte ();
92: else
93: volume = DEFAULT_SOUND_PACKET_VOLUME;
94:
95: if (field_mask & SND_ATTENUATION)
96: attenuation = MSG_ReadByte () / 64.0;
97: else
98: attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
99:
100: channel = MSG_ReadShort ();
101: sound_num = MSG_ReadByte ();
102:
103: ent = channel >> 3;
104: channel &= 7;
105:
106: if (ent > MAX_EDICTS)
107: Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
108:
109: for (i=0 ; i<3 ; i++)
110: pos[i] = MSG_ReadCoord ();
111:
112: S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
113: }
114:
115: /*
116: ==================
117: CL_KeepaliveMessage
118:
119: When the client is taking a long time to load stuff, send keepalive messages
120: so the server doesn't disconnect.
121: ==================
122: */
123: void CL_KeepaliveMessage (void)
124: {
125: float time;
126: static float lastmsg;
127: int ret;
128: sizebuf_t old;
129: byte olddata[8192];
130:
131: if (sv.active)
132: return; // no need if server is local
133: if (cls.demoplayback)
134: return;
135:
136: // read messages from server, should just be nops
137: old = net_message;
138: memcpy (olddata, net_message.data, net_message.cursize);
139:
140: do
141: {
142: ret = CL_GetMessage ();
143: switch (ret)
144: {
145: default:
146: Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
147: case 0:
148: break; // nothing waiting
149: case 1:
150: Host_Error ("CL_KeepaliveMessage: received a message");
151: break;
152: case 2:
153: if (MSG_ReadByte() != svc_nop)
154: Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
155: break;
156: }
157: } while (ret);
158:
159: net_message = old;
160: memcpy (net_message.data, olddata, net_message.cursize);
161:
162: // check time
163: time = Sys_FloatTime ();
164: if (time - lastmsg < 5)
165: return;
166: lastmsg = time;
167:
168: // write out a nop
169: Con_Printf ("--> client to server keepalive\n");
170:
171: MSG_WriteByte (&cls.message, clc_nop);
172: NET_SendMessage (cls.netcon, &cls.message);
173: SZ_Clear (&cls.message);
174: }
175:
176: /*
177: ==================
178: CL_ParseServerInfo
179: ==================
180: */
181: void CL_ParseServerInfo (void)
182: {
183: char *str;
184: int i;
185: int nummodels, numsounds;
186: char model_precache[MAX_MODELS][MAX_QPATH];
187: char sound_precache[MAX_SOUNDS][MAX_QPATH];
188:
189: Con_DPrintf ("Serverinfo packet received.\n");
190: //
191: // wipe the client_state_t struct
192: //
193: CL_ClearState ();
194:
195: // parse protocol version number
196: i = MSG_ReadLong ();
197: if (i != PROTOCOL_VERSION)
1.1.1.2 ! root 198: Host_Error ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
1.1 root 199:
200: // parse maxclients
201: cl.maxclients = MSG_ReadByte ();
1.1.1.2 ! root 202: if (cl.maxclients == 0)
! 203: Sys_Error ("Bad maxclients from server");
1.1 root 204: cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
205:
206: // parse gametype
207: cl.gametype = MSG_ReadByte ();
208:
209: // parse signon message
210: str = MSG_ReadString ();
211: strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
212:
213: // seperate the printfs so the server message can have a color
214: Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
215: Con_Printf ("%c%s\n", 2, str);
216:
217: //
218: // first we go through and touch all of the precache data that still
219: // happens to be in the cache, so precaching something else doesn't
220: // needlessly purge it
221: //
222:
223: // precache models
224: memset (cl.model_precache, 0, sizeof(cl.model_precache));
225: for (nummodels=1 ; ; nummodels++)
226: {
227: str = MSG_ReadString ();
228: if (!str[0])
229: break;
230: if (nummodels==MAX_MODELS)
1.1.1.2 ! root 231: Host_Error ("Server sent too many model_precache");
1.1 root 232: strcpy (model_precache[nummodels], str);
233: Mod_TouchModel (str);
234: }
235:
236: // precache sounds
237: memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
238: for (numsounds=1 ; ; numsounds++)
239: {
240: str = MSG_ReadString ();
241: if (!str[0])
242: break;
243: if (numsounds==MAX_SOUNDS)
1.1.1.2 ! root 244: Host_Error ("Server sent too many sound_precache");
1.1 root 245: strcpy (sound_precache[numsounds], str);
246: S_TouchSound (str);
247: }
248:
249: //
250: // now we try to load everything else until a cache allocation fails
251: //
252: for (i=1 ; i<nummodels ; i++)
253: {
1.1.1.2 ! root 254: cl.model_precache[i] = Mod_ForName (model_precache[i], true);
1.1 root 255: CL_KeepaliveMessage ();
256: }
257:
258: for (i=1 ; i<numsounds ; i++)
259: {
260: cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
261: CL_KeepaliveMessage ();
262: }
263:
264:
265: // local state
266: cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
267:
268: R_NewMap ();
269:
270: Hunk_Check (); // make sure nothing is hurt
271:
272: noclip_anglehack = false; // noclip is turned off at start
273: }
274:
275:
276: /*
277: ==================
278: CL_ParseUpdate
279:
280: Parse an entity update message from the server
281: If an entities model or origin changes from frame to frame, it must be
282: relinked. Other attributes can change without relinking.
283: ==================
284: */
285: int bitcounts[16];
286:
287: void CL_ParseUpdate (int bits)
288: {
289: int i;
290: model_t *model;
291: int modnum;
292: qboolean forcelink;
293: entity_t *ent;
294: int num;
295:
296: if (cls.signon == SIGNONS - 1)
297: { // first update is the final signon stage
298: cls.signon = SIGNONS;
299: CL_SignonReply ();
300: }
301:
302: if (bits & U_MOREBITS)
303: {
304: i = MSG_ReadByte ();
305: bits |= (i<<8);
306: }
307:
308: if (bits & U_LONGENTITY)
309: num = MSG_ReadShort ();
310: else
311: num = MSG_ReadByte ();
312:
313: ent = CL_EntityNum (num);
314:
315: for (i=0 ; i<16 ; i++)
316: if (bits&(1<<i))
317: bitcounts[i]++;
318:
319: if (ent->msgtime != cl.mtime[1])
320: forcelink = true; // no previous frame to lerp from
321: else
322: forcelink = false;
323:
324: ent->msgtime = cl.mtime[0];
325:
326: if (bits & U_MODEL)
327: {
328: modnum = MSG_ReadByte ();
329: if (modnum >= MAX_MODELS)
330: Host_Error ("CL_ParseModel: bad modnum");
331: }
332: else
333: modnum = ent->baseline.modelindex;
334:
335: model = cl.model_precache[modnum];
336: if (model != ent->model)
337: {
338: ent->model = model;
339: // automatic animation (torches, etc) can be either all together
340: // or randomized
341: if (model)
342: {
343: if (model->synctype == ST_RAND)
344: ent->syncbase = (float)(rand()&0x7fff) / 0x7fff;
345: else
346: ent->syncbase = 0.0;
347: }
348: else
349: forcelink = true; // hack to make null model players work
350: }
351:
352: if (bits & U_FRAME)
353: ent->frame = MSG_ReadByte ();
354: else
355: ent->frame = ent->baseline.frame;
356:
357: if (bits & U_COLORMAP)
358: i = MSG_ReadByte();
359: else
360: i = ent->baseline.colormap;
361: if (!i)
362: ent->colormap = vid.colormap;
363: else
364: {
365: if (i > cl.maxclients)
366: Sys_Error ("i >= cl.maxclients");
367: ent->colormap = cl.scores[i-1].translations;
368: }
369:
370: if (bits & U_SKIN)
371: ent->skinnum = MSG_ReadByte();
372: else
373: ent->skinnum = ent->baseline.skin;
374:
375: if (bits & U_EFFECTS)
376: ent->effects = MSG_ReadByte();
377: else
378: ent->effects = ent->baseline.effects;
379:
380: // shift the known values for interpolation
381: VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
382: VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
383:
384: if (bits & U_ORIGIN1)
385: ent->msg_origins[0][0] = MSG_ReadCoord ();
386: else
387: ent->msg_origins[0][0] = ent->baseline.origin[0];
388: if (bits & U_ANGLE1)
389: ent->msg_angles[0][0] = MSG_ReadAngle();
390: else
391: ent->msg_angles[0][0] = ent->baseline.angles[0];
392:
393: if (bits & U_ORIGIN2)
394: ent->msg_origins[0][1] = MSG_ReadCoord ();
395: else
396: ent->msg_origins[0][1] = ent->baseline.origin[1];
397: if (bits & U_ANGLE2)
398: ent->msg_angles[0][1] = MSG_ReadAngle();
399: else
400: ent->msg_angles[0][1] = ent->baseline.angles[1];
401:
402: if (bits & U_ORIGIN3)
403: ent->msg_origins[0][2] = MSG_ReadCoord ();
404: else
405: ent->msg_origins[0][2] = ent->baseline.origin[2];
406: if (bits & U_ANGLE3)
407: ent->msg_angles[0][2] = MSG_ReadAngle();
408: else
409: ent->msg_angles[0][2] = ent->baseline.angles[2];
410:
411: if ( bits & U_NOLERP )
412: ent->forcelink = true;
413:
414: if ( forcelink )
415: { // didn't have an update last message
416: VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
417: VectorCopy (ent->msg_origins[0], ent->origin);
418: VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
419: VectorCopy (ent->msg_angles[0], ent->angles);
420: ent->forcelink = true;
421: }
422: }
423:
424: /*
425: ==================
426: CL_ParseBaseline
427: ==================
428: */
429: void CL_ParseBaseline (entity_t *ent)
430: {
431: int i;
432:
433: ent->baseline.modelindex = MSG_ReadByte ();
434: ent->baseline.frame = MSG_ReadByte ();
435: ent->baseline.colormap = MSG_ReadByte();
436: ent->baseline.skin = MSG_ReadByte();
437: for (i=0 ; i<3 ; i++)
438: {
439: ent->baseline.origin[i] = MSG_ReadCoord ();
440: ent->baseline.angles[i] = MSG_ReadAngle ();
441: }
442: }
443:
444:
445: /*
446: ==================
447: CL_ParseClientdata
448:
449: Server information pertaining to this client only
450: ==================
451: */
452: void CL_ParseClientdata (int bits)
453: {
454: int i, j;
455:
456: if (bits & SU_VIEWHEIGHT)
457: cl.viewheight = MSG_ReadChar ();
458: else
459: cl.viewheight = DEFAULT_VIEWHEIGHT;
460:
461: if (bits & SU_IDEALPITCH)
462: cl.idealpitch = MSG_ReadChar ();
463: else
464: cl.idealpitch = 0;
465:
466: VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
467: for (i=0 ; i<3 ; i++)
468: {
469: if (bits & (SU_PUNCH1<<i) )
470: cl.punchangle[i] = MSG_ReadChar();
471: else
472: cl.punchangle[i] = 0;
473: if (bits & (SU_VELOCITY1<<i) )
474: cl.mvelocity[0][i] = MSG_ReadChar()*16;
475: else
476: cl.mvelocity[0][i] = 0;
477: }
478:
479: if (bits & SU_ITEMS)
480: i = MSG_ReadLong ();
481: else
482: i = DEFAULT_ITEMS;
483: if (cl.items != i)
484: { // set flash times
485: Sbar_Changed ();
486: for (j=0 ; j<32 ; j++)
487: if ( (i & (1<<j)) && !(cl.items & (1<<j)))
488: cl.item_gettime[j] = cl.time;
489: cl.items = i;
490: }
491:
492: cl.onground = (bits & SU_ONGROUND) != 0;
493: cl.inwater = (bits & SU_INWATER) != 0;
494:
495: if (bits & SU_WEAPONFRAME)
496: cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
497: else
498: cl.stats[STAT_WEAPONFRAME] = 0;
499:
500: if (bits & SU_ARMOR)
501: i = MSG_ReadByte ();
502: else
503: i = 0;
504: if (cl.stats[STAT_ARMOR] != i)
505: {
506: cl.stats[STAT_ARMOR] = i;
507: Sbar_Changed ();
508: }
509:
510: if (bits & SU_WEAPON)
511: i = MSG_ReadByte ();
512: else
513: i = 0;
514: if (cl.stats[STAT_WEAPON] != i)
515: {
516: cl.stats[STAT_WEAPON] = i;
517: Sbar_Changed ();
518: }
519:
520: i = MSG_ReadShort ();
521: if (cl.stats[STAT_HEALTH] != i)
522: {
523: cl.stats[STAT_HEALTH] = i;
524: Sbar_Changed ();
525: }
526:
527: i = MSG_ReadByte ();
528: if (cl.stats[STAT_AMMO] != i)
529: {
530: cl.stats[STAT_AMMO] = i;
531: Sbar_Changed ();
532: }
533:
534: for (i=0 ; i<4 ; i++)
535: {
536: j = MSG_ReadByte ();
537: if (cl.stats[STAT_SHELLS+i] != j)
538: {
539: cl.stats[STAT_SHELLS+i] = j;
540: Sbar_Changed ();
541: }
542: }
543:
544: i = MSG_ReadByte ();
545: if (cl.stats[STAT_ACTIVEWEAPON] != i)
546: {
547: cl.stats[STAT_ACTIVEWEAPON] = i;
548: Sbar_Changed ();
549: }
550:
551: }
552:
553: /*
554: =====================
555: CL_NewTranslation
556: =====================
557: */
558: void CL_NewTranslation (int slot)
559: {
560: int i, j;
561: int top, bottom;
562: byte *dest, *source;
563:
564: if (slot > cl.maxclients)
565: Sys_Error ("CL_NewTranslation: slot > cl.maxclients");
566: dest = cl.scores[slot].translations;
567: source = vid.colormap;
568: memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations));
569: top = cl.scores[slot].colors & 0xf0;
570: bottom = (cl.scores[slot].colors &15)<<4;
571:
572: for (i=0 ; i<VID_GRADES ; i++, dest += 256, source+=256)
573: {
574: if (top < 128) // the artists made some backwards ranges. sigh.
575: memcpy (dest + TOP_RANGE, source + top, 16);
576: else
577: for (j=0 ; j<16 ; j++)
578: dest[TOP_RANGE+j] = source[top+15-j];
579:
580: if (bottom < 128)
581: memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
582: else
583: for (j=0 ; j<16 ; j++)
584: dest[BOTTOM_RANGE+j] = source[bottom+15-j];
585: }
586: }
587:
588: /*
589: =====================
590: CL_ParseStatic
591: =====================
592: */
593: void CL_ParseStatic (void)
594: {
595: entity_t *ent;
596: int i;
597:
598: i = cl.num_statics;
599: if (i >= MAX_STATIC_ENTITIES)
600: Host_Error ("Too many static entities");
601: ent = &cl_static_entities[i];
602: cl.num_statics++;
603: CL_ParseBaseline (ent);
604:
605: // copy it to the current state
606: ent->model = cl.model_precache[ent->baseline.modelindex];
607: ent->frame = ent->baseline.frame;
608: ent->colormap = vid.colormap;
609: ent->skinnum = ent->baseline.skin;
610: ent->effects = ent->baseline.effects;
611:
612: VectorCopy (ent->baseline.origin, ent->origin);
613: VectorCopy (ent->baseline.angles, ent->angles);
614: R_AddEfrags (ent);
615: }
616:
617: /*
618: ===================
619: CL_ParseStaticSound
620: ===================
621: */
622: void CL_ParseStaticSound (void)
623: {
624: vec3_t org;
625: int sound_num, vol, atten;
626: int i;
627:
628: for (i=0 ; i<3 ; i++)
629: org[i] = MSG_ReadCoord ();
630: sound_num = MSG_ReadByte ();
631: vol = MSG_ReadByte ();
632: atten = MSG_ReadByte ();
633:
634: S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
635: }
636:
637:
638: #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
639:
640: /*
641: =====================
642: CL_ParseServerMessage
643: =====================
644: */
645: void CL_ParseServerMessage (void)
646: {
647: int cmd;
648: int i;
649:
650: //
651: // if recording demos, copy the message out
652: //
653: if (cl_shownet.value == 1)
654: Con_Printf ("%i ",net_message.cursize);
655: else if (cl_shownet.value == 2)
656: Con_Printf ("------------------\n");
657:
658: cl.onground = false; // unless the server says otherwise
659: //
660: // parse the message
661: //
662: MSG_BeginReading ();
663:
664: while (1)
665: {
666: if (msg_badread)
667: Host_Error ("CL_ParseServerMessage: Bad server message");
668:
669: cmd = MSG_ReadByte ();
670:
671: if (cmd == -1)
672: {
673: SHOWNET("END OF MESSAGE");
674: return; // end of message
675: }
676:
677: // if the high bit of the command byte is set, it is a fast update
678: if (cmd & 128)
679: {
680: SHOWNET("fast update");
681: CL_ParseUpdate (cmd&127);
682: continue;
683: }
684:
685: SHOWNET(svc_strings[cmd]);
686:
687: // other commands
688: switch (cmd)
689: {
690: default:
691: Host_Error ("CL_ParseServerMessage: Illegible server message\n");
692: break;
693:
694: case svc_nop:
695: // Con_Printf ("svc_nop\n");
696: break;
697:
698: case svc_time:
699: cl.mtime[1] = cl.mtime[0];
700: cl.mtime[0] = MSG_ReadFloat ();
701: break;
702:
703: case svc_clientdata:
704: i = MSG_ReadShort ();
705: CL_ParseClientdata (i);
706: break;
707:
708: case svc_version:
709: i = MSG_ReadLong ();
710: if (i != PROTOCOL_VERSION)
711: Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
712: break;
713:
714: case svc_disconnect:
715: Host_EndGame ("Server disconnected\n");
716:
717: case svc_print:
1.1.1.2 ! root 718: Con_Printf (MSG_ReadString ());
1.1 root 719: break;
720:
721: case svc_centerprint:
722: SCR_CenterPrint (MSG_ReadString ());
723: break;
724:
725: case svc_stufftext:
726: Cbuf_AddText (MSG_ReadString ());
727: break;
728:
729: case svc_damage:
730: V_ParseDamage ();
731: break;
732:
733: case svc_serverinfo:
734: CL_ParseServerInfo ();
735: vid.recalc_refdef = true; // leave intermission full screen
736: break;
737:
738: case svc_setangle:
739: for (i=0 ; i<3 ; i++)
740: cl.viewangles[i] = MSG_ReadAngle ();
741: break;
742:
743: case svc_setview:
744: cl.viewentity = MSG_ReadShort ();
745: break;
746:
747: case svc_lightstyle:
748: i = MSG_ReadByte ();
749: if (i >= MAX_LIGHTSTYLES)
750: Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
751: Q_strcpy (cl_lightstyle[i].map, MSG_ReadString());
752: cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
753: break;
754:
755: case svc_sound:
756: CL_ParseStartSoundPacket();
757: break;
758:
759: case svc_stopsound:
760: i = MSG_ReadShort();
761: S_StopSound(i>>3, i&7);
762: break;
763:
764: case svc_updatename:
765: Sbar_Changed ();
766: i = MSG_ReadByte ();
767: if (i >= cl.maxclients)
768: Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
769: strcpy (cl.scores[i].name, MSG_ReadString ());
770: break;
771:
772: case svc_updatefrags:
773: Sbar_Changed ();
774: i = MSG_ReadByte ();
775: if (i >= cl.maxclients)
776: Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
777: cl.scores[i].frags = MSG_ReadShort ();
778: break;
779:
780: case svc_updatecolors:
781: Sbar_Changed ();
782: i = MSG_ReadByte ();
783: if (i >= cl.maxclients)
784: Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
785: cl.scores[i].colors = MSG_ReadByte ();
786: CL_NewTranslation (i);
787: break;
788:
789: case svc_particle:
790: R_ParseParticleEffect ();
791: break;
792:
793: case svc_spawnbaseline:
794: i = MSG_ReadShort ();
795: // must use CL_EntityNum() to force cl.num_entities up
796: CL_ParseBaseline (CL_EntityNum(i));
797: break;
798: case svc_spawnstatic:
799: CL_ParseStatic ();
800: break;
801: case svc_temp_entity:
802: CL_ParseTEnt ();
803: break;
804:
805: case svc_setpause:
806: cl.paused = MSG_ReadByte ();
807: if (cl.paused)
808: CDAudio_Stop();
809: else
810: CDAudio_Resume();
811: break;
812:
813: case svc_signonnum:
814: i = MSG_ReadByte ();
815: if (i <= cls.signon)
816: Host_Error ("Received signon %i when at %i", i, cls.signon);
817: cls.signon = i;
818: CL_SignonReply ();
819: break;
820:
821: case svc_killedmonster:
822: cl.stats[STAT_MONSTERS]++;
823: break;
824:
825: case svc_foundsecret:
826: cl.stats[STAT_SECRETS]++;
827: break;
828:
829: case svc_updatestat:
830: i = MSG_ReadByte ();
831: if (i < 0 || i >= MAX_CL_STATS)
832: Sys_Error ("svc_updatestat: %i is invalid", i);
833: cl.stats[i] = MSG_ReadLong ();;
834: break;
835:
836: case svc_spawnstaticsound:
837: CL_ParseStaticSound ();
838: break;
839:
840: case svc_cdtrack:
841: cl.cdtrack = MSG_ReadByte ();
842: cl.looptrack = MSG_ReadByte ();
843: if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
844: CDAudio_Play ((byte)cls.forcetrack, true);
845: else
846: CDAudio_Play ((byte)cl.cdtrack, true);
847: break;
848:
849: case svc_intermission:
850: cl.intermission = 1;
851: cl.completed_time = cl.time;
852: vid.recalc_refdef = true; // go to full screen
853: break;
854:
855: case svc_finale:
856: cl.intermission = 2;
857: cl.completed_time = cl.time;
858: vid.recalc_refdef = true; // go to full screen
859: SCR_CenterPrint (MSG_ReadString ());
860: break;
861:
862: case svc_sellscreen:
863: Cmd_ExecuteString ("help", src_command);
864: break;
865: }
866: }
867: }
868:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.