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.

305 lines
8.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. //========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============
  8. //
  9. // Purpose:
  10. //
  11. // $NoKeywords: $
  12. //=============================================================================
  13. #include "cbase.h"
  14. #include "gamemovement.h"
  15. #include "in_buttons.h"
  16. #include <stdarg.h>
  17. #include "movevars_shared.h"
  18. #include "engine/IEngineTrace.h"
  19. #include "SoundEmitterSystem/isoundemittersystembase.h"
  20. #include "decals.h"
  21. #include "tier0/vprof.h"
  22. #include "hl1_gamemovement.h"
  23. // Expose our interface.
  24. static CHL1GameMovement g_GameMovement;
  25. IGameMovement *g_pGameMovement = ( IGameMovement * )&g_GameMovement;
  26. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CGameMovement, IGameMovement, INTERFACENAME_GAMEMOVEMENT, g_GameMovement );
  27. #ifdef CLIENT_DLL
  28. #include "hl1/c_hl1mp_player.h"
  29. #else
  30. #include "hl1mp_player.h"
  31. #endif
  32. //-----------------------------------------------------------------------------
  33. // Purpose:
  34. //-----------------------------------------------------------------------------
  35. bool CHL1GameMovement::CheckJumpButton( void )
  36. {
  37. m_pHL1Player = ToHL1Player( player );
  38. Assert( m_pHL1Player );
  39. if (m_pHL1Player->pl.deadflag)
  40. {
  41. mv->m_nOldButtons |= IN_JUMP ; // don't jump again until released
  42. return false;
  43. }
  44. // See if we are waterjumping. If so, decrement count and return.
  45. if (m_pHL1Player->m_flWaterJumpTime)
  46. {
  47. m_pHL1Player->m_flWaterJumpTime -= gpGlobals->frametime;
  48. if (m_pHL1Player->m_flWaterJumpTime < 0)
  49. m_pHL1Player->m_flWaterJumpTime = 0;
  50. return false;
  51. }
  52. // If we are in the water most of the way...
  53. if ( m_pHL1Player->GetWaterLevel() >= 2 )
  54. {
  55. // swimming, not jumping
  56. SetGroundEntity( NULL );
  57. if(m_pHL1Player->GetWaterType() == CONTENTS_WATER) // We move up a certain amount
  58. mv->m_vecVelocity[2] = 100;
  59. else if (m_pHL1Player->GetWaterType() == CONTENTS_SLIME)
  60. mv->m_vecVelocity[2] = 80;
  61. // play swiming sound
  62. if ( m_pHL1Player->m_flSwimSoundTime <= 0 )
  63. {
  64. // Don't play sound again for 1 second
  65. m_pHL1Player->m_flSwimSoundTime = 1000;
  66. PlaySwimSound();
  67. }
  68. return false;
  69. }
  70. // No more effect
  71. if (m_pHL1Player->GetGroundEntity() == NULL)
  72. {
  73. mv->m_nOldButtons |= IN_JUMP;
  74. return false; // in air, so no effect
  75. }
  76. if ( mv->m_nOldButtons & IN_JUMP )
  77. return false; // don't pogo stick
  78. // In the air now.
  79. SetGroundEntity( NULL );
  80. m_pHL1Player->PlayStepSound( (Vector &)mv->GetAbsOrigin(), player->GetSurfaceData(), 1.0, true );
  81. MoveHelper()->PlayerSetAnimation( PLAYER_JUMP );
  82. float flGroundFactor = 1.0f;
  83. if ( player->GetSurfaceData() )
  84. {
  85. flGroundFactor = 1.0;//player->GetSurfaceData()->game.jumpFactor;
  86. }
  87. // Acclerate upward
  88. // If we are ducking...
  89. float startz = mv->m_vecVelocity[2];
  90. if ( ( m_pHL1Player->m_Local.m_bDucking ) || ( m_pHL1Player->GetFlags() & FL_DUCKING ) )
  91. {
  92. // d = 0.5 * g * t^2 - distance traveled with linear accel
  93. // t = sqrt(2.0 * 45 / g) - how long to fall 45 units
  94. // v = g * t - velocity at the end (just invert it to jump up that high)
  95. // v = g * sqrt(2.0 * 45 / g )
  96. // v^2 = g * g * 2.0 * 45 / g
  97. // v = sqrt( g * 2.0 * 45 )
  98. // Adjust for super long jump module
  99. // UNDONE -- note this should be based on forward angles, not current velocity.
  100. if ( m_pHL1Player->m_bHasLongJump &&
  101. ( mv->m_nButtons & IN_DUCK ) &&
  102. ( m_pHL1Player->m_Local.m_flDucktime > 0 ) &&
  103. mv->m_vecVelocity.Length() > 50 )
  104. {
  105. m_pHL1Player->m_Local.m_vecPunchAngle.Set( PITCH, -5 );
  106. mv->m_vecVelocity = m_vecForward * PLAYER_LONGJUMP_SPEED * 1.6;
  107. mv->m_vecVelocity.z = sqrt(2 * 800 * 56.0);
  108. }
  109. else
  110. {
  111. mv->m_vecVelocity[2] = flGroundFactor * sqrt(2 * 800 * 45.0); // 2 * gravity * height
  112. }
  113. }
  114. else
  115. {
  116. mv->m_vecVelocity[2] += flGroundFactor * sqrt(2 * 800 * 45.0); // 2 * gravity * height
  117. }
  118. FinishGravity();
  119. mv->m_outWishVel.z += mv->m_vecVelocity[2] - startz;
  120. mv->m_outStepHeight += 0.1f;
  121. if ( gpGlobals->maxClients > 1 )
  122. #ifdef CLIENT_DLL
  123. (dynamic_cast<C_HL1MP_Player*>(m_pHL1Player))->DoAnimationEvent( PLAYERANIMEVENT_JUMP );
  124. #else
  125. (dynamic_cast<CHL1MP_Player*>(m_pHL1Player))->DoAnimationEvent( PLAYERANIMEVENT_JUMP );
  126. #endif
  127. // Flag that we jumped.
  128. mv->m_nOldButtons |= IN_JUMP; // don't jump again until released
  129. return true;
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Purpose: See if duck button is pressed and do the appropriate things
  133. //-----------------------------------------------------------------------------
  134. void CHL1GameMovement::Duck( void )
  135. {
  136. int buttonsChanged = ( mv->m_nOldButtons ^ mv->m_nButtons ); // These buttons have changed this frame
  137. int buttonsPressed = buttonsChanged & mv->m_nButtons; // The changed ones still down are "pressed"
  138. int buttonsReleased = buttonsChanged & mv->m_nOldButtons; // The changed ones which were previously down are "released"
  139. // Check to see if we are in the air.
  140. bool bInAir = ( player->GetGroundEntity() == NULL );
  141. bool bInDuck = ( player->GetFlags() & FL_DUCKING ) ? true : false;
  142. if ( mv->m_nButtons & IN_DUCK )
  143. {
  144. mv->m_nOldButtons |= IN_DUCK;
  145. }
  146. else
  147. {
  148. mv->m_nOldButtons &= ~IN_DUCK;
  149. }
  150. // Handle death.
  151. if ( IsDead() )
  152. {
  153. if ( bInDuck )
  154. {
  155. // Unduck
  156. FinishUnDuck();
  157. }
  158. return;
  159. }
  160. HandleDuckingSpeedCrop();
  161. // If the player is holding down the duck button, the player is in duck transition, ducking, or duck-jumping.
  162. if ( ( mv->m_nButtons & IN_DUCK ) || player->m_Local.m_bDucking || bInDuck )
  163. {
  164. if ( ( mv->m_nButtons & IN_DUCK ) )
  165. {
  166. // Have the duck button pressed, but the player currently isn't in the duck position.
  167. if ( ( buttonsPressed & IN_DUCK ) && !bInDuck )
  168. {
  169. // Use 1 second so super long jump will work
  170. player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME;
  171. player->m_Local.m_bDucking = true;
  172. }
  173. // The player is in duck transition and not duck-jumping.
  174. if ( player->m_Local.m_bDucking )
  175. {
  176. float flDuckMilliseconds = MAX( 0.0f, GAMEMOVEMENT_DUCK_TIME - ( float )player->m_Local.m_flDucktime );
  177. float flDuckSeconds = flDuckMilliseconds / GAMEMOVEMENT_DUCK_TIME;
  178. // Finish in duck transition when transition time is over, in "duck", in air.
  179. if ( ( flDuckSeconds > TIME_TO_DUCK ) || bInDuck || bInAir )
  180. {
  181. FinishDuck();
  182. }
  183. else
  184. {
  185. // Calc parametric time
  186. float flDuckFraction = SimpleSpline( flDuckSeconds / TIME_TO_DUCK );
  187. SetDuckedEyeOffset( flDuckFraction );
  188. }
  189. }
  190. }
  191. else
  192. {
  193. // Try to unduck unless automovement is not allowed
  194. // NOTE: When not onground, you can always unduck
  195. if ( player->m_Local.m_bAllowAutoMovement || bInAir )
  196. {
  197. if ( ( buttonsReleased & IN_DUCK ) && bInDuck )
  198. {
  199. // Use 1 second so super long jump will work
  200. player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME;
  201. }
  202. // Check to see if we are capable of unducking.
  203. if ( CanUnduck() )
  204. {
  205. // or unducking
  206. if ( ( player->m_Local.m_bDucking || player->m_Local.m_bDucked ) )
  207. {
  208. float flDuckMilliseconds = MAX( 0.0f, GAMEMOVEMENT_DUCK_TIME - (float)player->m_Local.m_flDucktime );
  209. float flDuckSeconds = flDuckMilliseconds / GAMEMOVEMENT_DUCK_TIME;
  210. // Finish ducking immediately if duck time is over or not on ground
  211. if ( flDuckSeconds > TIME_TO_UNDUCK || ( bInAir ) )
  212. {
  213. FinishUnDuck();
  214. }
  215. else
  216. {
  217. // Calc parametric time
  218. float flDuckFraction = SimpleSpline( 1.0f - ( flDuckSeconds / TIME_TO_UNDUCK ) );
  219. SetDuckedEyeOffset( flDuckFraction );
  220. player->m_Local.m_bDucking = true;
  221. }
  222. }
  223. }
  224. else
  225. {
  226. // Still under something where we can't unduck, so make sure we reset this timer so
  227. // that we'll unduck once we exit the tunnel, etc.
  228. player->m_Local.m_flDucktime = GAMEMOVEMENT_DUCK_TIME;
  229. SetDuckedEyeOffset( 1.0f );
  230. }
  231. }
  232. }
  233. }
  234. }
  235. void CHL1GameMovement::HandleDuckingSpeedCrop()
  236. {
  237. if ( !( m_iSpeedCropped & SPEED_CROPPED_DUCK ) )
  238. {
  239. if ( player->GetFlags() & FL_DUCKING )
  240. {
  241. float frac = 0.33333333f;
  242. mv->m_flForwardMove *= frac;
  243. mv->m_flSideMove *= frac;
  244. mv->m_flUpMove *= frac;
  245. m_iSpeedCropped |= SPEED_CROPPED_DUCK;
  246. }
  247. }
  248. }
  249. void CHL1GameMovement::CheckParameters( void )
  250. {
  251. if ( mv->m_nButtons & IN_SPEED )
  252. {
  253. mv->m_flClientMaxSpeed = 100;
  254. }
  255. else
  256. {
  257. mv->m_flClientMaxSpeed = mv->m_flMaxSpeed;
  258. }
  259. CHL1_Player* pHL1Player = dynamic_cast<CHL1_Player*>(player);
  260. if( pHL1Player && pHL1Player->IsPullingObject() )
  261. {
  262. mv->m_flClientMaxSpeed = mv->m_flMaxSpeed * 0.5f;
  263. }
  264. BaseClass::CheckParameters();
  265. }