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 channel = MSG_ReadShort ();
131 sound_num = (unsigned short) MSG_ReadShort ();
133 sound_num = MSG_ReadByte ();
135 if (sound_num >= MAX_SOUNDS)
136 Host_Error("CL_ParseStartSoundPacket: sound_num (%i) >= MAX_SOUNDS (%i)\n", sound_num, MAX_SOUNDS);
141 if (ent > MAX_EDICTS)
142 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
144 for (i=0 ; i<3 ; i++)
145 pos[i] = MSG_ReadCoord ();
147 S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
154 When the client is taking a long time to load stuff, send keepalive messages
155 so the server doesn't disconnect.
158 void CL_KeepaliveMessage (void)
161 static float lastmsg;
168 return; // no need if server is local
169 if (cls.demoplayback)
172 // read messages from server, should just be nops
174 memcpy (olddata, net_message.data, net_message.cursize);
178 ret = CL_GetMessage ();
182 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
184 break; // nothing waiting
186 Host_Error ("CL_KeepaliveMessage: received a message");
191 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
197 memcpy (net_message.data, olddata, net_message.cursize);
200 time = Sys_DoubleTime ();
201 if (time - lastmsg < 5)
206 Con_Printf ("--> client to server keepalive\n");
208 MSG_WriteByte (&cls.message, clc_nop);
209 NET_SendMessage (cls.netcon, &cls.message);
210 SZ_Clear (&cls.message);
213 void CL_ParseEntityLump(char *entdata)
216 char key[128], value[4096];
217 FOG_clear(); // LordHavoc: no fog until set
218 R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set
222 if (!COM_ParseToken(&data))
224 if (com_token[0] != '{')
228 if (!COM_ParseToken(&data))
230 if (com_token[0] == '}')
231 break; // end of worldspawn
232 if (com_token[0] == '_')
233 strcpy(key, com_token + 1);
235 strcpy(key, com_token);
236 while (key[strlen(key)-1] == ' ') // remove trailing spaces
237 key[strlen(key)-1] = 0;
238 if (!COM_ParseToken(&data))
240 strcpy(value, com_token);
241 if (!strcmp("sky", key))
243 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
245 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
247 else if (!strcmp("fog", key))
248 sscanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
249 else if (!strcmp("fog_density", key))
250 fog_density = atof(value);
251 else if (!strcmp("fog_red", key))
252 fog_red = atof(value);
253 else if (!strcmp("fog_green", key))
254 fog_green = atof(value);
255 else if (!strcmp("fog_blue", key))
256 fog_blue = atof(value);
261 =====================
264 An svc_signonnum has been received, perform a client side setup
265 =====================
267 static void CL_SignonReply (void)
271 Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
276 MSG_WriteByte (&cls.message, clc_stringcmd);
277 MSG_WriteString (&cls.message, "prespawn");
281 MSG_WriteByte (&cls.message, clc_stringcmd);
282 MSG_WriteString (&cls.message, va("name \"%s\"\n", cl_name.string));
284 MSG_WriteByte (&cls.message, clc_stringcmd);
285 MSG_WriteString (&cls.message, va("color %i %i\n", cl_color.integer >> 4, cl_color.integer & 15));
287 if (cl_pmodel.integer)
289 MSG_WriteByte (&cls.message, clc_stringcmd);
290 MSG_WriteString (&cls.message, va("pmodel %i\n", cl_pmodel.integer));
293 MSG_WriteByte (&cls.message, clc_stringcmd);
294 MSG_WriteString (&cls.message, "spawn");
298 MSG_WriteByte (&cls.message, clc_stringcmd);
299 MSG_WriteString (&cls.message, "begin");
313 qbyte entlife[MAX_EDICTS];
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];
323 Con_DPrintf ("Serverinfo packet received.\n");
325 // wipe the client_state_t struct
329 // parse protocol version number
331 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
333 Con_Printf ("Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
336 Nehahrademcompatibility = false;
338 Nehahrademcompatibility = true;
339 if (cls.demoplayback && demo_nehahra.integer)
340 Nehahrademcompatibility = true;
342 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
346 cl.maxclients = MSG_ReadByte ();
347 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
349 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
352 cl.scores = Mem_Alloc(cl_scores_mempool, cl.maxclients*sizeof(*cl.scores));
355 cl.gametype = MSG_ReadByte ();
357 // parse signon message
358 str = MSG_ReadString ();
359 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
361 // seperate the printfs so the server message can have a color
362 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
364 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");
365 Con_Printf ("%c%s\n", 2, str);
369 // first we go through and touch all of the precache data that still
370 // happens to be in the cache, so precaching something else doesn't
371 // needlessly purge it
374 Mem_CheckSentinelsGlobal();
378 // disable until we get textures for it
382 memset (cl.model_precache, 0, sizeof(cl.model_precache));
383 for (nummodels=1 ; ; nummodels++)
385 str = MSG_ReadString ();
388 if (nummodels==MAX_MODELS)
390 Host_Error ("Server sent too many model precaches\n");
393 if (strlen(str) >= MAX_QPATH)
394 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
395 strcpy (model_precache[nummodels], str);
396 Mod_TouchModel (str);
400 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
401 for (numsounds=1 ; ; numsounds++)
403 str = MSG_ReadString ();
406 if (numsounds==MAX_SOUNDS)
408 Host_Error ("Server sent too many sound precaches\n");
411 if (strlen(str) >= MAX_QPATH)
412 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
413 strcpy (sound_precache[numsounds], str);
420 // now we try to load everything else until a cache allocation fails
423 for (i=1 ; i<nummodels ; i++)
425 // LordHavoc: i == 1 means the first model is the world model
426 cl.model_precache[i] = Mod_ForName (model_precache[i], false, false, i == 1);
427 if (cl.model_precache[i] == NULL)
429 Con_Printf("Model %s not found\n", model_precache[i]);
432 CL_KeepaliveMessage ();
435 S_BeginPrecaching ();
436 for (i=1 ; i<numsounds ; i++)
438 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i], true);
439 CL_KeepaliveMessage ();
444 ent = &cl_entities[0];
445 // entire entity array was cleared, so just fill in a few fields
446 ent->state_current.active = true;
447 ent->render.model = cl.worldmodel = cl.model_precache[1];
448 ent->render.scale = 1;
449 ent->render.alpha = 1;
450 CL_BoundingBoxForEntity(&ent->render);
451 // clear entlife array
452 memset(entlife, 0, MAX_EDICTS);
459 noclip_anglehack = false; // noclip is turned off at start
461 Mem_CheckSentinelsGlobal();
465 void CL_ValidateState(entity_state_t *s)
472 if (s->modelindex >= MAX_MODELS)
473 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
475 // colormap is client index + 1
476 if (s->colormap > cl.maxclients)
477 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
479 model = cl.model_precache[s->modelindex];
480 Mod_CheckLoaded(model);
481 if (model && s->frame >= model->numframes)
483 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
486 if (model && s->skin > 0 && s->skin >= model->numskins)
488 Con_DPrintf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
493 void CL_MoveLerpEntityStates(entity_t *ent)
495 float odelta[3], adelta[3];
496 VectorSubtract(ent->state_current.origin, ent->persistent.neworigin, odelta);
497 VectorSubtract(ent->state_current.angles, ent->persistent.newangles, adelta);
498 if (!ent->state_previous.active || cls.timedemo || DotProduct(odelta, odelta) > 1000*1000 || cl_nolerp.integer)
500 // we definitely shouldn't lerp
501 ent->persistent.lerpdeltatime = 0;
502 ent->persistent.lerpstarttime = cl.mtime[1];
503 VectorCopy(ent->state_current.origin, ent->persistent.oldorigin);
504 VectorCopy(ent->state_current.angles, ent->persistent.oldangles);
505 VectorCopy(ent->state_current.origin, ent->persistent.neworigin);
506 VectorCopy(ent->state_current.angles, ent->persistent.newangles);
508 else// if (ent->state_current.flags & RENDER_STEP)
510 // monster interpolation
511 if (DotProduct(odelta, odelta) + DotProduct(adelta, adelta) > 0.01 || cl.mtime[0] - ent->persistent.lerpstarttime >= 0.1)
513 ent->persistent.lerpdeltatime = cl.time - ent->persistent.lerpstarttime;
514 ent->persistent.lerpstarttime = cl.mtime[1];
515 VectorCopy(ent->persistent.neworigin, ent->persistent.oldorigin);
516 VectorCopy(ent->persistent.newangles, ent->persistent.oldangles);
517 VectorCopy(ent->state_current.origin, ent->persistent.neworigin);
518 VectorCopy(ent->state_current.angles, ent->persistent.newangles);
525 ent->persistent.lerpstarttime = cl.mtime[1];
526 // no lerp if it's singleplayer
527 //if (sv.active && svs.maxclients == 1 && !ent->state_current.flags & RENDER_STEP)
528 // ent->persistent.lerpdeltatime = 0;
530 ent->persistent.lerpdeltatime = cl.mtime[0] - cl.mtime[1];
531 VectorCopy(ent->persistent.neworigin, ent->persistent.oldorigin);
532 VectorCopy(ent->persistent.newangles, ent->persistent.oldangles);
533 VectorCopy(ent->state_current.origin, ent->persistent.neworigin);
534 VectorCopy(ent->state_current.angles, ent->persistent.newangles);
543 Parse an entity update message from the server
544 If an entities model or origin changes from frame to frame, it must be
545 relinked. Other attributes can change without relinking.
548 void CL_ParseUpdate (int bits)
554 if (bits & U_MOREBITS)
555 bits |= (MSG_ReadByte()<<8);
556 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
558 bits |= MSG_ReadByte() << 16;
559 if (bits & U_EXTEND2)
560 bits |= MSG_ReadByte() << 24;
563 if (bits & U_LONGENTITY)
564 num = (unsigned) MSG_ReadShort ();
566 num = (unsigned) MSG_ReadByte ();
568 if (num >= MAX_EDICTS)
569 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
571 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
573 ent = cl_entities + num;
575 // note: this inherits the 'active' state of the baseline chosen
576 // (state_baseline is always active, state_current may not be active if
577 // the entity was missing in the last frame)
579 new = ent->state_current;
582 new = ent->state_baseline;
587 new.time = cl.mtime[0];
589 if (bits & U_MODEL) new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte();
590 if (bits & U_FRAME) new.frame = (new.frame & 0xFF00) | MSG_ReadByte();
591 if (bits & U_COLORMAP) new.colormap = MSG_ReadByte();
592 if (bits & U_SKIN) new.skin = MSG_ReadByte();
593 if (bits & U_EFFECTS) new.effects = (new.effects & 0xFF00) | MSG_ReadByte();
594 if (bits & U_ORIGIN1) new.origin[0] = MSG_ReadCoord();
595 if (bits & U_ANGLE1) new.angles[0] = MSG_ReadAngle();
596 if (bits & U_ORIGIN2) new.origin[1] = MSG_ReadCoord();
597 if (bits & U_ANGLE2) new.angles[1] = MSG_ReadAngle();
598 if (bits & U_ORIGIN3) new.origin[2] = MSG_ReadCoord();
599 if (bits & U_ANGLE3) new.angles[2] = MSG_ReadAngle();
600 if (bits & U_STEP) new.flags |= RENDER_STEP;
601 if (bits & U_ALPHA) new.alpha = MSG_ReadByte();
602 if (bits & U_SCALE) new.scale = MSG_ReadByte();
603 if (bits & U_EFFECTS2) new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8);
604 if (bits & U_GLOWSIZE) new.glowsize = MSG_ReadByte();
605 if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte();
606 // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
607 if (bits & U_COLORMOD) MSG_ReadByte();
608 if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL;
609 if (bits & U_FRAME2) new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8);
610 if (bits & U_MODEL2) new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
611 if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL;
612 if (bits & U_EXTERIORMODEL) new.flags |= RENDER_EXTERIORMODEL;
614 // LordHavoc: to allow playback of the Nehahra movie
615 if (Nehahrademcompatibility && (bits & U_EXTEND1))
617 // LordHavoc: evil format
618 int i = MSG_ReadFloat();
619 int j = MSG_ReadFloat() * 255.0f;
624 new.effects |= EF_FULLBRIGHT;
628 else if (j == 0 || j >= 255)
635 CL_ValidateState(&new);
637 ent->state_previous = ent->state_current;
638 ent->state_current = new;
639 if (ent->state_current.active)
641 CL_MoveLerpEntityStates(ent);
642 cl_entities_active[ent->state_current.number] = true;
643 // mark as visible (no kill this frame)
644 entlife[ent->state_current.number] = 2;
648 void CL_ReadEntityFrame(void)
651 entity_frame_t entityframe;
653 EntityFrame_Read(&cl.entitydatabase);
654 EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
655 for (i = 0;i < entityframe.numentities;i++)
658 ent = &cl_entities[entityframe.entitydata[i].number];
659 ent->state_previous = ent->state_current;
660 ent->state_current = entityframe.entitydata[i];
661 CL_MoveLerpEntityStates(ent);
662 // the entity lives again...
663 entlife[ent->state_current.number] = 2;
664 cl_entities_active[ent->state_current.number] = true;
666 VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
667 VectorCopy(entityframe.eye, cl.viewentoriginnew);
670 void CL_EntityUpdateSetup(void)
674 void CL_EntityUpdateEnd(void)
677 // disable entities that disappeared this frame
678 for (i = 1;i < MAX_EDICTS;i++)
680 // clear only the entities that were active last frame but not this
681 // frame, don't waste time clearing all entities (which would cause
687 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
697 void CL_ParseBaseline (entity_t *ent, int large)
701 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
702 ent->state_baseline.active = true;
705 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
706 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
710 ent->state_baseline.modelindex = MSG_ReadByte ();
711 ent->state_baseline.frame = MSG_ReadByte ();
713 ent->state_baseline.colormap = MSG_ReadByte();
714 ent->state_baseline.skin = MSG_ReadByte();
715 for (i = 0;i < 3;i++)
717 ent->state_baseline.origin[i] = MSG_ReadCoord ();
718 ent->state_baseline.angles[i] = MSG_ReadAngle ();
720 ent->state_baseline.alpha = 255;
721 ent->state_baseline.scale = 16;
722 ent->state_baseline.glowsize = 0;
723 ent->state_baseline.glowcolor = 254;
724 ent->state_previous = ent->state_current = ent->state_baseline;
726 CL_ValidateState(&ent->state_baseline);
734 Server information pertaining to this client only
737 void CL_ParseClientdata (int bits)
742 if (bits & SU_EXTEND1)
743 bits |= (MSG_ReadByte() << 16);
744 if (bits & SU_EXTEND2)
745 bits |= (MSG_ReadByte() << 24);
747 if (bits & SU_VIEWHEIGHT)
748 cl.viewheight = MSG_ReadChar ();
750 cl.viewheight = DEFAULT_VIEWHEIGHT;
752 if (bits & SU_IDEALPITCH)
753 cl.idealpitch = MSG_ReadChar ();
757 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
758 for (i=0 ; i<3 ; i++)
760 if (bits & (SU_PUNCH1<<i) )
763 cl.punchangle[i] = MSG_ReadPreciseAngle();
765 cl.punchangle[i] = MSG_ReadChar();
768 cl.punchangle[i] = 0;
769 if (bits & (SU_PUNCHVEC1<<i))
770 cl.punchvector[i] = MSG_ReadCoord();
772 cl.punchvector[i] = 0;
773 if (bits & (SU_VELOCITY1<<i) )
774 cl.mvelocity[0][i] = MSG_ReadChar()*16;
776 cl.mvelocity[0][i] = 0;
782 for (j=0 ; j<32 ; j++)
783 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
784 cl.item_gettime[j] = cl.time;
788 cl.onground = (bits & SU_ONGROUND) != 0;
789 cl.inwater = (bits & SU_INWATER) != 0;
791 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
792 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
793 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
794 cl.stats[STAT_HEALTH] = MSG_ReadShort();
795 cl.stats[STAT_AMMO] = MSG_ReadByte();
797 cl.stats[STAT_SHELLS] = MSG_ReadByte();
798 cl.stats[STAT_NAILS] = MSG_ReadByte();
799 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
800 cl.stats[STAT_CELLS] = MSG_ReadByte();
804 if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
805 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
807 cl.stats[STAT_ACTIVEWEAPON] = i;
809 cl.viewzoomold = cl.viewzoomnew; // for interpolation
810 if (bits & SU_VIEWZOOM)
815 cl.viewzoomnew = (float) i * (1.0f / 255.0f);
823 =====================
825 =====================
827 void CL_ParseStatic (int large)
831 if (cl_num_static_entities >= cl_max_static_entities)
832 Host_Error ("Too many static entities");
833 ent = &cl_static_entities[cl_num_static_entities++];
834 CL_ParseBaseline (ent, large);
836 // copy it to the current state
837 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
838 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
839 ent->render.framelerp = 0;
840 // make torchs play out of sync
841 ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1);
842 ent->render.colormap = -1; // no special coloring
843 ent->render.skinnum = ent->state_baseline.skin;
844 ent->render.effects = ent->state_baseline.effects;
845 ent->render.alpha = 1;
846 ent->render.scale = 1;
847 ent->render.alpha = 1;
849 VectorCopy (ent->state_baseline.origin, ent->render.origin);
850 VectorCopy (ent->state_baseline.angles, ent->render.angles);
852 CL_BoundingBoxForEntity(&ent->render);
854 // This is definitely cheating...
855 if (ent->render.model == NULL)
856 cl_num_static_entities--;
864 void CL_ParseStaticSound (int large)
867 int sound_num, vol, atten;
871 sound_num = (unsigned short) MSG_ReadShort ();
873 sound_num = MSG_ReadByte ();
874 vol = MSG_ReadByte ();
875 atten = MSG_ReadByte ();
877 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
880 void CL_ParseEffect (void)
883 int modelindex, startframe, framecount, framerate;
886 modelindex = MSG_ReadByte ();
887 startframe = MSG_ReadByte ();
888 framecount = MSG_ReadByte ();
889 framerate = MSG_ReadByte ();
891 CL_Effect(org, modelindex, startframe, framecount, framerate);
894 void CL_ParseEffect2 (void)
897 int modelindex, startframe, framecount, framerate;
900 modelindex = MSG_ReadShort ();
901 startframe = MSG_ReadShort ();
902 framecount = MSG_ReadByte ();
903 framerate = MSG_ReadByte ();
905 CL_Effect(org, modelindex, startframe, framecount, framerate);
908 model_t *cl_model_bolt = NULL;
909 model_t *cl_model_bolt2 = NULL;
910 model_t *cl_model_bolt3 = NULL;
911 model_t *cl_model_beam = NULL;
913 sfx_t *cl_sfx_wizhit;
914 sfx_t *cl_sfx_knighthit;
919 sfx_t *cl_sfx_r_exp3;
926 void CL_InitTEnts (void)
928 cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav", false);
929 cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav", false);
930 cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav", false);
931 cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav", false);
932 cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav", false);
933 cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav", false);
934 cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav", false);
937 void CL_ParseBeam (model_t *m)
943 ent = MSG_ReadShort ();
944 MSG_ReadVector(start);
947 // override any beam with the same entity
948 for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
950 if (b->entity == ent)
954 b->endtime = cl.time + 0.2;
955 VectorCopy (start, b->start);
956 VectorCopy (end, b->end);
962 for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
964 if (!b->model || b->endtime < cl.time)
968 b->endtime = cl.time + 0.2;
969 VectorCopy (start, b->start);
970 VectorCopy (end, b->end);
974 Con_Printf ("beam list overflow!\n");
977 void CL_ParseTempEntity (void)
985 int colorStart, colorLength, count;
986 float velspeed, radius;
989 type = MSG_ReadByte ();
993 // spike hitting wall
995 Mod_FindNonSolidLocation(pos, cl.worldmodel);
996 CL_RunParticleEffect (pos, vec3_origin, 20, 30);
997 S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
1000 case TE_KNIGHTSPIKE:
1001 // spike hitting wall
1002 MSG_ReadVector(pos);
1003 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1004 CL_RunParticleEffect (pos, vec3_origin, 226, 20);
1005 S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
1009 // spike hitting wall
1010 MSG_ReadVector(pos);
1011 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1012 // LordHavoc: changed to spark shower
1013 CL_SparkShower(pos, vec3_origin, 15);
1015 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1020 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1022 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1024 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1028 // quad spike hitting wall
1029 MSG_ReadVector(pos);
1030 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1031 // LordHavoc: changed to spark shower
1032 CL_SparkShower(pos, vec3_origin, 15);
1033 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1034 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1036 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1041 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1043 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1045 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1049 // super spike hitting wall
1050 MSG_ReadVector(pos);
1051 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1052 // LordHavoc: changed to dust shower
1053 CL_SparkShower(pos, vec3_origin, 30);
1055 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1060 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1062 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1064 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1067 case TE_SUPERSPIKEQUAD:
1068 // quad super spike hitting wall
1069 MSG_ReadVector(pos);
1070 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1071 // LordHavoc: changed to dust shower
1072 CL_SparkShower(pos, vec3_origin, 30);
1073 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1075 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1080 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1082 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1084 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1087 // LordHavoc: added for improved blood splatters
1090 MSG_ReadVector(pos);
1091 dir[0] = MSG_ReadChar ();
1092 dir[1] = MSG_ReadChar ();
1093 dir[2] = MSG_ReadChar ();
1094 count = MSG_ReadByte ();
1095 CL_BloodPuff(pos, dir, count);
1099 MSG_ReadVector(pos);
1100 CL_BloodPuff(pos, vec3_origin, 10);
1104 MSG_ReadVector(pos);
1105 dir[0] = MSG_ReadChar ();
1106 dir[1] = MSG_ReadChar ();
1107 dir[2] = MSG_ReadChar ();
1108 count = MSG_ReadByte ();
1109 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1110 CL_SparkShower(pos, dir, count);
1113 MSG_ReadVector(pos);
1114 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1115 CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
1118 // LordHavoc: added for improved gore
1119 case TE_BLOODSHOWER:
1121 MSG_ReadVector(pos); // mins
1122 MSG_ReadVector(pos2); // maxs
1123 velspeed = MSG_ReadCoord (); // speed
1124 count = MSG_ReadShort (); // number of particles
1125 CL_BloodShower(pos, pos2, velspeed, count);
1127 case TE_PARTICLECUBE:
1128 // general purpose particle effect
1129 MSG_ReadVector(pos); // mins
1130 MSG_ReadVector(pos2); // maxs
1131 MSG_ReadVector(dir); // dir
1132 count = MSG_ReadShort (); // number of particles
1133 colorStart = MSG_ReadByte (); // color
1134 colorLength = MSG_ReadByte (); // gravity (1 or 0)
1135 velspeed = MSG_ReadCoord (); // randomvel
1136 CL_ParticleCube(pos, pos2, dir, count, colorStart, colorLength, velspeed);
1139 case TE_PARTICLERAIN:
1140 // general purpose particle effect
1141 MSG_ReadVector(pos); // mins
1142 MSG_ReadVector(pos2); // maxs
1143 MSG_ReadVector(dir); // dir
1144 count = MSG_ReadShort (); // number of particles
1145 colorStart = MSG_ReadByte (); // color
1146 CL_ParticleRain(pos, pos2, dir, count, colorStart, 0);
1149 case TE_PARTICLESNOW:
1150 // general purpose particle effect
1151 MSG_ReadVector(pos); // mins
1152 MSG_ReadVector(pos2); // maxs
1153 MSG_ReadVector(dir); // dir
1154 count = MSG_ReadShort (); // number of particles
1155 colorStart = MSG_ReadByte (); // color
1156 CL_ParticleRain(pos, pos2, dir, count, colorStart, 1);
1160 // bullet hitting wall
1161 MSG_ReadVector(pos);
1162 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1163 // LordHavoc: changed to dust shower
1164 CL_SparkShower(pos, vec3_origin, 15);
1167 case TE_GUNSHOTQUAD:
1168 // quad bullet hitting wall
1169 MSG_ReadVector(pos);
1170 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1171 CL_SparkShower(pos, vec3_origin, 15);
1172 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1177 MSG_ReadVector(pos);
1178 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1179 CL_ParticleExplosion (pos);
1180 // LordHavoc: boosted color from 1.0, 0.8, 0.4 to 1.25, 1.0, 0.5
1181 CL_AllocDlight (NULL, pos, 350, 1.25f, 1.0f, 0.5f, 700, 0.5);
1182 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1185 case TE_EXPLOSIONQUAD:
1186 // quad rocket explosion
1187 MSG_ReadVector(pos);
1188 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1189 CL_ParticleExplosion (pos);
1190 CL_AllocDlight (NULL, pos, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5);
1191 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1195 // Nehahra movie colored lighting explosion
1196 MSG_ReadVector(pos);
1197 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1198 CL_ParticleExplosion (pos);
1199 CL_AllocDlight (NULL, pos, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5);
1200 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1203 case TE_EXPLOSIONRGB:
1204 // colored lighting explosion
1205 MSG_ReadVector(pos);
1206 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1207 CL_ParticleExplosion (pos);
1208 color[0] = MSG_ReadByte() * (1.0 / 255.0);
1209 color[1] = MSG_ReadByte() * (1.0 / 255.0);
1210 color[2] = MSG_ReadByte() * (1.0 / 255.0);
1211 CL_AllocDlight (NULL, pos, 350, color[0], color[1], color[2], 700, 0.5);
1212 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1215 case TE_TAREXPLOSION:
1216 // tarbaby explosion
1217 MSG_ReadVector(pos);
1218 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1219 CL_BlobExplosion (pos);
1221 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1222 CL_AllocDlight (NULL, pos, 600, 0.8f, 0.4f, 1.0f, 1200, 0.5);
1223 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1227 MSG_ReadVector(pos);
1228 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1229 CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
1232 case TE_CUSTOMFLASH:
1233 MSG_ReadVector(pos);
1234 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1235 radius = MSG_ReadByte() * 8;
1236 velspeed = (MSG_ReadByte() + 1) * (1.0 / 256.0);
1237 color[0] = MSG_ReadByte() * (1.0 / 255.0);
1238 color[1] = MSG_ReadByte() * (1.0 / 255.0);
1239 color[2] = MSG_ReadByte() * (1.0 / 255.0);
1240 CL_AllocDlight (NULL, pos, radius, color[0], color[1], color[2], radius / velspeed, velspeed);
1244 MSG_ReadVector(pos);
1245 MSG_ReadVector(dir);
1246 count = MSG_ReadByte();
1247 CL_Flames(pos, dir, count);
1253 cl_model_bolt = Mod_ForName("progs/bolt.mdl", true, false, false);
1254 CL_ParseBeam (cl_model_bolt);
1259 if (!cl_model_bolt2)
1260 cl_model_bolt2 = Mod_ForName("progs/bolt2.mdl", true, false, false);
1261 CL_ParseBeam (cl_model_bolt2);
1266 if (!cl_model_bolt3)
1267 cl_model_bolt3 = Mod_ForName("progs/bolt3.mdl", true, false, false);
1268 CL_ParseBeam (cl_model_bolt3);
1273 // grappling hook beam
1275 cl_model_beam = Mod_ForName("progs/beam.mdl", true, false, false);
1276 CL_ParseBeam (cl_model_beam);
1280 // LordHavoc: for compatibility with the Nehahra movie...
1281 case TE_LIGHTNING4NEH:
1282 CL_ParseBeam (Mod_ForName(MSG_ReadString(), true, false, false));
1286 pos[0] = MSG_ReadCoord ();
1287 pos[1] = MSG_ReadCoord ();
1288 pos[2] = MSG_ReadCoord ();
1289 CL_LavaSplash (pos);
1293 pos[0] = MSG_ReadCoord ();
1294 pos[1] = MSG_ReadCoord ();
1295 pos[2] = MSG_ReadCoord ();
1296 CL_AllocDlight (NULL, pos, 1000, 1.25f, 1.25f, 1.25f, 3000, 99.0f);
1297 // CL_TeleportSplash (pos);
1301 // color mapped explosion
1302 MSG_ReadVector(pos);
1303 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1304 colorStart = MSG_ReadByte ();
1305 colorLength = MSG_ReadByte ();
1306 CL_ParticleExplosion2 (pos, colorStart, colorLength);
1307 tempcolor = (qbyte *)&d_8to24table[(rand()%colorLength) + colorStart];
1308 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);
1309 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1313 Host_Error ("CL_ParseTempEntity: bad type %d", type);
1317 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
1319 static qbyte cgamenetbuffer[65536];
1322 =====================
1323 CL_ParseServerMessage
1324 =====================
1326 void CL_ParseServerMessage (void)
1329 int i, entitiesupdated;
1331 char *cmdlogname[32], *temp;
1332 int cmdindex, cmdcount = 0;
1335 // if recording demos, copy the message out
1337 if (cl_shownet.integer == 1)
1338 Con_Printf ("%i ",net_message.cursize);
1339 else if (cl_shownet.integer == 2)
1340 Con_Printf ("------------------\n");
1342 cl.onground = false; // unless the server says otherwise
1344 // parse the message
1346 MSG_BeginReading ();
1348 entitiesupdated = false;
1353 Host_Error ("CL_ParseServerMessage: Bad server message");
1355 cmd = MSG_ReadByte ();
1359 SHOWNET("END OF MESSAGE");
1360 break; // end of message
1363 cmdindex = cmdcount & 31;
1365 cmdlog[cmdindex] = cmd;
1367 // if the high bit of the command byte is set, it is a fast update
1370 // 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)
1372 cmdlogname[cmdindex] = temp;
1373 SHOWNET("fast update");
1374 if (cls.signon == SIGNONS - 1)
1376 // first update is the final signon stage
1377 cls.signon = SIGNONS;
1380 CL_ParseUpdate (cmd&127);
1384 SHOWNET(svc_strings[cmd]);
1385 cmdlogname[cmdindex] = svc_strings[cmd];
1386 if (!cmdlogname[cmdindex])
1388 // 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)
1390 cmdlogname[cmdindex] = temp;
1398 char description[32*64], temp[64];
1400 strcpy(description, "packet dump: ");
1404 count = cmdcount - i;
1408 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
1409 strcat(description, temp);
1414 description[strlen(description)-1] = '\n'; // replace the last space with a newline
1415 Con_Printf("%s", description);
1416 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
1424 if (!entitiesupdated)
1426 // this is a new frame, we'll be seeing entities,
1427 // so prepare for entity updates
1428 CL_EntityUpdateSetup();
1429 entitiesupdated = true;
1431 cl.mtime[1] = cl.mtime[0];
1432 cl.mtime[0] = MSG_ReadFloat ();
1435 case svc_clientdata:
1436 i = MSG_ReadShort ();
1437 CL_ParseClientdata (i);
1441 i = MSG_ReadLong ();
1442 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
1443 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
1444 Nehahrademcompatibility = false;
1446 Nehahrademcompatibility = true;
1447 if (cls.demoplayback && demo_nehahra.integer)
1448 Nehahrademcompatibility = true;
1450 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
1454 case svc_disconnect:
1455 Host_EndGame ("Server disconnected\n");
1458 Con_Printf ("%s", MSG_ReadString ());
1461 case svc_centerprint:
1462 SCR_CenterPrint (MSG_ReadString ());
1466 Cbuf_AddText (MSG_ReadString ());
1473 case svc_serverinfo:
1474 CL_ParseServerInfo ();
1478 for (i=0 ; i<3 ; i++)
1479 cl.viewangles[i] = MSG_ReadAngle ();
1483 cl.viewentity = MSG_ReadShort ();
1484 // LordHavoc: assume first setview recieved is the real player entity
1485 if (!cl.playerentity)
1486 cl.playerentity = cl.viewentity;
1489 case svc_lightstyle:
1490 i = MSG_ReadByte ();
1491 if (i >= MAX_LIGHTSTYLES)
1492 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1493 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1494 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1495 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1499 CL_ParseStartSoundPacket(false);
1503 CL_ParseStartSoundPacket(true);
1507 i = MSG_ReadShort();
1508 S_StopSound(i>>3, i&7);
1511 case svc_updatename:
1512 i = MSG_ReadByte ();
1513 if (i >= cl.maxclients)
1514 Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
1515 strcpy (cl.scores[i].name, MSG_ReadString ());
1518 case svc_updatefrags:
1519 i = MSG_ReadByte ();
1520 if (i >= cl.maxclients)
1521 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
1522 cl.scores[i].frags = MSG_ReadShort ();
1525 case svc_updatecolors:
1526 i = MSG_ReadByte ();
1527 if (i >= cl.maxclients)
1528 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
1529 cl.scores[i].colors = MSG_ReadByte ();
1530 // update our color cvar if our color changed
1531 if (i == cl.playerentity - 1)
1532 Cvar_SetValue ("_cl_color", cl.scores[i].colors);
1536 CL_ParseParticleEffect ();
1547 case svc_spawnbaseline:
1548 i = MSG_ReadShort ();
1549 if (i < 0 || i >= MAX_EDICTS)
1550 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
1551 CL_ParseBaseline (cl_entities + i, false);
1553 case svc_spawnbaseline2:
1554 i = MSG_ReadShort ();
1555 if (i < 0 || i >= MAX_EDICTS)
1556 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline2: invalid entity number %i", i);
1557 CL_ParseBaseline (cl_entities + i, true);
1559 case svc_spawnstatic:
1560 CL_ParseStatic (false);
1562 case svc_spawnstatic2:
1563 CL_ParseStatic (true);
1565 case svc_temp_entity:
1566 CL_ParseTempEntity ();
1570 cl.paused = MSG_ReadByte ();
1578 i = MSG_ReadByte ();
1579 if (i <= cls.signon)
1580 Host_Error ("Received signon %i when at %i", i, cls.signon);
1585 case svc_killedmonster:
1586 cl.stats[STAT_MONSTERS]++;
1589 case svc_foundsecret:
1590 cl.stats[STAT_SECRETS]++;
1593 case svc_updatestat:
1594 i = MSG_ReadByte ();
1595 if (i < 0 || i >= MAX_CL_STATS)
1596 Host_Error ("svc_updatestat: %i is invalid", i);
1597 cl.stats[i] = MSG_ReadLong ();
1600 case svc_spawnstaticsound:
1601 CL_ParseStaticSound (false);
1604 case svc_spawnstaticsound2:
1605 CL_ParseStaticSound (true);
1609 cl.cdtrack = MSG_ReadByte ();
1610 cl.looptrack = MSG_ReadByte ();
1611 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1612 CDAudio_Play ((qbyte)cls.forcetrack, true);
1614 CDAudio_Play ((qbyte)cl.cdtrack, true);
1617 case svc_intermission:
1618 cl.intermission = 1;
1619 cl.completed_time = cl.time;
1623 cl.intermission = 2;
1624 cl.completed_time = cl.time;
1625 SCR_CenterPrint (MSG_ReadString ());
1629 cl.intermission = 3;
1630 cl.completed_time = cl.time;
1631 SCR_CenterPrint (MSG_ReadString ());
1634 case svc_sellscreen:
1635 Cmd_ExecuteString ("help", src_command);
1638 SHOWLMP_decodehide();
1641 SHOWLMP_decodeshow();
1644 R_SetSkyBox(MSG_ReadString());
1649 length = (int) ((unsigned short) MSG_ReadShort());
1650 for (i = 0;i < length;i++)
1651 cgamenetbuffer[i] = MSG_ReadByte();
1653 CL_CGVM_ParseNetwork(cgamenetbuffer, length);
1657 if (cls.signon == SIGNONS - 1)
1659 // first update is the final signon stage
1660 cls.signon = SIGNONS;
1663 CL_ReadEntityFrame();
1668 if (entitiesupdated)
1669 CL_EntityUpdateEnd();
1672 void CL_Parse_Init(void)
1674 // LordHavoc: added demo_nehahra cvar
1675 Cvar_RegisterVariable (&demo_nehahra);
1676 if (gamemode == GAME_NEHAHRA)
1677 Cvar_SetValue("demo_nehahra", 1);