Beispiel #1
0
/*
================
R_StoreEfrags

// FIXME: a lot of this goes away with edge-based
================
*/
void R_StoreEfrags (efrag_t **ppefrag)
{
	entity_t	*pent;
	model_t		*model;
	efrag_t		*pefrag;

	for (pefrag = *ppefrag ; pefrag ; pefrag = pefrag->leafnext)
	{
		pent = pefrag->entity;
		model = pent->model;

		if (model->modhint == MOD_FLAME && !r_drawflame.value)
			continue;

		switch (model->type)
		{
		case mod_alias:
		case mod_brush:
		case mod_sprite:
			if ((pent->visframe != r_framecount) &&
				(cl_numvisedicts < MAX_VISEDICTS))
			{
				V_AddEntity (pent);

			// mark that we've recorded this entity for this frame
				pent->visframe = r_framecount;
			}
			break;

		default:	
			Sys_Error ("R_StoreEfrags: Bad entity type %d", model->type);
		}
	}
}
Beispiel #2
0
void CL_UpdateExplosions (void)
{
    int			f;
    explosion_t	*ex;
    explosion_t *next, *hnode;
    entity_t	ent;

    memset (&ent, 0, sizeof(entity_t));
    ent.colormap = 0;

    hnode = &cl_explosions_headnode;
    for (ex = hnode->next; ex != hnode; ex = next)
    {
        next = ex->next;
        f = 10 * (cl.time - ex->start);

        if (f >= EXPLOSION_FRAMES)
        {
            CL_FreeExplosion (ex);
            continue;
        }

        VectorCopy (ex->origin, ent.origin);
        ent.model = ex->model;
        ent.frame = f;

        V_AddEntity (&ent);
    }
}
Beispiel #3
0
void CL_AddViewLocs (void)
{
	int index = CL_LocIndex(cl.frame.playerstate.pmove.origin);
	int i;
	int num = 0;

	if (!cl_drawlocs->value)
		return;

	for (i = 0; i < MAX_LOCATIONS; i++)
	{
		int dist;
		entity_t ent;

		if (locations[i].used == false)
			continue;

		dist = (cl.frame.playerstate.pmove.origin[0] - locations[i].origin[0]) *
		    (cl.frame.playerstate.pmove.origin[0] - locations[i].origin[0]) +
		    (cl.frame.playerstate.pmove.origin[1] - locations[i].origin[1]) *
		    (cl.frame.playerstate.pmove.origin[1] - locations[i].origin[1]) +
		    (cl.frame.playerstate.pmove.origin[2] - locations[i].origin[2]) *
		    (cl.frame.playerstate.pmove.origin[2] - locations[i].origin[2]);

		if (dist > 4000 * 4000)
			continue;

		memset(&ent, 0, sizeof(entity_t));
		ent.origin[0] = locations[i].origin[0] * 0.125f;
		ent.origin[1] = locations[i].origin[1] * 0.125f;
		ent.origin[2] = locations[i].origin[2] * 0.125f;
		ent.skinnum = 0;
//		ent.skin = NULL;
		memset(ent.skins, 0, sizeof(ent.skins));
		ent.model = NULL;

		if (i == index)
			ent.origin[2] += sin(cl.time * 0.01f) * 10.0f;

		V_AddEntity(&ent);
		num++;
	}
}
Beispiel #4
0
/*
================
R_StoreEfrags

FIXME: a lot of this goes away with edge-based
================
*/
void R_StoreEfrags (efrag_t **ppefrag)
{
	entity_t	*pent;
	efrag_t		*pefrag;

	while ((pefrag = *ppefrag) != NULL)
	{
		pent = pefrag->entity;

		if ((pent->visframe != r_framecount) &&	(cl_numvisedicts < MAX_VISEDICTS))
		{
			V_AddEntity (pent);

			// mark that we've recorded this entity for this frame
			pent->visframe = r_framecount;
		}

		ppefrag = &pefrag->leafnext;
	}
}
Beispiel #5
0
/*
=================
CL_UpdateBeams
=================
*/
void CL_UpdateBeams (void)
{
    int			i;
    beam_t		*b;
    vec3_t		dist, org;
    float		d, dec;
    entity_t	ent;
    vec3_t		angles;

    dec = 30;
    memset (&ent, 0, sizeof(entity_t));
    ent.colormap = 0;

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

        // if coming from the player, update the start position
        if (b->entity == Cam_PlayerNum() + 1 && !cl.intermission)
        {
            VectorCopy (cl.simorg, b->start);
            b->start[2] += cl.crouch;
            if (cl_fakeshaft.value && cl.allow_fakeshaft)
            {
                vec3_t	forward;
                vec3_t	v, org;
                vec3_t	ang;
                float	f, delta;
                trace_t	trace;

                f = max(0, min(1, cl_fakeshaft.value));

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

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

                // lerp yaw
                delta = cl.simangles[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.simorg, org);
                org[2] += 16;
                VectorAdd (org, forward, b->end);

                trace = PM_TraceLine (&cl.pmove, org, b->end);
                if (trace.fraction < 1)
                    VectorCopy (trace.endpos, b->end);
            }
        }

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

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

        while (d > 0)
        {
            VectorCopy (org, ent.origin);
            ent.model = b->model;
            ent.angles[PITCH] = angles[PITCH];
            ent.angles[YAW] = angles[YAW];
            ent.angles[ROLL] = rand() % 360;
            if (b->model == cl_bolt2_mod)
                ent.alpha = r_shaftalpha.value;

            V_AddEntity (&ent);

            d -= dec;
            VectorAdd (org, dist, org);
        }
    }
}
Beispiel #6
0
/*
=================
ROGUE - draw player locked beams
CL_AddPlayerBeams
=================
*/
void CL_AddPlayerBeams (void)
{
	int32_t			i,j;
	beam_t		*b;
	vec3_t		dist, org;
	float		d;
	entity_t	ent;
	float		yaw, pitch;
	float		forward;
	float		len, steps;
	int32_t			framenum;
	float		model_length;
	float		hand_multiplier;
	frame_t		*oldframe;
	player_state_t	*ps, *ops;
	qboolean	firstperson, chasecam;
	int32_t			newhandmult;
	vec3_t		thirdp_pbeam_offset;
	vec3_t		pbeam_offset_dir;

//PMM
	if (hand)
	{
		if (hand->value == 2)
			hand_multiplier = 0;
		else if (hand->value == 1)
			hand_multiplier = -1;
		else
			hand_multiplier = 1;
	}
	else 
	{
		hand_multiplier = 1;
	}
//PMM

	// chasecam beam offset stuff
	newhandmult = hand_multiplier;
	if (newhandmult == 0)
		newhandmult = 1;

	VectorSet(thirdp_pbeam_offset, 6.5, 0, 12);
	// end chasecam beam offset stuff

// update beams
	for (i=0, b=cl_playerbeams; i< MAX_BEAMS; i++, b++)
	{
		vec3_t		f,r,u;

		if (!b->model || b->endtime < cl.time)
			continue;

		firstperson = ((b->entity == cl.playernum+1) && !cg_thirdperson->value);
		chasecam = ((b->entity == cl.playernum+1) && cg_thirdperson->value);

		if(clMedia.mod_heatbeam && (b->model == clMedia.mod_heatbeam))
		{

			// if coming from the player, update the start position
			if (firstperson || chasecam)
			{	
				// set up gun position
				// code straight out of CL_AddViewWeapon
				ps = &cl.frame.playerstate;
				j = (cl.frame.serverframe - 1) & UPDATE_MASK;
				oldframe = &cl.frames[j];
				if (oldframe->serverframe != cl.frame.serverframe-1 || !oldframe->valid)
					oldframe = &cl.frame;		// previous frame was dropped or involid
				ops = &oldframe->playerstate;
				// lerp for chasecam mode
				if (chasecam)
				{	// use player's original viewangles
					AngleVectors(cl.refdef.aimangles, f, r, u);
					VectorClear (pbeam_offset_dir);
					for (j=0; j<3; j++)
					{
						pbeam_offset_dir[j] += f[j]*thirdp_pbeam_offset[1];
						pbeam_offset_dir[j] += r[j]*thirdp_pbeam_offset[0]*newhandmult;
						pbeam_offset_dir[j] += u[j]*(-thirdp_pbeam_offset[2]);
					}
					for (j=0; j<3; j++)
						b->start[j] = cl.predicted_origin[j] + ops->viewoffset[j]
						+ cl.lerpfrac * (ps->viewoffset[j] - ops->viewoffset[j])
						+ pbeam_offset_dir[j];
				//	Com_Printf("%f, %f, %f\n", pbeam_offset_dir[0], pbeam_offset_dir[1], pbeam_offset_dir[2]);
					VectorMA (b->start, (newhandmult * b->offset[0]), r, org);
					VectorMA (     org, b->offset[1], f, org);
				 	VectorMA (     org, b->offset[2], u, org);
				}
				else // firstperson
				{
					AngleVectors(cl.refdef.aimangles,f,r,u);
					for (j=0; j<3; j++)
					{
		
						b->start[j] = cl.refdef.vieworg[j] + ops->gunoffset[j]
							+ cl.lerpfrac * (ps->gunoffset[j] - ops->gunoffset[j]);
					}
					VectorMA (b->start, (hand_multiplier * b->offset[0]), r, org);
					VectorMA (     org, b->offset[1], f, org);
					VectorMA (     org, b->offset[2], u, org);
					if ((hand) && (hand->value == 2)) {
						VectorMA (org, -1, u, org);
					}
				}
			}
			else // some other player or monster
				VectorCopy (b->start, org);
		}
		else // some other beam model
		{
			// if coming from the player, update the start position
			// skip for chasecam mode
			if (firstperson)
			{
				VectorCopy (cl.refdef.aimstart, b->start);
				b->start[2] -= 22;	// adjust for view height
			}
			VectorAdd (b->start, b->offset, org);
		}

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

//PMM

		if (clMedia.mod_heatbeam && (b->model == clMedia.mod_heatbeam) && (firstperson||chasecam))
		{
			vec_t len;
			vec3_t forward, right, up;
			AngleVectors(cl.refdef.aimangles,forward,right,up);
			len = VectorLength (dist);
			VectorScale (forward, len, dist);
			if (chasecam)
				VectorMA (dist, (newhandmult * b->offset[0]), right, dist);
			else
				VectorMA (dist, (hand_multiplier * b->offset[0]), right, dist);
			VectorMA (dist, b->offset[1], forward, dist);
			VectorMA (dist, b->offset[2], up, dist);
			if (chasecam) {
				VectorMA (dist, -(newhandmult * thirdp_pbeam_offset[0]), right, dist);
				VectorMA (dist, thirdp_pbeam_offset[1], forward, dist);
				VectorMA (dist, thirdp_pbeam_offset[2], up, dist);
			}
			if ((hand) && (hand->value == 2) && !chasecam)
				VectorMA (org, -1, up, org);
		}

//PMM

		if (dist[1] == 0 && dist[0] == 0)
		{
			yaw = 0;
			if (dist[2] > 0)
				pitch = 90;
			else
				pitch = 270;
		}
		else
		{
	// PMM - fixed to correct for pitch of 0
			if (dist[0])
				yaw = (atan2(dist[1], dist[0]) * 180 / M_PI);
			else if (dist[1] > 0)
				yaw = 90;
			else
				yaw = 270;
			if (yaw < 0)
				yaw += 360;
	
			forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]);
			pitch = (atan2(dist[2], forward) * -180.0 / M_PI);
			if (pitch < 0)
				pitch += 360.0; 
		}
		
		if (clMedia.mod_heatbeam && (b->model == clMedia.mod_heatbeam) )
		{
			if (!firstperson)
			{
				framenum = 2;
				ent.angles[0] = -pitch;
				ent.angles[1] = yaw + 180.0;
				ent.angles[2] = 0;
				// skip this for chasecam mode
				if (!chasecam)
				{
				//	Com_Printf ("%f %f - %f %f %f\n", -pitch, yaw+180.0, b->offset[0], b->offset[1], b->offset[2]);
					AngleVectors(ent.angles, f, r, u);

					// if it's a non-origin offset, it's a player, so use the hardcoded player offset
					if (!VectorCompare (b->offset, vec3_origin))
					{
						VectorMA (org, -(b->offset[0])+1, r, org);
						VectorMA (org, -(b->offset[1])+12, f, org); //was 0
						VectorMA (org, -(b->offset[2])-5, u, org); //was -10
					}
					else
					{
						// if it's a monster, do the particle effect
						CL_MonsterPlasma_Shell(b->start);
					}
				}
			}
			else
			{
				framenum = 1;
			}
		}

		// if it's the heatbeam, draw the particle effect
		// also do this in chasecam mode
		if ((clMedia.mod_heatbeam && (b->model == clMedia.mod_heatbeam) && (firstperson||chasecam)))
		{
			CL_HeatbeamParticles (org, dist);
		}

	// add new entities for the beams
		d = VectorNormalize(dist);

		memset (&ent, 0, sizeof(ent));
		if (b->model == clMedia.mod_heatbeam)
		{
			model_length = 32.0;
		}
		else if (b->model == clMedia.mod_lightning)
		{
			model_length = 35.0;
			d-= 20.0;  // correction so it doesn't end in middle of tesla
		}
		else
		{
			model_length = 30.0;
		}
		steps = ceil(d/model_length);
		len = (d-model_length)/(steps-1);

		// PMM - special case for lightning model .. if the real length is shorter than the model,
		// flip it around & draw it from the end to the start.  This prevents the model from going
		// through the tesla mine (instead it goes through the target)
		if ((b->model == clMedia.mod_lightning) && (d <= model_length))
		{
//			Com_Printf ("special case\n");
			VectorCopy (b->end, ent.origin);
			// offset to push beam outside of tesla model (negative because dist is from end to start
			// for this beam)
//			for (j=0 ; j<3 ; j++)
//				ent.origin[j] -= dist[j]*10.0;
			ent.model = b->model;
			ent.flags |= RF_FULLBRIGHT;
			ent.angles[0] = pitch;
			ent.angles[1] = yaw;
			ent.angles[2] = rand()%360;
			//AnglesToAxis(ent.angles, ent.axis);
			ent.flags |= RF_NOSHADOW; // beams don't cast shadows
			V_AddEntity (&ent);			
			return;
		}
		while (d > 0)
		{
			VectorCopy (org, ent.origin);
			ent.model = b->model;
			if (clMedia.mod_heatbeam && (b->model == clMedia.mod_heatbeam))
			{
			//	ent.flags |= RF_FULLBRIGHT|RF_TRANSLUCENT;
			//	ent.alpha = 0.6;
				ent.flags |= RF_FULLBRIGHT;
				ent.angles[0] = -pitch;
				ent.angles[1] = yaw + 180.0;
				ent.angles[2] = (cl.time) % 360;
			//	ent.angles[2] = rand()%360;
				ent.frame = framenum;
			}
			else if (b->model == clMedia.mod_lightning)
			{
				ent.flags |= RF_FULLBRIGHT;
				ent.angles[0] = -pitch;
				ent.angles[1] = yaw + 180.0;
				ent.angles[2] = rand()%360;
			}
			else
			{
				ent.angles[0] = pitch;
				ent.angles[1] = yaw;
				ent.angles[2] = rand()%360;
			}
			//AnglesToAxis(ent.angles, ent.axis);
			ent.flags |= RF_NOSHADOW; // beams don't cast shadows
		//	Com_Printf("B: %d -> %d\n", b->entity, b->dest_entity);
			V_AddEntity (&ent);

			for (j=0 ; j<3 ; j++)
				org[j] += dist[j]*len;
			d -= model_length;
		}
	}
}
Beispiel #7
0
void CL_AddBeams (void)
{
	int32_t			i,j;
	beam_t		*b;
	vec3_t		dist, org;
	float		d;
	entity_t	ent;
	float		yaw, pitch;
	float		forward;
	float		len, steps;
	float		model_length;
	frame_t		*oldframe; 	// added
	player_state_t	*ps, *ops;
	qboolean	firstperson, chasecam;
	int32_t			handmult;
	vec3_t		thirdp_grapple_offset;
	vec3_t		grapple_offset_dir;

	// chasecam grapple offset stuff
	if (hand)
	{
		if (hand->value == 2)
			handmult = 1;
		else if (hand->value == 1)
			handmult = -1;
		else
			handmult = 1;
	}
	else 
		handmult = 1;
	VectorSet(thirdp_grapple_offset, 6, 16, 16);
	// end third person grapple

// update beams
	for (i=0, b=cl_beams; i< MAX_BEAMS; i++, b++)
	{
		if (!b->model || b->endtime < cl.time)
			continue;

		firstperson = ((b->entity == cl.playernum+1) && !cg_thirdperson->value);
		chasecam = ((b->entity == cl.playernum+1) && cg_thirdperson->value);

		// if coming from the player, update the start position
		if (firstperson)	// entity 0 is the world
		{
			VectorCopy (cl.refdef.vieworg, b->start);
			b->start[2] -= 22;	// adjust for view height
		}
		else if (chasecam)
		{
			vec3_t		f,r,u;

			ps = &cl.frame.playerstate;
			j = (cl.frame.serverframe - 1) & UPDATE_MASK;
			oldframe = &cl.frames[j];
			if (oldframe->serverframe != cl.frame.serverframe-1 || !oldframe->valid)
				oldframe = &cl.frame;
			ops = &oldframe->playerstate;

			AngleVectors(old_viewangles, f, r, u);
			VectorClear (grapple_offset_dir);
			for (j=0; j<3; j++)
			{
				grapple_offset_dir[j] += f[j]*thirdp_grapple_offset[1];
				grapple_offset_dir[j] += r[j]*thirdp_grapple_offset[0]*handmult;
				grapple_offset_dir[j] += u[j]*(-thirdp_grapple_offset[2]);
			}

			for (j=0; j<3; j++)
				b->start[j] = cl.predicted_origin[j] + ops->viewoffset[j]
				+ cl.lerpfrac * (ps->viewoffset[j] - ops->viewoffset[j])
				+ grapple_offset_dir[j];
		//	Com_Printf("%f, %f, %f\n", grapple_offset_dir[0], grapple_offset_dir[1], grapple_offset_dir[2]);
		}
		if (chasecam)
			VectorCopy (b->start, org);
		else
			VectorAdd (b->start, b->offset, org);

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

		if (dist[1] == 0 && dist[0] == 0)
		{
			yaw = 0;
			if (dist[2] > 0)
				pitch = 90;
			else
				pitch = 270;
		}
		else
		{
	// PMM - fixed to correct for pitch of 0
			if (dist[0])
				yaw = (atan2(dist[1], dist[0]) * 180 / M_PI);
			else if (dist[1] > 0)
				yaw = 90;
			else
				yaw = 270;
			if (yaw < 0)
				yaw += 360;
	
			forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]);
			pitch = (atan2(dist[2], forward) * -180.0 / M_PI);
			if (pitch < 0)
				pitch += 360.0;
		}

	// add new entities for the beams
		d = VectorNormalize(dist);

		memset (&ent, 0, sizeof(ent));
		if (b->model == clMedia.mod_lightning)
		{
			model_length = 35.0;
			d-= 20.0;  // correction so it doesn't end in middle of tesla
		}
		else
		{
			model_length = 30.0;
		}
		steps = ceil(d/model_length);
		len = (d-model_length)/(steps-1);

		// PMM - special case for lightning model .. if the real length is shorter than the model,
		// flip it around & draw it from the end to the start.  This prevents the model from going
		// through the tesla mine (instead it goes through the target)
		if ((b->model == clMedia.mod_lightning) && (d <= model_length))
		{
//			Com_Printf ("special case\n");
			VectorCopy (b->end, ent.origin);
			// offset to push beam outside of tesla model (negative because dist is from end to start
			// for this beam)
//			for (j=0 ; j<3 ; j++)
//				ent.origin[j] -= dist[j]*10.0;
			ent.model = b->model;
			ent.flags |= RF_FULLBRIGHT;
			ent.angles[0] = pitch;
			ent.angles[1] = yaw;
			ent.angles[2] = rand()%360;
			//AnglesToAxis(ent.angles, ent.axis);
			V_AddEntity (&ent);			
			return;
		}
		while (d > 0)
		{
			VectorCopy (org, ent.origin);
			ent.model = b->model;
			if (b->model == clMedia.mod_lightning)
			{
				ent.flags |= RF_FULLBRIGHT;
				ent.angles[0] = -pitch;
				ent.angles[1] = yaw + 180.0;
				ent.angles[2] = rand()%360;
			}
			else
			{
				ent.angles[0] = pitch;
				ent.angles[1] = yaw;
				ent.angles[2] = rand()%360;
			}
			//AnglesToAxis(ent.angles, ent.axis);

			ent.flags |= RF_NOSHADOW; // beams don't cast shadows
//			Com_Printf("B: %d -> %d\n", b->entity, b->dest_entity);
			V_AddEntity (&ent);

			for (j=0 ; j<3 ; j++)
				org[j] += dist[j]*len;
			d -= model_length;
		}
	}
}
Beispiel #8
0
void NQD_LinkEntities (void)
{
	entity_t			ent;
	centity_t			*cent;
	entity_state_t		*state;
	float				f;
	struct model_s		*model;
	int					modelflags;
	vec3_t				cur_origin;
	vec3_t				old_origin;
	float				autorotate;
	int					i;
	int					num;

	f = NQD_LerpPoint ();

	NQD_LerpPlayerinfo (f);

	autorotate = anglemod (100*cl.time);

	memset (&ent, 0, sizeof(ent));

	for (num = 1; num < nq_num_entities; num++)
	{
		cent = &cl_entities[num];
		state = &cent->current;

		if (cent->lastframe != cl_entframecount)
			continue;		// not present in this frame

		MSG_UnpackOrigin (state->s_origin, cur_origin);

		if (state->effects & EF_BRIGHTFIELD)
			CL_EntityParticles (cur_origin);

		// spawn light flashes, even ones coming from invisible objects
		if (state->effects & EF_MUZZLEFLASH) {
			vec3_t		angles, forward;
			cdlight_t	*dl;

			dl = CL_AllocDlight (-num);
			MSG_UnpackAngles (state->s_angles, angles);
			AngleVectors (angles, forward, NULL, NULL);
			VectorMA (cur_origin, 18, forward, dl->origin);
			dl->origin[2] += 16;
			dl->radius = 200 + (rand()&31);
			dl->minlight = 32;
			dl->die = cl.time + 0.1;
			dl->type = lt_muzzleflash;
		}
		if (state->effects & EF_BRIGHTLIGHT) {
			if (state->modelindex != cl_playerindex || r_powerupglow.value) {
				vec3_t	tmp;
				VectorCopy (cur_origin, tmp);
				tmp[2] += 16;
				V_AddDlight (state->number, tmp, 400 + (rand()&31), 0, lt_default);
			}
		}
		if (state->effects & EF_DIMLIGHT)
			if (state->modelindex != cl_playerindex || r_powerupglow.value)
				V_AddDlight (state->number, cur_origin, 200 + (rand()&31), 0, lt_default);

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

		cent->current = *state;

		ent.model = model = cl.model_precache[state->modelindex];
		if (!model)
			Host_Error ("CL_LinkPacketEntities: bad modelindex");

		if (cl_r2g.value && cl_grenadeindex != -1)
			if (state->modelindex == cl_rocketindex)
				ent.model = cl.model_precache[cl_grenadeindex];

		modelflags = R_ModelFlags (model);

		// rotate binary objects locally
		if (modelflags & MF_ROTATE)
		{
			ent.angles[0] = 0;
			ent.angles[1] = autorotate;
			ent.angles[2] = 0;
		}
		else
		{
			vec3_t	old, cur;

			MSG_UnpackAngles (cent->current.s_angles, old);
			MSG_UnpackAngles (cent->previous.s_angles, cur);
			LerpAngles (old, cur, f, ent.angles);
		}

if (num == nq_viewentity) {
extern float nq_speed;
float f;
nq_speed = 0;
	for (i = 0; i < 3; i++) {
		f = (cent->current.s_origin[i] - cent->previous.s_origin[i]) * 0.125;
		nq_speed += f * f;
	}
if (nq_speed) nq_speed = sqrt(nq_speed);
nq_speed /= nq_mtime[0] - nq_mtime[1];

}

		// calculate origin
		for (i = 0; i < 3; i++)
		{
			if (abs(cent->current.s_origin[i] - cent->previous.s_origin[i]) > 128 * 8) {
				// teleport or something, don't lerp
				VectorCopy (cur_origin, ent.origin);
				if (num == nq_viewentity)
					nq_player_teleported = true;
				break;
			}
			ent.origin[i] = cent->previous.s_origin[i] * 0.125 + 
				f * (cur_origin[i] - cent->previous.s_origin[i] * 0.125);
		}

		if (num == nq_viewentity) {
			VectorCopy (ent.origin, cent->trail_origin);	// FIXME?
			continue;			// player entity
		}

		if (cl_deadbodyfilter.value && state->modelindex == cl_playerindex
			&& ( (i=state->frame)==49 || i==60 || i==69 || i==84 || i==93 || i==102) )
			continue;

		if (cl_gibfilter.value && cl.modelinfos[state->modelindex] == mi_gib)
			continue;

		// set colormap
		if (state->colormap && state->colormap <= MAX_CLIENTS
			&& state->modelindex == cl_playerindex
		)
			ent.colormap = state->colormap;
		else
			ent.colormap = 0;

		// set skin
		ent.skinnum = state->skinnum;
		
		// set frame
		ent.frame = state->frame;

		// add automatic particle trails
		if ((modelflags & ~MF_ROTATE))
		{
			if (false /*cl_entframecount == 1 || cent->lastframe != cl_entframecount-1*/)
			{	// not in last message
				VectorCopy (ent.origin, old_origin);
			}
			else
			{
				VectorCopy (cent->trail_origin, old_origin);

				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 (modelflags & MF_ROCKET)
			{
				if (r_rockettrail.value) {
					if (r_rockettrail.value == 2)
						CL_GrenadeTrail (old_origin, ent.origin, cent->trail_origin);
					else
						CL_RocketTrail (old_origin, ent.origin, cent->trail_origin);
				} else
					VectorCopy (ent.origin, cent->trail_origin);

				if (r_rocketlight.value)
					CL_NewDlight (state->number, ent.origin, 200, 0.1, lt_rocket);
			}
			else if (modelflags & MF_GRENADE && r_grenadetrail.value)
				CL_GrenadeTrail (old_origin, ent.origin, cent->trail_origin);
			else if (modelflags & MF_GIB)
				CL_BloodTrail (old_origin, ent.origin, cent->trail_origin);
			else if (modelflags & MF_ZOMGIB)
				CL_SlightBloodTrail (old_origin, ent.origin, cent->trail_origin);
			else if (modelflags & MF_TRACER)
				CL_TracerTrail (old_origin, ent.origin, cent->trail_origin, 52);
			else if (modelflags & MF_TRACER2)
				CL_TracerTrail (old_origin, ent.origin, cent->trail_origin, 230);
			else if (modelflags & MF_TRACER3)
				CL_VoorTrail (old_origin, ent.origin, cent->trail_origin);
		}

		cent->lastframe = cl_entframecount;
		V_AddEntity (&ent);
	}

	if (nq_viewentity == 0)
		Host_Error ("viewentity == 0");
	VectorCopy (cl_entities[nq_viewentity].trail_origin, cl.simorg);
}
Beispiel #9
0
/*
==================
V_AddViewWeapon
==================
*/
void V_AddViewWeapon (float bob)
{
	vec3_t		forward, up;
	entity_t	ent;
	extern cvar_t	scr_fov;
	// FIXME, move the statics to a structure like cl
	static int oldweapon, curframe, oldframe;
	static double start_lerp_time;

	if (!cl_drawgun.value || (cl_drawgun.value == 2 && scr_fov.value > 90)
		|| view_message.flags & (PF_GIB|PF_DEAD)
		|| !Cam_DrawViewModel())
		return;

	memset (&ent, 0, sizeof(ent));

	if ((unsigned int)cl.stats[STAT_WEAPON] >= MAX_MODELS)
		Host_Error ("STAT_WEAPON >= MAX_MODELS");
	ent.model = cl.model_precache[cl.stats[STAT_WEAPON]];
	if (!ent.model)
		return;
	ent.frame = view_message.weaponframe;
	ent.colormap = 0;
	ent.renderfx = RF_WEAPONMODEL;

	if (cl.stats[STAT_WEAPON] != oldweapon) {
		oldweapon = cl.stats[STAT_WEAPON];
		curframe = -1;
		start_lerp_time = -1;
	}
	if (ent.frame != curframe) {
		oldframe = curframe;
		curframe = ent.frame;
		start_lerp_time = cl.time;
	}
	ent.oldframe = oldframe;
	ent.backlerp = 1 - (cl.time - start_lerp_time)*10;
	ent.backlerp = bound (0, ent.backlerp, 1);

//	if (r_lerpmuzzlehack.value && cl.modelinfos[cl.stats[STAT_WEAPON]] != mi_no_lerp_hack)
//		ent.renderfx |= RF_LIMITLERP;

	if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
		ent.alpha = 128;

	ent.angles[YAW] = r_refdef2.viewangles[YAW];
	ent.angles[PITCH] = -r_refdef2.viewangles[PITCH];
	ent.angles[ROLL] = r_refdef2.viewangles[ROLL];

	AngleVectors (r_refdef2.viewangles, forward, NULL, up);
	
	VectorCopy (r_refdef2.vieworg, ent.origin);

	if (cl_bobmodel.value) {
		// calculate for swinging gun model
		// the gun bobs when running on the ground, but doesn't bob when you're in the air.
		// Sajt: I tried to smooth out the transitions between bob and no bob, which works
		// for the most part, but for some reason when you go through a message trigger or
		// pick up an item or anything like that it will momentarily jolt the gun.
		vec3_t forward, right, up;
		static double lastongroundtime = 0;
		double xyspeed;
		float bspeed;
		float s, t;

		xyspeed = sqrt(cl.simvel[0] * cl.simvel[0] + cl.simvel[1] * cl.simvel[1]);
		s = cl.time * cl_bobmodel_speed.value;
		if (cl.onground) {
			lastongroundtime = cl.time;
			if (cl.time - cl.landtime < 0.2) {
				// just hit the ground, speed the bob back up over the next 0.2 seconds
				t = cl.time - cl.landtime;
				t = bound(0, t, 0.2);
				t *= 5;
			} else {
				t = 1;
			}
		} else {
			// recently left the ground, slow the bob down over the next 0.2 seconds
			t = cl.time - lastongroundtime;
			t = 0.2 - bound(0, t, 0.2);
			t *= 5;
		}

		bspeed = bound (0, xyspeed, 400) * 0.01f;
		AngleVectors (r_refdef2.viewangles, forward, right, up);
		bob = bspeed * cl_bobmodel_side.value * sin (s) * t;
		VectorMA (ent.origin, bob, right, ent.origin);
		bob = bspeed * cl_bobmodel_up.value * cos (s * 2) * t;
		VectorMA (ent.origin, bob, up, ent.origin);
	}

	// fudge position around to keep amount of weapon visible
	// roughly equal with different FOV
	if (scr_viewsize.value == 110)
		VectorMA (ent.origin, 1, up, ent.origin);
	else if (scr_viewsize.value == 100)
		VectorMA (ent.origin, 2, up, ent.origin);
	else if (scr_viewsize.value == 90)
		VectorMA (ent.origin, 1, up, ent.origin);
	else if (scr_viewsize.value == 80)
		VectorMA (ent.origin, 0.5, up, ent.origin);

	V_AddEntity (&ent);
}