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.

267 lines
6.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "c_physicsprop.h"
  9. #include "c_physbox.h"
  10. #include "c_props.h"
  11. #define CPhysBox C_PhysBox
  12. #define CPhysicsProp C_PhysicsProp
  13. // memdbgon must be the last include file in a .cpp file!!!
  14. #include "tier0/memdbgon.h"
  15. IMPLEMENT_NETWORKCLASS_ALIASED( DynamicProp, DT_DynamicProp )
  16. BEGIN_NETWORK_TABLE( CDynamicProp, DT_DynamicProp )
  17. RecvPropBool(RECVINFO(m_bUseHitboxesForRenderBox)),
  18. END_NETWORK_TABLE()
  19. C_DynamicProp::C_DynamicProp( void )
  20. {
  21. m_iCachedFrameCount = -1;
  22. }
  23. C_DynamicProp::~C_DynamicProp( void )
  24. {
  25. }
  26. bool C_DynamicProp::TestBoneFollowers( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr )
  27. {
  28. // UNDONE: There is no list of the bone followers that is networked to the client
  29. // so instead we do a search for solid stuff here. This is not really great - a list would be
  30. // preferable.
  31. CBaseEntity *pList[128];
  32. Vector mins, maxs;
  33. CollisionProp()->WorldSpaceAABB( &mins, &maxs );
  34. int count = UTIL_EntitiesInBox( pList, ARRAYSIZE(pList), mins, maxs, 0, PARTITION_CLIENT_SOLID_EDICTS );
  35. for ( int i = 0; i < count; i++ )
  36. {
  37. if ( pList[i]->GetOwnerEntity() == this )
  38. {
  39. if ( pList[i]->TestCollision(ray, fContentsMask, tr) )
  40. {
  41. return true;
  42. }
  43. }
  44. }
  45. return false;
  46. }
  47. bool C_DynamicProp::TestCollision( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr )
  48. {
  49. if ( IsSolidFlagSet(FSOLID_NOT_SOLID) )
  50. {
  51. // if this entity is marked non-solid and custom test it must have bone followers
  52. if ( IsSolidFlagSet( FSOLID_CUSTOMBOXTEST ) && IsSolidFlagSet( FSOLID_CUSTOMRAYTEST ))
  53. {
  54. return TestBoneFollowers( ray, fContentsMask, tr );
  55. }
  56. }
  57. return BaseClass::TestCollision( ray, fContentsMask, tr );
  58. }
  59. //-----------------------------------------------------------------------------
  60. // implements these so ragdolls can handle frustum culling & leaf visibility
  61. //-----------------------------------------------------------------------------
  62. void C_DynamicProp::GetRenderBounds( Vector& theMins, Vector& theMaxs )
  63. {
  64. if ( m_bUseHitboxesForRenderBox )
  65. {
  66. if ( GetModel() )
  67. {
  68. studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( GetModel() );
  69. if ( !pStudioHdr || GetSequence() == -1 )
  70. {
  71. theMins = vec3_origin;
  72. theMaxs = vec3_origin;
  73. return;
  74. }
  75. // Only recompute if it's a new frame
  76. if ( gpGlobals->framecount != m_iCachedFrameCount )
  77. {
  78. ComputeEntitySpaceHitboxSurroundingBox( &m_vecCachedRenderMins, &m_vecCachedRenderMaxs );
  79. m_iCachedFrameCount = gpGlobals->framecount;
  80. }
  81. theMins = m_vecCachedRenderMins;
  82. theMaxs = m_vecCachedRenderMaxs;
  83. return;
  84. }
  85. }
  86. BaseClass::GetRenderBounds( theMins, theMaxs );
  87. }
  88. unsigned int C_DynamicProp::ComputeClientSideAnimationFlags()
  89. {
  90. if ( GetSequence() != -1 )
  91. {
  92. CStudioHdr *pStudioHdr = GetModelPtr();
  93. if ( GetSequenceCycleRate(pStudioHdr, GetSequence()) != 0.0f )
  94. {
  95. return BaseClass::ComputeClientSideAnimationFlags();
  96. }
  97. }
  98. // no sequence or no cycle rate, don't do any per-frame calcs
  99. return 0;
  100. }
  101. // ------------------------------------------------------------------------------------------ //
  102. // ------------------------------------------------------------------------------------------ //
  103. class C_BasePropDoor : public C_DynamicProp
  104. {
  105. DECLARE_CLASS( C_BasePropDoor, C_DynamicProp );
  106. public:
  107. DECLARE_CLIENTCLASS();
  108. // constructor, destructor
  109. C_BasePropDoor( void );
  110. virtual ~C_BasePropDoor( void );
  111. virtual void OnDataChanged( DataUpdateType_t type );
  112. virtual bool TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace );
  113. private:
  114. C_BasePropDoor( const C_BasePropDoor & );
  115. };
  116. IMPLEMENT_CLIENTCLASS_DT(C_BasePropDoor, DT_BasePropDoor, CBasePropDoor)
  117. END_RECV_TABLE()
  118. C_BasePropDoor::C_BasePropDoor( void )
  119. {
  120. }
  121. C_BasePropDoor::~C_BasePropDoor( void )
  122. {
  123. }
  124. void C_BasePropDoor::OnDataChanged( DataUpdateType_t type )
  125. {
  126. BaseClass::OnDataChanged( type );
  127. if ( type == DATA_UPDATE_CREATED )
  128. {
  129. SetSolid(SOLID_VPHYSICS);
  130. VPhysicsInitShadow( false, false );
  131. }
  132. else if ( VPhysicsGetObject() )
  133. {
  134. VPhysicsGetObject()->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, TICK_INTERVAL );
  135. }
  136. }
  137. bool C_BasePropDoor::TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace )
  138. {
  139. if ( !VPhysicsGetObject() )
  140. return false;
  141. CStudioHdr *pStudioHdr = GetModelPtr( );
  142. if (!pStudioHdr)
  143. return false;
  144. physcollision->TraceBox( ray, VPhysicsGetObject()->GetCollide(), GetAbsOrigin(), GetAbsAngles(), &trace );
  145. if ( trace.DidHit() )
  146. {
  147. trace.surface.surfaceProps = VPhysicsGetObject()->GetMaterialIndex();
  148. return true;
  149. }
  150. return false;
  151. }
  152. // ------------------------------------------------------------------------------------------ //
  153. // Special version of func_physbox.
  154. // ------------------------------------------------------------------------------------------ //
  155. #ifndef _XBOX
  156. class CPhysBoxMultiplayer : public CPhysBox, public IMultiplayerPhysics
  157. {
  158. public:
  159. DECLARE_CLASS( CPhysBoxMultiplayer, CPhysBox );
  160. virtual int GetMultiplayerPhysicsMode()
  161. {
  162. return m_iPhysicsMode;
  163. }
  164. virtual float GetMass()
  165. {
  166. return m_fMass;
  167. }
  168. virtual bool IsAsleep()
  169. {
  170. Assert ( 0 );
  171. return true;
  172. }
  173. CNetworkVar( int, m_iPhysicsMode ); // One of the PHYSICS_MULTIPLAYER_ defines.
  174. CNetworkVar( float, m_fMass );
  175. DECLARE_CLIENTCLASS();
  176. };
  177. IMPLEMENT_CLIENTCLASS_DT( CPhysBoxMultiplayer, DT_PhysBoxMultiplayer, CPhysBoxMultiplayer )
  178. RecvPropInt( RECVINFO( m_iPhysicsMode ) ),
  179. RecvPropFloat( RECVINFO( m_fMass ) ),
  180. END_RECV_TABLE()
  181. class CPhysicsPropMultiplayer : public CPhysicsProp, public IMultiplayerPhysics
  182. {
  183. DECLARE_CLASS( CPhysicsPropMultiplayer, CPhysicsProp );
  184. virtual int GetMultiplayerPhysicsMode()
  185. {
  186. Assert( m_iPhysicsMode != PHYSICS_MULTIPLAYER_CLIENTSIDE );
  187. Assert( m_iPhysicsMode != PHYSICS_MULTIPLAYER_AUTODETECT );
  188. return m_iPhysicsMode;
  189. }
  190. virtual float GetMass()
  191. {
  192. return m_fMass;
  193. }
  194. virtual bool IsAsleep()
  195. {
  196. return !m_bAwake;
  197. }
  198. virtual void ComputeWorldSpaceSurroundingBox( Vector *mins, Vector *maxs )
  199. {
  200. Assert( mins != NULL && maxs != NULL );
  201. if ( !mins || !maxs )
  202. return;
  203. // Take our saved collision bounds, and transform into world space
  204. TransformAABB( EntityToWorldTransform(), m_collisionMins, m_collisionMaxs, *mins, *maxs );
  205. }
  206. CNetworkVar( int, m_iPhysicsMode ); // One of the PHYSICS_MULTIPLAYER_ defines.
  207. CNetworkVar( float, m_fMass );
  208. CNetworkVector( m_collisionMins );
  209. CNetworkVector( m_collisionMaxs );
  210. DECLARE_CLIENTCLASS();
  211. };
  212. IMPLEMENT_CLIENTCLASS_DT( CPhysicsPropMultiplayer, DT_PhysicsPropMultiplayer, CPhysicsPropMultiplayer )
  213. RecvPropInt( RECVINFO( m_iPhysicsMode ) ),
  214. RecvPropFloat( RECVINFO( m_fMass ) ),
  215. RecvPropVector( RECVINFO( m_collisionMins ) ),
  216. RecvPropVector( RECVINFO( m_collisionMaxs ) ),
  217. END_RECV_TABLE()
  218. #endif