|
|
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)
198: {
199: Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
200: return;
201: }
202:
203: // parse maxclients
204: cl.maxclients = MSG_ReadByte ();
205: if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
206: {
207: Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
208: return;
209: }
210: cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
211:
212: // parse gametype
213: cl.gametype = MSG_ReadByte ();
214:
215: // parse signon message
216: str = MSG_ReadString ();
217: strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
218:
219: // seperate the printfs so the server message can have a color
220: 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");
221: Con_Printf ("%c%s\n", 2, str);
222:
223: //
224: // first we go through and touch all of the precache data that still
225: // happens to be in the cache, so precaching something else doesn't
226: // needlessly purge it
227: //
228:
229: // precache models
230: memset (cl.model_precache, 0, sizeof(cl.model_precache));
231: for (nummodels=1 ; ; nummodels++)
232: {
233: str = MSG_ReadString ();
234: if (!str[0])
235: break;
236: if (nummodels==MAX_MODELS)
237: {
238: Con_Printf ("Server sent too many model precaches\n");
239: return;
240: }
241: strcpy (model_precache[nummodels], str);
242: Mod_TouchModel (str);
243: }
244:
245: // precache sounds
246: memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
247: for (numsounds=1 ; ; numsounds++)
248: {
249: str = MSG_ReadString ();
250: if (!str[0])
251: break;
252: if (numsounds==MAX_SOUNDS)
253: {
254: Con_Printf ("Server sent too many sound precaches\n");
255: return;
256: }
257: strcpy (sound_precache[numsounds], str);
258: S_TouchSound (str);
259: }
260:
261: //
262: // now we try to load everything else until a cache allocation fails
263: //
264: for (i=1 ; i<nummodels ; i++)
265: {
266: cl.model_precache[i] = Mod_ForName (model_precache[i], false);
267: if (cl.model_precache[i] == NULL)
268: {
269: Con_Printf("Model %s not found\n", model_precache[i]);
270: return;
271: }
272: CL_KeepaliveMessage ();
273: }
274:
275: for (i=1 ; i<numsounds ; i++)
276: {
277: cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
278: CL_KeepaliveMessage ();
279: }
280:
281:
282: // local state
283: cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
284:
285: R_NewMap ();
286:
287: Hunk_Check (); // make sure nothing is hurt
288:
289: noclip_anglehack = false; // noclip is turned off at start
290: }
291:
292:
293: /*
294: ==================
295: CL_ParseUpdate
296:
297: Parse an entity update message from the server
298: If an entities model or origin changes from frame to frame, it must be
299: relinked. Other attributes can change without relinking.
300: ==================
301: */
302: int bitcounts[16];
303:
304: void CL_ParseUpdate (int bits)
305: {
306: int i;
307: model_t *model;
308: int modnum;
309: qboolean forcelink;
310: entity_t *ent;
311: int num;
312:
313: if (cls.signon == SIGNONS - 1)
314: { // first update is the final signon stage
315: cls.signon = SIGNONS;
316: CL_SignonReply ();
317: }
318:
319: if (bits & U_MOREBITS)
320: {
321: i = MSG_ReadByte ();
322: bits |= (i<<8);
323: }
324:
325: if (bits & U_LONGENTITY)
326: num = MSG_ReadShort ();
327: else
328: num = MSG_ReadByte ();
329:
330: ent = CL_EntityNum (num);
331:
332: for (i=0 ; i<16 ; i++)
333: if (bits&(1<<i))
334: bitcounts[i]++;
335:
336: if (ent->msgtime != cl.mtime[1])
337: forcelink = true; // no previous frame to lerp from
338: else
339: forcelink = false;
340:
341: ent->msgtime = cl.mtime[0];
342:
343: if (bits & U_MODEL)
344: {
345: modnum = MSG_ReadByte ();
346: if (modnum >= MAX_MODELS)
347: Host_Error ("CL_ParseModel: bad modnum");
348: }
349: else
350: modnum = ent->baseline.modelindex;
351:
352: model = cl.model_precache[modnum];
353: if (model != ent->model)
354: {
355: ent->model = model;
356: // automatic animation (torches, etc) can be either all together
357: // or randomized
358: if (model)
359: {
360: if (model->synctype == ST_RAND)
361: ent->syncbase = (float)(rand()&0x7fff) / 0x7fff;
362: else
363: ent->syncbase = 0.0;
364: }
365: else
366: forcelink = true; // hack to make null model players work
367: }
368:
369: if (bits & U_FRAME)
370: ent->frame = MSG_ReadByte ();
371: else
372: ent->frame = ent->baseline.frame;
373:
374: if (bits & U_COLORMAP)
375: i = MSG_ReadByte();
376: else
377: i = ent->baseline.colormap;
378: if (!i)
379: ent->colormap = vid.colormap;
380: else
381: {
382: if (i > cl.maxclients)
383: Sys_Error ("i >= cl.maxclients");
384: ent->colormap = cl.scores[i-1].translations;
385: }
386:
387: if (bits & U_SKIN)
388: ent->skinnum = MSG_ReadByte();
389: else
390: ent->skinnum = ent->baseline.skin;
391:
392: if (bits & U_EFFECTS)
393: ent->effects = MSG_ReadByte();
394: else
395: ent->effects = ent->baseline.effects;
396:
397: // shift the known values for interpolation
398: VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
399: VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
400:
401: if (bits & U_ORIGIN1)
402: ent->msg_origins[0][0] = MSG_ReadCoord ();
403: else
404: ent->msg_origins[0][0] = ent->baseline.origin[0];
405: if (bits & U_ANGLE1)
406: ent->msg_angles[0][0] = MSG_ReadAngle();
407: else
408: ent->msg_angles[0][0] = ent->baseline.angles[0];
409:
410: if (bits & U_ORIGIN2)
411: ent->msg_origins[0][1] = MSG_ReadCoord ();
412: else
413: ent->msg_origins[0][1] = ent->baseline.origin[1];
414: if (bits & U_ANGLE2)
415: ent->msg_angles[0][1] = MSG_ReadAngle();
416: else
417: ent->msg_angles[0][1] = ent->baseline.angles[1];
418:
419: if (bits & U_ORIGIN3)
420: ent->msg_origins[0][2] = MSG_ReadCoord ();
421: else
422: ent->msg_origins[0][2] = ent->baseline.origin[2];
423: if (bits & U_ANGLE3)
424: ent->msg_angles[0][2] = MSG_ReadAngle();
425: else
426: ent->msg_angles[0][2] = ent->baseline.angles[2];
427:
428: if ( bits & U_NOLERP )
429: ent->forcelink = true;
430:
431: if ( forcelink )
432: { // didn't have an update last message
433: VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
434: VectorCopy (ent->msg_origins[0], ent->origin);
435: VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
436: VectorCopy (ent->msg_angles[0], ent->angles);
437: ent->forcelink = true;
438: }
439: }
440:
441: /*
442: ==================
443: CL_ParseBaseline
444: ==================
445: */
446: void CL_ParseBaseline (entity_t *ent)
447: {
448: int i;
449:
450: ent->baseline.modelindex = MSG_ReadByte ();
451: ent->baseline.frame = MSG_ReadByte ();
452: ent->baseline.colormap = MSG_ReadByte();
453: ent->baseline.skin = MSG_ReadByte();
454: for (i=0 ; i<3 ; i++)
455: {
456: ent->baseline.origin[i] = MSG_ReadCoord ();
457: ent->baseline.angles[i] = MSG_ReadAngle ();
458: }
459: }
460:
461:
462: /*
463: ==================
464: CL_ParseClientdata
465:
466: Server information pertaining to this client only
467: ==================
468: */
469: void CL_ParseClientdata (int bits)
470: {
471: int i, j;
472:
473: if (bits & SU_VIEWHEIGHT)
474: cl.viewheight = MSG_ReadChar ();
475: else
476: cl.viewheight = DEFAULT_VIEWHEIGHT;
477:
478: if (bits & SU_IDEALPITCH)
479: cl.idealpitch = MSG_ReadChar ();
480: else
481: cl.idealpitch = 0;
482:
483: VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
484: for (i=0 ; i<3 ; i++)
485: {
486: if (bits & (SU_PUNCH1<<i) )
487: cl.punchangle[i] = MSG_ReadChar();
488: else
489: cl.punchangle[i] = 0;
490: if (bits & (SU_VELOCITY1<<i) )
491: cl.mvelocity[0][i] = MSG_ReadChar()*16;
492: else
493: cl.mvelocity[0][i] = 0;
494: }
495:
496: if (bits & SU_ITEMS)
497: i = MSG_ReadLong ();
498: else
499: i = DEFAULT_ITEMS;
500: if (cl.items != i)
501: { // set flash times
502: Sbar_Changed ();
503: for (j=0 ; j<32 ; j++)
504: if ( (i & (1<<j)) && !(cl.items & (1<<j)))
505: cl.item_gettime[j] = cl.time;
506: cl.items = i;
507: }
508:
509: cl.onground = (bits & SU_ONGROUND) != 0;
510: cl.inwater = (bits & SU_INWATER) != 0;
511:
512: if (bits & SU_WEAPONFRAME)
513: cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
514: else
515: cl.stats[STAT_WEAPONFRAME] = 0;
516:
517: if (bits & SU_ARMOR)
518: i = MSG_ReadByte ();
519: else
520: i = 0;
521: if (cl.stats[STAT_ARMOR] != i)
522: {
523: cl.stats[STAT_ARMOR] = i;
524: Sbar_Changed ();
525: }
526:
527: if (bits & SU_WEAPON)
528: i = MSG_ReadByte ();
529: else
530: i = 0;
531: if (cl.stats[STAT_WEAPON] != i)
532: {
533: cl.stats[STAT_WEAPON] = i;
534: Sbar_Changed ();
535: }
536:
537: i = MSG_ReadShort ();
538: if (cl.stats[STAT_HEALTH] != i)
539: {
540: cl.stats[STAT_HEALTH] = i;
541: Sbar_Changed ();
542: }
543:
544: i = MSG_ReadByte ();
545: if (cl.stats[STAT_AMMO] != i)
546: {
547: cl.stats[STAT_AMMO] = i;
548: Sbar_Changed ();
549: }
550:
551: for (i=0 ; i<4 ; i++)
552: {
553: j = MSG_ReadByte ();
554: if (cl.stats[STAT_SHELLS+i] != j)
555: {
556: cl.stats[STAT_SHELLS+i] = j;
557: Sbar_Changed ();
558: }
559: }
560:
561: i = MSG_ReadByte ();
562: if (cl.stats[STAT_ACTIVEWEAPON] != i)
563: {
564: cl.stats[STAT_ACTIVEWEAPON] = i;
565: Sbar_Changed ();
566: }
567:
568: }
569:
570: /*
571: =====================
572: CL_NewTranslation
573: =====================
574: */
575: void CL_NewTranslation (int slot)
576: {
577: int i, j;
578: int top, bottom;
579: byte *dest, *source;
580:
581: if (slot > cl.maxclients)
582: Sys_Error ("CL_NewTranslation: slot > cl.maxclients");
583: dest = cl.scores[slot].translations;
584: source = vid.colormap;
585: memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations));
586: top = cl.scores[slot].colors & 0xf0;
587: bottom = (cl.scores[slot].colors &15)<<4;
588:
589: for (i=0 ; i<VID_GRADES ; i++, dest += 256, source+=256)
590: {
591: if (top < 128) // the artists made some backwards ranges. sigh.
592: memcpy (dest + TOP_RANGE, source + top, 16);
593: else
594: for (j=0 ; j<16 ; j++)
595: dest[TOP_RANGE+j] = source[top+15-j];
596:
597: if (bottom < 128)
598: memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
599: else
600: for (j=0 ; j<16 ; j++)
601: dest[BOTTOM_RANGE+j] = source[bottom+15-j];
602: }
603: }
604:
605: /*
606: =====================
607: CL_ParseStatic
608: =====================
609: */
610: void CL_ParseStatic (void)
611: {
612: entity_t *ent;
613: int i;
614:
615: i = cl.num_statics;
616: if (i >= MAX_STATIC_ENTITIES)
617: Host_Error ("Too many static entities");
618: ent = &cl_static_entities[i];
619: cl.num_statics++;
620: CL_ParseBaseline (ent);
621:
622: // copy it to the current state
623: ent->model = cl.model_precache[ent->baseline.modelindex];
624: ent->frame = ent->baseline.frame;
625: ent->colormap = vid.colormap;
626: ent->skinnum = ent->baseline.skin;
627: ent->effects = ent->baseline.effects;
628:
629: VectorCopy (ent->baseline.origin, ent->origin);
630: VectorCopy (ent->baseline.angles, ent->angles);
631: R_AddEfrags (ent);
632: }
633:
634: /*
635: ===================
636: CL_ParseStaticSound
637: ===================
638: */
639: void CL_ParseStaticSound (void)
640: {
641: vec3_t org;
642: int sound_num, vol, atten;
643: int i;
644:
645: for (i=0 ; i<3 ; i++)
646: org[i] = MSG_ReadCoord ();
647: sound_num = MSG_ReadByte ();
648: vol = MSG_ReadByte ();
649: atten = MSG_ReadByte ();
650:
651: S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
652: }
653:
654:
655: #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
656:
657: /*
658: =====================
659: CL_ParseServerMessage
660: =====================
661: */
662: void CL_ParseServerMessage (void)
663: {
664: int cmd;
665: int i;
666:
667: //
668: // if recording demos, copy the message out
669: //
670: if (cl_shownet.value == 1)
671: Con_Printf ("%i ",net_message.cursize);
672: else if (cl_shownet.value == 2)
673: Con_Printf ("------------------\n");
674:
675: cl.onground = false; // unless the server says otherwise
676: //
677: // parse the message
678: //
679: MSG_BeginReading ();
680:
681: while (1)
682: {
683: if (msg_badread)
684: Host_Error ("CL_ParseServerMessage: Bad server message");
685:
686: cmd = MSG_ReadByte ();
687:
688: if (cmd == -1)
689: {
690: SHOWNET("END OF MESSAGE");
691: return; // end of message
692: }
693:
694: // if the high bit of the command byte is set, it is a fast update
695: if (cmd & 128)
696: {
697: SHOWNET("fast update");
698: CL_ParseUpdate (cmd&127);
699: continue;
700: }
701:
702: SHOWNET(svc_strings[cmd]);
703:
704: // other commands
705: switch (cmd)
706: {
707: default:
708: Host_Error ("CL_ParseServerMessage: Illegible server message\n");
709: break;
710:
711: case svc_nop:
712: // Con_Printf ("svc_nop\n");
713: break;
714:
715: case svc_time:
716: cl.mtime[1] = cl.mtime[0];
717: cl.mtime[0] = MSG_ReadFloat ();
718: break;
719:
720: case svc_clientdata:
721: i = MSG_ReadShort ();
722: CL_ParseClientdata (i);
723: break;
724:
725: case svc_version:
726: i = MSG_ReadLong ();
727: if (i != PROTOCOL_VERSION)
728: Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
729: break;
730:
731: case svc_disconnect:
732: Host_EndGame ("Server disconnected\n");
733:
734: case svc_print:
735: Con_Printf ("%s", MSG_ReadString ());
736: break;
737:
738: case svc_centerprint:
739: SCR_CenterPrint (MSG_ReadString ());
740: break;
741:
742: case svc_stufftext:
743: Cbuf_AddText (MSG_ReadString ());
744: break;
745:
746: case svc_damage:
747: V_ParseDamage ();
748: break;
749:
750: case svc_serverinfo:
751: CL_ParseServerInfo ();
752: vid.recalc_refdef = true; // leave intermission full screen
753: break;
754:
755: case svc_setangle:
756: for (i=0 ; i<3 ; i++)
757: cl.viewangles[i] = MSG_ReadAngle ();
758: break;
759:
760: case svc_setview:
761: cl.viewentity = MSG_ReadShort ();
762: break;
763:
764: case svc_lightstyle:
765: i = MSG_ReadByte ();
766: if (i >= MAX_LIGHTSTYLES)
767: Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
768: Q_strcpy (cl_lightstyle[i].map, MSG_ReadString());
769: cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
770: break;
771:
772: case svc_sound:
773: CL_ParseStartSoundPacket();
774: break;
775:
776: case svc_stopsound:
777: i = MSG_ReadShort();
778: S_StopSound(i>>3, i&7);
779: break;
780:
781: case svc_updatename:
782: Sbar_Changed ();
783: i = MSG_ReadByte ();
784: if (i >= cl.maxclients)
785: Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
786: strcpy (cl.scores[i].name, MSG_ReadString ());
787: break;
788:
789: case svc_updatefrags:
790: Sbar_Changed ();
791: i = MSG_ReadByte ();
792: if (i >= cl.maxclients)
793: Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
794: cl.scores[i].frags = MSG_ReadShort ();
795: break;
796:
797: case svc_updatecolors:
798: Sbar_Changed ();
799: i = MSG_ReadByte ();
800: if (i >= cl.maxclients)
801: Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
802: cl.scores[i].colors = MSG_ReadByte ();
803: CL_NewTranslation (i);
804: break;
805:
806: case svc_particle:
807: R_ParseParticleEffect ();
808: break;
809:
810: case svc_spawnbaseline:
811: i = MSG_ReadShort ();
812: // must use CL_EntityNum() to force cl.num_entities up
813: CL_ParseBaseline (CL_EntityNum(i));
814: break;
815: case svc_spawnstatic:
816: CL_ParseStatic ();
817: break;
818: case svc_temp_entity:
819: CL_ParseTEnt ();
820: break;
821:
822: case svc_setpause:
823: cl.paused = MSG_ReadByte ();
824: if (cl.paused)
825: CDAudio_Stop();
826: else
827: CDAudio_Resume();
828: break;
829:
830: case svc_signonnum:
831: i = MSG_ReadByte ();
832: if (i <= cls.signon)
833: Host_Error ("Received signon %i when at %i", i, cls.signon);
834: cls.signon = i;
835: CL_SignonReply ();
836: break;
837:
838: case svc_killedmonster:
839: cl.stats[STAT_MONSTERS]++;
840: break;
841:
842: case svc_foundsecret:
843: cl.stats[STAT_SECRETS]++;
844: break;
845:
846: case svc_updatestat:
847: i = MSG_ReadByte ();
848: if (i < 0 || i >= MAX_CL_STATS)
849: Sys_Error ("svc_updatestat: %i is invalid", i);
850: cl.stats[i] = MSG_ReadLong ();;
851: break;
852:
853: case svc_spawnstaticsound:
854: CL_ParseStaticSound ();
855: break;
856:
857: case svc_cdtrack:
858: cl.cdtrack = MSG_ReadByte ();
859: cl.looptrack = MSG_ReadByte ();
860: if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
861: CDAudio_Play ((byte)cls.forcetrack, true);
862: else
863: CDAudio_Play ((byte)cl.cdtrack, true);
864: break;
865:
866: case svc_intermission:
867: cl.intermission = 1;
868: cl.completed_time = cl.time;
869: vid.recalc_refdef = true; // go to full screen
870: break;
871:
872: case svc_finale:
873: cl.intermission = 2;
874: cl.completed_time = cl.time;
875: vid.recalc_refdef = true; // go to full screen
876: SCR_CenterPrint (MSG_ReadString ());
877: break;
878:
879: case svc_sellscreen:
880: Cmd_ExecuteString ("help", src_command);
881: break;
882: }
883: }
884: }
885:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.