Home | History | Annotate | Download | only in client
      1 /*
      2 Copyright (C) 1996-1997 Id Software, Inc.
      3 
      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.
      8 
      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.
     12 
     13 See the GNU General Public License for more details.
     14 
     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.
     18 
     19 */
     20 // cl_ents.c -- entity parsing and management
     21 
     22 #include "quakedef.h"
     23 
     24 extern	cvar_t	cl_predict_players;
     25 extern	cvar_t	cl_predict_players2;
     26 extern	cvar_t	cl_solid_players;
     27 
     28 static struct predicted_player {
     29 	int flags;
     30 	qboolean active;
     31 	vec3_t origin;	// predicted origin
     32 } predicted_players[MAX_CLIENTS];
     33 
     34 //============================================================
     35 
     36 /*
     37 ===============
     38 CL_AllocDlight
     39 
     40 ===============
     41 */
     42 dlight_t *CL_AllocDlight (int key)
     43 {
     44 	int		i;
     45 	dlight_t	*dl;
     46 
     47 // first look for an exact key match
     48 	if (key)
     49 	{
     50 		dl = cl_dlights;
     51 		for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
     52 		{
     53 			if (dl->key == key)
     54 			{
     55 				memset (dl, 0, sizeof(*dl));
     56 				dl->key = key;
     57 				return dl;
     58 			}
     59 		}
     60 	}
     61 
     62 // then look for anything else
     63 	dl = cl_dlights;
     64 	for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
     65 	{
     66 		if (dl->die < cl.time)
     67 		{
     68 			memset (dl, 0, sizeof(*dl));
     69 			dl->key = key;
     70 			return dl;
     71 		}
     72 	}
     73 
     74 	dl = &cl_dlights[0];
     75 	memset (dl, 0, sizeof(*dl));
     76 	dl->key = key;
     77 	return dl;
     78 }
     79 
     80 /*
     81 ===============
     82 CL_NewDlight
     83 ===============
     84 */
     85 void CL_NewDlight (int key, float x, float y, float z, float radius, float time,
     86 				   int type)
     87 {
     88 	dlight_t	*dl;
     89 
     90 	dl = CL_AllocDlight (key);
     91 	dl->origin[0] = x;
     92 	dl->origin[1] = y;
     93 	dl->origin[2] = z;
     94 	dl->radius = radius;
     95 	dl->die = cl.time + time;
     96 	if (type == 0) {
     97 		dl->color[0] = 0.2;
     98 		dl->color[1] = 0.1;
     99 		dl->color[2] = 0.05;
    100 		dl->color[3] = 0.7;
    101 	} else if (type == 1) {
    102 		dl->color[0] = 0.05;
    103 		dl->color[1] = 0.05;
    104 		dl->color[2] = 0.3;
    105 		dl->color[3] = 0.7;
    106 	} else if (type == 2) {
    107 		dl->color[0] = 0.5;
    108 		dl->color[1] = 0.05;
    109 		dl->color[2] = 0.05;
    110 		dl->color[3] = 0.7;
    111 	} else if (type == 3) {
    112 		dl->color[0]=0.5;
    113 		dl->color[1] = 0.05;
    114 		dl->color[2] = 0.4;
    115 		dl->color[3] = 0.7;
    116 	}
    117 }
    118 
    119 
    120 /*
    121 ===============
    122 CL_DecayLights
    123 
    124 ===============
    125 */
    126 void CL_DecayLights (void)
    127 {
    128 	int			i;
    129 	dlight_t	*dl;
    130 
    131 	dl = cl_dlights;
    132 	for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
    133 	{
    134 		if (dl->die < cl.time || !dl->radius)
    135 			continue;
    136 
    137 		dl->radius -= host_frametime*dl->decay;
    138 		if (dl->radius < 0)
    139 			dl->radius = 0;
    140 	}
    141 }
    142 
    143 
    144 /*
    145 =========================================================================
    146 
    147 PACKET ENTITY PARSING / LINKING
    148 
    149 =========================================================================
    150 */
    151 
    152 /*
    153 ==================
    154 CL_ParseDelta
    155 
    156 Can go from either a baseline or a previous packet_entity
    157 ==================
    158 */
    159 int	bitcounts[32];	/// just for protocol profiling
    160 void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits)
    161 {
    162 	int			i;
    163 
    164 	// set everything to the state we are delta'ing from
    165 	*to = *from;
    166 
    167 	to->number = bits & 511;
    168 	bits &= ~511;
    169 
    170 	if (bits & U_MOREBITS)
    171 	{	// read in the low order bits
    172 		i = MSG_ReadByte ();
    173 		bits |= i;
    174 	}
    175 
    176 	// count the bits for net profiling
    177 	for (i=0 ; i<16 ; i++)
    178 		if (bits&(1<<i))
    179 			bitcounts[i]++;
    180 
    181 	to->flags = bits;
    182 
    183 	if (bits & U_MODEL)
    184 		to->modelindex = MSG_ReadByte ();
    185 
    186 	if (bits & U_FRAME)
    187 		to->frame = MSG_ReadByte ();
    188 
    189 	if (bits & U_COLORMAP)
    190 		to->colormap = MSG_ReadByte();
    191 
    192 	if (bits & U_SKIN)
    193 		to->skinnum = MSG_ReadByte();
    194 
    195 	if (bits & U_EFFECTS)
    196 		to->effects = MSG_ReadByte();
    197 
    198 	if (bits & U_ORIGIN1)
    199 		to->origin[0] = MSG_ReadCoord ();
    200 
    201 	if (bits & U_ANGLE1)
    202 		to->angles[0] = MSG_ReadAngle();
    203 
    204 	if (bits & U_ORIGIN2)
    205 		to->origin[1] = MSG_ReadCoord ();
    206 
    207 	if (bits & U_ANGLE2)
    208 		to->angles[1] = MSG_ReadAngle();
    209 
    210 	if (bits & U_ORIGIN3)
    211 		to->origin[2] = MSG_ReadCoord ();
    212 
    213 	if (bits & U_ANGLE3)
    214 		to->angles[2] = MSG_ReadAngle();
    215 
    216 	if (bits & U_SOLID)
    217 	{
    218 		// FIXME
    219 	}
    220 }
    221 
    222 
    223 /*
    224 =================
    225 FlushEntityPacket
    226 =================
    227 */
    228 void FlushEntityPacket (void)
    229 {
    230 	int			word;
    231 	entity_state_t	olde, newe;
    232 
    233 	Con_DPrintf ("FlushEntityPacket\n");
    234 
    235 	memset (&olde, 0, sizeof(olde));
    236 
    237 	cl.validsequence = 0;		// can't render a frame
    238 	cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].invalid = true;
    239 
    240 	// read it all, but ignore it
    241 	while (1)
    242 	{
    243 		word = (unsigned short)MSG_ReadShort ();
    244 		if (msg_badread)
    245 		{	// something didn't parse right...
    246 			Host_EndGame ("msg_badread in packetentities");
    247 			return;
    248 		}
    249 
    250 		if (!word)
    251 			break;	// done
    252 
    253 		CL_ParseDelta (&olde, &newe, word);
    254 	}
    255 }
    256 
    257 /*
    258 ==================
    259 CL_ParsePacketEntities
    260 
    261 An svc_packetentities has just been parsed, deal with the
    262 rest of the data stream.
    263 ==================
    264 */
    265 void CL_ParsePacketEntities (qboolean delta)
    266 {
    267 	int			oldpacket, newpacket;
    268 	packet_entities_t	*oldp, *newp, dummy;
    269 	int			oldindex, newindex;
    270 	int			word, newnum, oldnum;
    271 	qboolean	full;
    272 	byte		from;
    273 
    274 	newpacket = cls.netchan.incoming_sequence&UPDATE_MASK;
    275 	newp = &cl.frames[newpacket].packet_entities;
    276 	cl.frames[newpacket].invalid = false;
    277 
    278 	if (delta)
    279 	{
    280 		from = MSG_ReadByte ();
    281 
    282 		oldpacket = cl.frames[newpacket].delta_sequence;
    283 
    284 		if ( (from&UPDATE_MASK) != (oldpacket&UPDATE_MASK) )
    285 			Con_DPrintf ("WARNING: from mismatch\n");
    286 	}
    287 	else
    288 		oldpacket = -1;
    289 
    290 	full = false;
    291 	if (oldpacket != -1)
    292 	{
    293 		if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP-1)
    294 		{	// we can't use this, it is too old
    295 			FlushEntityPacket ();
    296 			return;
    297 		}
    298 		cl.validsequence = cls.netchan.incoming_sequence;
    299 		oldp = &cl.frames[oldpacket&UPDATE_MASK].packet_entities;
    300 	}
    301 	else
    302 	{	// this is a full update that we can start delta compressing from now
    303 		oldp = &dummy;
    304 		dummy.num_entities = 0;
    305 		cl.validsequence = cls.netchan.incoming_sequence;
    306 		full = true;
    307 	}
    308 
    309 	oldindex = 0;
    310 	newindex = 0;
    311 	newp->num_entities = 0;
    312 
    313 	while (1)
    314 	{
    315 		word = (unsigned short)MSG_ReadShort ();
    316 		if (msg_badread)
    317 		{	// something didn't parse right...
    318 			Host_EndGame ("msg_badread in packetentities");
    319 			return;
    320 		}
    321 
    322 		if (!word)
    323 		{
    324 			while (oldindex < oldp->num_entities)
    325 			{	// copy all the rest of the entities from the old packet
    326 //Con_Printf ("copy %i\n", oldp->entities[oldindex].number);
    327 				if (newindex >= MAX_PACKET_ENTITIES)
    328 					Host_EndGame ("CL_ParsePacketEntities: newindex == MAX_PACKET_ENTITIES");
    329 				newp->entities[newindex] = oldp->entities[oldindex];
    330 				newindex++;
    331 				oldindex++;
    332 			}
    333 			break;
    334 		}
    335 		newnum = word&511;
    336 		oldnum = oldindex >= oldp->num_entities ? 9999 : oldp->entities[oldindex].number;
    337 
    338 		while (newnum > oldnum)
    339 		{
    340 			if (full)
    341 			{
    342 				Con_Printf ("WARNING: oldcopy on full update");
    343 				FlushEntityPacket ();
    344 				return;
    345 			}
    346 
    347 //Con_Printf ("copy %i\n", oldnum);
    348 			// copy one of the old entities over to the new packet unchanged
    349 			if (newindex >= MAX_PACKET_ENTITIES)
    350 				Host_EndGame ("CL_ParsePacketEntities: newindex == MAX_PACKET_ENTITIES");
    351 			newp->entities[newindex] = oldp->entities[oldindex];
    352 			newindex++;
    353 			oldindex++;
    354 			oldnum = oldindex >= oldp->num_entities ? 9999 : oldp->entities[oldindex].number;
    355 		}
    356 
    357 		if (newnum < oldnum)
    358 		{	// new from baseline
    359 //Con_Printf ("baseline %i\n", newnum);
    360 			if (word & U_REMOVE)
    361 			{
    362 				if (full)
    363 				{
    364 					cl.validsequence = 0;
    365 					Con_Printf ("WARNING: U_REMOVE on full update\n");
    366 					FlushEntityPacket ();
    367 					return;
    368 				}
    369 				continue;
    370 			}
    371 			if (newindex >= MAX_PACKET_ENTITIES)
    372 				Host_EndGame ("CL_ParsePacketEntities: newindex == MAX_PACKET_ENTITIES");
    373 			CL_ParseDelta (&cl_baselines[newnum], &newp->entities[newindex], word);
    374 			newindex++;
    375 			continue;
    376 		}
    377 
    378 		if (newnum == oldnum)
    379 		{	// delta from previous
    380 			if (full)
    381 			{
    382 				cl.validsequence = 0;
    383 				Con_Printf ("WARNING: delta on full update");
    384 			}
    385 			if (word & U_REMOVE)
    386 			{
    387 				oldindex++;
    388 				continue;
    389 			}
    390 //Con_Printf ("delta %i\n",newnum);
    391 			CL_ParseDelta (&oldp->entities[oldindex], &newp->entities[newindex], word);
    392 			newindex++;
    393 			oldindex++;
    394 		}
    395 
    396 	}
    397 
    398 	newp->num_entities = newindex;
    399 }
    400 
    401 
    402 /*
    403 ===============
    404 CL_LinkPacketEntities
    405 
    406 ===============
    407 */
    408 void CL_LinkPacketEntities (void)
    409 {
    410 	entity_t			*ent;
    411 	packet_entities_t	*pack;
    412 	entity_state_t		*s1, *s2;
    413 	float				f;
    414 	model_t				*model;
    415 	vec3_t				old_origin;
    416 	float				autorotate;
    417 	int					i;
    418 	int					pnum;
    419 	dlight_t			*dl;
    420 
    421 	pack = &cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities;
    422 
    423 	autorotate = anglemod(100*cl.time);
    424 
    425 	f = 0;		// FIXME: no interpolation right now
    426 
    427 	for (pnum=0 ; pnum<pack->num_entities ; pnum++)
    428 	{
    429 		s1 = &pack->entities[pnum];
    430 		s2 = s1;	// FIXME: no interpolation right now
    431 
    432 		// spawn light flashes, even ones coming from invisible objects
    433 		if ((s1->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED))
    434 			CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 3);
    435 		else if (s1->effects & EF_BLUE)
    436 			CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 1);
    437 		else if (s1->effects & EF_RED)
    438 			CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 2);
    439 		else if (s1->effects & EF_BRIGHTLIGHT)
    440 			CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2] + 16, 400 + (rand()&31), 0.1, 0);
    441 		else if (s1->effects & EF_DIMLIGHT)
    442 			CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 0);
    443 
    444 		// if set to invisible, skip
    445 		if (!s1->modelindex)
    446 			continue;
    447 
    448 		// create a new entity
    449 		if (cl_numvisedicts == MAX_VISEDICTS)
    450 			break;		// object list is full
    451 
    452 		ent = &cl_visedicts[cl_numvisedicts];
    453 		cl_numvisedicts++;
    454 
    455 		ent->keynum = s1->number;
    456 		ent->model = model = cl.model_precache[s1->modelindex];
    457 
    458 		// set colormap
    459 		if (s1->colormap && (s1->colormap < MAX_CLIENTS)
    460 			&& !strcmp(ent->model->name,"progs/player.mdl") )
    461 		{
    462 			ent->colormap = cl.players[s1->colormap-1].translations;
    463 			ent->scoreboard = &cl.players[s1->colormap-1];
    464 		}
    465 		else
    466 		{
    467 			ent->colormap = vid.colormap;
    468 			ent->scoreboard = NULL;
    469 		}
    470 
    471 		// set skin
    472 		ent->skinnum = s1->skinnum;
    473 
    474 		// set frame
    475 		ent->frame = s1->frame;
    476 
    477 		// rotate binary objects locally
    478 		if (model->flags & EF_ROTATE)
    479 		{
    480 			ent->angles[0] = 0;
    481 			ent->angles[1] = autorotate;
    482 			ent->angles[2] = 0;
    483 		}
    484 		else
    485 		{
    486 			float	a1, a2;
    487 
    488 			for (i=0 ; i<3 ; i++)
    489 			{
    490 				a1 = s1->angles[i];
    491 				a2 = s2->angles[i];
    492 				if (a1 - a2 > 180)
    493 					a1 -= 360;
    494 				if (a1 - a2 < -180)
    495 					a1 += 360;
    496 				ent->angles[i] = a2 + f * (a1 - a2);
    497 			}
    498 		}
    499 
    500 		// calculate origin
    501 		for (i=0 ; i<3 ; i++)
    502 			ent->origin[i] = s2->origin[i] +
    503 			f * (s1->origin[i] - s2->origin[i]);
    504 
    505 		// add automatic particle trails
    506 		if (!model->flags)
    507 			continue;
    508 
    509 		// scan the old entity display list for a matching
    510 		for (i=0 ; i<cl_oldnumvisedicts ; i++)
    511 		{
    512 			if (cl_oldvisedicts[i].keynum == ent->keynum)
    513 			{
    514 				VectorCopy (cl_oldvisedicts[i].origin, old_origin);
    515 				break;
    516 			}
    517 		}
    518 		if (i == cl_oldnumvisedicts)
    519 			continue;		// not in last message
    520 
    521 		for (i=0 ; i<3 ; i++)
    522 			if ( abs(old_origin[i] - ent->origin[i]) > 128)
    523 			{	// no trail if too far
    524 				VectorCopy (ent->origin, old_origin);
    525 				break;
    526 			}
    527 		if (model->flags & EF_ROCKET)
    528 		{
    529 			R_RocketTrail (old_origin, ent->origin, 0);
    530 			dl = CL_AllocDlight (s1->number);
    531 			VectorCopy (ent->origin, dl->origin);
    532 			dl->radius = 200;
    533 			dl->die = cl.time + 0.1;
    534 		}
    535 		else if (model->flags & EF_GRENADE)
    536 			R_RocketTrail (old_origin, ent->origin, 1);
    537 		else if (model->flags & EF_GIB)
    538 			R_RocketTrail (old_origin, ent->origin, 2);
    539 		else if (model->flags & EF_ZOMGIB)
    540 			R_RocketTrail (old_origin, ent->origin, 4);
    541 		else if (model->flags & EF_TRACER)
    542 			R_RocketTrail (old_origin, ent->origin, 3);
    543 		else if (model->flags & EF_TRACER2)
    544 			R_RocketTrail (old_origin, ent->origin, 5);
    545 		else if (model->flags & EF_TRACER3)
    546 			R_RocketTrail (old_origin, ent->origin, 6);
    547 	}
    548 }
    549 
    550 
    551 /*
    552 =========================================================================
    553 
    554 PROJECTILE PARSING / LINKING
    555 
    556 =========================================================================
    557 */
    558 
    559 typedef struct
    560 {
    561 	int		modelindex;
    562 	vec3_t	origin;
    563 	vec3_t	angles;
    564 } projectile_t;
    565 
    566 #define	MAX_PROJECTILES	32
    567 projectile_t	cl_projectiles[MAX_PROJECTILES];
    568 int				cl_num_projectiles;
    569 
    570 extern int cl_spikeindex;
    571 
    572 void CL_ClearProjectiles (void)
    573 {
    574 	cl_num_projectiles = 0;
    575 }
    576 
    577 /*
    578 =====================
    579 CL_ParseProjectiles
    580 
    581 Nails are passed as efficient temporary entities
    582 =====================
    583 */
    584 void CL_ParseProjectiles (void)
    585 {
    586 	int		i, c, j;
    587 	byte	bits[6];
    588 	projectile_t	*pr;
    589 
    590 	c = MSG_ReadByte ();
    591 	for (i=0 ; i<c ; i++)
    592 	{
    593 		for (j=0 ; j<6 ; j++)
    594 			bits[j] = MSG_ReadByte ();
    595 
    596 		if (cl_num_projectiles == MAX_PROJECTILES)
    597 			continue;
    598 
    599 		pr = &cl_projectiles[cl_num_projectiles];
    600 		cl_num_projectiles++;
    601 
    602 		pr->modelindex = cl_spikeindex;
    603 		pr->origin[0] = ( ( bits[0] + ((bits[1]&15)<<8) ) <<1) - 4096;
    604 		pr->origin[1] = ( ( (bits[1]>>4) + (bits[2]<<4) ) <<1) - 4096;
    605 		pr->origin[2] = ( ( bits[3] + ((bits[4]&15)<<8) ) <<1) - 4096;
    606 		pr->angles[0] = 360*(bits[4]>>4)/16;
    607 		pr->angles[1] = 360*bits[5]/256;
    608 	}
    609 }
    610 
    611 /*
    612 =============
    613 CL_LinkProjectiles
    614 
    615 =============
    616 */
    617 void CL_LinkProjectiles (void)
    618 {
    619 	int		i;
    620 	projectile_t	*pr;
    621 	entity_t		*ent;
    622 
    623 	for (i=0, pr=cl_projectiles ; i<cl_num_projectiles ; i++, pr++)
    624 	{
    625 		// grab an entity to fill in
    626 		if (cl_numvisedicts == MAX_VISEDICTS)
    627 			break;		// object list is full
    628 		ent = &cl_visedicts[cl_numvisedicts];
    629 		cl_numvisedicts++;
    630 		ent->keynum = 0;
    631 
    632 		if (pr->modelindex < 1)
    633 			continue;
    634 		ent->model = cl.model_precache[pr->modelindex];
    635 		ent->skinnum = 0;
    636 		ent->frame = 0;
    637 		ent->colormap = vid.colormap;
    638 		ent->scoreboard = NULL;
    639 		VectorCopy (pr->origin, ent->origin);
    640 		VectorCopy (pr->angles, ent->angles);
    641 	}
    642 }
    643 
    644 //========================================
    645 
    646 extern	int		cl_spikeindex, cl_playerindex, cl_flagindex;
    647 
    648 entity_t *CL_NewTempEntity (void);
    649 
    650 /*
    651 ===================
    652 CL_ParsePlayerinfo
    653 ===================
    654 */
    655 extern int parsecountmod;
    656 extern double parsecounttime;
    657 void CL_ParsePlayerinfo (void)
    658 {
    659 	int			msec;
    660 	int			flags;
    661 	player_info_t	*info;
    662 	player_state_t	*state;
    663 	int			num;
    664 	int			i;
    665 
    666 	num = MSG_ReadByte ();
    667 	if (num > MAX_CLIENTS)
    668 		Sys_Error ("CL_ParsePlayerinfo: bad num");
    669 
    670 	info = &cl.players[num];
    671 
    672 	state = &cl.frames[parsecountmod].playerstate[num];
    673 
    674 	flags = state->flags = MSG_ReadShort ();
    675 
    676 	state->messagenum = cl.parsecount;
    677 	state->origin[0] = MSG_ReadCoord ();
    678 	state->origin[1] = MSG_ReadCoord ();
    679 	state->origin[2] = MSG_ReadCoord ();
    680 
    681 	state->frame = MSG_ReadByte ();
    682 
    683 	// the other player's last move was likely some time
    684 	// before the packet was sent out, so accurately track
    685 	// the exact time it was valid at
    686 	if (flags & PF_MSEC)
    687 	{
    688 		msec = MSG_ReadByte ();
    689 		state->state_time = parsecounttime - msec*0.001;
    690 	}
    691 	else
    692 		state->state_time = parsecounttime;
    693 
    694 	if (flags & PF_COMMAND)
    695 		MSG_ReadDeltaUsercmd (&nullcmd, &state->command);
    696 
    697 	for (i=0 ; i<3 ; i++)
    698 	{
    699 		if (flags & (PF_VELOCITY1<<i) )
    700 			state->velocity[i] = MSG_ReadShort();
    701 		else
    702 			state->velocity[i] = 0;
    703 	}
    704 	if (flags & PF_MODEL)
    705 		state->modelindex = MSG_ReadByte ();
    706 	else
    707 		state->modelindex = cl_playerindex;
    708 
    709 	if (flags & PF_SKINNUM)
    710 		state->skinnum = MSG_ReadByte ();
    711 	else
    712 		state->skinnum = 0;
    713 
    714 	if (flags & PF_EFFECTS)
    715 		state->effects = MSG_ReadByte ();
    716 	else
    717 		state->effects = 0;
    718 
    719 	if (flags & PF_WEAPONFRAME)
    720 		state->weaponframe = MSG_ReadByte ();
    721 	else
    722 		state->weaponframe = 0;
    723 
    724 	VectorCopy (state->command.angles, state->viewangles);
    725 }
    726 
    727 
    728 /*
    729 ================
    730 CL_AddFlagModels
    731 
    732 Called when the CTF flags are set
    733 ================
    734 */
    735 void CL_AddFlagModels (entity_t *ent, int team)
    736 {
    737 	int		i;
    738 	float	f;
    739 	vec3_t	v_forward, v_right, v_up;
    740 	entity_t	*newent;
    741 
    742 	if (cl_flagindex == -1)
    743 		return;
    744 
    745 	f = 14;
    746 	if (ent->frame >= 29 && ent->frame <= 40) {
    747 		if (ent->frame >= 29 && ent->frame <= 34) { //axpain
    748 			if      (ent->frame == 29) f = f + 2;
    749 			else if (ent->frame == 30) f = f + 8;
    750 			else if (ent->frame == 31) f = f + 12;
    751 			else if (ent->frame == 32) f = f + 11;
    752 			else if (ent->frame == 33) f = f + 10;
    753 			else if (ent->frame == 34) f = f + 4;
    754 		} else if (ent->frame >= 35 && ent->frame <= 40) { // pain
    755 			if      (ent->frame == 35) f = f + 2;
    756 			else if (ent->frame == 36) f = f + 10;
    757 			else if (ent->frame == 37) f = f + 10;
    758 			else if (ent->frame == 38) f = f + 8;
    759 			else if (ent->frame == 39) f = f + 4;
    760 			else if (ent->frame == 40) f = f + 2;
    761 		}
    762 	} else if (ent->frame >= 103 && ent->frame <= 118) {
    763 		if      (ent->frame >= 103 && ent->frame <= 104) f = f + 6;  //nailattack
    764 		else if (ent->frame >= 105 && ent->frame <= 106) f = f + 6;  //light
    765 		else if (ent->frame >= 107 && ent->frame <= 112) f = f + 7;  //rocketattack
    766 		else if (ent->frame >= 112 && ent->frame <= 118) f = f + 7;  //shotattack
    767 	}
    768 
    769 	newent = CL_NewTempEntity ();
    770 	newent->model = cl.model_precache[cl_flagindex];
    771 	newent->skinnum = team;
    772 
    773 	AngleVectors (ent->angles, v_forward, v_right, v_up);
    774 	v_forward[2] = -v_forward[2]; // reverse z component
    775 	for (i=0 ; i<3 ; i++)
    776 		newent->origin[i] = ent->origin[i] - f*v_forward[i] + 22*v_right[i];
    777 	newent->origin[2] -= 16;
    778 
    779 	VectorCopy (ent->angles, newent->angles)
    780 	newent->angles[2] -= 45;
    781 }
    782 
    783 /*
    784 =============
    785 CL_LinkPlayers
    786 
    787 Create visible entities in the correct position
    788 for all current players
    789 =============
    790 */
    791 void CL_LinkPlayers (void)
    792 {
    793 	int				j;
    794 	player_info_t	*info;
    795 	player_state_t	*state;
    796 	player_state_t	exact;
    797 	double			playertime;
    798 	entity_t		*ent;
    799 	int				msec;
    800 	frame_t			*frame;
    801 	int				oldphysent;
    802 
    803 	playertime = realtime - cls.latency + 0.02;
    804 	if (playertime > realtime)
    805 		playertime = realtime;
    806 
    807 	frame = &cl.frames[cl.parsecount&UPDATE_MASK];
    808 
    809 	for (j=0, info=cl.players, state=frame->playerstate ; j < MAX_CLIENTS
    810 		; j++, info++, state++)
    811 	{
    812 		if (state->messagenum != cl.parsecount)
    813 			continue;	// not present this frame
    814 
    815 		// spawn light flashes, even ones coming from invisible objects
    816 #ifdef GLQUAKE
    817 		if (!gl_flashblend.value || j != cl.playernum) {
    818 #endif
    819 			if ((state->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED))
    820 				CL_NewDlight (j, state->origin[0], state->origin[1], state->origin[2], 200 + (rand()&31), 0.1, 3);
    821 			else if (state->effects & EF_BLUE)
    822 				CL_NewDlight (j, state->origin[0], state->origin[1], state->origin[2], 200 + (rand()&31), 0.1, 1);
    823 			else if (state->effects & EF_RED)
    824 				CL_NewDlight (j, state->origin[0], state->origin[1], state->origin[2], 200 + (rand()&31), 0.1, 2);
    825 			else if (state->effects & EF_BRIGHTLIGHT)
    826 				CL_NewDlight (j, state->origin[0], state->origin[1], state->origin[2] + 16, 400 + (rand()&31), 0.1, 0);
    827 			else if (state->effects & EF_DIMLIGHT)
    828 				CL_NewDlight (j, state->origin[0], state->origin[1], state->origin[2], 200 + (rand()&31), 0.1, 0);
    829 #ifdef GLQUAKE
    830 		}
    831 #endif
    832 
    833 		// the player object never gets added
    834 		if (j == cl.playernum)
    835 			continue;
    836 
    837 		if (!state->modelindex)
    838 			continue;
    839 
    840 		if (!Cam_DrawPlayer(j))
    841 			continue;
    842 
    843 		// grab an entity to fill in
    844 		if (cl_numvisedicts == MAX_VISEDICTS)
    845 			break;		// object list is full
    846 		ent = &cl_visedicts[cl_numvisedicts];
    847 		cl_numvisedicts++;
    848 		ent->keynum = 0;
    849 
    850 		ent->model = cl.model_precache[state->modelindex];
    851 		ent->skinnum = state->skinnum;
    852 		ent->frame = state->frame;
    853 		ent->colormap = info->translations;
    854 		if (state->modelindex == cl_playerindex)
    855 			ent->scoreboard = info;		// use custom skin
    856 		else
    857 			ent->scoreboard = NULL;
    858 
    859 		//
    860 		// angles
    861 		//
    862 		ent->angles[PITCH] = -state->viewangles[PITCH]/3;
    863 		ent->angles[YAW] = state->viewangles[YAW];
    864 		ent->angles[ROLL] = 0;
    865 		ent->angles[ROLL] = V_CalcRoll (ent->angles, state->velocity)*4;
    866 
    867 		// only predict half the move to minimize overruns
    868 		msec = 500*(playertime - state->state_time);
    869 		if (msec <= 0 || (!cl_predict_players.value && !cl_predict_players2.value))
    870 		{
    871 			VectorCopy (state->origin, ent->origin);
    872 //Con_DPrintf ("nopredict\n");
    873 		}
    874 		else
    875 		{
    876 			// predict players movement
    877 			if (msec > 255)
    878 				msec = 255;
    879 			state->command.msec = msec;
    880 //Con_DPrintf ("predict: %i\n", msec);
    881 
    882 			oldphysent = pmove.numphysent;
    883 			CL_SetSolidPlayers (j);
    884 			CL_PredictUsercmd (state, &exact, &state->command, false);
    885 			pmove.numphysent = oldphysent;
    886 			VectorCopy (exact.origin, ent->origin);
    887 		}
    888 
    889 		if (state->effects & EF_FLAG1)
    890 			CL_AddFlagModels (ent, 0);
    891 		else if (state->effects & EF_FLAG2)
    892 			CL_AddFlagModels (ent, 1);
    893 
    894 	}
    895 }
    896 
    897 //======================================================================
    898 
    899 /*
    900 ===============
    901 CL_SetSolid
    902 
    903 Builds all the pmove physents for the current frame
    904 ===============
    905 */
    906 void CL_SetSolidEntities (void)
    907 {
    908 	int		i;
    909 	frame_t	*frame;
    910 	packet_entities_t	*pak;
    911 	entity_state_t		*state;
    912 
    913 	pmove.physents[0].model = cl.worldmodel;
    914 	VectorCopy (vec3_origin, pmove.physents[0].origin);
    915 	pmove.physents[0].info = 0;
    916 	pmove.numphysent = 1;
    917 
    918 	frame = &cl.frames[parsecountmod];
    919 	pak = &frame->packet_entities;
    920 
    921 	for (i=0 ; i<pak->num_entities ; i++)
    922 	{
    923 		state = &pak->entities[i];
    924 
    925 		if (!state->modelindex)
    926 			continue;
    927 		if (!cl.model_precache[state->modelindex])
    928 			continue;
    929 		if ( cl.model_precache[state->modelindex]->hulls[1].firstclipnode
    930 			|| cl.model_precache[state->modelindex]->clipbox )
    931 		{
    932 			pmove.physents[pmove.numphysent].model = cl.model_precache[state->modelindex];
    933 			VectorCopy (state->origin, pmove.physents[pmove.numphysent].origin);
    934 			pmove.numphysent++;
    935 		}
    936 	}
    937 
    938 }
    939 
    940 /*
    941 ===
    942 Calculate the new position of players, without other player clipping
    943 
    944 We do this to set up real player prediction.
    945 Players are predicted twice, first without clipping other players,
    946 then with clipping against them.
    947 This sets up the first phase.
    948 ===
    949 */
    950 void CL_SetUpPlayerPrediction(qboolean dopred)
    951 {
    952 	int				j;
    953 	player_state_t	*state;
    954 	player_state_t	exact;
    955 	double			playertime;
    956 	int				msec;
    957 	frame_t			*frame;
    958 	struct predicted_player *pplayer;
    959 
    960 	playertime = realtime - cls.latency + 0.02;
    961 	if (playertime > realtime)
    962 		playertime = realtime;
    963 
    964 	frame = &cl.frames[cl.parsecount&UPDATE_MASK];
    965 
    966 	for (j=0, pplayer = predicted_players, state=frame->playerstate;
    967 		j < MAX_CLIENTS;
    968 		j++, pplayer++, state++) {
    969 
    970 		pplayer->active = false;
    971 
    972 		if (state->messagenum != cl.parsecount)
    973 			continue;	// not present this frame
    974 
    975 		if (!state->modelindex)
    976 			continue;
    977 
    978 		pplayer->active = true;
    979 		pplayer->flags = state->flags;
    980 
    981 		// note that the local player is special, since he moves locally
    982 		// we use his last predicted postition
    983 		if (j == cl.playernum) {
    984 			VectorCopy(cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].playerstate[cl.playernum].origin,
    985 				pplayer->origin);
    986 		} else {
    987 			// only predict half the move to minimize overruns
    988 			msec = 500*(playertime - state->state_time);
    989 			if (msec <= 0 ||
    990 				(!cl_predict_players.value && !cl_predict_players2.value) ||
    991 				!dopred)
    992 			{
    993 				VectorCopy (state->origin, pplayer->origin);
    994 	//Con_DPrintf ("nopredict\n");
    995 			}
    996 			else
    997 			{
    998 				// predict players movement
    999 				if (msec > 255)
   1000 					msec = 255;
   1001 				state->command.msec = msec;
   1002 	//Con_DPrintf ("predict: %i\n", msec);
   1003 
   1004 				CL_PredictUsercmd (state, &exact, &state->command, false);
   1005 				VectorCopy (exact.origin, pplayer->origin);
   1006 			}
   1007 		}
   1008 	}
   1009 }
   1010 
   1011 /*
   1012 ===============
   1013 CL_SetSolid
   1014 
   1015 Builds all the pmove physents for the current frame
   1016 Note that CL_SetUpPlayerPrediction() must be called first!
   1017 pmove must be setup with world and solid entity hulls before calling
   1018 (via CL_PredictMove)
   1019 ===============
   1020 */
   1021 void CL_SetSolidPlayers (int playernum)
   1022 {
   1023 	int		j;
   1024 	extern	vec3_t	player_mins;
   1025 	extern	vec3_t	player_maxs;
   1026 	struct predicted_player *pplayer;
   1027 	physent_t *pent;
   1028 
   1029 	if (!cl_solid_players.value)
   1030 		return;
   1031 
   1032 	pent = pmove.physents + pmove.numphysent;
   1033 
   1034 	for (j=0, pplayer = predicted_players; j < MAX_CLIENTS;	j++, pplayer++) {
   1035 
   1036 		if (!pplayer->active)
   1037 			continue;	// not present this frame
   1038 
   1039 		// the player object never gets added
   1040 		if (j == playernum)
   1041 			continue;
   1042 
   1043 		if (pplayer->flags & PF_DEAD)
   1044 			continue; // dead players aren't solid
   1045 
   1046 		pent->model = 0;
   1047 		VectorCopy(pplayer->origin, pent->origin);
   1048 		VectorCopy(player_mins, pent->mins);
   1049 		VectorCopy(player_maxs, pent->maxs);
   1050 		pmove.numphysent++;
   1051 		pent++;
   1052 	}
   1053 }
   1054 
   1055 
   1056 /*
   1057 ===============
   1058 CL_EmitEntities
   1059 
   1060 Builds the visedicts array for cl.time
   1061 
   1062 Made up of: clients, packet_entities, nails, and tents
   1063 ===============
   1064 */
   1065 void CL_EmitEntities (void)
   1066 {
   1067 	if (cls.state != ca_active)
   1068 		return;
   1069 	if (!cl.validsequence)
   1070 		return;
   1071 
   1072 	cl_oldnumvisedicts = cl_numvisedicts;
   1073 	cl_oldvisedicts = cl_visedicts_list[(cls.netchan.incoming_sequence-1)&1];
   1074 	cl_visedicts = cl_visedicts_list[cls.netchan.incoming_sequence&1];
   1075 
   1076 	cl_numvisedicts = 0;
   1077 
   1078 	CL_LinkPlayers ();
   1079 	CL_LinkPacketEntities ();
   1080 	CL_LinkProjectiles ();
   1081 	CL_UpdateTEnts ();
   1082 }
   1083 
   1084