Counter Strike : Global Offensive Source Code
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.

689 lines
21 KiB

  1. //===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //===========================================================================//
  7. #include "cbase.h"
  8. #include "weapon_ifmsteadycam.h"
  9. #include "in_buttons.h"
  10. #include "usercmd.h"
  11. #include "dt_shared.h"
  12. #ifdef CLIENT_DLL
  13. #include "vgui_controls/controls.h"
  14. #include "vgui/isurface.h"
  15. #include "vgui/ischeme.h"
  16. #include "vgui/ilocalize.h"
  17. #include "vgui/vgui.h"
  18. #include "tier1/KeyValues.h"
  19. #include "toolframework/itoolframework.h"
  20. #endif
  21. // NOTE: This has to be the last file included!
  22. #include "tier0/memdbgon.h"
  23. //-----------------------------------------------------------------------------
  24. // CWeaponIFMSteadyCam tables.
  25. //-----------------------------------------------------------------------------
  26. IMPLEMENT_NETWORKCLASS_ALIASED( WeaponIFMSteadyCam, DT_WeaponIFMSteadyCam )
  27. LINK_ENTITY_TO_CLASS( weapon_ifm_steadycam, CWeaponIFMSteadyCam );
  28. #if !( defined( TF_CLIENT_DLL ) || defined( TF_DLL ) )
  29. PRECACHE_WEAPON_REGISTER( weapon_ifm_steadycam );
  30. #endif
  31. BEGIN_NETWORK_TABLE( CWeaponIFMSteadyCam, DT_WeaponIFMSteadyCam )
  32. END_NETWORK_TABLE()
  33. #ifdef CLIENT_DLL
  34. BEGIN_PREDICTION_DATA( CWeaponIFMSteadyCam )
  35. DEFINE_PRED_FIELD( m_bIsLocked, FIELD_BOOLEAN, 0 ),
  36. DEFINE_PRED_FIELD( m_bInSpringMode, FIELD_BOOLEAN, 0 ),
  37. DEFINE_PRED_FIELD( m_bInDirectMode, FIELD_BOOLEAN, 0 ),
  38. DEFINE_PRED_FIELD( m_vecOffset, FIELD_VECTOR, 0 ),
  39. DEFINE_PRED_FIELD( m_hLockTarget, FIELD_EHANDLE, 0 ),
  40. DEFINE_PRED_FIELD( m_vec2DVelocity, FIELD_VECTOR, 0 ),
  41. DEFINE_PRED_FIELD( m_vecActualViewOffset, FIELD_VECTOR, 0 ),
  42. DEFINE_PRED_FIELD( m_vecViewOffset, FIELD_VECTOR, 0 ),
  43. DEFINE_PRED_FIELD( m_flFOVOffsetY, FIELD_FLOAT, 0 ),
  44. END_PREDICTION_DATA()
  45. #endif
  46. #ifdef GAME_DLL
  47. BEGIN_DATADESC( CWeaponIFMSteadyCam )
  48. DEFINE_FIELD( m_hLockTarget, FIELD_EHANDLE ),
  49. END_DATADESC()
  50. #endif
  51. //-----------------------------------------------------------------------------
  52. // CWeaponIFMSteadyCam implementation.
  53. //-----------------------------------------------------------------------------
  54. CWeaponIFMSteadyCam::CWeaponIFMSteadyCam()
  55. {
  56. #ifdef CLIENT_DLL
  57. m_bIsLocked = false;
  58. m_bInDirectMode = false;
  59. m_bInSpringMode = true;
  60. m_vec2DVelocity.Init();
  61. m_vecActualViewOffset.Init();
  62. m_vecViewOffset.Init();
  63. m_flFOVOffsetY = 0.0f;
  64. m_vecOffset.Init();
  65. m_hFont = vgui::INVALID_FONT;
  66. m_nTextureId = -1;
  67. #endif
  68. }
  69. //-----------------------------------------------------------------------------
  70. //
  71. // Specific methods on the client
  72. //
  73. //-----------------------------------------------------------------------------
  74. #ifdef CLIENT_DLL
  75. //-----------------------------------------------------------------------------
  76. // Computes a matrix given a forward direction
  77. //-----------------------------------------------------------------------------
  78. void CWeaponIFMSteadyCam::MatrixFromForwardDirection( const Vector &vecForward, matrix3x4_t &mat )
  79. {
  80. // Convert desired to quaternion
  81. Vector vecLeft( -vecForward.y, vecForward.x, 0.0f );
  82. if ( VectorNormalize( vecLeft ) < 1e-3 )
  83. {
  84. vecLeft.Init( 1.0f, 0.0f, 0.0f );
  85. }
  86. Vector vecUp;
  87. CrossProduct( vecForward, vecLeft, vecUp );
  88. MatrixInitialize( mat, m_vecRelativePosition, vecForward, vecLeft, vecUp );
  89. }
  90. //-----------------------------------------------------------------------------
  91. // Updates the relative orientation of the camera, spring mode
  92. //-----------------------------------------------------------------------------
  93. void CWeaponIFMSteadyCam::ComputeMouseRay( const VMatrix &steadyCamToPlayer, Vector &vecForward )
  94. {
  95. // Create a ray in steadycam space
  96. float flMaxD = 1.0f / tan( M_PI * m_flFOV / 360.0f );
  97. // Remap offsets into normalized space
  98. int w, h;
  99. GetViewportSize( w, h );
  100. float flViewX = ( w != 0 ) ? m_vecViewOffset.x / ( w / 2 ) : 0.0f;
  101. float flViewY = ( h != 0 ) ? m_vecViewOffset.y / ( h / 2 ) : 0.0f;
  102. flViewX *= flMaxD;
  103. flViewY *= flMaxD;
  104. Vector vecSelectionDir( 1.0f, -flViewX, -flViewY );
  105. VectorNormalize( vecSelectionDir );
  106. // Rotate the ray into player coordinates
  107. Vector3DMultiply( steadyCamToPlayer, vecSelectionDir, vecForward );
  108. }
  109. //-----------------------------------------------------------------------------
  110. // Updates the relative orientation of the camera, spring mode
  111. //-----------------------------------------------------------------------------
  112. void CWeaponIFMSteadyCam::UpdateDirectRelativeOrientation()
  113. {
  114. // Compute a player to steadycam matrix
  115. VMatrix steadyCamToPlayer;
  116. MatrixFromAngles( m_angRelativeAngles, steadyCamToPlayer );
  117. MatrixSetColumn( steadyCamToPlayer, 3, m_vecRelativePosition );
  118. // Compute a forward direction
  119. Vector vecCurrentForward;
  120. MatrixGetColumn( steadyCamToPlayer, 0, &vecCurrentForward );
  121. // Before any updating occurs, sample the current
  122. // world-space direction of the mouse
  123. Vector vecDesiredDirection;
  124. ComputeMouseRay( steadyCamToPlayer, vecDesiredDirection );
  125. // rebuild a roll-less orientation based on that direction vector
  126. matrix3x4_t mat;
  127. MatrixFromForwardDirection( vecDesiredDirection, mat );
  128. MatrixAngles( mat, m_angRelativeAngles );
  129. Assert( m_angRelativeAngles.IsValid() );
  130. m_vecActualViewOffset -= m_vecViewOffset;
  131. m_vecViewOffset.Init();
  132. }
  133. //-----------------------------------------------------------------------------
  134. // Updates the relative orientation of the camera when locked
  135. //-----------------------------------------------------------------------------
  136. void CWeaponIFMSteadyCam::UpdateLockedRelativeOrientation()
  137. {
  138. CBasePlayer *pPlayer = GetPlayerOwner();
  139. if ( !pPlayer )
  140. return;
  141. Vector vecDesiredDirection = m_vecOffset;
  142. CBaseEntity *pLock = m_hLockTarget.Get();
  143. if ( pLock )
  144. {
  145. vecDesiredDirection += pLock->GetAbsOrigin();
  146. }
  147. Vector vecAbsOrigin;
  148. QAngle angAbsRotation;
  149. ComputeAbsCameraTransform( vecAbsOrigin, angAbsRotation );
  150. vecDesiredDirection -= vecAbsOrigin;
  151. VectorNormalize( vecDesiredDirection );
  152. matrix3x4_t mat;
  153. MatrixFromForwardDirection( vecDesiredDirection, mat );
  154. MatrixAngles( mat, m_angRelativeAngles );
  155. }
  156. //-----------------------------------------------------------------------------
  157. // Updates the relative orientation of the camera
  158. //-----------------------------------------------------------------------------
  159. static ConVar ifm_steadycam_rotaterate( "ifm_steadycam_rotaterate", "60", FCVAR_ARCHIVE );
  160. static ConVar ifm_steadycam_zoomspeed( "ifm_steadycam_zoomspeed", "1.0", FCVAR_ARCHIVE );
  161. static ConVar ifm_steadycam_zoomdamp( "ifm_steadycam_zoomdamp", "0.95", FCVAR_ARCHIVE );
  162. static ConVar ifm_steadycam_armspeed( "ifm_steadycam_armspeed", "0.5", FCVAR_ARCHIVE );
  163. static ConVar ifm_steadycam_rotatedamp( "ifm_steadycam_rotatedamp", "0.95", FCVAR_ARCHIVE );
  164. static ConVar ifm_steadycam_mousefactor( "ifm_steadycam_mousefactor", "1.0", FCVAR_ARCHIVE );
  165. static ConVar ifm_steadycam_mousepower( "ifm_steadycam_mousepower", "1.0", FCVAR_ARCHIVE );
  166. void CWeaponIFMSteadyCam::UpdateRelativeOrientation()
  167. {
  168. if ( m_bIsLocked )
  169. return;
  170. if ( m_bInDirectMode )
  171. {
  172. UpdateDirectRelativeOrientation();
  173. return;
  174. }
  175. if ( ( m_vecViewOffset.x == 0.0f ) && ( m_vecViewOffset.y == 0.0f ) )
  176. return;
  177. // Compute a player to steadycam matrix
  178. VMatrix steadyCamToPlayer;
  179. MatrixFromAngles( m_angRelativeAngles, steadyCamToPlayer );
  180. MatrixSetColumn( steadyCamToPlayer, 3, m_vecRelativePosition );
  181. Vector vecCurrentForward;
  182. MatrixGetColumn( steadyCamToPlayer, 0, &vecCurrentForward );
  183. // Create a ray in steadycam space
  184. float flMaxD = 1.0f / tan( M_PI * m_flFOV / 360.0f );
  185. // Remap offsets into normalized space
  186. float flViewX = m_vecViewOffset.x / ( 384 / 2 );
  187. float flViewY = m_vecViewOffset.y / ( 288 / 2 );
  188. flViewX *= flMaxD * ifm_steadycam_mousefactor.GetFloat();
  189. flViewY *= flMaxD * ifm_steadycam_mousefactor.GetFloat();
  190. Vector vecSelectionDir( 1.0f, -flViewX, -flViewY );
  191. VectorNormalize( vecSelectionDir );
  192. // Rotate the ray into player coordinates
  193. Vector vecDesiredDirection;
  194. Vector3DMultiply( steadyCamToPlayer, vecSelectionDir, vecDesiredDirection );
  195. float flDot = DotProduct( vecDesiredDirection, vecCurrentForward );
  196. flDot = clamp( flDot, -1.0f, 1.0f );
  197. float flAngle = 180.0f * acos( flDot ) / M_PI;
  198. if ( flAngle < 1e-3 )
  199. {
  200. matrix3x4_t mat;
  201. MatrixFromForwardDirection( vecDesiredDirection, mat );
  202. MatrixAngles( mat, m_angRelativeAngles );
  203. return;
  204. }
  205. Vector vecAxis;
  206. CrossProduct( vecCurrentForward, vecDesiredDirection, vecAxis );
  207. VectorNormalize( vecAxis );
  208. float flRotateRate = ifm_steadycam_rotaterate.GetFloat();
  209. if ( flRotateRate < 1.0f )
  210. {
  211. flRotateRate = 1.0f;
  212. }
  213. float flRateFactor = flAngle / flRotateRate;
  214. flRateFactor *= flRateFactor * flRateFactor;
  215. float flRate = flRateFactor * 30.0f;
  216. float flMaxAngle = gpGlobals->frametime * flRate;
  217. flAngle = clamp( flAngle, 0.0f, flMaxAngle );
  218. Vector vecNewForard;
  219. VMatrix rotation;
  220. MatrixBuildRotationAboutAxis( rotation, vecAxis, flAngle );
  221. Vector3DMultiply( rotation, vecCurrentForward, vecNewForard );
  222. matrix3x4_t mat;
  223. MatrixFromForwardDirection( vecNewForard, mat );
  224. MatrixAngles( mat, m_angRelativeAngles );
  225. Assert( m_angRelativeAngles.IsValid() );
  226. }
  227. //-----------------------------------------------------------------------------
  228. // Toggles to springy camera
  229. //-----------------------------------------------------------------------------
  230. void CWeaponIFMSteadyCam::ToggleDirectMode()
  231. {
  232. m_vecViewOffset.Init();
  233. m_vecActualViewOffset.Init();
  234. m_vec2DVelocity.Init();
  235. m_bInDirectMode = !m_bInDirectMode;
  236. }
  237. //-----------------------------------------------------------------------------
  238. // Targets the camera to always look at a point
  239. //-----------------------------------------------------------------------------
  240. void CWeaponIFMSteadyCam::LockCamera()
  241. {
  242. m_vecViewOffset.Init();
  243. m_vecActualViewOffset.Init();
  244. m_vec2DVelocity.Init();
  245. m_bIsLocked = !m_bIsLocked;
  246. if ( !m_bIsLocked )
  247. {
  248. UpdateLockedRelativeOrientation();
  249. return;
  250. }
  251. CBasePlayer *pPlayer = GetPlayerOwner();
  252. if ( !pPlayer )
  253. return;
  254. Vector vTraceStart, vTraceEnd, vTraceDir;
  255. QAngle angles;
  256. BaseClass::ComputeAbsCameraTransform( vTraceStart, angles );
  257. AngleVectors( angles, &vTraceDir );
  258. VectorMA( vTraceStart, 10000.0f, vTraceDir, vTraceEnd);
  259. trace_t tr;
  260. UTIL_TraceLine( vTraceStart, vTraceEnd, MASK_ALL, GetPlayerOwner(), COLLISION_GROUP_NONE, &tr );
  261. if ( tr.fraction == 1.0f )
  262. {
  263. m_bIsLocked = false;
  264. UpdateLockedRelativeOrientation();
  265. return;
  266. }
  267. m_hLockTarget = tr.m_pEnt;
  268. m_vecOffset = tr.endpos;
  269. if ( tr.m_pEnt )
  270. {
  271. m_vecOffset -= tr.m_pEnt->GetAbsOrigin();
  272. }
  273. }
  274. //-----------------------------------------------------------------------------
  275. // Gets the abs orientation of the camera
  276. //-----------------------------------------------------------------------------
  277. void CWeaponIFMSteadyCam::ComputeAbsCameraTransform( Vector &vecAbsOrigin, QAngle &angAbsRotation )
  278. {
  279. CBaseEntity *pLock = m_bIsLocked ? m_hLockTarget.Get() : NULL;
  280. CBasePlayer *pPlayer = GetPlayerOwner();
  281. if ( !pLock || !pPlayer )
  282. {
  283. BaseClass::ComputeAbsCameraTransform( vecAbsOrigin, angAbsRotation );
  284. return;
  285. }
  286. Vector vecDesiredDirection = m_vecOffset;
  287. if ( pLock )
  288. {
  289. vecDesiredDirection += pLock->GetAbsOrigin();
  290. }
  291. BaseClass::ComputeAbsCameraTransform( vecAbsOrigin, angAbsRotation );
  292. vecDesiredDirection -= vecAbsOrigin;
  293. VectorNormalize( vecDesiredDirection );
  294. matrix3x4_t mat;
  295. MatrixFromForwardDirection( vecDesiredDirection, mat );
  296. MatrixAngles( mat, angAbsRotation );
  297. }
  298. //-----------------------------------------------------------------------------
  299. // Computes the view offset from the actual view offset
  300. //-----------------------------------------------------------------------------
  301. static ConVar ifm_steadycam_2dspringconstant( "ifm_steadycam_2dspringconstant", "33.0", FCVAR_ARCHIVE );
  302. static ConVar ifm_steadycam_2ddragconstant( "ifm_steadycam_2ddragconstant", "11.0", FCVAR_ARCHIVE );
  303. void CWeaponIFMSteadyCam::ComputeViewOffset()
  304. {
  305. // Update 2D spring
  306. if ( !m_bInSpringMode )
  307. {
  308. m_vecViewOffset = m_vecActualViewOffset;
  309. return;
  310. }
  311. Vector2D dir;
  312. Vector2DSubtract( m_vecViewOffset.AsVector2D(), m_vecActualViewOffset.AsVector2D(), dir );
  313. float flDist = Vector2DNormalize( dir );
  314. Vector2D vecForce;
  315. Vector2DMultiply( dir, -flDist * ifm_steadycam_2dspringconstant.GetFloat(), vecForce );
  316. Vector2DMA( vecForce, -ifm_steadycam_2ddragconstant.GetFloat(), m_vec2DVelocity.AsVector2D(), vecForce );
  317. Vector2DMA( m_vecViewOffset.AsVector2D(), gpGlobals->frametime, m_vec2DVelocity.AsVector2D(), m_vecViewOffset.AsVector2D() );
  318. Vector2DMA( m_vec2DVelocity.AsVector2D(), gpGlobals->frametime, vecForce, m_vec2DVelocity.AsVector2D() );
  319. }
  320. //-----------------------------------------------------------------------------
  321. // Camera control
  322. //-----------------------------------------------------------------------------
  323. static ConVar ifm_steadycam_noise( "ifm_steadycam_noise", "0.0", FCVAR_ARCHIVE | FCVAR_REPLICATED );
  324. static ConVar ifm_steadycam_sensitivity( "ifm_steadycam_sensitivity", "1.0", FCVAR_ARCHIVE | FCVAR_REPLICATED );
  325. void CWeaponIFMSteadyCam::ItemPostFrame()
  326. {
  327. CBasePlayer *pPlayer = GetPlayerOwner();
  328. if ( !pPlayer )
  329. return;
  330. float flSensitivity = ifm_steadycam_sensitivity.GetFloat();
  331. Vector2D vecOldActualViewOffset = m_vecActualViewOffset.AsVector2D();
  332. if ( pPlayer->m_nButtons & IN_ATTACK )
  333. {
  334. const CUserCmd *pUserCmd = pPlayer->GetCurrentUserCommand();
  335. m_vecActualViewOffset.x += pUserCmd->mousedx * flSensitivity;
  336. m_vecActualViewOffset.y += pUserCmd->mousedy * flSensitivity;
  337. }
  338. else
  339. {
  340. if ( !m_bIsLocked && !m_bInDirectMode )
  341. {
  342. float flDamp = ifm_steadycam_rotatedamp.GetFloat();
  343. m_vecActualViewOffset.x *= flDamp;
  344. m_vecActualViewOffset.y *= flDamp;
  345. }
  346. }
  347. // Add noise
  348. if ( !m_bIsLocked )
  349. {
  350. float flNoise = ifm_steadycam_noise.GetFloat();
  351. if ( flNoise > 0.0f )
  352. {
  353. CUniformRandomStream stream;
  354. stream.SetSeed( (int)(gpGlobals->curtime * 100) );
  355. CGaussianRandomStream gauss( &stream );
  356. float dx = gauss.RandomFloat( 0.0f, flNoise );
  357. float dy = gauss.RandomFloat( 0.0f, flNoise );
  358. m_vecActualViewOffset.x += dx;
  359. m_vecActualViewOffset.y += dy;
  360. }
  361. }
  362. ComputeViewOffset();
  363. if ( pPlayer->m_nButtons & IN_ZOOM )
  364. {
  365. const CUserCmd *pUserCmd = pPlayer->GetCurrentUserCommand();
  366. m_flFOVOffsetY += pUserCmd->mousedy * flSensitivity;
  367. }
  368. else
  369. {
  370. float flDamp = ifm_steadycam_zoomdamp.GetFloat();
  371. m_flFOVOffsetY *= flDamp;
  372. }
  373. m_flFOV += m_flFOVOffsetY * ifm_steadycam_zoomspeed.GetFloat() / 1000.0f;
  374. m_flFOV = clamp( m_flFOV, 0.5f, 160.0f );
  375. if ( pPlayer->m_nButtons & IN_WALK )
  376. {
  377. const CUserCmd *pUserCmd = pPlayer->GetCurrentUserCommand();
  378. m_flArmLength -= ifm_steadycam_armspeed.GetFloat() * pUserCmd->mousedy;
  379. }
  380. if ( pPlayer->GetImpulse() == 87 )
  381. {
  382. ToggleDirectMode();
  383. }
  384. if ( pPlayer->GetImpulse() == 89 )
  385. {
  386. m_bInSpringMode = !m_bInSpringMode;
  387. }
  388. if ( pPlayer->m_afButtonPressed & IN_USE )
  389. {
  390. LockCamera();
  391. }
  392. if ( pPlayer->m_afButtonPressed & IN_ATTACK2 )
  393. {
  394. m_bFullScreen = !m_bFullScreen;
  395. }
  396. if ( pPlayer->GetImpulse() == 88 )
  397. {
  398. // Make the view angles exactly match the player
  399. m_vecViewOffset.Init();
  400. m_vecActualViewOffset.Init();
  401. m_vecOffset.Init();
  402. m_vec2DVelocity.Init();
  403. m_hLockTarget.Set( NULL );
  404. m_flArmLength = 0.0f;
  405. if ( m_bIsLocked )
  406. {
  407. LockCamera();
  408. }
  409. m_angRelativeAngles = pPlayer->EyeAngles();
  410. m_flFOV = pPlayer->GetFOV();
  411. }
  412. UpdateRelativeOrientation();
  413. TransmitRenderInfo();
  414. }
  415. //-----------------------------------------------------------------------------
  416. // Records the state for the IFM
  417. //-----------------------------------------------------------------------------
  418. void CWeaponIFMSteadyCam::GetToolRecordingState( KeyValues *msg )
  419. {
  420. BaseClass::GetToolRecordingState( msg );
  421. static CameraRecordingState_t state;
  422. state.m_flFOV = m_flFOV;
  423. ComputeAbsCameraTransform( state.m_vecEyePosition, state.m_vecEyeAngles );
  424. msg->SetPtr( "camera", &state );
  425. }
  426. //-----------------------------------------------------------------------------
  427. // Slams view angles if the mouse is down
  428. //-----------------------------------------------------------------------------
  429. void CWeaponIFMSteadyCam::CreateMove( float flInputSampleTime, CUserCmd *pCmd, const QAngle &vecOldViewAngles )
  430. {
  431. BaseClass::CreateMove( flInputSampleTime, pCmd, vecOldViewAngles );
  432. // Block angular movement when IN_ATTACK is pressed
  433. if ( pCmd->buttons & (IN_ATTACK | IN_WALK | IN_ZOOM) )
  434. {
  435. VectorCopy( vecOldViewAngles, pCmd->viewangles );
  436. }
  437. }
  438. //-----------------------------------------------------------------------------
  439. // Purpose: Draw the weapon's crosshair
  440. //-----------------------------------------------------------------------------
  441. void CWeaponIFMSteadyCam::DrawArmLength( int x, int y, int w, int h, Color clr )
  442. {
  443. // Draw a readout for the arm length
  444. if ( m_hFont == vgui::INVALID_FONT )
  445. {
  446. vgui::HScheme hScheme = vgui::scheme()->GetScheme( "ClientScheme" );
  447. vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( hScheme );
  448. m_hFont = pScheme->GetFont("DefaultVerySmall", false );
  449. Assert( m_hFont != vgui::INVALID_FONT );
  450. }
  451. // Create our string
  452. char szString[256];
  453. Q_snprintf( szString, sizeof(szString), "Arm Length: %.2f\n", m_flArmLength );
  454. // Convert it to localize friendly unicode
  455. wchar_t wcString[256];
  456. g_pVGuiLocalize->ConvertANSIToUnicode( szString, wcString, sizeof(wcString) );
  457. int tw, th;
  458. vgui::surface()->GetTextSize( m_hFont, wcString, tw, th );
  459. vgui::surface()->DrawSetTextFont( m_hFont ); // set the font
  460. vgui::surface()->DrawSetTextColor( clr ); // white
  461. vgui::surface()->DrawSetTextPos( x + w - tw - 10, y + 10 ); // x,y position
  462. vgui::surface()->DrawPrintText( wcString, wcslen(wcString) ); // print text
  463. }
  464. //-----------------------------------------------------------------------------
  465. // Purpose: Draw the FOV
  466. //-----------------------------------------------------------------------------
  467. void CWeaponIFMSteadyCam::DrawFOV( int x, int y, int w, int h, Color clrEdges, Color clrTriangle )
  468. {
  469. if ( m_nTextureId < 0 )
  470. {
  471. m_nTextureId = vgui::surface()->CreateNewTextureID();
  472. vgui::surface()->DrawSetTextureFile( m_nTextureId, "vgui/white", true, false );
  473. }
  474. // This is the fov
  475. int nSize = 30;
  476. int fx = x + w - 10 - nSize;
  477. int fy = y + h - 10;
  478. int fh = nSize * cos( M_PI * m_flFOV / 360.0f );
  479. int fw = nSize * sin( M_PI * m_flFOV / 360.0f );
  480. vgui::Vertex_t v[3];
  481. v[0].m_Position.Init( fx, fy );
  482. v[0].m_TexCoord.Init( 0.0f, 0.0f );
  483. v[1].m_Position.Init( fx-fw, fy-fh );
  484. v[1].m_TexCoord.Init( 0.0f, 0.0f );
  485. v[2].m_Position.Init( fx+fw, fy-fh );
  486. v[2].m_TexCoord.Init( 0.0f, 0.0f );
  487. vgui::surface()->DrawSetTexture( m_nTextureId );
  488. vgui::surface()->DrawSetColor( clrTriangle );
  489. vgui::surface()->DrawTexturedPolygon( 3, v );
  490. vgui::surface()->DrawSetColor( clrEdges );
  491. vgui::surface()->DrawLine( fx, fy, fx - fw, fy - fh );
  492. vgui::surface()->DrawLine( fx, fy, fx + fw, fy - fh );
  493. }
  494. //-----------------------------------------------------------------------------
  495. // Purpose: Draw the weapon's crosshair
  496. //-----------------------------------------------------------------------------
  497. void CWeaponIFMSteadyCam::DrawCrosshair( void )
  498. {
  499. BaseClass::DrawCrosshair();
  500. int x, y, w, h;
  501. GetOverlayBounds( x, y, w, h );
  502. // Draw the targeting zone around the crosshair
  503. int r, g, b, a;
  504. GetHud().m_clrYellowish.GetColor( r, g, b, a );
  505. Color gray( 255, 255, 255, 192 );
  506. Color light( r, g, b, 255 );
  507. Color dark( r, g, b, 128 );
  508. Color red( 255, 0, 0, 128 );
  509. DrawArmLength( x, y, w, h, light );
  510. DrawFOV( x, y, w, h, light, dark );
  511. int cx, cy;
  512. cx = x + ( w / 2 );
  513. cy = y + ( h / 2 );
  514. // This is the crosshair
  515. vgui::surface()->DrawSetColor( gray );
  516. vgui::surface()->DrawFilledRect( cx-10, cy-1, cx-3, cy+1 );
  517. vgui::surface()->DrawFilledRect( cx+3, cy-1, cx+10, cy+1 );
  518. vgui::surface()->DrawFilledRect( cx-1, cy-10, cx+1, cy-3 );
  519. vgui::surface()->DrawFilledRect( cx-1, cy+3, cx+1, cy+10 );
  520. // This is the yellow aiming dot
  521. if ( ( m_vecViewOffset.x != 0.0f ) || ( m_vecViewOffset.y != 0.0f ) )
  522. {
  523. int ax, ay;
  524. ax = cx + m_vecViewOffset.x;
  525. ay = cy + m_vecViewOffset.y;
  526. vgui::surface()->DrawSetColor( light );
  527. vgui::surface()->DrawFilledRect( ax-2, ay-2, ax+2, ay+2 );
  528. }
  529. // This is the red actual dot
  530. if ( ( m_vecActualViewOffset.x != 0.0f ) || ( m_vecActualViewOffset.y != 0.0f ) )
  531. {
  532. int ax, ay;
  533. ax = cx + m_vecActualViewOffset.x;
  534. ay = cy + m_vecActualViewOffset.y;
  535. vgui::surface()->DrawSetColor( red );
  536. vgui::surface()->DrawFilledRect( ax-2, ay-2, ax+2, ay+2 );
  537. }
  538. // This is the purple fov dot
  539. if ( m_flFOVOffsetY != 0.0f )
  540. {
  541. Color purple( 255, 0, 255, 255 );
  542. int vy = cy + m_flFOVOffsetY;
  543. vgui::surface()->DrawSetColor( purple );
  544. vgui::surface()->DrawFilledRect( cx-2, vy-2, cx+2, vy+2 );
  545. }
  546. }
  547. #endif // CLIENT_DLL
  548. //-----------------------------------------------------------------------------
  549. //
  550. // Specific methods on the server
  551. //
  552. //-----------------------------------------------------------------------------
  553. #ifdef GAME_DLL
  554. void CWeaponIFMSteadyCam::ItemPostFrame()
  555. {
  556. }
  557. #endif // GAME_DLL