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.

415 lines
12 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "weapon_hl2mpbasehlmpcombatweapon.h"
  8. #include "hl2mp_player_shared.h"
  9. // memdbgon must be the last include file in a .cpp file!!!
  10. #include "tier0/memdbgon.h"
  11. LINK_ENTITY_TO_CLASS( basehl2mpcombatweapon, CBaseHL2MPCombatWeapon );
  12. IMPLEMENT_NETWORKCLASS_ALIASED( BaseHL2MPCombatWeapon , DT_BaseHL2MPCombatWeapon )
  13. BEGIN_NETWORK_TABLE( CBaseHL2MPCombatWeapon , DT_BaseHL2MPCombatWeapon )
  14. #if !defined( CLIENT_DLL )
  15. // SendPropInt( SENDINFO( m_bReflectViewModelAnimations ), 1, SPROP_UNSIGNED ),
  16. #else
  17. // RecvPropInt( RECVINFO( m_bReflectViewModelAnimations ) ),
  18. #endif
  19. END_NETWORK_TABLE()
  20. #if !defined( CLIENT_DLL )
  21. #include "globalstate.h"
  22. //---------------------------------------------------------
  23. // Save/Restore
  24. //---------------------------------------------------------
  25. BEGIN_DATADESC( CBaseHL2MPCombatWeapon )
  26. DEFINE_FIELD( m_bLowered, FIELD_BOOLEAN ),
  27. DEFINE_FIELD( m_flRaiseTime, FIELD_TIME ),
  28. DEFINE_FIELD( m_flHolsterTime, FIELD_TIME ),
  29. END_DATADESC()
  30. #endif
  31. BEGIN_PREDICTION_DATA( CBaseHL2MPCombatWeapon )
  32. END_PREDICTION_DATA()
  33. extern ConVar sk_auto_reload_time;
  34. CBaseHL2MPCombatWeapon::CBaseHL2MPCombatWeapon( void )
  35. {
  36. }
  37. //-----------------------------------------------------------------------------
  38. // Purpose:
  39. //-----------------------------------------------------------------------------
  40. void CBaseHL2MPCombatWeapon::ItemHolsterFrame( void )
  41. {
  42. BaseClass::ItemHolsterFrame();
  43. // Must be player held
  44. if ( GetOwner() && GetOwner()->IsPlayer() == false )
  45. return;
  46. // We can't be active
  47. if ( GetOwner()->GetActiveWeapon() == this )
  48. return;
  49. // If it's been longer than three seconds, reload
  50. if ( ( gpGlobals->curtime - m_flHolsterTime ) > sk_auto_reload_time.GetFloat() )
  51. {
  52. // Just load the clip with no animations
  53. FinishReload();
  54. m_flHolsterTime = gpGlobals->curtime;
  55. }
  56. }
  57. //-----------------------------------------------------------------------------
  58. // Purpose: Drops the weapon into a lowered pose
  59. // Output : Returns true on success, false on failure.
  60. //-----------------------------------------------------------------------------
  61. bool CBaseHL2MPCombatWeapon::Lower( void )
  62. {
  63. //Don't bother if we don't have the animation
  64. if ( SelectWeightedSequence( ACT_VM_IDLE_LOWERED ) == ACTIVITY_NOT_AVAILABLE )
  65. return false;
  66. m_bLowered = true;
  67. return true;
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Purpose: Brings the weapon up to the ready position
  71. // Output : Returns true on success, false on failure.
  72. //-----------------------------------------------------------------------------
  73. bool CBaseHL2MPCombatWeapon::Ready( void )
  74. {
  75. //Don't bother if we don't have the animation
  76. if ( SelectWeightedSequence( ACT_VM_LOWERED_TO_IDLE ) == ACTIVITY_NOT_AVAILABLE )
  77. return false;
  78. m_bLowered = false;
  79. m_flRaiseTime = gpGlobals->curtime + 0.5f;
  80. return true;
  81. }
  82. //-----------------------------------------------------------------------------
  83. // Purpose:
  84. // Output : Returns true on success, false on failure.
  85. //-----------------------------------------------------------------------------
  86. bool CBaseHL2MPCombatWeapon::Deploy( void )
  87. {
  88. // If we should be lowered, deploy in the lowered position
  89. // We have to ask the player if the last time it checked, the weapon was lowered
  90. if ( GetOwner() && GetOwner()->IsPlayer() )
  91. {
  92. CHL2MP_Player *pPlayer = assert_cast<CHL2MP_Player*>( GetOwner() );
  93. if ( pPlayer->IsWeaponLowered() )
  94. {
  95. if ( SelectWeightedSequence( ACT_VM_IDLE_LOWERED ) != ACTIVITY_NOT_AVAILABLE )
  96. {
  97. if ( DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), ACT_VM_IDLE_LOWERED, (char*)GetAnimPrefix() ) )
  98. {
  99. m_bLowered = true;
  100. // Stomp the next attack time to fix the fact that the lower idles are long
  101. pPlayer->SetNextAttack( gpGlobals->curtime + 1.0 );
  102. m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
  103. m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
  104. return true;
  105. }
  106. }
  107. }
  108. }
  109. m_bLowered = false;
  110. return BaseClass::Deploy();
  111. }
  112. //-----------------------------------------------------------------------------
  113. // Purpose:
  114. // Output : Returns true on success, false on failure.
  115. //-----------------------------------------------------------------------------
  116. bool CBaseHL2MPCombatWeapon::Holster( CBaseCombatWeapon *pSwitchingTo )
  117. {
  118. if ( BaseClass::Holster( pSwitchingTo ) )
  119. {
  120. SetWeaponVisible( false );
  121. m_flHolsterTime = gpGlobals->curtime;
  122. return true;
  123. }
  124. return false;
  125. }
  126. //-----------------------------------------------------------------------------
  127. // Purpose:
  128. // Output : Returns true on success, false on failure.
  129. //-----------------------------------------------------------------------------
  130. bool CBaseHL2MPCombatWeapon::WeaponShouldBeLowered( void )
  131. {
  132. // Can't be in the middle of another animation
  133. if ( GetIdealActivity() != ACT_VM_IDLE_LOWERED && GetIdealActivity() != ACT_VM_IDLE &&
  134. GetIdealActivity() != ACT_VM_IDLE_TO_LOWERED && GetIdealActivity() != ACT_VM_LOWERED_TO_IDLE )
  135. return false;
  136. if ( m_bLowered )
  137. return true;
  138. #if !defined( CLIENT_DLL )
  139. if ( GlobalEntity_GetState( "friendly_encounter" ) == GLOBAL_ON )
  140. return true;
  141. #endif
  142. return false;
  143. }
  144. //-----------------------------------------------------------------------------
  145. // Purpose: Allows the weapon to choose proper weapon idle animation
  146. //-----------------------------------------------------------------------------
  147. void CBaseHL2MPCombatWeapon::WeaponIdle( void )
  148. {
  149. //See if we should idle high or low
  150. if ( WeaponShouldBeLowered() )
  151. {
  152. // Move to lowered position if we're not there yet
  153. if ( GetActivity() != ACT_VM_IDLE_LOWERED && GetActivity() != ACT_VM_IDLE_TO_LOWERED
  154. && GetActivity() != ACT_TRANSITION )
  155. {
  156. SendWeaponAnim( ACT_VM_IDLE_LOWERED );
  157. }
  158. else if ( HasWeaponIdleTimeElapsed() )
  159. {
  160. // Keep idling low
  161. SendWeaponAnim( ACT_VM_IDLE_LOWERED );
  162. }
  163. }
  164. else
  165. {
  166. // See if we need to raise immediately
  167. if ( m_flRaiseTime < gpGlobals->curtime && GetActivity() == ACT_VM_IDLE_LOWERED )
  168. {
  169. SendWeaponAnim( ACT_VM_IDLE );
  170. }
  171. else if ( HasWeaponIdleTimeElapsed() )
  172. {
  173. SendWeaponAnim( ACT_VM_IDLE );
  174. }
  175. }
  176. }
  177. #if defined( CLIENT_DLL )
  178. #define HL2_BOB_CYCLE_MIN 1.0f
  179. #define HL2_BOB_CYCLE_MAX 0.45f
  180. #define HL2_BOB 0.002f
  181. #define HL2_BOB_UP 0.5f
  182. extern float g_lateralBob;
  183. extern float g_verticalBob;
  184. static ConVar cl_bobcycle( "cl_bobcycle","0.8" );
  185. static ConVar cl_bob( "cl_bob","0.002" );
  186. static ConVar cl_bobup( "cl_bobup","0.5" );
  187. // Register these cvars if needed for easy tweaking
  188. static ConVar v_iyaw_cycle( "v_iyaw_cycle", "2", FCVAR_REPLICATED | FCVAR_CHEAT );
  189. static ConVar v_iroll_cycle( "v_iroll_cycle", "0.5", FCVAR_REPLICATED | FCVAR_CHEAT );
  190. static ConVar v_ipitch_cycle( "v_ipitch_cycle", "1", FCVAR_REPLICATED | FCVAR_CHEAT );
  191. static ConVar v_iyaw_level( "v_iyaw_level", "0.3", FCVAR_REPLICATED | FCVAR_CHEAT );
  192. static ConVar v_iroll_level( "v_iroll_level", "0.1", FCVAR_REPLICATED | FCVAR_CHEAT );
  193. static ConVar v_ipitch_level( "v_ipitch_level", "0.3", FCVAR_REPLICATED | FCVAR_CHEAT );
  194. //-----------------------------------------------------------------------------
  195. // Purpose:
  196. // Output : float
  197. //-----------------------------------------------------------------------------
  198. float CBaseHL2MPCombatWeapon::CalcViewmodelBob( void )
  199. {
  200. static float bobtime;
  201. static float lastbobtime;
  202. float cycle;
  203. CBasePlayer *player = ToBasePlayer( GetOwner() );
  204. //Assert( player );
  205. //NOTENOTE: For now, let this cycle continue when in the air, because it snaps badly without it
  206. if ( ( !gpGlobals->frametime ) || ( player == NULL ) )
  207. {
  208. //NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!)
  209. return 0.0f;// just use old value
  210. }
  211. //Find the speed of the player
  212. float speed = player->GetLocalVelocity().Length2D();
  213. //FIXME: This maximum speed value must come from the server.
  214. // MaxSpeed() is not sufficient for dealing with sprinting - jdw
  215. speed = clamp( speed, -320, 320 );
  216. float bob_offset = RemapVal( speed, 0, 320, 0.0f, 1.0f );
  217. bobtime += ( gpGlobals->curtime - lastbobtime ) * bob_offset;
  218. lastbobtime = gpGlobals->curtime;
  219. //Calculate the vertical bob
  220. cycle = bobtime - (int)(bobtime/HL2_BOB_CYCLE_MAX)*HL2_BOB_CYCLE_MAX;
  221. cycle /= HL2_BOB_CYCLE_MAX;
  222. if ( cycle < HL2_BOB_UP )
  223. {
  224. cycle = M_PI * cycle / HL2_BOB_UP;
  225. }
  226. else
  227. {
  228. cycle = M_PI + M_PI*(cycle-HL2_BOB_UP)/(1.0 - HL2_BOB_UP);
  229. }
  230. g_verticalBob = speed*0.005f;
  231. g_verticalBob = g_verticalBob*0.3 + g_verticalBob*0.7*sin(cycle);
  232. g_verticalBob = clamp( g_verticalBob, -7.0f, 4.0f );
  233. //Calculate the lateral bob
  234. cycle = bobtime - (int)(bobtime/HL2_BOB_CYCLE_MAX*2)*HL2_BOB_CYCLE_MAX*2;
  235. cycle /= HL2_BOB_CYCLE_MAX*2;
  236. if ( cycle < HL2_BOB_UP )
  237. {
  238. cycle = M_PI * cycle / HL2_BOB_UP;
  239. }
  240. else
  241. {
  242. cycle = M_PI + M_PI*(cycle-HL2_BOB_UP)/(1.0 - HL2_BOB_UP);
  243. }
  244. g_lateralBob = speed*0.005f;
  245. g_lateralBob = g_lateralBob*0.3 + g_lateralBob*0.7*sin(cycle);
  246. g_lateralBob = clamp( g_lateralBob, -7.0f, 4.0f );
  247. //NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!)
  248. return 0.0f;
  249. }
  250. //-----------------------------------------------------------------------------
  251. // Purpose:
  252. // Input : &origin -
  253. // &angles -
  254. // viewmodelindex -
  255. //-----------------------------------------------------------------------------
  256. void CBaseHL2MPCombatWeapon::AddViewmodelBob( CBaseViewModel *viewmodel, Vector &origin, QAngle &angles )
  257. {
  258. Vector forward, right;
  259. AngleVectors( angles, &forward, &right, NULL );
  260. CalcViewmodelBob();
  261. // Apply bob, but scaled down to 40%
  262. VectorMA( origin, g_verticalBob * 0.1f, forward, origin );
  263. // Z bob a bit more
  264. origin[2] += g_verticalBob * 0.1f;
  265. // bob the angles
  266. angles[ ROLL ] += g_verticalBob * 0.5f;
  267. angles[ PITCH ] -= g_verticalBob * 0.4f;
  268. angles[ YAW ] -= g_lateralBob * 0.3f;
  269. VectorMA( origin, g_lateralBob * 0.8f, right, origin );
  270. }
  271. //-----------------------------------------------------------------------------
  272. Vector CBaseHL2MPCombatWeapon::GetBulletSpread( WeaponProficiency_t proficiency )
  273. {
  274. return BaseClass::GetBulletSpread( proficiency );
  275. }
  276. //-----------------------------------------------------------------------------
  277. float CBaseHL2MPCombatWeapon::GetSpreadBias( WeaponProficiency_t proficiency )
  278. {
  279. return BaseClass::GetSpreadBias( proficiency );
  280. }
  281. //-----------------------------------------------------------------------------
  282. const WeaponProficiencyInfo_t *CBaseHL2MPCombatWeapon::GetProficiencyValues()
  283. {
  284. return NULL;
  285. }
  286. #else
  287. // Server stubs
  288. float CBaseHL2MPCombatWeapon::CalcViewmodelBob( void )
  289. {
  290. return 0.0f;
  291. }
  292. //-----------------------------------------------------------------------------
  293. // Purpose:
  294. // Input : &origin -
  295. // &angles -
  296. // viewmodelindex -
  297. //-----------------------------------------------------------------------------
  298. void CBaseHL2MPCombatWeapon::AddViewmodelBob( CBaseViewModel *viewmodel, Vector &origin, QAngle &angles )
  299. {
  300. }
  301. //-----------------------------------------------------------------------------
  302. Vector CBaseHL2MPCombatWeapon::GetBulletSpread( WeaponProficiency_t proficiency )
  303. {
  304. Vector baseSpread = BaseClass::GetBulletSpread( proficiency );
  305. const WeaponProficiencyInfo_t *pProficiencyValues = GetProficiencyValues();
  306. float flModifier = (pProficiencyValues)[ proficiency ].spreadscale;
  307. return ( baseSpread * flModifier );
  308. }
  309. //-----------------------------------------------------------------------------
  310. float CBaseHL2MPCombatWeapon::GetSpreadBias( WeaponProficiency_t proficiency )
  311. {
  312. const WeaponProficiencyInfo_t *pProficiencyValues = GetProficiencyValues();
  313. return (pProficiencyValues)[ proficiency ].bias;
  314. }
  315. //-----------------------------------------------------------------------------
  316. const WeaponProficiencyInfo_t *CBaseHL2MPCombatWeapon::GetProficiencyValues()
  317. {
  318. return GetDefaultProficiencyValues();
  319. }
  320. //-----------------------------------------------------------------------------
  321. const WeaponProficiencyInfo_t *CBaseHL2MPCombatWeapon::GetDefaultProficiencyValues()
  322. {
  323. // Weapon proficiency table. Keep this in sync with WeaponProficiency_t enum in the header!!
  324. static WeaponProficiencyInfo_t g_BaseWeaponProficiencyTable[] =
  325. {
  326. { 2.50, 1.0 },
  327. { 2.00, 1.0 },
  328. { 1.50, 1.0 },
  329. { 1.25, 1.0 },
  330. { 1.00, 1.0 },
  331. };
  332. COMPILE_TIME_ASSERT( ARRAYSIZE(g_BaseWeaponProficiencyTable) == WEAPON_PROFICIENCY_PERFECT + 1);
  333. return g_BaseWeaponProficiencyTable;
  334. }
  335. #endif