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);
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);
546 Parse an entity update message from the server
547 If an entities model or origin changes from frame to frame, it must be
548 relinked. Other attributes can change without relinking.
551 void CL_ParseUpdate (int bits)
557 if (bits & U_MOREBITS)
558 bits |= (MSG_ReadByte()<<8);
559 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
561 bits |= MSG_ReadByte() << 16;
562 if (bits & U_EXTEND2)
563 bits |= MSG_ReadByte() << 24;
566 if (bits & U_LONGENTITY)
567 num = (unsigned) MSG_ReadShort ();
569 num = (unsigned) MSG_ReadByte ();
571 if (num >= MAX_EDICTS)
572 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
574 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
576 ent = cl_entities + num;
578 // note: this inherits the 'active' state of the baseline chosen
579 // (state_baseline is always active, state_current may not be active if
580 // the entity was missing in the last frame)
582 new = ent->state_current;
585 new = ent->state_baseline;
590 new.time = cl.mtime[0];
592 if (bits & U_MODEL) new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte();
593 if (bits & U_FRAME) new.frame = (new.frame & 0xFF00) | MSG_ReadByte();
594 if (bits & U_COLORMAP) new.colormap = MSG_ReadByte();
595 if (bits & U_SKIN) new.skin = MSG_ReadByte();
596 if (bits & U_EFFECTS) new.effects = (new.effects & 0xFF00) | MSG_ReadByte();
597 if (bits & U_ORIGIN1) new.origin[0] = MSG_ReadCoord();
598 if (bits & U_ANGLE1) new.angles[0] = MSG_ReadAngle();
599 if (bits & U_ORIGIN2) new.origin[1] = MSG_ReadCoord();
600 if (bits & U_ANGLE2) new.angles[1] = MSG_ReadAngle();
601 if (bits & U_ORIGIN3) new.origin[2] = MSG_ReadCoord();
602 if (bits & U_ANGLE3) new.angles[2] = MSG_ReadAngle();
603 if (bits & U_STEP) new.flags |= RENDER_STEP;
604 if (bits & U_ALPHA) new.alpha = MSG_ReadByte();
605 if (bits & U_SCALE) new.scale = MSG_ReadByte();
606 if (bits & U_EFFECTS2) new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8);
607 if (bits & U_GLOWSIZE) new.glowsize = MSG_ReadByte();
608 if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte();
609 // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
610 if (bits & U_COLORMOD) MSG_ReadByte();
611 if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL;
612 if (bits & U_FRAME2) new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8);
613 if (bits & U_MODEL2) new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
614 if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL;
615 if (bits & U_EXTERIORMODEL) new.flags |= RENDER_EXTERIORMODEL;
617 // LordHavoc: to allow playback of the Nehahra movie
618 if (Nehahrademcompatibility && (bits & U_EXTEND1))
620 // LordHavoc: evil format
621 int i = MSG_ReadFloat();
622 int j = MSG_ReadFloat() * 255.0f;
627 new.effects |= EF_FULLBRIGHT;
631 else if (j == 0 || j >= 255)
638 CL_ValidateState(&new);
640 ent->state_previous = ent->state_current;
641 ent->state_current = new;
642 if (ent->state_current.active)
644 CL_MoveLerpEntityStates(ent);
645 cl_entities_active[ent->state_current.number] = true;
646 // mark as visible (no kill this frame)
647 entlife[ent->state_current.number] = 2;
651 static entity_frame_t entityframe;
652 void CL_ReadEntityFrame(void)
656 EntityFrame_Read(&cl.entitydatabase);
657 EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
658 for (i = 0;i < entityframe.numentities;i++)
661 ent = &cl_entities[entityframe.entitydata[i].number];
662 ent->state_previous = ent->state_current;
663 ent->state_current = entityframe.entitydata[i];
664 CL_MoveLerpEntityStates(ent);
665 // the entity lives again...
666 entlife[ent->state_current.number] = 2;
667 cl_entities_active[ent->state_current.number] = true;
669 VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
670 VectorCopy(entityframe.eye, cl.viewentoriginnew);
673 void CL_EntityUpdateSetup(void)
677 void CL_EntityUpdateEnd(void)
680 // disable entities that disappeared this frame
681 for (i = 1;i < MAX_EDICTS;i++)
683 // clear only the entities that were active last frame but not this
684 // frame, don't waste time clearing all entities (which would cause
690 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
700 void CL_ParseBaseline (entity_t *ent, int large)
704 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
705 ent->state_baseline.active = true;
708 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
709 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
713 ent->state_baseline.modelindex = MSG_ReadByte ();
714 ent->state_baseline.frame = MSG_ReadByte ();
716 ent->state_baseline.colormap = MSG_ReadByte();
717 ent->state_baseline.skin = MSG_ReadByte();
718 for (i = 0;i < 3;i++)
720 ent->state_baseline.origin[i] = MSG_ReadCoord ();
721 ent->state_baseline.angles[i] = MSG_ReadAngle ();
723 ent->state_baseline.alpha = 255;
724 ent->state_baseline.scale = 16;
725 ent->state_baseline.glowsize = 0;
726 ent->state_baseline.glowcolor = 254;
727 ent->state_previous = ent->state_current = ent->state_baseline;
729 CL_ValidateState(&ent->state_baseline);
737 Server information pertaining to this client only
740 void CL_ParseClientdata (int bits)
745 if (bits & SU_EXTEND1)
746 bits |= (MSG_ReadByte() << 16);
747 if (bits & SU_EXTEND2)
748 bits |= (MSG_ReadByte() << 24);
750 if (bits & SU_VIEWHEIGHT)
751 cl.viewheight = MSG_ReadChar ();
753 cl.viewheight = DEFAULT_VIEWHEIGHT;
755 if (bits & SU_IDEALPITCH)
756 cl.idealpitch = MSG_ReadChar ();
760 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
761 for (i=0 ; i<3 ; i++)
763 if (bits & (SU_PUNCH1<<i) )
766 cl.punchangle[i] = MSG_ReadPreciseAngle();
768 cl.punchangle[i] = MSG_ReadChar();
771 cl.punchangle[i] = 0;
772 if (bits & (SU_PUNCHVEC1<<i))
773 cl.punchvector[i] = MSG_ReadCoord();
775 cl.punchvector[i] = 0;
776 if (bits & (SU_VELOCITY1<<i) )
777 cl.mvelocity[0][i] = MSG_ReadChar()*16;
779 cl.mvelocity[0][i] = 0;
785 for (j=0 ; j<32 ; j++)
786 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
787 cl.item_gettime[j] = cl.time;
791 cl.onground = (bits & SU_ONGROUND) != 0;
792 cl.inwater = (bits & SU_INWATER) != 0;
794 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
795 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
796 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
797 cl.stats[STAT_HEALTH] = MSG_ReadShort();
798 cl.stats[STAT_AMMO] = MSG_ReadByte();
800 cl.stats[STAT_SHELLS] = MSG_ReadByte();
801 cl.stats[STAT_NAILS] = MSG_ReadByte();
802 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
803 cl.stats[STAT_CELLS] = MSG_ReadByte();
807 if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
808 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
810 cl.stats[STAT_ACTIVEWEAPON] = i;
812 cl.viewzoomold = cl.viewzoomnew; // for interpolation
813 if (bits & SU_VIEWZOOM)
818 cl.viewzoomnew = (float) i * (1.0f / 255.0f);
826 =====================
828 =====================
830 void CL_ParseStatic (int large)
834 if (cl_num_static_entities >= cl_max_static_entities)
835 Host_Error ("Too many static entities");
836 ent = &cl_static_entities[cl_num_static_entities++];
837 CL_ParseBaseline (ent, large);
839 // copy it to the current state
840 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
841 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
842 ent->render.framelerp = 0;
843 // make torchs play out of sync
844 ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1);
845 ent->render.colormap = -1; // no special coloring
846 ent->render.skinnum = ent->state_baseline.skin;
847 ent->render.effects = ent->state_baseline.effects;
848 ent->render.alpha = 1;
849 ent->render.scale = 1;
850 ent->render.alpha = 1;
852 VectorCopy (ent->state_baseline.origin, ent->render.origin);
853 VectorCopy (ent->state_baseline.angles, ent->render.angles);
855 CL_BoundingBoxForEntity(&ent->render);
857 // This is definitely cheating...
858 if (ent->render.model == NULL)
859 cl_num_static_entities--;
867 void CL_ParseStaticSound (int large)
870 int sound_num, vol, atten;
874 sound_num = (unsigned short) MSG_ReadShort ();
876 sound_num = MSG_ReadByte ();
877 vol = MSG_ReadByte ();
878 atten = MSG_ReadByte ();
880 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
883 void CL_ParseEffect (void)
886 int modelindex, startframe, framecount, framerate;
889 modelindex = MSG_ReadByte ();
890 startframe = MSG_ReadByte ();
891 framecount = MSG_ReadByte ();
892 framerate = MSG_ReadByte ();
894 CL_Effect(org, modelindex, startframe, framecount, framerate);
897 void CL_ParseEffect2 (void)
900 int modelindex, startframe, framecount, framerate;
903 modelindex = MSG_ReadShort ();
904 startframe = MSG_ReadShort ();
905 framecount = MSG_ReadByte ();
906 framerate = MSG_ReadByte ();
908 CL_Effect(org, modelindex, startframe, framecount, framerate);
911 model_t *cl_model_bolt = NULL;
912 model_t *cl_model_bolt2 = NULL;
913 model_t *cl_model_bolt3 = NULL;
914 model_t *cl_model_beam = NULL;
916 sfx_t *cl_sfx_wizhit;
917 sfx_t *cl_sfx_knighthit;
922 sfx_t *cl_sfx_r_exp3;
929 void CL_InitTEnts (void)
931 cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav", false);
932 cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav", false);
933 cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav", false);
934 cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav", false);
935 cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav", false);
936 cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav", false);
937 cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav", false);
940 void CL_ParseBeam (model_t *m, int lightning)
946 ent = MSG_ReadShort ();
947 MSG_ReadVector(start);
950 if (ent >= MAX_EDICTS)
952 Con_Printf("CL_ParseBeam: invalid entity number %i\n", ent);
956 // override any beam with the same entity
957 for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
959 if (b->entity == ent)
962 b->lightning = lightning;
963 b->relativestartvalid = (ent && cl_entities[ent].state_current.active) ? 2 : 0;
965 b->endtime = cl.time + 0.2;
966 VectorCopy (start, b->start);
967 VectorCopy (end, b->end);
973 for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
975 if (!b->model || b->endtime < cl.time)
978 b->lightning = lightning;
979 b->relativestartvalid = (ent && cl_entities[ent].state_current.active) ? 2 : 0;
981 b->endtime = cl.time + 0.2;
982 VectorCopy (start, b->start);
983 VectorCopy (end, b->end);
987 Con_Printf ("beam list overflow!\n");
990 void CL_ParseTempEntity (void)
998 int colorStart, colorLength, count;
999 float velspeed, radius;
1002 type = MSG_ReadByte ();
1006 // spike hitting wall
1007 MSG_ReadVector(pos);
1008 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1009 CL_RunParticleEffect (pos, vec3_origin, 20, 30);
1010 S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
1013 case TE_KNIGHTSPIKE:
1014 // spike hitting wall
1015 MSG_ReadVector(pos);
1016 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1017 CL_RunParticleEffect (pos, vec3_origin, 226, 20);
1018 S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
1022 // spike hitting wall
1023 MSG_ReadVector(pos);
1024 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1025 // LordHavoc: changed to spark shower
1026 CL_SparkShower(pos, vec3_origin, 15);
1028 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1033 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1035 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1037 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1041 // quad spike hitting wall
1042 MSG_ReadVector(pos);
1043 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1044 // LordHavoc: changed to spark shower
1045 CL_SparkShower(pos, vec3_origin, 15);
1046 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1047 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1049 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1054 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1056 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1058 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1062 // super spike hitting wall
1063 MSG_ReadVector(pos);
1064 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1065 // LordHavoc: changed to dust shower
1066 CL_SparkShower(pos, vec3_origin, 30);
1068 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1073 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1075 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1077 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1080 case TE_SUPERSPIKEQUAD:
1081 // quad super spike hitting wall
1082 MSG_ReadVector(pos);
1083 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1084 // LordHavoc: changed to dust shower
1085 CL_SparkShower(pos, vec3_origin, 30);
1086 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1088 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1093 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1095 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1097 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1100 // LordHavoc: added for improved blood splatters
1103 MSG_ReadVector(pos);
1104 dir[0] = MSG_ReadChar ();
1105 dir[1] = MSG_ReadChar ();
1106 dir[2] = MSG_ReadChar ();
1107 count = MSG_ReadByte ();
1108 CL_BloodPuff(pos, dir, count);
1112 MSG_ReadVector(pos);
1113 CL_BloodPuff(pos, vec3_origin, 10);
1117 MSG_ReadVector(pos);
1118 dir[0] = MSG_ReadChar ();
1119 dir[1] = MSG_ReadChar ();
1120 dir[2] = MSG_ReadChar ();
1121 count = MSG_ReadByte ();
1122 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1123 CL_SparkShower(pos, dir, count);
1126 MSG_ReadVector(pos);
1127 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1128 CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
1131 // LordHavoc: added for improved gore
1132 case TE_BLOODSHOWER:
1134 MSG_ReadVector(pos); // mins
1135 MSG_ReadVector(pos2); // maxs
1136 velspeed = MSG_ReadCoord (); // speed
1137 count = MSG_ReadShort (); // number of particles
1138 CL_BloodShower(pos, pos2, velspeed, count);
1140 case TE_PARTICLECUBE:
1141 // general purpose particle effect
1142 MSG_ReadVector(pos); // mins
1143 MSG_ReadVector(pos2); // maxs
1144 MSG_ReadVector(dir); // dir
1145 count = MSG_ReadShort (); // number of particles
1146 colorStart = MSG_ReadByte (); // color
1147 colorLength = MSG_ReadByte (); // gravity (1 or 0)
1148 velspeed = MSG_ReadCoord (); // randomvel
1149 CL_ParticleCube(pos, pos2, dir, count, colorStart, colorLength, velspeed);
1152 case TE_PARTICLERAIN:
1153 // general purpose particle effect
1154 MSG_ReadVector(pos); // mins
1155 MSG_ReadVector(pos2); // maxs
1156 MSG_ReadVector(dir); // dir
1157 count = MSG_ReadShort (); // number of particles
1158 colorStart = MSG_ReadByte (); // color
1159 CL_ParticleRain(pos, pos2, dir, count, colorStart, 0);
1162 case TE_PARTICLESNOW:
1163 // general purpose particle effect
1164 MSG_ReadVector(pos); // mins
1165 MSG_ReadVector(pos2); // maxs
1166 MSG_ReadVector(dir); // dir
1167 count = MSG_ReadShort (); // number of particles
1168 colorStart = MSG_ReadByte (); // color
1169 CL_ParticleRain(pos, pos2, dir, count, colorStart, 1);
1173 // bullet hitting wall
1174 MSG_ReadVector(pos);
1175 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1176 // LordHavoc: changed to dust shower
1177 CL_SparkShower(pos, vec3_origin, 15);
1180 case TE_GUNSHOTQUAD:
1181 // quad bullet hitting wall
1182 MSG_ReadVector(pos);
1183 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1184 CL_SparkShower(pos, vec3_origin, 15);
1185 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1190 MSG_ReadVector(pos);
1191 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1192 CL_ParticleExplosion (pos);
1193 // LordHavoc: boosted color from 1.0, 0.8, 0.4 to 1.25, 1.0, 0.5
1194 CL_AllocDlight (NULL, pos, 350, 1.25f, 1.0f, 0.5f, 700, 0.5);
1195 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1198 case TE_EXPLOSIONQUAD:
1199 // quad rocket explosion
1200 MSG_ReadVector(pos);
1201 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1202 CL_ParticleExplosion (pos);
1203 CL_AllocDlight (NULL, pos, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5);
1204 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1208 // Nehahra movie colored lighting explosion
1209 MSG_ReadVector(pos);
1210 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1211 CL_ParticleExplosion (pos);
1212 CL_AllocDlight (NULL, pos, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5);
1213 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1216 case TE_EXPLOSIONRGB:
1217 // colored lighting explosion
1218 MSG_ReadVector(pos);
1219 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1220 CL_ParticleExplosion (pos);
1221 color[0] = MSG_ReadByte() * (1.0 / 255.0);
1222 color[1] = MSG_ReadByte() * (1.0 / 255.0);
1223 color[2] = MSG_ReadByte() * (1.0 / 255.0);
1224 CL_AllocDlight (NULL, pos, 350, color[0], color[1], color[2], 700, 0.5);
1225 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1228 case TE_TAREXPLOSION:
1229 // tarbaby explosion
1230 MSG_ReadVector(pos);
1231 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1232 CL_BlobExplosion (pos);
1234 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1235 CL_AllocDlight (NULL, pos, 600, 0.8f, 0.4f, 1.0f, 1200, 0.5);
1236 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1240 MSG_ReadVector(pos);
1241 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1242 CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
1245 case TE_CUSTOMFLASH:
1246 MSG_ReadVector(pos);
1247 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1248 radius = MSG_ReadByte() * 8;
1249 velspeed = (MSG_ReadByte() + 1) * (1.0 / 256.0);
1250 color[0] = MSG_ReadByte() * (1.0 / 255.0);
1251 color[1] = MSG_ReadByte() * (1.0 / 255.0);
1252 color[2] = MSG_ReadByte() * (1.0 / 255.0);
1253 CL_AllocDlight (NULL, pos, radius, color[0], color[1], color[2], radius / velspeed, velspeed);
1257 MSG_ReadVector(pos);
1258 MSG_ReadVector(dir);
1259 count = MSG_ReadByte();
1260 CL_Flames(pos, dir, count);
1266 cl_model_bolt = Mod_ForName("progs/bolt.mdl", true, false, false);
1267 CL_ParseBeam (cl_model_bolt, true);
1272 if (!cl_model_bolt2)
1273 cl_model_bolt2 = Mod_ForName("progs/bolt2.mdl", true, false, false);
1274 CL_ParseBeam (cl_model_bolt2, true);
1279 if (!cl_model_bolt3)
1280 cl_model_bolt3 = Mod_ForName("progs/bolt3.mdl", true, false, false);
1281 CL_ParseBeam (cl_model_bolt3, false);
1286 // grappling hook beam
1288 cl_model_beam = Mod_ForName("progs/beam.mdl", true, false, false);
1289 CL_ParseBeam (cl_model_beam, false);
1293 // LordHavoc: for compatibility with the Nehahra movie...
1294 case TE_LIGHTNING4NEH:
1295 CL_ParseBeam (Mod_ForName(MSG_ReadString(), true, false, false), false);
1299 pos[0] = MSG_ReadCoord ();
1300 pos[1] = MSG_ReadCoord ();
1301 pos[2] = MSG_ReadCoord ();
1302 CL_LavaSplash (pos);
1306 pos[0] = MSG_ReadCoord ();
1307 pos[1] = MSG_ReadCoord ();
1308 pos[2] = MSG_ReadCoord ();
1309 CL_AllocDlight (NULL, pos, 500, 1.0f, 1.0f, 1.0f, 1500, 99.0f);
1310 // CL_TeleportSplash (pos);
1314 // color mapped explosion
1315 MSG_ReadVector(pos);
1316 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1317 colorStart = MSG_ReadByte ();
1318 colorLength = MSG_ReadByte ();
1319 CL_ParticleExplosion2 (pos, colorStart, colorLength);
1320 tempcolor = (qbyte *)&palette_complete[(rand()%colorLength) + colorStart];
1321 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);
1322 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1326 MSG_ReadVector(pos);
1327 MSG_ReadVector(pos2);
1328 MSG_ReadVector(dir);
1329 CL_BeamParticle(pos, pos2, 12, 1, 0.3, 0.1, 1, 1);
1330 CL_BeamParticle(pos, pos2, 5, 1, 0.9, 0.3, 1, 1);
1334 MSG_ReadVector(pos);
1335 MSG_ReadVector(dir);
1336 count = MSG_ReadByte ();
1337 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1338 CL_Tei_Smoke(pos, dir, count);
1341 case TE_TEI_BIGEXPLOSION:
1342 MSG_ReadVector(pos);
1343 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1344 CL_ParticleExplosion (pos);
1345 CL_AllocDlight (NULL, pos, 500, 1.25f, 1.0f, 0.5f, 500, 9999);
1346 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1349 case TE_TEI_PLASMAHIT:
1350 MSG_ReadVector(pos);
1351 MSG_ReadVector(dir);
1352 count = MSG_ReadByte ();
1353 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1354 CL_Tei_PlasmaHit(pos, dir, count);
1355 CL_AllocDlight (NULL, pos, 500, 0.3, 0.6, 1.0f, 2000, 9999);
1359 Host_Error ("CL_ParseTempEntity: bad type %d (hex %02X)", type, type);
1363 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
1365 static qbyte cgamenetbuffer[65536];
1368 =====================
1369 CL_ParseServerMessage
1370 =====================
1372 int parsingerror = false;
1373 void CL_ParseServerMessage (void)
1376 int i, entitiesupdated;
1378 char *cmdlogname[32], *temp;
1379 int cmdindex, cmdcount = 0;
1382 // if recording demos, copy the message out
1384 if (cl_shownet.integer == 1)
1385 Con_Printf ("%i ",net_message.cursize);
1386 else if (cl_shownet.integer == 2)
1387 Con_Printf ("------------------\n");
1389 cl.onground = false; // unless the server says otherwise
1391 // parse the message
1393 MSG_BeginReading ();
1395 entitiesupdated = false;
1397 parsingerror = true;
1402 Host_Error ("CL_ParseServerMessage: Bad server message");
1404 cmd = MSG_ReadByte ();
1408 SHOWNET("END OF MESSAGE");
1409 break; // end of message
1412 cmdindex = cmdcount & 31;
1414 cmdlog[cmdindex] = cmd;
1416 // if the high bit of the command byte is set, it is a fast update
1419 // 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)
1421 cmdlogname[cmdindex] = temp;
1422 SHOWNET("fast update");
1423 if (cls.signon == SIGNONS - 1)
1425 // first update is the final signon stage
1426 cls.signon = SIGNONS;
1429 CL_ParseUpdate (cmd&127);
1433 SHOWNET(svc_strings[cmd]);
1434 cmdlogname[cmdindex] = svc_strings[cmd];
1435 if (!cmdlogname[cmdindex])
1437 // 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)
1439 cmdlogname[cmdindex] = temp;
1447 char description[32*64], temp[64];
1449 strcpy(description, "packet dump: ");
1453 count = cmdcount - i;
1457 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
1458 strcat(description, temp);
1463 description[strlen(description)-1] = '\n'; // replace the last space with a newline
1464 Con_Printf("%s", description);
1465 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
1473 if (!entitiesupdated)
1475 // this is a new frame, we'll be seeing entities,
1476 // so prepare for entity updates
1477 CL_EntityUpdateSetup();
1478 entitiesupdated = true;
1480 cl.mtime[1] = cl.mtime[0];
1481 cl.mtime[0] = MSG_ReadFloat ();
1484 case svc_clientdata:
1485 i = MSG_ReadShort ();
1486 CL_ParseClientdata (i);
1490 i = MSG_ReadLong ();
1491 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
1492 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
1493 Nehahrademcompatibility = false;
1495 Nehahrademcompatibility = true;
1496 if (cls.demoplayback && demo_nehahra.integer)
1497 Nehahrademcompatibility = true;
1499 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
1503 case svc_disconnect:
1504 Host_EndGame ("Server disconnected\n");
1507 Con_Printf ("%s", MSG_ReadString ());
1510 case svc_centerprint:
1511 SCR_CenterPrint (MSG_ReadString ());
1515 Cbuf_AddText (MSG_ReadString ());
1522 case svc_serverinfo:
1523 CL_ParseServerInfo ();
1527 for (i=0 ; i<3 ; i++)
1528 cl.viewangles[i] = MSG_ReadAngle ();
1532 cl.viewentity = MSG_ReadShort ();
1533 // LordHavoc: assume first setview recieved is the real player entity
1534 if (!cl.playerentity)
1535 cl.playerentity = cl.viewentity;
1538 case svc_lightstyle:
1539 i = MSG_ReadByte ();
1540 if (i >= MAX_LIGHTSTYLES)
1541 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1542 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1543 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1544 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1548 CL_ParseStartSoundPacket(false);
1552 CL_ParseStartSoundPacket(true);
1556 i = MSG_ReadShort();
1557 S_StopSound(i>>3, i&7);
1560 case svc_updatename:
1561 i = MSG_ReadByte ();
1562 if (i >= cl.maxclients)
1563 Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
1564 strcpy (cl.scores[i].name, MSG_ReadString ());
1567 case svc_updatefrags:
1568 i = MSG_ReadByte ();
1569 if (i >= cl.maxclients)
1570 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
1571 cl.scores[i].frags = MSG_ReadShort ();
1574 case svc_updatecolors:
1575 i = MSG_ReadByte ();
1576 if (i >= cl.maxclients)
1577 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
1578 cl.scores[i].colors = MSG_ReadByte ();
1582 CL_ParseParticleEffect ();
1593 case svc_spawnbaseline:
1594 i = MSG_ReadShort ();
1595 if (i < 0 || i >= MAX_EDICTS)
1596 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
1597 CL_ParseBaseline (cl_entities + i, false);
1599 case svc_spawnbaseline2:
1600 i = MSG_ReadShort ();
1601 if (i < 0 || i >= MAX_EDICTS)
1602 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline2: invalid entity number %i", i);
1603 CL_ParseBaseline (cl_entities + i, true);
1605 case svc_spawnstatic:
1606 CL_ParseStatic (false);
1608 case svc_spawnstatic2:
1609 CL_ParseStatic (true);
1611 case svc_temp_entity:
1612 CL_ParseTempEntity ();
1616 cl.paused = MSG_ReadByte ();
1624 i = MSG_ReadByte ();
1625 if (i <= cls.signon)
1626 Host_Error ("Received signon %i when at %i", i, cls.signon);
1631 case svc_killedmonster:
1632 cl.stats[STAT_MONSTERS]++;
1635 case svc_foundsecret:
1636 cl.stats[STAT_SECRETS]++;
1639 case svc_updatestat:
1640 i = MSG_ReadByte ();
1641 if (i < 0 || i >= MAX_CL_STATS)
1642 Host_Error ("svc_updatestat: %i is invalid", i);
1643 cl.stats[i] = MSG_ReadLong ();
1646 case svc_spawnstaticsound:
1647 CL_ParseStaticSound (false);
1650 case svc_spawnstaticsound2:
1651 CL_ParseStaticSound (true);
1655 cl.cdtrack = MSG_ReadByte ();
1656 cl.looptrack = MSG_ReadByte ();
1657 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1658 CDAudio_Play ((qbyte)cls.forcetrack, true);
1660 CDAudio_Play ((qbyte)cl.cdtrack, true);
1663 case svc_intermission:
1664 cl.intermission = 1;
1665 cl.completed_time = cl.time;
1669 cl.intermission = 2;
1670 cl.completed_time = cl.time;
1671 SCR_CenterPrint (MSG_ReadString ());
1675 cl.intermission = 3;
1676 cl.completed_time = cl.time;
1677 SCR_CenterPrint (MSG_ReadString ());
1680 case svc_sellscreen:
1681 Cmd_ExecuteString ("help", src_command);
1684 SHOWLMP_decodehide();
1687 SHOWLMP_decodeshow();
1690 R_SetSkyBox(MSG_ReadString());
1695 length = (int) ((unsigned short) MSG_ReadShort());
1696 for (i = 0;i < length;i++)
1697 cgamenetbuffer[i] = MSG_ReadByte();
1699 CL_CGVM_ParseNetwork(cgamenetbuffer, length);
1703 if (cls.signon == SIGNONS - 1)
1705 // first update is the final signon stage
1706 cls.signon = SIGNONS;
1709 CL_ReadEntityFrame();
1714 if (entitiesupdated)
1715 CL_EntityUpdateEnd();
1717 parsingerror = false;
1720 void CL_Parse_DumpPacket(void)
1724 Con_Printf("Packet dump:\n");
1725 SZ_HexDumpToConsole(&net_message);
1726 parsingerror = false;
1729 void CL_Parse_Init(void)
1731 // LordHavoc: added demo_nehahra cvar
1732 Cvar_RegisterVariable (&demo_nehahra);
1733 if (gamemode == GAME_NEHAHRA)
1734 Cvar_SetValue("demo_nehahra", 1);