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.

697 lines
23 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Class to control 'aim-down-sights' aka "IronSight" weapon functionality
  4. //
  5. //=====================================================================================//
  6. #include "cbase.h"
  7. #include "cs_shareddefs.h"
  8. #ifdef IRONSIGHT
  9. #include "weapon_csbase.h"
  10. #include "weapon_ironsightcontroller.h"
  11. #if defined( CLIENT_DLL )
  12. #include "c_cs_player.h"
  13. #include "view_scene.h"
  14. #include "shaderapi/ishaderapi.h"
  15. #include "materialsystem/imaterialvar.h"
  16. #include "prediction.h"
  17. #else
  18. #include "cs_player.h"
  19. #endif
  20. // NOTE: This has to be the last file included!
  21. #include "tier0/memdbgon.h"
  22. #define IRONSIGHT_VIEWMODEL_BOB_MULT_X 0.05
  23. #define IRONSIGHT_VIEWMODEL_BOB_PERIOD_X 6
  24. #define IRONSIGHT_VIEWMODEL_BOB_MULT_Y 0.1
  25. #define IRONSIGHT_VIEWMODEL_BOB_PERIOD_Y 10
  26. #ifdef DEBUG
  27. ConVar ironsight_override( "ironsight_override", "0", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT );
  28. ConVar ironsight_position( "ironsight_position", "0 0 0", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT );
  29. ConVar ironsight_angle( "ironsight_angle", "0 0 0", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT );
  30. ConVar ironsight_fov( "ironsight_fov", "60", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT );
  31. ConVar ironsight_pivot_forward( "ironsight_pivot_forward", "0", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT );
  32. ConVar ironsight_looseness( "ironsight_looseness", "0.1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT );
  33. ConVar ironsight_speed_bringup( "ironsight_speed_bringup", "4.0", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT );
  34. ConVar ironsight_speed_putdown( "ironsight_speed_putdown", "2.0", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT );
  35. ConVar ironsight_catchupspeed( "ironsight_catchupspeed", "60.0", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT );
  36. ConVar ironsight_running_looseness( "ironsight_running_looseness", "0.3", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT );
  37. ConVar ironsight_spew_amount( "ironsight_spew_amount", "0", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT );
  38. #else
  39. #define ironsight_catchupspeed 60.0f
  40. #endif
  41. CIronSightController::CIronSightController( void )
  42. {
  43. m_bIronSightAvailable = false;
  44. m_angPivotAngle.Init();
  45. m_vecEyePos.Init();
  46. m_flIronSightAmount = 0.0f;
  47. m_flIronSightPullUpSpeed = 8.0f;
  48. m_flIronSightPutDownSpeed = 4.0f;
  49. m_flIronSightFOV = 80.0f;
  50. m_flIronSightPivotForward = 10.0f;
  51. m_flIronSightLooseness = 0.5f;
  52. m_pAttachedWeapon = NULL;
  53. #ifdef CLIENT_DLL
  54. m_angViewLast.Init();
  55. for ( int i=0; i<IRONSIGHT_ANGLE_AVERAGE_SIZE; i++ )
  56. {
  57. m_angDeltaAverage[i].Init();
  58. }
  59. m_vecDotCoords.Init();
  60. m_flDotBlur = 0.0f;
  61. m_flSpeedRatio = 0.0f;
  62. #endif
  63. }
  64. void CIronSightController::SetState( CSIronSightMode newState )
  65. {
  66. if ( newState == IronSight_viewmodel_is_deploying || newState == IronSight_weapon_is_dropped )
  67. {
  68. m_flIronSightAmount = 0.0f;
  69. }
  70. if ( m_pAttachedWeapon )
  71. {
  72. m_pAttachedWeapon->m_iIronSightMode = newState;
  73. }
  74. }
  75. bool CIronSightController::IsApproachingSighted(void)
  76. {
  77. return (m_pAttachedWeapon && m_pAttachedWeapon->m_iIronSightMode == IronSight_should_approach_sighted);
  78. }
  79. bool CIronSightController::IsApproachingUnSighted(void)
  80. {
  81. return (m_pAttachedWeapon && m_pAttachedWeapon->m_iIronSightMode == IronSight_should_approach_unsighted);
  82. }
  83. bool CIronSightController::IsDeploying(void)
  84. {
  85. return (m_pAttachedWeapon && m_pAttachedWeapon->m_iIronSightMode == IronSight_viewmodel_is_deploying);
  86. }
  87. bool CIronSightController::IsDropped(void)
  88. {
  89. return (m_pAttachedWeapon && m_pAttachedWeapon->m_iIronSightMode == IronSight_weapon_is_dropped);
  90. }
  91. void CIronSightController::UpdateIronSightAmount( void )
  92. {
  93. if (!m_pAttachedWeapon || IsDeploying() || IsDropped())
  94. {
  95. //ignore and discard any lingering ironsight amount.
  96. m_flIronSightAmount = 0.0f;
  97. m_flIronSightAmountGained = 0.0f;
  98. return;
  99. }
  100. //first determine if we are going into or out of ironsights, and set m_flIronSightAmount accordingly
  101. float flIronSightAmountTarget = IsApproachingSighted() ? 1.0f : 0.0f;
  102. float flIronSightUpdOrDownSpeed = IsApproachingSighted() ? m_flIronSightPullUpSpeed : m_flIronSightPutDownSpeed;
  103. #ifdef DEBUG
  104. if (ironsight_override.GetBool())
  105. flIronSightUpdOrDownSpeed = IsApproachingSighted() ? ironsight_speed_bringup.GetFloat() : ironsight_speed_putdown.GetFloat();
  106. #endif
  107. m_flIronSightAmount = Approach(flIronSightAmountTarget, m_flIronSightAmount, gpGlobals->frametime * flIronSightUpdOrDownSpeed);
  108. m_flIronSightAmountGained = Gain( m_flIronSightAmount, 0.8f );
  109. m_flIronSightAmountBiased = Bias( m_flIronSightAmount, 0.2f );
  110. #ifdef DEBUG
  111. if ( ironsight_spew_amount.GetBool() )
  112. DevMsg( "Ironsight amount: %f, Gained: %f, Biased: %f\n", m_flIronSightAmount, m_flIronSightAmountGained, m_flIronSightAmountBiased );
  113. #endif
  114. }
  115. #ifdef CLIENT_DLL
  116. void CIronSightController::IncreaseDotBlur(float flAmount)
  117. {
  118. if ( IsInIronSight() && prediction->IsFirstTimePredicted() )
  119. m_flDotBlur = clamp(m_flDotBlur + flAmount, 0, 1);
  120. }
  121. float CIronSightController::GetDotBlur(void)
  122. {
  123. return Bias(1.0f - Max(m_flDotBlur, m_flSpeedRatio * 0.5f), 0.2f);
  124. }
  125. float CIronSightController::GetDotWidth(void)
  126. {
  127. return (32 + (256 * Max(m_flDotBlur, m_flSpeedRatio * 0.3f)));
  128. }
  129. Vector2D CIronSightController::GetDotCoords(void)
  130. {
  131. return m_vecDotCoords;
  132. }
  133. bool CIronSightController::ShouldHideCrossHair( void )
  134. {
  135. return ( (IsApproachingSighted() || IsApproachingUnSighted()) && GetIronSightAmount() > IRONSIGHT_HIDE_CROSSHAIR_THRESHOLD );
  136. }
  137. const char *CIronSightController::GetDotMaterial( void )
  138. {
  139. //TODO: convert to schema attribute
  140. if ( m_pAttachedWeapon && m_pAttachedWeapon->GetCSWeaponID() == WEAPON_SG556 )
  141. return "models/weapons/shared/scope/scope_dot_red";
  142. return "models/weapons/shared/scope/scope_dot_green";
  143. }
  144. QAngle CIronSightController::QAngleDiff( QAngle &angTarget, QAngle &angSrc )
  145. {
  146. return QAngle( AngleDiff( angTarget.x, angSrc.x ),
  147. AngleDiff( angTarget.y, angSrc.y ),
  148. AngleDiff( angTarget.z, angSrc.z ) );
  149. }
  150. QAngle CIronSightController::GetAngleAverage( void )
  151. {
  152. QAngle temp;
  153. temp.Init();
  154. if (GetIronSightAmount() < 1.0f)
  155. return temp;
  156. for ( int i=0; i<IRONSIGHT_ANGLE_AVERAGE_SIZE; i++ )
  157. {
  158. temp += m_angDeltaAverage[i];
  159. }
  160. return ( temp * IRONSIGHT_ANGLE_AVERAGE_DIVIDE );
  161. }
  162. void CIronSightController::AddToAngleAverage( QAngle newAngle )
  163. {
  164. if (GetIronSightAmount() < 1.0f)
  165. return;
  166. newAngle.x = clamp( newAngle.x, -2, 2 );
  167. newAngle.y = clamp( newAngle.y, -2, 2 );
  168. newAngle.z = clamp( newAngle.z, -2, 2 );
  169. for ( int i=IRONSIGHT_ANGLE_AVERAGE_SIZE-1; i>0; i-- )
  170. {
  171. m_angDeltaAverage[i] = m_angDeltaAverage[i-1];
  172. }
  173. m_angDeltaAverage[0] = newAngle;
  174. }
  175. extern ConVar cl_righthand;
  176. void CIronSightController::ApplyIronSightPositioning( Vector &vecPosition, QAngle &angAngle, const Vector &vecBobbedEyePosition, const QAngle &angBobbedEyeAngle )
  177. {
  178. UpdateIronSightAmount();
  179. if ( m_flIronSightAmount == 0 )
  180. return;
  181. //check if the player is moving and save off a usable movement speed ratio for later
  182. if ( m_pAttachedWeapon->GetOwner() )
  183. {
  184. CBaseCombatCharacter *pPlayer = m_pAttachedWeapon->GetOwner();
  185. m_flSpeedRatio = Approach( pPlayer->GetAbsVelocity().Length() / m_pAttachedWeapon->GetMaxSpeed(), m_flSpeedRatio, gpGlobals->frametime * 10.0f );
  186. }
  187. //if we're more than 10% ironsighted, apply looseness.
  188. if ( m_flIronSightAmount > 0.1f )
  189. {
  190. //get the difference between current angles and last angles
  191. QAngle angDelta = QAngleDiff( m_angViewLast, angAngle );
  192. //dampen the delta to simulate 'looseness', but the faster we move, the more looseness approaches ironsight_running_looseness.GetFloat(), which is as waggly as possible
  193. #ifdef DEBUG
  194. if ( ironsight_override.GetBool() )
  195. {
  196. AddToAngleAverage( angDelta * Lerp(m_flSpeedRatio, ironsight_looseness.GetFloat(), ironsight_running_looseness.GetFloat()) );
  197. }
  198. else
  199. #endif
  200. {
  201. AddToAngleAverage( angDelta * Lerp(m_flSpeedRatio, m_flIronSightLooseness, 0.3f ) );
  202. }
  203. //m_angViewLast tries to catch up to angAngle
  204. #ifdef DEBUG
  205. m_angViewLast -= angDelta * clamp( gpGlobals->frametime * ironsight_catchupspeed.GetFloat(), 0, 1 );
  206. #else
  207. m_angViewLast -= angDelta * clamp( gpGlobals->frametime * ironsight_catchupspeed, 0, 1 );
  208. #endif
  209. }
  210. else
  211. {
  212. m_angViewLast = angAngle;
  213. }
  214. //now the fun part - move the viewmodel to look down the sights
  215. //create a working matrix at the current eye position and angles
  216. VMatrix matIronSightMatrix = SetupMatrixOrgAngles( vecPosition, angAngle );
  217. //offset the matrix by the ironsight eye position
  218. #ifdef DEBUG
  219. if ( ironsight_override.GetBool() )
  220. {
  221. Vector vecTemp; //when overridden use convar values instead of schema driven ones so we can iterate on the values quickly while authoring
  222. if ( sscanf( ironsight_position.GetString(), "%f %f %f", &vecTemp.x, &vecTemp.y, &vecTemp.z ) == 3 )
  223. MatrixTranslate( matIronSightMatrix, (-vecTemp) * GetIronSightAmountGained() );
  224. }
  225. else
  226. #endif
  227. {
  228. //use schema defined offset
  229. MatrixTranslate( matIronSightMatrix, (-m_vecEyePos) * GetIronSightAmountGained() );
  230. }
  231. //additionally offset by the ironsight origin of rotation, the weapon will pivot around this offset from the eye
  232. #ifdef DEBUG
  233. if ( ironsight_override.GetBool() )
  234. {
  235. MatrixTranslate( matIronSightMatrix, Vector( ironsight_pivot_forward.GetFloat(), 0, 0 ) );
  236. }
  237. else
  238. #endif
  239. {
  240. MatrixTranslate( matIronSightMatrix, Vector( m_flIronSightPivotForward, 0, 0 ) );
  241. }
  242. QAngle angDeltaAverage = GetAngleAverage();
  243. if ( !cl_righthand.GetBool() )
  244. angDeltaAverage = -angDeltaAverage;
  245. //apply ironsight eye rotation
  246. #ifdef DEBUG
  247. if ( ironsight_override.GetBool() )
  248. {
  249. QAngle angTemp; //when overridden use convar values instead of schema driven ones so we can iterate on the values quickly while authoring
  250. if ( sscanf( ironsight_angle.GetString(), "%f %f %f", &angTemp.x, &angTemp.y, &angTemp.z ) == 3 )
  251. {
  252. MatrixRotate( matIronSightMatrix, Vector( 1, 0, 0 ), (angDeltaAverage.z + angTemp.z) * GetIronSightAmountGained() );
  253. MatrixRotate( matIronSightMatrix, Vector( 0, 1, 0 ), (angDeltaAverage.x + angTemp.x) * GetIronSightAmountGained() );
  254. MatrixRotate( matIronSightMatrix, Vector( 0, 0, 1 ), (angDeltaAverage.y + angTemp.y) * GetIronSightAmountGained() );
  255. }
  256. }
  257. else
  258. #endif
  259. {
  260. //use schema defined angles
  261. MatrixRotate( matIronSightMatrix, Vector( 1, 0, 0 ), (angDeltaAverage.z + m_angPivotAngle.z) * GetIronSightAmountGained() );
  262. MatrixRotate( matIronSightMatrix, Vector( 0, 1, 0 ), (angDeltaAverage.x + m_angPivotAngle.x) * GetIronSightAmountGained() );
  263. MatrixRotate( matIronSightMatrix, Vector( 0, 0, 1 ), (angDeltaAverage.y + m_angPivotAngle.y) * GetIronSightAmountGained() );
  264. }
  265. if ( !cl_righthand.GetBool() )
  266. angDeltaAverage = -angDeltaAverage;
  267. //move the weapon back to the ironsight eye position
  268. #ifdef DEBUG
  269. if ( ironsight_override.GetBool() )
  270. {
  271. MatrixTranslate( matIronSightMatrix, Vector( -ironsight_pivot_forward.GetFloat(), 0, 0 ) );
  272. }
  273. else
  274. #endif
  275. {
  276. MatrixTranslate( matIronSightMatrix, Vector( -m_flIronSightPivotForward, 0, 0 ) );
  277. }
  278. //if the player is moving, pull down and re-bob the weapon
  279. if ( m_pAttachedWeapon->GetOwner() )
  280. {
  281. //magic bob value, replace me
  282. Vector vecIronSightBob = Vector(
  283. 1,
  284. IRONSIGHT_VIEWMODEL_BOB_MULT_X * sin( gpGlobals->curtime * IRONSIGHT_VIEWMODEL_BOB_PERIOD_X ),
  285. IRONSIGHT_VIEWMODEL_BOB_MULT_Y * sin( gpGlobals->curtime * IRONSIGHT_VIEWMODEL_BOB_PERIOD_Y ) - IRONSIGHT_VIEWMODEL_BOB_MULT_Y
  286. );
  287. m_vecDotCoords.x = -vecIronSightBob.y;
  288. m_vecDotCoords.y = -vecIronSightBob.z;
  289. m_vecDotCoords *= 0.1f;
  290. m_vecDotCoords.x -= angDeltaAverage.y * 0.03f;
  291. m_vecDotCoords.y += angDeltaAverage.x * 0.03f;
  292. m_vecDotCoords *= m_flSpeedRatio;
  293. if ( !cl_righthand.GetBool() )
  294. vecIronSightBob.y = -vecIronSightBob.y;
  295. MatrixTranslate( matIronSightMatrix, vecIronSightBob * m_flSpeedRatio );
  296. }
  297. //extract the final position and angles and apply them as differences from the passed in values
  298. vecPosition -= ( vecPosition - matIronSightMatrix.GetTranslation() );
  299. QAngle angIronSightAngles;
  300. MatrixAngles( matIronSightMatrix.As3x4(), angIronSightAngles );
  301. angAngle -= QAngleDiff( angAngle, angIronSightAngles );
  302. //dampen dot blur
  303. m_flDotBlur = Approach(0.0f, m_flDotBlur, gpGlobals->frametime * 2.0f);
  304. }
  305. static void SetRenderTargetAndViewPort(ITexture *rt)
  306. {
  307. CMatRenderContextPtr pRenderContext(materials);
  308. pRenderContext->SetRenderTarget(rt);
  309. if (rt)
  310. {
  311. pRenderContext->Viewport(0, 0, rt->GetActualWidth(), rt->GetActualHeight());
  312. }
  313. }
  314. #ifdef DEBUG
  315. ConVar r_ironsight_scope_effect("r_ironsight_scope_effect", "1", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT);
  316. ConVar ironsight_laser_dot_render_tweak1("ironsight_laser_dot_render_tweak1", "61", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT);
  317. ConVar ironsight_laser_dot_render_tweak2("ironsight_laser_dot_render_tweak2", "64", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT);
  318. #endif
  319. bool CIronSightController::PrepareScopeEffect( int x, int y, int w, int h, CViewSetup *pViewSetup )
  320. {
  321. #ifdef DEBUG
  322. if (!r_ironsight_scope_effect.GetBool())
  323. return false;
  324. #endif
  325. if (!IsInIronSight())
  326. return false;
  327. Rect_t actualRect;
  328. UpdateScreenEffectTexture(0, x, y, w, h, false, &actualRect);
  329. ITexture *pRtFullFrame = GetFullFrameFrameBufferTexture(0);
  330. CMatRenderContextPtr pRenderContext(materials);
  331. pRenderContext->PushRenderTargetAndViewport();
  332. // DOWNSAMPLE _rt_FullFrameFB TO _rt_SmallFB0
  333. IMaterial *pMatDownsample = materials->FindMaterial("dev/scope_downsample", TEXTURE_GROUP_OTHER, true);
  334. ITexture *pRtQuarterSize0 = materials->FindTexture("_rt_SmallFB0", TEXTURE_GROUP_RENDER_TARGET);
  335. SetRenderTargetAndViewPort(pRtQuarterSize0);
  336. int nSrcWidth = pViewSetup->width;
  337. int nSrcHeight = pViewSetup->height;
  338. pRenderContext->DrawScreenSpaceRectangle(pMatDownsample, 0, 0, nSrcWidth / 4, nSrcHeight / 4,
  339. 0, 0, nSrcWidth - 4, nSrcHeight - 4,
  340. pRtFullFrame->GetActualWidth(), pRtFullFrame->GetActualHeight());
  341. //horizontally blur pRtQuarterSize0 over to pRtQuarterSize1
  342. IMaterial *pMatBlurX = materials->FindMaterial("dev/scope_blur_x", TEXTURE_GROUP_OTHER, true);
  343. ITexture *pRtQuarterSize1 = materials->FindTexture("_rt_SmallFB1", TEXTURE_GROUP_RENDER_TARGET);
  344. SetRenderTargetAndViewPort(pRtQuarterSize1);
  345. pRenderContext->DrawScreenSpaceRectangle(pMatBlurX, 0, 0, nSrcWidth / 4, nSrcHeight / 4,
  346. 0, 0, nSrcWidth / 4 - 1, nSrcHeight / 4 - 1,
  347. pRtQuarterSize0->GetActualWidth(), pRtQuarterSize0->GetActualHeight());
  348. //vertically blur pRtQuarterSize1 over to pRtQuarterSize0
  349. IMaterial *pMatBlurY = materials->FindMaterial("dev/scope_blur_y", TEXTURE_GROUP_OTHER, true);
  350. SetRenderTargetAndViewPort(pRtQuarterSize0);
  351. pRenderContext->DrawScreenSpaceRectangle(pMatBlurY, 0, 0, nSrcWidth / 4, nSrcHeight / 4,
  352. 0, 0, nSrcWidth / 4 - 1, nSrcHeight / 4 - 1,
  353. pRtQuarterSize0->GetActualWidth(), pRtQuarterSize0->GetActualHeight());
  354. pRenderContext->PopRenderTargetAndViewport();
  355. //Prepare to render the scope lens mask shape into the stencil buffer.
  356. //The weapon itself will take care of using the correct blend mode and override material.
  357. ShaderStencilState_t stencilState;
  358. stencilState.m_bEnable = true;
  359. stencilState.m_nReferenceValue = 1;
  360. stencilState.m_CompareFunc = SHADER_STENCILFUNC_ALWAYS;
  361. stencilState.m_PassOp = SHADER_STENCILOP_SET_TO_REFERENCE;
  362. stencilState.m_FailOp = SHADER_STENCILOP_KEEP;
  363. stencilState.m_ZFailOp = SHADER_STENCILOP_KEEP;
  364. pRenderContext->SetStencilState(stencilState);
  365. return true;
  366. }
  367. void CIronSightController::RenderScopeEffect( int x, int y, int w, int h, CViewSetup *pViewSetup )
  368. {
  369. #ifdef DEBUG
  370. if ( !r_ironsight_scope_effect.GetBool() )
  371. return;
  372. #endif
  373. if ( !IsInIronSight() )
  374. return;
  375. // apply the blur effect to the screen while masking out the scope lens
  376. CMatRenderContextPtr pRenderContext(materials);
  377. ShaderStencilState_t stencilState_skip_scope_lens_pixels;
  378. stencilState_skip_scope_lens_pixels.m_bEnable = true;
  379. stencilState_skip_scope_lens_pixels.m_nReferenceValue = 1;
  380. stencilState_skip_scope_lens_pixels.m_CompareFunc = SHADER_STENCILFUNC_NOTEQUAL;
  381. stencilState_skip_scope_lens_pixels.m_PassOp = SHADER_STENCILOP_KEEP;
  382. stencilState_skip_scope_lens_pixels.m_FailOp = SHADER_STENCILOP_KEEP;
  383. stencilState_skip_scope_lens_pixels.m_ZFailOp = SHADER_STENCILOP_KEEP;
  384. pRenderContext->SetStencilState(stencilState_skip_scope_lens_pixels);
  385. // RENDER _rt_SmallFB0 to screen
  386. IMaterial *pBlurOverlayMaterial = materials->FindMaterial("dev/scope_bluroverlay", TEXTURE_GROUP_OTHER, true);
  387. //set alpha to the amount of ironsightedness
  388. IMaterialVar *pAlphaVar = pBlurOverlayMaterial->FindVar("$alpha", 0);
  389. if (pAlphaVar != NULL)
  390. {
  391. pAlphaVar->SetFloatValue(Bias( GetIronSightAmount(), 0.2f));
  392. }
  393. pRenderContext->DrawScreenSpaceQuad(pBlurOverlayMaterial);
  394. // now draw the laser dot, masked to ONLY render on the lens
  395. Vector2D dotCoords = GetDotCoords();
  396. dotCoords.x *= engine->GetScreenAspectRatio(w, h);
  397. //CMatRenderContextPtr pRenderContext(materials);
  398. IMaterial *pMatDot = materials->FindMaterial(GetDotMaterial(), TEXTURE_GROUP_OTHER, true);
  399. pRenderContext->OverrideDepthEnable(true, false, false);
  400. ShaderStencilState_t stencilState_use_only_scope_lens_pixels;
  401. stencilState_use_only_scope_lens_pixels.m_bEnable = true;
  402. stencilState_use_only_scope_lens_pixels.m_nReferenceValue = 1;
  403. stencilState_use_only_scope_lens_pixels.m_CompareFunc = SHADER_STENCILFUNC_EQUAL;
  404. stencilState_use_only_scope_lens_pixels.m_PassOp = SHADER_STENCILOP_KEEP;
  405. stencilState_use_only_scope_lens_pixels.m_FailOp = SHADER_STENCILOP_KEEP;
  406. stencilState_use_only_scope_lens_pixels.m_ZFailOp = SHADER_STENCILOP_KEEP;
  407. pRenderContext->SetStencilState(stencilState_use_only_scope_lens_pixels);
  408. int iWidth = GetDotWidth();
  409. IMaterialVar *pAlphaVar2 = pMatDot->FindVar("$alpha", 0);
  410. if (pAlphaVar2 != NULL)
  411. {
  412. pAlphaVar2->SetFloatValue(GetDotBlur());
  413. }
  414. dotCoords.x += 0.5f;
  415. dotCoords.y += 0.5f;
  416. #ifdef DEBUG
  417. pRenderContext->DrawScreenSpaceRectangle(pMatDot, (w * dotCoords.x) - (iWidth / 2), (h * dotCoords.y) - (iWidth / 2), iWidth, iWidth,
  418. 0, 0, ironsight_laser_dot_render_tweak1.GetInt(), ironsight_laser_dot_render_tweak1.GetInt(),
  419. ironsight_laser_dot_render_tweak2.GetInt(), ironsight_laser_dot_render_tweak2.GetInt());
  420. #else
  421. pRenderContext->DrawScreenSpaceRectangle(pMatDot, (w * dotCoords.x) - (iWidth / 2), (h * dotCoords.y) - (iWidth / 2), iWidth, iWidth,
  422. 0, 0, 61, 61,
  423. 64, 64);
  424. #endif
  425. pRenderContext->OverrideDepthEnable(false, true);
  426. // restore a disabled stencil state
  427. ShaderStencilState_t stencilStateDisable;
  428. stencilStateDisable.m_bEnable = false;
  429. pRenderContext->SetStencilState(stencilStateDisable);
  430. //clean up stencil buffer once we're done so render elements like the glow pass draw correctly
  431. pRenderContext->ClearBuffers(false, false, true);
  432. }
  433. #endif //CLIENT_DLL
  434. bool CIronSightController::IsInIronSight( void )
  435. {
  436. if ( m_pAttachedWeapon )
  437. {
  438. if ( IsDeploying() ||
  439. IsDropped() ||
  440. m_pAttachedWeapon->m_bInReload ||
  441. m_pAttachedWeapon->IsSwitchingSilencer() )
  442. return false;
  443. CCSPlayer *pPlayer = ToCSPlayer( m_pAttachedWeapon->GetOwner() );
  444. if ( pPlayer && pPlayer->IsLookingAtWeapon() )
  445. return false;
  446. #if defined ( CLIENT_DLL )
  447. C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
  448. if ( pLocalPlayer && pLocalPlayer->GetObserverTarget() == pPlayer && pLocalPlayer->GetObserverInterpState() == C_CSPlayer::OBSERVER_INTERP_TRAVELING )
  449. return false;
  450. #endif
  451. if ( GetIronSightAmount() > 0 && (IsApproachingSighted() || IsApproachingUnSighted()) )
  452. return true;
  453. }
  454. return false;
  455. }
  456. float CIronSightController::GetIronSightFOV( float flDefaultFOV, bool bUseBiasedValue /*= false*/ )
  457. {
  458. //sets biased value between the current FOV and the ideal IronSight FOV based on how 'ironsighted' the weapon currently is
  459. if ( !IsInIronSight() )
  460. return flDefaultFOV;
  461. float flIronSightFOVAmount = bUseBiasedValue ? GetIronSightAmountBiased() : GetIronSightAmount();
  462. #ifdef DEBUG
  463. if ( ironsight_override.GetBool() )
  464. {
  465. return Lerp( flIronSightFOVAmount, flDefaultFOV, ironsight_fov.GetFloat() );
  466. }
  467. #endif
  468. return Lerp( flIronSightFOVAmount, flDefaultFOV, GetIronSightIdealFOV() );
  469. }
  470. bool CIronSightController::Init( CWeaponCSBase *pWeaponToMonitor )
  471. {
  472. if ( IsInitializedAndAvailable() )
  473. {
  474. return true;
  475. }
  476. else if( pWeaponToMonitor )
  477. {
  478. // currently only the following hardcoded weapon types support ironsights:
  479. if (pWeaponToMonitor->GetCSWeaponID() != WEAPON_AUG &&
  480. pWeaponToMonitor->GetCSWeaponID() != WEAPON_SG556)
  481. {
  482. return false;
  483. }
  484. if ( pWeaponToMonitor->GetCSWeaponID() == WEAPON_AUG )
  485. {
  486. m_pAttachedWeapon = pWeaponToMonitor;
  487. m_bIronSightAvailable = true;
  488. m_flIronSightLooseness = 0.03f;
  489. m_flIronSightPullUpSpeed = 10.0f;
  490. m_flIronSightPutDownSpeed = 8.0f;
  491. m_flIronSightFOV = 45.0f;
  492. m_flIronSightPivotForward = 10.0f;
  493. m_vecEyePos = Vector( -1.56, -3.6, -0.07 );
  494. m_angPivotAngle = QAngle( 0.78, -0.1, -0.03 );
  495. return true;
  496. }
  497. else if (pWeaponToMonitor->GetCSWeaponID() == WEAPON_SG556)
  498. {
  499. m_pAttachedWeapon = pWeaponToMonitor;
  500. m_bIronSightAvailable = true;
  501. m_flIronSightLooseness = 0.03f;
  502. m_flIronSightPullUpSpeed = 10.0f;
  503. m_flIronSightPutDownSpeed = 8.0f;
  504. m_flIronSightFOV = 45.0f;
  505. m_flIronSightPivotForward = 8.0f;
  506. m_vecEyePos = Vector(0.72, -5.12, -1.33);
  507. m_angPivotAngle = QAngle(0.52, 0.04, 0.72);
  508. return true;
  509. }
  510. CEconItemView *pEconItem = ( (CWeaponCSBase *)pWeaponToMonitor )->GetEconItemView();
  511. if ( pEconItem && pEconItem->IsValid() )
  512. {
  513. m_pAttachedWeapon = pWeaponToMonitor;
  514. float flTemp;
  515. uint32 unTemp;
  516. static CSchemaAttributeDefHandle pAttrbIronSightCapable("aimsight capable");
  517. if (pEconItem->FindAttribute(pAttrbIronSightCapable, &unTemp))
  518. {
  519. m_bIronSightAvailable = (unTemp != 0);
  520. if (m_bIronSightAvailable)
  521. {
  522. static CSchemaAttributeDefHandle pAttrflIronSightLooseness("aimsight looseness");
  523. FindAttribute_UnsafeBitwiseCast<attrib_value_t>(pEconItem, pAttrflIronSightLooseness, &flTemp);
  524. m_flIronSightLooseness = flTemp;
  525. static CSchemaAttributeDefHandle pAttrflIronSightPullUpSpeed("aimsight speed up");
  526. FindAttribute_UnsafeBitwiseCast<attrib_value_t>(pEconItem, pAttrflIronSightPullUpSpeed, &flTemp);
  527. m_flIronSightPullUpSpeed = flTemp;
  528. static CSchemaAttributeDefHandle pAttrflIronSightPutDownSpeed("aimsight speed down");
  529. FindAttribute_UnsafeBitwiseCast<attrib_value_t>(pEconItem, pAttrflIronSightPutDownSpeed, &flTemp);
  530. m_flIronSightPutDownSpeed = flTemp;
  531. static CSchemaAttributeDefHandle pAttrflIronSightFOV("aimsight fov");
  532. FindAttribute_UnsafeBitwiseCast<attrib_value_t>(pEconItem, pAttrflIronSightFOV, &flTemp);
  533. m_flIronSightFOV = flTemp;
  534. static CSchemaAttributeDefHandle pAttrflIronSightPivotForward("aimsight pivot forward");
  535. FindAttribute_UnsafeBitwiseCast<attrib_value_t>(pEconItem, pAttrflIronSightPivotForward, &flTemp);
  536. m_flIronSightPivotForward = flTemp;
  537. static CSchemaAttributeDefHandle pAttrDef_IronSightEyePos("aimsight eye pos");
  538. pEconItem->FindAttribute(pAttrDef_IronSightEyePos, &m_vecEyePos);
  539. static CSchemaAttributeDefHandle pAttrDef_IronSightPivotAngle("aimsight pivot angle");
  540. Vector temp;
  541. pEconItem->FindAttribute(pAttrDef_IronSightPivotAngle, &temp);
  542. m_angPivotAngle.x = temp.x;
  543. m_angPivotAngle.y = temp.y;
  544. m_angPivotAngle.z = temp.z;
  545. return true;
  546. }
  547. }
  548. }
  549. }
  550. return false;
  551. }
  552. #endif //IRONSIGHT