//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
float CPropJetski::CalculateDrag( CUserCmd *ucmd )
{
	// Get the speed and ratio to max speed.
	float flSpeed = m_VehiclePhysics.GetSpeed();
	float flMaxSpeed = m_VehiclePhysics.GetMaxSpeed();
	float flRatio = flSpeed / flMaxSpeed;

	float flDrag = 0.0f;

	bool bLean = UpdateLean( ucmd );
	
#if 0
	if ( bLean )
	{
		flDrag += JETSKI_DRAG_LEAN_ADD;
	}
		float flNormalizedRatio = ( flRatio - 0.4f ) * 1.667f;
		float flSplineRatio = SimpleSpline( flNormalizedRatio );

		flFriction = JETSKI_FRICTION_MAX + ( JETSKI_FRICTION_MIN - JETSKI_FRICTION_MAX ) * flSplineRatio;
		flDrag = JETSKI_DRAG_IN_WATER + ( JETSKI_DRAG_ON_WATER - JETSKI_DRAG_IN_WATER ) * flNormalizedRatio;

		// Leaning backwards.
		if ( bLean )
		{
			flDrag += JETSKI_DRAG_LEAN_ADD;
		}
	}
Esempio n. 2
0
// remaps an angular variable to a 3 band function:
// 0 <= t < start :		f(t) = 0
// start <= t <= end :	f(t) = end * spline(( t-start) / (end-start) )  // s curve between clamped and linear
// end < t :			f(t) = t
float RemapAngleRange( float startInterval, float endInterval, float value )
{
	// Fixup the roll
	value = AngleNormalize( value );
	float absAngle = fabs(value);

	// beneath cutoff?
	if ( absAngle < startInterval )
	{
		value = 0;
	}
	// in spline range?
	else if ( absAngle <= endInterval )
	{
		float newAngle = SimpleSpline( (absAngle - startInterval) / (endInterval-startInterval) ) * endInterval;
		// grab the sign from the initial value
		if ( value < 0 )
		{
			newAngle *= -1;
		}
		value = newAngle;
	}
	// else leave it alone, in linear range
	
	return value;
}
Esempio n. 3
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &out - 
//			t - 
//			&start - 
//			&end - 
//-----------------------------------------------------------------------------
void CSimpleKeyInterp::Interp( Vector &out, float t, const CSimpleKeyInterp &start, const CSimpleKeyInterp &end )
{
	float delta = end.GetTime() - start.GetTime();
	t = clamp( t-start.GetTime(), 0.f, delta );

	float unitT = (delta > 0) ? (t / delta) : 1;

	switch( end.m_interp )
	{
	case KEY_SPLINE:
		unitT = SimpleSpline( unitT );
		break;
	case KEY_ACCELERATE:
		unitT *= unitT;
		break;
	case KEY_DECELERATE:
		unitT = sqrt(unitT);
		break;
	default:
	case KEY_LINEAR:
		//unitT = unitT;
		break;
	}
	out = (1-unitT) * ((Vector)start) + unitT * ((Vector)end);
}
Esempio n. 4
0
	virtual void OnBind( C_BaseEntity *pC_BaseEntity )
	{
		C_BaseAnimating *pBaseAnimating = pC_BaseEntity ? pC_BaseEntity->GetBaseAnimating() : NULL;
		if ( pBaseAnimating )
		{
			float fCycle = pBaseAnimating->GetCycle();
			float f = RemapValClamped( fCycle, m_fStart, m_fEnd, 0.0f, 1.0f );
			if ( m_bEaseIn && m_bEaseOut )
			{
				f = SimpleSpline( f );
			}
			else if ( m_bEaseIn )
			{
				f = sin( M_PI * f * 0.5f );
			}
			else if ( m_bEaseOut )
			{
				f = 1.0f - sin( M_PI * f * 0.5f + 0.5f * M_PI );
			}
			
			MaterialVarType_t resultType;
			int vecSize;
			ComputeResultType( resultType, vecSize );

			switch( resultType )
			{
			case MATERIAL_VAR_TYPE_VECTOR:
				{
					Vector4D vec( f, f, f, f );
					m_pResult->SetVecValue( vec.Base(), vecSize );
				}
				break;

			case MATERIAL_VAR_TYPE_FLOAT:
			case MATERIAL_VAR_TYPE_INT:
			default:
				m_pResult->SetFloatValue( f );
				break;
			}
		}
	}
Esempio n. 5
0
float FadeFilter::Update(float value)
{
	float now = ENGINE_NOW;

	if(m_fadeInEnd == 0)
	{
		m_fadeInStart = now;
		m_fadeInEnd = m_fadeInStart + m_duration->GetFloat() - max(m_fadeOutEnd - now, 0);
		m_fadeOutStart = 0;
		m_fadeOutEnd = 0;
		m_prevVal = GetValue();
	}

	if(now > m_fadeInEnd)
		return value;

	float p = (now - m_fadeInStart) / (m_fadeInEnd - m_fadeInStart);
	p = SimpleSpline(p);

	return (1 - p) * m_prevVal + p * value;
}
//-----------------------------------------------------------------------------
// Purpose: Vehicle dampening shared between server and client
//-----------------------------------------------------------------------------
void SharedVehicleViewSmoothing(CBasePlayer *pPlayer,
                                Vector *pAbsOrigin, QAngle *pAbsAngles,
                                bool bEnterAnimOn, bool bExitAnimOn,
                                const Vector &vecEyeExitEndpoint,
                                ViewSmoothingData_t *pData,
                                float *pFOV )
{
    int eyeAttachmentIndex = pData->pVehicle->LookupAttachment( "vehicle_driver_eyes" );
    matrix3x4_t vehicleEyePosToWorld;
    Vector vehicleEyeOrigin;
    QAngle vehicleEyeAngles;
    pData->pVehicle->GetAttachment( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
    AngleMatrix( vehicleEyeAngles, vehicleEyePosToWorld );

    // Dampen the eye positional change as we drive around.
    *pAbsAngles = pPlayer->EyeAngles();
    if ( r_VehicleViewDampen.GetInt() && pData->bDampenEyePosition )
    {
        CPropVehicleDriveable *pDriveable = assert_cast<CPropVehicleDriveable*>(pData->pVehicle);
        pDriveable->DampenEyePosition( vehicleEyeOrigin, vehicleEyeAngles );
    }

    // Started running an entry or exit anim?
    bool bRunningAnim = ( bEnterAnimOn || bExitAnimOn );
    if ( bRunningAnim && !pData->bWasRunningAnim )
    {
        pData->bRunningEnterExit = true;
        pData->flEnterExitStartTime = gpGlobals->curtime;
        pData->flEnterExitDuration = pData->pVehicle->SequenceDuration( pData->pVehicle->GetSequence() );

#ifdef CLIENT_DLL
        pData->vecOriginSaved = PrevMainViewOrigin();
        pData->vecAnglesSaved = PrevMainViewAngles();
#endif

        // Save our initial angular error, which we will blend out over the length of the animation.
        pData->vecAngleDiffSaved.x = AngleDiff( vehicleEyeAngles.x, pData->vecAnglesSaved.x );
        pData->vecAngleDiffSaved.y = AngleDiff( vehicleEyeAngles.y, pData->vecAnglesSaved.y );
        pData->vecAngleDiffSaved.z = AngleDiff( vehicleEyeAngles.z, pData->vecAnglesSaved.z );

        pData->vecAngleDiffMin = pData->vecAngleDiffSaved;
    }

    pData->bWasRunningAnim = bRunningAnim;

    float frac = 0;
    float flFracFOV = 0;

    // If we're in an enter/exit animation, blend the player's eye angles to the attachment's
    if ( bRunningAnim || pData->bRunningEnterExit )
    {
        *pAbsAngles = vehicleEyeAngles;

        // Forward integrate to determine the elapsed time in this entry/exit anim.
        frac = ( gpGlobals->curtime - pData->flEnterExitStartTime ) / pData->flEnterExitDuration;
        frac = clamp( frac, 0.0f, 1.0f );

        flFracFOV = ( gpGlobals->curtime - pData->flEnterExitStartTime ) / ( pData->flEnterExitDuration * 0.85f );
        flFracFOV = clamp( flFracFOV, 0.0f, 1.0f );

        //Msg("Frac: %f\n", frac );

        if ( frac < 1.0 )
        {
            // Blend to the desired vehicle eye origin
            //Vector vecToView = (vehicleEyeOrigin - PrevMainViewOrigin());
            //vehicleEyeOrigin = PrevMainViewOrigin() + (vecToView * SimpleSpline(frac));
            //debugoverlay->AddBoxOverlay( vehicleEyeOrigin, -Vector(1,1,1), Vector(1,1,1), vec3_angle, 0,255,255, 64, 10 );
        }
        else
        {
            pData->bRunningEnterExit = false;

            // Enter animation has finished, align view with the eye attachment point
            // so they can start mouselooking around.
#if !defined ( HL2MP_DEV_DLL ) && !defined ( HL2MP_DEV_VEHICLE_FIX )
            if ( !bExitAnimOn )
            {
                Vector localEyeOrigin;
                QAngle localEyeAngles;

                pData->pVehicle->GetAttachmentLocal( eyeAttachmentIndex, localEyeOrigin, localEyeAngles );
#ifdef CLIENT_DLL
                engine->SetViewAngles( localEyeAngles );
#endif
            }
#else

#ifdef CLIENT_DLL
            pPlayer = C_BasePlayer::GetLocalPlayer();
#endif
            if ( pPlayer )
            {
                if ( !bExitAnimOn )
                {
                    Vector localEyeOrigin;
                    QAngle localEyeAngles;

                    pData->pVehicle->GetAttachmentLocal( eyeAttachmentIndex, localEyeOrigin, localEyeAngles );
#ifdef CLIENT_DLL
                    engine->SetViewAngles( localEyeAngles );
#endif
                }
            }
#endif
        }
    }

    // Compute the relative rotation between the unperturbed eye attachment + the eye angles
    matrix3x4_t cameraToWorld;
    AngleMatrix( *pAbsAngles, cameraToWorld );

    matrix3x4_t worldToEyePos;
    MatrixInvert( vehicleEyePosToWorld, worldToEyePos );

    matrix3x4_t vehicleCameraToEyePos;
    ConcatTransforms( worldToEyePos, cameraToWorld, vehicleCameraToEyePos );

    // Damp out some of the vehicle motion (neck/head would do this)
    if ( pData->bClampEyeAngles )
    {
        RemapViewAngles( pData, vehicleEyeAngles );
    }

    AngleMatrix( vehicleEyeAngles, vehicleEyeOrigin, vehicleEyePosToWorld );

    // Now treat the relative eye angles as being relative to this new, perturbed view position...
    matrix3x4_t newCameraToWorld;
    ConcatTransforms( vehicleEyePosToWorld, vehicleCameraToEyePos, newCameraToWorld );

    // output new view abs angles
    MatrixAngles( newCameraToWorld, *pAbsAngles );

    // UNDONE: *pOrigin would already be correct in single player if the HandleView() on the server ran after vphysics
    MatrixGetColumn( newCameraToWorld, 3, *pAbsOrigin );

    float flDefaultFOV;
#ifdef CLIENT_DLL
    flDefaultFOV = default_fov.GetFloat();
#else
    flDefaultFOV = pPlayer->GetDefaultFOV();
#endif

    // If we're playing an entry or exit animation...
    if ( bRunningAnim || pData->bRunningEnterExit )
    {
        float flSplineFrac = clamp( SimpleSpline( frac ), 0.f, 1.f );

        // Blend out the error between the player's initial eye angles and the animation's initial
        // eye angles over the duration of the animation.
        QAngle vecAngleDiffBlend = ( ( 1 - flSplineFrac ) * pData->vecAngleDiffSaved );

        // If our current error is less than the error amount that we're blending
        // out, use that. This lets the angles converge as quickly as possible.
        QAngle vecAngleDiffCur;
        vecAngleDiffCur.x = AngleDiff( vehicleEyeAngles.x, pData->vecAnglesSaved.x );
        vecAngleDiffCur.y = AngleDiff( vehicleEyeAngles.y, pData->vecAnglesSaved.y );
        vecAngleDiffCur.z = AngleDiff( vehicleEyeAngles.z, pData->vecAnglesSaved.z );

        // In either case, never increase the error, so track the minimum error and clamp to that.
        for (int i = 0; i < 3; i++)
        {
            if ( fabs(vecAngleDiffCur[i] ) < fabs( pData->vecAngleDiffMin[i] ) )
            {
                pData->vecAngleDiffMin[i] = vecAngleDiffCur[i];
            }

            if ( fabs(vecAngleDiffBlend[i] ) < fabs( pData->vecAngleDiffMin[i] ) )
            {
                pData->vecAngleDiffMin[i] = vecAngleDiffBlend[i];
            }
        }

        // Add the error to the animation's eye angles.
        *pAbsAngles -= pData->vecAngleDiffMin;

        // Use this as the basis for the next error calculation.
        pData->vecAnglesSaved = *pAbsAngles;

        //if ( gpGlobals->frametime )
        //{
        //	Msg("Angle : %.2f %.2f %.2f\n", target.x, target.y, target.z );
        //}
        //Msg("Prev: %.2f %.2f %.2f\n", pData->vecAnglesSaved.x, pData->vecAnglesSaved.y, pData->vecAnglesSaved.z );

        Vector vecAbsOrigin = *pAbsOrigin;

        // If we're exiting, our desired position is the server-sent exit position
        if ( bExitAnimOn )
        {
            //debugoverlay->AddBoxOverlay( vecEyeExitEndpoint, -Vector(1,1,1), Vector(1,1,1), vec3_angle, 255,255,255, 64, 10 );

            // Blend to the exit position
            *pAbsOrigin = Lerp( flSplineFrac, vecAbsOrigin, vecEyeExitEndpoint );

            if ( pFOV != NULL )
            {
                if ( pData->flFOV > flDefaultFOV )
                {
                    *pFOV = Lerp( flFracFOV, pData->flFOV, flDefaultFOV );
                }
            }
        }
        else
        {
            // Blend from our starting position to the desired origin
            *pAbsOrigin = Lerp( flSplineFrac, pData->vecOriginSaved, vecAbsOrigin );

            if ( pFOV != NULL )
            {
                if ( pData->flFOV > flDefaultFOV )
                {
                    *pFOV = Lerp( flFracFOV, flDefaultFOV, pData->flFOV );
                }
            }
        }
    }
    else if ( pFOV != NULL )
    {
        if ( pData->flFOV > flDefaultFOV )
        {
            // Not running an entry/exit anim. Just use the vehicle's FOV.
            *pFOV = pData->flFOV;
        }
    }
}
Esempio n. 7
0
//-----------------------------------------------------------------------------
// Purpose: See if duck button is pressed and do the appropriate things
//-----------------------------------------------------------------------------
void CHL2GameMovement::Duck(void)
{
	int buttonsChanged = (mv->m_nOldButtons ^ mv->m_nButtons);	// These buttons have changed this frame
	int buttonsPressed = buttonsChanged & mv->m_nButtons;			// The changed ones still down are "pressed"
	int buttonsReleased = buttonsChanged & mv->m_nOldButtons;		// The changed ones which were previously down are "released"

	if (mv->m_nButtons & IN_DUCK)
	{
		mv->m_nOldButtons |= IN_DUCK;
	}
	else
	{
		mv->m_nOldButtons &= ~IN_DUCK;
	}

	if (IsDead())
	{
		// Unduck
		if (player->GetFlags() & FL_DUCKING)
		{
			FinishUnDuck();
		}
		return;
	}

	HandleDuckingSpeedCrop();

	// Holding duck, in process of ducking or fully ducked?
	if ((mv->m_nButtons & IN_DUCK) || (player->m_Local.m_bDucking) || (player->GetFlags() & FL_DUCKING))
	{
		if (mv->m_nButtons & IN_DUCK)
		{
			bool alreadyDucked = (player->GetFlags() & FL_DUCKING) ? true : false;

			if ((buttonsPressed & IN_DUCK) && !(player->GetFlags() & FL_DUCKING))
			{
				// Use 1 second so super long jump will work
				player->m_Local.m_flDucktime = 1000;
				player->m_Local.m_bDucking = true;
			}

			float duckmilliseconds = max(0.0f, 1000.0f - (float)player->m_Local.m_flDucktime);
			float duckseconds = duckmilliseconds / 1000.0f;

			//time = max( 0.0, ( 1.0 - (float)player->m_Local.m_flDucktime / 1000.0 ) );

			if (player->m_Local.m_bDucking)
			{
				// Finish ducking immediately if duck time is over or not on ground
				if ((duckseconds > TIME_TO_DUCK) ||
					(player->GetGroundEntity() == NULL) ||
					alreadyDucked)
				{
					FinishDuck();
				}
				else
				{
					// Calc parametric time
					float duckFraction = SimpleSpline(duckseconds / TIME_TO_DUCK);
					SetDuckedEyeOffset(duckFraction);
				}
			}
		}
		else
		{
			// Try to unduck unless automovement is not allowed
			// NOTE: When not onground, you can always unduck
			if (player->m_Local.m_bAllowAutoMovement || player->GetGroundEntity() == NULL)
			{
				if ((buttonsReleased & IN_DUCK) && (player->GetFlags() & FL_DUCKING))
				{
					// Use 1 second so super long jump will work
					player->m_Local.m_flDucktime = 1000;
					player->m_Local.m_bDucking = true;  // or unducking
				}

				float duckmilliseconds = max(0.0f, 1000.0f - (float)player->m_Local.m_flDucktime);
				float duckseconds = duckmilliseconds / 1000.0f;

				if (CanUnduck())
				{
					if (player->m_Local.m_bDucking ||
						player->m_Local.m_bDucked) // or unducking
					{
						// Finish ducking immediately if duck time is over or not on ground
						if ((duckseconds > TIME_TO_UNDUCK) ||
							(player->GetGroundEntity() == NULL))
						{
							FinishUnDuck();
						}
						else
						{
							// Calc parametric time
							float duckFraction = SimpleSpline(1.0f - (duckseconds / TIME_TO_UNDUCK));
							SetDuckedEyeOffset(duckFraction);
						}
					}
				}
				else
				{
					// Still under something where we can't unduck, so make sure we reset this timer so
					//  that we'll unduck once we exit the tunnel, etc.
					player->m_Local.m_flDucktime = 1000;
				}
			}
		}
	}
}
Esempio n. 8
0
void Interpolator_CurveInterpolate_NonNormalized( int interpolationType,
	const Vector &vPre,
	const Vector &vStart,
	const Vector &vEnd,
	const Vector &vNext,
	float f,
	Vector &vOut )
{
	vOut.Init();

	switch ( interpolationType )
	{
	default:
		Warning( "Unknown interpolation type %d\n",
			(int)interpolationType );
		// break; // Fall through and use catmull_rom as default
	case INTERPOLATE_CATMULL_ROM_NORMALIZEX:
	case INTERPOLATE_DEFAULT:
	case INTERPOLATE_CATMULL_ROM:
	case INTERPOLATE_CATMULL_ROM_NORMALIZE:
	case INTERPOLATE_CATMULL_ROM_TANGENT:
		Catmull_Rom_Spline( 
			vPre,
			vStart,
			vEnd,
			vNext,
			f, 
			vOut );
		break;
	case INTERPOLATE_EASE_IN:
		{
			f = sin( M_PI * f * 0.5f );
			// Fixme, since this ignores vPre and vNext we could omit computing them aove
			VectorLerp( vStart, vEnd, f, vOut );
		}
		break;
	case INTERPOLATE_EASE_OUT:
		{
			f = 1.0f - sin( M_PI * f * 0.5f + 0.5f * M_PI );
			// Fixme, since this ignores vPre and vNext we could omit computing them aove
			VectorLerp( vStart, vEnd, f, vOut );
		}
		break;
	case INTERPOLATE_EASE_INOUT:
		{
			f = SimpleSpline( f );
			// Fixme, since this ignores vPre and vNext we could omit computing them aove
			VectorLerp( vStart, vEnd, f, vOut );
		}
		break;
	case INTERPOLATE_LINEAR_INTERP:
		// Fixme, since this ignores vPre and vNext we could omit computing them aove
		VectorLerp( vStart, vEnd, f, vOut );
		break;
	case INTERPOLATE_KOCHANEK_BARTELS:
	case INTERPOLATE_KOCHANEK_BARTELS_EARLY:
	case INTERPOLATE_KOCHANEK_BARTELS_LATE:
		{
			float t, b, c;
			Interpolator_GetKochanekBartelsParams( interpolationType, t, b, c );
			Kochanek_Bartels_Spline
			( 
				t, b, c, 
				vPre,
				vStart,
				vEnd,
				vNext,
				f, 
				vOut 
			);
		}
		break;
	case INTERPOLATE_SIMPLE_CUBIC:
		Cubic_Spline( 
			vPre,
			vStart,
			vEnd,
			vNext,
			f, 
			vOut );
		break;
	case INTERPOLATE_BSPLINE:
		BSpline( 
			vPre,
			vStart,
			vEnd,
			vNext,
			f, 
			vOut );
		break;
	case INTERPOLATE_EXPONENTIAL_DECAY:
		{
			float dt = vEnd.x - vStart.x;
			if ( dt > 0.0f )
			{
				float val = 1.0f - ExponentialDecay( 0.001, dt, f * dt ); 
				vOut.y = vStart.y + val * ( vEnd.y - vStart.y );
			}
			else
			{
				vOut.y = vStart.y;
			}
		}
		break;
	case INTERPOLATE_HOLD:
		{
			vOut.y = vStart.y;
		}
		break;
	}
}
Esempio n. 9
0
//-----------------------------------------------------------------------------
// Purpose: See if duck button is pressed and do the appropriate things
//-----------------------------------------------------------------------------
void CSDKGameMovement::Duck( void )
{
	int buttonsChanged	= ( mv->m_nOldButtons ^ mv->m_nButtons );	// These buttons have changed this frame
	int buttonsPressed	=  buttonsChanged & mv->m_nButtons;			// The changed ones still down are "pressed"
	int buttonsReleased	=  buttonsChanged & mv->m_nOldButtons;		// The changed ones which were previously down are "released"

	if ( mv->m_nButtons & IN_DUCK )
	{
		mv->m_nOldButtons |= IN_DUCK;
	}
	else
	{
		mv->m_nOldButtons &= ~IN_DUCK;
	}

	if ( !player->IsAlive() )
	{
#if defined ( SDK_USE_PRONE )
		if( m_pSDKPlayer->m_Shared.IsProne() )
		{
			FinishUnProne();
		}
#endif // SDK_USE_PRONE

		// Unduck
		if ( player->m_Local.m_bDucking || player->m_Local.m_bDucked )
		{
			FinishUnDuck();
		}
		return;
	}

	static int iState = 0;

#if defined ( SDK_USE_PRONE )
	// Prone / UnProne - we don't duck if this is happening
	if( m_pSDKPlayer->m_Shared.IsGettingUpFromProne() == true )
	{
		float pronetime = m_pSDKPlayer->m_Shared.m_flUnProneTime - gpGlobals->curtime;

		if( pronetime < 0 )
		{
			FinishUnProne();

			if ( !m_pSDKPlayer->m_bUnProneToDuck && ( mv->m_nButtons & IN_DUCK ) )
			{
				buttonsPressed |= IN_DUCK;
				mv->m_nOldButtons &= ~IN_DUCK;
			}
		}
		else
		{
			// Calc parametric time
			float fraction = SimpleSpline( pronetime / TIME_TO_PRONE );
			SetProneEyeOffset( fraction );

		}

		// Set these, so that as soon as we stop unproning, we don't pop to standing
		// the information that we let go of the duck key has been lost by now.
		if ( m_pSDKPlayer->m_bUnProneToDuck )
		{
            player->m_Local.m_flDucktime = 1000;
			player->m_Local.m_bDucking    = true;
		}

		//don't deal with ducking while we're proning
		return;
	}
	else if ( m_pSDKPlayer->m_Shared.IsGoingProne() == true )
	{
		float pronetime = m_pSDKPlayer->m_Shared.m_flGoProneTime - gpGlobals->curtime;

		if( pronetime < 0 )
		{
			FinishProne();
		}
		else
		{
			// Calc parametric time
			float fraction = SimpleSpline( 1.0f - ( pronetime / TIME_TO_PRONE ) );
			SetProneEyeOffset( fraction );
		}

		//don't deal with ducking while we're proning
		return;
	}

	if ( gpGlobals->curtime > m_pSDKPlayer->m_Shared.m_flNextProneCheck )
	{
		if ( buttonsPressed & IN_ALT1 && m_pSDKPlayer->m_Shared.CanChangePosition() )
		{
			if( m_pSDKPlayer->m_Shared.IsProne() == false &&
				m_pSDKPlayer->m_Shared.IsGettingUpFromProne() == false )
			{
				m_pSDKPlayer->m_Shared.StartGoingProne();

				//Tony; here is where you'd want to do an animation for first person to give the effect of going prone.
				if ( m_pSDKPlayer->m_Shared.IsDucking() )
					m_pSDKPlayer->DoAnimationEvent( PLAYERANIMEVENT_CROUCH_TO_PRONE );
				else
					m_pSDKPlayer->DoAnimationEvent( PLAYERANIMEVENT_STAND_TO_PRONE );

			}
			else if ( CanUnprone() )
			{
				m_pSDKPlayer->m_Shared.SetProne( false );
				m_pSDKPlayer->m_Shared.StandUpFromProne();

				//
				//Tony; here is where you'd want to do an animation for first person to give the effect of getting up from prone.
				//

				m_pSDKPlayer->m_bUnProneToDuck = ( mv->m_nButtons & IN_DUCK ) > 0;

				if ( m_pSDKPlayer->m_bUnProneToDuck )
					m_pSDKPlayer->DoAnimationEvent( PLAYERANIMEVENT_PRONE_TO_CROUCH );
				else
					m_pSDKPlayer->DoAnimationEvent( PLAYERANIMEVENT_PRONE_TO_STAND );
			}
			
			m_pSDKPlayer->m_Shared.m_flNextProneCheck = gpGlobals->curtime + 1.0f;
			return;
		}
	}

	if ( m_pSDKPlayer->m_Shared.IsProne() &&
		m_pSDKPlayer->m_Shared.CanChangePosition() &&
		( buttonsPressed & IN_DUCK ) && 
		CanUnprone() )	
	{
		// If the player presses duck while prone,
		// unprone them to the duck position
		m_pSDKPlayer->m_Shared.SetProne( false );
		m_pSDKPlayer->m_Shared.StandUpFromProne();

		m_pSDKPlayer->m_bUnProneToDuck = true;

		//
		//Tony; here is where you'd want to do an animation for first person to give the effect of going to duck from prone.
		//

		m_pSDKPlayer->DoAnimationEvent( PLAYERANIMEVENT_PRONE_TO_CROUCH );

		// simulate a duck that was pressed while we were prone
		player->AddFlag( FL_DUCKING );
		player->m_Local.m_bDucked = true;
		player->m_Local.m_flDucktime = 1000;
		player->m_Local.m_bDucking    = true;
	}

	// no ducking or unducking while deployed or prone
	if( m_pSDKPlayer->m_Shared.IsProne() ||
		m_pSDKPlayer->m_Shared.IsGettingUpFromProne() ||
		!m_pSDKPlayer->m_Shared.CanChangePosition() )
	{
		return;
	}
#endif // SDK_USE_PRONE
	HandleDuckingSpeedCrop();

	if ( !( player->GetFlags() & FL_DUCKING ) && ( player->m_Local.m_bDucked ) )
	{
		player->m_Local.m_bDucked = false;
	}

	// Holding duck, in process of ducking or fully ducked?
	if ( ( mv->m_nButtons & IN_DUCK ) || ( player->m_Local.m_bDucking ) || ( player->GetFlags() & FL_DUCKING ) )
	{
		if ( mv->m_nButtons & IN_DUCK )
		{
			bool alreadyDucked = ( player->GetFlags() & FL_DUCKING ) ? true : false;

			if ( (buttonsPressed & IN_DUCK ) && !( player->GetFlags() & FL_DUCKING ) )
			{
				// Use 1 second so super long jump will work
				player->m_Local.m_flDucktime = 1000;
				player->m_Local.m_bDucking    = true;
			}

			float duckmilliseconds = max( 0.0f, 1000.0f - (float)player->m_Local.m_flDucktime );
			float duckseconds = duckmilliseconds / 1000.0f;

			//time = max( 0.0, ( 1.0 - (float)player->m_Local.m_flDucktime / 1000.0 ) );
			
			if ( player->m_Local.m_bDucking )
			{
				// Finish ducking immediately if duck time is over or not on ground
				if ( ( duckseconds > TIME_TO_DUCK ) || 
					( player->GetGroundEntity() == NULL ) ||
					alreadyDucked)
				{
					FinishDuck();
				}
				else
				{
					// Calc parametric time
					float flDuckFraction = SimpleSpline( duckseconds / TIME_TO_DUCK );
					SetSDKDuckedEyeOffset( flDuckFraction );
				}
			}
		}
		else
		{
			// Try to unduck unless automovement is not allowed
			// NOTE: When not onground, you can always unduck
			if ( player->m_Local.m_bAllowAutoMovement || player->GetGroundEntity() == NULL )
			{
				if ( (buttonsReleased & IN_DUCK ) && ( player->GetFlags() & FL_DUCKING ) )
				{
					// Use 1 second so super long jump will work
					player->m_Local.m_flDucktime = 1000;
					player->m_Local.m_bDucking    = true;  // or unducking
				}

				float duckmilliseconds = max( 0.0f, 1000.0f - (float)player->m_Local.m_flDucktime );
				float duckseconds = duckmilliseconds / 1000.0f;

				if ( CanUnduck() )
				{
					if ( player->m_Local.m_bDucking || 
						 player->m_Local.m_bDucked ) // or unducking
					{
						// Finish ducking immediately if duck time is over or not on ground
						if ( ( duckseconds > TIME_TO_UNDUCK ) ||
							 ( player->GetGroundEntity() == NULL ) )
						{
							FinishUnDuck();
						}
						else
						{
							// Calc parametric time
							float duckFraction = SimpleSpline( 1.0f - ( duckseconds / TIME_TO_UNDUCK ) );
							SetSDKDuckedEyeOffset( duckFraction );
						}
					}
				}
				else
				{
					// Still under something where we can't unduck, so make sure we reset this timer so
					//  that we'll unduck once we exit the tunnel, etc.
					player->m_Local.m_flDucktime	= 1000;
				}
			}
		}
	}
}
Esempio n. 10
0
void CSDKGameMovement::SetPlayerSpeed( void )
{
#if defined ( SDK_USE_PRONE )
	// This check is now simplified, just use CanChangePosition because it checks the two things we need to check anyway.
	if ( m_pSDKPlayer->m_Shared.IsProne() && m_pSDKPlayer->m_Shared.CanChangePosition() && m_pSDKPlayer->GetGroundEntity() != NULL )
	{
			mv->m_flClientMaxSpeed = m_pSDKPlayer->m_Shared.m_flProneSpeed;		//Base prone speed 
	}
	else	//not prone - standing or crouching and possibly moving
#endif // SDK_USE_PRONE
	{
		float stamina = 100.0f;
#if defined ( SDK_USE_STAMINA ) || defined ( SDK_USE_SPRINTING )
		stamina = m_pSDKPlayer->m_Shared.GetStamina();
#endif
		if ( mv->m_nButtons & IN_DUCK )
		{
			mv->m_flClientMaxSpeed = m_pSDKPlayer->m_Shared.m_flRunSpeed;	//gets cut in fraction later
		}
		else
		{
			float flMaxSpeed;	
#if defined ( SDK_USE_SPRINTING )
			if ( ( mv->m_nButtons & IN_SPEED ) && ( stamina > 0 ) && ( mv->m_nButtons & IN_FORWARD ) )
			{
				flMaxSpeed = m_pSDKPlayer->m_Shared.m_flSprintSpeed;	//sprinting
			}
			else
#endif // SDK_USE_SPRINTING
			{
				flMaxSpeed = m_pSDKPlayer->m_Shared.m_flRunSpeed;	//jogging
			}

			mv->m_flClientMaxSpeed = flMaxSpeed - 100 + stamina;
		}
	}

#if defined ( SDK_USE_PRONE )
	if ( m_pSDKPlayer->GetGroundEntity() != NULL )
	{
		if( m_pSDKPlayer->m_Shared.IsGoingProne() )
		{
			float pronetime = m_pSDKPlayer->m_Shared.m_flGoProneTime - gpGlobals->curtime;

			//interp to prone speed
			float flProneFraction = SimpleSpline( pronetime / TIME_TO_PRONE );

			float maxSpeed = mv->m_flClientMaxSpeed;

			if ( m_pSDKPlayer->m_bUnProneToDuck )
				maxSpeed *= 0.33;
			
			mv->m_flClientMaxSpeed = ( ( 1 - flProneFraction ) * m_pSDKPlayer->m_Shared.m_flProneSpeed ) + ( flProneFraction * maxSpeed );
		}
		else if ( m_pSDKPlayer->m_Shared.IsGettingUpFromProne() )
		{
			float pronetime = m_pSDKPlayer->m_Shared.m_flUnProneTime - gpGlobals->curtime;

			//interp to regular speed speed
			float flProneFraction = SimpleSpline( pronetime / TIME_TO_PRONE );
			
			float maxSpeed = mv->m_flClientMaxSpeed;

			if ( m_pSDKPlayer->m_bUnProneToDuck )
				maxSpeed *= 0.33;

			mv->m_flClientMaxSpeed = ( flProneFraction * m_pSDKPlayer->m_Shared.m_flProneSpeed ) + ( ( 1 - flProneFraction ) * maxSpeed );
		}
	}	
#endif // SDK_USE_PRONE
}
Esempio n. 11
0
mstudioanim_t *mstudioanimdesc_t::pAnim( int *piFrame, float &flStall ) const
{
	mstudioanim_t *panim = NULL;

	int block = animblock;
	int index = animindex;
	int section = 0;

	if (sectionframes != 0)
	{
		if (numframes > sectionframes && *piFrame == numframes - 1)
		{
			// last frame on long anims is stored separately
			*piFrame = 0;
			section = (numframes / sectionframes) + 1;
		}
		else
		{
			section = *piFrame / sectionframes;
			*piFrame -= section * sectionframes;
		}

		block = pSection( section )->animblock;
		index = pSection( section )->animindex;
	}

	if (block == -1)
	{
		// model needs to be recompiled
		return NULL;
	}

	panim = pAnimBlock( block, index );

	// force a preload on the next block
	if ( sectionframes != 0 )
	{
		int count = ( numframes / sectionframes) + 2;
		for ( int i = section + 1; i < count; i++ )
		{
			if ( pSection( i )->animblock != block )
			{
				pAnimBlock( pSection( i )->animblock, pSection( i )->animindex );
				break;
			}
		}
	}

	if (panim == NULL)
	{
		if (section > 0 && mod_load_showstall.GetInt() > 0)
		{
			Msg("[%8.3f] hitch on %s:%s:%d:%d\n", Plat_FloatTime(), pStudiohdr()->pszName(), pszName(), section, block );
		}
		// back up until a previously loaded block is found
		while (--section >= 0)
		{
			block = pSection( section )->animblock;
			index = pSection( section )->animindex;
			panim = pAnimBlock( block, index );
			if (panim)
			{
				// set it to the last frame in the last valid section
				*piFrame = sectionframes - 1;
				break;
			}
		}
	}

	// try to guess a valid stall time interval (tuned for the X360)
	flStall = 0.0f;
	if (panim == NULL && section <= 0)
	{
		zeroframestalltime = Plat_FloatTime();
		flStall = 1.0f;
	}
	else if (panim != NULL && zeroframestalltime != 0.0f)
	{
		float dt = Plat_FloatTime() - zeroframestalltime;
		if (dt >= 0.0)
		{
			flStall = SimpleSpline( clamp( (0.200f - dt) * 5.0f, 0.0f, 1.0f ) );
		}

		if (flStall == 0.0f)
		{
			// disable stalltime
			zeroframestalltime = 0.0f;
		}
		else if (mod_load_showstall.GetInt() > 1)
		{
			Msg("[%8.3f] stall blend %.2f on %s:%s:%d:%d\n", Plat_FloatTime(), flStall, pStudiohdr()->pszName(), pszName(), section, block );
		}
	}

	if (panim == NULL && mod_load_showstall.GetInt() > 1)
	{
		Msg("[%8.3f] stall on %s:%s:%d:%d\n", Plat_FloatTime(), pStudiohdr()->pszName(), pszName(), section, block );
	}

	return panim;
}
Esempio n. 12
0
void Interpolator_CurveInterpolate_NonNormalized( int interpolationType,
												 const Quaternion &vPre,
												 const Quaternion &vStart,
												 const Quaternion &vEnd,
												 const Quaternion &vNext,
												 float f,
												 Quaternion &vOut )
{
	vOut.Init();

	switch ( interpolationType )
	{
	default:
		Warning( "Unknown interpolation type %d\n",
			(int)interpolationType );
		// break; // Fall through and use catmull_rom as default
	case INTERPOLATE_CATMULL_ROM_NORMALIZEX:
	case INTERPOLATE_DEFAULT:
	case INTERPOLATE_CATMULL_ROM:
	case INTERPOLATE_CATMULL_ROM_NORMALIZE:
	case INTERPOLATE_CATMULL_ROM_TANGENT:
	case INTERPOLATE_KOCHANEK_BARTELS:
	case INTERPOLATE_KOCHANEK_BARTELS_EARLY:
	case INTERPOLATE_KOCHANEK_BARTELS_LATE:
	case INTERPOLATE_SIMPLE_CUBIC:
	case INTERPOLATE_BSPLINE:
		// FIXME, since this ignores vPre and vNext we could omit computing them aove
		QuaternionSlerp( vStart, vEnd, f, vOut );
		break;
	case INTERPOLATE_EASE_IN:
		{
			f = sin( M_PI * f * 0.5f );
			// Fixme, since this ignores vPre and vNext we could omit computing them aove
			QuaternionSlerp( vStart, vEnd, f, vOut );
		}
		break;
	case INTERPOLATE_EASE_OUT:
		{
			f = 1.0f - sin( M_PI * f * 0.5f + 0.5f * M_PI );
			// Fixme, since this ignores vPre and vNext we could omit computing them aove
			QuaternionSlerp( vStart, vEnd, f, vOut );
		}
		break;
	case INTERPOLATE_EASE_INOUT:
		{
			f = SimpleSpline( f );
			// Fixme, since this ignores vPre and vNext we could omit computing them aove
			QuaternionSlerp( vStart, vEnd, f, vOut );
		}
		break;
	case INTERPOLATE_LINEAR_INTERP:
		// Fixme, since this ignores vPre and vNext we could omit computing them aove
		QuaternionSlerp( vStart, vEnd, f, vOut );
		break;
	case INTERPOLATE_EXPONENTIAL_DECAY:
		vOut.Init();
		break;
	case INTERPOLATE_HOLD:
		{
			vOut = vStart;
		}
		break;
	}
}
Esempio n. 13
0
void CMomentumGameMovement::Duck(void)
{
    int buttonsChanged = (mv->m_nOldButtons ^ mv->m_nButtons);	// These buttons have changed this frame
    int buttonsPressed = buttonsChanged & mv->m_nButtons;			// The changed ones still down are "pressed"
    int buttonsReleased = buttonsChanged & mv->m_nOldButtons;		// The changed ones which were previously down are "released"

    // Check to see if we are in the air.
    bool bInAir = player->GetGroundEntity() == NULL && player->GetMoveType() != MOVETYPE_LADDER;

    if (mv->m_nButtons & IN_DUCK)
    {
        mv->m_nOldButtons |= IN_DUCK;
    }
    else
    {
        mv->m_nOldButtons &= ~IN_DUCK;
    }

    if (IsDead())
    {
        // Unduck
        if (player->GetFlags() & FL_DUCKING)
        {
            FinishUnDuck();
        }
        return;
    }

    HandleDuckingSpeedCrop();

    if (player->m_duckUntilOnGround)
    {
        if (!bInAir)
        {
            player->m_duckUntilOnGround = false;
            if (CanUnduck())
            {
                FinishUnDuck();
            }
            return;
        }
        else
        {
            if (mv->m_vecVelocity.z > 0.0f)
                return;

            // Check if we can un-duck.  We want to unduck if we have space for the standing hull, and
            // if it is less than 2 inches off the ground.
            trace_t trace;
            Vector newOrigin;
            Vector groundCheck;

            VectorCopy(mv->GetAbsOrigin(), newOrigin);
            Vector hullSizeNormal = VEC_HULL_MAX - VEC_HULL_MIN;
            Vector hullSizeCrouch = VEC_DUCK_HULL_MAX - VEC_DUCK_HULL_MIN;
            newOrigin -= (hullSizeNormal - hullSizeCrouch);
            groundCheck = newOrigin;
            groundCheck.z -= player->GetStepSize();

            UTIL_TraceHull(newOrigin, groundCheck, VEC_HULL_MIN, VEC_HULL_MAX, PlayerSolidMask(), player, COLLISION_GROUP_PLAYER_MOVEMENT, &trace);

            if (trace.startsolid || trace.fraction == 1.0f)
                return; // Can't even stand up, or there's no ground underneath us

            player->m_duckUntilOnGround = false;
            if (CanUnduck())
            {
                FinishUnDuck();
            }
            return;
        }
    }

    // Holding duck, in process of ducking or fully ducked?
    if ((mv->m_nButtons & IN_DUCK) || (player->m_Local.m_bDucking) || (player->GetFlags() & FL_DUCKING))
    {
        if (mv->m_nButtons & IN_DUCK)
        {
            bool alreadyDucked = (player->GetFlags() & FL_DUCKING) ? true : false;

            if ((buttonsPressed & IN_DUCK) && !(player->GetFlags() & FL_DUCKING))
            {
                // Use 1 second so super long jump will work
                player->m_Local.m_flDucktime = 1000;
                player->m_Local.m_bDucking = true;
            }

            float duckmilliseconds = max(0.0f, 1000.0f - (float)player->m_Local.m_flDucktime);
            float duckseconds = duckmilliseconds / 1000.0f;

            //time = max( 0.0, ( 1.0 - (float)player->m_Local.m_flDucktime / 1000.0 ) );

            if (player->m_Local.m_bDucking)
            {
                // Finish ducking immediately if duck time is over or not on ground
                if ((duckseconds > TIME_TO_DUCK) ||
                    (player->GetGroundEntity() == NULL) ||
                    alreadyDucked)
                {
                    FinishDuck();
                }
                else
                {
                    // Calc parametric time
                    float duckFraction = SimpleSpline(duckseconds / TIME_TO_DUCK);
                    SetDuckedEyeOffset(duckFraction);
                }
            }
        }
        else
        {
            // Try to unduck unless automovement is not allowed
            // NOTE: When not onground, you can always unduck
            if (player->m_Local.m_bAllowAutoMovement || player->GetGroundEntity() == NULL)
            {
                if ((buttonsReleased & IN_DUCK) && (player->GetFlags() & FL_DUCKING))
                {
                    // Use 1 second so super long jump will work
                    player->m_Local.m_flDucktime = 1000;
                    player->m_Local.m_bDucking = true;  // or unducking
                }

                float duckmilliseconds = max(0.0f, 1000.0f - (float)player->m_Local.m_flDucktime);
                float duckseconds = duckmilliseconds / 1000.0f;

                if (CanUnduck())
                {
                    if (player->m_Local.m_bDucking ||
                        player->m_Local.m_bDucked) // or unducking
                    {
                        // Finish ducking immediately if duck time is over or not on ground
                        if ((duckseconds > TIME_TO_UNDUCK) ||
                            (player->GetGroundEntity() == NULL))
                        {
                            FinishUnDuck();
                        }
                        else
                        {
                            // Calc parametric time
                            float duckFraction = SimpleSpline(1.0f - (duckseconds / TIME_TO_UNDUCK));
                            SetDuckedEyeOffset(duckFraction);
                        }
                    }
                }
                else
                {
                    // Still under something where we can't unduck, so make sure we reset this timer so
                    //  that we'll unduck once we exit the tunnel, etc.
                    player->m_Local.m_flDucktime = 1000;
                }
            }
        }
    }
}