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.

782 lines
19 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_dodbipodgun.h"
  9. #include "dod_gamerules.h"
  10. #include "engine/IEngineSound.h"
  11. #ifndef CLIENT_DLL
  12. #include "ndebugoverlay.h"
  13. #endif
  14. IMPLEMENT_NETWORKCLASS_ALIASED( DODBipodWeapon, DT_BipodWeapon )
  15. BEGIN_NETWORK_TABLE( CDODBipodWeapon, DT_BipodWeapon )
  16. #ifdef CLIENT_DLL
  17. RecvPropBool( RECVINFO( m_bDeployed ) ),
  18. RecvPropInt( RECVINFO( m_iDeployedReloadModelIndex) ),
  19. #else
  20. SendPropBool( SENDINFO( m_bDeployed ) ),
  21. SendPropModelIndex( SENDINFO(m_iDeployedReloadModelIndex) ),
  22. #endif
  23. END_NETWORK_TABLE()
  24. #ifdef CLIENT_DLL
  25. BEGIN_PREDICTION_DATA( CDODBipodWeapon )
  26. DEFINE_PRED_FIELD( m_bDeployed, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE )
  27. END_PREDICTION_DATA()
  28. #endif
  29. CDODBipodWeapon::CDODBipodWeapon()
  30. {
  31. }
  32. void CDODBipodWeapon::Spawn()
  33. {
  34. SetDeployed( false );
  35. m_flNextDeployCheckTime = 0;
  36. m_iCurrentWorldModel = 0;
  37. m_iAltFireHint = HINT_USE_DEPLOY;
  38. BaseClass::Spawn();
  39. }
  40. void CDODBipodWeapon::SetDeployed( bool bDeployed )
  41. {
  42. if ( bDeployed == false )
  43. {
  44. m_hDeployedOnEnt = NULL;
  45. m_DeployedEntOrigin = vec3_origin;
  46. m_flDeployedHeight = 0;
  47. #ifdef GAME_DLL
  48. CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
  49. if ( pPlayer )
  50. {
  51. pPlayer->HandleDeployedMGKillCount( 0 ); // reset when we undeploy
  52. }
  53. #endif
  54. }
  55. m_bDeployed = bDeployed;
  56. }
  57. void CDODBipodWeapon::Precache( void )
  58. {
  59. // precache base first, it loads weapon scripts
  60. BaseClass::Precache();
  61. const CDODWeaponInfo &info = GetDODWpnData();
  62. if( Q_strlen(info.m_szDeployedModel) > 0 )
  63. {
  64. Assert( info.m_iAltWpnCriteria & ALTWPN_CRITERIA_DEPLOYED );
  65. m_iDeployedModelIndex = CBaseEntity::PrecacheModel( info.m_szDeployedModel );
  66. }
  67. if( Q_strlen(info.m_szDeployedReloadModel) > 0 )
  68. {
  69. Assert( info.m_iAltWpnCriteria & ALTWPN_CRITERIA_DEPLOYED_RELOAD );
  70. m_iDeployedReloadModelIndex = CBaseEntity::PrecacheModel( info.m_szDeployedReloadModel );
  71. }
  72. if( Q_strlen(info.m_szProneDeployedReloadModel) > 0 )
  73. {
  74. Assert( info.m_iAltWpnCriteria & ALTWPN_CRITERIA_PRONE_DEPLOYED_RELOAD );
  75. m_iProneDeployedReloadModelIndex = CBaseEntity::PrecacheModel( info.m_szProneDeployedReloadModel );
  76. }
  77. m_iCurrentWorldModel = m_iWorldModelIndex;
  78. Assert( m_iCurrentWorldModel != 0 );
  79. }
  80. bool CDODBipodWeapon::CanDrop( void )
  81. {
  82. return ( IsDeployed() == false );
  83. }
  84. bool CDODBipodWeapon::CanHolster( void )
  85. {
  86. return ( IsDeployed() == false );
  87. }
  88. void CDODBipodWeapon::Drop( const Vector &vecVelocity )
  89. {
  90. // If a player is killed while deployed, this resets the weapon state
  91. SetDeployed( false );
  92. BaseClass::Drop( vecVelocity );
  93. }
  94. void CDODBipodWeapon::SecondaryAttack( void )
  95. {
  96. // Toggle deployed / undeployed
  97. if ( IsDeployed() )
  98. UndeployBipod();
  99. else
  100. {
  101. if ( CanAttack() )
  102. {
  103. bool bSuccess = AttemptToDeploy();
  104. CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
  105. Assert( pPlayer );
  106. if ( !bSuccess )
  107. {
  108. pPlayer->HintMessage( HINT_MG_DEPLOY_USAGE );
  109. }
  110. else
  111. {
  112. #ifndef CLIENT_DLL
  113. pPlayer->RemoveHintTimer( m_iAltFireHint );
  114. #endif
  115. }
  116. }
  117. }
  118. }
  119. bool CDODBipodWeapon::Reload( void )
  120. {
  121. bool bSuccess = BaseClass::Reload();
  122. if ( bSuccess )
  123. {
  124. m_flNextSecondaryAttack = gpGlobals->curtime;
  125. }
  126. return bSuccess;
  127. }
  128. #include "in_buttons.h"
  129. // check in busy frame too, to catch cancelling reloads
  130. void CDODBipodWeapon::ItemBusyFrame( void )
  131. {
  132. BipodThink();
  133. CBasePlayer *pPlayer = GetPlayerOwner();
  134. if ( !pPlayer )
  135. return;
  136. if ((pPlayer->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime))
  137. {
  138. SecondaryAttack();
  139. pPlayer->m_nButtons &= ~IN_ATTACK2;
  140. }
  141. BaseClass::ItemBusyFrame();
  142. }
  143. void CDODBipodWeapon::ItemPostFrame( void )
  144. {
  145. BipodThink();
  146. BaseClass::ItemPostFrame();
  147. }
  148. // see if we're still deployed on the same entity at the same height
  149. // in future can be expanded to check when deploying on other ents that may move / die / break
  150. void CDODBipodWeapon::BipodThink( void )
  151. {
  152. if ( m_flNextDeployCheckTime < gpGlobals->curtime )
  153. {
  154. if ( IsDeployed() )
  155. {
  156. if ( CheckDeployEnt() == false )
  157. {
  158. UndeployBipod();
  159. // cancel any reload in progress
  160. m_bInReload = false;
  161. m_flNextPrimaryAttack = gpGlobals->curtime + 0.1;
  162. m_flNextSecondaryAttack = gpGlobals->curtime + 0.1;
  163. }
  164. }
  165. m_flNextDeployCheckTime = gpGlobals->curtime + 0.2;
  166. }
  167. }
  168. void CDODBipodWeapon::DoFireEffects()
  169. {
  170. BaseClass::DoFireEffects();
  171. CBaseEntity *pDeployedOn = m_hDeployedOnEnt.Get();
  172. // in future can be expanded to check when deploying on other ents that may move / die / break
  173. if ( pDeployedOn && pDeployedOn->IsPlayer() && IsDeployed() )
  174. {
  175. #ifndef CLIENT_DLL
  176. CSingleUserRecipientFilter user( (CBasePlayer *)pDeployedOn );
  177. enginesound->SetPlayerDSP( user, 32, false );
  178. #endif
  179. }
  180. }
  181. // Do the work of deploying the gun at the current location and angles
  182. void CDODBipodWeapon::DeployBipod( float flHeight, CBaseEntity *pDeployedOn, float flYawLimitLeft, float flYawLimitRight )
  183. {
  184. m_flDeployedHeight = flHeight;
  185. m_hDeployedOnEnt = pDeployedOn;
  186. if ( pDeployedOn )
  187. m_DeployedEntOrigin = pDeployedOn->GetAbsOrigin();
  188. else
  189. m_DeployedEntOrigin = vec3_origin; // world ent
  190. SendWeaponAnim( GetDeployActivity() );
  191. SetDeployed( true );
  192. CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
  193. pPlayer->m_Shared.SetDeployed( true, flHeight );
  194. pPlayer->m_Shared.SetDeployedYawLimits( flYawLimitLeft, flYawLimitRight );
  195. // Save this off so we do duck checks later, even though we won't be flagged as ducking
  196. m_bDuckedWhenDeployed = pPlayer->m_Shared.IsDucking();
  197. // More TODO:
  198. // recalc our yaw limits if the item we're deployed on has moved or rotated
  199. // if our new limits are outside our current eye angles, undeploy us
  200. m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
  201. m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration();
  202. m_flTimeWeaponIdle = gpGlobals->curtime + SequenceDuration();
  203. }
  204. // Do the work of undeploying the gun
  205. void CDODBipodWeapon::UndeployBipod( void )
  206. {
  207. SendWeaponAnim( GetUndeployActivity() );
  208. SetDeployed( false );
  209. CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
  210. pPlayer->m_Shared.SetDeployed( false );
  211. // if we cancelled our reload by undeploying, don't let the reload complete
  212. if ( m_bInReload )
  213. m_bInReload = false;
  214. m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
  215. m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration();
  216. pPlayer->m_flNextAttack = m_flNextPrimaryAttack;
  217. m_flTimeWeaponIdle = gpGlobals->curtime + SequenceDuration();
  218. }
  219. #ifndef CLIENT_DLL
  220. ConVar dod_debugmgdeploy( "dod_debugmgdeploy", "0", FCVAR_CHEAT|FCVAR_GAMEDLL );
  221. #endif
  222. bool CDODBipodWeapon::AttemptToDeploy( void )
  223. {
  224. CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
  225. if ( pPlayer->GetGroundEntity() == NULL )
  226. return false;
  227. if ( pPlayer->m_Shared.IsGettingUpFromProne() || pPlayer->m_Shared.IsGoingProne() )
  228. return false;
  229. CBaseEntity *pDeployedOn = NULL;
  230. float flDeployedHeight = 0.0f;
  231. float flYawLimitLeft = 0;
  232. float flYawLimitRight = 0;
  233. if ( TestDeploy( &flDeployedHeight, &pDeployedOn, &flYawLimitLeft, &flYawLimitRight ) )
  234. {
  235. if ( pPlayer->m_Shared.IsProne() && !pPlayer->m_Shared.IsGettingUpFromProne() )
  236. {
  237. DeployBipod( flDeployedHeight, NULL, flYawLimitLeft, flYawLimitRight );
  238. return true;
  239. }
  240. else
  241. {
  242. float flMinDeployHeight = 24.0;
  243. if( flDeployedHeight >= flMinDeployHeight )
  244. {
  245. DeployBipod( flDeployedHeight, pDeployedOn, flYawLimitLeft, flYawLimitRight );
  246. return true;
  247. }
  248. }
  249. }
  250. return false;
  251. }
  252. bool CDODBipodWeapon::CheckDeployEnt( void )
  253. {
  254. CBaseEntity *pDeployedOn = NULL;
  255. float flDeployedHeight = 0.0f;
  256. if ( TestDeploy( &flDeployedHeight, &pDeployedOn ) == false )
  257. return false;
  258. // If the entity we were deployed on has changed, or has moved, the origin
  259. // of it will be different. If so, recalc our yaw limits.
  260. if ( pDeployedOn )
  261. {
  262. if ( m_DeployedEntOrigin != pDeployedOn->GetAbsOrigin() )
  263. {
  264. float flYawLimitLeft = 0, flYawLimitRight = 0;
  265. TestDeploy( &flDeployedHeight, &pDeployedOn, &flYawLimitLeft, &flYawLimitRight );
  266. CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
  267. if ( pPlayer )
  268. pPlayer->m_Shared.SetDeployedYawLimits( flYawLimitLeft, flYawLimitRight );
  269. m_DeployedEntOrigin = pDeployedOn->GetAbsOrigin();
  270. }
  271. }
  272. // 20 unit tolerance in height
  273. if ( abs( m_flDeployedHeight - flDeployedHeight ) > 20 )
  274. return false;
  275. return true;
  276. }
  277. bool CDODBipodWeapon::TestDeploy( float *flDeployedHeight, CBaseEntity **pDeployedOn, float *flYawLimitLeft /* = NULL */, float *flYawLimitRight /* = NULL */ )
  278. {
  279. CDODPlayer *pPlayer = ToDODPlayer( GetPlayerOwner() );
  280. QAngle angles = pPlayer->EyeAngles();
  281. float flPitch = angles[PITCH];
  282. if( flPitch > 180 )
  283. {
  284. flPitch -= 360;
  285. }
  286. if( flPitch > MIN_DEPLOY_PITCH || flPitch < MAX_DEPLOY_PITCH )
  287. {
  288. return false;
  289. }
  290. bool bSuccess = false;
  291. // if we're not finding the range, test at the current angles
  292. if ( flYawLimitLeft == NULL && flYawLimitRight == NULL )
  293. {
  294. // test our current angle only
  295. bSuccess = TestDeployAngle( pPlayer, flDeployedHeight, pDeployedOn, angles );
  296. }
  297. else
  298. {
  299. float flSaveYaw = angles[YAW];
  300. const float flAngleDelta = 5;
  301. const float flMaxYaw = 45;
  302. float flLeft = 0;
  303. float flRight = 0;
  304. float flTestDeployHeight = 0;
  305. CBaseEntity *pTestDeployedOn = NULL;
  306. // Sweep Left
  307. while ( flLeft <= flMaxYaw )
  308. {
  309. angles[YAW] = flSaveYaw + flLeft;
  310. if ( TestDeployAngle( pPlayer, &flTestDeployHeight, &pTestDeployedOn, angles ) == true )
  311. {
  312. if ( flLeft == 0 ) // first sweep is authoritative on deploy height and entity
  313. {
  314. *flDeployedHeight = flTestDeployHeight;
  315. *pDeployedOn = pTestDeployedOn;
  316. }
  317. else if ( abs( *flDeployedHeight - flTestDeployHeight ) > 20 )
  318. {
  319. // don't allow yaw to a position that is too different in height
  320. break;
  321. }
  322. *flYawLimitLeft = flLeft;
  323. }
  324. else
  325. {
  326. break;
  327. }
  328. flLeft += flAngleDelta;
  329. }
  330. // can't deploy here, drop out early
  331. if ( flLeft <= 0 )
  332. return false;
  333. // we already tested directly ahead and it was clear. skip one test
  334. flRight += flAngleDelta;
  335. // Sweep Right
  336. while ( flRight <= flMaxYaw )
  337. {
  338. angles[YAW] = flSaveYaw - flRight;
  339. if ( TestDeployAngle( pPlayer, &flTestDeployHeight, &pTestDeployedOn, angles ) == true )
  340. {
  341. if ( abs( *flDeployedHeight - flTestDeployHeight ) > 20 )
  342. {
  343. // don't allow yaw to a position that is too different in height
  344. break;
  345. }
  346. *flYawLimitRight = flRight;
  347. }
  348. else
  349. {
  350. break;
  351. }
  352. flRight += flAngleDelta;
  353. }
  354. bSuccess = true;
  355. }
  356. return bSuccess;
  357. }
  358. //ConVar dod_deploy_box_size( "dod_deploy_box_size", "8", FCVAR_REPLICATED );
  359. #include "util_shared.h"
  360. // trace filter that ignores all players except the passed one
  361. class CTraceFilterIgnorePlayersExceptFor : public CTraceFilterSimple
  362. {
  363. public:
  364. // It does have a base, but we'll never network anything below here..
  365. DECLARE_CLASS( CTraceFilterIgnorePlayersExceptFor, CTraceFilterSimple );
  366. CTraceFilterIgnorePlayersExceptFor( const IHandleEntity *passentity, int collisionGroup )
  367. : CTraceFilterSimple( passentity, collisionGroup )
  368. {
  369. }
  370. virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
  371. {
  372. CBaseEntity *pEntity = EntityFromEntityHandle( pServerEntity );
  373. if ( pEntity->IsPlayer() )
  374. {
  375. if ( pEntity != GetPassEntity() )
  376. {
  377. return false;
  378. }
  379. else
  380. return true;
  381. }
  382. return true;
  383. }
  384. };
  385. #define DEPLOY_DOWNTRACE_FORWARD_DIST 16
  386. #define DEPLOY_DOWNTRACE_OFFSET 16 // yay for magic numbers
  387. bool CDODBipodWeapon::TestDeployAngle( CDODPlayer *pPlayer, float *flDeployedHeight, CBaseEntity **pDeployedOn, QAngle angles )
  388. {
  389. // make sure we are deployed on the same entity at the same height
  390. trace_t tr;
  391. angles[PITCH] = 0;
  392. Vector forward, right, up;
  393. AngleVectors( angles, &forward, &right, &up );
  394. // start at top of player bbox
  395. Vector vecStart = pPlayer->GetAbsOrigin();
  396. float flForwardTraceDist = 32;
  397. // check us as ducking if we are ducked, or if were ducked when we were deployed
  398. bool bDucking = pPlayer->m_Shared.IsDucking() || ( IsDeployed() && m_bDuckedWhenDeployed );
  399. if ( pPlayer->m_Shared.IsProne() )
  400. {
  401. vecStart.z += VEC_PRONE_HULL_MAX[2];
  402. flForwardTraceDist = 16;
  403. }
  404. else if ( bDucking )
  405. {
  406. vecStart.z += VEC_DUCK_HULL_MAX[2];
  407. }
  408. else
  409. {
  410. vecStart.z += 60;
  411. }
  412. int dim = 1; // dod_deploy_box_size.GetInt();
  413. Vector vecDeployTraceBoxSize( dim, dim, dim );
  414. vecStart.z -= vecDeployTraceBoxSize[2];
  415. vecStart.z -= 4;
  416. // sandbags are around 50 units high. Shouldn't be able to deploy on anything a lot higher than that
  417. // optimal standing height ( for animation's sake ) is around 42 units
  418. // optimal ducking height is around 20 units ( 20 unit high object, plus 8 units of gun )
  419. // Start one half box width away from the edge of the player hull
  420. Vector vecForwardStart = vecStart + forward * ( VEC_HULL_MAX_SCALED( pPlayer )[0] + vecDeployTraceBoxSize[0] );
  421. int traceMask = MASK_SOLID;
  422. CBaseEntity *pDeployedOnPlayer = NULL;
  423. if ( m_hDeployedOnEnt && m_hDeployedOnEnt->IsPlayer() )
  424. {
  425. pDeployedOnPlayer = m_hDeployedOnEnt.Get();
  426. }
  427. CTraceFilterIgnorePlayersExceptFor deployedFilter( pDeployedOnPlayer, COLLISION_GROUP_NONE );
  428. CTraceFilterSimple undeployedFilter( pPlayer, COLLISION_GROUP_NONE );
  429. // if we're deployed, skip all players except for the deployed on player
  430. // if we're not, only skip ourselves
  431. ITraceFilter *filter;
  432. if ( IsDeployed() )
  433. filter = &deployedFilter;
  434. else
  435. filter = &undeployedFilter;
  436. UTIL_TraceHull( vecForwardStart,
  437. vecForwardStart + forward * ( flForwardTraceDist - 2 * vecDeployTraceBoxSize[0] ),
  438. -vecDeployTraceBoxSize,
  439. vecDeployTraceBoxSize,
  440. traceMask,
  441. filter,
  442. &tr );
  443. #ifndef CLIENT_DLL
  444. if ( dod_debugmgdeploy.GetBool() )
  445. {
  446. NDebugOverlay::Line( vecForwardStart, vecForwardStart + forward * ( flForwardTraceDist - 2 * vecDeployTraceBoxSize[0] ), 0, 0, 255, true, 0.1 );
  447. NDebugOverlay::Box( vecForwardStart, -vecDeployTraceBoxSize, vecDeployTraceBoxSize, 255, 0, 0, 128, 0.1 );
  448. NDebugOverlay::Box( tr.endpos, -vecDeployTraceBoxSize, vecDeployTraceBoxSize, 0, 0, 255, 128, 0.1 );
  449. }
  450. #endif
  451. // Test forward, are we trying to deploy into a solid object?
  452. if ( tr.fraction < 1.0 )
  453. {
  454. return false;
  455. }
  456. // If we're prone, we can always deploy, don't do the ground test
  457. if ( pPlayer->m_Shared.IsProne() && !pPlayer->m_Shared.IsGettingUpFromProne() )
  458. {
  459. // MATTTODO: do trace from *front* of player, not from the edge of crouch hull
  460. // this is sufficient
  461. *flDeployedHeight = PRONE_DEPLOY_HEIGHT;
  462. return true;
  463. }
  464. // fix prediction hitch when coming up from prone. client thinks we aren't
  465. // prone, but hull is still prone hull
  466. // assumes prone hull is shorter than duck hull!
  467. if ( pPlayer->WorldAlignMaxs().z <= VEC_PRONE_HULL_MAX.z )
  468. return false;
  469. // Else trace down
  470. Vector vecDownTraceStart = vecStart + forward * ( VEC_HULL_MAX_SCALED( pPlayer )[0] + DEPLOY_DOWNTRACE_FORWARD_DIST );
  471. int iTraceHeight = -( pPlayer->WorldAlignMaxs().z );
  472. // search down from the forward trace
  473. // use the farthest point first. If that fails, move towards the player a few times
  474. // to see if they are trying to deploy on a thin railing
  475. bool bFound = false;
  476. int maxAttempts = 4;
  477. float flHighestTraceEnd = vecDownTraceStart.z + iTraceHeight;
  478. CBaseEntity *pBestDeployEnt = NULL;
  479. while( maxAttempts > 0 )
  480. {
  481. UTIL_TraceHull( vecDownTraceStart,
  482. vecDownTraceStart + Vector(0,0,iTraceHeight), // trace forward one box width
  483. -vecDeployTraceBoxSize,
  484. vecDeployTraceBoxSize,
  485. traceMask,
  486. filter,
  487. &tr );
  488. #ifndef CLIENT_DLL
  489. if ( dod_debugmgdeploy.GetBool() )
  490. {
  491. NDebugOverlay::Line( vecDownTraceStart, tr.endpos, 255, 0, 0, true, 0.1 );
  492. NDebugOverlay::Box( vecDownTraceStart, -vecDeployTraceBoxSize, vecDeployTraceBoxSize, 255, 0, 0, 128, 0.1 );
  493. NDebugOverlay::Box( tr.endpos, -vecDeployTraceBoxSize, vecDeployTraceBoxSize, 0, 0, 255, 128, 0.1 );
  494. }
  495. #endif
  496. bool bSuccess = ( tr.fraction < 1.0 ) && !tr.startsolid && !tr.allsolid;
  497. // if this is the first one found, set found flag
  498. if ( bSuccess && !bFound )
  499. {
  500. bFound = true;
  501. }
  502. else if ( bFound == true && bSuccess == false )
  503. {
  504. // it failed and we have some data. break here
  505. break;
  506. }
  507. // if this trace is better ( higher ) use this one
  508. if ( tr.endpos.z > flHighestTraceEnd )
  509. {
  510. flHighestTraceEnd = tr.endpos.z;
  511. pBestDeployEnt = tr.m_pEnt;
  512. }
  513. --maxAttempts;
  514. // move towards the player, looking for a better height to deploy on
  515. vecDownTraceStart += forward * -4;
  516. }
  517. if ( bFound == false || pBestDeployEnt == NULL )
  518. return false;
  519. *pDeployedOn = pBestDeployEnt;
  520. *flDeployedHeight = flHighestTraceEnd - vecDeployTraceBoxSize[0] + DEPLOY_DOWNTRACE_OFFSET - pPlayer->GetAbsOrigin().z;
  521. return true;
  522. }
  523. Activity CDODBipodWeapon::GetUndeployActivity( void )
  524. {
  525. return ACT_VM_UNDEPLOY;
  526. }
  527. Activity CDODBipodWeapon::GetDeployActivity( void )
  528. {
  529. return ACT_VM_DEPLOY;
  530. }
  531. Activity CDODBipodWeapon::GetPrimaryAttackActivity( void )
  532. {
  533. Activity actPrim;
  534. if( IsDeployed() )
  535. actPrim = ACT_VM_PRIMARYATTACK_DEPLOYED;
  536. else
  537. actPrim = ACT_VM_PRIMARYATTACK;
  538. return actPrim;
  539. }
  540. Activity CDODBipodWeapon::GetReloadActivity( void )
  541. {
  542. Activity actReload;
  543. if( IsDeployed() )
  544. actReload = ACT_VM_RELOAD_DEPLOYED;
  545. else
  546. actReload = ACT_VM_RELOAD;
  547. return actReload;
  548. }
  549. Activity CDODBipodWeapon::GetIdleActivity( void )
  550. {
  551. Activity actIdle;
  552. if( IsDeployed() )
  553. actIdle = ACT_VM_IDLE_DEPLOYED;
  554. else
  555. actIdle = ACT_VM_IDLE;
  556. return actIdle;
  557. }
  558. float CDODBipodWeapon::GetWeaponAccuracy( float flPlayerSpeed )
  559. {
  560. float flSpread = BaseClass::GetWeaponAccuracy( flPlayerSpeed );
  561. if( IsDeployed() )
  562. {
  563. flSpread = m_pWeaponInfo->m_flSecondaryAccuracy;
  564. }
  565. return flSpread;
  566. }
  567. #ifdef CLIENT_DLL
  568. int CDODBipodWeapon::GetWorldModelIndex( void )
  569. {
  570. if( GetOwner() == NULL )
  571. return m_iWorldModelIndex;
  572. else if( m_bUseAltWeaponModel )
  573. return m_iWorldModelIndex; //override for hand signals etc
  574. else
  575. return m_iCurrentWorldModel;
  576. }
  577. void CDODBipodWeapon::CheckForAltWeapon( int iCurrentState )
  578. {
  579. int iCriteria = GetDODWpnData().m_iAltWpnCriteria;
  580. bool bReloading = ( iCurrentState & ALTWPN_CRITERIA_RELOADING );
  581. if( bReloading )
  582. {
  583. if( IsDeployed() && iCurrentState & ALTWPN_CRITERIA_PRONE &&
  584. iCriteria & ALTWPN_CRITERIA_PRONE_DEPLOYED_RELOAD )
  585. {
  586. m_iCurrentWorldModel = m_iProneDeployedReloadModelIndex; // prone deployed reload
  587. }
  588. else if( IsDeployed() && iCriteria & ALTWPN_CRITERIA_DEPLOYED_RELOAD )
  589. {
  590. m_iCurrentWorldModel = m_iDeployedReloadModelIndex; // deployed reload
  591. }
  592. else if( iCriteria & ALTWPN_CRITERIA_RELOADING )
  593. {
  594. m_iCurrentWorldModel = m_iReloadModelIndex; // left handed reload
  595. }
  596. else
  597. {
  598. m_iCurrentWorldModel = m_iWorldModelIndex; // normal weapon reload
  599. }
  600. }
  601. else if( IsDeployed() && iCriteria & ALTWPN_CRITERIA_DEPLOYED )
  602. {
  603. m_iCurrentWorldModel = m_iDeployedModelIndex; // bipod down
  604. }
  605. else if( (iCurrentState & iCriteria) & ALTWPN_CRITERIA_FIRING )
  606. {
  607. // don't think we have any weapons that do this
  608. m_iCurrentWorldModel = m_iReloadModelIndex; // left handed shooting?
  609. }
  610. else
  611. {
  612. m_iCurrentWorldModel = m_iWorldModelIndex; // normal weapon
  613. }
  614. }
  615. ConVar deployed_mg_sensitivity( "deployed_mg_sensitivity", "0.9", FCVAR_CHEAT, "Mouse sensitivity while deploying a machine gun" );
  616. void CDODBipodWeapon::OverrideMouseInput( float *x, float *y )
  617. {
  618. if( IsDeployed() )
  619. {
  620. float flSensitivity = deployed_mg_sensitivity.GetFloat();
  621. *x *= flSensitivity;
  622. *y *= flSensitivity;
  623. }
  624. }
  625. #endif