//----------------------------------------------------------------------------- // 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; } } } } }
//----------------------------------------------------------------------------- // 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; } } } } }
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; } } } } }