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.

509 lines
15 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "weapon_portalbasecombatweapon.h"
  8. #include "in_buttons.h"
  9. #include "portal_player_shared.h"
  10. #if defined( CLIENT_DLL )
  11. #include "c_portal_player.h"
  12. #else
  13. #include "vphysics/constraints.h"
  14. #include "gameweaponmanager.h"
  15. #endif
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include "tier0/memdbgon.h"
  18. IMPLEMENT_NETWORKCLASS_ALIASED( BasePortalCombatWeapon , DT_BasePortalCombatWeapon )
  19. LINK_ENTITY_TO_CLASS_ALIASED( baseportalcombatweapon, BasePortalCombatWeapon );
  20. BEGIN_NETWORK_TABLE( CBasePortalCombatWeapon , DT_BasePortalCombatWeapon )
  21. #if !defined( CLIENT_DLL )
  22. // SendPropInt( SENDINFO( m_bReflectViewModelAnimations ), 1, SPROP_UNSIGNED ),
  23. #else
  24. // RecvPropInt( RECVINFO( m_bReflectViewModelAnimations ) ),
  25. #endif
  26. END_NETWORK_TABLE()
  27. #if !defined( CLIENT_DLL )
  28. #include "globalstate.h"
  29. //---------------------------------------------------------
  30. // Save/Restore
  31. //---------------------------------------------------------
  32. BEGIN_DATADESC( CBasePortalCombatWeapon )
  33. DEFINE_FIELD( m_bLowered, FIELD_BOOLEAN ),
  34. DEFINE_FIELD( m_flRaiseTime, FIELD_TIME ),
  35. DEFINE_FIELD( m_flHolsterTime, FIELD_TIME ),
  36. DEFINE_FIELD( m_flNextRepeatPrimaryAttack, FIELD_TIME ),
  37. DEFINE_FIELD( m_flNextRepeatSecondaryAttack, FIELD_TIME ),
  38. END_DATADESC()
  39. #else
  40. BEGIN_PREDICTION_DATA( CBasePortalCombatWeapon )
  41. DEFINE_FIELD( m_flNextRepeatPrimaryAttack, FIELD_TIME ),
  42. DEFINE_FIELD( m_flNextRepeatSecondaryAttack, FIELD_TIME ),
  43. END_PREDICTION_DATA()
  44. #endif
  45. extern ConVar sk_auto_reload_time;
  46. CBasePortalCombatWeapon::CBasePortalCombatWeapon( void )
  47. {
  48. }
  49. //-----------------------------------------------------------------------------
  50. // Purpose:
  51. //-----------------------------------------------------------------------------
  52. void CBasePortalCombatWeapon::ItemHolsterFrame( void )
  53. {
  54. BaseClass::ItemHolsterFrame();
  55. // Must be player held
  56. if ( GetOwner() && GetOwner()->IsPlayer() == false )
  57. return;
  58. // We can't be active
  59. if ( GetOwner()->GetActiveWeapon() == this )
  60. return;
  61. // If it's been longer than three seconds, reload
  62. if ( ( gpGlobals->curtime - m_flHolsterTime ) > sk_auto_reload_time.GetFloat() )
  63. {
  64. // Just load the clip with no animations
  65. FinishReload();
  66. m_flHolsterTime = gpGlobals->curtime;
  67. }
  68. }
  69. bool CBasePortalCombatWeapon::CanLower()
  70. {
  71. if ( SelectWeightedSequence( ACT_VM_IDLE_LOWERED ) == ACTIVITY_NOT_AVAILABLE )
  72. return false;
  73. return true;
  74. }
  75. //-----------------------------------------------------------------------------
  76. // Purpose: Drops the weapon into a lowered pose
  77. // Output : Returns true on success, false on failure.
  78. //-----------------------------------------------------------------------------
  79. bool CBasePortalCombatWeapon::Lower( void )
  80. {
  81. //Don't bother if we don't have the animation
  82. if ( SelectWeightedSequence( ACT_VM_IDLE_LOWERED ) == ACTIVITY_NOT_AVAILABLE )
  83. return false;
  84. m_bLowered = true;
  85. return true;
  86. }
  87. //-----------------------------------------------------------------------------
  88. // Purpose: Brings the weapon up to the ready position
  89. // Output : Returns true on success, false on failure.
  90. //-----------------------------------------------------------------------------
  91. bool CBasePortalCombatWeapon::Ready( void )
  92. {
  93. //Don't bother if we don't have the animation
  94. if ( SelectWeightedSequence( ACT_VM_LOWERED_TO_IDLE ) == ACTIVITY_NOT_AVAILABLE )
  95. return false;
  96. m_bLowered = false;
  97. m_flRaiseTime = gpGlobals->curtime + 0.5f;
  98. return true;
  99. }
  100. //-----------------------------------------------------------------------------
  101. // Purpose:
  102. // Output : Returns true on success, false on failure.
  103. //-----------------------------------------------------------------------------
  104. bool CBasePortalCombatWeapon::Deploy( void )
  105. {
  106. return BaseClass::Deploy();
  107. }
  108. //-----------------------------------------------------------------------------
  109. // Purpose:
  110. // Output : Returns true on success, false on failure.
  111. //-----------------------------------------------------------------------------
  112. bool CBasePortalCombatWeapon::Holster( CBaseCombatWeapon *pSwitchingTo )
  113. {
  114. if ( BaseClass::Holster( pSwitchingTo ) )
  115. {
  116. m_flHolsterTime = gpGlobals->curtime;
  117. return true;
  118. }
  119. return false;
  120. }
  121. //-----------------------------------------------------------------------------
  122. // Purpose:
  123. // Output : Returns true on success, false on failure.
  124. //-----------------------------------------------------------------------------
  125. bool CBasePortalCombatWeapon::WeaponShouldBeLowered( void )
  126. {
  127. // Can't be in the middle of another animation
  128. if ( GetIdealActivity() != ACT_VM_IDLE_LOWERED && GetIdealActivity() != ACT_VM_IDLE &&
  129. GetIdealActivity() != ACT_VM_IDLE_TO_LOWERED && GetIdealActivity() != ACT_VM_LOWERED_TO_IDLE )
  130. return false;
  131. if ( m_bLowered )
  132. return true;
  133. #if !defined( CLIENT_DLL )
  134. if ( GlobalEntity_GetState( "friendly_encounter" ) == GLOBAL_ON )
  135. return true;
  136. #endif
  137. return false;
  138. }
  139. //-----------------------------------------------------------------------------
  140. // Purpose: Allows the weapon to choose proper weapon idle animation
  141. //-----------------------------------------------------------------------------
  142. void CBasePortalCombatWeapon::WeaponIdle( void )
  143. {
  144. }
  145. #if defined( CLIENT_DLL )
  146. extern float g_lateralBob;
  147. extern float g_verticalBob;
  148. #define HL2_BOB_CYCLE_MIN 1.0f
  149. #define HL2_BOB_CYCLE_MAX 0.45f
  150. #define HL2_BOB 0.002f
  151. #define HL2_BOB_UP 0.5f
  152. #if !defined( PORTAL2 )
  153. static ConVar cl_bobcycle( "cl_bobcycle","0.8" );
  154. static ConVar cl_bob( "cl_bob","0.002" );
  155. static ConVar cl_bobup( "cl_bobup","0.5" );
  156. // Register these cvars if needed for easy tweaking
  157. static ConVar v_iyaw_cycle( "v_iyaw_cycle", "2", FCVAR_CHEAT );
  158. static ConVar v_iroll_cycle( "v_iroll_cycle", "0.5", FCVAR_CHEAT );
  159. static ConVar v_ipitch_cycle( "v_ipitch_cycle", "1", FCVAR_CHEAT );
  160. static ConVar v_iyaw_level( "v_iyaw_level", "0.3", FCVAR_CHEAT );
  161. static ConVar v_iroll_level( "v_iroll_level", "0.1", FCVAR_CHEAT );
  162. static ConVar v_ipitch_level( "v_ipitch_level", "0.3", FCVAR_CHEAT );
  163. #endif
  164. //-----------------------------------------------------------------------------
  165. // Purpose:
  166. // Output : float
  167. //-----------------------------------------------------------------------------
  168. float CBasePortalCombatWeapon::CalcViewmodelBob( void )
  169. {
  170. static float bobtime;
  171. static float lastbobtime;
  172. float cycle;
  173. CBasePlayer *player = ToBasePlayer( GetOwner() );
  174. //Assert( player );
  175. //NOTENOTE: For now, let this cycle continue when in the air, because it snaps badly without it
  176. if ( ( !gpGlobals->frametime ) || ( player == NULL ) )
  177. {
  178. //NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!)
  179. return 0.0f;// just use old value
  180. }
  181. // Note: we use paint code for this so when player move on speed paint, gun bob faster (Bank)
  182. //Find the speed of the player
  183. float speed = player->GetLocalVelocity().Length();
  184. speed = clamp( speed, -player->MaxSpeed(), player->MaxSpeed() );
  185. float bob_offset = RemapVal( speed, 0, player->MaxSpeed(), 0.0f, 1.0f );
  186. ////Find the speed of the player
  187. //float speed = player->GetLocalVelocity().Length2D();
  188. ////FIXME: This maximum speed value must come from the server.
  189. //// MaxSpeed() is not sufficient for dealing with sprinting - jdw
  190. //speed = clamp( speed, -320, 320 );
  191. //float bob_offset = RemapVal( speed, 0, 320, 0.0f, 1.0f );
  192. bobtime += ( gpGlobals->curtime - lastbobtime ) * bob_offset;
  193. lastbobtime = gpGlobals->curtime;
  194. //Calculate the vertical bob
  195. cycle = bobtime - (int)(bobtime/HL2_BOB_CYCLE_MAX)*HL2_BOB_CYCLE_MAX;
  196. cycle /= HL2_BOB_CYCLE_MAX;
  197. if ( cycle < HL2_BOB_UP )
  198. {
  199. cycle = M_PI * cycle / HL2_BOB_UP;
  200. }
  201. else
  202. {
  203. cycle = M_PI + M_PI*(cycle-HL2_BOB_UP)/(1.0 - HL2_BOB_UP);
  204. }
  205. g_verticalBob = speed*0.005f;
  206. g_verticalBob = g_verticalBob*0.3 + g_verticalBob*0.7*sin(cycle);
  207. g_verticalBob = clamp( g_verticalBob, -7.0f, 4.0f );
  208. //Calculate the lateral bob
  209. cycle = bobtime - (int)(bobtime/HL2_BOB_CYCLE_MAX*2)*HL2_BOB_CYCLE_MAX*2;
  210. cycle /= HL2_BOB_CYCLE_MAX*2;
  211. if ( cycle < HL2_BOB_UP )
  212. {
  213. cycle = M_PI * cycle / HL2_BOB_UP;
  214. }
  215. else
  216. {
  217. cycle = M_PI + M_PI*(cycle-HL2_BOB_UP)/(1.0 - HL2_BOB_UP);
  218. }
  219. g_lateralBob = speed*0.005f;
  220. g_lateralBob = g_lateralBob*0.3 + g_lateralBob*0.7*sin(cycle);
  221. g_lateralBob = clamp( g_lateralBob, -7.0f, 4.0f );
  222. //NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!)
  223. return 0.0f;
  224. }
  225. //-----------------------------------------------------------------------------
  226. // Purpose:
  227. // Input : &origin -
  228. // &angles -
  229. // viewmodelindex -
  230. //-----------------------------------------------------------------------------
  231. void CBasePortalCombatWeapon::AddViewmodelBob( CBaseViewModel *viewmodel, Vector &origin, QAngle &angles )
  232. {
  233. Vector forward, right, up;
  234. AngleVectors( angles, &forward, &right, &up );
  235. CalcViewmodelBob();
  236. // Note: we need to use paint code for gun bob so the gun bobs correctly when player sticks on walls (Bank)
  237. C_Portal_Player *pPortalPlayer = ToPortalPlayer( GetOwner() );
  238. if ( !pPortalPlayer )
  239. return;
  240. // Apply bob, but scaled down to 40%
  241. VectorMA( origin, g_verticalBob * 0.1f, forward, origin );
  242. // Z bob a bit more
  243. origin += g_verticalBob * 0.1f * pPortalPlayer->GetPortalPlayerLocalData().m_Up;
  244. //move left and right
  245. VectorMA( origin, g_lateralBob * 0.8f, right, origin );
  246. //roll, pitch, yaw
  247. float rollAngle = g_verticalBob * 0.5f;
  248. VMatrix rotMatrix;
  249. Vector rotAxis = CrossProduct( right, up ).Normalized();
  250. MatrixBuildRotationAboutAxis( rotMatrix, rotAxis, rollAngle );
  251. up = rotMatrix * up;
  252. forward = rotMatrix * forward;
  253. right = rotMatrix * right;
  254. float pitchAngle = -g_verticalBob * 0.4f;
  255. rotAxis = right;
  256. MatrixBuildRotationAboutAxis( rotMatrix, rotAxis, pitchAngle );
  257. up = rotMatrix * up;
  258. forward = rotMatrix * forward;
  259. float yawAngle = -g_lateralBob * 0.3f;
  260. rotAxis = up;
  261. MatrixBuildRotationAboutAxis( rotMatrix, rotAxis, yawAngle );
  262. forward = rotMatrix * forward;
  263. VectorAngles( forward, up, angles );
  264. //// Apply bob, but scaled down to 40%
  265. //VectorMA( origin, g_verticalBob * 0.1f, forward, origin );
  266. //
  267. //// Z bob a bit more
  268. //origin[2] += g_verticalBob * 0.1f;
  269. //
  270. //// bob the angles
  271. //angles[ ROLL ] += g_verticalBob * 0.5f;
  272. //angles[ PITCH ] -= g_verticalBob * 0.4f;
  273. //angles[ YAW ] -= g_lateralBob * 0.3f;
  274. //VectorMA( origin, g_lateralBob * 0.8f, right, origin );
  275. }
  276. //-----------------------------------------------------------------------------
  277. Vector CBasePortalCombatWeapon::GetBulletSpread( WeaponProficiency_t proficiency )
  278. {
  279. return BaseClass::GetBulletSpread( proficiency );
  280. }
  281. //-----------------------------------------------------------------------------
  282. float CBasePortalCombatWeapon::GetSpreadBias( WeaponProficiency_t proficiency )
  283. {
  284. return BaseClass::GetSpreadBias( proficiency );
  285. }
  286. //-----------------------------------------------------------------------------
  287. const WeaponProficiencyInfo_t *CBasePortalCombatWeapon::GetProficiencyValues()
  288. {
  289. return NULL;
  290. }
  291. #else
  292. // Server stubs
  293. float CBasePortalCombatWeapon::CalcViewmodelBob( void )
  294. {
  295. return 0.0f;
  296. }
  297. //-----------------------------------------------------------------------------
  298. // Purpose:
  299. // Input : &origin -
  300. // &angles -
  301. // viewmodelindex -
  302. //-----------------------------------------------------------------------------
  303. void CBasePortalCombatWeapon::AddViewmodelBob( CBaseViewModel *viewmodel, Vector &origin, QAngle &angles )
  304. {
  305. }
  306. //-----------------------------------------------------------------------------
  307. Vector CBasePortalCombatWeapon::GetBulletSpread( WeaponProficiency_t proficiency )
  308. {
  309. Vector baseSpread = BaseClass::GetBulletSpread( proficiency );
  310. const WeaponProficiencyInfo_t *pProficiencyValues = GetProficiencyValues();
  311. float flModifier = (pProficiencyValues)[ proficiency ].spreadscale;
  312. return ( baseSpread * flModifier );
  313. }
  314. //-----------------------------------------------------------------------------
  315. float CBasePortalCombatWeapon::GetSpreadBias( WeaponProficiency_t proficiency )
  316. {
  317. const WeaponProficiencyInfo_t *pProficiencyValues = GetProficiencyValues();
  318. return (pProficiencyValues)[ proficiency ].bias;
  319. }
  320. //-----------------------------------------------------------------------------
  321. const WeaponProficiencyInfo_t *CBasePortalCombatWeapon::GetProficiencyValues()
  322. {
  323. return GetDefaultProficiencyValues();
  324. }
  325. //-----------------------------------------------------------------------------
  326. const WeaponProficiencyInfo_t *CBasePortalCombatWeapon::GetDefaultProficiencyValues()
  327. {
  328. // Weapon proficiency table. Keep this in sync with WeaponProficiency_t enum in the header!!
  329. static WeaponProficiencyInfo_t g_BaseWeaponProficiencyTable[] =
  330. {
  331. { 2.50, 1.0 },
  332. { 2.00, 1.0 },
  333. { 1.50, 1.0 },
  334. { 1.25, 1.0 },
  335. { 1.00, 1.0 },
  336. };
  337. COMPILE_TIME_ASSERT( ARRAYSIZE(g_BaseWeaponProficiencyTable) == WEAPON_PROFICIENCY_PERFECT + 1);
  338. return g_BaseWeaponProficiencyTable;
  339. }
  340. #endif
  341. //-----------------------------------------------------------------------------
  342. // Purpose: Handle firing
  343. //-----------------------------------------------------------------------------
  344. void CBasePortalCombatWeapon::ItemPostFrame( void )
  345. {
  346. CPortal_Player *pOwner = ToPortalPlayer( GetOwner() );
  347. if ( pOwner == NULL )
  348. return;
  349. // Primary attack
  350. if ( pOwner->m_nButtons & IN_ATTACK && ( m_flNextPrimaryAttack <= gpGlobals->curtime ) )
  351. {
  352. if ( pOwner->GetWaterLevel() == 3 && m_bFiresUnderwater == false )
  353. {
  354. // This weapon doesn't fire underwater
  355. WeaponSound(EMPTY);
  356. m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->curtime + 0.2;
  357. return;
  358. }
  359. // If they're still holding down the button, wait for the next fire time
  360. if ( ( pOwner->m_afButtonLast & IN_ATTACK ) && ( m_flNextRepeatPrimaryAttack > gpGlobals->curtime ) )
  361. return;
  362. PrimaryAttack();
  363. return;
  364. }
  365. // Secondary attack
  366. if ( pOwner->m_nButtons & IN_ATTACK2 && ( m_flNextSecondaryAttack <= gpGlobals->curtime ) )
  367. {
  368. if ( pOwner->GetWaterLevel() == 3 )
  369. {
  370. // This weapon doesn't fire underwater
  371. WeaponSound( EMPTY );
  372. m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->curtime + 0.2;
  373. return;
  374. }
  375. // If they're still holding down the button, wait for the next fire time
  376. if ( ( pOwner->m_afButtonLast & IN_ATTACK2 ) && ( m_flNextRepeatSecondaryAttack > gpGlobals->curtime ) )
  377. return;
  378. // Attack!
  379. SecondaryAttack();
  380. return;
  381. }
  382. WeaponIdle();
  383. }
  384. ConVar sv_weapon_pickup_time_delay("sv_weapon_pickup_time_delay", "0.2f", FCVAR_REPLICATED | FCVAR_CHEAT);
  385. bool CBasePortalCombatWeapon::EnoughTimeSinceThrown()
  386. {
  387. return gpGlobals->curtime - m_flThrowTime > sv_weapon_pickup_time_delay.GetFloat();
  388. }
  389. float CBasePortalCombatWeapon::GetThrowTime()
  390. {
  391. return m_flThrowTime;
  392. }
  393. void CBasePortalCombatWeapon::Drop( const Vector& vecVelocity )
  394. {
  395. // Store time when we threw the gun so we dont go and pick up the gun too soon
  396. m_flThrowTime = gpGlobals->curtime;
  397. m_pLastOwner = GetOwner();
  398. BaseClass::Drop( vecVelocity );
  399. }
  400. CBaseEntity* CBasePortalCombatWeapon::GetLastOwner()
  401. {
  402. return m_pLastOwner;
  403. }