void CL_UpdateEntityFields( cl_entity_t *ent ) { // parametric rockets code if( ent->curstate.starttime != 0.0f && ent->curstate.impacttime != 0.0f ) { float lerp = ( cl.time - ent->curstate.starttime ) / ( ent->curstate.impacttime - ent->curstate.starttime ); vec3_t dir; lerp = bound( 0.0f, lerp, 1.0f ); // first we need to calc actual origin VectorLerp( ent->curstate.startpos, lerp, ent->curstate.endpos, ent->curstate.origin ); VectorSubtract( ent->curstate.endpos, ent->curstate.startpos, dir ); VectorAngles( dir, ent->curstate.angles ); // re-aim projectile } ent->model = Mod_Handle( ent->curstate.modelindex ); ent->curstate.msg_time = cl.time; CL_InterpolateModel( ent ); if( ent->player && RP_LOCALCLIENT( ent )) // stupid Half-Life bug ent->angles[PITCH] = -ent->angles[PITCH] / 3.0f; // make me lerp if( ent->model && ent->model->type == mod_brush && ent->curstate.animtime != 0.0f ) { float d, f = 0.0f; int i; // don't do it if the goalstarttime hasn't updated in a while. // NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit // was increased to 1.0 s., which is 2x the max lag we are accounting for. if(( cl.time < ent->curstate.animtime + 1.0f ) && ( ent->curstate.animtime != ent->latched.prevanimtime )) f = ( cl.time - ent->curstate.animtime ) / ( ent->curstate.animtime - ent->latched.prevanimtime ); f = f - 1.0f; ent->origin[0] += ( ent->origin[0] - ent->latched.prevorigin[0] ) * f; ent->origin[1] += ( ent->origin[1] - ent->latched.prevorigin[1] ) * f; ent->origin[2] += ( ent->origin[2] - ent->latched.prevorigin[2] ) * f; for( i = 0; i < 3; i++ ) { float ang1, ang2; ang1 = ent->angles[i]; ang2 = ent->latched.prevangles[i]; d = ang1 - ang2; if( d > 180.0f ) d -= 360.0f; else if( d < -180.0f ) d += 360.0f; ent->angles[i] += d * f; } } else if( ent->curstate.eflags & EFLAG_SLERP ) { float d, f = 0.0f; cl_entity_t *m_pGround = NULL; int i; // don't do it if the goalstarttime hasn't updated in a while. // NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit // was increased to 1.0 s., which is 2x the max lag we are accounting for. if(( cl.time < ent->curstate.animtime + 1.0f ) && ( ent->curstate.animtime != ent->latched.prevanimtime )) f = ( cl.time - ent->curstate.animtime ) / ( ent->curstate.animtime - ent->latched.prevanimtime ); f = f - 1.0f; if( ent->curstate.movetype == MOVETYPE_FLY ) { ent->origin[0] += ( ent->curstate.origin[0] - ent->latched.prevorigin[0] ) * f; ent->origin[1] += ( ent->curstate.origin[1] - ent->latched.prevorigin[1] ) * f; ent->origin[2] += ( ent->curstate.origin[2] - ent->latched.prevorigin[2] ) * f; for( i = 0; i < 3; i++ ) { float ang1, ang2; ang1 = ent->curstate.angles[i]; ang2 = ent->latched.prevangles[i]; d = ang1 - ang2; if( d > 180.0f ) d -= 360.0f; else if( d < -180.0f ) d += 360.0f; ent->angles[i] += d * f; } } else if( ent->curstate.movetype == MOVETYPE_STEP ) { vec3_t vecSrc, vecEnd; pmtrace_t trace; if( ent->model ) { CL_SetTraceHull( 0 ); // g-cont. player hull for better detect moving platforms VectorSet( vecSrc, ent->origin[0], ent->origin[1], ent->origin[2] + ent->model->maxs[2] ); VectorSet( vecEnd, vecSrc[0], vecSrc[1], vecSrc[2] - ent->model->mins[2] - 8.0f ); CL_PlayerTraceExt( vecSrc, vecEnd, PM_STUDIO_IGNORE, CL_PushMoveFilter, &trace ); m_pGround = CL_GetEntityByIndex( pfnIndexFromTrace( &trace )); } if( m_pGround && m_pGround->curstate.movetype == MOVETYPE_PUSH ) { qboolean applyVel, applyAvel; applyVel = !VectorCompare( m_pGround->curstate.origin, m_pGround->prevstate.origin ); applyAvel = !VectorCompare( m_pGround->curstate.angles, m_pGround->prevstate.angles ); if( applyVel || applyAvel ) { ent->origin[0] += ( m_pGround->curstate.origin[0] - m_pGround->prevstate.origin[0] ) * -1.0f; ent->origin[1] += ( m_pGround->curstate.origin[1] - m_pGround->prevstate.origin[1] ) * -1.0f; // ent->origin[2] += ( m_pGround->curstate.origin[2] - m_pGround->prevstate.origin[2] ) * -1.0f; ent->latched.prevorigin[2] = ent->origin[2]; } if( applyAvel ) { for( i = 0; i < 3; i++ ) { float ang1, ang2; ang1 = m_pGround->curstate.angles[i]; ang2 = m_pGround->prevstate.angles[i]; d = ang1 - ang2; if( d > 180.0f ) d -= 360.0f; else if( d < -180.0f ) d += 360.0f; ent->angles[i] += d * -1.0f; } } } // moved code from StudioSetupTransform here if( host.features & ENGINE_COMPUTE_STUDIO_LERP ) { ent->origin[0] += ( ent->curstate.origin[0] - ent->latched.prevorigin[0] ) * f; ent->origin[1] += ( ent->curstate.origin[1] - ent->latched.prevorigin[1] ) * f; ent->origin[2] += ( ent->curstate.origin[2] - ent->latched.prevorigin[2] ) * f; for( i = 0; i < 3; i++ ) { float ang1, ang2; ang1 = ent->angles[i]; ang2 = ent->latched.prevangles[i]; d = ang1 - ang2; if( d > 180.0f ) d -= 360.0f; else if( d < -180.0f ) d += 360.0f; ent->angles[i] += d * f; } } } } }
/* ========================================================================= FRAME PARSING ========================================================================= */ void CL_UpdateEntityFields( cl_entity_t *ent ) { VectorCopy( ent->curstate.origin, ent->origin ); VectorCopy( ent->curstate.angles, ent->angles ); ent->model = Mod_Handle( ent->curstate.modelindex ); ent->curstate.msg_time = cl.time; if( ent->player ) // stupid Half-Life bug ent->angles[PITCH] = -ent->angles[PITCH] / 3.0f; // make me lerp if( ent->model && ent->model->type == mod_brush && ent->curstate.animtime != 0.0f ) { float d, f = 0.0f; int i; // don't do it if the goalstarttime hasn't updated in a while. // NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit // was increased to 1.0 s., which is 2x the max lag we are accounting for. if(( cl.time < ent->curstate.animtime + 1.0f ) && ( ent->curstate.animtime != ent->latched.prevanimtime )) f = ( cl.time - ent->curstate.animtime ) / ( ent->curstate.animtime - ent->latched.prevanimtime ); f = f - 1.0f; ent->origin[0] += ( ent->origin[0] - ent->latched.prevorigin[0] ) * f; ent->origin[1] += ( ent->origin[1] - ent->latched.prevorigin[1] ) * f; ent->origin[2] += ( ent->origin[2] - ent->latched.prevorigin[2] ) * f; for( i = 0; i < 3; i++ ) { float ang1, ang2; ang1 = ent->angles[i]; ang2 = ent->latched.prevangles[i]; d = ang1 - ang2; if( d > 180.0f ) d -= 360.0f; else if( d < -180.0f ) d += 360.0f; ent->angles[i] += d * f; } } else if( ent->curstate.eflags & EFLAG_SLERP ) { float d, f = 0.0f; cl_entity_t *m_pGround = NULL; int i; // don't do it if the goalstarttime hasn't updated in a while. // NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit // was increased to 1.0 s., which is 2x the max lag we are accounting for. if(( cl.time < ent->curstate.animtime + 1.0f ) && ( ent->curstate.animtime != ent->latched.prevanimtime )) f = ( cl.time - ent->curstate.animtime ) / ( ent->curstate.animtime - ent->latched.prevanimtime ); f = f - 1.0f; if( ent->curstate.movetype == MOVETYPE_FLY ) { ent->origin[0] += ( ent->curstate.origin[0] - ent->latched.prevorigin[0] ) * f; ent->origin[1] += ( ent->curstate.origin[1] - ent->latched.prevorigin[1] ) * f; ent->origin[2] += ( ent->curstate.origin[2] - ent->latched.prevorigin[2] ) * f; for( i = 0; i < 3; i++ ) { float ang1, ang2; ang1 = ent->curstate.angles[i]; ang2 = ent->latched.prevangles[i]; d = ang1 - ang2; if( d > 180.0f ) d -= 360.0f; else if( d < -180.0f ) d += 360.0f; ent->angles[i] += d * f; } } else if( ent->curstate.movetype == MOVETYPE_STEP ) { vec3_t vecSrc, vecEnd; pmtrace_t trace; if( ent->model ) { CL_SetTraceHull( 0 ); // g-cont. player hull for better detect moving platforms VectorSet( vecSrc, ent->origin[0], ent->origin[1], ent->origin[2] + ent->model->maxs[2] ); VectorSet( vecEnd, vecSrc[0], vecSrc[1], vecSrc[2] - ent->model->mins[2] - 8.0f ); CL_PlayerTraceExt( vecSrc, vecEnd, PM_STUDIO_IGNORE, CL_PushMoveFilter, &trace ); m_pGround = CL_GetEntityByIndex( pfnIndexFromTrace( &trace )); } if( m_pGround && m_pGround->curstate.movetype == MOVETYPE_PUSH ) { qboolean applyVel, applyAvel; d = -1.0f; applyVel = !VectorCompare( m_pGround->curstate.origin, m_pGround->prevstate.origin ); applyAvel = !VectorCompare( m_pGround->curstate.angles, m_pGround->prevstate.angles ); if( applyVel || applyAvel ) { ent->origin[0] += ( m_pGround->curstate.origin[0] - m_pGround->prevstate.origin[0] ) * d; ent->origin[1] += ( m_pGround->curstate.origin[1] - m_pGround->prevstate.origin[1] ) * d; // ent->origin[2] += ( m_pGround->curstate.origin[2] - m_pGround->prevstate.origin[2] ) * d; ent->latched.prevorigin[2] = ent->origin[2]; } if( applyAvel ) { for( i = 0; i < 3; i++ ) { float ang1, ang2; ang1 = m_pGround->curstate.angles[i]; ang2 = m_pGround->prevstate.angles[i]; f = ang1 - ang2; if( d > 180.0f ) f -= 360.0f; else if( d < -180.0f ) f += 360.0f; ent->angles[i] += d * f; } } } } } }