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 void CL_Parse_Init(void)
101 // LordHavoc: added demo_nehahra cvar
102 Cvar_RegisterVariable (&demo_nehahra);
103 if (gamemode == GAME_NEHAHRA)
104 Cvar_SetValue("demo_nehahra", 1);
107 qboolean Nehahrademcompatibility; // LordHavoc: to allow playback of the early Nehahra movie segments
108 int dpprotocol; // LordHavoc: version of network protocol, or 0 if not DarkPlaces
112 CL_ParseStartSoundPacket
115 void CL_ParseStartSoundPacket(int largesoundindex)
125 field_mask = MSG_ReadByte();
127 if (field_mask & SND_VOLUME)
128 volume = MSG_ReadByte ();
130 volume = DEFAULT_SOUND_PACKET_VOLUME;
132 if (field_mask & SND_ATTENUATION)
133 attenuation = MSG_ReadByte () / 64.0;
135 attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
137 channel = MSG_ReadShort ();
139 sound_num = (unsigned short) MSG_ReadShort ();
141 sound_num = MSG_ReadByte ();
143 if (sound_num >= MAX_SOUNDS)
144 Host_Error("CL_ParseStartSoundPacket: sound_num (%i) >= MAX_SOUNDS (%i)\n", sound_num, MAX_SOUNDS);
149 if (ent > MAX_EDICTS)
150 Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
152 for (i=0 ; i<3 ; i++)
153 pos[i] = MSG_ReadCoord ();
155 S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
162 When the client is taking a long time to load stuff, send keepalive messages
163 so the server doesn't disconnect.
166 void CL_KeepaliveMessage (void)
169 static float lastmsg;
176 return; // no need if server is local
177 if (cls.demoplayback)
180 // read messages from server, should just be nops
182 memcpy (olddata, net_message.data, net_message.cursize);
186 ret = CL_GetMessage ();
190 Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");
192 break; // nothing waiting
194 Host_Error ("CL_KeepaliveMessage: received a message");
199 Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
205 memcpy (net_message.data, olddata, net_message.cursize);
208 time = Sys_DoubleTime ();
209 if (time - lastmsg < 5)
214 Con_Printf ("--> client to server keepalive\n");
216 MSG_WriteByte (&cls.message, clc_nop);
217 NET_SendMessage (cls.netcon, &cls.message);
218 SZ_Clear (&cls.message);
221 void CL_ParseEntityLump(char *entdata)
224 char key[128], value[4096];
225 FOG_clear(); // LordHavoc: no fog until set
226 R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set
230 data = COM_Parse(data);
233 if (com_token[0] != '{')
237 data = COM_Parse(data);
240 if (com_token[0] == '}')
241 break; // end of worldspawn
242 if (com_token[0] == '_')
243 strcpy(key, com_token + 1);
245 strcpy(key, com_token);
246 while (key[strlen(key)-1] == ' ') // remove trailing spaces
247 key[strlen(key)-1] = 0;
248 data = COM_Parse(data);
251 strcpy(value, com_token);
252 if (!strcmp("sky", key))
254 else if (!strcmp("skyname", key)) // non-standard, introduced by QuakeForge... sigh.
256 else if (!strcmp("qlsky", key)) // non-standard, introduced by QuakeLives (EEK)
258 else if (!strcmp("fog", key))
259 sscanf(value, "%f %f %f %f", &fog_density, &fog_red, &fog_green, &fog_blue);
260 else if (!strcmp("fog_density", key))
261 fog_density = atof(value);
262 else if (!strcmp("fog_red", key))
263 fog_red = atof(value);
264 else if (!strcmp("fog_green", key))
265 fog_green = atof(value);
266 else if (!strcmp("fog_blue", key))
267 fog_blue = atof(value);
272 =====================
275 An svc_signonnum has been received, perform a client side setup
276 =====================
278 static void CL_SignonReply (void)
282 Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
287 MSG_WriteByte (&cls.message, clc_stringcmd);
288 MSG_WriteString (&cls.message, "prespawn");
292 MSG_WriteByte (&cls.message, clc_stringcmd);
293 MSG_WriteString (&cls.message, va("name \"%s\"\n", cl_name.string));
295 MSG_WriteByte (&cls.message, clc_stringcmd);
296 MSG_WriteString (&cls.message, va("color %i %i\n", cl_color.integer >> 4, cl_color.integer & 15));
298 if (cl_pmodel.integer)
300 MSG_WriteByte (&cls.message, clc_stringcmd);
301 MSG_WriteString (&cls.message, va("pmodel %i\n", cl_pmodel.integer));
304 MSG_WriteByte (&cls.message, clc_stringcmd);
305 //sprintf (str, "spawn %s", cls.spawnparms);
306 //MSG_WriteString (&cls.message, str);
307 MSG_WriteString (&cls.message, "spawn");
311 MSG_WriteByte (&cls.message, clc_stringcmd);
312 MSG_WriteString (&cls.message, "begin");
326 qbyte entlife[MAX_EDICTS];
327 void CL_ParseServerInfo (void)
331 int nummodels, numsounds;
332 char model_precache[MAX_MODELS][MAX_QPATH];
333 char sound_precache[MAX_SOUNDS][MAX_QPATH];
336 Con_DPrintf ("Serverinfo packet received.\n");
338 // wipe the client_state_t struct
342 // parse protocol version number
344 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
346 Con_Printf ("Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
349 Nehahrademcompatibility = false;
351 Nehahrademcompatibility = true;
352 if (cls.demoplayback && demo_nehahra.integer)
353 Nehahrademcompatibility = true;
355 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
359 cl.maxclients = MSG_ReadByte ();
360 if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
362 Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
365 cl.scores = Mem_Alloc(cl_scores_mempool, cl.maxclients*sizeof(*cl.scores));
368 cl.gametype = MSG_ReadByte ();
370 // parse signon message
371 str = MSG_ReadString ();
372 strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
374 // seperate the printfs so the server message can have a color
375 if (!Nehahrademcompatibility) // no messages when playing the Nehahra movie
377 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");
378 Con_Printf ("%c%s\n", 2, str);
382 // first we go through and touch all of the precache data that still
383 // happens to be in the cache, so precaching something else doesn't
384 // needlessly purge it
387 Mem_CheckSentinelsGlobal();
392 memset (cl.model_precache, 0, sizeof(cl.model_precache));
393 for (nummodels=1 ; ; nummodels++)
395 str = MSG_ReadString ();
398 if (nummodels==MAX_MODELS)
400 Host_Error ("Server sent too many model 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 (model_precache[nummodels], str);
406 Mod_TouchModel (str);
410 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
411 for (numsounds=1 ; ; numsounds++)
413 str = MSG_ReadString ();
416 if (numsounds==MAX_SOUNDS)
418 Host_Error ("Server sent too many sound precaches\n");
421 if (strlen(str) >= MAX_QPATH)
422 Host_Error ("Server sent a precache name of %i characters (max %i)", strlen(str), MAX_QPATH - 1);
423 strcpy (sound_precache[numsounds], str);
430 // now we try to load everything else until a cache allocation fails
433 for (i=1 ; i<nummodels ; i++)
435 // LordHavoc: i == 1 means the first model is the world model
436 cl.model_precache[i] = Mod_ForName (model_precache[i], false, false, i == 1);
438 if (cl.model_precache[i] == NULL)
440 Host_Error("Model %s not found\n", model_precache[i]);
443 CL_KeepaliveMessage ();
446 S_BeginPrecaching ();
447 for (i=1 ; i<numsounds ; i++)
449 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i], true);
450 CL_KeepaliveMessage ();
455 ent = &cl_entities[0];
456 // entire entity array was cleared, so just fill in a few fields
457 ent->state_current.active = true;
458 ent->render.model = cl.worldmodel = cl.model_precache[1];
459 ent->render.scale = 1;
460 ent->render.alpha = 1;
461 VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins);
462 VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs);
463 // clear entlife array
464 memset(entlife, 0, MAX_EDICTS);
472 Mem_CheckSentinelsGlobal();
474 noclip_anglehack = false; // noclip is turned off at start
477 void CL_ValidateState(entity_state_t *s)
484 if (s->modelindex >= MAX_MODELS)
485 Host_Error("CL_ValidateState: modelindex (%i) >= MAX_MODELS (%i)\n", s->modelindex, MAX_MODELS);
487 // colormap is client index + 1
488 if (s->colormap > cl.maxclients)
489 Host_Error ("CL_ValidateState: colormap (%i) > cl.maxclients (%i)", s->colormap, cl.maxclients);
491 model = cl.model_precache[s->modelindex];
492 Mod_CheckLoaded(model);
493 if (model && s->frame >= model->numframes)
495 Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\"\n", s->frame, model->name);
498 if (model && s->skin > 0 && s->skin >= model->numskins)
500 Con_DPrintf("CL_ValidateState: no such skin %i in \"%s\"\n", s->skin, model->name);
509 Parse an entity update message from the server
510 If an entities model or origin changes from frame to frame, it must be
511 relinked. Other attributes can change without relinking.
514 int bitprofile[32], bitprofilecount = 0;
515 void CL_ParseUpdate (int bits)
521 if (bits & U_MOREBITS)
522 bits |= (MSG_ReadByte()<<8);
523 if ((bits & U_EXTEND1) && (!Nehahrademcompatibility))
525 bits |= MSG_ReadByte() << 16;
526 if (bits & U_EXTEND2)
527 bits |= MSG_ReadByte() << 24;
530 if (bits & U_LONGENTITY)
531 num = (unsigned) MSG_ReadShort ();
533 num = (unsigned) MSG_ReadByte ();
535 if (num >= MAX_EDICTS)
536 Host_Error("CL_ParseUpdate: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS);
538 Host_Error("CL_ParseUpdate: invalid entity number (%i)\n", num);
540 ent = cl_entities + num;
542 for (i = 0;i < 32;i++)
547 // note: this inherits the 'active' state of the baseline chosen
548 // (state_baseline is always active, state_current may not be active if
549 // the entity was missing in the last frame)
551 new = ent->state_current;
554 new = ent->state_baseline;
559 new.time = cl.mtime[0];
561 if (bits & U_MODEL) new.modelindex = (new.modelindex & 0xFF00) | MSG_ReadByte();
562 if (bits & U_FRAME) new.frame = (new.frame & 0xFF00) | MSG_ReadByte();
563 if (bits & U_COLORMAP) new.colormap = MSG_ReadByte();
564 if (bits & U_SKIN) new.skin = MSG_ReadByte();
565 if (bits & U_EFFECTS) new.effects = (new.effects & 0xFF00) | MSG_ReadByte();
566 if (bits & U_ORIGIN1) new.origin[0] = MSG_ReadCoord();
567 if (bits & U_ANGLE1) new.angles[0] = MSG_ReadAngle();
568 if (bits & U_ORIGIN2) new.origin[1] = MSG_ReadCoord();
569 if (bits & U_ANGLE2) new.angles[1] = MSG_ReadAngle();
570 if (bits & U_ORIGIN3) new.origin[2] = MSG_ReadCoord();
571 if (bits & U_ANGLE3) new.angles[2] = MSG_ReadAngle();
572 if (bits & U_STEP) new.flags |= RENDER_STEP;
573 if (bits & U_ALPHA) new.alpha = MSG_ReadByte();
574 if (bits & U_SCALE) new.scale = MSG_ReadByte();
575 if (bits & U_EFFECTS2) new.effects = (new.effects & 0x00FF) | (MSG_ReadByte() << 8);
576 if (bits & U_GLOWSIZE) new.glowsize = MSG_ReadByte();
577 if (bits & U_GLOWCOLOR) new.glowcolor = MSG_ReadByte();
578 // apparently the dpcrush demo uses this (unintended, and it uses white anyway)
579 if (bits & U_COLORMOD) MSG_ReadByte();
580 if (bits & U_GLOWTRAIL) new.flags |= RENDER_GLOWTRAIL;
581 if (bits & U_FRAME2) new.frame = (new.frame & 0x00FF) | (MSG_ReadByte() << 8);
582 if (bits & U_MODEL2) new.modelindex = (new.modelindex & 0x00FF) | (MSG_ReadByte() << 8);
583 if (bits & U_VIEWMODEL) new.flags |= RENDER_VIEWMODEL;
584 if (bits & U_EXTERIORMODEL) new.flags |= RENDER_EXTERIORMODEL;
586 // LordHavoc: to allow playback of the Nehahra movie
587 if (Nehahrademcompatibility && (bits & U_EXTEND1))
589 // LordHavoc: evil format
590 int i = MSG_ReadFloat();
591 int j = MSG_ReadFloat() * 255.0f;
596 new.effects |= EF_FULLBRIGHT;
600 else if (j == 0 || j >= 255)
607 CL_ValidateState(&new);
609 if (new.flags & RENDER_STEP) // FIXME: rename this flag?
611 // make time identical for memcmp
612 new.time = ent->state_current.time;
613 if (memcmp(&new, &ent->state_current, sizeof(entity_state_t)))
615 // set it back to what it should be
616 new.time = cl.mtime[0] + 0.1;
618 ent->state_previous = ent->state_current;
619 ent->state_current = new;
620 // assume 10fps animation
621 //ent->state_previous.time = cl.mtime[0] - 0.1;
626 ent->state_previous = ent->state_current;
627 ent->state_current = new;
629 if (ent->state_current.active)
631 cl_entities_active[ent->state_current.number] = true;
632 // mark as visible (no kill this frame)
633 entlife[ent->state_current.number] = 2;
637 void CL_ReadEntityFrame(void)
640 entity_frame_t entityframe;
642 EntityFrame_Read(&cl.entitydatabase);
643 EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
644 for (i = 0;i < entityframe.numentities;i++)
647 ent = &cl_entities[entityframe.entitydata[i].number];
648 ent->state_previous = ent->state_current;
649 ent->state_current = entityframe.entitydata[i];
650 ent->state_current.time = cl.mtime[0];
651 // the entity lives again...
652 entlife[ent->state_current.number] = 2;
653 cl_entities_active[ent->state_current.number] = true;
655 VectorCopy(cl.viewentoriginnew, cl.viewentoriginold);
656 VectorCopy(entityframe.eye, cl.viewentoriginnew);
659 char *bitprofilenames[32] =
683 "obsolete U_COLORMOD",
695 void CL_BitProfile_f(void)
698 Con_Printf("bitprofile: %i updates\n");
700 for (i = 0;i < 32;i++)
701 Con_Printf("%s: %i %3.2f%%\n", bitprofilenames[i], bitprofile[i], bitprofile[i] * 100.0 / bitprofilecount);
703 for (i = 0;i < 32;i++)
708 void CL_EntityUpdateSetup(void)
712 void CL_EntityUpdateEnd(void)
715 // disable entities that disappeared this frame
716 for (i = 1;i < MAX_EDICTS;i++)
718 // clear only the entities that were active last frame but not this
719 // frame, don't waste time clearing all entities (which would cause
725 cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
735 void CL_ParseBaseline (entity_t *ent, int large)
739 memset(&ent->state_baseline, 0, sizeof(entity_state_t));
740 ent->state_baseline.active = true;
743 ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort ();
744 ent->state_baseline.frame = (unsigned short) MSG_ReadShort ();
748 ent->state_baseline.modelindex = MSG_ReadByte ();
749 ent->state_baseline.frame = MSG_ReadByte ();
751 ent->state_baseline.colormap = MSG_ReadByte();
752 ent->state_baseline.skin = MSG_ReadByte();
753 for (i = 0;i < 3;i++)
755 ent->state_baseline.origin[i] = MSG_ReadCoord ();
756 ent->state_baseline.angles[i] = MSG_ReadAngle ();
758 ent->state_baseline.alpha = 255;
759 ent->state_baseline.scale = 16;
760 ent->state_baseline.glowsize = 0;
761 ent->state_baseline.glowcolor = 254;
762 ent->state_previous = ent->state_current = ent->state_baseline;
764 CL_ValidateState(&ent->state_baseline);
772 Server information pertaining to this client only
775 void CL_ParseClientdata (int bits)
780 if (bits & SU_EXTEND1)
781 bits |= (MSG_ReadByte() << 16);
782 if (bits & SU_EXTEND2)
783 bits |= (MSG_ReadByte() << 24);
785 if (bits & SU_VIEWHEIGHT)
786 cl.viewheight = MSG_ReadChar ();
788 cl.viewheight = DEFAULT_VIEWHEIGHT;
790 if (bits & SU_IDEALPITCH)
791 cl.idealpitch = MSG_ReadChar ();
795 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
796 for (i=0 ; i<3 ; i++)
798 if (bits & (SU_PUNCH1<<i) )
801 cl.punchangle[i] = MSG_ReadPreciseAngle();
803 cl.punchangle[i] = MSG_ReadChar();
806 cl.punchangle[i] = 0;
807 if (bits & (SU_PUNCHVEC1<<i))
808 cl.punchvector[i] = MSG_ReadCoord();
810 cl.punchvector[i] = 0;
811 if (bits & (SU_VELOCITY1<<i) )
812 cl.mvelocity[0][i] = MSG_ReadChar()*16;
814 cl.mvelocity[0][i] = 0;
820 for (j=0 ; j<32 ; j++)
821 if ( (i & (1<<j)) && !(cl.items & (1<<j)))
822 cl.item_gettime[j] = cl.time;
826 cl.onground = (bits & SU_ONGROUND) != 0;
827 cl.inwater = (bits & SU_INWATER) != 0;
829 cl.stats[STAT_WEAPONFRAME] = (bits & SU_WEAPONFRAME) ? MSG_ReadByte() : 0;
830 cl.stats[STAT_ARMOR] = (bits & SU_ARMOR) ? MSG_ReadByte() : 0;
831 cl.stats[STAT_WEAPON] = (bits & SU_WEAPON) ? MSG_ReadByte() : 0;
832 cl.stats[STAT_HEALTH] = MSG_ReadShort();
833 cl.stats[STAT_AMMO] = MSG_ReadByte();
835 cl.stats[STAT_SHELLS] = MSG_ReadByte();
836 cl.stats[STAT_NAILS] = MSG_ReadByte();
837 cl.stats[STAT_ROCKETS] = MSG_ReadByte();
838 cl.stats[STAT_CELLS] = MSG_ReadByte();
842 if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
843 cl.stats[STAT_ACTIVEWEAPON] = (1<<i);
845 cl.stats[STAT_ACTIVEWEAPON] = i;
847 cl.viewzoomold = cl.viewzoomnew; // for interpolation
848 if (bits & SU_VIEWZOOM)
853 cl.viewzoomnew = (float) i * (1.0f / 255.0f);
861 =====================
863 =====================
865 void CL_ParseStatic (int large)
869 if (cl_num_static_entities >= cl_max_static_entities)
870 Host_Error ("Too many static entities");
871 ent = &cl_static_entities[cl_num_static_entities++];
872 CL_ParseBaseline (ent, large);
874 // copy it to the current state
875 ent->render.model = cl.model_precache[ent->state_baseline.modelindex];
876 ent->render.frame = ent->render.frame1 = ent->render.frame2 = ent->state_baseline.frame;
877 ent->render.framelerp = 0;
878 // make torchs play out of sync
879 ent->render.frame1time = ent->render.frame2time = lhrandom(-10, -1);
880 ent->render.colormap = -1; // no special coloring
881 ent->render.skinnum = ent->state_baseline.skin;
882 ent->render.effects = ent->state_baseline.effects;
883 ent->render.alpha = 1;
884 ent->render.scale = 1;
885 ent->render.alpha = 1;
887 VectorCopy (ent->state_baseline.origin, ent->render.origin);
888 VectorCopy (ent->state_baseline.angles, ent->render.angles);
890 if (ent->render.angles[0] || ent->render.angles[2])
893 VectorAdd(ent->render.origin, ent->render.model->rotatedmins, ent->render.mins);
894 VectorAdd(ent->render.origin, ent->render.model->rotatedmaxs, ent->render.maxs);
896 else if (ent->render.angles[1])
899 VectorAdd(ent->render.origin, ent->render.model->yawmins, ent->render.mins);
900 VectorAdd(ent->render.origin, ent->render.model->yawmaxs, ent->render.maxs);
904 VectorAdd(ent->render.origin, ent->render.model->normalmins, ent->render.mins);
905 VectorAdd(ent->render.origin, ent->render.model->normalmaxs, ent->render.maxs);
908 // This is definitely cheating...
909 if (ent->render.model == NULL)
910 cl_num_static_entities--;
918 void CL_ParseStaticSound (int large)
921 int sound_num, vol, atten;
925 sound_num = (unsigned short) MSG_ReadShort ();
927 sound_num = MSG_ReadByte ();
928 vol = MSG_ReadByte ();
929 atten = MSG_ReadByte ();
931 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
934 void CL_ParseEffect (void)
937 int modelindex, startframe, framecount, framerate;
940 modelindex = MSG_ReadByte ();
941 startframe = MSG_ReadByte ();
942 framecount = MSG_ReadByte ();
943 framerate = MSG_ReadByte ();
945 CL_Effect(org, modelindex, startframe, framecount, framerate);
948 void CL_ParseEffect2 (void)
951 int modelindex, startframe, framecount, framerate;
954 modelindex = MSG_ReadShort ();
955 startframe = MSG_ReadShort ();
956 framecount = MSG_ReadByte ();
957 framerate = MSG_ReadByte ();
959 CL_Effect(org, modelindex, startframe, framecount, framerate);
963 #define SHOWNET(x) if(cl_shownet.integer==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
965 static qbyte cgamenetbuffer[65536];
968 =====================
969 CL_ParseServerMessage
970 =====================
972 void CL_ParseServerMessage (void)
975 int i, entitiesupdated;
977 char *cmdlogname[32], *temp;
978 int cmdindex, cmdcount = 0;
981 // if recording demos, copy the message out
983 if (cl_shownet.integer == 1)
984 Con_Printf ("%i ",net_message.cursize);
985 else if (cl_shownet.integer == 2)
986 Con_Printf ("------------------\n");
988 cl.onground = false; // unless the server says otherwise
994 entitiesupdated = false;
999 Host_Error ("CL_ParseServerMessage: Bad server message");
1001 cmd = MSG_ReadByte ();
1005 SHOWNET("END OF MESSAGE");
1006 break; // end of message
1009 cmdindex = cmdcount & 31;
1011 cmdlog[cmdindex] = cmd;
1013 // if the high bit of the command byte is set, it is a fast update
1016 // 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)
1018 cmdlogname[cmdindex] = temp;
1019 SHOWNET("fast update");
1020 if (cls.signon == SIGNONS - 1)
1022 // first update is the final signon stage
1023 cls.signon = SIGNONS;
1026 CL_ParseUpdate (cmd&127);
1030 SHOWNET(svc_strings[cmd]);
1031 cmdlogname[cmdindex] = svc_strings[cmd];
1032 if (!cmdlogname[cmdindex])
1034 // 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)
1036 cmdlogname[cmdindex] = temp;
1044 char description[32*64], temp[64];
1046 strcpy(description, "packet dump: ");
1050 count = cmdcount - i;
1054 sprintf(temp, "%3i:%s ", cmdlog[i], cmdlogname[i]);
1055 strcat(description, temp);
1060 description[strlen(description)-1] = '\n'; // replace the last space with a newline
1061 Con_Printf("%s", description);
1062 Host_Error ("CL_ParseServerMessage: Illegible server message\n");
1070 if (!entitiesupdated)
1072 // this is a new frame, we'll be seeing entities,
1073 // so prepare for entity updates
1074 CL_EntityUpdateSetup();
1075 entitiesupdated = true;
1077 cl.mtime[1] = cl.mtime[0];
1078 cl.mtime[0] = MSG_ReadFloat ();
1081 case svc_clientdata:
1082 i = MSG_ReadShort ();
1083 CL_ParseClientdata (i);
1087 i = MSG_ReadLong ();
1088 if (i != PROTOCOL_VERSION && i != DPPROTOCOL_VERSION1 && i != DPPROTOCOL_VERSION2 && i != DPPROTOCOL_VERSION3 && i != 250)
1089 Host_Error ("CL_ParseServerMessage: Server is protocol %i, not %i, %i, %i or %i", i, DPPROTOCOL_VERSION1, DPPROTOCOL_VERSION2, DPPROTOCOL_VERSION3, PROTOCOL_VERSION);
1090 Nehahrademcompatibility = false;
1092 Nehahrademcompatibility = true;
1093 if (cls.demoplayback && demo_nehahra.integer)
1094 Nehahrademcompatibility = true;
1096 if (dpprotocol != DPPROTOCOL_VERSION1 && dpprotocol != DPPROTOCOL_VERSION2 && dpprotocol != DPPROTOCOL_VERSION3)
1100 case svc_disconnect:
1101 Host_EndGame ("Server disconnected\n");
1104 Con_Printf ("%s", MSG_ReadString ());
1107 case svc_centerprint:
1108 SCR_CenterPrint (MSG_ReadString ());
1112 Cbuf_AddText (MSG_ReadString ());
1119 case svc_serverinfo:
1120 CL_ParseServerInfo ();
1124 for (i=0 ; i<3 ; i++)
1125 cl.viewangles[i] = MSG_ReadAngle ();
1129 cl.viewentity = MSG_ReadShort ();
1130 // LordHavoc: assume first setview recieved is the real player entity
1131 if (!cl.playerentity)
1132 cl.playerentity = cl.viewentity;
1135 case svc_lightstyle:
1136 i = MSG_ReadByte ();
1137 if (i >= MAX_LIGHTSTYLES)
1138 Host_Error ("svc_lightstyle >= MAX_LIGHTSTYLES");
1139 strncpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING - 1);
1140 cl_lightstyle[i].map[MAX_STYLESTRING - 1] = 0;
1141 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1145 CL_ParseStartSoundPacket(false);
1149 CL_ParseStartSoundPacket(true);
1153 i = MSG_ReadShort();
1154 S_StopSound(i>>3, i&7);
1157 case svc_updatename:
1158 i = MSG_ReadByte ();
1159 if (i >= cl.maxclients)
1160 Host_Error ("CL_ParseServerMessage: svc_updatename >= cl.maxclients");
1161 strcpy (cl.scores[i].name, MSG_ReadString ());
1164 case svc_updatefrags:
1165 i = MSG_ReadByte ();
1166 if (i >= cl.maxclients)
1167 Host_Error ("CL_ParseServerMessage: svc_updatefrags >= cl.maxclients");
1168 cl.scores[i].frags = MSG_ReadShort ();
1171 case svc_updatecolors:
1172 i = MSG_ReadByte ();
1173 if (i >= cl.maxclients)
1174 Host_Error ("CL_ParseServerMessage: svc_updatecolors >= cl.maxclients");
1175 cl.scores[i].colors = MSG_ReadByte ();
1176 // update our color cvar if our color changed
1177 if (i == cl.playerentity - 1)
1178 Cvar_SetValue ("_cl_color", cl.scores[i].colors);
1182 CL_ParseParticleEffect ();
1193 case svc_spawnbaseline:
1194 i = MSG_ReadShort ();
1195 if (i < 0 || i >= MAX_EDICTS)
1196 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline: invalid entity number %i", i);
1197 CL_ParseBaseline (cl_entities + i, false);
1199 case svc_spawnbaseline2:
1200 i = MSG_ReadShort ();
1201 if (i < 0 || i >= MAX_EDICTS)
1202 Host_Error ("CL_ParseServerMessage: svc_spawnbaseline2: invalid entity number %i", i);
1203 CL_ParseBaseline (cl_entities + i, true);
1205 case svc_spawnstatic:
1206 CL_ParseStatic (false);
1208 case svc_spawnstatic2:
1209 CL_ParseStatic (true);
1211 case svc_temp_entity:
1216 cl.paused = MSG_ReadByte ();
1224 i = MSG_ReadByte ();
1225 if (i <= cls.signon)
1226 Host_Error ("Received signon %i when at %i", i, cls.signon);
1231 case svc_killedmonster:
1232 cl.stats[STAT_MONSTERS]++;
1235 case svc_foundsecret:
1236 cl.stats[STAT_SECRETS]++;
1239 case svc_updatestat:
1240 i = MSG_ReadByte ();
1241 if (i < 0 || i >= MAX_CL_STATS)
1242 Host_Error ("svc_updatestat: %i is invalid", i);
1243 cl.stats[i] = MSG_ReadLong ();
1246 case svc_spawnstaticsound:
1247 CL_ParseStaticSound (false);
1250 case svc_spawnstaticsound2:
1251 CL_ParseStaticSound (true);
1255 cl.cdtrack = MSG_ReadByte ();
1256 cl.looptrack = MSG_ReadByte ();
1257 if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
1258 CDAudio_Play ((qbyte)cls.forcetrack, true);
1260 CDAudio_Play ((qbyte)cl.cdtrack, true);
1263 case svc_intermission:
1264 cl.intermission = 1;
1265 cl.completed_time = cl.time;
1269 cl.intermission = 2;
1270 cl.completed_time = cl.time;
1271 SCR_CenterPrint (MSG_ReadString ());
1275 cl.intermission = 3;
1276 cl.completed_time = cl.time;
1277 SCR_CenterPrint (MSG_ReadString ());
1280 case svc_sellscreen:
1281 Cmd_ExecuteString ("help", src_command);
1284 SHOWLMP_decodehide();
1287 SHOWLMP_decodeshow();
1290 R_SetSkyBox(MSG_ReadString());
1295 length = (int) ((unsigned short) MSG_ReadShort());
1296 for (i = 0;i < length;i++)
1297 cgamenetbuffer[i] = MSG_ReadByte();
1299 CL_CGVM_ParseNetwork(cgamenetbuffer, length);
1303 if (cls.signon == SIGNONS - 1)
1305 // first update is the final signon stage
1306 cls.signon = SIGNONS;
1309 CL_ReadEntityFrame();
1314 if (entitiesupdated)
1315 CL_EntityUpdateEnd();