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_density", key))
271 fog_density = atof(value);
272 else if (!strcmp("fog_red", key))
273 fog_red = atof(value);
274 else if (!strcmp("fog_green", key))
275 fog_green = atof(value);
276 else if (!strcmp("fog_blue", key))
277 fog_blue = atof(value);
278 else if (!strcmp("wad", key)) // for HalfLife maps
281 for (i = 0;i < 128;i++)
282 if (value[i] != ';' && value[i] != '\\' && value[i] != '/' && value[i] != ':')
288 // ignore path - the \\ check is for HalfLife... stupid windoze 'programmers'...
289 if (value[i] == '\\' || value[i] == '/' || value[i] == ':')
291 else if (value[i] == ';' || value[i] == 0)
295 strcpy(wadname, "textures/");
296 strcat(wadname, &value[j]);
297 W_LoadTextureWadFile (wadname, FALSE);
313 extern cvar_t demo_nehahra;
314 void CL_ParseServerInfo (void)
318 int nummodels, numsounds;
319 char model_precache[MAX_MODELS][MAX_QPATH];
320 char sound_precache[MAX_SOUNDS][MAX_QPATH];
322 Con_DPrintf ("Serverinfo packet received.\n");
324 // wipe the client_state_t struct
328 // parse protocol version number
330 if (i != PROTOCOL_VERSION && i != 250)
332 Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
335 Nehahrademcompatibility = false;
337 Nehahrademcompatibility = true;
338 if (cls.demoplayback && demo_nehahra.value)
339 Nehahrademcompatibility = true;
342 cl.maxclients = MSG_ReadByte ();
343 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
345 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
348 cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
351 cl.gametype = MSG_ReadByte ();
353 // parse signon message
354 str = MSG_ReadString ();
355 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
357 // seperate the printfs so the server message can have a color
358 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
360 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");
361 Con_Printf ("%c%s\n", 2, str);
365 // first we go through and touch all of the precache data that still
366 // happens to be in the cache, so precaching something else doesn't
367 // needlessly purge it
371 memset (cl.model_precache, 0, sizeof(cl.model_precache));
372 for (nummodels=1 ; ; nummodels++)
374 str = MSG_ReadString ();
377 if (nummodels==MAX_MODELS)
379 Con_Printf ("Server sent too many model precaches\n");
382 strcpy (model_precache[nummodels], str);
383 Mod_TouchModel (str);
387 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
388 for (numsounds=1 ; ; numsounds++)
390 str = MSG_ReadString ();
393 if (numsounds==MAX_SOUNDS)
395 Con_Printf ("Server sent too many sound precaches\n");
398 strcpy (sound_precache[numsounds], str);
403 // now we try to load everything else until a cache allocation fails
406 for (i=1 ; i<nummodels ; i++)
408 isworldmodel = i == 1; // LordHavoc: first model is the world model
409 cl.model_precache[i] = Mod_ForName (model_precache[i], false);
410 if (cl.model_precache[i] == NULL)
412 Con_Printf("Model %s not found\n", model_precache[i]);
415 CL_KeepaliveMessage ();
418 S_BeginPrecaching ();
419 for (i=1 ; i<numsounds ; i++)
421 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
422 CL_KeepaliveMessage ();
428 cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
432 Hunk_Check (); // make sure nothing is hurt
434 noclip_anglehack = false; // noclip is turned off at start
442 Parse an entity update message from the server
443 If an entities model or origin changes from frame to frame, it must be
444 relinked. Other attributes can change without relinking.
449 void CL_ParseUpdate (int bits)
451 int i, modnum, num, skin, alpha, scale, glowsize, glowcolor, colormod;
455 entity_state_t *baseline;
457 if (cls.signon == SIGNONS - 1)
458 { // first update is the final signon stage
459 cls.signon = SIGNONS;
463 if (bits & U_MOREBITS)
468 if (bits & U_EXTEND1 && !Nehahrademcompatibility)
470 bits |= MSG_ReadByte() << 16;
471 if (bits & U_EXTEND2)
472 bits |= MSG_ReadByte() << 24;
475 if (bits & U_LONGENTITY)
476 num = MSG_ReadShort ();
478 num = MSG_ReadByte ();
480 ent = CL_EntityNum (num);
482 //for (i=0 ; i<16 ; i++)
486 forcelink = ent->msgtime != cl.mtime[1]; // no previous frame to lerp from
488 ent->msgtime = cl.mtime[0];
490 // LordHavoc: new protocol stuff
491 baseline = &ent->baseline;
493 baseline = &ent->deltabaseline;
495 modnum = bits & U_MODEL ? MSG_ReadByte() : baseline->modelindex;
496 if (modnum >= MAX_MODELS)
497 Host_Error ("CL_ParseModel: bad modnum");
498 ent->deltabaseline.modelindex = modnum;
500 model = cl.model_precache[modnum];
501 if (model != ent->model)
504 // automatic animation (torches, etc) can be either all together
507 ent->syncbase = model->synctype == ST_RAND ? (float)(rand()&0x7fff) / 0x7fff : 0.0;
509 forcelink = true; // hack to make null model players work
510 if (num > 0 && num <= cl.maxclients)
511 R_TranslatePlayerSkin (num - 1);
514 ent->frame = ((bits & U_FRAME) ? MSG_ReadByte() : (baseline->frame & 0xFF));
516 i = bits & U_COLORMAP ? MSG_ReadByte() : baseline->colormap;
517 ent->deltabaseline.colormap = i;
519 ent->colormap = vid.colormap;
522 if (i > cl.maxclients)
523 Host_Error ("i >= cl.maxclients");
524 ent->colormap = cl.scores[i-1].translations;
527 skin = bits & U_SKIN ? MSG_ReadByte() : baseline->skin;
528 if (skin != ent->skinnum)
531 if (num > 0 && num <= cl.maxclients)
532 R_TranslatePlayerSkin (num - 1);
534 ent->deltabaseline.skin = skin;
536 ent->effects = ((bits & U_EFFECTS) ? MSG_ReadByte() : (baseline->effects & 0xFF));
538 // shift the known values for interpolation
539 VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
540 VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
541 VectorCopy (baseline->origin, ent->msg_origins[0]);
542 VectorCopy (baseline->angles, ent->msg_angles[0]);
544 if (bits & U_ORIGIN1) ent->msg_origins[0][0] = MSG_ReadCoord ();
545 if (bits & U_ANGLE1) ent->msg_angles[0][0] = MSG_ReadAngle();
546 if (bits & U_ORIGIN2) ent->msg_origins[0][1] = MSG_ReadCoord ();
547 if (bits & U_ANGLE2) ent->msg_angles[0][1] = MSG_ReadAngle();
548 if (bits & U_ORIGIN3) ent->msg_origins[0][2] = MSG_ReadCoord ();
549 if (bits & U_ANGLE3) ent->msg_angles[0][2] = MSG_ReadAngle();
551 VectorCopy(ent->msg_origins[0], ent->deltabaseline.origin);
552 VectorCopy(ent->msg_angles[0], ent->deltabaseline.angles);
554 alpha = bits & U_ALPHA ? MSG_ReadByte() : baseline->alpha;
555 scale = bits & U_SCALE ? MSG_ReadByte() : baseline->scale;
556 ent->effects |= ((bits & U_EFFECTS2) ? (MSG_ReadByte() << 8) : (baseline->effects & 0xFF00));
557 glowsize = bits & U_GLOWSIZE ? MSG_ReadByte() : baseline->glowsize;
558 glowcolor = bits & U_GLOWCOLOR ? MSG_ReadByte() : baseline->glowcolor;
559 colormod = bits & U_COLORMOD ? MSG_ReadByte() : baseline->colormod;
560 ent->frame |= ((bits & U_FRAME2) ? (MSG_ReadByte() << 8) : (baseline->frame & 0xFF00));
561 ent->deltabaseline.alpha = alpha;
562 ent->deltabaseline.scale = scale;
563 ent->deltabaseline.effects = ent->effects;
564 ent->deltabaseline.glowsize = glowsize;
565 ent->deltabaseline.glowcolor = glowcolor;
566 ent->deltabaseline.colormod = colormod;
567 ent->deltabaseline.frame = ent->frame;
568 ent->alpha = (float) alpha * (1.0 / 255.0);
569 ent->scale = (float) scale * (1.0 / 16.0);
570 ent->glowsize = glowsize < 128 ? glowsize * 8.0 : (glowsize - 256) * 8.0;
571 ent->glowcolor = glowcolor;
572 ent->colormod[0] = (float) ((colormod >> 5) & 7) * (1.0 / 7.0);
573 ent->colormod[1] = (float) ((colormod >> 2) & 7) * (1.0 / 7.0);
574 ent->colormod[2] = (float) (colormod & 3) * (1.0 / 3.0);
575 if (bits & U_EXTEND1 && Nehahrademcompatibility) // LordHavoc: to allow playback of the early Nehahra movie segments
578 ent->alpha = MSG_ReadFloat();
579 if (i == 2 && MSG_ReadFloat() != 0.0)
580 ent->effects |= EF_FULLBRIGHT;
585 //if ( bits & U_NOLERP )
586 // ent->forcelink = true;
587 //if (bits & U_STEP) // FIXME: implement clientside interpolation of monsters
590 { // didn't have an update last message
591 VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
592 VectorCopy (ent->msg_origins[0], ent->origin);
593 VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
594 VectorCopy (ent->msg_angles[0], ent->angles);
595 ent->forcelink = true;
604 void CL_ParseBaseline (entity_t *ent)
608 ent->baseline.modelindex = MSG_ReadByte ();
609 ent->baseline.frame = MSG_ReadByte ();
610 ent->baseline.colormap = MSG_ReadByte();
611 ent->baseline.skin = MSG_ReadByte();
612 for (i=0 ; i<3 ; i++)
614 ent->baseline.origin[i] = MSG_ReadCoord ();
615 ent->baseline.angles[i] = MSG_ReadAngle ();
617 ent->baseline.alpha = 255;
618 ent->baseline.scale = 16;
619 ent->baseline.glowsize = 0;
620 ent->baseline.glowcolor = 254;
621 ent->baseline.colormod = 255;
629 Server information pertaining to this client only
632 void CL_ParseClientdata (int bits)
636 if (bits & SU_VIEWHEIGHT)
637 cl.viewheight = MSG_ReadChar ();
639 cl.viewheight = DEFAULT_VIEWHEIGHT;
641 if (bits & SU_IDEALPITCH)
642 cl.idealpitch = MSG_ReadChar ();
646 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
647 for (i=0 ; i<3 ; i++)
649 if (bits & (SU_PUNCH1<<i) )
650 cl.punchangle[i] = MSG_ReadChar();
652 cl.punchangle[i] = 0;
653 if (bits & (SU_VELOCITY1<<i) )
654 cl.mvelocity[0][i] = MSG_ReadChar()*16;
656 cl.mvelocity[0][i] = 0;
659 // [always sent] if (bits & SU_ITEMS)
665 for (j=0 ; j<32 ; j++)
666 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
667 cl.item_gettime[j] = cl.time;
671 cl.onground = (bits & SU_ONGROUND) != 0;
672 cl.inwater = (bits & SU_INWATER) != 0;
674 if (bits & SU_WEAPONFRAME)
675 cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
677 cl.stats[STAT_WEAPONFRAME] = 0;
683 if (cl.stats[STAT_ARMOR] != i)
685 cl.stats[STAT_ARMOR] = i;
689 if (bits & SU_WEAPON)
693 if (cl.stats[STAT_WEAPON] != i)
695 cl.stats[STAT_WEAPON] = i;
699 i = MSG_ReadShort ();
700 if (cl.stats[STAT_HEALTH] != i)
702 cl.stats[STAT_HEALTH] = i;
707 if (cl.stats[STAT_AMMO] != i)
709 cl.stats[STAT_AMMO] = i;
713 for (i=0 ; i<4 ; i++)
716 if (cl.stats[STAT_SHELLS+i] != j)
718 cl.stats[STAT_SHELLS+i] = j;
727 if (cl.stats[STAT_ACTIVEWEAPON] != i)
729 cl.stats[STAT_ACTIVEWEAPON] = i;
735 if (cl.stats[STAT_ACTIVEWEAPON] != (1<<i))
737 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
744 =====================
746 =====================
748 void CL_NewTranslation (int slot)
754 if (slot > cl.maxclients)
755 Host_Error ("CL_NewTranslation: slot > cl.maxclients");
756 dest = cl.scores[slot].translations;
757 source = vid.colormap;
758 memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations));
759 top = cl.scores[slot].colors & 0xf0;
760 bottom = (cl.scores[slot].colors &15)<<4;
761 R_TranslatePlayerSkin (slot);
763 for (i=0 ; i<VID_GRADES ; i++, dest += 256, source+=256)
765 // LordHavoc: corrected color ranges
766 if (top < 128 || (top >= 224 && top < 240)) // the artists made some backwards ranges. sigh.
767 memcpy (dest + TOP_RANGE, source + top, 16);
769 for (j=0 ; j<16 ; j++)
770 dest[TOP_RANGE+j] = source[top+15-j];
772 // LordHavoc: corrected color ranges
773 if (bottom < 128 || (bottom >= 224 && bottom < 240))
774 memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
776 for (j=0 ; j<16 ; j++)
777 dest[BOTTOM_RANGE+j] = source[bottom+15-j];
782 =====================
784 =====================
786 void CL_ParseStatic (void)
792 if (i >= MAX_STATIC_ENTITIES)
793 Host_Error ("Too many static entities");
794 ent = &cl_static_entities[i];
796 CL_ParseBaseline (ent);
798 // copy it to the current state
799 ent->model = cl.model_precache[ent->baseline.modelindex];
800 ent->frame = ent->baseline.frame;
801 ent->colormap = vid.colormap;
802 ent->skinnum = ent->baseline.skin;
803 ent->effects = ent->baseline.effects;
808 ent->glowcolor = 254;
809 ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
811 VectorCopy (ent->baseline.origin, ent->origin);
812 VectorCopy (ent->baseline.angles, ent->angles);
821 void CL_ParseStaticSound (void)
824 int sound_num, vol, atten;
827 for (i=0 ; i<3 ; i++)
828 org[i] = MSG_ReadCoord ();
829 sound_num = MSG_ReadByte ();
830 vol = MSG_ReadByte ();
831 atten = MSG_ReadByte ();
833 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
837 #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
839 extern void SHOWLMP_decodehide();
840 extern void SHOWLMP_decodeshow();
841 extern void R_SetSkyBox(char* sky);
843 extern float fog_density;
844 extern float fog_red;
845 extern float fog_green;
846 extern float fog_blue;
849 =====================
850 CL_ParseServerMessage
851 =====================
853 void CL_ParseServerMessage (void)
859 // if recording demos, copy the message out
861 if (cl_shownet.value == 1)
862 Con_Printf ("%i ",net_message.cursize);
863 else if (cl_shownet.value == 2)
864 Con_Printf ("------------------\n");
866 cl.onground = false; // unless the server says otherwise
875 Host_Error ("CL_ParseServerMessage: Bad server message");
877 cmd = MSG_ReadByte ();
881 SHOWNET("END OF MESSAGE");
882 return; // end of message
885 // if the high bit of the command byte is set, it is a fast update
888 SHOWNET("fast update");
889 CL_ParseUpdate (cmd&127);
893 SHOWNET(svc_strings[cmd]);
899 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
903 // Con_Printf ("svc_nop\n");
907 cl.mtime[1] = cl.mtime[0];
908 cl.mtime[0] = MSG_ReadFloat ();
912 i = MSG_ReadShort ();
913 CL_ParseClientdata (i);
918 if (i != PROTOCOL_VERSION && i != 250)
919 Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
920 Nehahrademcompatibility = i == 250;
924 Host_EndGame ("Server disconnected\n");
927 Con_Printf ("%s", MSG_ReadString ());
930 case svc_centerprint:
931 SCR_CenterPrint (MSG_ReadString ());
935 Cbuf_AddText (MSG_ReadString ());
943 CL_ParseServerInfo ();
944 vid.recalc_refdef = true; // leave intermission full screen
948 for (i=0 ; i<3 ; i++)
949 cl.viewangles[i] = MSG_ReadAngle ();
953 cl.viewentity = MSG_ReadShort ();
958 if (i >= MAX_LIGHTSTYLES)
959 Host_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
960 strcpy (cl_lightstyle[i].map, MSG_ReadString());
961 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
965 CL_ParseStartSoundPacket();
970 S_StopSound(i>>3, i&7);
976 if (i >= cl.maxclients)
977 Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
978 strcpy (cl.scores[i].name, MSG_ReadString ());
981 case svc_updatefrags:
984 if (i >= cl.maxclients)
985 Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
986 cl.scores[i].frags = MSG_ReadShort ();
989 case svc_updatecolors:
992 if (i >= cl.maxclients)
993 Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
994 cl.scores[i].colors = MSG_ReadByte ();
995 CL_NewTranslation (i);
999 R_ParseParticleEffect ();
1002 case svc_spawnbaseline:
1003 i = MSG_ReadShort ();
1004 // must use CL_EntityNum() to force cl.num_entities up
1005 CL_ParseBaseline (CL_EntityNum(i));
1007 case svc_spawnstatic:
1010 case svc_temp_entity:
1016 cl.paused = MSG_ReadByte ();
1022 VID_HandlePause (true);
1029 VID_HandlePause (false);
1036 i = MSG_ReadByte ();
1037 if (i <= cls.signon)
1038 Host_Error ("Received signon %i when at %i", i, cls.signon);
1043 case svc_killedmonster:
1044 cl.stats[STAT_MONSTERS]++;
1047 case svc_foundsecret:
1048 cl.stats[STAT_SECRETS]++;
1051 case svc_updatestat:
1052 i = MSG_ReadByte ();
1053 if (i < 0 || i >= MAX_CL_STATS)
1054 Host_Error ("svc_updatestat: %i is invalid", i);
1055 cl.stats[i] = MSG_ReadLong ();;
1058 case svc_spawnstaticsound:
1059 CL_ParseStaticSound ();
1063 cl.cdtrack = MSG_ReadByte ();
1064 cl.looptrack = MSG_ReadByte ();
1065 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1066 CDAudio_Play ((byte)cls.forcetrack, true);
1068 CDAudio_Play ((byte)cl.cdtrack, true);
1071 case svc_intermission:
1072 cl.intermission = 1;
1073 cl.completed_time = cl.time;
1074 vid.recalc_refdef = true; // go to full screen
1078 cl.intermission = 2;
1079 cl.completed_time = cl.time;
1080 vid.recalc_refdef = true; // go to full screen
1081 SCR_CenterPrint (MSG_ReadString ());
1085 cl.intermission = 3;
1086 cl.completed_time = cl.time;
1087 vid.recalc_refdef = true; // go to full screen
1088 SCR_CenterPrint (MSG_ReadString ());
1091 case svc_sellscreen:
1092 Cmd_ExecuteString ("help", src_command);
1095 SHOWLMP_decodehide();
1098 SHOWLMP_decodeshow();
1100 // LordHavoc: extra worldspawn fields (fog, sky, skyboxsize)
1102 R_SetSkyBox(MSG_ReadString());
1104 case svc_skyboxsize:
1105 /*r_skyboxsize.value = */MSG_ReadCoord();
1110 fog_density = MSG_ReadShort() * (1.0f / 4096.0f);
1111 fog_red = MSG_ReadByte() * (1.0 / 255.0);
1112 fog_green = MSG_ReadByte() * (1.0 / 255.0);
1113 fog_blue = MSG_ReadByte() * (1.0 / 255.0);