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 // FIXME: this is a lot of memory to be keeping around, this needs to be dynamically allocated and freed
324 static char parse_model_precache[MAX_MODELS][MAX_QPATH];
325 static char parse_sound_precache[MAX_SOUNDS][MAX_QPATH];
326 void CL_ParseServerInfo (void)
330 int nummodels, numsounds;
333 Con_DPrintf ("Serverinfo packet received.\n");
335 // wipe the client_state_t struct
339 // parse protocol version number
341 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
343 Host_Error ("Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
346 Nehahrademcompatibility = false;
348 Nehahrademcompatibility = true;
349 if (cls.demoplayback && demo_nehahra.integer)
350 Nehahrademcompatibility = true;
352 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
356 cl.maxclients = MSG_ReadByte ();
357 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
359 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
362 cl.scores = Mem_Alloc(cl_scores_mempool, cl.maxclients*sizeof(*cl.scores));
365 cl.gametype = MSG_ReadByte ();
367 // parse signon message
368 str = MSG_ReadString ();
369 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
371 // seperate the printfs so the server message can have a color
372 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
374 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");
375 Con_Printf ("%c%s\n", 2, str);
378 // check memory integrity
379 Mem_CheckSentinelsGlobal();
381 // disable until we get textures for it
384 memset (cl.model_precache, 0, sizeof(cl.model_precache));
385 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
387 // touch all of the precached models that are still loaded so we can free
388 // anything that isn't needed
390 for (nummodels=1 ; ; nummodels++)
392 CL_KeepaliveMessage ();
393 str = MSG_ReadString ();
396 if (nummodels==MAX_MODELS)
397 Host_Error ("Server sent too many model precaches\n");
398 if (strlen(str) >= MAX_QPATH)
399 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
400 strcpy (parse_model_precache[nummodels], str);
401 Mod_TouchModel (str);
404 // do the same for sounds
405 for (numsounds=1 ; ; numsounds++)
407 CL_KeepaliveMessage ();
408 str = MSG_ReadString ();
411 if (numsounds==MAX_SOUNDS)
412 Host_Error ("Server sent too many sound precaches\n");
413 if (strlen(str) >= MAX_QPATH)
414 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
415 strcpy (parse_sound_precache[numsounds], str);
419 // purge anything that was not touched
422 // now we try to load everything that is new
425 CL_KeepaliveMessage ();
426 cl.model_precache[1] = Mod_ForName (parse_model_precache[1], false, false, true);
427 if (cl.model_precache[1] == NULL)
428 Con_Printf("Map %s not found\n", parse_model_precache[1]);
431 for (i=2 ; i<nummodels ; i++)
433 CL_KeepaliveMessage ();
434 if ((cl.model_precache[i] = Mod_ForName (parse_model_precache[i], false, false, false)) == NULL)
435 Con_Printf("Model %s not found\n", parse_model_precache[i]);
439 S_BeginPrecaching ();
440 for (i=1 ; i<numsounds ; i++)
442 CL_KeepaliveMessage ();
443 cl.sound_precache[i] = S_PrecacheSound (parse_sound_precache[i], true);
448 ent = &cl_entities[0];
449 // entire entity array was cleared, so just fill in a few fields
450 ent->state_current.active = true;
451 ent->render.model = cl.worldmodel = cl.model_precache[1];
452 ent->render.scale = 1;
453 ent->render.alpha = 1;
454 CL_BoundingBoxForEntity(&ent->render);
455 // clear entlife array
456 memset(entlife, 0, MAX_EDICTS);
463 // noclip is turned off at start
464 noclip_anglehack = false;
466 // check memory integrity
467 Mem_CheckSentinelsGlobal();
470 void CL_ValidateState(entity_state_t *s)
477 if (s->modelindex >= MAX_MODELS)
478 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
480 // colormap is client index + 1
481 if (s->colormap > cl.maxclients)
482 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
484 model = cl.model_precache[s->modelindex];
485 Mod_CheckLoaded(model);
486 if (model && s->frame >= model->numframes)
488 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
491 if (model && s->skin > 0 && s->skin >= model->numskins)
493 Con_DPrintf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
498 void CL_MoveLerpEntityStates(entity_t *ent)
500 float odelta[3], adelta[3];
501 VectorSubtract(ent->state_current.origin, ent->persistent.neworigin, odelta);
502 VectorSubtract(ent->state_current.angles, ent->persistent.newangles, adelta);
503 if (!ent->state_previous.active || cls.timedemo || DotProduct(odelta, odelta) > 1000*1000 || cl_nolerp.integer)
505 // we definitely shouldn't lerp
506 ent->persistent.lerpdeltatime = 0;
507 ent->persistent.lerpstarttime = cl.mtime[1];
508 VectorCopy(ent->state_current.origin, ent->persistent.oldorigin);
509 VectorCopy(ent->state_current.angles, ent->persistent.oldangles);
510 VectorCopy(ent->state_current.origin, ent->persistent.neworigin);
511 VectorCopy(ent->state_current.angles, ent->persistent.newangles);
513 else// if (ent->state_current.flags & RENDER_STEP)
515 // monster interpolation
516 if (DotProduct(odelta, odelta) + DotProduct(adelta, adelta) > 0.01)
518 ent->persistent.lerpdeltatime = bound(0, cl.mtime[1] - ent->persistent.lerpstarttime, 0.1);
519 ent->persistent.lerpstarttime = cl.mtime[1];
520 VectorCopy(ent->persistent.neworigin, ent->persistent.oldorigin);
521 VectorCopy(ent->persistent.newangles, ent->persistent.oldangles);
522 VectorCopy(ent->state_current.origin, ent->persistent.neworigin);
523 VectorCopy(ent->state_current.angles, ent->persistent.newangles);
530 ent->persistent.lerpstarttime = cl.mtime[1];
531 // no lerp if it's singleplayer
532 //if (sv.active && svs.maxclients == 1 && !ent->state_current.flags & RENDER_STEP)
533 // ent->persistent.lerpdeltatime = 0;
535 ent->persistent.lerpdeltatime = cl.mtime[0] - cl.mtime[1];
536 VectorCopy(ent->persistent.neworigin, ent->persistent.oldorigin);
537 VectorCopy(ent->persistent.newangles, ent->persistent.oldangles);
538 VectorCopy(ent->state_current.origin, ent->persistent.neworigin);
539 VectorCopy(ent->state_current.angles, ent->persistent.newangles);
548 Parse an entity update message from the server
549 If an entities model or origin changes from frame to frame, it must be
550 relinked. Other attributes can change without relinking.
553 void CL_ParseUpdate (int bits)
559 if (bits & U_MOREBITS)
560 bits |= (MSG_ReadByte()<<8);
561 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
563 bits |= MSG_ReadByte() << 16;
564 if (bits & U_EXTEND2)
565 bits |= MSG_ReadByte() << 24;
568 if (bits & U_LONGENTITY)
569 num = (unsigned) MSG_ReadShort ();
571 num = (unsigned) MSG_ReadByte ();
573 if (num >= MAX_EDICTS)
574 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
576 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
578 ent = cl_entities + num;
580 // note: this inherits the 'active' state of the baseline chosen
581 // (state_baseline is always active, state_current may not be active if
582 // the entity was missing in the last frame)
584 new = ent->state_current;
587 new = ent->state_baseline;
592 new.time = cl.mtime[0];
594 if (bits & U_MODEL) new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte();
595 if (bits & U_FRAME) new.frame = (new.frame & 0xFF00) | MSG_ReadByte();
596 if (bits & U_COLORMAP) new.colormap = MSG_ReadByte();
597 if (bits & U_SKIN) new.skin = MSG_ReadByte();
598 if (bits & U_EFFECTS) new.effects = (new.effects & 0xFF00) | MSG_ReadByte();
599 if (bits & U_ORIGIN1) new.origin[0] = MSG_ReadCoord();
600 if (bits & U_ANGLE1) new.angles[0] = MSG_ReadAngle();
601 if (bits & U_ORIGIN2) new.origin[1] = MSG_ReadCoord();
602 if (bits & U_ANGLE2) new.angles[1] = MSG_ReadAngle();
603 if (bits & U_ORIGIN3) new.origin[2] = MSG_ReadCoord();
604 if (bits & U_ANGLE3) new.angles[2] = MSG_ReadAngle();
605 if (bits & U_STEP) new.flags |= RENDER_STEP;
606 if (bits & U_ALPHA) new.alpha = MSG_ReadByte();
607 if (bits & U_SCALE) new.scale = MSG_ReadByte();
608 if (bits & U_EFFECTS2) new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8);
609 if (bits & U_GLOWSIZE) new.glowsize = MSG_ReadByte();
610 if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte();
611 // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
612 if (bits & U_COLORMOD) MSG_ReadByte();
613 if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL;
614 if (bits & U_FRAME2) new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8);
615 if (bits & U_MODEL2) new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
616 if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL;
617 if (bits & U_EXTERIORMODEL) new.flags |= RENDER_EXTERIORMODEL;
619 // LordHavoc: to allow playback of the Nehahra movie
620 if (Nehahrademcompatibility && (bits & U_EXTEND1))
622 // LordHavoc: evil format
623 int i = MSG_ReadFloat();
624 int j = MSG_ReadFloat() * 255.0f;
629 new.effects |= EF_FULLBRIGHT;
633 else if (j == 0 || j >= 255)
640 CL_ValidateState(&new);
642 ent->state_previous = ent->state_current;
643 ent->state_current = new;
644 if (ent->state_current.active)
646 CL_MoveLerpEntityStates(ent);
647 cl_entities_active[ent->state_current.number] = true;
648 // mark as visible (no kill this frame)
649 entlife[ent->state_current.number] = 2;
653 void CL_ReadEntityFrame(void)
656 entity_frame_t entityframe;
658 EntityFrame_Read(&cl.entitydatabase);
659 EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
660 for (i = 0;i < entityframe.numentities;i++)
663 ent = &cl_entities[entityframe.entitydata[i].number];
664 ent->state_previous = ent->state_current;
665 ent->state_current = entityframe.entitydata[i];
666 CL_MoveLerpEntityStates(ent);
667 // the entity lives again...
668 entlife[ent->state_current.number] = 2;
669 cl_entities_active[ent->state_current.number] = true;
671 VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
672 VectorCopy(entityframe.eye, cl.viewentoriginnew);
675 void CL_EntityUpdateSetup(void)
679 void CL_EntityUpdateEnd(void)
682 // disable entities that disappeared this frame
683 for (i = 1;i < MAX_EDICTS;i++)
685 // clear only the entities that were active last frame but not this
686 // frame, don't waste time clearing all entities (which would cause
692 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
702 void CL_ParseBaseline (entity_t *ent, int large)
706 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
707 ent->state_baseline.active = true;
710 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
711 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
715 ent->state_baseline.modelindex = MSG_ReadByte ();
716 ent->state_baseline.frame = MSG_ReadByte ();
718 ent->state_baseline.colormap = MSG_ReadByte();
719 ent->state_baseline.skin = MSG_ReadByte();
720 for (i = 0;i < 3;i++)
722 ent->state_baseline.origin[i] = MSG_ReadCoord ();
723 ent->state_baseline.angles[i] = MSG_ReadAngle ();
725 ent->state_baseline.alpha = 255;
726 ent->state_baseline.scale = 16;
727 ent->state_baseline.glowsize = 0;
728 ent->state_baseline.glowcolor = 254;
729 ent->state_previous = ent->state_current = ent->state_baseline;
731 CL_ValidateState(&ent->state_baseline);
739 Server information pertaining to this client only
742 void CL_ParseClientdata (int bits)
747 if (bits & SU_EXTEND1)
748 bits |= (MSG_ReadByte() << 16);
749 if (bits & SU_EXTEND2)
750 bits |= (MSG_ReadByte() << 24);
752 if (bits & SU_VIEWHEIGHT)
753 cl.viewheight = MSG_ReadChar ();
755 cl.viewheight = DEFAULT_VIEWHEIGHT;
757 if (bits & SU_IDEALPITCH)
758 cl.idealpitch = MSG_ReadChar ();
762 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
763 for (i=0 ; i<3 ; i++)
765 if (bits & (SU_PUNCH1<<i) )
768 cl.punchangle[i] = MSG_ReadPreciseAngle();
770 cl.punchangle[i] = MSG_ReadChar();
773 cl.punchangle[i] = 0;
774 if (bits & (SU_PUNCHVEC1<<i))
775 cl.punchvector[i] = MSG_ReadCoord();
777 cl.punchvector[i] = 0;
778 if (bits & (SU_VELOCITY1<<i) )
779 cl.mvelocity[0][i] = MSG_ReadChar()*16;
781 cl.mvelocity[0][i] = 0;
787 for (j=0 ; j<32 ; j++)
788 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
789 cl.item_gettime[j] = cl.time;
793 cl.onground = (bits & SU_ONGROUND) != 0;
794 cl.inwater = (bits & SU_INWATER) != 0;
796 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
797 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
798 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
799 cl.stats[STAT_HEALTH] = MSG_ReadShort();
800 cl.stats[STAT_AMMO] = MSG_ReadByte();
802 cl.stats[STAT_SHELLS] = MSG_ReadByte();
803 cl.stats[STAT_NAILS] = MSG_ReadByte();
804 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
805 cl.stats[STAT_CELLS] = MSG_ReadByte();
809 if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
810 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
812 cl.stats[STAT_ACTIVEWEAPON] = i;
814 cl.viewzoomold = cl.viewzoomnew; // for interpolation
815 if (bits & SU_VIEWZOOM)
820 cl.viewzoomnew = (float) i * (1.0f / 255.0f);
828 =====================
830 =====================
832 void CL_ParseStatic (int large)
836 if (cl_num_static_entities >= cl_max_static_entities)
837 Host_Error ("Too many static entities");
838 ent = &cl_static_entities[cl_num_static_entities++];
839 CL_ParseBaseline (ent, large);
841 // copy it to the current state
842 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
843 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
844 ent->render.framelerp = 0;
845 // make torchs play out of sync
846 ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1);
847 ent->render.colormap = -1; // no special coloring
848 ent->render.skinnum = ent->state_baseline.skin;
849 ent->render.effects = ent->state_baseline.effects;
850 ent->render.alpha = 1;
851 ent->render.scale = 1;
852 ent->render.alpha = 1;
854 VectorCopy (ent->state_baseline.origin, ent->render.origin);
855 VectorCopy (ent->state_baseline.angles, ent->render.angles);
857 CL_BoundingBoxForEntity(&ent->render);
859 // This is definitely cheating...
860 if (ent->render.model == NULL)
861 cl_num_static_entities--;
869 void CL_ParseStaticSound (int large)
872 int sound_num, vol, atten;
876 sound_num = (unsigned short) MSG_ReadShort ();
878 sound_num = MSG_ReadByte ();
879 vol = MSG_ReadByte ();
880 atten = MSG_ReadByte ();
882 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
885 void CL_ParseEffect (void)
888 int modelindex, startframe, framecount, framerate;
891 modelindex = MSG_ReadByte ();
892 startframe = MSG_ReadByte ();
893 framecount = MSG_ReadByte ();
894 framerate = MSG_ReadByte ();
896 CL_Effect(org, modelindex, startframe, framecount, framerate);
899 void CL_ParseEffect2 (void)
902 int modelindex, startframe, framecount, framerate;
905 modelindex = MSG_ReadShort ();
906 startframe = MSG_ReadShort ();
907 framecount = MSG_ReadByte ();
908 framerate = MSG_ReadByte ();
910 CL_Effect(org, modelindex, startframe, framecount, framerate);
913 model_t *cl_model_bolt = NULL;
914 model_t *cl_model_bolt2 = NULL;
915 model_t *cl_model_bolt3 = NULL;
916 model_t *cl_model_beam = NULL;
918 sfx_t *cl_sfx_wizhit;
919 sfx_t *cl_sfx_knighthit;
924 sfx_t *cl_sfx_r_exp3;
931 void CL_InitTEnts (void)
933 cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav", false);
934 cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav", false);
935 cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav", false);
936 cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav", false);
937 cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav", false);
938 cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav", false);
939 cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav", false);
942 void CL_ParseBeam (model_t *m, int lightning)
948 ent = MSG_ReadShort ();
949 MSG_ReadVector(start);
952 if (ent >= MAX_EDICTS)
954 Con_Printf("CL_ParseBeam: invalid entity number %i\n", ent);
958 // override any beam with the same entity
959 for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
961 if (b->entity == ent)
964 b->lightning = lightning;
965 b->relativestartvalid = (ent && cl_entities[ent].state_current.active) ? 2 : 0;
967 b->endtime = cl.time + 0.2;
968 VectorCopy (start, b->start);
969 VectorCopy (end, b->end);
975 for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
977 if (!b->model || b->endtime < cl.time)
980 b->lightning = lightning;
981 b->relativestartvalid = (ent && cl_entities[ent].state_current.active) ? 2 : 0;
983 b->endtime = cl.time + 0.2;
984 VectorCopy (start, b->start);
985 VectorCopy (end, b->end);
989 Con_Printf ("beam list overflow!\n");
992 void CL_ParseTempEntity (void)
1000 int colorStart, colorLength, count;
1001 float velspeed, radius;
1004 type = MSG_ReadByte ();
1008 // spike hitting wall
1009 MSG_ReadVector(pos);
1010 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1011 CL_RunParticleEffect (pos, vec3_origin, 20, 30);
1012 S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
1015 case TE_KNIGHTSPIKE:
1016 // spike hitting wall
1017 MSG_ReadVector(pos);
1018 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1019 CL_RunParticleEffect (pos, vec3_origin, 226, 20);
1020 S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
1024 // spike hitting wall
1025 MSG_ReadVector(pos);
1026 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1027 // LordHavoc: changed to spark shower
1028 CL_SparkShower(pos, vec3_origin, 15);
1030 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1035 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1037 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1039 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1043 // quad spike hitting wall
1044 MSG_ReadVector(pos);
1045 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1046 // LordHavoc: changed to spark shower
1047 CL_SparkShower(pos, vec3_origin, 15);
1048 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1049 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1051 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1056 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1058 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1060 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1064 // super spike hitting wall
1065 MSG_ReadVector(pos);
1066 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1067 // LordHavoc: changed to dust shower
1068 CL_SparkShower(pos, vec3_origin, 30);
1070 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1075 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1077 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1079 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1082 case TE_SUPERSPIKEQUAD:
1083 // quad super spike hitting wall
1084 MSG_ReadVector(pos);
1085 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1086 // LordHavoc: changed to dust shower
1087 CL_SparkShower(pos, vec3_origin, 30);
1088 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1090 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1095 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1097 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1099 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1102 // LordHavoc: added for improved blood splatters
1105 MSG_ReadVector(pos);
1106 dir[0] = MSG_ReadChar ();
1107 dir[1] = MSG_ReadChar ();
1108 dir[2] = MSG_ReadChar ();
1109 count = MSG_ReadByte ();
1110 CL_BloodPuff(pos, dir, count);
1114 MSG_ReadVector(pos);
1115 CL_BloodPuff(pos, vec3_origin, 10);
1119 MSG_ReadVector(pos);
1120 dir[0] = MSG_ReadChar ();
1121 dir[1] = MSG_ReadChar ();
1122 dir[2] = MSG_ReadChar ();
1123 count = MSG_ReadByte ();
1124 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1125 CL_SparkShower(pos, dir, count);
1128 MSG_ReadVector(pos);
1129 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1130 CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
1133 // LordHavoc: added for improved gore
1134 case TE_BLOODSHOWER:
1136 MSG_ReadVector(pos); // mins
1137 MSG_ReadVector(pos2); // maxs
1138 velspeed = MSG_ReadCoord (); // speed
1139 count = MSG_ReadShort (); // number of particles
1140 CL_BloodShower(pos, pos2, velspeed, count);
1142 case TE_PARTICLECUBE:
1143 // general purpose particle effect
1144 MSG_ReadVector(pos); // mins
1145 MSG_ReadVector(pos2); // maxs
1146 MSG_ReadVector(dir); // dir
1147 count = MSG_ReadShort (); // number of particles
1148 colorStart = MSG_ReadByte (); // color
1149 colorLength = MSG_ReadByte (); // gravity (1 or 0)
1150 velspeed = MSG_ReadCoord (); // randomvel
1151 CL_ParticleCube(pos, pos2, dir, count, colorStart, colorLength, velspeed);
1154 case TE_PARTICLERAIN:
1155 // general purpose particle effect
1156 MSG_ReadVector(pos); // mins
1157 MSG_ReadVector(pos2); // maxs
1158 MSG_ReadVector(dir); // dir
1159 count = MSG_ReadShort (); // number of particles
1160 colorStart = MSG_ReadByte (); // color
1161 CL_ParticleRain(pos, pos2, dir, count, colorStart, 0);
1164 case TE_PARTICLESNOW:
1165 // general purpose particle effect
1166 MSG_ReadVector(pos); // mins
1167 MSG_ReadVector(pos2); // maxs
1168 MSG_ReadVector(dir); // dir
1169 count = MSG_ReadShort (); // number of particles
1170 colorStart = MSG_ReadByte (); // color
1171 CL_ParticleRain(pos, pos2, dir, count, colorStart, 1);
1175 // bullet hitting wall
1176 MSG_ReadVector(pos);
1177 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1178 // LordHavoc: changed to dust shower
1179 CL_SparkShower(pos, vec3_origin, 15);
1182 case TE_GUNSHOTQUAD:
1183 // quad bullet hitting wall
1184 MSG_ReadVector(pos);
1185 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1186 CL_SparkShower(pos, vec3_origin, 15);
1187 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1192 MSG_ReadVector(pos);
1193 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1194 CL_ParticleExplosion (pos);
1195 // LordHavoc: boosted color from 1.0, 0.8, 0.4 to 1.25, 1.0, 0.5
1196 CL_AllocDlight (NULL, pos, 350, 1.25f, 1.0f, 0.5f, 700, 0.5);
1197 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1200 case TE_EXPLOSIONQUAD:
1201 // quad rocket explosion
1202 MSG_ReadVector(pos);
1203 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1204 CL_ParticleExplosion (pos);
1205 CL_AllocDlight (NULL, pos, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5);
1206 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1210 // Nehahra movie colored lighting explosion
1211 MSG_ReadVector(pos);
1212 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1213 CL_ParticleExplosion (pos);
1214 CL_AllocDlight (NULL, pos, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5);
1215 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1218 case TE_EXPLOSIONRGB:
1219 // colored lighting explosion
1220 MSG_ReadVector(pos);
1221 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1222 CL_ParticleExplosion (pos);
1223 color[0] = MSG_ReadByte() * (1.0 / 255.0);
1224 color[1] = MSG_ReadByte() * (1.0 / 255.0);
1225 color[2] = MSG_ReadByte() * (1.0 / 255.0);
1226 CL_AllocDlight (NULL, pos, 350, color[0], color[1], color[2], 700, 0.5);
1227 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1230 case TE_TAREXPLOSION:
1231 // tarbaby explosion
1232 MSG_ReadVector(pos);
1233 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1234 CL_BlobExplosion (pos);
1236 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1237 CL_AllocDlight (NULL, pos, 600, 0.8f, 0.4f, 1.0f, 1200, 0.5);
1238 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1242 MSG_ReadVector(pos);
1243 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1244 CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
1247 case TE_CUSTOMFLASH:
1248 MSG_ReadVector(pos);
1249 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1250 radius = MSG_ReadByte() * 8;
1251 velspeed = (MSG_ReadByte() + 1) * (1.0 / 256.0);
1252 color[0] = MSG_ReadByte() * (1.0 / 255.0);
1253 color[1] = MSG_ReadByte() * (1.0 / 255.0);
1254 color[2] = MSG_ReadByte() * (1.0 / 255.0);
1255 CL_AllocDlight (NULL, pos, radius, color[0], color[1], color[2], radius / velspeed, velspeed);
1259 MSG_ReadVector(pos);
1260 MSG_ReadVector(dir);
1261 count = MSG_ReadByte();
1262 CL_Flames(pos, dir, count);
1268 cl_model_bolt = Mod_ForName("progs/bolt.mdl", true, false, false);
1269 CL_ParseBeam (cl_model_bolt, true);
1274 if (!cl_model_bolt2)
1275 cl_model_bolt2 = Mod_ForName("progs/bolt2.mdl", true, false, false);
1276 CL_ParseBeam (cl_model_bolt2, true);
1281 if (!cl_model_bolt3)
1282 cl_model_bolt3 = Mod_ForName("progs/bolt3.mdl", true, false, false);
1283 CL_ParseBeam (cl_model_bolt3, true);
1288 // grappling hook beam
1290 cl_model_beam = Mod_ForName("progs/beam.mdl", true, false, false);
1291 CL_ParseBeam (cl_model_beam, false);
1295 // LordHavoc: for compatibility with the Nehahra movie...
1296 case TE_LIGHTNING4NEH:
1297 CL_ParseBeam (Mod_ForName(MSG_ReadString(), true, false, false), false);
1301 pos[0] = MSG_ReadCoord ();
1302 pos[1] = MSG_ReadCoord ();
1303 pos[2] = MSG_ReadCoord ();
1304 CL_LavaSplash (pos);
1308 pos[0] = MSG_ReadCoord ();
1309 pos[1] = MSG_ReadCoord ();
1310 pos[2] = MSG_ReadCoord ();
1311 CL_AllocDlight (NULL, pos, 500, 1.0f, 1.0f, 1.0f, 1500, 99.0f);
1312 // CL_TeleportSplash (pos);
1316 // color mapped explosion
1317 MSG_ReadVector(pos);
1318 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1319 colorStart = MSG_ReadByte ();
1320 colorLength = MSG_ReadByte ();
1321 CL_ParticleExplosion2 (pos, colorStart, colorLength);
1322 tempcolor = (qbyte *)&palette_complete[(rand()%colorLength) + colorStart];
1323 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);
1324 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1328 MSG_ReadVector(pos);
1329 MSG_ReadVector(pos2);
1330 MSG_ReadVector(dir);
1331 CL_BeamParticle(pos, pos2, 12, 1, 0.3, 0.1, 1, 1);
1332 CL_BeamParticle(pos, pos2, 5, 1, 0.9, 0.3, 1, 1);
1336 MSG_ReadVector(pos);
1337 MSG_ReadVector(dir);
1338 count = MSG_ReadByte ();
1339 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1340 CL_Tei_Smoke(pos, dir, count);
1343 case TE_TEI_BIGEXPLOSION:
1344 MSG_ReadVector(pos);
1345 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1346 CL_ParticleExplosion (pos);
1347 CL_AllocDlight (NULL, pos, 500, 1.25f, 1.0f, 0.5f, 500, 9999);
1348 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1351 case TE_TEI_PLASMAHIT:
1352 MSG_ReadVector(pos);
1353 MSG_ReadVector(dir);
1354 count = MSG_ReadByte ();
1355 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1356 CL_Tei_PlasmaHit(pos, dir, count);
1357 CL_AllocDlight (NULL, pos, 500, 0.3, 0.6, 1.0f, 2000, 9999);
1361 Host_Error ("CL_ParseTempEntity: bad type %d (hex %02X)", type, type);
1365 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
1367 static qbyte cgamenetbuffer[65536];
1370 =====================
1371 CL_ParseServerMessage
1372 =====================
1374 int parsingerror = false;
1375 void CL_ParseServerMessage (void)
1378 int i, entitiesupdated;
1380 char *cmdlogname[32], *temp;
1381 int cmdindex, cmdcount = 0;
1384 // if recording demos, copy the message out
1386 if (cl_shownet.integer == 1)
1387 Con_Printf ("%i ",net_message.cursize);
1388 else if (cl_shownet.integer == 2)
1389 Con_Printf ("------------------\n");
1391 cl.onground = false; // unless the server says otherwise
1393 // parse the message
1395 MSG_BeginReading ();
1397 entitiesupdated = false;
1399 parsingerror = true;
1404 Host_Error ("CL_ParseServerMessage: Bad server message");
1406 cmd = MSG_ReadByte ();
1410 SHOWNET("END OF MESSAGE");
1411 break; // end of message
1414 cmdindex = cmdcount & 31;
1416 cmdlog[cmdindex] = cmd;
1418 // if the high bit of the command byte is set, it is a fast update
1421 // 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)
1423 cmdlogname[cmdindex] = temp;
1424 SHOWNET("fast update");
1425 if (cls.signon == SIGNONS - 1)
1427 // first update is the final signon stage
1428 cls.signon = SIGNONS;
1431 CL_ParseUpdate (cmd&127);
1435 SHOWNET(svc_strings[cmd]);
1436 cmdlogname[cmdindex] = svc_strings[cmd];
1437 if (!cmdlogname[cmdindex])
1439 // 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)
1441 cmdlogname[cmdindex] = temp;
1449 char description[32*64], temp[64];
1451 strcpy(description, "packet dump: ");
1455 count = cmdcount - i;
1459 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
1460 strcat(description, temp);
1465 description[strlen(description)-1] = '\n'; // replace the last space with a newline
1466 Con_Printf("%s", description);
1467 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
1475 if (!entitiesupdated)
1477 // this is a new frame, we'll be seeing entities,
1478 // so prepare for entity updates
1479 CL_EntityUpdateSetup();
1480 entitiesupdated = true;
1482 cl.mtime[1] = cl.mtime[0];
1483 cl.mtime[0] = MSG_ReadFloat ();
1486 case svc_clientdata:
1487 i = MSG_ReadShort ();
1488 CL_ParseClientdata (i);
1492 i = MSG_ReadLong ();
1493 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
1494 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
1495 Nehahrademcompatibility = false;
1497 Nehahrademcompatibility = true;
1498 if (cls.demoplayback && demo_nehahra.integer)
1499 Nehahrademcompatibility = true;
1501 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
1505 case svc_disconnect:
1506 Host_EndGame ("Server disconnected\n");
1509 Con_Printf ("%s", MSG_ReadString ());
1512 case svc_centerprint:
1513 SCR_CenterPrint (MSG_ReadString ());
1517 Cbuf_AddText (MSG_ReadString ());
1524 case svc_serverinfo:
1525 CL_ParseServerInfo ();
1529 for (i=0 ; i<3 ; i++)
1530 cl.viewangles[i] = MSG_ReadAngle ();
1534 cl.viewentity = MSG_ReadShort ();
1535 // LordHavoc: assume first setview recieved is the real player entity
1536 if (!cl.playerentity)
1537 cl.playerentity = cl.viewentity;
1540 case svc_lightstyle:
1541 i = MSG_ReadByte ();
1542 if (i >= MAX_LIGHTSTYLES)
1543 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1544 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1545 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1546 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1550 CL_ParseStartSoundPacket(false);
1554 CL_ParseStartSoundPacket(true);
1558 i = MSG_ReadShort();
1559 S_StopSound(i>>3, i&7);
1562 case svc_updatename:
1563 i = MSG_ReadByte ();
1564 if (i >= cl.maxclients)
1565 Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
1566 strcpy (cl.scores[i].name, MSG_ReadString ());
1569 case svc_updatefrags:
1570 i = MSG_ReadByte ();
1571 if (i >= cl.maxclients)
1572 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
1573 cl.scores[i].frags = MSG_ReadShort ();
1576 case svc_updatecolors:
1577 i = MSG_ReadByte ();
1578 if (i >= cl.maxclients)
1579 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
1580 cl.scores[i].colors = MSG_ReadByte ();
1581 // update our color cvar if our color changed
1582 if (i == cl.playerentity - 1)
1583 Cvar_SetValue ("_cl_color", cl.scores[i].colors);
1587 CL_ParseParticleEffect ();
1598 case svc_spawnbaseline:
1599 i = MSG_ReadShort ();
1600 if (i < 0 || i >= MAX_EDICTS)
1601 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
1602 CL_ParseBaseline (cl_entities + i, false);
1604 case svc_spawnbaseline2:
1605 i = MSG_ReadShort ();
1606 if (i < 0 || i >= MAX_EDICTS)
1607 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline2: invalid entity number %i", i);
1608 CL_ParseBaseline (cl_entities + i, true);
1610 case svc_spawnstatic:
1611 CL_ParseStatic (false);
1613 case svc_spawnstatic2:
1614 CL_ParseStatic (true);
1616 case svc_temp_entity:
1617 CL_ParseTempEntity ();
1621 cl.paused = MSG_ReadByte ();
1629 i = MSG_ReadByte ();
1630 if (i <= cls.signon)
1631 Host_Error ("Received signon %i when at %i", i, cls.signon);
1636 case svc_killedmonster:
1637 cl.stats[STAT_MONSTERS]++;
1640 case svc_foundsecret:
1641 cl.stats[STAT_SECRETS]++;
1644 case svc_updatestat:
1645 i = MSG_ReadByte ();
1646 if (i < 0 || i >= MAX_CL_STATS)
1647 Host_Error ("svc_updatestat: %i is invalid", i);
1648 cl.stats[i] = MSG_ReadLong ();
1651 case svc_spawnstaticsound:
1652 CL_ParseStaticSound (false);
1655 case svc_spawnstaticsound2:
1656 CL_ParseStaticSound (true);
1660 cl.cdtrack = MSG_ReadByte ();
1661 cl.looptrack = MSG_ReadByte ();
1662 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1663 CDAudio_Play ((qbyte)cls.forcetrack, true);
1665 CDAudio_Play ((qbyte)cl.cdtrack, true);
1668 case svc_intermission:
1669 cl.intermission = 1;
1670 cl.completed_time = cl.time;
1674 cl.intermission = 2;
1675 cl.completed_time = cl.time;
1676 SCR_CenterPrint (MSG_ReadString ());
1680 cl.intermission = 3;
1681 cl.completed_time = cl.time;
1682 SCR_CenterPrint (MSG_ReadString ());
1685 case svc_sellscreen:
1686 Cmd_ExecuteString ("help", src_command);
1689 SHOWLMP_decodehide();
1692 SHOWLMP_decodeshow();
1695 R_SetSkyBox(MSG_ReadString());
1700 length = (int) ((unsigned short) MSG_ReadShort());
1701 for (i = 0;i < length;i++)
1702 cgamenetbuffer[i] = MSG_ReadByte();
1704 CL_CGVM_ParseNetwork(cgamenetbuffer, length);
1708 if (cls.signon == SIGNONS - 1)
1710 // first update is the final signon stage
1711 cls.signon = SIGNONS;
1714 CL_ReadEntityFrame();
1719 if (entitiesupdated)
1720 CL_EntityUpdateEnd();
1722 parsingerror = false;
1725 void CL_Parse_DumpPacket(void)
1729 Con_Printf("Packet dump:\n");
1730 SZ_HexDumpToConsole(&net_message);
1731 parsingerror = false;
1734 void CL_Parse_Init(void)
1736 // LordHavoc: added demo_nehahra cvar
1737 Cvar_RegisterVariable (&demo_nehahra);
1738 if (gamemode == GAME_NEHAHRA)
1739 Cvar_SetValue("demo_nehahra", 1);