1 /*
2 * cl_parse.c -- parse a message received from the server
3 * $Id: cl_parse.c 5899 2017-07-16 10:53:21Z bszili $
4 *
5 * Copyright (C) 1996-1997 Id Software, Inc.
6 * Copyright (C) 1997-1998 Raven Software Corp.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 *
17 * See the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #include "quakedef.h"
25 #include "bgmusic.h"
26 #include "cdaudio.h"
27 #include "r_shared.h"
28
29 static const char *svc_strings[] =
30 {
31 "svc_bad",
32 "svc_nop",
33 "svc_disconnect",
34 "svc_updatestat",
35 "svc_version", // [long] server version
36 "svc_setview", // [short] entity number
37 "svc_sound", // <see code>
38 "svc_time", // [float] server time
39 "svc_print", // [string] null terminated string
40 "svc_stufftext", // [string] stuffed into client's console buffer
41 // the string should be \n terminated
42 "svc_setangle", // [vec3] set the view angle to this absolute value
43
44 "svc_serverinfo", // [long] version
45 // [string] signon string
46 // [string]..[0]model cache [string]...[0]sounds cache
47 // [string]..[0]item cache
48 "svc_lightstyle", // [byte] [string]
49 "svc_updatename", // [byte] [string]
50 "svc_updatefrags", // [byte] [short]
51 "svc_clientdata", // <shortbits + data>
52 "svc_stopsound", // <see code>
53 "svc_updatecolors", // [byte] [byte]
54 "svc_particle", // [vec3] <variable>
55 "svc_damage", // [byte] impact [byte] blood [vec3] from
56
57 "svc_spawnstatic",
58 "svc_raineffect",
59 "svc_spawnbaseline",
60
61 "svc_temp_entity", // <variable>
62 "svc_setpause",
63 "svc_signonnum",
64 "svc_centerprint",
65 "svc_killedmonster",
66 "svc_foundsecret",
67 "svc_spawnstaticsound",
68 "svc_intermission",
69 "svc_finale", // [string] music [string] text
70 "svc_cdtrack", // [byte] track [byte] looptrack
71 "svc_sellscreen",
72 "svc_particle2", // [vec3] <variable>
73 "svc_cutscene",
74 "svc_midi_name",
75 "svc_updateclass", // [byte] client [byte] class
76 "svc_particle3",
77 "svc_particle4",
78 "svc_set_view_flags",
79 "svc_clear_view_flags",
80 "svc_start_effect",
81 "svc_end_effect",
82 "svc_plaque",
83 "svc_particle_explosion",
84 "svc_set_view_tint",
85 "svc_reference",
86 "svc_clear_edicts",
87 "svc_update_inv",
88 "svc_setangle_interpolate",
89 "svc_update_kingofhill",
90 "svc_toggle_statbar",
91 "svc_sound_update_pos",
92 "svc_mod_name", // UQE v1.13 by Korax, music file name
93 "svc_skybox" // UQE v1.13 by Korax, skybox name
94 };
95 #define NUM_SVC_STRINGS (sizeof(svc_strings) / sizeof(svc_strings[0]))
96
97 int cl_protocol; /* protocol version used by the server */
98 int LastServerMessageSize;
99
100 qmodel_t *player_models[MAX_PLAYER_CLASS];
101
102 extern cvar_t precache;
103 extern qboolean menu_disabled_mouse;
104
105
106 //=============================================================================
107
108
109 /*
110 ===============
111 CL_EntityNum
112
113 This error checks and tracks the total number of entities
114 ===============
115 */
CL_EntityNum(int num)116 static entity_t *CL_EntityNum (int num)
117 {
118 if (num >= cl.num_entities)
119 {
120 if (num >= MAX_EDICTS)
121 Host_Error ("%s: %i is an invalid number", __thisfunc__, num);
122 while (cl.num_entities <= num)
123 {
124 cl_entities[cl.num_entities].colormap = vid.colormap;
125 cl.num_entities++;
126 }
127 }
128
129 return &cl_entities[num];
130 }
131
132
133 /*
134 ==================
135 CL_ParseStartSoundPacket
136 ==================
137 */
CL_ParseStartSoundPacket(void)138 static void CL_ParseStartSoundPacket(void)
139 {
140 vec3_t pos;
141 int channel, ent;
142 int sound_num, volume, field_mask;
143 float attenuation;
144 int i;
145
146 field_mask = MSG_ReadByte();
147
148 if (field_mask & SND_VOLUME)
149 volume = MSG_ReadByte ();
150 else volume = DEFAULT_SOUND_PACKET_VOLUME;
151
152 if (field_mask & SND_ATTENUATION)
153 attenuation = MSG_ReadByte () / 64.0;
154 else attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
155
156 channel = MSG_ReadShort ();
157 sound_num = MSG_ReadByte ();
158 if (field_mask & SND_OVERFLOW)
159 sound_num += MAX_SOUNDS_OLD;
160 if (field_mask & SND_OVERFLOW2)
161 {
162 /* this means the server has MAX_SOUNDS > 512 (== 1024)
163 * and is sending it to us as a byte: Kor Skarn's code.
164 * UQE does this but I haven't seen this in real life yet.
165 * Currently not supported. TODO: in a newer protocol.
166 */
167 sound_num += MAX_SOUNDS_H2MP; /* +512 */
168 Con_DPrintf("%s: field_mask & SND_OVERFLOW2 (%d)\n", __thisfunc__, sound_num);
169 return;
170 }
171
172 ent = channel >> 3;
173 channel &= 7;
174
175 if (ent > MAX_EDICTS)
176 Host_Error ("%s: ent = %i", __thisfunc__, ent);
177
178 for (i = 0; i < 3; i++)
179 pos[i] = MSG_ReadCoord ();
180
181 S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
182 }
183
184 /*
185 ==================
186 CL_KeepaliveMessage
187
188 When the client is taking a long time to load stuff, send keepalive messages
189 so the server doesn't disconnect.
190 ==================
191 */
CL_KeepaliveMessage(void)192 static void CL_KeepaliveMessage (void)
193 {
194 float time;
195 static float lastmsg;
196 int ret;
197 sizebuf_t old;
198 byte olddata[NET_MAXMESSAGE];
199
200 if (sv.active)
201 return; // no need if server is local
202 if (cls.demoplayback)
203 return;
204
205 // read messages from server, should just be nops
206 old = net_message;
207 memcpy (olddata, net_message.data, net_message.cursize);
208
209 do
210 {
211 ret = CL_GetMessage ();
212 switch (ret)
213 {
214 default:
215 Host_Error ("%s: CL_GetMessage failed", __thisfunc__);
216 case 0:
217 break; // nothing waiting
218 case 1:
219 Host_Error ("%s: received a message", __thisfunc__);
220 break;
221 case 2:
222 if (MSG_ReadByte() != svc_nop)
223 Host_Error ("%s: datagram wasn't a nop", __thisfunc__);
224 break;
225 }
226 } while (ret);
227
228 net_message = old;
229 memcpy (net_message.data, olddata, net_message.cursize);
230
231 // check time
232 time = Sys_DoubleTime ();
233 if (time - lastmsg < 5)
234 return;
235 lastmsg = time;
236
237 // write out a nop
238 Con_Printf ("--> client to server keepalive\n");
239
240 MSG_WriteByte (&cls.message, clc_nop);
241 NET_SendMessage (cls.netcon, &cls.message);
242 SZ_Clear (&cls.message);
243 }
244
245 /*
246 ==================
247 CL_ParseServerInfo
248 ==================
249 */
CL_ParseServerInfo(void)250 static void CL_ParseServerInfo (void)
251 {
252 const char *str;
253 int i;
254 int nummodels, numsounds;
255 char model_precache[MAX_MODELS][MAX_QPATH];
256 char sound_precache[MAX_SOUNDS][MAX_QPATH];
257 // rjr edict_t *ent;
258
259 Con_DPrintf ("Serverinfo packet received.\n");
260
261 // bring up loading plaque for map changes within a demo.
262 // it will be hidden in CL_SignonReply() -- ericw
263 if (cls.demoplayback)
264 SCR_BeginLoadingPlaque();
265
266 //
267 // wipe the client_state_t struct
268 //
269 CL_ClearState ();
270
271 // parse protocol version number
272 cl_protocol = MSG_ReadLong ();
273 switch (cl_protocol)
274 {
275 case PROTOCOL_RAVEN_111:
276 case PROTOCOL_RAVEN_112:
277 case PROTOCOL_UQE_113:
278 Con_DPrintf ("\nServer using protocol %i\n", cl_protocol);
279 break;
280 default:
281 Con_Printf ("\nServer returned version %i, not %i or %i\n",
282 cl_protocol, PROTOCOL_RAVEN_112, PROTOCOL_UQE_113);
283 return;
284 }
285
286 // parse maxclients
287 cl.maxclients = MSG_ReadByte ();
288 if (cl.maxclients < 1 || cl.maxclients > MAX_CLIENTS)
289 {
290 Con_Printf("Bad maxclients (%d) from server\n", cl.maxclients);
291 return;
292 }
293 cl.scores = (scoreboard_t *) Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
294
295 // parse gametype
296 cl.gametype = MSG_ReadByte ();
297
298 if (cl.gametype == GAME_DEATHMATCH && cl_protocol > PROTOCOL_RAVEN_111)
299 sv_kingofhill = MSG_ReadShort ();
300
301 // parse signon message
302 str = MSG_ReadString ();
303 q_strlcpy (cl.levelname, str, sizeof(cl.levelname));
304
305 // seperate the printfs so the server message can have a color
306 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");
307 Con_Printf ("%c%s\n", 2, str);
308
309 //
310 // first we go through and touch all of the precache data that still
311 // happens to be in the cache, so precaching something else doesn't
312 // needlessly purge it
313 //
314
315 // precache models
316 memset (cl.model_precache, 0, sizeof(cl.model_precache));
317 for (nummodels = 1 ; ; nummodels++)
318 {
319 str = MSG_ReadString ();
320 if (!str[0])
321 break;
322 if (nummodels == MAX_MODELS)
323 {
324 Con_Printf ("Server sent too many model precaches\n");
325 return;
326 }
327 q_strlcpy (model_precache[nummodels], str, MAX_QPATH);
328 Mod_TouchModel (str);
329 }
330
331 // precache sounds
332 memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
333 for (numsounds = 1 ; ; numsounds++)
334 {
335 str = MSG_ReadString ();
336 if (!str[0])
337 break;
338 if (numsounds == MAX_SOUNDS)
339 {
340 Con_Printf ("Server sent too many sound precaches\n");
341 return;
342 }
343 q_strlcpy (sound_precache[numsounds], str, MAX_QPATH);
344 S_TouchSound (str);
345 }
346
347 //
348 // now we try to load everything else until a cache allocation fails
349 //
350
351 if (precache.integer)
352 {
353 total_loading_size = nummodels + numsounds;
354 current_loading_size = 1;
355 loading_stage = 2;
356 }
357
358 // copy the naked name of the map file to the cl structure
359 COM_FileBase (model_precache[1], cl.mapname, sizeof(cl.mapname));
360
361 //always precache the world!!!
362 cl.model_precache[1] = Mod_ForName (model_precache[1], false);
363 for (i = 2; i < nummodels; i++)
364 {
365 if (precache.integer)
366 {
367 cl.model_precache[i] = Mod_ForName (model_precache[i], false);
368 current_loading_size++;
369 D_ShowLoadingSize();
370 }
371 else
372 cl.model_precache[i] = (qmodel_t *)Mod_FindName (model_precache[i]);
373
374 if (cl.model_precache[i] == NULL)
375 {
376 Host_Error("Model %s not found", model_precache[i]);
377 return;
378 }
379 CL_KeepaliveMessage ();
380 }
381
382 player_models[0] = (qmodel_t *)Mod_FindName ("models/paladin.mdl");
383 player_models[1] = !(gameflags & GAME_OLD_DEMO) ? (qmodel_t *)Mod_FindName ("models/crusader.mdl") : NULL;
384 player_models[2] = !(gameflags & GAME_OLD_DEMO) ? (qmodel_t *)Mod_FindName ("models/necro.mdl") : NULL;
385 player_models[3] = (qmodel_t *)Mod_FindName ("models/assassin.mdl");
386 player_models[4] = (gameflags & GAME_PORTALS) ? (qmodel_t *)Mod_FindName ("models/succubus.mdl") : NULL;
387
388 S_BeginPrecaching ();
389 for (i = 1; i < numsounds; i++)
390 {
391 cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
392 if (precache.integer)
393 {
394 current_loading_size++;
395 D_ShowLoadingSize();
396 }
397
398 CL_KeepaliveMessage ();
399 }
400 S_EndPrecaching ();
401
402 total_loading_size = 0;
403 loading_stage = 0;
404
405 // local state
406 cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
407
408 R_NewMap ();
409
410 if (!sv.active)
411 Host_LoadStrings();
412 CL_LoadPuzzleStrings();
413 // mission pack, objectives strings
414 if (gameflags & GAME_PORTALS)
415 CL_LoadInfoStrings();
416
417 Hunk_Check (); // make sure nothing is hurt
418
419 // we connected to the server, make sure the mouse is going - S.A.
420 menu_disabled_mouse = false;
421 IN_ActivateMouse();
422 }
423
424
425 /*
426 ==================
427 CL_ParseUpdate
428
429 Parse an entity update message from the server
430 If an entities model or origin changes from frame to frame, it must be
431 relinked. Other attributes can change without relinking.
432 ==================
433 */
CL_ParseUpdate(int bits)434 static void CL_ParseUpdate (int bits)
435 {
436 int i;
437 qmodel_t *model;
438 int modnum;
439 qboolean forcelink;
440 entity_t *ent;
441 int num;
442 entity_state2_t *ref_ent, *set_ent, build_ent, dummy;
443
444 if (cls.signon == SIGNONS - 1)
445 { // first update is the final signon stage
446 cls.signon = SIGNONS;
447 CL_SignonReply ();
448 }
449
450 if (bits & U_MOREBITS)
451 {
452 i = MSG_ReadByte ();
453 bits |= (i<<8);
454 }
455
456 if (bits & U_MOREBITS2)
457 {
458 i = MSG_ReadByte ();
459 bits |= (i<<16);
460 }
461
462 if (bits & U_LONGENTITY)
463 num = MSG_ReadShort ();
464 else num = MSG_ReadByte ();
465
466 ent = CL_EntityNum (num);
467 ent->baseline.flags |= BE_ON;
468 ref_ent = NULL;
469
470 for (i = 0; i < cl.frames[0].count; i++)
471 {
472 if (cl.frames[0].states[i].index == num)
473 {
474 ref_ent = &cl.frames[0].states[i];
475 break;
476 }
477 }
478 if (!ref_ent)
479 {
480 ref_ent = &build_ent;
481
482 build_ent.index = num;
483 build_ent.origin[0] = ent->baseline.origin[0];
484 build_ent.origin[1] = ent->baseline.origin[1];
485 build_ent.origin[2] = ent->baseline.origin[2];
486 build_ent.angles[0] = ent->baseline.angles[0];
487 build_ent.angles[1] = ent->baseline.angles[1];
488 build_ent.angles[2] = ent->baseline.angles[2];
489 build_ent.modelindex = ent->baseline.modelindex;
490 build_ent.frame = ent->baseline.frame;
491 build_ent.colormap = ent->baseline.colormap;
492 build_ent.skin = ent->baseline.skin;
493 build_ent.effects = ent->baseline.effects;
494 build_ent.scale = ent->baseline.scale;
495 build_ent.drawflags = ent->baseline.drawflags;
496 build_ent.abslight = ent->baseline.abslight;
497 }
498
499 if (cl.need_build)
500 { // new sequence, first valid frame
501 set_ent = &cl.frames[1].states[cl.frames[1].count];
502 cl.frames[1].count++;
503 }
504 else
505 set_ent = &dummy;
506
507 if (bits & U_CLEAR_ENT)
508 {
509 memset(ent, 0, sizeof(entity_t));
510 memset(ref_ent, 0, sizeof(*ref_ent));
511 ref_ent->index = num;
512 }
513
514 *set_ent = *ref_ent;
515
516 if (ent->msgtime != cl.mtime[1])
517 forcelink = true; // no previous frame to lerp from
518 else forcelink = false;
519
520 ent->msgtime = cl.mtime[0];
521
522 if (bits & U_MODEL)
523 {
524 modnum = MSG_ReadShort ();
525 if (modnum >= MAX_MODELS)
526 Host_Error ("%s: bad modnum", __thisfunc__);
527 }
528 else modnum = ref_ent->modelindex;
529
530 model = cl.model_precache[modnum];
531 set_ent->modelindex = modnum;
532 if (model != ent->model)
533 {
534 ent->model = model;
535 // automatic animation (torches, etc) can
536 // be either all together or randomized
537 if (model)
538 {
539 if (model->synctype == ST_RAND)
540 ent->syncbase = rand() * (1.0 / RAND_MAX);//(float)(rand() & 0x7fff) / 0x7fff;
541 else ent->syncbase = 0.0;
542 }
543 else forcelink = true; // hack to make null model players work
544 #ifdef GLQUAKE
545 if (num > 0 && num <= cl.maxclients)
546 R_TranslatePlayerSkin (num - 1);
547 #endif
548 }
549
550 if (bits & U_FRAME)
551 set_ent->frame = ent->frame = MSG_ReadByte ();
552 else ent->frame = ref_ent->frame;
553
554 if (bits & U_COLORMAP)
555 set_ent->colormap = i = MSG_ReadByte();
556 else i = ref_ent->colormap;
557
558 if (num && num <= cl.maxclients)
559 ent->colormap = ent->sourcecolormap = cl.scores[num-1].translations;
560 else ent->sourcecolormap = vid.colormap;
561
562 #ifdef GLQUAKE
563 // ent->colormap = vid.colormap;
564 #endif
565
566 if (!i)
567 {
568 ent->colorshade = i;
569 ent->colormap = ent->sourcecolormap;
570 }
571 else
572 {
573 ent->colorshade = i;
574 #ifdef GLQUAKE
575 // ent->colormap = vid.colormap;
576 ent->colormap = globalcolormap;
577 #else
578 ent->colormap = globalcolormap;
579 #endif
580 }
581
582 if (bits & U_SKIN)
583 {
584 set_ent->skin = ent->skinnum = MSG_ReadByte();
585 set_ent->drawflags = ent->drawflags = MSG_ReadByte();
586 }
587 else
588 {
589 ent->skinnum = ref_ent->skin;
590 ent->drawflags = ref_ent->drawflags;
591 }
592
593 if (bits & U_EFFECTS)
594 set_ent->effects = ent->effects = MSG_ReadByte();
595 else ent->effects = ref_ent->effects;
596
597 // shift the known values for interpolation
598 VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
599 VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
600
601 if (bits & U_ORIGIN1)
602 set_ent->origin[0] = ent->msg_origins[0][0] = MSG_ReadCoord ();
603 else ent->msg_origins[0][0] = ref_ent->origin[0];
604
605 if (bits & U_ANGLE1)
606 set_ent->angles[0] = ent->msg_angles[0][0] = MSG_ReadAngle();
607 else ent->msg_angles[0][0] = ref_ent->angles[0];
608
609 if (bits & U_ORIGIN2)
610 set_ent->origin[1] = ent->msg_origins[0][1] = MSG_ReadCoord ();
611 else ent->msg_origins[0][1] = ref_ent->origin[1];
612
613 if (bits & U_ANGLE2)
614 set_ent->angles[1] = ent->msg_angles[0][1] = MSG_ReadAngle();
615 else ent->msg_angles[0][1] = ref_ent->angles[1];
616
617 if (bits & U_ORIGIN3)
618 set_ent->origin[2] = ent->msg_origins[0][2] = MSG_ReadCoord ();
619 else ent->msg_origins[0][2] = ref_ent->origin[2];
620
621 if (bits & U_ANGLE3)
622 set_ent->angles[2] = ent->msg_angles[0][2] = MSG_ReadAngle();
623 else ent->msg_angles[0][2] = ref_ent->angles[2];
624
625 if (bits & U_SCALE)
626 {
627 set_ent->scale = ent->scale = MSG_ReadByte();
628 set_ent->abslight = ent->abslight = MSG_ReadByte();
629 }
630 else
631 {
632 ent->scale = ref_ent->scale;
633 ent->abslight = ref_ent->abslight;
634 }
635
636 if (bits & U_NOLERP)
637 ent->forcelink = true;
638
639 if (forcelink)
640 { // didn't have an update last message
641 VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
642 VectorCopy (ent->msg_origins[0], ent->origin);
643 VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
644 VectorCopy (ent->msg_angles[0], ent->angles);
645 ent->forcelink = true;
646 }
647 }
648
CL_ParseUpdate2(int bits)649 static void CL_ParseUpdate2 (int bits)
650 {
651 int i;
652
653 if (bits & U_MOREBITS)
654 {
655 i = MSG_ReadByte ();
656 bits |= (i<<8);
657 }
658 if (bits & U_MOREBITS2)
659 {
660 i = MSG_ReadByte ();
661 bits |= (i<<16);
662 }
663 if (bits & U_LONGENTITY)
664 MSG_ReadShort ();
665 else MSG_ReadByte ();
666 if (bits & U_MODEL)
667 MSG_ReadShort ();
668 if (bits & U_FRAME)
669 MSG_ReadByte ();
670 if (bits & U_COLORMAP)
671 MSG_ReadByte();
672 if (bits & U_SKIN)
673 {
674 MSG_ReadByte();
675 MSG_ReadByte();
676 }
677 if (bits & U_EFFECTS)
678 MSG_ReadByte();
679 if (bits & U_ORIGIN1)
680 MSG_ReadCoord ();
681 if (bits & U_ANGLE1)
682 MSG_ReadAngle();
683 if (bits & U_ORIGIN2)
684 MSG_ReadCoord ();
685 if (bits & U_ANGLE2)
686 MSG_ReadAngle();
687 if (bits & U_ORIGIN3)
688 MSG_ReadCoord ();
689 if (bits & U_ANGLE3)
690 MSG_ReadAngle();
691 if (bits & U_SCALE)
692 {
693 MSG_ReadByte();
694 MSG_ReadByte();
695 }
696 }
697
698 /*
699 ==================
700 CL_ParseBaseline
701 ==================
702 */
CL_ParseBaseline(entity_t * ent)703 static void CL_ParseBaseline (entity_t *ent)
704 {
705 int i;
706
707 ent->baseline.modelindex = MSG_ReadShort ();
708 ent->baseline.frame = MSG_ReadByte ();
709 ent->baseline.colormap = MSG_ReadByte();
710 ent->baseline.skin = MSG_ReadByte();
711 ent->baseline.scale = MSG_ReadByte();
712 ent->baseline.drawflags = MSG_ReadByte();
713 ent->baseline.abslight = MSG_ReadByte();
714 for (i = 0; i < 3; i++)
715 {
716 ent->baseline.origin[i] = MSG_ReadCoord ();
717 ent->baseline.angles[i] = MSG_ReadAngle ();
718 }
719 }
720
721
722 /*
723 ==================
724 CL_ParseClientdata
725
726 Server information pertaining to this client only
727 ==================
728 */
CL_ParseClientdata(int bits)729 static void CL_ParseClientdata (int bits)
730 {
731 int i, j;
732
733 if (bits & SU_VIEWHEIGHT)
734 cl.viewheight = MSG_ReadChar ();
735 //rjr else cl.viewheight = DEFAULT_VIEWHEIGHT;
736
737 if (bits & SU_IDEALPITCH)
738 cl.idealpitch = MSG_ReadChar ();
739
740 if (bits & SU_IDEALROLL)
741 cl.idealroll = MSG_ReadChar ();
742 //rjr else cl.idealroll = 0;
743
744 VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
745 for (i = 0; i < 3; i++)
746 {
747 if (bits & (SU_PUNCH1<<i))
748 cl.punchangle[i] = MSG_ReadChar();
749 //rjr else cl.punchangle[i] = 0;
750 if (bits & (SU_VELOCITY1<<i))
751 cl.mvelocity[0][i] = MSG_ReadChar()*16;
752 //rjr else cl.mvelocity[0][i] = 0;
753 }
754
755 /*
756 if (bits & SU_ITEMS)
757 i = MSG_ReadLong ();
758 */
759
760 if (cl.items != i)
761 { // set flash times
762 Sbar_Changed();
763 for (j = 0; j < 32; j++)
764 if ((i & (1<<j)) && !(cl.items & (1<<j)))
765 cl.item_gettime[j] = cl.time;
766 cl.items = i;
767 }
768
769 cl.onground = ((bits & SU_ONGROUND) != 0);
770 cl.inwater = ((bits & SU_INWATER) != 0);
771
772 if (bits & SU_WEAPONFRAME)
773 cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
774 //rjr else cl.stats[STAT_WEAPONFRAME] = 0;
775
776 if (bits & SU_ARMOR)
777 {
778 cl.stats[STAT_ARMOR] = MSG_ReadByte ();
779 //Sbar_Changed();
780 }
781
782 if (bits & SU_WEAPON)
783 {
784 cl.stats[STAT_WEAPON] = MSG_ReadShort ();
785 //Sbar_Changed();
786 }
787
788 /*
789 sc1 = sc2 = 0;
790
791 if (bits & SU_SC1)
792 sc1 = MSG_ReadLong ();
793 if (bits & SU_SC2)
794 sc2 = MSG_ReadLong ();
795
796 if (sc1 & SC1_HEALTH)
797 cl.v.health = MSG_ReadShort();
798 if (sc1 & SC1_LEVEL)
799 cl.v.level = MSG_ReadByte();
800 if (sc1 & SC1_INTELLIGENCE)
801 cl.v.intelligence = MSG_ReadByte();
802 if (sc1 & SC1_WISDOM)
803 cl.v.wisdom = MSG_ReadByte();
804 if (sc1 & SC1_STRENGTH)
805 cl.v.strength = MSG_ReadByte();
806 if (sc1 & SC1_DEXTERITY)
807 cl.v.dexterity = MSG_ReadByte();
808 if (sc1 & SC1_WEAPON)
809 cl.v.weapon = MSG_ReadByte();
810 if (sc1 & SC1_BLUEMANA)
811 cl.v.bluemana = MSG_ReadByte();
812 if (sc1 & SC1_GREENMANA)
813 cl.v.greenmana = MSG_ReadByte();
814 if (sc1 & SC1_EXPERIENCE)
815 cl.v.experience = MSG_ReadLong();
816 if (sc1 & SC1_CNT_TORCH)
817 cl.v.cnt_torch = MSG_ReadByte();
818 if (sc1 & SC1_CNT_H_BOOST)
819 cl.v.cnt_h_boost = MSG_ReadByte();
820 if (sc1 & SC1_CNT_SH_BOOST)
821 cl.v.cnt_sh_boost = MSG_ReadByte();
822 if (sc1 & SC1_CNT_MANA_BOOST)
823 cl.v.cnt_mana_boost = MSG_ReadByte();
824 if (sc1 & SC1_CNT_TELEPORT)
825 cl.v.cnt_teleport = MSG_ReadByte();
826 if (sc1 & SC1_CNT_TOME)
827 cl.v.cnt_tome = MSG_ReadByte();
828 if (sc1 & SC1_CNT_SUMMON)
829 cl.v.cnt_summon = MSG_ReadByte();
830 if (sc1 & SC1_CNT_INVISIBILITY)
831 cl.v.cnt_invisibility = MSG_ReadByte();
832 if (sc1 & SC1_CNT_GLYPH)
833 cl.v.cnt_glyph = MSG_ReadByte();
834 if (sc1 & SC1_CNT_HASTE)
835 cl.v.cnt_haste = MSG_ReadByte();
836 if (sc1 & SC1_CNT_BLAST)
837 cl.v.cnt_blast = MSG_ReadByte();
838 if (sc1 & SC1_CNT_POLYMORPH)
839 cl.v.cnt_polymorph = MSG_ReadByte();
840 if (sc1 & SC1_CNT_FLIGHT)
841 cl.v.cnt_flight = MSG_ReadByte();
842 if (sc1 & SC1_CNT_CUBEOFFORCE)
843 cl.v.cnt_cubeofforce = MSG_ReadByte();
844 if (sc1 & SC1_CNT_INVINCIBILITY)
845 cl.v.cnt_invincibility = MSG_ReadByte();
846 if (sc1 & SC1_ARTIFACT_ACTIVE)
847 cl.v.artifact_active = MSG_ReadFloat();
848 if (sc1 & SC1_ARTIFACT_LOW)
849 cl.v.artifact_low = MSG_ReadFloat();
850 if (sc1 & SC1_MOVETYPE)
851 cl.v.movetype = MSG_ReadByte();
852 if (sc1 & SC1_CAMERAMODE)
853 cl.v.cameramode = MSG_ReadByte();
854 if (sc1 & SC1_HASTED)
855 cl.v.hasted = MSG_ReadFloat();
856 if (sc1 & SC1_INVENTORY)
857 cl.v.inventory = MSG_ReadByte();
858 if (sc1 & SC1_RINGS_ACTIVE)
859 cl.v.rings_active = MSG_ReadFloat();
860
861 if (sc2 & SC2_RINGS_LOW)
862 cl.v.rings_low = MSG_ReadFloat();
863 if (sc2 & SC2_AMULET)
864 cl.v.armor_amulet = MSG_ReadByte();
865 if (sc2 & SC2_BRACER)
866 cl.v.armor_bracer = MSG_ReadByte();
867 if (sc2 & SC2_BREASTPLATE)
868 cl.v.armor_breastplate = MSG_ReadByte();
869 if (sc2 & SC2_HELMET)
870 cl.v.armor_helmet = MSG_ReadByte();
871 if (sc2 & SC2_FLIGHT_T)
872 cl.v.ring_flight = MSG_ReadByte();
873 if (sc2 & SC2_WATER_T)
874 cl.v.ring_water = MSG_ReadByte();
875 if (sc2 & SC2_TURNING_T)
876 cl.v.ring_turning = MSG_ReadByte();
877 if (sc2 & SC2_REGEN_T)
878 cl.v.ring_regeneration = MSG_ReadByte();
879 if (sc2 & SC2_HASTE_T)
880 cl.v.haste_time = MSG_ReadFloat();
881 if (sc2 & SC2_TOME_T)
882 cl.v.tome_time = MSG_ReadFloat();
883 if (sc2 & SC2_PUZZLE1)
884 q_snprintf(cl.puzzle_pieces[0], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
885 if (sc2 & SC2_PUZZLE2)
886 q_snprintf(cl.puzzle_pieces[1], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
887 if (sc2 & SC2_PUZZLE3)
888 q_snprintf(cl.puzzle_pieces[2], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
889 if (sc2 & SC2_PUZZLE4)
890 q_snprintf(cl.puzzle_pieces[3], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
891 if (sc2 & SC2_PUZZLE5)
892 q_snprintf(cl.puzzle_pieces[4], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
893 if (sc2 & SC2_PUZZLE6)
894 q_snprintf(cl.puzzle_pieces[5], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
895 if (sc2 & SC2_PUZZLE7)
896 q_snprintf(cl.puzzle_pieces[6], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
897 if (sc2 & SC2_PUZZLE8)
898 q_snprintf(cl.puzzle_pieces[7], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
899 if (sc2 & SC2_MAXHEALTH)
900 cl.v.max_health = MSG_ReadShort();
901 if (sc2 & SC2_MAXMANA)
902 cl.v.max_mana = MSG_ReadByte();
903 if (sc2 & SC2_FLAGS)
904 cl.v.flags = MSG_ReadFloat();
905
906 if ((sc1 & SC1_STAT_BAR) || (sc2 & SC2_STAT_BAR))
907 Sbar_Changed();
908
909 if ((sc1 & SC1_INV) || (sc2 & SC2_INV))
910 SB_InvChanged();
911 */
912 }
913
914 /*
915 =====================
916 CL_NewTranslation
917 =====================
918 */
CL_NewTranslation(int slot)919 static void CL_NewTranslation (int slot)
920 {
921 #ifndef GLQUAKE
922 int i, j;
923 int top, bottom;
924 byte *dest, *source, *sourceA, *sourceB, *colorA, *colorB;
925 #endif
926
927 if (slot >= cl.maxclients)
928 Sys_Error ("%s: slot > cl.maxclients", __thisfunc__);
929 if (!cl.scores[slot].playerclass)
930 return;
931
932 #ifdef GLQUAKE
933 R_TranslatePlayerSkin (slot);
934 return;
935 #else
936
937 dest = cl.scores[slot].translations;
938 source = vid.colormap;
939 memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations));
940 top = (cl.scores[slot].colors & 0xf0) >> 4;
941 bottom = (cl.scores[slot].colors & 15);
942
943 if (top > 11 || bottom > 11)
944 Con_Printf("Invalid Player Color: %d,%d\n", top, bottom);
945 if (top > 10)
946 top = 0;
947 if (bottom > 10)
948 bottom = 0;
949 top -= 1;
950 bottom -= 1;
951
952 // Con_Printf("Class is %d for slot %d\n",(int)cl.scores[slot].playerclass,slot);
953 for (i = 0; i < VID_GRADES; i++, dest += 256, source += 256)
954 {
955 colorA = playerTranslation + 256 + color_offsets[(int)cl.scores[slot].playerclass-1];
956 colorB = colorA + 256;
957 sourceA = colorB + 256 + (top * 256);
958 sourceB = colorB + 256 + (bottom * 256);
959 for (j = 0; j < 256; j++, colorA++, colorB++, sourceA++, sourceB++)
960 {
961 if (top >= 0 && (*colorA != 255))
962 dest[j] = source[*sourceA];
963 if (bottom >= 0 && (*colorB != 255))
964 dest[j] = source[*sourceB];
965 }
966 }
967 #endif
968 }
969
970 /*
971 =====================
972 CL_ParseStatic
973 =====================
974 */
CL_ParseStatic(void)975 static void CL_ParseStatic (void)
976 {
977 entity_t *ent;
978 int i;
979
980 i = cl.num_statics;
981 if (i >= MAX_STATIC_ENTITIES)
982 Host_Error ("Too many static entities");
983 ent = &cl_static_entities[i];
984 cl.num_statics++;
985 CL_ParseBaseline (ent);
986
987 // copy it to the current state
988 ent->model = cl.model_precache[ent->baseline.modelindex];
989 ent->frame = ent->baseline.frame;
990 ent->colormap = vid.colormap;
991 ent->skinnum = ent->baseline.skin;
992 ent->scale = ent->baseline.scale;
993 ent->effects = ent->baseline.effects;
994 ent->drawflags = ent->baseline.drawflags;
995 ent->abslight = ent->baseline.abslight;
996
997 VectorCopy (ent->baseline.origin, ent->origin);
998 VectorCopy (ent->baseline.angles, ent->angles);
999 R_AddEfrags (ent);
1000 }
1001
1002 /*
1003 ===================
1004 CL_ParseStaticSound
1005 ===================
1006 */
CL_ParseStaticSound(void)1007 static void CL_ParseStaticSound (void)
1008 {
1009 vec3_t org;
1010 int sound_num, vol, atten;
1011 int i;
1012
1013 for (i = 0; i < 3; i++)
1014 org[i] = MSG_ReadCoord ();
1015
1016 if (cl_protocol == PROTOCOL_RAVEN_111)
1017 sound_num = MSG_ReadByte ();
1018 else sound_num = MSG_ReadShort();
1019 vol = MSG_ReadByte ();
1020 atten = MSG_ReadByte ();
1021
1022 S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
1023 }
1024
1025
CL_Plaque(void)1026 static void CL_Plaque(void)
1027 {
1028 int idx;
1029
1030 idx = MSG_ReadShort ();
1031
1032 if (idx > 0 && idx <= host_string_count)
1033 SCR_SetPlaqueMessage (Host_GetString(idx - 1));
1034 else SCR_SetPlaqueMessage ("");
1035 }
1036
CL_ParticleExplosion(void)1037 static void CL_ParticleExplosion(void)
1038 {
1039 vec3_t org;
1040 short color, radius, counter;
1041
1042 org[0] = MSG_ReadCoord();
1043 org[1] = MSG_ReadCoord();
1044 org[2] = MSG_ReadCoord();
1045 color = MSG_ReadShort();
1046 radius = MSG_ReadShort();
1047 counter = MSG_ReadShort();
1048
1049 R_ColoredParticleExplosion(org,color,radius,counter);
1050 }
1051
CL_ParseRainEffect(void)1052 static void CL_ParseRainEffect(void)
1053 {
1054 vec3_t org, e_size;
1055 short color,count;
1056 int x_dir, y_dir;
1057
1058 org[0] = MSG_ReadCoord();
1059 org[1] = MSG_ReadCoord();
1060 org[2] = MSG_ReadCoord();
1061 e_size[0] = MSG_ReadCoord();
1062 e_size[1] = MSG_ReadCoord();
1063 e_size[2] = MSG_ReadCoord();
1064 x_dir = MSG_ReadAngle();
1065 y_dir = MSG_ReadAngle();
1066 color = MSG_ReadShort();
1067 count = MSG_ReadShort();
1068
1069 R_RainEffect(org,e_size,x_dir,y_dir,color,count);
1070 }
1071
1072 #if 0 /* for debugging. from fteqw. */
1073 static void CL_DumpPacket (void)
1074 {
1075 int i, pos;
1076 char *packet = net_message.data;
1077
1078 Con_Printf("%s, BEGIN:\n", __thisfunc__);
1079 pos = 0;
1080 while (pos < net_message.cursize)
1081 {
1082 Con_Printf("%5i ", pos);
1083 for (i = 0; i < 16; i++)
1084 {
1085 if (pos >= net_message.cursize)
1086 Con_Printf(" X ");
1087 else Con_Printf("%2x ", (unsigned char)packet[pos]);
1088 pos++;
1089 }
1090 pos -= 16;
1091 for (i = 0; i < 16; i++)
1092 {
1093 if (pos >= net_message.cursize)
1094 Con_Printf("X");
1095 else if (packet[pos] == 0)
1096 Con_Printf(".");
1097 else Con_Printf("%c", (unsigned char)packet[pos]);
1098 pos++;
1099 }
1100 Con_Printf("\n");
1101 }
1102
1103 Con_Printf("%s, --- END ---\n", __thisfunc__);
1104 }
1105 #endif /* CL_DumpPacket */
1106
1107 #define SHOWNET(S) \
1108 do { \
1109 if (cl_shownet.integer == 2) \
1110 Con_Printf ("%3i:%s\n", msg_readcount-1, (S)); \
1111 } while (0)
1112
1113 /*
1114 =====================
1115 CL_ParseServerMessage
1116 =====================
1117 */
CL_ParseServerMessage(void)1118 void CL_ParseServerMessage (void)
1119 {
1120 int cmd;
1121 int i, j, k;
1122 int EntityCount = 0;
1123 int EntitySize = 0;
1124 int before;
1125 static double lasttime;
1126 static qboolean packet_loss = false;
1127 entity_t *ent;
1128 int sc1, sc2;
1129 byte test;
1130 float compangles[2][3];
1131 vec3_t deltaangles;
1132
1133 // if recording demos, copy the message out
1134 if (net_message.cursize > LastServerMessageSize)
1135 {
1136 LastServerMessageSize = net_message.cursize;
1137 }
1138 if (cl_shownet.integer == 1)
1139 {
1140 Con_Printf ("Time: %2.2f Pck: %i ", realtime - lasttime, net_message.cursize);
1141 lasttime = realtime;
1142 }
1143 else if (cl_shownet.integer == 2)
1144 {
1145 Con_Printf ("------------------\n");
1146 }
1147
1148 cl.onground = false; // unless the server says otherwise
1149
1150 // parse the message
1151 MSG_BeginReading ();
1152
1153 while (1)
1154 {
1155 if (msg_badread)
1156 Host_Error ("%s: Bad server message", __thisfunc__);
1157
1158 cmd = MSG_ReadByte ();
1159 if (cmd == -1)
1160 {
1161 if (cl_shownet.integer == 1)
1162 Con_Printf ("Ent: %i (%i bytes)", EntityCount, EntitySize);
1163 SHOWNET("END OF MESSAGE");
1164 return; // end of message
1165 }
1166
1167 // if the high bit of the command byte is set, it is a fast update
1168 if (cmd & 128)
1169 {
1170 before = msg_readcount;
1171 SHOWNET("fast update");
1172 if (packet_loss)
1173 CL_ParseUpdate2 (cmd & 127);
1174 else CL_ParseUpdate (cmd & 127);
1175
1176 EntityCount++;
1177 EntitySize += msg_readcount - before + 1;
1178 continue;
1179 }
1180
1181 if (cmd < (int)NUM_SVC_STRINGS) {
1182 SHOWNET(svc_strings[cmd]);
1183 }
1184
1185 // other commands
1186 switch (cmd)
1187 {
1188 default:
1189 // CL_DumpPacket ();
1190 Host_Error ("%s: Illegible server message %d", __thisfunc__, cmd);
1191 break;
1192
1193 case svc_nop:
1194 // Con_Printf ("svc_nop\n");
1195 break;
1196
1197 case svc_time:
1198 cl.mtime[1] = cl.mtime[0];
1199 cl.mtime[0] = MSG_ReadFloat ();
1200 break;
1201
1202 case svc_clientdata:
1203 i = MSG_ReadShort ();
1204 CL_ParseClientdata (i);
1205 break;
1206
1207 case svc_version:
1208 cl_protocol = MSG_ReadLong ();
1209 switch (cl_protocol)
1210 {
1211 case PROTOCOL_RAVEN_111:
1212 case PROTOCOL_RAVEN_112:
1213 case PROTOCOL_UQE_113:
1214 Con_Printf ("Server using protocol %i\n", cl_protocol);
1215 break;
1216 default:
1217 Host_Error ("%s: Server is protocol %i instead of %i or %i",
1218 __thisfunc__, cl_protocol,
1219 PROTOCOL_RAVEN_112, PROTOCOL_UQE_113);
1220 }
1221 break;
1222
1223 case svc_disconnect:
1224 Host_EndGame ("Server disconnected\n");
1225 break;
1226
1227 case svc_print:
1228 if (intro_playing) {
1229 MSG_ReadString ();
1230 break;
1231 }
1232 Con_Printf ("%s", MSG_ReadString ());
1233 break;
1234
1235 case svc_centerprint:
1236 SCR_CenterPrint (MSG_ReadString ());
1237 break;
1238
1239 case svc_stufftext:
1240 Cbuf_AddText (MSG_ReadString ());
1241 break;
1242
1243 case svc_damage:
1244 V_ParseDamage ();
1245 break;
1246
1247 case svc_serverinfo:
1248 CL_ParseServerInfo ();
1249 vid.recalc_refdef = true; // leave intermission full screen
1250 break;
1251
1252 case svc_setangle:
1253 for (i = 0; i < 3; i++)
1254 cl.viewangles[i] = MSG_ReadAngle ();
1255 break;
1256
1257 case svc_setangle_interpolate:
1258 compangles[0][0] = MSG_ReadAngle();
1259 compangles[0][1] = MSG_ReadAngle();
1260 compangles[0][2] = MSG_ReadAngle();
1261 for (i = 0; i < 3; i++)
1262 {
1263 compangles[1][i] = cl.viewangles[i];
1264 for (j = 0; j < 2; j++)
1265 {//standardize both old and new angles to +-180
1266 if (compangles[j][i] >= 360)
1267 compangles[j][i] -= 360*((int)(compangles[j][i]/360));
1268 else if (compangles[j][i] <= 360)
1269 compangles[j][i] += 360*(1+(int)(-compangles[j][i]/360));
1270 if (compangles[j][i] > 180)
1271 compangles[j][i] = -360 + compangles[j][i];
1272 else if (compangles[j][i] < -180)
1273 compangles[j][i] = 360 + compangles[j][i];
1274 }
1275 //get delta
1276 deltaangles[i] = compangles[0][i] - compangles[1][i];
1277 //cap delta to <=180,>=-180
1278 if (deltaangles[i] > 180)
1279 deltaangles[i] += -360;
1280 else if (deltaangles[i] < -180)
1281 deltaangles[i] += 360;
1282 //add the delta
1283 cl.viewangles[i]+=(deltaangles[i]/8);//8 step interpolation
1284 //cap newangles to +-180
1285 if (cl.viewangles[i] >= 360)
1286 cl.viewangles[i] -= 360*((int)(cl.viewangles[i]/360));
1287 else if (cl.viewangles[i] <= 360)
1288 cl.viewangles[i] += 360*(1+(int)(-cl.viewangles[i]/360));
1289 if (cl.viewangles[i] > 180)
1290 cl.viewangles[i] += -360;
1291 else if (cl.viewangles[i] < -180)
1292 cl.viewangles[i] += 360;
1293 }
1294 break;
1295
1296 case svc_setview:
1297 cl.viewentity = MSG_ReadShort ();
1298 break;
1299
1300 case svc_lightstyle:
1301 i = MSG_ReadByte ();
1302 if (i >= MAX_LIGHTSTYLES)
1303 Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
1304 q_strlcpy (cl_lightstyle[i].map, MSG_ReadString(), MAX_STYLESTRING);
1305 cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
1306 break;
1307
1308 case svc_sound:
1309 CL_ParseStartSoundPacket();
1310 break;
1311
1312 case svc_sound_update_pos:
1313 { // FIXME: put a field on the entity that lists the channels
1314 // it should update when it moves- if a certain flag
1315 // is on the ent, this update_channels field could
1316 // be set automatically by each sound and stopSound
1317 // called for this ent?
1318 vec3_t pos;
1319 int channel, ent_num;
1320
1321 channel = MSG_ReadShort ();
1322 ent_num = channel >> 3;
1323 channel &= 7;
1324
1325 if (ent_num > MAX_EDICTS)
1326 Host_Error ("svc_sound_update_pos: ent = %i", ent_num);
1327
1328 for (i = 0; i < 3; i++)
1329 pos[i] = MSG_ReadCoord ();
1330
1331 S_UpdateSoundPos (ent_num, channel, pos);
1332 } break;
1333
1334 case svc_stopsound:
1335 i = MSG_ReadShort();
1336 S_StopSound(i>>3, i&7);
1337 break;
1338
1339 case svc_updatename:
1340 Sbar_Changed();
1341 i = MSG_ReadByte ();
1342 if (i >= cl.maxclients)
1343 Host_Error ("%s: svc_updatename > MAX_CLIENTS", __thisfunc__);
1344 q_strlcpy (cl.scores[i].name, MSG_ReadString(), MAX_SCOREBOARDNAME);
1345 break;
1346
1347 case svc_updateclass:
1348 Sbar_Changed();
1349 i = MSG_ReadByte ();
1350 if (i >= cl.maxclients)
1351 Host_Error ("%s: svc_updateclass > MAX_CLIENTS", __thisfunc__);
1352 cl.scores[i].playerclass = (float)MSG_ReadByte();
1353 CL_NewTranslation(i); // update the color
1354 break;
1355
1356 case svc_updatefrags:
1357 Sbar_Changed();
1358 i = MSG_ReadByte ();
1359 if (i >= cl.maxclients)
1360 Host_Error ("%s: svc_updatefrags > MAX_CLIENTS", __thisfunc__);
1361 cl.scores[i].frags = MSG_ReadShort ();
1362 break;
1363
1364 case svc_update_kingofhill:
1365 sv_kingofhill = MSG_ReadShort() - 1;
1366 break;
1367
1368 case svc_updatecolors:
1369 Sbar_Changed();
1370 i = MSG_ReadByte ();
1371 if (i >= cl.maxclients)
1372 Host_Error ("%s: svc_updatecolors > MAX_CLIENTS", __thisfunc__);
1373 cl.scores[i].colors = MSG_ReadByte ();
1374 CL_NewTranslation (i);
1375 break;
1376
1377 case svc_particle:
1378 R_ParseParticleEffect ();
1379 break;
1380
1381 case svc_particle2:
1382 R_ParseParticleEffect2 ();
1383 break;
1384 case svc_particle3:
1385 R_ParseParticleEffect3 ();
1386 break;
1387 case svc_particle4:
1388 R_ParseParticleEffect4 ();
1389 break;
1390
1391 case svc_spawnbaseline:
1392 i = MSG_ReadShort ();
1393 // must use CL_EntityNum() to force cl.num_entities up
1394 CL_ParseBaseline (CL_EntityNum(i));
1395 break;
1396 case svc_spawnstatic:
1397 CL_ParseStatic ();
1398 break;
1399
1400 case svc_raineffect:
1401 CL_ParseRainEffect();
1402 break;
1403
1404 case svc_temp_entity:
1405 CL_ParseTEnt ();
1406 break;
1407
1408 case svc_setpause:
1409 cl.paused = MSG_ReadByte ();
1410 if (cl.paused)
1411 {
1412 CDAudio_Pause ();
1413 BGM_Pause ();
1414 VID_HandlePause (true);
1415 }
1416 else
1417 {
1418 CDAudio_Resume ();
1419 BGM_Resume ();
1420 VID_HandlePause (false);
1421 }
1422 break;
1423
1424 case svc_signonnum:
1425 i = MSG_ReadByte ();
1426 if (i <= cls.signon)
1427 Host_Error ("Received signon %i when at %i", i, cls.signon);
1428 cls.signon = i;
1429 CL_SignonReply ();
1430 break;
1431
1432 case svc_killedmonster:
1433 cl.stats[STAT_MONSTERS]++;
1434 break;
1435
1436 case svc_foundsecret:
1437 cl.stats[STAT_SECRETS]++;
1438 break;
1439
1440 case svc_updatestat:
1441 i = MSG_ReadByte ();
1442 if (i < 0 || i >= MAX_CL_STATS)
1443 Sys_Error ("svc_updatestat: %i is invalid", i);
1444 cl.stats[i] = MSG_ReadLong ();
1445 break;
1446
1447 case svc_spawnstaticsound:
1448 CL_ParseStaticSound ();
1449 break;
1450
1451 case svc_cdtrack:
1452 cl.cdtrack = MSG_ReadByte ();
1453 cl.looptrack = MSG_ReadByte ();
1454 if (q_strcasecmp(bgmtype.string,"cd") != 0)
1455 CDAudio_Stop ();
1456 else if ((cls.demoplayback || cls.demorecording) &&
1457 cls.forcetrack != -1)
1458 CDAudio_Play ((byte)cls.forcetrack, true);
1459 else CDAudio_Play ((byte)cl.cdtrack, true);
1460 break;
1461
1462 case svc_midi_name:
1463 q_strlcpy (cl.midi_name, MSG_ReadString(), sizeof(cl.midi_name));
1464 if (q_strcasecmp(bgmtype.string,"midi") != 0)
1465 BGM_Stop();
1466 else BGM_PlayMIDIorMusic(cl.midi_name);
1467 break;
1468
1469 case svc_toggle_statbar:
1470 break;
1471
1472 case svc_intermission:
1473 CL_SetupIntermission (MSG_ReadByte());
1474 vid.recalc_refdef = true; // go to full screen
1475 break;
1476
1477 /*
1478 case svc_finale:
1479 cl.intermission = 2;
1480 cl.completed_time = cl.time;
1481 vid.recalc_refdef = true; // go to full screen
1482 SCR_CenterPrint (MSG_ReadString ());
1483 break;
1484
1485 case svc_cutscene:
1486 cl.intermission = 3;
1487 cl.completed_time = cl.time;
1488 vid.recalc_refdef = true; // go to full screen
1489 SCR_CenterPrint (MSG_ReadString ());
1490 break;
1491
1492 case svc_sellscreen:
1493 Cmd_ExecuteString ("help", src_command);
1494 break;
1495 */
1496
1497 case svc_set_view_flags:
1498 cl.viewent.drawflags |= MSG_ReadByte();
1499 break;
1500
1501 case svc_clear_view_flags:
1502 cl.viewent.drawflags &= ~MSG_ReadByte();
1503 break;
1504
1505 case svc_start_effect:
1506 CL_ParseEffect();
1507 break;
1508 case svc_end_effect:
1509 CL_EndEffect();
1510 break;
1511
1512 case svc_plaque:
1513 CL_Plaque();
1514 break;
1515
1516 case svc_particle_explosion:
1517 CL_ParticleExplosion();
1518 break;
1519
1520 case svc_set_view_tint:
1521 i = MSG_ReadByte();
1522 cl.viewent.colorshade = i;
1523 break;
1524
1525 case svc_reference:
1526 { short RemovePlace, OrigPlace, NewPlace, AddedIndex;
1527
1528 packet_loss = false;
1529 cl.last_frame = cl.current_frame;
1530 cl.last_sequence = cl.current_sequence;
1531 cl.current_frame = MSG_ReadByte();
1532 cl.current_sequence = MSG_ReadByte();
1533 if (cl.need_build == 2)
1534 {
1535 // Con_Printf("CL: NB2 CL(%d,%d) R(%d)\n",
1536 // cl.current_sequence, cl.current_frame, cl.reference_frame);
1537 cl.frames[0].count = cl.frames[1].count = cl.frames[2].count = 0;
1538 cl.need_build = 1;
1539 cl.reference_frame = cl.current_frame;
1540 }
1541 else if (cl.last_sequence != cl.current_sequence)
1542 {
1543 // Con_Printf("CL: Sequence CL(%d,%d) R(%d)\n",
1544 // cl.current_sequence, cl.current_frame, cl.reference_frame);
1545 if (cl.reference_frame >= 1 && cl.reference_frame <= MAX_FRAMES)
1546 {
1547 RemovePlace = OrigPlace = NewPlace = AddedIndex = 0;
1548 for (i = 0; i < cl.num_entities; i++)
1549 {
1550 if (RemovePlace >= cl.NumToRemove ||
1551 cl.RemoveList[RemovePlace] != i)
1552 {
1553 if (NewPlace < cl.frames[1].count &&
1554 cl.frames[1].states[NewPlace].index == i)
1555 {
1556 cl.frames[2].states[AddedIndex] =
1557 cl.frames[1].states[NewPlace];
1558 AddedIndex++;
1559 cl.frames[2].count++;
1560 }
1561 else if (OrigPlace < cl.frames[0].count &&
1562 cl.frames[0].states[OrigPlace].index == i)
1563 {
1564 cl.frames[2].states[AddedIndex] =
1565 cl.frames[0].states[OrigPlace];
1566 AddedIndex++;
1567 cl.frames[2].count++;
1568 }
1569 }
1570 else RemovePlace++;
1571
1572 if (cl.frames[0].states[OrigPlace].index == i)
1573 OrigPlace++;
1574 if (cl.frames[1].states[NewPlace].index == i)
1575 NewPlace++;
1576 }
1577 cl.frames[0] = cl.frames[2];
1578 }
1579 cl.frames[1].count = cl.frames[2].count = 0;
1580 cl.need_build = 1;
1581 cl.reference_frame = cl.current_frame;
1582 }
1583 else
1584 {
1585 // Con_Printf("CL: Normal CL(%d,%d) R(%d)\n",
1586 // cl.current_sequence, cl.current_frame,cl.reference_frame);
1587 cl.need_build = 0;
1588 }
1589
1590 for (i = 1, ent = cl_entities+1; i < cl.num_entities; i++, ent++)
1591 ent->baseline.flags &= ~BE_ON;
1592 for (i = 0; i < cl.frames[0].count; i++)
1593 {
1594 ent = CL_EntityNum (cl.frames[0].states[i].index);
1595 ent->model = cl.model_precache[cl.frames[0].states[i].modelindex];
1596 ent->baseline.flags |= BE_ON;
1597 }
1598 } break;
1599
1600 case svc_clear_edicts:
1601 j = MSG_ReadByte();
1602 if (cl.need_build)
1603 cl.NumToRemove = j;
1604 for (i = 0; i < j; i++)
1605 {
1606 k = MSG_ReadShort();
1607 if (cl.need_build)
1608 cl.RemoveList[i] = k;
1609 ent = CL_EntityNum (k);
1610 ent->baseline.flags &= ~BE_ON;
1611 }
1612 break;
1613
1614 case svc_update_inv:
1615 sc1 = sc2 = 0;
1616
1617 test = MSG_ReadByte();
1618 if (test & 1)
1619 sc1 |= ((int)MSG_ReadByte());
1620 if (test & 2)
1621 sc1 |= ((int)MSG_ReadByte())<<8;
1622 if (test & 4)
1623 sc1 |= ((int)MSG_ReadByte())<<16;
1624 if (test & 8)
1625 sc1 |= ((int)MSG_ReadByte())<<24;
1626 if (test & 16)
1627 sc2 |= ((int)MSG_ReadByte());
1628 if (test & 32)
1629 sc2 |= ((int)MSG_ReadByte())<<8;
1630 if (test & 64)
1631 sc2 |= ((int)MSG_ReadByte())<<16;
1632 if (test & 128)
1633 sc2 |= ((int)MSG_ReadByte())<<24;
1634
1635 if (sc1 & SC1_HEALTH)
1636 cl.v.health = MSG_ReadShort();
1637 if (sc1 & SC1_LEVEL)
1638 cl.v.level = MSG_ReadByte();
1639 if (sc1 & SC1_INTELLIGENCE)
1640 cl.v.intelligence = MSG_ReadByte();
1641 if (sc1 & SC1_WISDOM)
1642 cl.v.wisdom = MSG_ReadByte();
1643 if (sc1 & SC1_STRENGTH)
1644 cl.v.strength = MSG_ReadByte();
1645 if (sc1 & SC1_DEXTERITY)
1646 cl.v.dexterity = MSG_ReadByte();
1647 if (sc1 & SC1_WEAPON)
1648 cl.v.weapon = MSG_ReadByte();
1649 if (sc1 & SC1_BLUEMANA)
1650 cl.v.bluemana = MSG_ReadByte();
1651 if (sc1 & SC1_GREENMANA)
1652 cl.v.greenmana = MSG_ReadByte();
1653 if (sc1 & SC1_EXPERIENCE)
1654 cl.v.experience = MSG_ReadLong();
1655 if (sc1 & SC1_CNT_TORCH)
1656 cl.v.cnt_torch = MSG_ReadByte();
1657 if (sc1 & SC1_CNT_H_BOOST)
1658 cl.v.cnt_h_boost = MSG_ReadByte();
1659 if (sc1 & SC1_CNT_SH_BOOST)
1660 cl.v.cnt_sh_boost = MSG_ReadByte();
1661 if (sc1 & SC1_CNT_MANA_BOOST)
1662 cl.v.cnt_mana_boost = MSG_ReadByte();
1663 if (sc1 & SC1_CNT_TELEPORT)
1664 cl.v.cnt_teleport = MSG_ReadByte();
1665 if (sc1 & SC1_CNT_TOME)
1666 cl.v.cnt_tome = MSG_ReadByte();
1667 if (sc1 & SC1_CNT_SUMMON)
1668 cl.v.cnt_summon = MSG_ReadByte();
1669 if (sc1 & SC1_CNT_INVISIBILITY)
1670 cl.v.cnt_invisibility = MSG_ReadByte();
1671 if (sc1 & SC1_CNT_GLYPH)
1672 cl.v.cnt_glyph = MSG_ReadByte();
1673 if (sc1 & SC1_CNT_HASTE)
1674 cl.v.cnt_haste = MSG_ReadByte();
1675 if (sc1 & SC1_CNT_BLAST)
1676 cl.v.cnt_blast = MSG_ReadByte();
1677 if (sc1 & SC1_CNT_POLYMORPH)
1678 cl.v.cnt_polymorph = MSG_ReadByte();
1679 if (sc1 & SC1_CNT_FLIGHT)
1680 cl.v.cnt_flight = MSG_ReadByte();
1681 if (sc1 & SC1_CNT_CUBEOFFORCE)
1682 cl.v.cnt_cubeofforce = MSG_ReadByte();
1683 if (sc1 & SC1_CNT_INVINCIBILITY)
1684 cl.v.cnt_invincibility = MSG_ReadByte();
1685 if (sc1 & SC1_ARTIFACT_ACTIVE)
1686 cl.v.artifact_active = MSG_ReadFloat();
1687 if (sc1 & SC1_ARTIFACT_LOW)
1688 cl.v.artifact_low = MSG_ReadFloat();
1689 if (sc1 & SC1_MOVETYPE)
1690 cl.v.movetype = MSG_ReadByte();
1691 if (sc1 & SC1_CAMERAMODE)
1692 cl.v.cameramode = MSG_ReadByte();
1693 if (sc1 & SC1_HASTED)
1694 cl.v.hasted = MSG_ReadFloat();
1695 if (sc1 & SC1_INVENTORY)
1696 cl.v.inventory = MSG_ReadByte();
1697 if (sc1 & SC1_RINGS_ACTIVE)
1698 cl.v.rings_active = MSG_ReadFloat();
1699
1700 if (sc2 & SC2_RINGS_LOW)
1701 cl.v.rings_low = MSG_ReadFloat();
1702 if (sc2 & SC2_AMULET)
1703 cl.v.armor_amulet = MSG_ReadByte();
1704 if (sc2 & SC2_BRACER)
1705 cl.v.armor_bracer = MSG_ReadByte();
1706 if (sc2 & SC2_BREASTPLATE)
1707 cl.v.armor_breastplate = MSG_ReadByte();
1708 if (sc2 & SC2_HELMET)
1709 cl.v.armor_helmet = MSG_ReadByte();
1710 if (sc2 & SC2_FLIGHT_T)
1711 cl.v.ring_flight = MSG_ReadByte();
1712 if (sc2 & SC2_WATER_T)
1713 cl.v.ring_water = MSG_ReadByte();
1714 if (sc2 & SC2_TURNING_T)
1715 cl.v.ring_turning = MSG_ReadByte();
1716 if (sc2 & SC2_REGEN_T)
1717 cl.v.ring_regeneration = MSG_ReadByte();
1718 if (sc2 & SC2_HASTE_T)
1719 cl.v.haste_time = MSG_ReadFloat();
1720 if (sc2 & SC2_TOME_T)
1721 cl.v.tome_time = MSG_ReadFloat();
1722 if (sc2 & SC2_PUZZLE1)
1723 q_snprintf(cl.puzzle_pieces[0], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1724 if (sc2 & SC2_PUZZLE2)
1725 q_snprintf(cl.puzzle_pieces[1], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1726 if (sc2 & SC2_PUZZLE3)
1727 q_snprintf(cl.puzzle_pieces[2], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1728 if (sc2 & SC2_PUZZLE4)
1729 q_snprintf(cl.puzzle_pieces[3], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1730 if (sc2 & SC2_PUZZLE5)
1731 q_snprintf(cl.puzzle_pieces[4], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1732 if (sc2 & SC2_PUZZLE6)
1733 q_snprintf(cl.puzzle_pieces[5], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1734 if (sc2 & SC2_PUZZLE7)
1735 q_snprintf(cl.puzzle_pieces[6], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1736 if (sc2 & SC2_PUZZLE8)
1737 q_snprintf(cl.puzzle_pieces[7], sizeof(cl.puzzle_pieces[0]), "%.9s", MSG_ReadString());
1738 if (sc2 & SC2_MAXHEALTH)
1739 cl.v.max_health = MSG_ReadShort();
1740 if (sc2 & SC2_MAXMANA)
1741 cl.v.max_mana = MSG_ReadByte();
1742 if (sc2 & SC2_FLAGS)
1743 cl.v.flags = MSG_ReadFloat();
1744
1745 /* SC2_OBJ, SC2_OBJ2: mission pack objectives
1746 * With protocol 18 (PROTOCOL_RAVEN_111), these
1747 * bits get set somehow (?!): let's avoid them. */
1748 if (cl_protocol > PROTOCOL_RAVEN_111)
1749 {
1750 if (sc2 & SC2_OBJ)
1751 cl.info_mask = MSG_ReadLong();
1752 if (sc2 & SC2_OBJ2)
1753 cl.info_mask2 = MSG_ReadLong();
1754 }
1755
1756 if ((sc1 & SC1_STAT_BAR) || (sc2 & SC2_STAT_BAR))
1757 Sbar_Changed();
1758
1759 if ((sc1 & SC1_INV) || (sc2 & SC2_INV))
1760 SB_InvChanged();
1761 break;
1762
1763 case svc_mod_name:
1764 case svc_skybox:
1765 MSG_ReadString();
1766 Con_DPrintf ("Ignored server msg %d (%s)\n", cmd, svc_strings[cmd]);
1767 break;
1768 }
1769 }
1770 }
1771
1772