You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
414 lines
8.8 KiB
414 lines
8.8 KiB
//========= 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
|
|
|