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 Host_Error ("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);
368 // check memory integrity
369 Mem_CheckSentinelsGlobal();
371 // disable until we get textures for it
374 memset (cl.model_precache, 0, sizeof(cl.model_precache));
375 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
377 // touch all of the precached models that are still loaded so we can free
378 // anything that isn't needed
380 for (nummodels=1 ; ; nummodels++)
382 CL_KeepaliveMessage ();
383 str = MSG_ReadString ();
386 if (nummodels==MAX_MODELS)
387 Host_Error ("Server sent too many model precaches\n");
388 if (strlen(str) >= MAX_QPATH)
389 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
390 strcpy (model_precache[nummodels], str);
391 Mod_TouchModel (str);
394 // do the same for sounds
395 for (numsounds=1 ; ; numsounds++)
397 CL_KeepaliveMessage ();
398 str = MSG_ReadString ();
401 if (numsounds==MAX_SOUNDS)
402 Host_Error ("Server sent too many sound precaches\n");
403 if (strlen(str) >= MAX_QPATH)
404 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
405 strcpy (sound_precache[numsounds], str);
409 // purge anything that was not touched
412 // now we try to load everything that is new
415 CL_KeepaliveMessage ();
416 cl.model_precache[1] = Mod_ForName (model_precache[1], false, false, true);
417 if (cl.model_precache[1] == NULL)
418 Con_Printf("Map %s not found\n", model_precache[1]);
421 for (i=2 ; i<nummodels ; i++)
423 CL_KeepaliveMessage ();
424 if ((cl.model_precache[i] = Mod_ForName (model_precache[i], false, false, false)) == NULL)
425 Con_Printf("Model %s not found\n", model_precache[i]);
429 S_BeginPrecaching ();
430 for (i=1 ; i<numsounds ; i++)
432 CL_KeepaliveMessage ();
433 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i], true);
438 ent = &cl_entities[0];
439 // entire entity array was cleared, so just fill in a few fields
440 ent->state_current.active = true;
441 ent->render.model = cl.worldmodel = cl.model_precache[1];
442 ent->render.scale = 1;
443 ent->render.alpha = 1;
444 CL_BoundingBoxForEntity(&ent->render);
445 // clear entlife array
446 memset(entlife, 0, MAX_EDICTS);
453 // noclip is turned off at start
454 noclip_anglehack = false;
456 // check memory integrity
457 Mem_CheckSentinelsGlobal();
460 void CL_ValidateState(entity_state_t *s)
467 if (s->modelindex >= MAX_MODELS)
468 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
470 // colormap is client index + 1
471 if (s->colormap > cl.maxclients)
472 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
474 model = cl.model_precache[s->modelindex];
475 Mod_CheckLoaded(model);
476 if (model && s->frame >= model->numframes)
478 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
481 if (model && s->skin > 0 && s->skin >= model->numskins)
483 Con_DPrintf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
488 void CL_MoveLerpEntityStates(entity_t *ent)
490 float odelta[3], adelta[3];
491 VectorSubtract(ent->state_current.origin, ent->persistent.neworigin, odelta);
492 VectorSubtract(ent->state_current.angles, ent->persistent.newangles, adelta);
493 if (!ent->state_previous.active || cls.timedemo || DotProduct(odelta, odelta) > 1000*1000 || cl_nolerp.integer)
495 // we definitely shouldn't lerp
496 ent->persistent.lerpdeltatime = 0;
497 ent->persistent.lerpstarttime = cl.mtime[1];
498 VectorCopy(ent->state_current.origin, ent->persistent.oldorigin);
499 VectorCopy(ent->state_current.angles, ent->persistent.oldangles);
500 VectorCopy(ent->state_current.origin, ent->persistent.neworigin);
501 VectorCopy(ent->state_current.angles, ent->persistent.newangles);
503 else// if (ent->state_current.flags & RENDER_STEP)
505 // monster interpolation
506 if (DotProduct(odelta, odelta) + DotProduct(adelta, adelta) > 0.01)
508 ent->persistent.lerpdeltatime = bound(0, cl.mtime[1] - ent->persistent.lerpstarttime, 0.1);
509 ent->persistent.lerpstarttime = cl.mtime[1];
510 VectorCopy(ent->persistent.neworigin, ent->persistent.oldorigin);
511 VectorCopy(ent->persistent.newangles, ent->persistent.oldangles);
512 VectorCopy(ent->state_current.origin, ent->persistent.neworigin);
513 VectorCopy(ent->state_current.angles, ent->persistent.newangles);
520 ent->persistent.lerpstarttime = cl.mtime[1];
521 // no lerp if it's singleplayer
522 //if (sv.active && svs.maxclients == 1 && !ent->state_current.flags & RENDER_STEP)
523 // ent->persistent.lerpdeltatime = 0;
525 ent->persistent.lerpdeltatime = cl.mtime[0] - cl.mtime[1];
526 VectorCopy(ent->persistent.neworigin, ent->persistent.oldorigin);
527 VectorCopy(ent->persistent.newangles, ent->persistent.oldangles);
528 VectorCopy(ent->state_current.origin, ent->persistent.neworigin);
529 VectorCopy(ent->state_current.angles, ent->persistent.newangles);
538 Parse an entity update message from the server
539 If an entities model or origin changes from frame to frame, it must be
540 relinked. Other attributes can change without relinking.
543 void CL_ParseUpdate (int bits)
549 if (bits & U_MOREBITS)
550 bits |= (MSG_ReadByte()<<8);
551 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
553 bits |= MSG_ReadByte() << 16;
554 if (bits & U_EXTEND2)
555 bits |= MSG_ReadByte() << 24;
558 if (bits & U_LONGENTITY)
559 num = (unsigned) MSG_ReadShort ();
561 num = (unsigned) MSG_ReadByte ();
563 if (num >= MAX_EDICTS)
564 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
566 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
568 ent = cl_entities + num;
570 // note: this inherits the 'active' state of the baseline chosen
571 // (state_baseline is always active, state_current may not be active if
572 // the entity was missing in the last frame)
574 new = ent->state_current;
577 new = ent->state_baseline;
582 new.time = cl.mtime[0];
584 if (bits & U_MODEL) new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte();
585 if (bits & U_FRAME) new.frame = (new.frame & 0xFF00) | MSG_ReadByte();
586 if (bits & U_COLORMAP) new.colormap = MSG_ReadByte();
587 if (bits & U_SKIN) new.skin = MSG_ReadByte();
588 if (bits & U_EFFECTS) new.effects = (new.effects & 0xFF00) | MSG_ReadByte();
589 if (bits & U_ORIGIN1) new.origin[0] = MSG_ReadCoord();
590 if (bits & U_ANGLE1) new.angles[0] = MSG_ReadAngle();
591 if (bits & U_ORIGIN2) new.origin[1] = MSG_ReadCoord();
592 if (bits & U_ANGLE2) new.angles[1] = MSG_ReadAngle();
593 if (bits & U_ORIGIN3) new.origin[2] = MSG_ReadCoord();
594 if (bits & U_ANGLE3) new.angles[2] = MSG_ReadAngle();
595 if (bits & U_STEP) new.flags |= RENDER_STEP;
596 if (bits & U_ALPHA) new.alpha = MSG_ReadByte();
597 if (bits & U_SCALE) new.scale = MSG_ReadByte();
598 if (bits & U_EFFECTS2) new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8);
599 if (bits & U_GLOWSIZE) new.glowsize = MSG_ReadByte();
600 if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte();
601 // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
602 if (bits & U_COLORMOD) MSG_ReadByte();
603 if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL;
604 if (bits & U_FRAME2) new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8);
605 if (bits & U_MODEL2) new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
606 if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL;
607 if (bits & U_EXTERIORMODEL) new.flags |= RENDER_EXTERIORMODEL;
609 // LordHavoc: to allow playback of the Nehahra movie
610 if (Nehahrademcompatibility && (bits & U_EXTEND1))
612 // LordHavoc: evil format
613 int i = MSG_ReadFloat();
614 int j = MSG_ReadFloat() * 255.0f;
619 new.effects |= EF_FULLBRIGHT;
623 else if (j == 0 || j >= 255)
630 CL_ValidateState(&new);
632 ent->state_previous = ent->state_current;
633 ent->state_current = new;
634 if (ent->state_current.active)
636 CL_MoveLerpEntityStates(ent);
637 cl_entities_active[ent->state_current.number] = true;
638 // mark as visible (no kill this frame)
639 entlife[ent->state_current.number] = 2;
643 void CL_ReadEntityFrame(void)
646 entity_frame_t entityframe;
648 EntityFrame_Read(&cl.entitydatabase);
649 EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
650 for (i = 0;i < entityframe.numentities;i++)
653 ent = &cl_entities[entityframe.entitydata[i].number];
654 ent->state_previous = ent->state_current;
655 ent->state_current = entityframe.entitydata[i];
656 CL_MoveLerpEntityStates(ent);
657 // the entity lives again...
658 entlife[ent->state_current.number] = 2;
659 cl_entities_active[ent->state_current.number] = true;
661 VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
662 VectorCopy(entityframe.eye, cl.viewentoriginnew);
665 void CL_EntityUpdateSetup(void)
669 void CL_EntityUpdateEnd(void)
672 // disable entities that disappeared this frame
673 for (i = 1;i < MAX_EDICTS;i++)
675 // clear only the entities that were active last frame but not this
676 // frame, don't waste time clearing all entities (which would cause
682 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
692 void CL_ParseBaseline (entity_t *ent, int large)
696 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
697 ent->state_baseline.active = true;
700 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
701 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
705 ent->state_baseline.modelindex = MSG_ReadByte ();
706 ent->state_baseline.frame = MSG_ReadByte ();
708 ent->state_baseline.colormap = MSG_ReadByte();
709 ent->state_baseline.skin = MSG_ReadByte();
710 for (i = 0;i < 3;i++)
712 ent->state_baseline.origin[i] = MSG_ReadCoord ();
713 ent->state_baseline.angles[i] = MSG_ReadAngle ();
715 ent->state_baseline.alpha = 255;
716 ent->state_baseline.scale = 16;
717 ent->state_baseline.glowsize = 0;
718 ent->state_baseline.glowcolor = 254;
719 ent->state_previous = ent->state_current = ent->state_baseline;
721 CL_ValidateState(&ent->state_baseline);
729 Server information pertaining to this client only
732 void CL_ParseClientdata (int bits)
737 if (bits & SU_EXTEND1)
738 bits |= (MSG_ReadByte() << 16);
739 if (bits & SU_EXTEND2)
740 bits |= (MSG_ReadByte() << 24);
742 if (bits & SU_VIEWHEIGHT)
743 cl.viewheight = MSG_ReadChar ();
745 cl.viewheight = DEFAULT_VIEWHEIGHT;
747 if (bits & SU_IDEALPITCH)
748 cl.idealpitch = MSG_ReadChar ();
752 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
753 for (i=0 ; i<3 ; i++)
755 if (bits & (SU_PUNCH1<<i) )
758 cl.punchangle[i] = MSG_ReadPreciseAngle();
760 cl.punchangle[i] = MSG_ReadChar();
763 cl.punchangle[i] = 0;
764 if (bits & (SU_PUNCHVEC1<<i))
765 cl.punchvector[i] = MSG_ReadCoord();
767 cl.punchvector[i] = 0;
768 if (bits & (SU_VELOCITY1<<i) )
769 cl.mvelocity[0][i] = MSG_ReadChar()*16;
771 cl.mvelocity[0][i] = 0;
777 for (j=0 ; j<32 ; j++)
778 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
779 cl.item_gettime[j] = cl.time;
783 cl.onground = (bits & SU_ONGROUND) != 0;
784 cl.inwater = (bits & SU_INWATER) != 0;
786 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
787 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
788 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
789 cl.stats[STAT_HEALTH] = MSG_ReadShort();
790 cl.stats[STAT_AMMO] = MSG_ReadByte();
792 cl.stats[STAT_SHELLS] = MSG_ReadByte();
793 cl.stats[STAT_NAILS] = MSG_ReadByte();
794 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
795 cl.stats[STAT_CELLS] = MSG_ReadByte();
799 if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
800 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
802 cl.stats[STAT_ACTIVEWEAPON] = i;
804 cl.viewzoomold = cl.viewzoomnew; // for interpolation
805 if (bits & SU_VIEWZOOM)
810 cl.viewzoomnew = (float) i * (1.0f / 255.0f);
818 =====================
820 =====================
822 void CL_ParseStatic (int large)
826 if (cl_num_static_entities >= cl_max_static_entities)
827 Host_Error ("Too many static entities");
828 ent = &cl_static_entities[cl_num_static_entities++];
829 CL_ParseBaseline (ent, large);
831 // copy it to the current state
832 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
833 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
834 ent->render.framelerp = 0;
835 // make torchs play out of sync
836 ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1);
837 ent->render.colormap = -1; // no special coloring
838 ent->render.skinnum = ent->state_baseline.skin;
839 ent->render.effects = ent->state_baseline.effects;
840 ent->render.alpha = 1;
841 ent->render.scale = 1;
842 ent->render.alpha = 1;
844 VectorCopy (ent->state_baseline.origin, ent->render.origin);
845 VectorCopy (ent->state_baseline.angles, ent->render.angles);
847 CL_BoundingBoxForEntity(&ent->render);
849 // This is definitely cheating...
850 if (ent->render.model == NULL)
851 cl_num_static_entities--;
859 void CL_ParseStaticSound (int large)
862 int sound_num, vol, atten;
866 sound_num = (unsigned short) MSG_ReadShort ();
868 sound_num = MSG_ReadByte ();
869 vol = MSG_ReadByte ();
870 atten = MSG_ReadByte ();
872 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
875 void CL_ParseEffect (void)
878 int modelindex, startframe, framecount, framerate;
881 modelindex = MSG_ReadByte ();
882 startframe = MSG_ReadByte ();
883 framecount = MSG_ReadByte ();
884 framerate = MSG_ReadByte ();
886 CL_Effect(org, modelindex, startframe, framecount, framerate);
889 void CL_ParseEffect2 (void)
892 int modelindex, startframe, framecount, framerate;
895 modelindex = MSG_ReadShort ();
896 startframe = MSG_ReadShort ();
897 framecount = MSG_ReadByte ();
898 framerate = MSG_ReadByte ();
900 CL_Effect(org, modelindex, startframe, framecount, framerate);
903 model_t *cl_model_bolt = NULL;
904 model_t *cl_model_bolt2 = NULL;
905 model_t *cl_model_bolt3 = NULL;
906 model_t *cl_model_beam = NULL;
908 sfx_t *cl_sfx_wizhit;
909 sfx_t *cl_sfx_knighthit;
914 sfx_t *cl_sfx_r_exp3;
921 void CL_InitTEnts (void)
923 cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav", false);
924 cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav", false);
925 cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav", false);
926 cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav", false);
927 cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav", false);
928 cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav", false);
929 cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav", false);
932 void CL_ParseBeam (model_t *m)
938 ent = MSG_ReadShort ();
939 MSG_ReadVector(start);
942 // override any beam with the same entity
943 for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
945 if (b->entity == ent)
949 b->endtime = cl.time + 0.2;
950 VectorCopy (start, b->start);
951 VectorCopy (end, b->end);
957 for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
959 if (!b->model || b->endtime < cl.time)
963 b->endtime = cl.time + 0.2;
964 VectorCopy (start, b->start);
965 VectorCopy (end, b->end);
969 Con_Printf ("beam list overflow!\n");
972 void CL_ParseTempEntity (void)
980 int colorStart, colorLength, count;
981 float velspeed, radius;
984 type = MSG_ReadByte ();
988 // spike hitting wall
990 Mod_FindNonSolidLocation(pos, cl.worldmodel);
991 CL_RunParticleEffect (pos, vec3_origin, 20, 30);
992 S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
996 // spike hitting wall
998 Mod_FindNonSolidLocation(pos, cl.worldmodel);
999 CL_RunParticleEffect (pos, vec3_origin, 226, 20);
1000 S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
1004 // spike hitting wall
1005 MSG_ReadVector(pos);
1006 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1007 // LordHavoc: changed to spark shower
1008 CL_SparkShower(pos, vec3_origin, 15);
1010 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1015 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1017 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1019 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1023 // quad spike hitting wall
1024 MSG_ReadVector(pos);
1025 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1026 // LordHavoc: changed to spark shower
1027 CL_SparkShower(pos, vec3_origin, 15);
1028 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1029 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1031 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1036 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1038 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1040 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1044 // super spike hitting wall
1045 MSG_ReadVector(pos);
1046 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1047 // LordHavoc: changed to dust shower
1048 CL_SparkShower(pos, vec3_origin, 30);
1050 S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
1055 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
1057 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
1059 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
1062 case TE_SUPERSPIKEQUAD:
1063 // quad super spike hitting wall
1064 MSG_ReadVector(pos);
1065 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1066 // LordHavoc: changed to dust shower
1067 CL_SparkShower(pos, vec3_origin, 30);
1068 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
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 // LordHavoc: added for improved blood splatters
1085 MSG_ReadVector(pos);
1086 dir[0] = MSG_ReadChar ();
1087 dir[1] = MSG_ReadChar ();
1088 dir[2] = MSG_ReadChar ();
1089 count = MSG_ReadByte ();
1090 CL_BloodPuff(pos, dir, count);
1094 MSG_ReadVector(pos);
1095 CL_BloodPuff(pos, vec3_origin, 10);
1099 MSG_ReadVector(pos);
1100 dir[0] = MSG_ReadChar ();
1101 dir[1] = MSG_ReadChar ();
1102 dir[2] = MSG_ReadChar ();
1103 count = MSG_ReadByte ();
1104 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1105 CL_SparkShower(pos, dir, count);
1108 MSG_ReadVector(pos);
1109 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1110 CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
1113 // LordHavoc: added for improved gore
1114 case TE_BLOODSHOWER:
1116 MSG_ReadVector(pos); // mins
1117 MSG_ReadVector(pos2); // maxs
1118 velspeed = MSG_ReadCoord (); // speed
1119 count = MSG_ReadShort (); // number of particles
1120 CL_BloodShower(pos, pos2, velspeed, count);
1122 case TE_PARTICLECUBE:
1123 // general purpose particle effect
1124 MSG_ReadVector(pos); // mins
1125 MSG_ReadVector(pos2); // maxs
1126 MSG_ReadVector(dir); // dir
1127 count = MSG_ReadShort (); // number of particles
1128 colorStart = MSG_ReadByte (); // color
1129 colorLength = MSG_ReadByte (); // gravity (1 or 0)
1130 velspeed = MSG_ReadCoord (); // randomvel
1131 CL_ParticleCube(pos, pos2, dir, count, colorStart, colorLength, velspeed);
1134 case TE_PARTICLERAIN:
1135 // general purpose particle effect
1136 MSG_ReadVector(pos); // mins
1137 MSG_ReadVector(pos2); // maxs
1138 MSG_ReadVector(dir); // dir
1139 count = MSG_ReadShort (); // number of particles
1140 colorStart = MSG_ReadByte (); // color
1141 CL_ParticleRain(pos, pos2, dir, count, colorStart, 0);
1144 case TE_PARTICLESNOW:
1145 // general purpose particle effect
1146 MSG_ReadVector(pos); // mins
1147 MSG_ReadVector(pos2); // maxs
1148 MSG_ReadVector(dir); // dir
1149 count = MSG_ReadShort (); // number of particles
1150 colorStart = MSG_ReadByte (); // color
1151 CL_ParticleRain(pos, pos2, dir, count, colorStart, 1);
1155 // bullet hitting wall
1156 MSG_ReadVector(pos);
1157 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1158 // LordHavoc: changed to dust shower
1159 CL_SparkShower(pos, vec3_origin, 15);
1162 case TE_GUNSHOTQUAD:
1163 // quad bullet hitting wall
1164 MSG_ReadVector(pos);
1165 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1166 CL_SparkShower(pos, vec3_origin, 15);
1167 CL_AllocDlight (NULL, pos, 200, 0.1f, 0.1f, 1.0f, 1000, 0.2);
1172 MSG_ReadVector(pos);
1173 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1174 CL_ParticleExplosion (pos);
1175 // LordHavoc: boosted color from 1.0, 0.8, 0.4 to 1.25, 1.0, 0.5
1176 CL_AllocDlight (NULL, pos, 350, 1.25f, 1.0f, 0.5f, 700, 0.5);
1177 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1180 case TE_EXPLOSIONQUAD:
1181 // quad rocket explosion
1182 MSG_ReadVector(pos);
1183 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1184 CL_ParticleExplosion (pos);
1185 CL_AllocDlight (NULL, pos, 600, 0.5f, 0.4f, 1.0f, 1200, 0.5);
1186 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1190 // Nehahra movie colored lighting explosion
1191 MSG_ReadVector(pos);
1192 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1193 CL_ParticleExplosion (pos);
1194 CL_AllocDlight (NULL, pos, 350, MSG_ReadCoord(), MSG_ReadCoord(), MSG_ReadCoord(), 700, 0.5);
1195 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1198 case TE_EXPLOSIONRGB:
1199 // colored lighting explosion
1200 MSG_ReadVector(pos);
1201 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1202 CL_ParticleExplosion (pos);
1203 color[0] = MSG_ReadByte() * (1.0 / 255.0);
1204 color[1] = MSG_ReadByte() * (1.0 / 255.0);
1205 color[2] = MSG_ReadByte() * (1.0 / 255.0);
1206 CL_AllocDlight (NULL, pos, 350, color[0], color[1], color[2], 700, 0.5);
1207 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1210 case TE_TAREXPLOSION:
1211 // tarbaby explosion
1212 MSG_ReadVector(pos);
1213 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1214 CL_BlobExplosion (pos);
1216 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1217 CL_AllocDlight (NULL, pos, 600, 0.8f, 0.4f, 1.0f, 1200, 0.5);
1218 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1222 MSG_ReadVector(pos);
1223 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1224 CL_AllocDlight (NULL, pos, 200, 1, 1, 1, 1000, 0.2);
1227 case TE_CUSTOMFLASH:
1228 MSG_ReadVector(pos);
1229 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1230 radius = MSG_ReadByte() * 8;
1231 velspeed = (MSG_ReadByte() + 1) * (1.0 / 256.0);
1232 color[0] = MSG_ReadByte() * (1.0 / 255.0);
1233 color[1] = MSG_ReadByte() * (1.0 / 255.0);
1234 color[2] = MSG_ReadByte() * (1.0 / 255.0);
1235 CL_AllocDlight (NULL, pos, radius, color[0], color[1], color[2], radius / velspeed, velspeed);
1239 MSG_ReadVector(pos);
1240 MSG_ReadVector(dir);
1241 count = MSG_ReadByte();
1242 CL_Flames(pos, dir, count);
1248 cl_model_bolt = Mod_ForName("progs/bolt.mdl", true, false, false);
1249 CL_ParseBeam (cl_model_bolt);
1254 if (!cl_model_bolt2)
1255 cl_model_bolt2 = Mod_ForName("progs/bolt2.mdl", true, false, false);
1256 CL_ParseBeam (cl_model_bolt2);
1261 if (!cl_model_bolt3)
1262 cl_model_bolt3 = Mod_ForName("progs/bolt3.mdl", true, false, false);
1263 CL_ParseBeam (cl_model_bolt3);
1268 // grappling hook beam
1270 cl_model_beam = Mod_ForName("progs/beam.mdl", true, false, false);
1271 CL_ParseBeam (cl_model_beam);
1275 // LordHavoc: for compatibility with the Nehahra movie...
1276 case TE_LIGHTNING4NEH:
1277 CL_ParseBeam (Mod_ForName(MSG_ReadString(), true, false, false));
1281 pos[0] = MSG_ReadCoord ();
1282 pos[1] = MSG_ReadCoord ();
1283 pos[2] = MSG_ReadCoord ();
1284 CL_LavaSplash (pos);
1288 pos[0] = MSG_ReadCoord ();
1289 pos[1] = MSG_ReadCoord ();
1290 pos[2] = MSG_ReadCoord ();
1291 CL_AllocDlight (NULL, pos, 500, 1.0f, 1.0f, 1.0f, 1500, 99.0f);
1292 // CL_TeleportSplash (pos);
1296 // color mapped explosion
1297 MSG_ReadVector(pos);
1298 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1299 colorStart = MSG_ReadByte ();
1300 colorLength = MSG_ReadByte ();
1301 CL_ParticleExplosion2 (pos, colorStart, colorLength);
1302 tempcolor = (qbyte *)&palette_complete[(rand()%colorLength) + colorStart];
1303 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);
1304 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1308 MSG_ReadVector(pos);
1309 MSG_ReadVector(pos2);
1310 MSG_ReadVector(dir);
1311 CL_BeamParticle(pos, pos2, 12, 1, 0.3, 0.1, 1, 1);
1312 CL_BeamParticle(pos, pos2, 5, 1, 0.9, 0.3, 1, 1);
1316 MSG_ReadVector(pos);
1317 MSG_ReadVector(dir);
1318 count = MSG_ReadByte ();
1319 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1320 CL_Tei_Smoke(pos, dir, count);
1323 case TE_TEI_BIGEXPLOSION:
1324 MSG_ReadVector(pos);
1325 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1326 CL_ParticleExplosion (pos);
1327 CL_AllocDlight (NULL, pos, 500, 1.25f, 1.0f, 0.5f, 500, 9999);
1328 S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
1331 case TE_TEI_PLASMAHIT:
1332 MSG_ReadVector(pos);
1333 MSG_ReadVector(dir);
1334 count = MSG_ReadByte ();
1335 Mod_FindNonSolidLocation(pos, cl.worldmodel);
1336 CL_Tei_PlasmaHit(pos, dir, count);
1337 CL_AllocDlight (NULL, pos, 500, 0.3, 0.6, 1.0f, 2000, 9999);
1341 Host_Error ("CL_ParseTempEntity: bad type %d (hex %02X)", type, type);
1345 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
1347 static qbyte cgamenetbuffer[65536];
1350 =====================
1351 CL_ParseServerMessage
1352 =====================
1354 int parsingerror = false;
1355 void CL_ParseServerMessage (void)
1358 int i, entitiesupdated;
1360 char *cmdlogname[32], *temp;
1361 int cmdindex, cmdcount = 0;
1364 // if recording demos, copy the message out
1366 if (cl_shownet.integer == 1)
1367 Con_Printf ("%i ",net_message.cursize);
1368 else if (cl_shownet.integer == 2)
1369 Con_Printf ("------------------\n");
1371 cl.onground = false; // unless the server says otherwise
1373 // parse the message
1375 MSG_BeginReading ();
1377 entitiesupdated = false;
1379 parsingerror = true;
1384 Host_Error ("CL_ParseServerMessage: Bad server message");
1386 cmd = MSG_ReadByte ();
1390 SHOWNET("END OF MESSAGE");
1391 break; // end of message
1394 cmdindex = cmdcount & 31;
1396 cmdlog[cmdindex] = cmd;
1398 // if the high bit of the command byte is set, it is a fast update
1401 // 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)
1403 cmdlogname[cmdindex] = temp;
1404 SHOWNET("fast update");
1405 if (cls.signon == SIGNONS - 1)
1407 // first update is the final signon stage
1408 cls.signon = SIGNONS;
1411 CL_ParseUpdate (cmd&127);
1415 SHOWNET(svc_strings[cmd]);
1416 cmdlogname[cmdindex] = svc_strings[cmd];
1417 if (!cmdlogname[cmdindex])
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;
1429 char description[32*64], temp[64];
1431 strcpy(description, "packet dump: ");
1435 count = cmdcount - i;
1439 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
1440 strcat(description, temp);
1445 description[strlen(description)-1] = '\n'; // replace the last space with a newline
1446 Con_Printf("%s", description);
1447 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
1455 if (!entitiesupdated)
1457 // this is a new frame, we'll be seeing entities,
1458 // so prepare for entity updates
1459 CL_EntityUpdateSetup();
1460 entitiesupdated = true;
1462 cl.mtime[1] = cl.mtime[0];
1463 cl.mtime[0] = MSG_ReadFloat ();
1466 case svc_clientdata:
1467 i = MSG_ReadShort ();
1468 CL_ParseClientdata (i);
1472 i = MSG_ReadLong ();
1473 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
1474 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
1475 Nehahrademcompatibility = false;
1477 Nehahrademcompatibility = true;
1478 if (cls.demoplayback && demo_nehahra.integer)
1479 Nehahrademcompatibility = true;
1481 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
1485 case svc_disconnect:
1486 Host_EndGame ("Server disconnected\n");
1489 Con_Printf ("%s", MSG_ReadString ());
1492 case svc_centerprint:
1493 SCR_CenterPrint (MSG_ReadString ());
1497 Cbuf_AddText (MSG_ReadString ());
1504 case svc_serverinfo:
1505 CL_ParseServerInfo ();
1509 for (i=0 ; i<3 ; i++)
1510 cl.viewangles[i] = MSG_ReadAngle ();
1514 cl.viewentity = MSG_ReadShort ();
1515 // LordHavoc: assume first setview recieved is the real player entity
1516 if (!cl.playerentity)
1517 cl.playerentity = cl.viewentity;
1520 case svc_lightstyle:
1521 i = MSG_ReadByte ();
1522 if (i >= MAX_LIGHTSTYLES)
1523 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1524 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1525 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1526 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1530 CL_ParseStartSoundPacket(false);
1534 CL_ParseStartSoundPacket(true);
1538 i = MSG_ReadShort();
1539 S_StopSound(i>>3, i&7);
1542 case svc_updatename:
1543 i = MSG_ReadByte ();
1544 if (i >= cl.maxclients)
1545 Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
1546 strcpy (cl.scores[i].name, MSG_ReadString ());
1549 case svc_updatefrags:
1550 i = MSG_ReadByte ();
1551 if (i >= cl.maxclients)
1552 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
1553 cl.scores[i].frags = MSG_ReadShort ();
1556 case svc_updatecolors:
1557 i = MSG_ReadByte ();
1558 if (i >= cl.maxclients)
1559 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
1560 cl.scores[i].colors = MSG_ReadByte ();
1561 // update our color cvar if our color changed
1562 if (i == cl.playerentity - 1)
1563 Cvar_SetValue ("_cl_color", cl.scores[i].colors);
1567 CL_ParseParticleEffect ();
1578 case svc_spawnbaseline:
1579 i = MSG_ReadShort ();
1580 if (i < 0 || i >= MAX_EDICTS)
1581 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
1582 CL_ParseBaseline (cl_entities + i, false);
1584 case svc_spawnbaseline2:
1585 i = MSG_ReadShort ();
1586 if (i < 0 || i >= MAX_EDICTS)
1587 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline2: invalid entity number %i", i);
1588 CL_ParseBaseline (cl_entities + i, true);
1590 case svc_spawnstatic:
1591 CL_ParseStatic (false);
1593 case svc_spawnstatic2:
1594 CL_ParseStatic (true);
1596 case svc_temp_entity:
1597 CL_ParseTempEntity ();
1601 cl.paused = MSG_ReadByte ();
1609 i = MSG_ReadByte ();
1610 if (i <= cls.signon)
1611 Host_Error ("Received signon %i when at %i", i, cls.signon);
1616 case svc_killedmonster:
1617 cl.stats[STAT_MONSTERS]++;
1620 case svc_foundsecret:
1621 cl.stats[STAT_SECRETS]++;
1624 case svc_updatestat:
1625 i = MSG_ReadByte ();
1626 if (i < 0 || i >= MAX_CL_STATS)
1627 Host_Error ("svc_updatestat: %i is invalid", i);
1628 cl.stats[i] = MSG_ReadLong ();
1631 case svc_spawnstaticsound:
1632 CL_ParseStaticSound (false);
1635 case svc_spawnstaticsound2:
1636 CL_ParseStaticSound (true);
1640 cl.cdtrack = MSG_ReadByte ();
1641 cl.looptrack = MSG_ReadByte ();
1642 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1643 CDAudio_Play ((qbyte)cls.forcetrack, true);
1645 CDAudio_Play ((qbyte)cl.cdtrack, true);
1648 case svc_intermission:
1649 cl.intermission = 1;
1650 cl.completed_time = cl.time;
1654 cl.intermission = 2;
1655 cl.completed_time = cl.time;
1656 SCR_CenterPrint (MSG_ReadString ());
1660 cl.intermission = 3;
1661 cl.completed_time = cl.time;
1662 SCR_CenterPrint (MSG_ReadString ());
1665 case svc_sellscreen:
1666 Cmd_ExecuteString ("help", src_command);
1669 SHOWLMP_decodehide();
1672 SHOWLMP_decodeshow();
1675 R_SetSkyBox(MSG_ReadString());
1680 length = (int) ((unsigned short) MSG_ReadShort());
1681 for (i = 0;i < length;i++)
1682 cgamenetbuffer[i] = MSG_ReadByte();
1684 CL_CGVM_ParseNetwork(cgamenetbuffer, length);
1688 if (cls.signon == SIGNONS - 1)
1690 // first update is the final signon stage
1691 cls.signon = SIGNONS;
1694 CL_ReadEntityFrame();
1699 if (entitiesupdated)
1700 CL_EntityUpdateEnd();
1702 parsingerror = false;
1705 void CL_Parse_DumpPacket(void)
1709 Con_Printf("Packet dump:\n");
1710 SZ_HexDumpToConsole(&net_message);
1711 parsingerror = false;
1714 void CL_Parse_Init(void)
1716 // LordHavoc: added demo_nehahra cvar
1717 Cvar_RegisterVariable (&demo_nehahra);
1718 if (gamemode == GAME_NEHAHRA)
1719 Cvar_SetValue("demo_nehahra", 1);