//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #include "cbase.h" #include "fx_dod_shared.h" #include "weapon_dodsniper.h" #ifdef CLIENT_DLL #include "prediction.h" #endif IMPLEMENT_NETWORKCLASS_ALIASED( DODSniperWeapon, DT_SniperWeapon ) #ifdef CLIENT_DLL void RecvProxy_AnimStart( const CRecvProxyData *pData, void *pStruct, void *pOut ) { CDODSniperWeapon *pWpn = (CDODSniperWeapon *) pStruct; pWpn->m_bDoViewAnim = ( pData->m_Value.m_Int > 0 ); } #endif BEGIN_NETWORK_TABLE( CDODSniperWeapon, DT_SniperWeapon ) #ifdef CLIENT_DLL RecvPropBool( RECVINFO( m_bZoomed ) ), RecvPropInt( RECVINFO( m_bDoViewAnim ), 0, RecvProxy_AnimStart ) #else SendPropBool( SENDINFO( m_bZoomed ) ), SendPropBool( SENDINFO( m_bDoViewAnim ) ) #endif END_NETWORK_TABLE() #ifdef CLIENT_DLL BEGIN_PREDICTION_DATA( CDODSniperWeapon ) DEFINE_PRED_FIELD( m_bZoomed, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ) END_PREDICTION_DATA() #else BEGIN_DATADESC( CDODSniperWeapon ) END_DATADESC() #endif CDODSniperWeapon::CDODSniperWeapon() { } void CDODSniperWeapon::Spawn( void ) { BaseClass::Spawn(); ResetTimers(); #ifdef CLIENT_DLL m_bDoViewAnimCache = false; m_flZoomPercent = 0.0f; #endif m_bShouldRezoomAfterShot = true; } void CDODSniperWeapon::ResetTimers( void ) { m_flUnzoomTime = -1; m_flRezoomTime = -1; m_flZoomOutTime = -1; m_flZoomInTime = -1; m_bRezoomAfterShot = false; m_bRezoomAfterReload = false; } bool CDODSniperWeapon::Holster( CBaseCombatWeapon *pSwitchingTo ) { #ifndef CLIENT_DLL ZoomOut(); ResetTimers(); #endif return BaseClass::Holster( pSwitchingTo ); } void CDODSniperWeapon::PrimaryAttack( void ) { BaseClass::PrimaryAttack(); CDODPlayer *pPlayer = ToDODPlayer( GetOwner() ); if ( IsZoomed() && ShouldZoomOutBetweenShots() ) { //If we have more bullets, zoom out, play the bolt animation and zoom back in if( m_iClip1 > 0 && m_bShouldRezoomAfterShot && ( pPlayer && pPlayer->ShouldAutoRezoom() ) ) { SetRezoom( true, 0.5f ); // zoom out in 0.5 seconds, then rezoom } else //just zoom out { SetRezoom( false, 0.5f ); // just zoom out in 0.5 seconds } } // overwrite the next secondary attack, so we can zoom sooned after we've fired if ( m_bRezoomAfterShot && m_iClip1 > 0 ) m_flNextSecondaryAttack = gpGlobals->curtime + 2.0; else m_flNextSecondaryAttack = SequenceDuration(); } void CDODSniperWeapon::SecondaryAttack( void ) { CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); Assert( pPlayer ); if ( !pPlayer ) return; ToggleZoom(); } bool CDODSniperWeapon::Reload( void ) { bool bSuccess = BaseClass::Reload(); if ( bSuccess && IsZoomed() ) { //if ( ShouldRezoomAfterReload() ) // m_bRezoomAfterReload = true; ZoomOut(); } if ( !bSuccess ) m_bRezoomAfterReload = false; return bSuccess; } void CDODSniperWeapon::FinishReload( void ) { BaseClass::FinishReload(); if ( m_bRezoomAfterReload ) { ZoomIn(); m_bRezoomAfterReload = false; } } float CDODSniperWeapon::GetWeaponAccuracy( float flPlayerSpeed ) { //snipers and deployable weapons inherit this and override when we need a different accuracy float flSpread = m_pWeaponInfo->m_flAccuracy; if ( IsZoomed() && ( gpGlobals->curtime - m_flZoomChangeTime ) > DOD_SNIPER_ZOOM_CHANGE_TIME ) { flSpread = m_pWeaponInfo->m_flSecondaryAccuracy; } if( flPlayerSpeed > 45 ) flSpread += m_pWeaponInfo->m_flAccuracyMovePenalty; return flSpread; } bool CDODSniperWeapon::IsZoomed( void ) { // check the player? return IsSniperZoomed(); } bool CDODSniperWeapon::ShouldDrawCrosshair( void ) { //if ( IsFullyZoomed() ) // return false; // don't draw if we are zoomed at all if ( m_bZoomed ) return false; return BaseClass::ShouldDrawCrosshair(); } #include "in_buttons.h" void CDODSniperWeapon::ItemPostFrame( void ) { if ( m_flUnzoomTime > 0 && gpGlobals->curtime > m_flUnzoomTime ) { if ( m_bRezoomAfterShot ) { ZoomOutIn(); m_bRezoomAfterShot = false; } else { ZoomOut(); } m_flUnzoomTime = -1; } CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() ); Assert( pPlayer ); if ( m_flRezoomTime > 0 ) { // if the player is sprinting and moving at all, cancel the rezoom if ( ( pPlayer->m_nButtons & IN_SPEED ) > 0 && pPlayer->GetAbsVelocity().Length2D() > 20 ) { m_flRezoomTime = -1; } else if ( gpGlobals->curtime > m_flRezoomTime ) { ZoomIn(); m_flRezoomTime = -1; } } if ( m_flZoomInTime > 0 && gpGlobals->curtime > m_flZoomInTime ) { #ifndef CLIENT_DLL CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() ); Assert( pPlayer ); pPlayer->SetFOV( pPlayer, GetZoomedFOV(), 0.1f ); #endif m_flZoomInTime = -1; m_flZoomOutTime = -1; } if ( m_flZoomInTime > 0 && (pPlayer->m_nButtons & IN_ATTACK) ) { m_bInAttack = true; } BaseClass::ItemPostFrame(); } void CDODSniperWeapon::Drop( const Vector &vecVelocity ) { // If a player is killed while deployed, this resets the weapon state if ( IsZoomed() ) ZoomOut(); ResetTimers(); BaseClass::Drop( vecVelocity ); } void CDODSniperWeapon::ToggleZoom( void ) { CDODPlayer *pPlayer = GetDODPlayerOwner(); if ( !pPlayer->m_Shared.IsJumping() ) { if( !IsZoomed() ) { if ( CanAttack() ) { #ifndef CLIENT_DLL pPlayer->RemoveHintTimer( m_iAltFireHint ); #endif ZoomIn(); } } else { ZoomOut(); } } } void CDODSniperWeapon::ZoomIn( void ) { m_flZoomInTime = gpGlobals->curtime + DOD_SNIPER_ZOOM_CHANGE_TIME; #ifndef CLIENT_DLL SetZoomed( true ); m_bDoViewAnim = !m_bDoViewAnim; #endif m_flNextPrimaryAttack = MAX( gpGlobals->curtime + 0.5, m_flNextPrimaryAttack ); m_flNextSecondaryAttack = MAX( gpGlobals->curtime + 0.5, m_flNextSecondaryAttack ); m_flTimeWeaponIdle = gpGlobals->curtime + m_pWeaponInfo->m_flTimeToIdleAfterFire; m_flZoomChangeTime = gpGlobals->curtime; } void CDODSniperWeapon::ZoomOut( void ) { bool bWasZoomed = IsZoomed(); #ifndef CLIENT_DLL CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() ); Assert( pPlayer ); pPlayer->SetFOV( pPlayer, 90, 0.1f ); SetZoomed( false ); m_bDoViewAnim = !m_bDoViewAnim; #endif if ( bWasZoomed ) { m_flNextPrimaryAttack = MAX( gpGlobals->curtime + 0.5, m_flNextPrimaryAttack ); m_flNextSecondaryAttack = MAX( gpGlobals->curtime + 0.5, m_flNextSecondaryAttack ); m_flTimeWeaponIdle = gpGlobals->curtime + m_pWeaponInfo->m_flTimeToIdleAfterFire; } m_flZoomChangeTime = gpGlobals->curtime; // if we are thinking about zooming, cancel it m_flZoomInTime = -1; m_flUnzoomTime = -1; m_flRezoomTime = -1; } // reduce rezoome time, to account for fade in we're replacing with anim #define REZOOM_TIME 1.2f void CDODSniperWeapon::ZoomOutIn( void ) { ZoomOut(); m_flRezoomTime = gpGlobals->curtime + 1.0; } void CDODSniperWeapon::SetRezoom( bool bRezoom, float flDelay ) { m_flUnzoomTime = gpGlobals->curtime + flDelay; m_bRezoomAfterShot = bRezoom; } bool CDODSniperWeapon::IsFullyZoomed( void ) { return ( IsZoomed() == true && (( gpGlobals->curtime - m_flZoomChangeTime ) > DOD_SNIPER_ZOOM_CHANGE_TIME) ); } bool CDODSniperWeapon::IsZoomingIn( void ) { return ( m_flZoomInTime > gpGlobals->curtime ); } #ifdef CLIENT_DLL float CDODSniperWeapon::GetZoomedPercentage( void ) { return m_flZoomPercent; } Vector CDODSniperWeapon::GetDesiredViewModelOffset( C_DODPlayer *pOwner ) { static Vector vecLastResult = vec3_origin; if ( prediction->InPrediction() && !prediction->IsFirstTimePredicted() ) { return vecLastResult; } if ( m_bDoViewAnim != m_bDoViewAnimCache ) { // start the anim timer m_flViewAnimTimer = gpGlobals->curtime + DOD_SNIPER_ZOOM_CHANGE_TIME; m_bDoViewAnimCache = m_bDoViewAnim.m_Value; } Vector viewOffset = pOwner->GetViewOffset(); float flPercent = clamp( ( viewOffset.z - VEC_PRONE_VIEW_SCALED( pOwner ).z ) / ( VEC_VIEW_SCALED( pOwner ).z - VEC_PRONE_VIEW_SCALED( pOwner ).z ), 0.0, 1.0 ); Vector offset = ( flPercent * GetDODWpnData().m_vecViewNormalOffset + ( 1.0 - flPercent ) * GetDODWpnData().m_vecViewProneOffset ); // how long since we changed iron sight mode float flZoomAnimPercent = clamp( ( (m_flViewAnimTimer - gpGlobals->curtime) / ( DOD_SNIPER_ZOOM_CHANGE_TIME ) ), 0.0, 1.0 ); m_flZoomPercent = ( IsZoomed() ? ( 1.0 - flZoomAnimPercent ) : flZoomAnimPercent ); //Msg( "(%.1f) zoom %.2f %.2f\n", gpGlobals->curtime, m_flViewAnimTimer - gpGlobals->curtime, m_flZoomPercent ); // use that percent to interp to iron sight position Vector vecResult = ( m_flZoomPercent * GetDODWpnData().m_vecIronSightOffset + ( 1.0 - m_flZoomPercent ) * offset ); // store this value to use when called in prediction vecLastResult = vecResult; return vecResult; } float CDODSniperWeapon::GetViewModelSwayScale( void ) { if ( IsFullyZoomed() ) return 0; return BaseClass::GetViewModelSwayScale(); } #endif //CLIENT_DLL