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.

161 lines
5.1 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: An entity that can be used to constrain the player's movement around it
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "saverestore_utlvector.h"
  8. // memdbgon must be the last include file in a .cpp file!!!
  9. #include "tier0/memdbgon.h"
  10. #define SF_TELEPORT_TO_SPAWN_POS 0x00000001
  11. //-----------------------------------------------------------------------------
  12. // Purpose:
  13. //-----------------------------------------------------------------------------
  14. class CPointPlayerMoveConstraint : public CBaseEntity
  15. {
  16. DECLARE_CLASS( CPointPlayerMoveConstraint, CBaseEntity );
  17. public:
  18. DECLARE_DATADESC();
  19. int UpdateTransmitState( void );
  20. void Activate( void );
  21. void ConstraintThink( void );
  22. void InputTurnOn( inputdata_t &inputdata );
  23. void InputTurnOff( inputdata_t &inputdata );
  24. private:
  25. float m_flRadius;
  26. float m_flConstraintWidth;
  27. float m_flSpeedFactor;
  28. float m_flRadiusSquared;
  29. CUtlVector<EHANDLE> m_hConstrainedPlayers;
  30. COutputEvent m_OnConstraintBroken;
  31. };
  32. LINK_ENTITY_TO_CLASS( point_playermoveconstraint, CPointPlayerMoveConstraint );
  33. BEGIN_DATADESC( CPointPlayerMoveConstraint )
  34. DEFINE_KEYFIELD( m_flRadius, FIELD_FLOAT, "radius" ),
  35. DEFINE_KEYFIELD( m_flConstraintWidth, FIELD_FLOAT, "width" ),
  36. DEFINE_KEYFIELD( m_flSpeedFactor, FIELD_FLOAT, "speedfactor" ),
  37. // DEFINE_FIELD( m_flRadiusSquared, FIELD_FLOAT ), // Don't Save
  38. DEFINE_UTLVECTOR( m_hConstrainedPlayers, FIELD_EHANDLE ),
  39. DEFINE_THINKFUNC( ConstraintThink ),
  40. DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ),
  41. DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ),
  42. DEFINE_OUTPUT( m_OnConstraintBroken, "OnConstraintBroken" ),
  43. END_DATADESC()
  44. //-----------------------------------------------------------------------------
  45. // Purpose:
  46. //-----------------------------------------------------------------------------
  47. int CPointPlayerMoveConstraint::UpdateTransmitState()
  48. {
  49. // ALWAYS transmit to all clients.
  50. return SetTransmitState( FL_EDICT_ALWAYS );
  51. }
  52. //------------------------------------------------------------------------------
  53. // Purpose:
  54. //------------------------------------------------------------------------------
  55. void CPointPlayerMoveConstraint::Activate( void )
  56. {
  57. BaseClass::Activate();
  58. m_flRadiusSquared = (m_flRadius * m_flRadius);
  59. }
  60. //------------------------------------------------------------------------------
  61. // Purpose:
  62. //------------------------------------------------------------------------------
  63. void CPointPlayerMoveConstraint::InputTurnOn( inputdata_t &inputdata )
  64. {
  65. // Find all players within our radius and constraint them
  66. float flRadius = m_flRadius;
  67. // If we're in singleplayer, blow the radius a bunch
  68. if ( gpGlobals->maxClients == 1 )
  69. {
  70. flRadius = MAX_COORD_RANGE;
  71. }
  72. CBaseEntity *pEntity = NULL;
  73. while ( (pEntity = gEntList.FindEntityByClassnameWithin( pEntity, "player", GetLocalOrigin(), flRadius)) != NULL )
  74. {
  75. CBasePlayer *pPlayer = ToBasePlayer( pEntity );
  76. Assert( pPlayer );
  77. // Only add him if he's not already constrained
  78. if ( m_hConstrainedPlayers.Find( pPlayer ) == m_hConstrainedPlayers.InvalidIndex() )
  79. {
  80. m_hConstrainedPlayers.AddToTail( pPlayer );
  81. pPlayer->ActivateMovementConstraint( this, GetAbsOrigin(), m_flRadius, m_flConstraintWidth, m_flSpeedFactor );
  82. }
  83. }
  84. // Only think if we found any
  85. if ( m_hConstrainedPlayers.Count() )
  86. {
  87. SetThink( &CPointPlayerMoveConstraint::ConstraintThink );
  88. SetNextThink( gpGlobals->curtime + 0.1f );
  89. }
  90. }
  91. //------------------------------------------------------------------------------
  92. // Purpose: Release all players we've constrained
  93. //------------------------------------------------------------------------------
  94. void CPointPlayerMoveConstraint::InputTurnOff( inputdata_t &inputdata )
  95. {
  96. int iCount = m_hConstrainedPlayers.Count();
  97. for ( int i = 0; i < iCount; i++ )
  98. {
  99. CBasePlayer *pPlayer = ToBasePlayer( m_hConstrainedPlayers[i] );
  100. if ( pPlayer )
  101. {
  102. pPlayer->DeactivateMovementConstraint();
  103. }
  104. }
  105. m_hConstrainedPlayers.Purge();
  106. }
  107. //-----------------------------------------------------------------------------
  108. // Purpose: Check to see if any of our constrained players have broken the constraint
  109. //-----------------------------------------------------------------------------
  110. void CPointPlayerMoveConstraint::ConstraintThink( void )
  111. {
  112. int iCount = m_hConstrainedPlayers.Count();
  113. // Count backwards, because we might drop them if they've broken the constraint
  114. for ( int i = (iCount-1); i >= 0; i-- )
  115. {
  116. CBasePlayer *pPlayer = ToBasePlayer( m_hConstrainedPlayers[i] );
  117. if ( pPlayer )
  118. {
  119. float flDistanceSqr = (pPlayer->GetAbsOrigin() - GetAbsOrigin()).LengthSqr();
  120. if ( flDistanceSqr > m_flRadiusSquared )
  121. {
  122. // Break the constraint to this player
  123. pPlayer->DeactivateMovementConstraint();
  124. m_hConstrainedPlayers.Remove(i);
  125. // Fire the broken output
  126. m_OnConstraintBroken.FireOutput( this, pPlayer );
  127. }
  128. }
  129. }
  130. // Only keep thinking if we any left
  131. if ( m_hConstrainedPlayers.Count() )
  132. {
  133. SetNextThink( gpGlobals->curtime + 0.1f );
  134. }
  135. }