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
24 char *svc_strings[128] =
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] density*4096 [byte] red [byte] green [byte] blue
85 "svc_playerposition" // [float] x [float] y [float] z
88 //=============================================================================
90 qboolean Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
91 qboolean dpprotocol; // LordHavoc: whether or not the current network stream is the enhanced DarkPlaces protocol
97 This error checks and tracks the total number of entities
100 entity_t *CL_EntityNum (int num)
102 if (num >= cl.num_entities)
104 if (num >= MAX_EDICTS)
105 Host_Error ("CL_EntityNum: %i is an invalid number",num);
106 while (cl.num_entities<=num)
108 cl_entities[cl.num_entities].colormap = -1; // no special coloring
113 return &cl_entities[num];
119 CL_ParseStartSoundPacket
122 void CL_ParseStartSoundPacket(void)
132 field_mask = MSG_ReadByte();
134 if (field_mask & SND_VOLUME)
135 volume = MSG_ReadByte ();
137 volume = DEFAULT_SOUND_PACKET_VOLUME;
139 if (field_mask & SND_ATTENUATION)
140 attenuation = MSG_ReadByte () / 64.0;
142 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
144 channel = MSG_ReadShort ();
145 sound_num = MSG_ReadByte ();
150 if (ent > MAX_EDICTS)
151 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
153 for (i=0 ; i<3 ; i++)
154 pos[i] = MSG_ReadCoord ();
156 S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
163 When the client is taking a long time to load stuff, send keepalive messages
164 so the server doesn't disconnect.
167 void CL_KeepaliveMessage (void)
170 static float lastmsg;
176 return; // no need if server is local
177 if (cls.demoplayback)
180 // read messages from server, should just be nops
182 memcpy (olddata, net_message.data, net_message.cursize);
186 ret = CL_GetMessage ();
190 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
192 break; // nothing waiting
194 Host_Error ("CL_KeepaliveMessage: received a message");
197 if (MSG_ReadByte() != svc_nop)
198 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
204 memcpy (net_message.data, olddata, net_message.cursize);
207 time = Sys_FloatTime ();
208 if (time - lastmsg < 5)
213 Con_Printf ("--> client to server keepalive\n");
215 MSG_WriteByte (&cls.message, clc_nop);
216 NET_SendMessage (cls.netcon, &cls.message);
217 SZ_Clear (&cls.message);
220 extern qboolean isworldmodel;
221 extern char skyname[];
222 extern void R_SetSkyBox (char *sky);
223 extern void FOG_clear();
224 extern cvar_t r_farclip;
226 void CL_ParseEntityLump(char *entdata)
229 char key[128], value[1024];
232 FOG_clear(); // LordHavoc: no fog until set
233 skyname[0] = 0; // LordHavoc: no enviroment mapped sky until set
234 r_farclip.value = 6144; // LordHavoc: default farclip distance
238 data = COM_Parse(data);
240 return; // valid exit
241 if (com_token[0] != '{')
245 data = COM_Parse(data);
248 if (com_token[0] == '}')
249 return; // since we're just parsing the first ent (worldspawn), exit
250 strcpy(key, com_token);
251 while (key[strlen(key)-1] == ' ') // remove trailing spaces
252 key[strlen(key)-1] = 0;
253 data = COM_Parse(data);
256 strcpy(value, com_token);
257 if (!strcmp("sky", key))
259 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
261 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
263 else if (!strcmp("farclip", key))
265 r_farclip.value = atof(value);
266 if (r_farclip.value < 64)
267 r_farclip.value = 64;
269 else if (!strcmp("fog", key))
271 scanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
274 else if (!strcmp("fog_density", key))
275 fog_density = atof(value);
276 else if (!strcmp("fog_red", key))
277 fog_red = atof(value);
278 else if (!strcmp("fog_green", key))
279 fog_green = atof(value);
280 else if (!strcmp("fog_blue", key))
281 fog_blue = atof(value);
282 else if (!strcmp("wad", key)) // for HalfLife maps
285 for (i = 0;i < 128;i++)
286 if (value[i] != ';' && value[i] != '\\' && value[i] != '/' && value[i] != ':')
292 // ignore path - the \\ check is for HalfLife... stupid windoze 'programmers'...
293 if (value[i] == '\\' || value[i] == '/' || value[i] == ':')
295 else if (value[i] == ';' || value[i] == 0)
299 strcpy(wadname, "textures/");
300 strcat(wadname, &value[j]);
301 W_LoadTextureWadFile (wadname, FALSE);
317 extern cvar_t demo_nehahra;
318 void CL_ParseServerInfo (void)
322 int nummodels, numsounds;
323 char model_precache[MAX_MODELS][MAX_QPATH];
324 char sound_precache[MAX_SOUNDS][MAX_QPATH];
326 Con_DPrintf ("Serverinfo packet received.\n");
328 // wipe the client_state_t struct
332 // parse protocol version number
334 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION && i != 250)
336 Con_Printf ("Server returned version %i, not %i or %i", i, DPPROTOCOL_VERSION, PROTOCOL_VERSION);
339 Nehahrademcompatibility = false;
341 Nehahrademcompatibility = true;
342 if (cls.demoplayback && demo_nehahra.value)
343 Nehahrademcompatibility = true;
344 dpprotocol = i == DPPROTOCOL_VERSION;
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 if (strlen(str) >= MAX_QPATH)
388 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
389 strcpy (model_precache[nummodels], str);
390 Mod_TouchModel (str);
394 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
395 for (numsounds=1 ; ; numsounds++)
397 str = MSG_ReadString ();
400 if (numsounds==MAX_SOUNDS)
402 Con_Printf ("Server sent too many sound precaches\n");
405 if (strlen(str) >= MAX_QPATH)
406 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
407 strcpy (sound_precache[numsounds], str);
412 // now we try to load everything else until a cache allocation fails
415 for (i=1 ; i<nummodels ; i++)
417 isworldmodel = i == 1; // LordHavoc: first model is the world model
418 cl.model_precache[i] = Mod_ForName (model_precache[i], false);
419 if (cl.model_precache[i] == NULL)
421 Con_Printf("Model %s not found\n", model_precache[i]);
424 CL_KeepaliveMessage ();
427 S_BeginPrecaching ();
428 for (i=1 ; i<numsounds ; i++)
430 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
431 CL_KeepaliveMessage ();
437 cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
441 Hunk_Check (); // make sure nothing is hurt
443 noclip_anglehack = false; // noclip is turned off at start
451 Parse an entity update message from the server
452 If an entities model or origin changes from frame to frame, it must be
453 relinked. Other attributes can change without relinking.
456 void CL_ParseUpdate (int bits)
458 int i, modnum, num, alpha, scale, glowsize, glowcolor, colormod;
462 entity_state_t *baseline;
464 if (cls.signon == SIGNONS - 1)
465 { // first update is the final signon stage
466 cls.signon = SIGNONS;
470 if (bits & U_MOREBITS)
471 bits |= (MSG_ReadByte()<<8);
472 if (bits & U_EXTEND1 && !Nehahrademcompatibility)
474 bits |= MSG_ReadByte() << 16;
475 if (bits & U_EXTEND2)
476 bits |= MSG_ReadByte() << 24;
479 if (bits & U_LONGENTITY)
480 num = MSG_ReadShort ();
482 num = MSG_ReadByte ();
484 ent = CL_EntityNum (num);
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;
497 ent->deltabaseline.origin[0] = ent->deltabaseline.origin[1] = ent->deltabaseline.origin[2] = 0;
498 ent->deltabaseline.angles[0] = ent->deltabaseline.angles[1] = ent->deltabaseline.angles[2] = 0;
499 ent->deltabaseline.effects = 0;
500 ent->deltabaseline.modelindex = 0;
501 ent->deltabaseline.frame = 0;
502 ent->deltabaseline.colormap = 0;
503 ent->deltabaseline.skin = 0;
504 ent->deltabaseline.alpha = 255;
505 ent->deltabaseline.scale = 16;
506 ent->deltabaseline.glowsize = 0;
507 ent->deltabaseline.glowcolor = 254;
508 ent->deltabaseline.colormod = 255;
511 modnum = bits & U_MODEL ? MSG_ReadByte() : baseline->modelindex;
512 if (modnum >= MAX_MODELS)
513 Host_Error ("CL_ParseModel: bad modnum");
514 ent->deltabaseline.modelindex = modnum;
516 model = cl.model_precache[modnum];
517 if (model != ent->model)
520 // automatic animation (torches, etc) can be either all together
523 ent->syncbase = model->synctype == ST_RAND ? (float)(rand()&0x7fff) / 0x7fff : 0.0;
525 forcelink = true; // hack to make null model players work
528 ent->frame = ((bits & U_FRAME) ? MSG_ReadByte() : (baseline->frame & 0xFF));
530 i = bits & U_COLORMAP ? MSG_ReadByte() : baseline->colormap;
531 ent->deltabaseline.colormap = i;
533 ent->colormap = -1; // no special coloring
536 if (i > cl.maxclients)
537 Host_Error ("i >= cl.maxclients");
538 ent->colormap = cl.scores[i-1].colors; // color it
541 ent->deltabaseline.skin = ent->skinnum = bits & U_SKIN ? MSG_ReadByte() : baseline->skin;
543 ent->effects = ((bits & U_EFFECTS) ? MSG_ReadByte() : (baseline->effects & 0xFF));
545 // shift the known values for interpolation
546 VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
547 VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
548 VectorCopy (baseline->origin, ent->msg_origins[0]);
549 VectorCopy (baseline->angles, ent->msg_angles[0]);
551 if (bits & U_ORIGIN1) ent->msg_origins[0][0] = MSG_ReadCoord ();
552 if (bits & U_ANGLE1) ent->msg_angles[0][0] = MSG_ReadAngle();
553 if (bits & U_ORIGIN2) ent->msg_origins[0][1] = MSG_ReadCoord ();
554 if (bits & U_ANGLE2) ent->msg_angles[0][1] = MSG_ReadAngle();
555 if (bits & U_ORIGIN3) ent->msg_origins[0][2] = MSG_ReadCoord ();
556 if (bits & U_ANGLE3) ent->msg_angles[0][2] = MSG_ReadAngle();
558 VectorCopy(ent->msg_origins[0], ent->deltabaseline.origin);
559 VectorCopy(ent->msg_angles[0], ent->deltabaseline.angles);
561 alpha = bits & U_ALPHA ? MSG_ReadByte() : baseline->alpha;
562 scale = bits & U_SCALE ? MSG_ReadByte() : baseline->scale;
563 ent->effects |= ((bits & U_EFFECTS2) ? (MSG_ReadByte() << 8) : (baseline->effects & 0xFF00));
564 glowsize = bits & U_GLOWSIZE ? MSG_ReadByte() : baseline->glowsize;
565 glowcolor = bits & U_GLOWCOLOR ? MSG_ReadByte() : baseline->glowcolor;
566 colormod = bits & U_COLORMOD ? MSG_ReadByte() : baseline->colormod;
567 ent->frame |= ((bits & U_FRAME2) ? (MSG_ReadByte() << 8) : (baseline->frame & 0xFF00));
568 ent->deltabaseline.alpha = alpha;
569 ent->deltabaseline.scale = scale;
570 ent->deltabaseline.effects = ent->effects;
571 ent->deltabaseline.glowsize = glowsize;
572 ent->deltabaseline.glowcolor = glowcolor;
573 ent->deltabaseline.colormod = colormod;
574 ent->deltabaseline.frame = ent->frame;
575 ent->alpha = (float) alpha * (1.0 / 255.0);
576 ent->scale = (float) scale * (1.0 / 16.0);
577 ent->glowsize = glowsize * 4.0;
578 ent->glowcolor = glowcolor;
579 ent->colormod[0] = (float) ((colormod >> 5) & 7) * (1.0 / 7.0);
580 ent->colormod[1] = (float) ((colormod >> 2) & 7) * (1.0 / 7.0);
581 ent->colormod[2] = (float) (colormod & 3) * (1.0 / 3.0);
582 if (bits & U_EXTEND1 && Nehahrademcompatibility) // LordHavoc: to allow playback of the early Nehahra movie segments
585 ent->alpha = MSG_ReadFloat();
586 if (i == 2 && MSG_ReadFloat() != 0.0)
587 ent->effects |= EF_FULLBRIGHT;
592 //if ( bits & U_NOLERP )
593 // ent->forcelink = true;
594 //if (bits & U_STEP) // FIXME: implement clientside interpolation of monsters
597 { // didn't have an update last message
598 VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
599 VectorCopy (ent->msg_origins[0], ent->origin);
600 VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
601 VectorCopy (ent->msg_angles[0], ent->angles);
602 ent->forcelink = true;
611 void CL_ParseBaseline (entity_t *ent)
615 ent->baseline.modelindex = MSG_ReadByte ();
616 ent->baseline.frame = MSG_ReadByte ();
617 ent->baseline.colormap = MSG_ReadByte();
618 ent->baseline.skin = MSG_ReadByte();
619 for (i=0 ; i<3 ; i++)
621 ent->baseline.origin[i] = MSG_ReadCoord ();
622 ent->baseline.angles[i] = MSG_ReadAngle ();
624 ent->baseline.alpha = 255;
625 ent->baseline.scale = 16;
626 ent->baseline.glowsize = 0;
627 ent->baseline.glowcolor = 254;
628 ent->baseline.colormod = 255;
636 Server information pertaining to this client only
639 void CL_ParseClientdata (int bits)
643 if (bits & SU_VIEWHEIGHT)
644 cl.viewheight = MSG_ReadChar ();
646 cl.viewheight = DEFAULT_VIEWHEIGHT;
648 if (bits & SU_IDEALPITCH)
649 cl.idealpitch = MSG_ReadChar ();
653 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
654 for (i=0 ; i<3 ; i++)
656 if (bits & (SU_PUNCH1<<i) )
657 cl.punchangle[i] = MSG_ReadChar();
659 cl.punchangle[i] = 0;
660 if (bits & (SU_VELOCITY1<<i) )
661 cl.mvelocity[0][i] = MSG_ReadChar()*16;
663 cl.mvelocity[0][i] = 0;
669 for (j=0 ; j<32 ; j++)
670 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
671 cl.item_gettime[j] = cl.time;
675 cl.onground = (bits & SU_ONGROUND) != 0;
676 cl.inwater = (bits & SU_INWATER) != 0;
678 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
679 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
680 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
681 cl.stats[STAT_HEALTH] = MSG_ReadShort();
682 cl.stats[STAT_AMMO] = MSG_ReadByte();
684 cl.stats[STAT_SHELLS] = MSG_ReadByte();
685 cl.stats[STAT_NAILS] = MSG_ReadByte();
686 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
687 cl.stats[STAT_CELLS] = MSG_ReadByte();
692 cl.stats[STAT_ACTIVEWEAPON] = i;
694 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
698 =====================
700 =====================
702 void CL_ParseStatic (void)
708 if (i >= MAX_STATIC_ENTITIES)
709 Host_Error ("Too many static entities");
710 ent = &cl_static_entities[i];
712 CL_ParseBaseline (ent);
714 // copy it to the current state
715 ent->model = cl.model_precache[ent->baseline.modelindex];
716 ent->frame = ent->baseline.frame;
717 ent->colormap = -1; // no special coloring
718 ent->skinnum = ent->baseline.skin;
719 ent->effects = ent->baseline.effects;
724 ent->glowcolor = 254;
725 ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
727 VectorCopy (ent->baseline.origin, ent->origin);
728 VectorCopy (ent->baseline.angles, ent->angles);
737 void CL_ParseStaticSound (void)
740 int sound_num, vol, atten;
743 for (i=0 ; i<3 ; i++)
744 org[i] = MSG_ReadCoord ();
745 sound_num = MSG_ReadByte ();
746 vol = MSG_ReadByte ();
747 atten = MSG_ReadByte ();
749 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
753 #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
755 extern void SHOWLMP_decodehide();
756 extern void SHOWLMP_decodeshow();
757 extern void R_SetSkyBox(char* sky);
760 =====================
761 CL_ParseServerMessage
762 =====================
764 void CL_ParseServerMessage (void)
769 char *cmdlogname[32];
770 int cmdindex, cmdcount = 0;
773 // if recording demos, copy the message out
775 if (cl_shownet.value == 1)
776 Con_Printf ("%i ",net_message.cursize);
777 else if (cl_shownet.value == 2)
778 Con_Printf ("------------------\n");
780 cl.onground = false; // unless the server says otherwise
789 Host_Error ("CL_ParseServerMessage: Bad server message");
791 cmd = MSG_ReadByte ();
795 SHOWNET("END OF MESSAGE");
796 return; // end of message
799 cmdindex = cmdcount & 31;
801 cmdlog[cmdindex] = cmd;
803 // if the high bit of the command byte is set, it is a fast update
806 cmdlogname[cmdindex] = "svc_entity";
807 SHOWNET("fast update");
808 CL_ParseUpdate (cmd&127);
812 SHOWNET(svc_strings[cmd]);
813 cmdlogname[cmdindex] = svc_strings[cmd];
814 if (!cmdlogname[cmdindex])
815 cmdlogname[cmdindex] = "<unknown>";
822 char description[32*64], temp[64];
824 strcpy(description, "packet dump: ");
828 count = cmdcount - i;
832 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
833 strcat(description, temp);
838 description[strlen(description)-1] = '\n'; // replace the last space with a newline
839 Con_Printf(description);
840 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
845 // Con_Printf ("svc_nop\n");
849 cl.mtime[1] = cl.mtime[0];
850 cl.mtime[0] = MSG_ReadFloat ();
854 i = MSG_ReadShort ();
855 CL_ParseClientdata (i);
860 if (i != PROTOCOL_VERSION && i != 250)
861 Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
862 Nehahrademcompatibility = i == 250;
866 Host_EndGame ("Server disconnected\n");
869 Con_Printf ("%s", MSG_ReadString ());
872 case svc_centerprint:
873 SCR_CenterPrint (MSG_ReadString ());
877 Cbuf_AddText (MSG_ReadString ());
885 CL_ParseServerInfo ();
886 vid.recalc_refdef = true; // leave intermission full screen
890 for (i=0 ; i<3 ; i++)
891 cl.viewangles[i] = MSG_ReadAngle ();
895 cl.viewentity = MSG_ReadShort ();
900 if (i >= MAX_LIGHTSTYLES)
901 Host_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
902 strcpy (cl_lightstyle[i].map, MSG_ReadString());
903 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
907 CL_ParseStartSoundPacket();
912 S_StopSound(i>>3, i&7);
917 if (i >= cl.maxclients)
918 Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
919 strcpy (cl.scores[i].name, MSG_ReadString ());
922 case svc_updatefrags:
924 if (i >= cl.maxclients)
925 Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
926 cl.scores[i].frags = MSG_ReadShort ();
929 case svc_updatecolors:
931 if (i >= cl.maxclients)
932 Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
933 cl.scores[i].colors = MSG_ReadByte ();
937 R_ParseParticleEffect ();
940 case svc_spawnbaseline:
941 i = MSG_ReadShort ();
942 // must use CL_EntityNum() to force cl.num_entities up
943 CL_ParseBaseline (CL_EntityNum(i));
945 case svc_spawnstatic:
948 case svc_temp_entity:
953 cl.paused = MSG_ReadByte ();
963 Host_Error ("Received signon %i when at %i", i, cls.signon);
968 case svc_killedmonster:
969 cl.stats[STAT_MONSTERS]++;
972 case svc_foundsecret:
973 cl.stats[STAT_SECRETS]++;
978 if (i < 0 || i >= MAX_CL_STATS)
979 Host_Error ("svc_updatestat: %i is invalid", i);
980 cl.stats[i] = MSG_ReadLong ();;
983 case svc_spawnstaticsound:
984 CL_ParseStaticSound ();
988 cl.cdtrack = MSG_ReadByte ();
989 cl.looptrack = MSG_ReadByte ();
990 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
991 CDAudio_Play ((byte)cls.forcetrack, true);
993 CDAudio_Play ((byte)cl.cdtrack, true);
996 case svc_intermission:
998 cl.completed_time = cl.time;
999 vid.recalc_refdef = true; // go to full screen
1003 cl.intermission = 2;
1004 cl.completed_time = cl.time;
1005 vid.recalc_refdef = true; // go to full screen
1006 SCR_CenterPrint (MSG_ReadString ());
1010 cl.intermission = 3;
1011 cl.completed_time = cl.time;
1012 vid.recalc_refdef = true; // go to full screen
1013 SCR_CenterPrint (MSG_ReadString ());
1016 case svc_sellscreen:
1017 Cmd_ExecuteString ("help", src_command);
1020 SHOWLMP_decodehide();
1023 SHOWLMP_decodeshow();
1025 // LordHavoc: extra worldspawn fields (fog, sky, farclip)
1027 R_SetSkyBox(MSG_ReadString());
1030 r_farclip.value = MSG_ReadCoord();
1035 fog_density = MSG_ReadShort() * (1.0f / 4096.0f);
1036 fog_red = MSG_ReadByte() * (1.0 / 255.0);
1037 fog_green = MSG_ReadByte() * (1.0 / 255.0);
1038 fog_blue = MSG_ReadByte() * (1.0 / 255.0);