Ejemplo n.º 1
0
/*
=============
CL_LinkPlayers

Create visible entities in the correct position
for all current players
=============
*/
static void
CL_LinkPlayers(physent_stack_t *pestack)
{
    int playernum;
    player_info_t *info;
    player_state_t *state;
    player_state_t exact;
    double playertime;
    entity_t *ent;
    int msec;
    frame_t *frame;
    int oldphysent;

    playertime = realtime - cls.latency + 0.02;
    if (playertime > realtime)
	playertime = realtime;

    frame = &cl.frames[cl.parsecount & UPDATE_MASK];

    info = cl.players;
    state = frame->playerstate;
    for (playernum = 0; playernum < MAX_CLIENTS; playernum++, info++, state++) {
	if (state->messagenum != cl.parsecount)
	    continue;		// not present this frame

	// spawn light flashes, even ones coming from invisible objects
#ifdef GLQUAKE
	if (!gl_flashblend.value || playernum != cl.playernum) {
#endif
	    if ((state->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED))
		CL_NewDlight(playernum, state->origin[0], state->origin[1],
			     state->origin[2], 200 + (rand() & 31), 0.1, DLIGHT_PURPLE);
	    else if (state->effects & EF_BLUE)
		CL_NewDlight(playernum, state->origin[0], state->origin[1],
			     state->origin[2], 200 + (rand() & 31), 0.1, DLIGHT_BLUE);
	    else if (state->effects & EF_RED)
		CL_NewDlight(playernum, state->origin[0], state->origin[1],
			     state->origin[2], 200 + (rand() & 31), 0.1, DLIGHT_RED);
	    else if (state->effects & EF_BRIGHTLIGHT)
		CL_NewDlight(playernum, state->origin[0], state->origin[1],
			     state->origin[2] + 16, 400 + (rand() & 31),
			     0.1, DLIGHT_FLASH);
	    else if (state->effects & EF_DIMLIGHT)
		CL_NewDlight(playernum, state->origin[0], state->origin[1],
			     state->origin[2], 200 + (rand() & 31), 0.1, DLIGHT_FLASH);
#ifdef GLQUAKE
	}
#endif

	// the player object never gets added
	if (playernum == cl.playernum)
	    continue;

	if (!state->modelindex)
	    continue;

	if (!Cam_DrawPlayer(playernum))
	    continue;

	// grab an entity to fill in
	if (cl_numvisedicts == MAX_VISEDICTS)
	    break;		// object list is full
	ent = &cl_visedicts[cl_numvisedicts];
	cl_numvisedicts++;
	ent->keynum = 0;

	ent->model = cl.model_precache[state->modelindex];
	ent->skinnum = state->skinnum;
	ent->frame = state->frame;
	ent->colormap = info->translations;
	if (state->modelindex == cl_playerindex)
	    ent->scoreboard = info;	// use custom skin
	else
	    ent->scoreboard = NULL;

	//
	// angles
	//
	ent->angles[PITCH] = -state->viewangles[PITCH] / 3;
	ent->angles[YAW] = state->viewangles[YAW];
	ent->angles[ROLL] = 0;
	ent->angles[ROLL] = V_CalcRoll(ent->angles, state->velocity) * 4;

	// only predict half the move to minimize overruns
	msec = 500 * (playertime - state->state_time);
	if (msec <= 0 || (!cl_predict_players.value && !cl_predict_players2.value)) {
	    VectorCopy(state->origin, ent->origin);
//Con_DPrintf ("nopredict\n");
	} else {
	    // predict players movement
	    if (msec > 255)
		msec = 255;
	    state->command.msec = msec;
//Con_DPrintf ("predict: %i\n", msec);

	    oldphysent = pestack->numphysent;
	    CL_SetSolidPlayers(pestack, playernum);
	    CL_PredictUsercmd(state, &exact, &state->command, pestack, false);
	    pestack->numphysent = oldphysent;
	    VectorCopy(exact.origin, ent->origin);
	}

	if (state->effects & EF_FLAG1)
	    CL_AddFlagModels(ent, 0);
	else if (state->effects & EF_FLAG2)
	    CL_AddFlagModels(ent, 1);

    }
}
Ejemplo n.º 2
0
/*
===============
CL_LinkPacketEntities

===============
*/
void CL_LinkPacketEntities (void)
{
	entity_t			*ent;
	packet_entities_t	*pack;
	entity_state_t		*s1, *s2;
	float				f;
	model_t				*model;
	vec3_t				old_origin;
	float				autorotate;
	int					i;
	int					pnum;
	dlight_t			*dl;

	pack = &cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities;

	autorotate = anglemod(100*cl.time);

	f = 0;		// FIXME: no interpolation right now

	for (pnum=0 ; pnum<pack->num_entities ; pnum++)
	{
		s1 = &pack->entities[pnum];
		s2 = s1;	// FIXME: no interpolation right now

		// spawn light flashes, even ones coming from invisible objects
		if ((s1->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED))
			CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 3);
		else if (s1->effects & EF_BLUE)
			CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 1);
		else if (s1->effects & EF_RED)
			CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 2);
		else if (s1->effects & EF_BRIGHTLIGHT)
			CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2] + 16, 400 + (rand()&31), 0.1, 0);
		else if (s1->effects & EF_DIMLIGHT)
			CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 0);

		// if set to invisible, skip
		if (!s1->modelindex)
			continue;

		// create a new entity
		if (cl_numvisedicts == MAX_VISEDICTS)
			break;		// object list is full

		ent = &cl_visedicts[cl_numvisedicts];
		cl_numvisedicts++;

		ent->keynum = s1->number;
		ent->model = model = cl.model_precache[s1->modelindex];
	
		// set colormap
		if (s1->colormap && (s1->colormap < MAX_CLIENTS) 
			&& !strcmp(ent->model->name,"progs/player.mdl") )
		{
			ent->colormap = cl.players[s1->colormap-1].translations;
			ent->scoreboard = &cl.players[s1->colormap-1];
		}
		else
		{
			ent->colormap = vid.colormap;
			ent->scoreboard = NULL;
		}

		// set skin
		ent->skinnum = s1->skinnum;
		
		// set frame
		ent->frame = s1->frame;

		// rotate binary objects locally
		if (model->flags & EF_ROTATE)
		{
			ent->angles[0] = 0;
			ent->angles[1] = autorotate;
			ent->angles[2] = 0;
		}
		else
		{
			float	a1, a2;

			for (i=0 ; i<3 ; i++)
			{
				a1 = s1->angles[i];
				a2 = s2->angles[i];
				if (a1 - a2 > 180)
					a1 -= 360;
				if (a1 - a2 < -180)
					a1 += 360;
				ent->angles[i] = a2 + f * (a1 - a2);
			}
		}

		// calculate origin
		for (i=0 ; i<3 ; i++)
			ent->origin[i] = s2->origin[i] + 
			f * (s1->origin[i] - s2->origin[i]);

		// add automatic particle trails
		if (!model->flags)
			continue;

		// scan the old entity display list for a matching
		for (i=0 ; i<cl_oldnumvisedicts ; i++)
		{
			if (cl_oldvisedicts[i].keynum == ent->keynum)
			{
				VectorCopy (cl_oldvisedicts[i].origin, old_origin);
				break;
			}
		}
		if (i == cl_oldnumvisedicts)
			continue;		// not in last message

		for (i=0 ; i<3 ; i++)
			if ( abs(old_origin[i] - ent->origin[i]) > 128)
			{	// no trail if too far
				VectorCopy (ent->origin, old_origin);
				break;
			}
		if (model->flags & EF_ROCKET)
		{
			R_RocketTrail (old_origin, ent->origin, 0);
			dl = CL_AllocDlight (s1->number);
			VectorCopy (ent->origin, dl->origin);
			dl->radius = 200;
			dl->die = cl.time + 0.1;
		}
		else if (model->flags & EF_GRENADE)
			R_RocketTrail (old_origin, ent->origin, 1);
		else if (model->flags & EF_GIB)
			R_RocketTrail (old_origin, ent->origin, 2);
		else if (model->flags & EF_ZOMGIB)
			R_RocketTrail (old_origin, ent->origin, 4);
		else if (model->flags & EF_TRACER)
			R_RocketTrail (old_origin, ent->origin, 3);
		else if (model->flags & EF_TRACER2)
			R_RocketTrail (old_origin, ent->origin, 5);
		else if (model->flags & EF_TRACER3)
			R_RocketTrail (old_origin, ent->origin, 6);
	}
}
Ejemplo n.º 3
0
/*
=================
CL_UpdateLightning
=================
*/
void CL_UpdateLightning (void)
{
	int			i, j;
	beam_t		*b;
	vec3_t		dist, org, beamstart, beamend;
	float		d, yaw, pitch, forward;
	entity_t	*ent;
//	qboolean	sparks = false;

	num_temp_entities = 0;

	// update lightning
	for (i = 0, b = cl_beams ; i < MAX_BEAMS ; i++, b++)
	{
		if (!b->model || BEAM_INACTIVE(b))
			continue;

		// if coming from the player, update the start position
		if (b->entity == cl.viewentity)
		{
			VectorCopy (cl_entities[cl.viewentity].origin, b->start);
			// joe: using koval's [sons]Quake code
			b->start[2] += cl.crouch;
			if (!cls.demorecording && cl_truelightning.value)
			{
				vec3_t	forward, v, org, ang;
				float	f, delta;
				trace_t	trace;

				f = bound(0, cl_truelightning.value, 1);

				VectorSubtract (playerbeam_end, cl_entities[cl.viewentity].origin, v);
		//		v[2] -= 22;		// adjust for view height
				v[2] -= cl.viewheight;		// adjust for view height
				vectoangles (v, ang);

				// lerp pitch
				ang[0] = -ang[0];
				if (ang[0] < -180)
					ang[0] += 360;
				ang[0] += (cl.viewangles[0] - ang[0]) * f;

				// lerp yaw
				delta = cl.viewangles[1] - ang[1];
				if (delta > 180)
					delta -= 360;
				if (delta < -180)
					delta += 360;
				ang[1] += delta * f;
				ang[2] = 0;

				AngleVectors (ang, forward, NULL, NULL);
				VectorScale (forward, 600, forward);
				VectorCopy (cl_entities[cl.viewentity].origin, org);
				org[2] += 16;
				VectorAdd(org, forward, b->end);

				memset (&trace, 0, sizeof(trace_t));
				if (!SV_RecursiveHullCheck(cl.worldmodel->hulls, 0, 0, 1, org, b->end, &trace))
					VectorCopy (trace.endpos, b->end);
			}
		}

		// calculate pitch and yaw
		VectorSubtract (b->end, b->start, dist);

		if (!dist[1] && !dist[0])
		{
			yaw = 0;
			pitch = (dist[2] > 0) ? 90 : 270;
		}
		else
		{
			yaw = atan2 (dist[1], dist[0]) * 180 / M_PI;
			if (yaw < 0)
				yaw += 360;
	
			forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]);
			pitch = atan2 (dist[2], forward) * 180 / M_PI;
			if (pitch < 0)
				pitch += 360;
		}

		// add new entities for the lightning
		VectorCopy (b->start, org);
		VectorCopy (b->start, beamstart);
		d = VectorNormalize (dist);
		VectorScale (dist, 30, dist);

		for ( ; d > 0 ; d -= 30)
		{
			if (qmb_initialized && gl_part_lightning.value)
			{
				VectorAdd(org, dist, beamend);
				for (j=0 ; j<3 ; j++)
					beamend[j] += (b->entity != cl.viewentity) ? (rand() % 40) - 20 : (rand() % 16) - 8;
				QMB_LightningBeam (beamstart, beamend);

				// JT040905 - glowing lightning.
				CL_NewDlight (i, beamend, 200 + (rand() & 31), 0.1, lt_blue);
				CL_NewDlight (i, beamstart, 200 + (rand() & 31), 0.1, lt_blue);
				// end

				VectorCopy (beamend, beamstart);
			}
			else
			{
				if (!(ent = CL_NewTempEntity()))
					return;
				VectorCopy (org, ent->origin);
				ent->model = b->model;
				ent->angles[0] = pitch;
				ent->angles[1] = yaw;
				ent->angles[2] = rand() % 360;
			}

#if 0
			if (qmb_initialized && gl_part_lightning.value && !sparks)
			{
				trace_t	trace;

				memset (&trace, 0, sizeof(trace_t));
				if (!SV_RecursiveHullCheck(cl.worldmodel->hulls, 0, 0, 1, org, beamend, &trace))
				{
					byte	col[3] = {240, 150, 0};	// change color here 60, 100, 240

					QMB_GenSparks (trace.endpos, col, 3, 300, 0.25);	// 

					// JT 041105 - add second spark color
					/*
					byte	col[3] = {255, 204, 0};	// change color here

					QMB_GenSparks (trace.endpos, col, 2, 300, 0.25);
					*/
					// end

					QMB_Lightning_Splash (trace.endpos);
					sparks = true;
				}
			}
#endif
			VectorAdd(org, dist, org);
		}
	}
}