コード例 #1
0
ファイル: entities.cpp プロジェクト: janisl/jlquake
static void CLH2_RelinkEntities() {
	h2entity_t* ent;
	int i, j;
	float frac, f, d;
	vec3_t delta;
	//float		bobjrotate;
	vec3_t oldorg;
	int c;

	c = 0;
	// determine partial update time
	frac = CLQH_LerpPoint();

	//
	// interpolate player info
	//
	for ( i = 0; i < 3; i++ ) {
		cl.qh_velocity[ i ] = cl.qh_mvelocity[ 1 ][ i ] +
							  frac * ( cl.qh_mvelocity[ 0 ][ i ] - cl.qh_mvelocity[ 1 ][ i ] );
	}

	if ( clc.demoplaying && !h2intro_playing ) {
		// interpolate the angles
		for ( j = 0; j < 3; j++ ) {
			d = cl.qh_mviewangles[ 0 ][ j ] - cl.qh_mviewangles[ 1 ][ j ];
			if ( d > 180 ) {
				d -= 360;
			} else if ( d < -180 ) {
				d += 360;
			}
			cl.viewangles[ j ] = cl.qh_mviewangles[ 1 ][ j ] + frac * d;
		}
	}

	// start on the entity after the world
	for ( i = 1,ent = h2cl_entities + 1; i < cl.qh_num_entities; i++,ent++ ) {
		if ( !ent->state.modelindex ) {
			// empty slot
			continue;
		}

		// if the object wasn't included in the last packet, remove it
		if ( ent->msgtime != cl.qh_mtime[ 0 ] && !( clh2_baselines[ i ].flags & BE_ON ) ) {
			ent->state.modelindex = 0;
			continue;
		}

		VectorCopy( ent->state.origin, oldorg );

		if ( ent->msgtime != cl.qh_mtime[ 0 ] ) {	// the entity was not updated in the last message
												// so move to the final spot
			VectorCopy( ent->msg_origins[ 0 ], ent->state.origin );
			VectorCopy( ent->msg_angles[ 0 ], ent->state.angles );
		} else {	// if the delta is large, assume a teleport and don't lerp
			f = frac;
			for ( j = 0; j < 3; j++ ) {
				delta[ j ] = ent->msg_origins[ 0 ][ j ] - ent->msg_origins[ 1 ][ j ];

				if ( delta[ j ] > 100 || delta[ j ] < -100 ) {
					f = 1;		// assume a teleportation, not a motion
				}
			}

			// interpolate the origin and angles
			for ( j = 0; j < 3; j++ ) {
				ent->state.origin[ j ] = ent->msg_origins[ 1 ][ j ] + f * delta[ j ];

				d = ent->msg_angles[ 0 ][ j ] - ent->msg_angles[ 1 ][ j ];
				if ( d > 180 ) {
					d -= 360;
				} else if ( d < -180 ) {
					d += 360;
				}
				ent->state.angles[ j ] = ent->msg_angles[ 1 ][ j ] + f * d;
			}
		}

		c++;
		if ( ent->state.effects & H2EF_DARKFIELD ) {
			CLH2_DarkFieldParticles( ent->state.origin );
		}
		if ( ent->state.effects & H2EF_MUZZLEFLASH ) {
			CLH2_MuzzleFlashLight( i, ent->state.origin, ent->state.angles, true );
		}
		if ( ent->state.effects & H2EF_BRIGHTLIGHT ) {
			CLH2_BrightLight( i, ent->state.origin );
		}
		if ( ent->state.effects & H2EF_DIMLIGHT ) {
			CLH2_DimLight( i, ent->state.origin );
		}
		if ( ent->state.effects & H2EF_DARKLIGHT ) {
			CLH2_DarkLight( i, ent->state.origin );
		}
		if ( ent->state.effects & H2EF_LIGHT ) {
			CLH2_Light( i, ent->state.origin );
		}

		int ModelFlags = R_ModelFlags( cl.model_draw[ ent->state.modelindex ] );
		if ( ModelFlags & H2MDLEF_GIB ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_blood );
		} else if ( ModelFlags & H2MDLEF_ZOMGIB ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_slight_blood );
		} else if ( ModelFlags & H2MDLEF_BLOODSHOT ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_bloodshot );
		} else if ( ModelFlags & H2MDLEF_TRACER ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_tracer );
		} else if ( ModelFlags & H2MDLEF_TRACER2 ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_tracer2 );
		} else if ( ModelFlags & H2MDLEF_ROCKET ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_rocket_trail );
		} else if ( ModelFlags & H2MDLEF_FIREBALL ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_fireball );
			CLH2_FireBallLight( i, ent->state.origin );
		} else if ( ModelFlags & H2MDLEF_ACIDBALL ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_acidball );
			CLH2_FireBallLight( i, ent->state.origin );
		} else if ( ModelFlags & H2MDLEF_ICE ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_ice );
		} else if ( ModelFlags & H2MDLEF_SPIT ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_spit );
			CLH2_SpitLight( i, ent->state.origin );
		} else if ( ModelFlags & H2MDLEF_SPELL ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_spell );
		} else if ( ModelFlags & H2MDLEF_GRENADE ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_smoke );
		} else if ( ModelFlags & H2MDLEF_TRACER3 ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_voor_trail );
		} else if ( ModelFlags & H2MDLEF_VORP_MISSILE ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_vorpal );
		} else if ( ModelFlags & H2MDLEF_SET_STAFF ) {
			CLH2_TrailParticles( oldorg, ent->state.origin,rt_setstaff );
		} else if ( ModelFlags & H2MDLEF_MAGICMISSILE ) {
			if ( ( rand() & 3 ) < 1 ) {
				CLH2_TrailParticles( oldorg, ent->state.origin, rt_magicmissile );
			}
		} else if ( ModelFlags & H2MDLEF_BONESHARD ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_boneshard );
		} else if ( ModelFlags & H2MDLEF_SCARAB ) {
			CLH2_TrailParticles( oldorg, ent->state.origin, rt_scarab );
		}

		if ( ent->state.effects & H2EF_NODRAW ) {
			continue;
		}

		refEntity_t rent;
		Com_Memset( &rent, 0, sizeof ( rent ) );
		rent.reType = RT_MODEL;
		VectorCopy( ent->state.origin, rent.origin );
		rent.hModel = cl.model_draw[ ent->state.modelindex ];
		rent.frame = ent->state.frame;
		rent.syncBase = ent->syncbase;
		rent.skinNum = ent->state.skinnum;
		CLH2_SetRefEntAxis( &rent, ent->state.angles, oldvec3_origin, ent->state.scale, ent->state.abslight, ent->state.drawflags );
		CLH2_HandleCustomSkin( &rent );
		if ( i <= cl.qh_maxclients ) {
			CLH2_SetPlayerColours( &rent, i - 1 );
		}
		if ( i == cl.viewentity && !chase_active->value ) {
			rent.renderfx |= RF_THIRD_PERSON;
		}
		R_AddRefEntityToScene( &rent );
		CLH2_AddColourShadeRefEnt( &rent, ent->state.colormap, ent->state.drawflags );
	}
}
コード例 #2
0
ファイル: entities.cpp プロジェクト: janisl/jlquake
static void CLHW_LinkPacketEntities() {
	hwpacket_entities_t* pack = &cl.hw_frames[ clc.netchan.incomingSequence & UPDATE_MASK_HW ].packet_entities;
	hwpacket_entities_t* PrevPack = &cl.hw_frames[ ( clc.netchan.incomingSequence - 1 ) & UPDATE_MASK_HW ].packet_entities;

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

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

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

		// create a new entity
		refEntity_t ent;
		Com_Memset( &ent, 0, sizeof ( ent ) );

		ent.reType = RT_MODEL;
		qhandle_t model = cl.model_draw[ s1->modelindex ];
		ent.hModel = model;

		// set skin
		ent.skinNum = s1->skinnum;

		// set frame
		ent.frame = s1->frame;

		int drawflags = s1->drawflags;

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

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

		// scan the old entity display list for a matching
		vec3_t old_origin;
		int i;
		for ( i = 0; i < PrevPack->num_entities; i++ ) {
			if ( PrevPack->entities[ i ].number == s1->number ) {
				VectorCopy( PrevPack->entities[ i ].origin, old_origin );
				break;
			}
		}
		if ( i == PrevPack->num_entities ) {
			CLH2_SetRefEntAxis( &ent, angles, oldvec3_origin, s1->scale, s1->abslight, drawflags );
			R_AddRefEntityToScene( &ent );
			CLH2_AddColourShadeRefEnt( &ent, s1->colormap, drawflags );
			continue;		// not in last message
		}

		for ( i = 0; i < 3; i++ )
			//if ( abs(old_origin[i] - ent->origin[i]) > 128)
			if ( abs( old_origin[ i ] - ent.origin[ i ] ) > 512 ) {	// this is an issue for laggy situations...
				// no trail if too far
				VectorCopy( ent.origin, old_origin );
				break;
			}

		// some of the effects need to know how far the thing has moved...

		if ( clhw_siege ) {
			if ( ( int )s1->effects & H2EF_NODRAW ) {
				ent.skinNum = 101;	//ice, but in siege will be invis skin for dwarf to see
				drawflags |= H2DRF_TRANSLUCENT;
				s1->effects &= ~H2EF_NODRAW;
			}
		}

		vec3_t angleAdd;
		HandleEffects( s1->effects, s1->number, &ent, angles, angleAdd );
		CLH2_SetRefEntAxis( &ent, angles, angleAdd, s1->scale, s1->abslight, drawflags );
		R_AddRefEntityToScene( &ent );
		CLH2_AddColourShadeRefEnt( &ent, s1->colormap, drawflags );

		// add automatic particle trails
		int ModelFlags = R_ModelFlags( ent.hModel );
		if ( !ModelFlags ) {
			continue;
		}

		// Model Flags
		if ( ModelFlags & H2MDLEF_GIB ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_blood );
		} else if ( ModelFlags & H2MDLEF_ZOMGIB ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_slight_blood );
		} else if ( ModelFlags & H2MDLEF_TRACER ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_tracer );
		} else if ( ModelFlags & H2MDLEF_TRACER2 ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_tracer2 );
		} else if ( ModelFlags & H2MDLEF_ROCKET ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_rocket_trail );
		} else if ( ModelFlags & H2MDLEF_FIREBALL ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_fireball );
			CLH2_FireBallLight( i, ent.origin );
		} else if ( ModelFlags & H2MDLEF_ICE ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_ice );
		} else if ( ModelFlags & H2MDLEF_SPIT ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_spit );
			CLH2_SpitLight( i, ent.origin );
		} else if ( ModelFlags & H2MDLEF_SPELL ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_spell );
		} else if ( ModelFlags & H2MDLEF_GRENADE ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_grensmoke );
		} else if ( ModelFlags & H2MDLEF_TRACER3 ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_voor_trail );
		} else if ( ModelFlags & H2MDLEF_VORP_MISSILE ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_vorpal );
		} else if ( ModelFlags & H2MDLEF_SET_STAFF ) {
			CLH2_TrailParticles( old_origin, ent.origin,rt_setstaff );
		} else if ( ModelFlags & H2MDLEF_MAGICMISSILE ) {
			if ( ( rand() & 3 ) < 1 ) {
				CLH2_TrailParticles( old_origin, ent.origin, rt_magicmissile );
			}
		} else if ( ModelFlags & H2MDLEF_BONESHARD ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_boneshard );
		} else if ( ModelFlags & H2MDLEF_SCARAB ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_scarab );
		} else if ( ModelFlags & H2MDLEF_ACIDBALL ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_acidball );
		} else if ( ModelFlags & H2MDLEF_BLOODSHOT ) {
			CLH2_TrailParticles( old_origin, ent.origin, rt_bloodshot );
		}
	}
}
コード例 #3
0
ファイル: entities.cpp プロジェクト: janisl/jlquake
void CLH2_SetRefEntAxis( refEntity_t* entity, vec3_t entityAngles, vec3_t angleAdd, int scale, int absoluteLight, int drawFlags ) {
	if ( drawFlags & H2DRF_TRANSLUCENT ) {
		entity->renderfx |= RF_TRANSLUCENT;
		entity->shaderRGBA[ 3 ] = 100;
	}

	vec3_t angles;
	if ( R_IsMeshModel( entity->hModel ) ) {
		if ( R_ModelFlags( entity->hModel ) & H2MDLEF_FACE_VIEW ) {
			//	yaw and pitch must be 0 so that renderer can safely multply matrices.
			angles[ PITCH ] = 0;
			angles[ YAW ] = 0;
			angles[ ROLL ] = entityAngles[ ROLL ];

			AnglesToAxis( angles, entity->axis );
		} else {
			if ( R_ModelFlags( entity->hModel ) & H2MDLEF_ROTATE ) {
				angles[ YAW ] = AngleMod( ( entity->origin[ 0 ] + entity->origin[ 1 ] ) * 0.8 + ( 108 * cl.serverTime * 0.001 ) );
			} else {
				angles[ YAW ] = entityAngles[ YAW ];
			}
			angles[ ROLL ] = entityAngles[ ROLL ];
			// stupid quake bug
			angles[ PITCH ] = -entityAngles[ PITCH ];

			if ( angleAdd[ 0 ] || angleAdd[ 1 ] || angleAdd[ 2 ] ) {
				float BaseAxis[ 3 ][ 3 ];
				AnglesToAxis( angles, BaseAxis );

				// For clientside rotation stuff
				float AddAxis[ 3 ][ 3 ];
				AnglesToAxis( angleAdd, AddAxis );

				MatrixMultiply( AddAxis, BaseAxis, entity->axis );
			} else {
				AnglesToAxis( angles, entity->axis );
			}
		}

		if ( ( R_ModelFlags( entity->hModel ) & H2MDLEF_ROTATE ) || ( scale != 0 && scale != 100 ) ) {
			entity->renderfx |= RF_LIGHTING_ORIGIN;
			VectorCopy( entity->origin, entity->lightingOrigin );
		}

		if ( R_ModelFlags( entity->hModel ) & H2MDLEF_ROTATE ) {
			// Floating motion
			float delta = sin( entity->origin[ 0 ] + entity->origin[ 1 ] + ( cl.serverTime * 0.001 * 3 ) ) * 5.5;
			VectorMA( entity->origin, delta, entity->axis[ 2 ], entity->origin );
			absoluteLight = 60 + 34 + sin( entity->origin[ 0 ] + entity->origin[ 1 ] + ( cl.serverTime * 0.001 * 3.8 ) ) * 34;
			drawFlags |= H2MLS_ABSLIGHT;
		}

		if ( scale != 0 && scale != 100 ) {
			float entScale = ( float )scale / 100.0;
			float esx;
			float esy;
			float esz;
			switch ( drawFlags & H2SCALE_TYPE_MASKIN ) {
			case H2SCALE_TYPE_UNIFORM:
				esx = entScale;
				esy = entScale;
				esz = entScale;
				break;
			case H2SCALE_TYPE_XYONLY:
				esx = entScale;
				esy = entScale;
				esz = 1;
				break;
			case H2SCALE_TYPE_ZONLY:
				esx = 1;
				esy = 1;
				esz = entScale;
				break;
			}
			float etz;
			switch ( drawFlags & H2SCALE_ORIGIN_MASKIN ) {
			case H2SCALE_ORIGIN_CENTER:
				etz = 0.5;
				break;
			case H2SCALE_ORIGIN_BOTTOM:
				etz = 0;
				break;
			case H2SCALE_ORIGIN_TOP:
				etz = 1.0;
				break;
			}

			vec3_t Out;
			R_CalculateModelScaleOffset( entity->hModel, esx, esy, esz, etz, Out );
			VectorMA( entity->origin, Out[ 0 ], entity->axis[ 0 ], entity->origin );
			VectorMA( entity->origin, Out[ 1 ], entity->axis[ 1 ], entity->origin );
			VectorMA( entity->origin, Out[ 2 ], entity->axis[ 2 ], entity->origin );
			VectorScale( entity->axis[ 0 ], esx, entity->axis[ 0 ] );
			VectorScale( entity->axis[ 1 ], esy, entity->axis[ 1 ] );
			VectorScale( entity->axis[ 2 ], esz, entity->axis[ 2 ] );
			entity->nonNormalizedAxes = true;
		}
	} else {
		angles[ YAW ] = entityAngles[ YAW ];
		angles[ ROLL ] = entityAngles[ ROLL ];
		angles[ PITCH ] = entityAngles[ PITCH ];

		AnglesToAxis( angles, entity->axis );
	}

	int mls = drawFlags & H2MLS_MASKIN;
	if ( mls == H2MLS_ABSLIGHT ) {
		entity->renderfx |= RF_ABSOLUTE_LIGHT;
		entity->absoluteLight = absoluteLight / 128.0;
	} else if ( mls != H2MLS_NONE ) {
		// Use a model light style (25-30)
		entity->renderfx |= RF_ABSOLUTE_LIGHT;
		entity->absoluteLight = cl_lightstyle[ 24 + mls ].value[ 0 ] / 2;
	}
}
コード例 #4
0
ファイル: cl_nqdemo.c プロジェクト: luaman/zq
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);
}