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_skyboxsize", // [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 = 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();
227 void CL_ParseEntityLump(char *entdata)
230 char key[128], value[1024];
233 FOG_clear(); // LordHavoc: no fog until set
234 skyname[0] = 0; // LordHavoc: no enviroment mapped sky until set
235 // r_skyboxsize.value = 4096; // LordHavoc: default skyboxsize
239 data = COM_Parse(data);
241 return; // valid exit
242 if (com_token[0] != '{')
246 data = COM_Parse(data);
249 if (com_token[0] == '}')
250 return; // since we're just parsing the first ent (worldspawn), exit
251 strcpy(key, com_token);
252 while (key[strlen(key)-1] == ' ') // remove trailing spaces
253 key[strlen(key)-1] = 0;
254 data = COM_Parse(data);
257 strcpy(value, com_token);
258 if (!strcmp("sky", key))
260 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
262 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
264 // else if (!strcmp("skyboxsize", key))
266 // r_skyboxsize.value = atof(value);
267 // if (r_skyboxsize.value < 64)
268 // r_skyboxsize.value = 64;
270 else if (!strcmp("fog", key))
272 scanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
275 else if (!strcmp("fog_density", key))
276 fog_density = atof(value);
277 else if (!strcmp("fog_red", key))
278 fog_red = atof(value);
279 else if (!strcmp("fog_green", key))
280 fog_green = atof(value);
281 else if (!strcmp("fog_blue", key))
282 fog_blue = atof(value);
283 else if (!strcmp("wad", key)) // for HalfLife maps
286 for (i = 0;i < 128;i++)
287 if (value[i] != ';' && value[i] != '\\' && value[i] != '/' && value[i] != ':')
293 // ignore path - the \\ check is for HalfLife... stupid windoze 'programmers'...
294 if (value[i] == '\\' || value[i] == '/' || value[i] == ':')
296 else if (value[i] == ';' || value[i] == 0)
300 strcpy(wadname, "textures/");
301 strcat(wadname, &value[j]);
302 W_LoadTextureWadFile (wadname, FALSE);
318 extern cvar_t demo_nehahra;
319 void CL_ParseServerInfo (void)
323 int nummodels, numsounds;
324 char model_precache[MAX_MODELS][MAX_QPATH];
325 char sound_precache[MAX_SOUNDS][MAX_QPATH];
327 Con_DPrintf ("Serverinfo packet received.\n");
329 // wipe the client_state_t struct
333 // parse protocol version number
335 if (i != PROTOCOL_VERSION && i != 250)
337 Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
340 Nehahrademcompatibility = false;
342 Nehahrademcompatibility = true;
343 if (cls.demoplayback && demo_nehahra.value)
344 Nehahrademcompatibility = true;
347 cl.maxclients = MSG_ReadByte ();
348 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
350 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
353 cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
356 cl.gametype = MSG_ReadByte ();
358 // parse signon message
359 str = MSG_ReadString ();
360 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
362 // seperate the printfs so the server message can have a color
363 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
365 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");
366 Con_Printf ("%c%s\n", 2, str);
370 // first we go through and touch all of the precache data that still
371 // happens to be in the cache, so precaching something else doesn't
372 // needlessly purge it
376 memset (cl.model_precache, 0, sizeof(cl.model_precache));
377 for (nummodels=1 ; ; nummodels++)
379 str = MSG_ReadString ();
382 if (nummodels==MAX_MODELS)
384 Con_Printf ("Server sent too many model precaches\n");
387 strcpy (model_precache[nummodels], str);
388 Mod_TouchModel (str);
392 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
393 for (numsounds=1 ; ; numsounds++)
395 str = MSG_ReadString ();
398 if (numsounds==MAX_SOUNDS)
400 Con_Printf ("Server sent too many sound precaches\n");
403 strcpy (sound_precache[numsounds], str);
408 // now we try to load everything else until a cache allocation fails
411 for (i=1 ; i<nummodels ; i++)
413 isworldmodel = i == 1; // LordHavoc: first model is the world model
414 cl.model_precache[i] = Mod_ForName (model_precache[i], false);
415 if (cl.model_precache[i] == NULL)
417 Con_Printf("Model %s not found\n", model_precache[i]);
420 CL_KeepaliveMessage ();
423 S_BeginPrecaching ();
424 for (i=1 ; i<numsounds ; i++)
426 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
427 CL_KeepaliveMessage ();
433 cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
437 Hunk_Check (); // make sure nothing is hurt
439 noclip_anglehack = false; // noclip is turned off at start
447 Parse an entity update message from the server
448 If an entities model or origin changes from frame to frame, it must be
449 relinked. Other attributes can change without relinking.
454 void CL_ParseUpdate (int bits)
456 int i, modnum, num, skin, alpha, scale, glowsize, glowcolor, colormod;
460 entity_state_t *baseline;
462 if (cls.signon == SIGNONS - 1)
463 { // first update is the final signon stage
464 cls.signon = SIGNONS;
468 if (bits & U_MOREBITS)
473 if (bits & U_EXTEND1 && !Nehahrademcompatibility)
475 bits |= MSG_ReadByte() << 16;
476 if (bits & U_EXTEND2)
477 bits |= MSG_ReadByte() << 24;
480 if (bits & U_LONGENTITY)
481 num = MSG_ReadShort ();
483 num = MSG_ReadByte ();
485 ent = CL_EntityNum (num);
487 //for (i=0 ; i<16 ; i++)
491 forcelink = ent->msgtime != cl.mtime[1]; // no previous frame to lerp from
493 ent->msgtime = cl.mtime[0];
495 // LordHavoc: new protocol stuff
496 baseline = &ent->baseline;
498 baseline = &ent->deltabaseline;
500 modnum = bits & U_MODEL ? MSG_ReadByte() : baseline->modelindex;
501 if (modnum >= MAX_MODELS)
502 Host_Error ("CL_ParseModel: bad modnum");
503 ent->deltabaseline.modelindex = modnum;
505 model = cl.model_precache[modnum];
506 if (model != ent->model)
509 // automatic animation (torches, etc) can be either all together
512 ent->syncbase = model->synctype == ST_RAND ? (float)(rand()&0x7fff) / 0x7fff : 0.0;
514 forcelink = true; // hack to make null model players work
515 if (num > 0 && num <= cl.maxclients)
516 R_TranslatePlayerSkin (num - 1);
519 ent->frame = ((bits & U_FRAME) ? MSG_ReadByte() : (baseline->frame & 0xFF));
521 i = bits & U_COLORMAP ? MSG_ReadByte() : baseline->colormap;
522 ent->deltabaseline.colormap = i;
524 ent->colormap = vid.colormap;
527 if (i > cl.maxclients)
528 Host_Error ("i >= cl.maxclients");
529 ent->colormap = vid.colormap; // cl.scores[i-1].translations;
532 skin = bits & U_SKIN ? MSG_ReadByte() : baseline->skin;
533 if (skin != ent->skinnum)
536 if (num > 0 && num <= cl.maxclients)
537 R_TranslatePlayerSkin (num - 1);
539 ent->deltabaseline.skin = skin;
541 ent->effects = ((bits & U_EFFECTS) ? MSG_ReadByte() : (baseline->effects & 0xFF));
543 // shift the known values for interpolation
544 VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
545 VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
546 VectorCopy (baseline->origin, ent->msg_origins[0]);
547 VectorCopy (baseline->angles, ent->msg_angles[0]);
549 if (bits & U_ORIGIN1) ent->msg_origins[0][0] = MSG_ReadCoord ();
550 if (bits & U_ANGLE1) ent->msg_angles[0][0] = MSG_ReadAngle();
551 if (bits & U_ORIGIN2) ent->msg_origins[0][1] = MSG_ReadCoord ();
552 if (bits & U_ANGLE2) ent->msg_angles[0][1] = MSG_ReadAngle();
553 if (bits & U_ORIGIN3) ent->msg_origins[0][2] = MSG_ReadCoord ();
554 if (bits & U_ANGLE3) ent->msg_angles[0][2] = MSG_ReadAngle();
556 VectorCopy(ent->msg_origins[0], ent->deltabaseline.origin);
557 VectorCopy(ent->msg_angles[0], ent->deltabaseline.angles);
559 alpha = bits & U_ALPHA ? MSG_ReadByte() : baseline->alpha;
560 scale = bits & U_SCALE ? MSG_ReadByte() : baseline->scale;
561 ent->effects |= ((bits & U_EFFECTS2) ? (MSG_ReadByte() << 8) : (baseline->effects & 0xFF00));
562 glowsize = bits & U_GLOWSIZE ? MSG_ReadByte() : baseline->glowsize;
563 glowcolor = bits & U_GLOWCOLOR ? MSG_ReadByte() : baseline->glowcolor;
564 colormod = bits & U_COLORMOD ? MSG_ReadByte() : baseline->colormod;
565 ent->frame |= ((bits & U_FRAME2) ? (MSG_ReadByte() << 8) : (baseline->frame & 0xFF00));
566 ent->deltabaseline.alpha = alpha;
567 ent->deltabaseline.scale = scale;
568 ent->deltabaseline.effects = ent->effects;
569 ent->deltabaseline.glowsize = glowsize;
570 ent->deltabaseline.glowcolor = glowcolor;
571 ent->deltabaseline.colormod = colormod;
572 ent->deltabaseline.frame = ent->frame;
573 ent->alpha = (float) alpha * (1.0 / 255.0);
574 ent->scale = (float) scale * (1.0 / 16.0);
575 ent->glowsize = glowsize < 128 ? glowsize * 8.0 : (glowsize - 256) * 8.0;
576 ent->glowcolor = glowcolor;
577 ent->colormod[0] = (float) ((colormod >> 5) & 7) * (1.0 / 7.0);
578 ent->colormod[1] = (float) ((colormod >> 2) & 7) * (1.0 / 7.0);
579 ent->colormod[2] = (float) (colormod & 3) * (1.0 / 3.0);
580 if (bits & U_EXTEND1 && Nehahrademcompatibility) // LordHavoc: to allow playback of the early Nehahra movie segments
583 ent->alpha = MSG_ReadFloat();
584 if (i == 2 && MSG_ReadFloat() != 0.0)
585 ent->effects |= EF_FULLBRIGHT;
590 //if ( bits & U_NOLERP )
591 // ent->forcelink = true;
592 //if (bits & U_STEP) // FIXME: implement clientside interpolation of monsters
595 { // didn't have an update last message
596 VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
597 VectorCopy (ent->msg_origins[0], ent->origin);
598 VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
599 VectorCopy (ent->msg_angles[0], ent->angles);
600 ent->forcelink = true;
609 void CL_ParseBaseline (entity_t *ent)
613 ent->baseline.modelindex = MSG_ReadByte ();
614 ent->baseline.frame = MSG_ReadByte ();
615 ent->baseline.colormap = MSG_ReadByte();
616 ent->baseline.skin = MSG_ReadByte();
617 for (i=0 ; i<3 ; i++)
619 ent->baseline.origin[i] = MSG_ReadCoord ();
620 ent->baseline.angles[i] = MSG_ReadAngle ();
622 ent->baseline.alpha = 255;
623 ent->baseline.scale = 16;
624 ent->baseline.glowsize = 0;
625 ent->baseline.glowcolor = 254;
626 ent->baseline.colormod = 255;
634 Server information pertaining to this client only
637 void CL_ParseClientdata (int bits)
641 if (bits & SU_VIEWHEIGHT)
642 cl.viewheight = MSG_ReadChar ();
644 cl.viewheight = DEFAULT_VIEWHEIGHT;
646 if (bits & SU_IDEALPITCH)
647 cl.idealpitch = MSG_ReadChar ();
651 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
652 for (i=0 ; i<3 ; i++)
654 if (bits & (SU_PUNCH1<<i) )
655 cl.punchangle[i] = MSG_ReadChar();
657 cl.punchangle[i] = 0;
658 if (bits & (SU_VELOCITY1<<i) )
659 cl.mvelocity[0][i] = MSG_ReadChar()*16;
661 cl.mvelocity[0][i] = 0;
664 // [always sent] if (bits & SU_ITEMS)
670 for (j=0 ; j<32 ; j++)
671 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
672 cl.item_gettime[j] = cl.time;
676 cl.onground = (bits & SU_ONGROUND) != 0;
677 cl.inwater = (bits & SU_INWATER) != 0;
679 if (bits & SU_WEAPONFRAME)
680 cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
682 cl.stats[STAT_WEAPONFRAME] = 0;
688 if (cl.stats[STAT_ARMOR] != i)
690 cl.stats[STAT_ARMOR] = i;
694 if (bits & SU_WEAPON)
698 if (cl.stats[STAT_WEAPON] != i)
700 cl.stats[STAT_WEAPON] = i;
704 i = MSG_ReadShort ();
705 if (cl.stats[STAT_HEALTH] != i)
707 cl.stats[STAT_HEALTH] = i;
712 if (cl.stats[STAT_AMMO] != i)
714 cl.stats[STAT_AMMO] = i;
718 for (i=0 ; i<4 ; i++)
721 if (cl.stats[STAT_SHELLS+i] != j)
723 cl.stats[STAT_SHELLS+i] = j;
732 if (cl.stats[STAT_ACTIVEWEAPON] != i)
734 cl.stats[STAT_ACTIVEWEAPON] = i;
740 if (cl.stats[STAT_ACTIVEWEAPON] != (1<<i))
742 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
749 =====================
751 =====================
753 void CL_ParseStatic (void)
759 if (i >= MAX_STATIC_ENTITIES)
760 Host_Error ("Too many static entities");
761 ent = &cl_static_entities[i];
763 CL_ParseBaseline (ent);
765 // copy it to the current state
766 ent->model = cl.model_precache[ent->baseline.modelindex];
767 ent->frame = ent->baseline.frame;
768 ent->colormap = vid.colormap;
769 ent->skinnum = ent->baseline.skin;
770 ent->effects = ent->baseline.effects;
775 ent->glowcolor = 254;
776 ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
778 VectorCopy (ent->baseline.origin, ent->origin);
779 VectorCopy (ent->baseline.angles, ent->angles);
788 void CL_ParseStaticSound (void)
791 int sound_num, vol, atten;
794 for (i=0 ; i<3 ; i++)
795 org[i] = MSG_ReadCoord ();
796 sound_num = MSG_ReadByte ();
797 vol = MSG_ReadByte ();
798 atten = MSG_ReadByte ();
800 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
804 #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
806 extern void SHOWLMP_decodehide();
807 extern void SHOWLMP_decodeshow();
808 extern void R_SetSkyBox(char* sky);
810 extern float fog_density;
811 extern float fog_red;
812 extern float fog_green;
813 extern float fog_blue;
816 =====================
817 CL_ParseServerMessage
818 =====================
820 void CL_ParseServerMessage (void)
826 // if recording demos, copy the message out
828 if (cl_shownet.value == 1)
829 Con_Printf ("%i ",net_message.cursize);
830 else if (cl_shownet.value == 2)
831 Con_Printf ("------------------\n");
833 cl.onground = false; // unless the server says otherwise
842 Host_Error ("CL_ParseServerMessage: Bad server message");
844 cmd = MSG_ReadByte ();
848 SHOWNET("END OF MESSAGE");
849 return; // end of message
852 // if the high bit of the command byte is set, it is a fast update
855 SHOWNET("fast update");
856 CL_ParseUpdate (cmd&127);
860 SHOWNET(svc_strings[cmd]);
866 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
870 // Con_Printf ("svc_nop\n");
874 cl.mtime[1] = cl.mtime[0];
875 cl.mtime[0] = MSG_ReadFloat ();
879 i = MSG_ReadShort ();
880 CL_ParseClientdata (i);
885 if (i != PROTOCOL_VERSION && i != 250)
886 Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
887 Nehahrademcompatibility = i == 250;
891 Host_EndGame ("Server disconnected\n");
894 Con_Printf ("%s", MSG_ReadString ());
897 case svc_centerprint:
898 SCR_CenterPrint (MSG_ReadString ());
902 Cbuf_AddText (MSG_ReadString ());
910 CL_ParseServerInfo ();
911 vid.recalc_refdef = true; // leave intermission full screen
915 for (i=0 ; i<3 ; i++)
916 cl.viewangles[i] = MSG_ReadAngle ();
920 cl.viewentity = MSG_ReadShort ();
925 if (i >= MAX_LIGHTSTYLES)
926 Host_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
927 strcpy (cl_lightstyle[i].map, MSG_ReadString());
928 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
932 CL_ParseStartSoundPacket();
937 S_StopSound(i>>3, i&7);
943 if (i >= cl.maxclients)
944 Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
945 strcpy (cl.scores[i].name, MSG_ReadString ());
948 case svc_updatefrags:
951 if (i >= cl.maxclients)
952 Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
953 cl.scores[i].frags = MSG_ReadShort ();
956 case svc_updatecolors:
959 if (i >= cl.maxclients)
960 Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
961 cl.scores[i].colors = MSG_ReadByte ();
962 R_TranslatePlayerSkin (i);
966 R_ParseParticleEffect ();
969 case svc_spawnbaseline:
970 i = MSG_ReadShort ();
971 // must use CL_EntityNum() to force cl.num_entities up
972 CL_ParseBaseline (CL_EntityNum(i));
974 case svc_spawnstatic:
977 case svc_temp_entity:
983 cl.paused = MSG_ReadByte ();
989 VID_HandlePause (true);
996 VID_HandlePause (false);
1003 i = MSG_ReadByte ();
1004 if (i <= cls.signon)
1005 Host_Error ("Received signon %i when at %i", i, cls.signon);
1010 case svc_killedmonster:
1011 cl.stats[STAT_MONSTERS]++;
1014 case svc_foundsecret:
1015 cl.stats[STAT_SECRETS]++;
1018 case svc_updatestat:
1019 i = MSG_ReadByte ();
1020 if (i < 0 || i >= MAX_CL_STATS)
1021 Host_Error ("svc_updatestat: %i is invalid", i);
1022 cl.stats[i] = MSG_ReadLong ();;
1025 case svc_spawnstaticsound:
1026 CL_ParseStaticSound ();
1030 cl.cdtrack = MSG_ReadByte ();
1031 cl.looptrack = MSG_ReadByte ();
1032 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1033 CDAudio_Play ((byte)cls.forcetrack, true);
1035 CDAudio_Play ((byte)cl.cdtrack, true);
1038 case svc_intermission:
1039 cl.intermission = 1;
1040 cl.completed_time = cl.time;
1041 vid.recalc_refdef = true; // go to full screen
1045 cl.intermission = 2;
1046 cl.completed_time = cl.time;
1047 vid.recalc_refdef = true; // go to full screen
1048 SCR_CenterPrint (MSG_ReadString ());
1052 cl.intermission = 3;
1053 cl.completed_time = cl.time;
1054 vid.recalc_refdef = true; // go to full screen
1055 SCR_CenterPrint (MSG_ReadString ());
1058 case svc_sellscreen:
1059 Cmd_ExecuteString ("help", src_command);
1062 SHOWLMP_decodehide();
1065 SHOWLMP_decodeshow();
1067 // LordHavoc: extra worldspawn fields (fog, sky, skyboxsize)
1069 R_SetSkyBox(MSG_ReadString());
1071 case svc_skyboxsize:
1072 /*r_skyboxsize.value = */MSG_ReadCoord();
1077 fog_density = MSG_ReadShort() * (1.0f / 4096.0f);
1078 fog_red = MSG_ReadByte() * (1.0 / 255.0);
1079 fog_green = MSG_ReadByte() * (1.0 / 255.0);
1080 fog_blue = MSG_ReadByte() * (1.0 / 255.0);