Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "fx_dod_shared.h"
  8. #include "weapon_dodsniper.h"
  9. #ifdef CLIENT_DLL
  10. #include "prediction.h"
  11. #endif
  12. IMPLEMENT_NETWORKCLASS_ALIASED( DODSniperWeapon, DT_SniperWeapon )
  13. #ifdef CLIENT_DLL
  14. void RecvProxy_AnimStart( const CRecvProxyData *pData, void *pStruct, void *pOut )
  15. {
  16. CDODSniperWeapon *pWpn = (CDODSniperWeapon *) pStruct;
  17. pWpn->m_bDoViewAnim = ( pData->m_Value.m_Int > 0 );
  18. }
  19. #endif
  20. BEGIN_NETWORK_TABLE( CDODSniperWeapon, DT_SniperWeapon )
  21. #ifdef CLIENT_DLL
  22. RecvPropBool( RECVINFO( m_bZoomed ) ),
  23. RecvPropInt( RECVINFO( m_bDoViewAnim ), 0, RecvProxy_AnimStart )
  24. #else
  25. SendPropBool( SENDINFO( m_bZoomed ) ),
  26. SendPropBool( SENDINFO( m_bDoViewAnim ) )
  27. #endif
  28. END_NETWORK_TABLE()
  29. #ifdef CLIENT_DLL
  30. BEGIN_PREDICTION_DATA( CDODSniperWeapon )
  31. DEFINE_PRED_FIELD( m_bZoomed, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE )
  32. END_PREDICTION_DATA()
  33. #else
  34. BEGIN_DATADESC( CDODSniperWeapon )
  35. END_DATADESC()
  36. #endif
  37. CDODSniperWeapon::CDODSniperWeapon()
  38. {
  39. }
  40. void CDODSniperWeapon::Spawn( void )
  41. {
  42. BaseClass::Spawn();
  43. ResetTimers();
  44. #ifdef CLIENT_DLL
  45. m_bDoViewAnimCache = false;
  46. m_flZoomPercent = 0.0f;
  47. #endif
  48. m_bShouldRezoomAfterShot = true;
  49. }
  50. void CDODSniperWeapon::ResetTimers( void )
  51. {
  52. m_flUnzoomTime = -1;
  53. m_flRezoomTime = -1;
  54. m_flZoomOutTime = -1;
  55. m_flZoomInTime = -1;
  56. m_bRezoomAfterShot = false;
  57. m_bRezoomAfterReload = false;
  58. }
  59. bool CDODSniperWeapon::Holster( CBaseCombatWeapon *pSwitchingTo )
  60. {
  61. #ifndef CLIENT_DLL
  62. ZoomOut();
  63. ResetTimers();
  64. #endif
  65. return BaseClass::Holster( pSwitchingTo );
  66. }
  67. void CDODSniperWeapon::PrimaryAttack( void )
  68. {
  69. BaseClass::PrimaryAttack();
  70. CDODPlayer *pPlayer = ToDODPlayer( GetOwner() );
  71. if ( IsZoomed() && ShouldZoomOutBetweenShots() )
  72. {
  73. //If we have more bullets, zoom out, play the bolt animation and zoom back in
  74. if( m_iClip1 > 0 && m_bShouldRezoomAfterShot && ( pPlayer && pPlayer->ShouldAutoRezoom() ) )
  75. {
  76. SetRezoom( true, 0.5f ); // zoom out in 0.5 seconds, then rezoom
  77. }
  78. else //just zoom out
  79. {
  80. SetRezoom( false, 0.5f ); // just zoom out in 0.5 seconds
  81. }
  82. }
  83. // overwrite the next secondary attack, so we can zoom sooned after we've fired
  84. if ( m_bRezoomAfterShot && m_iClip1 > 0 )
  85. m_flNextSecondaryAttack = gpGlobals->curtime + 2.0;
  86. else
  87. m_flNextSecondaryAttack = SequenceDuration();
  88. }
  89. void CDODSniperWeapon::SecondaryAttack( void )
  90. {
  91. CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
  92. Assert( pPlayer );
  93. if ( !pPlayer )
  94. return;
  95. ToggleZoom();
  96. }
  97. bool CDODSniperWeapon::Reload( void )
  98. {
  99. bool bSuccess = BaseClass::Reload();
  100. if ( bSuccess && IsZoomed() )
  101. {
  102. //if ( ShouldRezoomAfterReload() )
  103. // m_bRezoomAfterReload = true;
  104. ZoomOut();
  105. }
  106. if ( !bSuccess )
  107. m_bRezoomAfterReload = false;
  108. return bSuccess;
  109. }
  110. void CDODSniperWeapon::FinishReload( void )
  111. {
  112. BaseClass::FinishReload();
  113. if ( m_bRezoomAfterReload )
  114. {
  115. ZoomIn();
  116. m_bRezoomAfterReload = false;
  117. }
  118. }
  119. float CDODSniperWeapon::GetWeaponAccuracy( float flPlayerSpeed )
  120. {
  121. //snipers and deployable weapons inherit this and override when we need a different accuracy
  122. float flSpread = m_pWeaponInfo->m_flAccuracy;
  123. if ( IsZoomed() && ( gpGlobals->curtime - m_flZoomChangeTime ) > DOD_SNIPER_ZOOM_CHANGE_TIME )
  124. {
  125. flSpread = m_pWeaponInfo->m_flSecondaryAccuracy;
  126. }
  127. if( flPlayerSpeed > 45 )
  128. flSpread += m_pWeaponInfo->m_flAccuracyMovePenalty;
  129. return flSpread;
  130. }
  131. bool CDODSniperWeapon::IsZoomed( void )
  132. {
  133. // check the player?
  134. return IsSniperZoomed();
  135. }
  136. bool CDODSniperWeapon::ShouldDrawCrosshair( void )
  137. {
  138. //if ( IsFullyZoomed() )
  139. // return false;
  140. // don't draw if we are zoomed at all
  141. if ( m_bZoomed )
  142. return false;
  143. return BaseClass::ShouldDrawCrosshair();
  144. }
  145. #include "in_buttons.h"
  146. void CDODSniperWeapon::ItemPostFrame( void )
  147. {
  148. if ( m_flUnzoomTime > 0 && gpGlobals->curtime > m_flUnzoomTime )
  149. {
  150. if ( m_bRezoomAfterShot )
  151. {
  152. ZoomOutIn();
  153. m_bRezoomAfterShot = false;
  154. }
  155. else
  156. {
  157. ZoomOut();
  158. }
  159. m_flUnzoomTime = -1;
  160. }
  161. CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
  162. Assert( pPlayer );
  163. if ( m_flRezoomTime > 0 )
  164. {
  165. // if the player is sprinting and moving at all, cancel the rezoom
  166. if ( ( pPlayer->m_nButtons & IN_SPEED ) > 0 &&
  167. pPlayer->GetAbsVelocity().Length2D() > 20 )
  168. {
  169. m_flRezoomTime = -1;
  170. }
  171. else if ( gpGlobals->curtime > m_flRezoomTime )
  172. {
  173. ZoomIn();
  174. m_flRezoomTime = -1;
  175. }
  176. }
  177. if ( m_flZoomInTime > 0 && gpGlobals->curtime > m_flZoomInTime )
  178. {
  179. #ifndef CLIENT_DLL
  180. CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
  181. Assert( pPlayer );
  182. pPlayer->SetFOV( pPlayer, GetZoomedFOV(), 0.1f );
  183. #endif
  184. m_flZoomInTime = -1;
  185. m_flZoomOutTime = -1;
  186. }
  187. if ( m_flZoomInTime > 0 && (pPlayer->m_nButtons & IN_ATTACK) )
  188. {
  189. m_bInAttack = true;
  190. }
  191. BaseClass::ItemPostFrame();
  192. }
  193. void CDODSniperWeapon::Drop( const Vector &vecVelocity )
  194. {
  195. // If a player is killed while deployed, this resets the weapon state
  196. if ( IsZoomed() )
  197. ZoomOut();
  198. ResetTimers();
  199. BaseClass::Drop( vecVelocity );
  200. }
  201. void CDODSniperWeapon::ToggleZoom( void )
  202. {
  203. CDODPlayer *pPlayer = GetDODPlayerOwner();
  204. if ( !pPlayer->m_Shared.IsJumping() )
  205. {
  206. if( !IsZoomed() )
  207. {
  208. if ( CanAttack() )
  209. {
  210. #ifndef CLIENT_DLL
  211. pPlayer->RemoveHintTimer( m_iAltFireHint );
  212. #endif
  213. ZoomIn();
  214. }
  215. }
  216. else
  217. {
  218. ZoomOut();
  219. }
  220. }
  221. }
  222. void CDODSniperWeapon::ZoomIn( void )
  223. {
  224. m_flZoomInTime = gpGlobals->curtime + DOD_SNIPER_ZOOM_CHANGE_TIME;
  225. #ifndef CLIENT_DLL
  226. SetZoomed( true );
  227. m_bDoViewAnim = !m_bDoViewAnim;
  228. #endif
  229. m_flNextPrimaryAttack = MAX( gpGlobals->curtime + 0.5, m_flNextPrimaryAttack );
  230. m_flNextSecondaryAttack = MAX( gpGlobals->curtime + 0.5, m_flNextSecondaryAttack );
  231. m_flTimeWeaponIdle = gpGlobals->curtime + m_pWeaponInfo->m_flTimeToIdleAfterFire;
  232. m_flZoomChangeTime = gpGlobals->curtime;
  233. }
  234. void CDODSniperWeapon::ZoomOut( void )
  235. {
  236. bool bWasZoomed = IsZoomed();
  237. #ifndef CLIENT_DLL
  238. CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
  239. Assert( pPlayer );
  240. pPlayer->SetFOV( pPlayer, 90, 0.1f );
  241. SetZoomed( false );
  242. m_bDoViewAnim = !m_bDoViewAnim;
  243. #endif
  244. if ( bWasZoomed )
  245. {
  246. m_flNextPrimaryAttack = MAX( gpGlobals->curtime + 0.5, m_flNextPrimaryAttack );
  247. m_flNextSecondaryAttack = MAX( gpGlobals->curtime + 0.5, m_flNextSecondaryAttack );
  248. m_flTimeWeaponIdle = gpGlobals->curtime + m_pWeaponInfo->m_flTimeToIdleAfterFire;
  249. }
  250. m_flZoomChangeTime = gpGlobals->curtime;
  251. // if we are thinking about zooming, cancel it
  252. m_flZoomInTime = -1;
  253. m_flUnzoomTime = -1;
  254. m_flRezoomTime = -1;
  255. }
  256. // reduce rezoome time, to account for fade in we're replacing with anim
  257. #define REZOOM_TIME 1.2f
  258. void CDODSniperWeapon::ZoomOutIn( void )
  259. {
  260. ZoomOut();
  261. m_flRezoomTime = gpGlobals->curtime + 1.0;
  262. }
  263. void CDODSniperWeapon::SetRezoom( bool bRezoom, float flDelay )
  264. {
  265. m_flUnzoomTime = gpGlobals->curtime + flDelay;
  266. m_bRezoomAfterShot = bRezoom;
  267. }
  268. bool CDODSniperWeapon::IsFullyZoomed( void )
  269. {
  270. return ( IsZoomed() == true &&
  271. (( gpGlobals->curtime - m_flZoomChangeTime ) > DOD_SNIPER_ZOOM_CHANGE_TIME) );
  272. }
  273. bool CDODSniperWeapon::IsZoomingIn( void )
  274. {
  275. return ( m_flZoomInTime > gpGlobals->curtime );
  276. }
  277. #ifdef CLIENT_DLL
  278. float CDODSniperWeapon::GetZoomedPercentage( void )
  279. {
  280. return m_flZoomPercent;
  281. }
  282. Vector CDODSniperWeapon::GetDesiredViewModelOffset( C_DODPlayer *pOwner )
  283. {
  284. static Vector vecLastResult = vec3_origin;
  285. if ( prediction->InPrediction() && !prediction->IsFirstTimePredicted() )
  286. {
  287. return vecLastResult;
  288. }
  289. if ( m_bDoViewAnim != m_bDoViewAnimCache )
  290. {
  291. // start the anim timer
  292. m_flViewAnimTimer = gpGlobals->curtime + DOD_SNIPER_ZOOM_CHANGE_TIME;
  293. m_bDoViewAnimCache = m_bDoViewAnim.m_Value;
  294. }
  295. Vector viewOffset = pOwner->GetViewOffset();
  296. 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 );
  297. Vector offset = ( flPercent * GetDODWpnData().m_vecViewNormalOffset +
  298. ( 1.0 - flPercent ) * GetDODWpnData().m_vecViewProneOffset );
  299. // how long since we changed iron sight mode
  300. float flZoomAnimPercent = clamp( ( (m_flViewAnimTimer - gpGlobals->curtime) / ( DOD_SNIPER_ZOOM_CHANGE_TIME ) ), 0.0, 1.0 );
  301. m_flZoomPercent = ( IsZoomed() ? ( 1.0 - flZoomAnimPercent ) : flZoomAnimPercent );
  302. //Msg( "(%.1f) zoom %.2f %.2f\n", gpGlobals->curtime, m_flViewAnimTimer - gpGlobals->curtime, m_flZoomPercent );
  303. // use that percent to interp to iron sight position
  304. Vector vecResult = ( m_flZoomPercent * GetDODWpnData().m_vecIronSightOffset +
  305. ( 1.0 - m_flZoomPercent ) * offset );
  306. // store this value to use when called in prediction
  307. vecLastResult = vecResult;
  308. return vecResult;
  309. }
  310. float CDODSniperWeapon::GetViewModelSwayScale( void )
  311. {
  312. if ( IsFullyZoomed() )
  313. return 0;
  314. return BaseClass::GetViewModelSwayScale();
  315. }
  316. #endif //CLIENT_DLL