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.

421 lines
12 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "weapon_portalbasecombatweapon.h"
  8. #include "portal_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( baseportalcombatweapon, CBasePortalCombatWeapon );
  12. IMPLEMENT_NETWORKCLASS_ALIASED( BasePortalCombatWeapon , DT_BasePortalCombatWeapon )
  13. BEGIN_NETWORK_TABLE( CBasePortalCombatWeapon , DT_BasePortalCombatWeapon )
  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( CBasePortalCombatWeapon )
  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( CBasePortalCombatWeapon )
  32. END_PREDICTION_DATA()
  33. extern ConVar sk_auto_reload_time;
  34. CBasePortalCombatWeapon::CBasePortalCombatWeapon( void )
  35. {
  36. }
  37. //-----------------------------------------------------------------------------
  38. // Purpose:
  39. //-----------------------------------------------------------------------------
  40. void CBasePortalCombatWeapon::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. bool CBasePortalCombatWeapon::CanLower()
  58. {
  59. if ( SelectWeightedSequence( ACT_VM_IDLE_LOWERED ) == ACTIVITY_NOT_AVAILABLE )
  60. return false;
  61. return true;
  62. }
  63. //-----------------------------------------------------------------------------
  64. // Purpose: Drops the weapon into a lowered pose
  65. // Output : Returns true on success, false on failure.
  66. //-----------------------------------------------------------------------------
  67. bool CBasePortalCombatWeapon::Lower( void )
  68. {
  69. //Don't bother if we don't have the animation
  70. if ( SelectWeightedSequence( ACT_VM_IDLE_LOWERED ) == ACTIVITY_NOT_AVAILABLE )
  71. return false;
  72. m_bLowered = true;
  73. return true;
  74. }
  75. //-----------------------------------------------------------------------------
  76. // Purpose: Brings the weapon up to the ready position
  77. // Output : Returns true on success, false on failure.
  78. //-----------------------------------------------------------------------------
  79. bool CBasePortalCombatWeapon::Ready( void )
  80. {
  81. //Don't bother if we don't have the animation
  82. if ( SelectWeightedSequence( ACT_VM_LOWERED_TO_IDLE ) == ACTIVITY_NOT_AVAILABLE )
  83. return false;
  84. m_bLowered = false;
  85. m_flRaiseTime = gpGlobals->curtime + 0.5f;
  86. return true;
  87. }
  88. //-----------------------------------------------------------------------------
  89. // Purpose:
  90. // Output : Returns true on success, false on failure.
  91. //-----------------------------------------------------------------------------
  92. bool CBasePortalCombatWeapon::Deploy( void )
  93. {
  94. // If we should be lowered, deploy in the lowered position
  95. // We have to ask the player if the last time it checked, the weapon was lowered
  96. if ( GetOwner() && GetOwner()->IsPlayer() )
  97. {
  98. CPortal_Player *pPlayer = assert_cast<CPortal_Player*>( GetOwner() );
  99. if ( pPlayer->IsWeaponLowered() )
  100. {
  101. if ( SelectWeightedSequence( ACT_VM_IDLE_LOWERED ) != ACTIVITY_NOT_AVAILABLE )
  102. {
  103. if ( DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), ACT_VM_IDLE_LOWERED, (char*)GetAnimPrefix() ) )
  104. {
  105. m_bLowered = true;
  106. // Stomp the next attack time to fix the fact that the lower idles are long
  107. pPlayer->SetNextAttack( gpGlobals->curtime + 1.0 );
  108. m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
  109. m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
  110. return true;
  111. }
  112. }
  113. }
  114. }
  115. m_bLowered = false;
  116. return BaseClass::Deploy();
  117. }
  118. //-----------------------------------------------------------------------------
  119. // Purpose:
  120. // Output : Returns true on success, false on failure.
  121. //-----------------------------------------------------------------------------
  122. bool CBasePortalCombatWeapon::Holster( CBaseCombatWeapon *pSwitchingTo )
  123. {
  124. if ( BaseClass::Holster( pSwitchingTo ) )
  125. {
  126. m_flHolsterTime = gpGlobals->curtime;
  127. return true;
  128. }
  129. return false;
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Purpose:
  133. // Output : Returns true on success, false on failure.
  134. //-----------------------------------------------------------------------------
  135. bool CBasePortalCombatWeapon::WeaponShouldBeLowered( void )
  136. {
  137. // Can't be in the middle of another animation
  138. if ( GetIdealActivity() != ACT_VM_IDLE_LOWERED && GetIdealActivity() != ACT_VM_IDLE &&
  139. GetIdealActivity() != ACT_VM_IDLE_TO_LOWERED && GetIdealActivity() != ACT_VM_LOWERED_TO_IDLE )
  140. return false;
  141. if ( m_bLowered )
  142. return true;
  143. #if !defined( CLIENT_DLL )
  144. if ( GlobalEntity_GetState( "friendly_encounter" ) == GLOBAL_ON )
  145. return true;
  146. #endif
  147. return false;
  148. }
  149. //-----------------------------------------------------------------------------
  150. // Purpose: Allows the weapon to choose proper weapon idle animation
  151. //-----------------------------------------------------------------------------
  152. void CBasePortalCombatWeapon::WeaponIdle( void )
  153. {
  154. //See if we should idle high or low
  155. if ( WeaponShouldBeLowered() )
  156. {
  157. // Move to lowered position if we're not there yet
  158. if ( GetActivity() != ACT_VM_IDLE_LOWERED && GetActivity() != ACT_VM_IDLE_TO_LOWERED
  159. && GetActivity() != ACT_TRANSITION )
  160. {
  161. SendWeaponAnim( ACT_VM_IDLE_LOWERED );
  162. }
  163. else if ( HasWeaponIdleTimeElapsed() )
  164. {
  165. // Keep idling low
  166. SendWeaponAnim( ACT_VM_IDLE_LOWERED );
  167. }
  168. }
  169. else
  170. {
  171. // See if we need to raise immediately
  172. if ( m_flRaiseTime < gpGlobals->curtime && GetActivity() == ACT_VM_IDLE_LOWERED )
  173. {
  174. SendWeaponAnim( ACT_VM_IDLE );
  175. }
  176. else if ( HasWeaponIdleTimeElapsed() )
  177. {
  178. SendWeaponAnim( ACT_VM_IDLE );
  179. }
  180. }
  181. }
  182. #if defined( CLIENT_DLL )
  183. #define HL2_BOB_CYCLE_MIN 1.0f
  184. #define HL2_BOB_CYCLE_MAX 0.45f
  185. #define HL2_BOB 0.002f
  186. #define HL2_BOB_UP 0.5f
  187. extern float g_lateralBob;
  188. extern float g_verticalBob;
  189. static ConVar cl_bobcycle( "cl_bobcycle","0.8" );
  190. static ConVar cl_bob( "cl_bob","0.002" );
  191. static ConVar cl_bobup( "cl_bobup","0.5" );
  192. // Register these cvars if needed for easy tweaking
  193. static ConVar v_iyaw_cycle( "v_iyaw_cycle", "2", FCVAR_REPLICATED | FCVAR_CHEAT );
  194. static ConVar v_iroll_cycle( "v_iroll_cycle", "0.5", FCVAR_REPLICATED | FCVAR_CHEAT );
  195. static ConVar v_ipitch_cycle( "v_ipitch_cycle", "1", FCVAR_REPLICATED | FCVAR_CHEAT );
  196. static ConVar v_iyaw_level( "v_iyaw_level", "0.3", FCVAR_REPLICATED | FCVAR_CHEAT );
  197. static ConVar v_iroll_level( "v_iroll_level", "0.1", FCVAR_REPLICATED | FCVAR_CHEAT );
  198. static ConVar v_ipitch_level( "v_ipitch_level", "0.3", FCVAR_REPLICATED | FCVAR_CHEAT );
  199. //-----------------------------------------------------------------------------
  200. // Purpose:
  201. // Output : float
  202. //-----------------------------------------------------------------------------
  203. float CBasePortalCombatWeapon::CalcViewmodelBob( void )
  204. {
  205. static float bobtime;
  206. static float lastbobtime;
  207. float cycle;
  208. CBasePlayer *player = ToBasePlayer( GetOwner() );
  209. //Assert( player );
  210. //NOTENOTE: For now, let this cycle continue when in the air, because it snaps badly without it
  211. if ( ( !gpGlobals->frametime ) || ( player == NULL ) )
  212. {
  213. //NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!)
  214. return 0.0f;// just use old value
  215. }
  216. //Find the speed of the player
  217. float speed = player->GetLocalVelocity().Length2D();
  218. //FIXME: This maximum speed value must come from the server.
  219. // MaxSpeed() is not sufficient for dealing with sprinting - jdw
  220. speed = clamp( speed, -320, 320 );
  221. float bob_offset = RemapVal( speed, 0, 320, 0.0f, 1.0f );
  222. bobtime += ( gpGlobals->curtime - lastbobtime ) * bob_offset;
  223. lastbobtime = gpGlobals->curtime;
  224. //Calculate the vertical bob
  225. cycle = bobtime - (int)(bobtime/HL2_BOB_CYCLE_MAX)*HL2_BOB_CYCLE_MAX;
  226. cycle /= HL2_BOB_CYCLE_MAX;
  227. if ( cycle < HL2_BOB_UP )
  228. {
  229. cycle = M_PI * cycle / HL2_BOB_UP;
  230. }
  231. else
  232. {
  233. cycle = M_PI + M_PI*(cycle-HL2_BOB_UP)/(1.0 - HL2_BOB_UP);
  234. }
  235. g_verticalBob = speed*0.005f;
  236. g_verticalBob = g_verticalBob*0.3 + g_verticalBob*0.7*sin(cycle);
  237. g_verticalBob = clamp( g_verticalBob, -7.0f, 4.0f );
  238. //Calculate the lateral bob
  239. cycle = bobtime - (int)(bobtime/HL2_BOB_CYCLE_MAX*2)*HL2_BOB_CYCLE_MAX*2;
  240. cycle /= HL2_BOB_CYCLE_MAX*2;
  241. if ( cycle < HL2_BOB_UP )
  242. {
  243. cycle = M_PI * cycle / HL2_BOB_UP;
  244. }
  245. else
  246. {
  247. cycle = M_PI + M_PI*(cycle-HL2_BOB_UP)/(1.0 - HL2_BOB_UP);
  248. }
  249. g_lateralBob = speed*0.005f;
  250. g_lateralBob = g_lateralBob*0.3 + g_lateralBob*0.7*sin(cycle);
  251. g_lateralBob = clamp( g_lateralBob, -7.0f, 4.0f );
  252. //NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!)
  253. return 0.0f;
  254. }
  255. //-----------------------------------------------------------------------------
  256. // Purpose:
  257. // Input : &origin -
  258. // &angles -
  259. // viewmodelindex -
  260. //-----------------------------------------------------------------------------
  261. void CBasePortalCombatWeapon::AddViewmodelBob( CBaseViewModel *viewmodel, Vector &origin, QAngle &angles )
  262. {
  263. Vector forward, right;
  264. AngleVectors( angles, &forward, &right, NULL );
  265. CalcViewmodelBob();
  266. // Apply bob, but scaled down to 40%
  267. VectorMA( origin, g_verticalBob * 0.1f, forward, origin );
  268. // Z bob a bit more
  269. origin[2] += g_verticalBob * 0.1f;
  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