2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 // cl_parse.c -- parse a message received from the server
30 "svc_version", // [long] server version
31 "svc_setview", // [short] entity number
32 "svc_sound", // <see code>
33 "svc_time", // [float] server time
34 "svc_print", // [string] null terminated string
35 "svc_stufftext", // [string] stuffed into client's console buffer
36 // the string should be \n terminated
37 "svc_setangle", // [vec3] set the view angle to this absolute value
39 "svc_serverinfo", // [long] version
40 // [string] signon string
41 // [string]..[0]model cache [string]...[0]sounds cache
42 // [string]..[0]item cache
43 "svc_lightstyle", // [byte] [string]
44 "svc_updatename", // [byte] [string]
45 "svc_updatefrags", // [byte] [short]
46 "svc_clientdata", // <shortbits + data>
47 "svc_stopsound", // <see code>
48 "svc_updatecolors", // [byte] [byte]
49 "svc_particle", // [vec3] <variable>
50 "svc_damage", // [byte] impact [byte] blood [vec3] from
53 "OBSOLETE svc_spawnbinary",
56 "svc_temp_entity", // <variable>
62 "svc_spawnstaticsound",
64 "svc_finale", // [string] music [string] text
65 "svc_cdtrack", // [byte] track [byte] looptrack
68 "svc_showlmp", // [string] iconlabel [string] lmpfile [byte] x [byte] y
69 "svc_hidelmp", // [string] iconlabel
70 "svc_skybox", // [string] skyname
83 "svc_farclip", // [coord] size
84 "svc_fog" // [byte] enable <optional past this point, only included if enable is true> [short * 4096] density [byte] red [byte] green [byte] blue
87 //=============================================================================
89 int Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
95 This error checks and tracks the total number of entities
98 entity_t *CL_EntityNum (int num)
100 if (num >= cl.num_entities)
102 if (num >= MAX_EDICTS)
103 Host_Error ("CL_EntityNum: %i is an invalid number",num);
104 while (cl.num_entities<=num)
106 cl_entities[cl.num_entities].colormap = 0; //vid.colormap;
111 return &cl_entities[num];
117 CL_ParseStartSoundPacket
120 void CL_ParseStartSoundPacket(void)
130 field_mask = MSG_ReadByte();
132 if (field_mask & SND_VOLUME)
133 volume = MSG_ReadByte ();
135 volume = DEFAULT_SOUND_PACKET_VOLUME;
137 if (field_mask & SND_ATTENUATION)
138 attenuation = MSG_ReadByte () / 64.0;
140 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
142 channel = MSG_ReadShort ();
143 sound_num = MSG_ReadByte ();
148 if (ent > MAX_EDICTS)
149 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
151 for (i=0 ; i<3 ; i++)
152 pos[i] = MSG_ReadCoord ();
154 S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
161 When the client is taking a long time to load stuff, send keepalive messages
162 so the server doesn't disconnect.
165 void CL_KeepaliveMessage (void)
168 static float lastmsg;
174 return; // no need if server is local
175 if (cls.demoplayback)
178 // read messages from server, should just be nops
180 memcpy (olddata, net_message.data, net_message.cursize);
184 ret = CL_GetMessage ();
188 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
190 break; // nothing waiting
192 Host_Error ("CL_KeepaliveMessage: received a message");
195 if (MSG_ReadByte() != svc_nop)
196 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
202 memcpy (net_message.data, olddata, net_message.cursize);
205 time = Sys_FloatTime ();
206 if (time - lastmsg < 5)
211 Con_Printf ("--> client to server keepalive\n");
213 MSG_WriteByte (&cls.message, clc_nop);
214 NET_SendMessage (cls.netcon, &cls.message);
215 SZ_Clear (&cls.message);
218 extern qboolean isworldmodel;
219 extern char skyname[];
220 extern float fog_density;
221 extern float fog_red;
222 extern float fog_green;
223 extern float fog_blue;
224 extern void R_SetSkyBox (char *sky);
225 extern void FOG_clear();
226 extern cvar_t r_farclip;
228 void CL_ParseEntityLump(char *entdata)
231 char key[128], value[1024];
234 FOG_clear(); // LordHavoc: no fog until set
235 skyname[0] = 0; // LordHavoc: no enviroment mapped sky until set
236 r_farclip.value = 6144; // LordHavoc: default farclip distance
240 data = COM_Parse(data);
242 return; // valid exit
243 if (com_token[0] != '{')
247 data = COM_Parse(data);
250 if (com_token[0] == '}')
251 return; // since we're just parsing the first ent (worldspawn), exit
252 strcpy(key, com_token);
253 while (key[strlen(key)-1] == ' ') // remove trailing spaces
254 key[strlen(key)-1] = 0;
255 data = COM_Parse(data);
258 strcpy(value, com_token);
259 if (!strcmp("sky", key))
261 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
263 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
265 else if (!strcmp("farclip", key))
267 r_farclip.value = atof(value);
268 if (r_farclip.value < 64)
269 r_farclip.value = 64;
271 else if (!strcmp("fog", key))
273 scanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
276 else if (!strcmp("fog_density", key))
277 fog_density = atof(value);
278 else if (!strcmp("fog_red", key))
279 fog_red = atof(value);
280 else if (!strcmp("fog_green", key))
281 fog_green = atof(value);
282 else if (!strcmp("fog_blue", key))
283 fog_blue = atof(value);
284 else if (!strcmp("wad", key)) // for HalfLife maps
287 for (i = 0;i < 128;i++)
288 if (value[i] != ';' && value[i] != '\\' && value[i] != '/' && value[i] != ':')
294 // ignore path - the \\ check is for HalfLife... stupid windoze 'programmers'...
295 if (value[i] == '\\' || value[i] == '/' || value[i] == ':')
297 else if (value[i] == ';' || value[i] == 0)
301 strcpy(wadname, "textures/");
302 strcat(wadname, &value[j]);
303 W_LoadTextureWadFile (wadname, FALSE);
319 extern cvar_t demo_nehahra;
320 void CL_ParseServerInfo (void)
324 int nummodels, numsounds;
325 char model_precache[MAX_MODELS][MAX_QPATH];
326 char sound_precache[MAX_SOUNDS][MAX_QPATH];
328 Con_DPrintf ("Serverinfo packet received.\n");
330 // wipe the client_state_t struct
334 // parse protocol version number
336 if (i != PROTOCOL_VERSION && i != 250)
338 Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
341 Nehahrademcompatibility = false;
343 Nehahrademcompatibility = true;
344 if (cls.demoplayback && demo_nehahra.value)
345 Nehahrademcompatibility = true;
348 cl.maxclients = MSG_ReadByte ();
349 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
351 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
354 cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
357 cl.gametype = MSG_ReadByte ();
359 // parse signon message
360 str = MSG_ReadString ();
361 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
363 // seperate the printfs so the server message can have a color
364 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
366 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");
367 Con_Printf ("%c%s\n", 2, str);
371 // first we go through and touch all of the precache data that still
372 // happens to be in the cache, so precaching something else doesn't
373 // needlessly purge it
377 memset (cl.model_precache, 0, sizeof(cl.model_precache));
378 for (nummodels=1 ; ; nummodels++)
380 str = MSG_ReadString ();
383 if (nummodels==MAX_MODELS)
385 Con_Printf ("Server sent too many model precaches\n");
388 strcpy (model_precache[nummodels], str);
389 Mod_TouchModel (str);
393 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
394 for (numsounds=1 ; ; numsounds++)
396 str = MSG_ReadString ();
399 if (numsounds==MAX_SOUNDS)
401 Con_Printf ("Server sent too many sound precaches\n");
404 strcpy (sound_precache[numsounds], str);
409 // now we try to load everything else until a cache allocation fails
412 for (i=1 ; i<nummodels ; i++)
414 isworldmodel = i == 1; // LordHavoc: first model is the world model
415 cl.model_precache[i] = Mod_ForName (model_precache[i], false);
416 if (cl.model_precache[i] == NULL)
418 Con_Printf("Model %s not found\n", model_precache[i]);
421 CL_KeepaliveMessage ();
424 S_BeginPrecaching ();
425 for (i=1 ; i<numsounds ; i++)
427 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
428 CL_KeepaliveMessage ();
434 cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
438 Hunk_Check (); // make sure nothing is hurt
440 noclip_anglehack = false; // noclip is turned off at start
448 Parse an entity update message from the server
449 If an entities model or origin changes from frame to frame, it must be
450 relinked. Other attributes can change without relinking.
455 void CL_ParseUpdate (int bits)
457 int i, modnum, num, skin, alpha, scale, glowsize, glowcolor, colormod;
461 entity_state_t *baseline;
463 if (cls.signon == SIGNONS - 1)
464 { // first update is the final signon stage
465 cls.signon = SIGNONS;
469 if (bits & U_MOREBITS)
474 if (bits & U_EXTEND1 && !Nehahrademcompatibility)
476 bits |= MSG_ReadByte() << 16;
477 if (bits & U_EXTEND2)
478 bits |= MSG_ReadByte() << 24;
481 if (bits & U_LONGENTITY)
482 num = MSG_ReadShort ();
484 num = MSG_ReadByte ();
486 ent = CL_EntityNum (num);
488 //for (i=0 ; i<16 ; i++)
492 forcelink = ent->msgtime != cl.mtime[1]; // no previous frame to lerp from
494 ent->msgtime = cl.mtime[0];
496 // LordHavoc: new protocol stuff
497 baseline = &ent->baseline;
499 baseline = &ent->deltabaseline;
501 modnum = bits & U_MODEL ? MSG_ReadByte() : baseline->modelindex;
502 if (modnum >= MAX_MODELS)
503 Host_Error ("CL_ParseModel: bad modnum");
504 ent->deltabaseline.modelindex = modnum;
506 model = cl.model_precache[modnum];
507 if (model != ent->model)
510 // automatic animation (torches, etc) can be either all together
513 ent->syncbase = model->synctype == ST_RAND ? (float)(rand()&0x7fff) / 0x7fff : 0.0;
515 forcelink = true; // hack to make null model players work
516 if (num > 0 && num <= cl.maxclients)
517 R_TranslatePlayerSkin(num - 1);
520 ent->frame = ((bits & U_FRAME) ? MSG_ReadByte() : (baseline->frame & 0xFF));
522 i = bits & U_COLORMAP ? MSG_ReadByte() : baseline->colormap;
523 ent->deltabaseline.colormap = i;
525 ent->colormap = 0; //vid.colormap;
528 if (i > cl.maxclients)
529 Host_Error ("i >= cl.maxclients");
530 ent->colormap = i; //vid.colormap; // cl.scores[i-1].translations;
533 skin = bits & U_SKIN ? MSG_ReadByte() : baseline->skin;
534 if (skin != ent->skinnum)
537 if (num > 0 && num <= cl.maxclients)
538 R_TranslatePlayerSkin(num - 1);
540 ent->deltabaseline.skin = skin;
542 ent->effects = ((bits & U_EFFECTS) ? MSG_ReadByte() : (baseline->effects & 0xFF));
544 // shift the known values for interpolation
545 VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
546 VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
547 VectorCopy (baseline->origin, ent->msg_origins[0]);
548 VectorCopy (baseline->angles, ent->msg_angles[0]);
550 if (bits & U_ORIGIN1) ent->msg_origins[0][0] = MSG_ReadCoord ();
551 if (bits & U_ANGLE1) ent->msg_angles[0][0] = MSG_ReadAngle();
552 if (bits & U_ORIGIN2) ent->msg_origins[0][1] = MSG_ReadCoord ();
553 if (bits & U_ANGLE2) ent->msg_angles[0][1] = MSG_ReadAngle();
554 if (bits & U_ORIGIN3) ent->msg_origins[0][2] = MSG_ReadCoord ();
555 if (bits & U_ANGLE3) ent->msg_angles[0][2] = MSG_ReadAngle();
557 VectorCopy(ent->msg_origins[0], ent->deltabaseline.origin);
558 VectorCopy(ent->msg_angles[0], ent->deltabaseline.angles);
560 alpha = bits & U_ALPHA ? MSG_ReadByte() : baseline->alpha;
561 scale = bits & U_SCALE ? MSG_ReadByte() : baseline->scale;
562 ent->effects |= ((bits & U_EFFECTS2) ? (MSG_ReadByte() << 8) : (baseline->effects & 0xFF00));
563 glowsize = bits & U_GLOWSIZE ? MSG_ReadByte() : baseline->glowsize;
564 glowcolor = bits & U_GLOWCOLOR ? MSG_ReadByte() : baseline->glowcolor;
565 colormod = bits & U_COLORMOD ? MSG_ReadByte() : baseline->colormod;
566 ent->frame |= ((bits & U_FRAME2) ? (MSG_ReadByte() << 8) : (baseline->frame & 0xFF00));
567 ent->deltabaseline.alpha = alpha;
568 ent->deltabaseline.scale = scale;
569 ent->deltabaseline.effects = ent->effects;
570 ent->deltabaseline.glowsize = glowsize;
571 ent->deltabaseline.glowcolor = glowcolor;
572 ent->deltabaseline.colormod = colormod;
573 ent->deltabaseline.frame = ent->frame;
574 ent->alpha = (float) alpha * (1.0 / 255.0);
575 ent->scale = (float) scale * (1.0 / 16.0);
576 ent->glowsize = glowsize < 128 ? glowsize * 8.0 : (glowsize - 256) * 8.0;
577 ent->glowcolor = glowcolor;
578 ent->colormod[0] = (float) ((colormod >> 5) & 7) * (1.0 / 7.0);
579 ent->colormod[1] = (float) ((colormod >> 2) & 7) * (1.0 / 7.0);
580 ent->colormod[2] = (float) (colormod & 3) * (1.0 / 3.0);
581 if (bits & U_EXTEND1 && Nehahrademcompatibility) // LordHavoc: to allow playback of the early Nehahra movie segments
584 ent->alpha = MSG_ReadFloat();
585 if (i == 2 && MSG_ReadFloat() != 0.0)
586 ent->effects |= EF_FULLBRIGHT;
591 //if ( bits & U_NOLERP )
592 // ent->forcelink = true;
593 //if (bits & U_STEP) // FIXME: implement clientside interpolation of monsters
596 { // didn't have an update last message
597 VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
598 VectorCopy (ent->msg_origins[0], ent->origin);
599 VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
600 VectorCopy (ent->msg_angles[0], ent->angles);
601 ent->forcelink = true;
610 void CL_ParseBaseline (entity_t *ent)
614 ent->baseline.modelindex = MSG_ReadByte ();
615 ent->baseline.frame = MSG_ReadByte ();
616 ent->baseline.colormap = MSG_ReadByte();
617 ent->baseline.skin = MSG_ReadByte();
618 for (i=0 ; i<3 ; i++)
620 ent->baseline.origin[i] = MSG_ReadCoord ();
621 ent->baseline.angles[i] = MSG_ReadAngle ();
623 ent->baseline.alpha = 255;
624 ent->baseline.scale = 16;
625 ent->baseline.glowsize = 0;
626 ent->baseline.glowcolor = 254;
627 ent->baseline.colormod = 255;
635 Server information pertaining to this client only
638 void CL_ParseClientdata (int bits)
642 if (bits & SU_VIEWHEIGHT)
643 cl.viewheight = MSG_ReadChar ();
645 cl.viewheight = DEFAULT_VIEWHEIGHT;
647 if (bits & SU_IDEALPITCH)
648 cl.idealpitch = MSG_ReadChar ();
652 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
653 for (i=0 ; i<3 ; i++)
655 if (bits & (SU_PUNCH1<<i) )
656 cl.punchangle[i] = MSG_ReadChar();
658 cl.punchangle[i] = 0;
659 if (bits & (SU_VELOCITY1<<i) )
660 cl.mvelocity[0][i] = MSG_ReadChar()*16;
662 cl.mvelocity[0][i] = 0;
665 // [always sent] if (bits & SU_ITEMS)
671 for (j=0 ; j<32 ; j++)
672 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
673 cl.item_gettime[j] = cl.time;
677 cl.onground = (bits & SU_ONGROUND) != 0;
678 cl.inwater = (bits & SU_INWATER) != 0;
680 if (bits & SU_WEAPONFRAME)
681 cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
683 cl.stats[STAT_WEAPONFRAME] = 0;
689 if (cl.stats[STAT_ARMOR] != i)
691 cl.stats[STAT_ARMOR] = i;
695 if (bits & SU_WEAPON)
699 if (cl.stats[STAT_WEAPON] != i)
701 cl.stats[STAT_WEAPON] = i;
705 i = MSG_ReadShort ();
706 if (cl.stats[STAT_HEALTH] != i)
708 cl.stats[STAT_HEALTH] = i;
713 if (cl.stats[STAT_AMMO] != i)
715 cl.stats[STAT_AMMO] = i;
719 for (i=0 ; i<4 ; i++)
722 if (cl.stats[STAT_SHELLS+i] != j)
724 cl.stats[STAT_SHELLS+i] = j;
733 if (cl.stats[STAT_ACTIVEWEAPON] != i)
735 cl.stats[STAT_ACTIVEWEAPON] = i;
741 if (cl.stats[STAT_ACTIVEWEAPON] != (1<<i))
743 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
750 =====================
752 =====================
754 void CL_ParseStatic (void)
760 if (i >= MAX_STATIC_ENTITIES)
761 Host_Error ("Too many static entities");
762 ent = &cl_static_entities[i];
764 CL_ParseBaseline (ent);
766 // copy it to the current state
767 ent->model = cl.model_precache[ent->baseline.modelindex];
768 ent->frame = ent->baseline.frame;
769 ent->colormap = 0; //vid.colormap;
770 ent->skinnum = ent->baseline.skin;
771 ent->effects = ent->baseline.effects;
776 ent->glowcolor = 254;
777 ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
779 VectorCopy (ent->baseline.origin, ent->origin);
780 VectorCopy (ent->baseline.angles, ent->angles);
789 void CL_ParseStaticSound (void)
792 int sound_num, vol, atten;
795 for (i=0 ; i<3 ; i++)
796 org[i] = MSG_ReadCoord ();
797 sound_num = MSG_ReadByte ();
798 vol = MSG_ReadByte ();
799 atten = MSG_ReadByte ();
801 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
805 #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
807 extern void SHOWLMP_decodehide();
808 extern void SHOWLMP_decodeshow();
809 extern void R_SetSkyBox(char* sky);
811 extern float fog_density;
812 extern float fog_red;
813 extern float fog_green;
814 extern float fog_blue;
817 =====================
818 CL_ParseServerMessage
819 =====================
821 void CL_ParseServerMessage (void)
827 // if recording demos, copy the message out
829 if (cl_shownet.value == 1)
830 Con_Printf ("%i ",net_message.cursize);
831 else if (cl_shownet.value == 2)
832 Con_Printf ("------------------\n");
834 cl.onground = false; // unless the server says otherwise
843 Host_Error ("CL_ParseServerMessage: Bad server message");
845 cmd = MSG_ReadByte ();
849 SHOWNET("END OF MESSAGE");
850 return; // end of message
853 // if the high bit of the command byte is set, it is a fast update
856 SHOWNET("fast update");
857 CL_ParseUpdate (cmd&127);
861 SHOWNET(svc_strings[cmd]);
867 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
871 // Con_Printf ("svc_nop\n");
875 cl.mtime[1] = cl.mtime[0];
876 cl.mtime[0] = MSG_ReadFloat ();
880 i = MSG_ReadShort ();
881 CL_ParseClientdata (i);
886 if (i != PROTOCOL_VERSION && i != 250)
887 Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
888 Nehahrademcompatibility = i == 250;
892 Host_EndGame ("Server disconnected\n");
895 Con_Printf ("%s", MSG_ReadString ());
898 case svc_centerprint:
899 SCR_CenterPrint (MSG_ReadString ());
903 Cbuf_AddText (MSG_ReadString ());
911 CL_ParseServerInfo ();
912 vid.recalc_refdef = true; // leave intermission full screen
916 for (i=0 ; i<3 ; i++)
917 cl.viewangles[i] = MSG_ReadAngle ();
921 cl.viewentity = MSG_ReadShort ();
926 if (i >= MAX_LIGHTSTYLES)
927 Host_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
928 strcpy (cl_lightstyle[i].map, MSG_ReadString());
929 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
933 CL_ParseStartSoundPacket();
938 S_StopSound(i>>3, i&7);
944 if (i >= cl.maxclients)
945 Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
946 strcpy (cl.scores[i].name, MSG_ReadString ());
949 case svc_updatefrags:
952 if (i >= cl.maxclients)
953 Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
954 cl.scores[i].frags = MSG_ReadShort ();
957 case svc_updatecolors:
960 if (i >= cl.maxclients)
961 Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
962 cl.scores[i].colors = MSG_ReadByte ();
963 R_TranslatePlayerSkin(i);
967 R_ParseParticleEffect ();
970 case svc_spawnbaseline:
971 i = MSG_ReadShort ();
972 // must use CL_EntityNum() to force cl.num_entities up
973 CL_ParseBaseline (CL_EntityNum(i));
975 case svc_spawnstatic:
978 case svc_temp_entity:
984 cl.paused = MSG_ReadByte ();
996 Host_Error ("Received signon %i when at %i", i, cls.signon);
1001 case svc_killedmonster:
1002 cl.stats[STAT_MONSTERS]++;
1005 case svc_foundsecret:
1006 cl.stats[STAT_SECRETS]++;
1009 case svc_updatestat:
1010 i = MSG_ReadByte ();
1011 if (i < 0 || i >= MAX_CL_STATS)
1012 Host_Error ("svc_updatestat: %i is invalid", i);
1013 cl.stats[i] = MSG_ReadLong ();;
1016 case svc_spawnstaticsound:
1017 CL_ParseStaticSound ();
1021 cl.cdtrack = MSG_ReadByte ();
1022 cl.looptrack = MSG_ReadByte ();
1023 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1024 CDAudio_Play ((byte)cls.forcetrack, true);
1026 CDAudio_Play ((byte)cl.cdtrack, true);
1029 case svc_intermission:
1030 cl.intermission = 1;
1031 cl.completed_time = cl.time;
1032 vid.recalc_refdef = true; // go to full screen
1036 cl.intermission = 2;
1037 cl.completed_time = cl.time;
1038 vid.recalc_refdef = true; // go to full screen
1039 SCR_CenterPrint (MSG_ReadString ());
1043 cl.intermission = 3;
1044 cl.completed_time = cl.time;
1045 vid.recalc_refdef = true; // go to full screen
1046 SCR_CenterPrint (MSG_ReadString ());
1049 case svc_sellscreen:
1050 Cmd_ExecuteString ("help", src_command);
1053 SHOWLMP_decodehide();
1056 SHOWLMP_decodeshow();
1058 // LordHavoc: extra worldspawn fields (fog, sky, farclip)
1060 R_SetSkyBox(MSG_ReadString());
1063 r_farclip.value = MSG_ReadCoord();
1068 fog_density = MSG_ReadShort() * (1.0f / 4096.0f);
1069 fog_red = MSG_ReadByte() * (1.0 / 255.0);
1070 fog_green = MSG_ReadByte() * (1.0 / 255.0);
1071 fog_blue = MSG_ReadByte() * (1.0 / 255.0);