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 [short] x [short] y
69 "svc_hidelmp", // [string] iconlabel
70 "svc_skybox", // [string] skyname
83 "svc_cgame", // 50 // [short] length [bytes] data
84 "svc_unusedlh1", // 51 // unused
85 "svc_effect", // 52 // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
86 "svc_effect2", // 53 // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate
87 "svc_sound2", // 54 // short soundindex instead of byte
88 "svc_spawnbaseline2", // 55 // short modelindex instead of byte
89 "svc_spawnstatic2", // 56 // short modelindex instead of byte
90 "svc_entities", // 57 // [int] deltaframe [int] thisframe [float vector] eye [variable length] entitydata
91 "svc_unusedlh3", // 58
92 "svc_spawnstaticsound2", // 59 // [coord3] [short] samp [byte] vol [byte] aten
95 //=============================================================================
97 cvar_t demo_nehahra = {0, "demo_nehahra", "0"};
99 qboolean Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
100 int dpprotocol; // LordHavoc: version of network protocol, or 0 if not DarkPlaces
104 CL_ParseStartSoundPacket
107 void CL_ParseStartSoundPacket(int largesoundindex)
117 field_mask = MSG_ReadByte();
119 if (field_mask & SND_VOLUME)
120 volume = MSG_ReadByte ();
122 volume = DEFAULT_SOUND_PACKET_VOLUME;
124 if (field_mask & SND_ATTENUATION)
125 attenuation = MSG_ReadByte () / 64.0;
127 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
129 if (field_mask & SND_LARGEENTITY)
131 ent = (unsigned short) MSG_ReadShort ();
132 channel = MSG_ReadByte ();
136 channel = (unsigned short) MSG_ReadShort ();
141 if (largesoundindex || field_mask & SND_LARGESOUND)
142 sound_num = (unsigned short) MSG_ReadShort ();
144 sound_num = MSG_ReadByte ();
146 if (sound_num >= MAX_SOUNDS)
147 Host_Error("CL_ParseStartSoundPacket: sound_num (%i) >= MAX_SOUNDS (%i)\n", sound_num, MAX_SOUNDS);
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;
177 return; // no need if server is local
178 if (cls.demoplayback)
181 // read messages from server, should just be nops
183 memcpy (olddata, net_message.data, net_message.cursize);
187 ret = CL_GetMessage ();
191 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
193 break; // nothing waiting
195 Host_Error ("CL_KeepaliveMessage: received a message");
200 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
206 memcpy (net_message.data, olddata, net_message.cursize);
209 time = Sys_DoubleTime ();
210 if (time - lastmsg < 5)
215 Con_Printf ("--> client to server keepalive\n");
217 MSG_WriteByte (&cls.message, clc_nop);
218 NET_SendMessage (cls.netcon, &cls.message);
219 SZ_Clear (&cls.message);
222 void CL_ParseEntityLump(char *entdata)
225 char key[128], value[4096];
226 FOG_clear(); // LordHavoc: no fog until set
227 R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set
231 if (!COM_ParseToken(&data))
233 if (com_token[0] != '{')
237 if (!COM_ParseToken(&data))
239 if (com_token[0] == '}')
240 break; // end of worldspawn
241 if (com_token[0] == '_')
242 strcpy(key, com_token + 1);
244 strcpy(key, com_token);
245 while (key[strlen(key)-1] == ' ') // remove trailing spaces
246 key[strlen(key)-1] = 0;
247 if (!COM_ParseToken(&data))
249 strcpy(value, com_token);
250 if (!strcmp("sky", key))
252 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
254 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
256 else if (!strcmp("fog", key))
257 sscanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
258 else if (!strcmp("fog_density", key))
259 fog_density = atof(value);
260 else if (!strcmp("fog_red", key))
261 fog_red = atof(value);
262 else if (!strcmp("fog_green", key))
263 fog_green = atof(value);
264 else if (!strcmp("fog_blue", key))
265 fog_blue = atof(value);
270 =====================
273 An svc_signonnum has been received, perform a client side setup
274 =====================
276 static void CL_SignonReply (void)
280 Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
285 MSG_WriteByte (&cls.message, clc_stringcmd);
286 MSG_WriteString (&cls.message, "prespawn");
290 MSG_WriteByte (&cls.message, clc_stringcmd);
291 MSG_WriteString (&cls.message, va("name \"%s\"\n", cl_name.string));
293 MSG_WriteByte (&cls.message, clc_stringcmd);
294 MSG_WriteString (&cls.message, va("color %i %i\n", cl_color.integer >> 4, cl_color.integer & 15));
296 if (cl_pmodel.integer)
298 MSG_WriteByte (&cls.message, clc_stringcmd);
299 MSG_WriteString (&cls.message, va("pmodel %i\n", cl_pmodel.integer));
302 MSG_WriteByte (&cls.message, clc_stringcmd);
303 MSG_WriteString (&cls.message, "spawn");
307 MSG_WriteByte (&cls.message, clc_stringcmd);
308 MSG_WriteString (&cls.message, "begin");
322 qbyte entlife[MAX_EDICTS];
323 void CL_ParseServerInfo (void)
327 int nummodels, numsounds;
328 char model_precache[MAX_MODELS][MAX_QPATH];
329 char sound_precache[MAX_SOUNDS][MAX_QPATH];
332 Con_DPrintf ("Serverinfo packet received.\n");
334 // wipe the client_state_t struct
338 // parse protocol version number
340 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
342 Host_Error ("Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
345 Nehahrademcompatibility = false;
347 Nehahrademcompatibility = true;
348 if (cls.demoplayback && demo_nehahra.integer)
349 Nehahrademcompatibility = true;
351 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
355 cl.maxclients = MSG_ReadByte ();
356 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
358 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
361 cl.scores = Mem_Alloc(cl_scores_mempool, cl.maxclients*sizeof(*cl.scores));
364 cl.gametype = MSG_ReadByte ();
366 // parse signon message
367 str = MSG_ReadString ();
368 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
370 // seperate the printfs so the server message can have a color
371 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
373 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");
374 Con_Printf ("%c%s\n", 2, str);
377 // check memory integrity
378 Mem_CheckSentinelsGlobal();
380 // disable until we get textures for it
383 memset (cl.model_precache, 0, sizeof(cl.model_precache));
384 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
386 // touch all of the precached models that are still loaded so we can free
387 // anything that isn't needed
389 for (nummodels=1 ; ; nummodels++)
391 CL_KeepaliveMessage ();
392 str = MSG_ReadString ();
395 if (nummodels==MAX_MODELS)
396 Host_Error ("Server sent too many model precaches\n");
397 if (strlen(str) >= MAX_QPATH)
398 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
399 strcpy (model_precache[nummodels], str);
400 Mod_TouchModel (str);
403 // do the same for sounds
404 for (numsounds=1 ; ; numsounds++)
406 CL_KeepaliveMessage ();
407 str = MSG_ReadString ();
410 if (numsounds==MAX_SOUNDS)
411 Host_Error ("Server sent too many sound precaches\n");
412 if (strlen(str) >= MAX_QPATH)
413 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
414 strcpy (sound_precache[numsounds], str);
418 // purge anything that was not touched
421 // now we try to load everything that is new
424 CL_KeepaliveMessage ();
425 cl.model_precache[1] = Mod_ForName (model_precache[1], false, false, true);
426 if (cl.model_precache[1] == NULL)
427 Con_Printf("Map %s not found\n", model_precache[1]);
430 for (i=2 ; i<nummodels ; i++)
432 CL_KeepaliveMessage ();
433 if ((cl.model_precache[i] = Mod_ForName (model_precache[i], false, false, false)) == NULL)
434 Con_Printf("Model %s not found\n", model_precache[i]);
438 S_BeginPrecaching ();
439 for (i=1 ; i<numsounds ; i++)
441 CL_KeepaliveMessage ();
442 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i], true);
447 ent = &cl_entities[0];
448 // entire entity array was cleared, so just fill in a few fields
449 ent->state_current.active = true;
450 ent->render.model = cl.worldmodel = cl.model_precache[1];
451 ent->render.scale = 1;
452 ent->render.alpha = 1;
453 CL_BoundingBoxForEntity(&ent->render);
454 // clear entlife array
455 memset(entlife, 0, MAX_EDICTS);
462 // noclip is turned off at start
463 noclip_anglehack = false;
465 // check memory integrity
466 Mem_CheckSentinelsGlobal();
469 void CL_ValidateState(entity_state_t *s)
476 if (s->modelindex >= MAX_MODELS)
477 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
479 // colormap is client index + 1
480 if (s->colormap > cl.maxclients)
481 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
483 model = cl.model_precache[s->modelindex];
484 Mod_CheckLoaded(model);
485 if (model && s->frame >= model->numframes)
487 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
490 if (model && s->skin > 0 && s->skin >= model->numskins)
492 Con_DPrintf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
497 void CL_MoveLerpEntityStates(entity_t *ent)
499 float odelta[3], adelta[3];
500 VectorSubtract(ent->state_current.origin, ent->persistent.neworigin, odelta);
501 VectorSubtract(ent->state_current.angles, ent->persistent.newangles, adelta);
502 if (!ent->state_previous.active || cls.timedemo || DotProduct(odelta, odelta) > 1000*1000 || cl_nolerp.integer)
504 // we definitely shouldn't lerp
505 ent->persistent.lerpdeltatime = 0;
506 ent->persistent.lerpstarttime = cl.mtime[1];
507 VectorCopy(ent->state_current.origin, ent->persistent.oldorigin);
508 VectorCopy(ent->state_current.angles, ent->persistent.oldangles);
509 VectorCopy(ent->state_current.origin, ent->persistent.neworigin);
510 VectorCopy(ent->state_current.angles, ent->persistent.newangles);
512 else// if (ent->state_current.flags & RENDER_STEP)
514 // monster interpolation
515 if (DotProduct(odelta, odelta) + DotProduct(adelta, adelta) > 0.01)
517 ent->persistent.lerpdeltatime = bound(0, cl.mtime[1] - ent->persistent.lerpstarttime, 0.1);
518 ent->persistent.lerpstarttime = cl.mtime[1];
519 VectorCopy(ent->persistent.neworigin, ent->persistent.oldorigin);
520 VectorCopy(ent->persistent.newangles, ent->persistent.oldangles);
521 VectorCopy(ent->state_current.origin, ent->persistent.neworigin);
522 VectorCopy(ent->state_current.angles, ent->persistent.newangles);
529 ent->persistent.lerpstarttime = cl.mtime[1];
530 // no lerp if it's singleplayer
531 //if (sv.active && svs.maxclients == 1 && !ent->state_current.flags & RENDER_STEP)
532 // ent->persistent.lerpdeltatime = 0;
534 ent->persistent.lerpdeltatime = cl.mtime[0] - cl.mtime[1];
535 VectorCopy(ent->persistent.neworigin, ent->persistent.oldorigin);
536 VectorCopy(ent->persistent.newangles, ent->persistent.oldangles);
537 VectorCopy(ent->state_current.origin, ent->persistent.neworigin);
538 VectorCopy(ent->state_current.angles, ent->persistent.newangles);
547 Parse an entity update message from the server
548 If an entities model or origin changes from frame to frame, it must be
549 relinked. Other attributes can change without relinking.
552 void CL_ParseUpdate (int bits)
558 if (bits & U_MOREBITS)
559 bits |= (MSG_ReadByte()<<8);
560 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
562 bits |= MSG_ReadByte() << 16;
563 if (bits & U_EXTEND2)
564 bits |= MSG_ReadByte() << 24;
567 if (bits & U_LONGENTITY)
568 num = (unsigned) MSG_ReadShort ();
570 num = (unsigned) MSG_ReadByte ();
572 if (num >= MAX_EDICTS)
573 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
575 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
577 ent = cl_entities + num;
579 // note: this inherits the 'active' state of the baseline chosen
580 // (state_baseline is always active, state_current may not be active if
581 // the entity was missing in the last frame)
583 new = ent->state_current;
586 new = ent->state_baseline;
591 new.time = cl.mtime[0];
593 if (bits & U_MODEL) new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte();
594 if (bits & U_FRAME) new.frame = (new.frame & 0xFF00) | MSG_ReadByte();
595 if (bits & U_COLORMAP) new.colormap = MSG_ReadByte();
596 if (bits & U_SKIN) new.skin = MSG_ReadByte();
597 if (bits & U_EFFECTS) new.effects = (new.effects & 0xFF00) | MSG_ReadByte();
598 if (bits & U_ORIGIN1) new.origin[0] = MSG_ReadCoord();
599 if (bits & U_ANGLE1) new.angles[0] = MSG_ReadAngle();
600 if (bits & U_ORIGIN2) new.origin[1] = MSG_ReadCoord();
601 if (bits & U_ANGLE2) new.angles[1] = MSG_ReadAngle();
602 if (bits & U_ORIGIN3) new.origin[2] = MSG_ReadCoord();
603 if (bits & U_ANGLE3) new.angles[2] = MSG_ReadAngle();
604 if (bits & U_STEP) new.flags |= RENDER_STEP;
605 if (bits & U_ALPHA) new.alpha = MSG_ReadByte();
606 if (bits & U_SCALE) new.scale = MSG_ReadByte();
607 if (bits & U_EFFECTS2) new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8);
608 if (bits & U_GLOWSIZE) new.glowsize = MSG_ReadByte();
609 if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte();
610 // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
611 if (bits & U_COLORMOD) MSG_ReadByte();
612 if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL;
613 if (bits & U_FRAME2) new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8);
614 if (bits & U_MODEL2) new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
615 if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL;
616 if (bits & U_EXTERIORMODEL) new.flags |= RENDER_EXTERIORMODEL;
618 // LordHavoc: to allow playback of the Nehahra movie
619 if (Nehahrademcompatibility && (bits & U_EXTEND1))
621 // LordHavoc: evil format
622 int i = MSG_ReadFloat();
623 int j = MSG_ReadFloat() * 255.0f;
628 new.effects |= EF_FULLBRIGHT;
632 else if (j == 0 || j >= 255)
639 CL_ValidateState(&new);
641 ent->state_previous = ent->state_current;
642 ent->state_current = new;
643 if (ent->state_current.active)
645 CL_MoveLerpEntityStates(ent);
646 cl_entities_active[ent->state_current.number] = true;
647 // mark as visible (no kill this frame)
648 entlife[ent->state_current.number] = 2;
652 void CL_ReadEntityFrame(void)
655 entity_frame_t entityframe;
657 EntityFrame_Read(&cl.entitydatabase);
658 EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
659 for (i = 0;i < entityframe.numentities;i++)
662 ent = &cl_entities[entityframe.entitydata[i].number];
663 ent->state_previous = ent->state_current;
664 ent->state_current = entityframe.entitydata[i];
665 CL_MoveLerpEntityStates(ent);
666 // the entity lives again...
667 entlife[ent->state_current.number] = 2;
668 cl_entities_active[ent->state_current.number] = true;
670 VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
671 VectorCopy(entityframe.eye, cl.viewentoriginnew);
674 void CL_EntityUpdateSetup(void)
678 void CL_EntityUpdateEnd(void)
681 // disable entities that disappeared this frame
682 for (i = 1;i < MAX_EDICTS;i++)
684 // clear only the entities that were active last frame but not this
685 // frame, don't waste time clearing all entities (which would cause
691 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
701 void CL_ParseBaseline (entity_t *ent, int large)
705 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
706 ent->state_baseline.active = true;
709 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
710 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
714 ent->state_baseline.modelindex = MSG_ReadByte ();
715 ent->state_baseline.frame = MSG_ReadByte ();
717 ent->state_baseline.colormap = MSG_ReadByte();
718 ent->state_baseline.skin = MSG_ReadByte();
719 for (i = 0;i < 3;i++)
721 ent->state_baseline.origin[i] = MSG_ReadCoord ();
722 ent->state_baseline.angles[i] = MSG_ReadAngle ();
724 ent->state_baseline.alpha = 255;
725 ent->state_baseline.scale = 16;
726 ent->state_baseline.glowsize = 0;
727 ent->state_baseline.glowcolor = 254;
728 ent->state_previous = ent->state_current = ent->state_baseline;
730 CL_ValidateState(&ent->state_baseline);
738 Server information pertaining to this client only
741 void CL_ParseClientdata (int bits)
746 if (bits & SU_EXTEND1)
747 bits |= (MSG_ReadByte() << 16);
748 if (bits & SU_EXTEND2)
749 bits |= (MSG_ReadByte() << 24);
751 if (bits & SU_VIEWHEIGHT)
752 cl.viewheight = MSG_ReadChar ();
754 cl.viewheight = DEFAULT_VIEWHEIGHT;
756 if (bits & SU_IDEALPITCH)
757 cl.idealpitch = MSG_ReadChar ();
761 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
762 for (i=0 ; i<3 ; i++)
764 if (bits & (SU_PUNCH1<<i) )
767 cl.punchangle[i] = MSG_ReadPreciseAngle();
769 cl.punchangle[i] = MSG_ReadChar();
772 cl.punchangle[i] = 0;
773 if (bits & (SU_PUNCHVEC1<<i))
774 cl.punchvector[i] = MSG_ReadCoord();
776 cl.punchvector[i] = 0;
777 if (bits & (SU_VELOCITY1<<i) )
778 cl.mvelocity[0][i] = MSG_ReadChar()*16;
780 cl.mvelocity[0][i] = 0;
786 for (j=0 ; j<32 ; j++)
787 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
788 cl.item_gettime[j] = cl.time;
792 cl.onground = (bits & SU_ONGROUND) != 0;
793 cl.inwater = (bits & SU_INWATER) != 0;
795 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
796 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
797 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
798 cl.stats[STAT_HEALTH] = MSG_ReadShort();
799 cl.stats[STAT_AMMO] = MSG_ReadByte();
801 cl.stats[STAT_SHELLS] = MSG_ReadByte();
802 cl.stats[STAT_NAILS] = MSG_ReadByte();
803 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
804 cl.stats[STAT_CELLS] = MSG_ReadByte();
808 if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
809 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
811 cl.stats[STAT_ACTIVEWEAPON] = i;
813 cl.viewzoomold = cl.viewzoomnew; // for interpolation
814 if (bits & SU_VIEWZOOM)
819 cl.viewzoomnew = (float) i * (1.0f / 255.0f);
827 =====================
829 =====================
831 void CL_ParseStatic (int large)
835 if (cl_num_static_entities >= cl_max_static_entities)
836 Host_Error ("Too many static entities");
837 ent = &cl_static_entities[cl_num_static_entities++];
838 CL_ParseBaseline (ent, large);
840 // copy it to the current state
841 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
842 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
843 ent->render.framelerp = 0;
844 // make torchs play out of sync
845 ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1);
846 ent->render.colormap = -1; // no special coloring
847 ent->render.skinnum = ent->state_baseline.skin;
848 ent->render.effects = ent->state_baseline.effects;
849 ent->render.alpha = 1;
850 ent->render.scale = 1;
851 ent->render.alpha = 1;
853 VectorCopy (ent->state_baseline.origin, ent->render.origin);
854 VectorCopy (ent->state_baseline.angles, ent->render.angles);
856 CL_BoundingBoxForEntity(&ent->render);
858 // This is definitely cheating...
859 if (ent->render.model == NULL)
860 cl_num_static_entities--;
868 void CL_ParseStaticSound (int large)
871 int sound_num, vol, atten;
875 sound_num = (unsigned short) MSG_ReadShort ();
877 sound_num = MSG_ReadByte ();
878 vol = MSG_ReadByte ();
879 atten = MSG_ReadByte ();
881 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
884 void CL_ParseEffect (void)
887 int modelindex, startframe, framecount, framerate;
890 modelindex = MSG_ReadByte ();
891 startframe = MSG_ReadByte ();
892 framecount = MSG_ReadByte ();
893 framerate = MSG_ReadByte ();
895 CL_Effect(org, modelindex, startframe, framecount, framerate);
898 void CL_ParseEffect2 (void)
901 int modelindex, startframe, framecount, framerate;
904 modelindex = MSG_ReadShort ();
905 startframe = MSG_ReadShort ();
906 framecount = MSG_ReadByte ();
907 framerate = MSG_ReadByte ();
909 CL_Effect(org, modelindex, startframe, framecount, framerate);
912 model_t *cl_model_bolt = NULL;
913 model_t *cl_model_bolt2 = NULL;
914 model_t *cl_model_bolt3 = NULL;
915 model_t *cl_model_beam = NULL;
917 sfx_t *cl_sfx_wizhit;
918 sfx_t *cl_sfx_knighthit;
923 sfx_t *cl_sfx_r_exp3;
930 void CL_InitTEnts (void)
932 cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav", false);
933 cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav", false);
934 cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav", false);
935 cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav", false);
936 cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav", false);
937 cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav", false);
938 cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav", false);
941 void CL_ParseBeam (model_t *m, int lightning)
947 ent = MSG_ReadShort ();
948 MSG_ReadVector(start);
951 if (ent >= MAX_EDICTS)
953 Con_Printf("CL_ParseBeam: invalid entity number %i\n", ent);
957 // override any beam with the same entity
958 for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
960 if (b->entity == ent)
963 b->lightning = lightning;
964 b->relativestartvalid = (ent && cl_entities[ent].state_current.active) ? 2 : 0;
966 b->endtime = cl.time + 0.2;
967 VectorCopy (start, b->start);
968 VectorCopy (end, b->end);
974 for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
976 if (!b->model || b->endtime < cl.time)
979 b->lightning = lightning;
980 b->relativestartvalid = (ent && cl_entities[ent].state_current.active) ? 2 : 0;
982 b->endtime = cl.time + 0.2;
983 VectorCopy (start, b->start);
984 VectorCopy (end, b->end);
988 Con_Printf ("beam list overflow!\n");
991 void CL_ParseTempEntity (void)
999 int colorStart, colorLength, count;
1000 float velspeed, radius;
1003 type = MSG_ReadByte ();
1007 // spike hitting wall
1008 MSG_ReadVector(pos);
1009 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1010 CL_RunParticleEffect (pos, vec3_origin, 20, 30);
1011 S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
1014 case TE_KNIGHTSPIKE:
1015 // spike hitting wall
1016 MSG_ReadVector(pos);
1017 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1018 CL_RunParticleEffect (pos, vec3_origin, 226, 20);
1019 S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
1023 // spike hitting wall
1024 MSG_ReadVector(pos);
1025 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1026 // LordHavoc: changed to spark shower
1027 CL_SparkShower(pos, vec3_origin, 15);
1029 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1034 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1036 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1038 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1042 // quad spike hitting wall
1043 MSG_ReadVector(pos);
1044 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1045 // LordHavoc: changed to spark shower
1046 CL_SparkShower(pos, vec3_origin, 15);
1047 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1048 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1050 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1055 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1057 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1059 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1063 // super spike hitting wall
1064 MSG_ReadVector(pos);
1065 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1066 // LordHavoc: changed to dust shower
1067 CL_SparkShower(pos, vec3_origin, 30);
1069 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1074 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1076 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1078 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1081 case TE_SUPERSPIKEQUAD:
1082 // quad super spike hitting wall
1083 MSG_ReadVector(pos);
1084 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1085 // LordHavoc: changed to dust shower
1086 CL_SparkShower(pos, vec3_origin, 30);
1087 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1089 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1094 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1096 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1098 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1101 // LordHavoc: added for improved blood splatters
1104 MSG_ReadVector(pos);
1105 dir[0] = MSG_ReadChar ();
1106 dir[1] = MSG_ReadChar ();
1107 dir[2] = MSG_ReadChar ();
1108 count = MSG_ReadByte ();
1109 CL_BloodPuff(pos, dir, count);
1113 MSG_ReadVector(pos);
1114 CL_BloodPuff(pos, vec3_origin, 10);
1118 MSG_ReadVector(pos);
1119 dir[0] = MSG_ReadChar ();
1120 dir[1] = MSG_ReadChar ();
1121 dir[2] = MSG_ReadChar ();
1122 count = MSG_ReadByte ();
1123 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1124 CL_SparkShower(pos, dir, count);
1127 MSG_ReadVector(pos);
1128 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1129 CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
1132 // LordHavoc: added for improved gore
1133 case TE_BLOODSHOWER:
1135 MSG_ReadVector(pos); // mins
1136 MSG_ReadVector(pos2); // maxs
1137 velspeed = MSG_ReadCoord (); // speed
1138 count = MSG_ReadShort (); // number of particles
1139 CL_BloodShower(pos, pos2, velspeed, count);
1141 case TE_PARTICLECUBE:
1142 // general purpose particle effect
1143 MSG_ReadVector(pos); // mins
1144 MSG_ReadVector(pos2); // maxs
1145 MSG_ReadVector(dir); // dir
1146 count = MSG_ReadShort (); // number of particles
1147 colorStart = MSG_ReadByte (); // color
1148 colorLength = MSG_ReadByte (); // gravity (1 or 0)
1149 velspeed = MSG_ReadCoord (); // randomvel
1150 CL_ParticleCube(pos, pos2, dir, count, colorStart, colorLength, velspeed);
1153 case TE_PARTICLERAIN:
1154 // general purpose particle effect
1155 MSG_ReadVector(pos); // mins
1156 MSG_ReadVector(pos2); // maxs
1157 MSG_ReadVector(dir); // dir
1158 count = MSG_ReadShort (); // number of particles
1159 colorStart = MSG_ReadByte (); // color
1160 CL_ParticleRain(pos, pos2, dir, count, colorStart, 0);
1163 case TE_PARTICLESNOW:
1164 // general purpose particle effect
1165 MSG_ReadVector(pos); // mins
1166 MSG_ReadVector(pos2); // maxs
1167 MSG_ReadVector(dir); // dir
1168 count = MSG_ReadShort (); // number of particles
1169 colorStart = MSG_ReadByte (); // color
1170 CL_ParticleRain(pos, pos2, dir, count, colorStart, 1);
1174 // bullet hitting wall
1175 MSG_ReadVector(pos);
1176 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1177 // LordHavoc: changed to dust shower
1178 CL_SparkShower(pos, vec3_origin, 15);
1181 case TE_GUNSHOTQUAD:
1182 // quad bullet hitting wall
1183 MSG_ReadVector(pos);
1184 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1185 CL_SparkShower(pos, vec3_origin, 15);
1186 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1191 MSG_ReadVector(pos);
1192 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1193 CL_ParticleExplosion (pos);
1194 // LordHavoc: boosted color from 1.0, 0.8, 0.4 to 1.25, 1.0, 0.5
1195 CL_AllocDlight (NULL, pos, 350, 1.25f, 1.0f, 0.5f, 700, 0.5);
1196 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1199 case TE_EXPLOSIONQUAD:
1200 // quad rocket explosion
1201 MSG_ReadVector(pos);
1202 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1203 CL_ParticleExplosion (pos);
1204 CL_AllocDlight (NULL, pos, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5);
1205 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1209 // Nehahra movie colored lighting explosion
1210 MSG_ReadVector(pos);
1211 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1212 CL_ParticleExplosion (pos);
1213 CL_AllocDlight (NULL, pos, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5);
1214 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1217 case TE_EXPLOSIONRGB:
1218 // colored lighting explosion
1219 MSG_ReadVector(pos);
1220 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1221 CL_ParticleExplosion (pos);
1222 color[0] = MSG_ReadByte() * (1.0 / 255.0);
1223 color[1] = MSG_ReadByte() * (1.0 / 255.0);
1224 color[2] = MSG_ReadByte() * (1.0 / 255.0);
1225 CL_AllocDlight (NULL, pos, 350, color[0], color[1], color[2], 700, 0.5);
1226 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1229 case TE_TAREXPLOSION:
1230 // tarbaby explosion
1231 MSG_ReadVector(pos);
1232 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1233 CL_BlobExplosion (pos);
1235 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1236 CL_AllocDlight (NULL, pos, 600, 0.8f, 0.4f, 1.0f, 1200, 0.5);
1237 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1241 MSG_ReadVector(pos);
1242 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1243 CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
1246 case TE_CUSTOMFLASH:
1247 MSG_ReadVector(pos);
1248 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1249 radius = MSG_ReadByte() * 8;
1250 velspeed = (MSG_ReadByte() + 1) * (1.0 / 256.0);
1251 color[0] = MSG_ReadByte() * (1.0 / 255.0);
1252 color[1] = MSG_ReadByte() * (1.0 / 255.0);
1253 color[2] = MSG_ReadByte() * (1.0 / 255.0);
1254 CL_AllocDlight (NULL, pos, radius, color[0], color[1], color[2], radius / velspeed, velspeed);
1258 MSG_ReadVector(pos);
1259 MSG_ReadVector(dir);
1260 count = MSG_ReadByte();
1261 CL_Flames(pos, dir, count);
1267 cl_model_bolt = Mod_ForName("progs/bolt.mdl", true, false, false);
1268 CL_ParseBeam (cl_model_bolt, true);
1273 if (!cl_model_bolt2)
1274 cl_model_bolt2 = Mod_ForName("progs/bolt2.mdl", true, false, false);
1275 CL_ParseBeam (cl_model_bolt2, true);
1280 if (!cl_model_bolt3)
1281 cl_model_bolt3 = Mod_ForName("progs/bolt3.mdl", true, false, false);
1282 CL_ParseBeam (cl_model_bolt3, true);
1287 // grappling hook beam
1289 cl_model_beam = Mod_ForName("progs/beam.mdl", true, false, false);
1290 CL_ParseBeam (cl_model_beam, false);
1294 // LordHavoc: for compatibility with the Nehahra movie...
1295 case TE_LIGHTNING4NEH:
1296 CL_ParseBeam (Mod_ForName(MSG_ReadString(), true, false, false), false);
1300 pos[0] = MSG_ReadCoord ();
1301 pos[1] = MSG_ReadCoord ();
1302 pos[2] = MSG_ReadCoord ();
1303 CL_LavaSplash (pos);
1307 pos[0] = MSG_ReadCoord ();
1308 pos[1] = MSG_ReadCoord ();
1309 pos[2] = MSG_ReadCoord ();
1310 CL_AllocDlight (NULL, pos, 500, 1.0f, 1.0f, 1.0f, 1500, 99.0f);
1311 // CL_TeleportSplash (pos);
1315 // color mapped explosion
1316 MSG_ReadVector(pos);
1317 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1318 colorStart = MSG_ReadByte ();
1319 colorLength = MSG_ReadByte ();
1320 CL_ParticleExplosion2 (pos, colorStart, colorLength);
1321 tempcolor = (qbyte *)&palette_complete[(rand()%colorLength) + colorStart];
1322 CL_AllocDlight (NULL, pos, 350, tempcolor[0] * (1.0f / 255.0f), tempcolor[1] * (1.0f / 255.0f), tempcolor[2] * (1.0f / 255.0f), 700, 0.5);
1323 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1327 MSG_ReadVector(pos);
1328 MSG_ReadVector(pos2);
1329 MSG_ReadVector(dir);
1330 CL_BeamParticle(pos, pos2, 12, 1, 0.3, 0.1, 1, 1);
1331 CL_BeamParticle(pos, pos2, 5, 1, 0.9, 0.3, 1, 1);
1335 MSG_ReadVector(pos);
1336 MSG_ReadVector(dir);
1337 count = MSG_ReadByte ();
1338 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1339 CL_Tei_Smoke(pos, dir, count);
1342 case TE_TEI_BIGEXPLOSION:
1343 MSG_ReadVector(pos);
1344 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1345 CL_ParticleExplosion (pos);
1346 CL_AllocDlight (NULL, pos, 500, 1.25f, 1.0f, 0.5f, 500, 9999);
1347 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1350 case TE_TEI_PLASMAHIT:
1351 MSG_ReadVector(pos);
1352 MSG_ReadVector(dir);
1353 count = MSG_ReadByte ();
1354 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1355 CL_Tei_PlasmaHit(pos, dir, count);
1356 CL_AllocDlight (NULL, pos, 500, 0.3, 0.6, 1.0f, 2000, 9999);
1360 Host_Error ("CL_ParseTempEntity: bad type %d (hex %02X)", type, type);
1364 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
1366 static qbyte cgamenetbuffer[65536];
1369 =====================
1370 CL_ParseServerMessage
1371 =====================
1373 int parsingerror = false;
1374 void CL_ParseServerMessage (void)
1377 int i, entitiesupdated;
1379 char *cmdlogname[32], *temp;
1380 int cmdindex, cmdcount = 0;
1383 // if recording demos, copy the message out
1385 if (cl_shownet.integer == 1)
1386 Con_Printf ("%i ",net_message.cursize);
1387 else if (cl_shownet.integer == 2)
1388 Con_Printf ("------------------\n");
1390 cl.onground = false; // unless the server says otherwise
1392 // parse the message
1394 MSG_BeginReading ();
1396 entitiesupdated = false;
1398 parsingerror = true;
1403 Host_Error ("CL_ParseServerMessage: Bad server message");
1405 cmd = MSG_ReadByte ();
1409 SHOWNET("END OF MESSAGE");
1410 break; // end of message
1413 cmdindex = cmdcount & 31;
1415 cmdlog[cmdindex] = cmd;
1417 // if the high bit of the command byte is set, it is a fast update
1420 // LordHavoc: fix for bizarre problem in MSVC that I do not understand (if I assign the string pointer directly it ends up storing a NULL pointer)
1422 cmdlogname[cmdindex] = temp;
1423 SHOWNET("fast update");
1424 if (cls.signon == SIGNONS - 1)
1426 // first update is the final signon stage
1427 cls.signon = SIGNONS;
1430 CL_ParseUpdate (cmd&127);
1434 SHOWNET(svc_strings[cmd]);
1435 cmdlogname[cmdindex] = svc_strings[cmd];
1436 if (!cmdlogname[cmdindex])
1438 // LordHavoc: fix for bizarre problem in MSVC that I do not understand (if I assign the string pointer directly it ends up storing a NULL pointer)
1440 cmdlogname[cmdindex] = temp;
1448 char description[32*64], temp[64];
1450 strcpy(description, "packet dump: ");
1454 count = cmdcount - i;
1458 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
1459 strcat(description, temp);
1464 description[strlen(description)-1] = '\n'; // replace the last space with a newline
1465 Con_Printf("%s", description);
1466 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
1474 if (!entitiesupdated)
1476 // this is a new frame, we'll be seeing entities,
1477 // so prepare for entity updates
1478 CL_EntityUpdateSetup();
1479 entitiesupdated = true;
1481 cl.mtime[1] = cl.mtime[0];
1482 cl.mtime[0] = MSG_ReadFloat ();
1485 case svc_clientdata:
1486 i = MSG_ReadShort ();
1487 CL_ParseClientdata (i);
1491 i = MSG_ReadLong ();
1492 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
1493 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
1494 Nehahrademcompatibility = false;
1496 Nehahrademcompatibility = true;
1497 if (cls.demoplayback && demo_nehahra.integer)
1498 Nehahrademcompatibility = true;
1500 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
1504 case svc_disconnect:
1505 Host_EndGame ("Server disconnected\n");
1508 Con_Printf ("%s", MSG_ReadString ());
1511 case svc_centerprint:
1512 SCR_CenterPrint (MSG_ReadString ());
1516 Cbuf_AddText (MSG_ReadString ());
1523 case svc_serverinfo:
1524 CL_ParseServerInfo ();
1528 for (i=0 ; i<3 ; i++)
1529 cl.viewangles[i] = MSG_ReadAngle ();
1533 cl.viewentity = MSG_ReadShort ();
1534 // LordHavoc: assume first setview recieved is the real player entity
1535 if (!cl.playerentity)
1536 cl.playerentity = cl.viewentity;
1539 case svc_lightstyle:
1540 i = MSG_ReadByte ();
1541 if (i >= MAX_LIGHTSTYLES)
1542 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1543 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1544 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1545 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1549 CL_ParseStartSoundPacket(false);
1553 CL_ParseStartSoundPacket(true);
1557 i = MSG_ReadShort();
1558 S_StopSound(i>>3, i&7);
1561 case svc_updatename:
1562 i = MSG_ReadByte ();
1563 if (i >= cl.maxclients)
1564 Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
1565 strcpy (cl.scores[i].name, MSG_ReadString ());
1568 case svc_updatefrags:
1569 i = MSG_ReadByte ();
1570 if (i >= cl.maxclients)
1571 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
1572 cl.scores[i].frags = MSG_ReadShort ();
1575 case svc_updatecolors:
1576 i = MSG_ReadByte ();
1577 if (i >= cl.maxclients)
1578 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
1579 cl.scores[i].colors = MSG_ReadByte ();
1580 // update our color cvar if our color changed
1581 if (i == cl.playerentity - 1)
1582 Cvar_SetValue ("_cl_color", cl.scores[i].colors);
1586 CL_ParseParticleEffect ();
1597 case svc_spawnbaseline:
1598 i = MSG_ReadShort ();
1599 if (i < 0 || i >= MAX_EDICTS)
1600 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
1601 CL_ParseBaseline (cl_entities + i, false);
1603 case svc_spawnbaseline2:
1604 i = MSG_ReadShort ();
1605 if (i < 0 || i >= MAX_EDICTS)
1606 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline2: invalid entity number %i", i);
1607 CL_ParseBaseline (cl_entities + i, true);
1609 case svc_spawnstatic:
1610 CL_ParseStatic (false);
1612 case svc_spawnstatic2:
1613 CL_ParseStatic (true);
1615 case svc_temp_entity:
1616 CL_ParseTempEntity ();
1620 cl.paused = MSG_ReadByte ();
1628 i = MSG_ReadByte ();
1629 if (i <= cls.signon)
1630 Host_Error ("Received signon %i when at %i", i, cls.signon);
1635 case svc_killedmonster:
1636 cl.stats[STAT_MONSTERS]++;
1639 case svc_foundsecret:
1640 cl.stats[STAT_SECRETS]++;
1643 case svc_updatestat:
1644 i = MSG_ReadByte ();
1645 if (i < 0 || i >= MAX_CL_STATS)
1646 Host_Error ("svc_updatestat: %i is invalid", i);
1647 cl.stats[i] = MSG_ReadLong ();
1650 case svc_spawnstaticsound:
1651 CL_ParseStaticSound (false);
1654 case svc_spawnstaticsound2:
1655 CL_ParseStaticSound (true);
1659 cl.cdtrack = MSG_ReadByte ();
1660 cl.looptrack = MSG_ReadByte ();
1661 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1662 CDAudio_Play ((qbyte)cls.forcetrack, true);
1664 CDAudio_Play ((qbyte)cl.cdtrack, true);
1667 case svc_intermission:
1668 cl.intermission = 1;
1669 cl.completed_time = cl.time;
1673 cl.intermission = 2;
1674 cl.completed_time = cl.time;
1675 SCR_CenterPrint (MSG_ReadString ());
1679 cl.intermission = 3;
1680 cl.completed_time = cl.time;
1681 SCR_CenterPrint (MSG_ReadString ());
1684 case svc_sellscreen:
1685 Cmd_ExecuteString ("help", src_command);
1688 SHOWLMP_decodehide();
1691 SHOWLMP_decodeshow();
1694 R_SetSkyBox(MSG_ReadString());
1699 length = (int) ((unsigned short) MSG_ReadShort());
1700 for (i = 0;i < length;i++)
1701 cgamenetbuffer[i] = MSG_ReadByte();
1703 CL_CGVM_ParseNetwork(cgamenetbuffer, length);
1707 if (cls.signon == SIGNONS - 1)
1709 // first update is the final signon stage
1710 cls.signon = SIGNONS;
1713 CL_ReadEntityFrame();
1718 if (entitiesupdated)
1719 CL_EntityUpdateEnd();
1721 parsingerror = false;
1724 void CL_Parse_DumpPacket(void)
1728 Con_Printf("Packet dump:\n");
1729 SZ_HexDumpToConsole(&net_message);
1730 parsingerror = false;
1733 void CL_Parse_Init(void)
1735 // LordHavoc: added demo_nehahra cvar
1736 Cvar_RegisterVariable (&demo_nehahra);
1737 if (gamemode == GAME_NEHAHRA)
1738 Cvar_SetValue("demo_nehahra", 1);