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.

360 lines
8.9 KiB

  1. //========= Copyright � 1996-2005, 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. #if defined(CSTRIKE15)
  12. #include "c_cs_player.h"
  13. #endif
  14. #define CPhysBox C_PhysBox
  15. #define CPhysicsProp C_PhysicsProp
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include "tier0/memdbgon.h"
  18. IMPLEMENT_NETWORKCLASS_ALIASED( DynamicProp, DT_DynamicProp )
  19. BEGIN_NETWORK_TABLE( CDynamicProp, DT_DynamicProp )
  20. RecvPropBool(RECVINFO(m_bUseHitboxesForRenderBox)),
  21. RecvPropFloat( RECVINFO(m_flGlowMaxDist) ),
  22. RecvPropBool(RECVINFO(m_bShouldGlow)),
  23. RecvPropInt( RECVINFO(m_clrGlow), 0, RecvProxy_Int32ToColor32 ),
  24. RecvPropInt( RECVINFO(m_nGlowStyle) ),
  25. END_NETWORK_TABLE()
  26. C_DynamicProp::C_DynamicProp( void ) :
  27. m_GlowObject( this, Vector( 1.0f, 1.0f, 1.0f ), 0.0f, false, false )
  28. {
  29. m_iCachedFrameCount = -1;
  30. }
  31. C_DynamicProp::~C_DynamicProp( void )
  32. {
  33. }
  34. bool C_DynamicProp::TestBoneFollowers( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr )
  35. {
  36. // UNDONE: There is no list of the bone followers that is networked to the client
  37. // so instead we do a search for solid stuff here. This is not really great - a list would be
  38. // preferable.
  39. CBaseEntity *pList[128];
  40. Vector mins, maxs;
  41. CollisionProp()->WorldSpaceAABB( &mins, &maxs );
  42. int count = UTIL_EntitiesInBox( pList, ARRAYSIZE(pList), mins, maxs, 0, PARTITION_CLIENT_SOLID_EDICTS );
  43. for ( int i = 0; i < count; i++ )
  44. {
  45. if ( pList[i]->GetOwnerEntity() == this )
  46. {
  47. if ( pList[i]->TestCollision(ray, fContentsMask, tr) )
  48. {
  49. return true;
  50. }
  51. }
  52. }
  53. return false;
  54. }
  55. bool C_DynamicProp::TestCollision( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr )
  56. {
  57. if ( IsSolidFlagSet(FSOLID_NOT_SOLID) )
  58. {
  59. // if this entity is marked non-solid and custom test it must have bone followers
  60. if ( IsSolidFlagSet( FSOLID_CUSTOMBOXTEST ) && IsSolidFlagSet( FSOLID_CUSTOMRAYTEST ))
  61. {
  62. return TestBoneFollowers( ray, fContentsMask, tr );
  63. }
  64. }
  65. return BaseClass::TestCollision( ray, fContentsMask, tr );
  66. }
  67. void C_DynamicProp::ClientThink( void )
  68. {
  69. BaseClass::ClientThink();
  70. UpdateGlow();
  71. }
  72. void C_DynamicProp::UpdateGlow( void )
  73. {
  74. if ( m_bShouldGlow == false )
  75. {
  76. if ( m_GlowObject.IsRendering() )
  77. {
  78. m_GlowObject.SetRenderFlags( false, false );
  79. m_GlowObject.SetAlpha( 0.0f );
  80. }
  81. return;
  82. }
  83. Vector glowColor;
  84. glowColor.x = (m_clrGlow.r/255.0f);
  85. glowColor.y = (m_clrGlow.g/255.0f);
  86. glowColor.z = (m_clrGlow.b/255.0f);
  87. float flAlpha = 0.9f;
  88. #if defined(CSTRIKE15)
  89. // fade the alpha based on distace
  90. C_CSPlayer *pPlayer = GetLocalOrInEyeCSPlayer();
  91. if ( pPlayer && m_bShouldGlow )
  92. {
  93. float flDistance = 0;
  94. flDistance = ( GetAbsOrigin() - pPlayer->GetAbsOrigin() ).Length();
  95. flAlpha = clamp( 1.0 - ( flDistance / m_flGlowMaxDist ), 0.0, 0.9 );
  96. }
  97. #endif
  98. //m_nGlowStyle
  99. GlowRenderStyle_t glowstyle = (GlowRenderStyle_t)m_nGlowStyle;
  100. // Start glowing
  101. m_GlowObject.SetRenderFlags( m_bShouldGlow, false );
  102. m_GlowObject.SetRenderStyle( glowstyle );
  103. m_GlowObject.SetColor( glowColor );
  104. m_GlowObject.SetAlpha( m_bShouldGlow ? flAlpha : 0.0f );
  105. SetNextClientThink( gpGlobals->curtime + 0.1f );
  106. }
  107. //-----------------------------------------------------------------------------
  108. // implements these so ragdolls can handle frustum culling & leaf visibility
  109. //-----------------------------------------------------------------------------
  110. void C_DynamicProp::GetRenderBounds( Vector& theMins, Vector& theMaxs )
  111. {
  112. if ( m_bUseHitboxesForRenderBox )
  113. {
  114. if ( GetModel() )
  115. {
  116. studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( GetModel() );
  117. if ( !pStudioHdr || GetSequence() == -1 )
  118. {
  119. theMins = vec3_origin;
  120. theMaxs = vec3_origin;
  121. return;
  122. }
  123. // Only recompute if it's a new frame
  124. if ( gpGlobals->framecount != m_iCachedFrameCount )
  125. {
  126. ComputeEntitySpaceHitboxSurroundingBox( &m_vecCachedRenderMins, &m_vecCachedRenderMaxs );
  127. m_iCachedFrameCount = gpGlobals->framecount;
  128. }
  129. theMins = m_vecCachedRenderMins;
  130. theMaxs = m_vecCachedRenderMaxs;
  131. return;
  132. }
  133. }
  134. BaseClass::GetRenderBounds( theMins, theMaxs );
  135. }
  136. unsigned int C_DynamicProp::ComputeClientSideAnimationFlags()
  137. {
  138. if ( GetSequence() != -1 )
  139. {
  140. CStudioHdr *pStudioHdr = GetModelPtr();
  141. if ( GetSequenceCycleRate(pStudioHdr, GetSequence()) != 0.0f )
  142. {
  143. return BaseClass::ComputeClientSideAnimationFlags();
  144. }
  145. }
  146. // no sequence or no cycle rate, don't do any per-frame calcs
  147. return 0;
  148. }
  149. void C_DynamicProp::ForceTurnOffGlow( void )
  150. {
  151. m_bShouldGlow = false;
  152. UpdateGlow();
  153. }
  154. void C_DynamicProp::OnDataChanged( DataUpdateType_t type )
  155. {
  156. BaseClass::OnDataChanged( type );
  157. // if ( type == DATA_UPDATE_CREATED )
  158. {
  159. // if ( m_bShouldGlow )
  160. {
  161. UpdateGlow();
  162. }
  163. }
  164. }
  165. // ------------------------------------------------------------------------------------------ //
  166. // ------------------------------------------------------------------------------------------ //
  167. IMPLEMENT_CLIENTCLASS_DT(C_BasePropDoor, DT_BasePropDoor, CBasePropDoor)
  168. END_RECV_TABLE()
  169. C_BasePropDoor::C_BasePropDoor( void )
  170. {
  171. m_modelChanged = false;
  172. }
  173. C_BasePropDoor::~C_BasePropDoor( void )
  174. {
  175. }
  176. void C_BasePropDoor::PostDataUpdate( DataUpdateType_t updateType )
  177. {
  178. if ( updateType == DATA_UPDATE_CREATED )
  179. {
  180. BaseClass::PostDataUpdate( updateType );
  181. }
  182. else
  183. {
  184. const model_t *oldModel = GetModel();
  185. BaseClass::PostDataUpdate( updateType );
  186. const model_t *newModel = GetModel();
  187. if ( oldModel != newModel )
  188. {
  189. m_modelChanged = true;
  190. }
  191. }
  192. }
  193. void C_BasePropDoor::OnDataChanged( DataUpdateType_t type )
  194. {
  195. BaseClass::OnDataChanged( type );
  196. bool bCreate = (type == DATA_UPDATE_CREATED) ? true : false;
  197. if ( VPhysicsGetObject() && m_modelChanged )
  198. {
  199. VPhysicsDestroyObject();
  200. m_modelChanged = false;
  201. bCreate = true;
  202. }
  203. VPhysicsShadowDataChanged(bCreate, this);
  204. }
  205. bool C_BasePropDoor::TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace )
  206. {
  207. if ( !VPhysicsGetObject() )
  208. return false;
  209. MDLCACHE_CRITICAL_SECTION();
  210. CStudioHdr *pStudioHdr = GetModelPtr( );
  211. if (!pStudioHdr)
  212. return false;
  213. physcollision->TraceBox( ray, VPhysicsGetObject()->GetCollide(), GetAbsOrigin(), GetAbsAngles(), &trace );
  214. if ( trace.DidHit() )
  215. {
  216. trace.contents = pStudioHdr->contents();
  217. // use the default surface properties
  218. trace.surface.name = "**studio**";
  219. trace.surface.flags = 0;
  220. trace.surface.surfaceProps = pStudioHdr->GetSurfaceProp();
  221. return true;
  222. }
  223. return false;
  224. }
  225. //just need to reference by classname in portal
  226. class C_PropDoorRotating : public C_BasePropDoor
  227. {
  228. public:
  229. DECLARE_CLASS( C_PropDoorRotating, C_BasePropDoor );
  230. DECLARE_CLIENTCLASS();
  231. };
  232. IMPLEMENT_CLIENTCLASS_DT(C_PropDoorRotating, DT_PropDoorRotating, CPropDoorRotating)
  233. END_RECV_TABLE()
  234. // ------------------------------------------------------------------------------------------ //
  235. // Special version of func_physbox.
  236. // ------------------------------------------------------------------------------------------ //
  237. class CPhysBoxMultiplayer : public CPhysBox, public IMultiplayerPhysics
  238. {
  239. public:
  240. DECLARE_CLASS( CPhysBoxMultiplayer, CPhysBox );
  241. virtual int GetMultiplayerPhysicsMode()
  242. {
  243. return m_iPhysicsMode;
  244. }
  245. virtual float GetMass()
  246. {
  247. return m_fMass;
  248. }
  249. virtual bool IsAsleep()
  250. {
  251. Assert ( 0 );
  252. return true;
  253. }
  254. CNetworkVar( int, m_iPhysicsMode ); // One of the PHYSICS_MULTIPLAYER_ defines.
  255. CNetworkVar( float, m_fMass );
  256. DECLARE_CLIENTCLASS();
  257. };
  258. IMPLEMENT_CLIENTCLASS_DT( CPhysBoxMultiplayer, DT_PhysBoxMultiplayer, CPhysBoxMultiplayer )
  259. RecvPropInt( RECVINFO( m_iPhysicsMode ) ),
  260. RecvPropFloat( RECVINFO( m_fMass ) ),
  261. END_RECV_TABLE()
  262. class CPhysicsPropMultiplayer : public CPhysicsProp, public IMultiplayerPhysics
  263. {
  264. DECLARE_CLASS( CPhysicsPropMultiplayer, CPhysicsProp );
  265. virtual int GetMultiplayerPhysicsMode()
  266. {
  267. Assert( m_iPhysicsMode != PHYSICS_MULTIPLAYER_CLIENTSIDE );
  268. Assert( m_iPhysicsMode != PHYSICS_MULTIPLAYER_AUTODETECT );
  269. return m_iPhysicsMode;
  270. }
  271. virtual float GetMass()
  272. {
  273. return m_fMass;
  274. }
  275. virtual bool IsAsleep()
  276. {
  277. return !m_bAwake;
  278. }
  279. virtual void ComputeWorldSpaceSurroundingBox( Vector *mins, Vector *maxs )
  280. {
  281. Assert( mins != NULL && maxs != NULL );
  282. if ( !mins || !maxs )
  283. return;
  284. // Take our saved collision bounds, and transform into world space
  285. TransformAABB( EntityToWorldTransform(), m_collisionMins, m_collisionMaxs, *mins, *maxs );
  286. }
  287. CNetworkVar( int, m_iPhysicsMode ); // One of the PHYSICS_MULTIPLAYER_ defines.
  288. CNetworkVar( float, m_fMass );
  289. CNetworkVector( m_collisionMins );
  290. CNetworkVector( m_collisionMaxs );
  291. DECLARE_CLIENTCLASS();
  292. };
  293. IMPLEMENT_CLIENTCLASS_DT( CPhysicsPropMultiplayer, DT_PhysicsPropMultiplayer, CPhysicsPropMultiplayer )
  294. RecvPropInt( RECVINFO( m_iPhysicsMode ) ),
  295. RecvPropFloat( RECVINFO( m_fMass ) ),
  296. RecvPropVector( RECVINFO( m_collisionMins ) ),
  297. RecvPropVector( RECVINFO( m_collisionMaxs ) ),
  298. END_RECV_TABLE()