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.

175 lines
4.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "cbase.h"
  9. #include "player_pickup.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include "tier0/memdbgon.h"
  12. // player pickup utility routine
  13. void Pickup_ForcePlayerToDropThisObject( CBaseEntity *pTarget )
  14. {
  15. if ( pTarget == NULL )
  16. return;
  17. IPhysicsObject *pPhysics = pTarget->VPhysicsGetObject();
  18. if ( pPhysics == NULL )
  19. return;
  20. if ( pPhysics->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
  21. {
  22. CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
  23. pPlayer->ForceDropOfCarriedPhysObjects( pTarget );
  24. }
  25. }
  26. void Pickup_OnPhysGunDrop( CBaseEntity *pDroppedObject, CBasePlayer *pPlayer, PhysGunDrop_t Reason )
  27. {
  28. IPlayerPickupVPhysics *pPickup = dynamic_cast<IPlayerPickupVPhysics *>(pDroppedObject);
  29. if ( pPickup )
  30. {
  31. pPickup->OnPhysGunDrop( pPlayer, Reason );
  32. }
  33. }
  34. void Pickup_OnPhysGunPickup( CBaseEntity *pPickedUpObject, CBasePlayer *pPlayer, PhysGunPickup_t reason )
  35. {
  36. IPlayerPickupVPhysics *pPickup = dynamic_cast<IPlayerPickupVPhysics *>(pPickedUpObject);
  37. if ( pPickup )
  38. {
  39. pPickup->OnPhysGunPickup( pPlayer, reason );
  40. }
  41. // send phys gun pickup item event, but only in single player
  42. if ( !g_pGameRules->IsMultiplayer() )
  43. {
  44. IGameEvent *event = gameeventmanager->CreateEvent( "physgun_pickup" );
  45. if ( event )
  46. {
  47. event->SetInt( "entindex", pPickedUpObject->entindex() );
  48. gameeventmanager->FireEvent( event );
  49. }
  50. }
  51. }
  52. bool Pickup_OnAttemptPhysGunPickup( CBaseEntity *pPickedUpObject, CBasePlayer *pPlayer, PhysGunPickup_t reason )
  53. {
  54. IPlayerPickupVPhysics *pPickup = dynamic_cast<IPlayerPickupVPhysics *>(pPickedUpObject);
  55. if ( pPickup )
  56. {
  57. return pPickup->OnAttemptPhysGunPickup( pPlayer, reason );
  58. }
  59. return true;
  60. }
  61. CBaseEntity *Pickup_OnFailedPhysGunPickup( CBaseEntity *pPickedUpObject, Vector vPhysgunPos )
  62. {
  63. IPlayerPickupVPhysics *pPickup = dynamic_cast<IPlayerPickupVPhysics *>(pPickedUpObject);
  64. if ( pPickup )
  65. {
  66. return pPickup->OnFailedPhysGunPickup( vPhysgunPos );
  67. }
  68. return NULL;
  69. }
  70. bool Pickup_GetPreferredCarryAngles( CBaseEntity *pObject, CBasePlayer *pPlayer, matrix3x4_t &localToWorld, QAngle &outputAnglesWorldSpace )
  71. {
  72. IPlayerPickupVPhysics *pPickup = dynamic_cast<IPlayerPickupVPhysics *>(pObject);
  73. if ( pPickup )
  74. {
  75. if ( pPickup->HasPreferredCarryAnglesForPlayer( pPlayer ) )
  76. {
  77. outputAnglesWorldSpace = TransformAnglesToWorldSpace( pPickup->PreferredCarryAngles(), localToWorld );
  78. return true;
  79. }
  80. }
  81. return false;
  82. }
  83. bool Pickup_ForcePhysGunOpen( CBaseEntity *pObject, CBasePlayer *pPlayer )
  84. {
  85. IPlayerPickupVPhysics *pPickup = dynamic_cast<IPlayerPickupVPhysics *>(pObject);
  86. if ( pPickup )
  87. {
  88. return pPickup->ForcePhysgunOpen( pPlayer );
  89. }
  90. return false;
  91. }
  92. AngularImpulse Pickup_PhysGunLaunchAngularImpulse( CBaseEntity *pObject, PhysGunForce_t reason )
  93. {
  94. IPlayerPickupVPhysics *pPickup = dynamic_cast<IPlayerPickupVPhysics *>(pObject);
  95. if ( pPickup != NULL && pPickup->ShouldPuntUseLaunchForces( reason ) )
  96. {
  97. return pPickup->PhysGunLaunchAngularImpulse();
  98. }
  99. return RandomAngularImpulse( -600, 600 );
  100. }
  101. Vector Pickup_DefaultPhysGunLaunchVelocity( const Vector &vecForward, float flMass )
  102. {
  103. #ifdef HL2_DLL
  104. // Calculate the velocity based on physcannon rules
  105. float flForceMax = physcannon_maxforce.GetFloat();
  106. float flForce = flForceMax;
  107. float mass = flMass;
  108. if ( mass > 100 )
  109. {
  110. mass = MIN( mass, 1000 );
  111. float flForceMin = physcannon_minforce.GetFloat();
  112. flForce = SimpleSplineRemapValClamped( mass, 100, 600, flForceMax, flForceMin );
  113. }
  114. return ( vecForward * flForce );
  115. #endif
  116. // Do the simple calculation
  117. return ( vecForward * flMass );
  118. }
  119. Vector Pickup_PhysGunLaunchVelocity( CBaseEntity *pObject, const Vector &vecForward, PhysGunForce_t reason )
  120. {
  121. // The object must be valid
  122. if ( pObject == NULL )
  123. {
  124. Assert( 0 );
  125. return vec3_origin;
  126. }
  127. // Shouldn't ever get here with a non-vphysics object.
  128. IPhysicsObject *pPhysicsObject = pObject->VPhysicsGetObject();
  129. if ( pPhysicsObject == NULL )
  130. {
  131. Assert( 0 );
  132. return vec3_origin;
  133. }
  134. // Call the pickup entity's callback
  135. IPlayerPickupVPhysics *pPickup = dynamic_cast<IPlayerPickupVPhysics *>(pObject);
  136. if ( pPickup != NULL && pPickup->ShouldPuntUseLaunchForces( reason ) )
  137. return pPickup->PhysGunLaunchVelocity( vecForward, pPhysicsObject->GetMass() );
  138. // Do our default behavior
  139. return Pickup_DefaultPhysGunLaunchVelocity( vecForward, pPhysicsObject->GetMass() );
  140. }
  141. bool Pickup_ShouldPuntUseLaunchForces( CBaseEntity *pObject, PhysGunForce_t reason )
  142. {
  143. IPlayerPickupVPhysics *pPickup = dynamic_cast<IPlayerPickupVPhysics *>(pObject);
  144. if ( pPickup )
  145. {
  146. return pPickup->ShouldPuntUseLaunchForces( reason );
  147. }
  148. return false;
  149. }