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.

213 lines
6.8 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Teleports a named entity to a given position and restores
  4. // it's physics state
  5. //
  6. // $NoKeywords: $
  7. //=============================================================================//
  8. #include "cbase.h"
  9. #include "in_buttons.h"
  10. #if defined ( PORTAL2 )
  11. #include "portal_player.h"
  12. #include "portal2/portal_grabcontroller_shared.h"
  13. #endif
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. #define SF_TELEPORT_TO_SPAWN_POS 0x00000001
  17. #define SF_TELEPORT_INTO_DUCK 0x00000002 ///< episodic only: player should be ducked after this teleport
  18. class CPointTeleport : public CBaseEntity
  19. {
  20. DECLARE_CLASS( CPointTeleport, CBaseEntity );
  21. public:
  22. void Activate( void );
  23. void InputTeleport( inputdata_t &inputdata );
  24. void InputTeleportEntity( inputdata_t &inputdata );
  25. void InputTeleportToCurrentPos( inputdata_t &inputdata );
  26. int ObjectCaps( void )
  27. {
  28. return (BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION);
  29. }
  30. private:
  31. void DoTeleport( inputdata_t &inputdata, const Vector &vecOrigin, const QAngle &angRotation, bool bOverrideTarget = false );
  32. bool EntityMayTeleport( CBaseEntity *pTarget );
  33. Vector m_vSaveOrigin;
  34. QAngle m_vSaveAngles;
  35. DECLARE_DATADESC();
  36. };
  37. LINK_ENTITY_TO_CLASS( point_teleport, CPointTeleport );
  38. BEGIN_DATADESC( CPointTeleport )
  39. DEFINE_FIELD( m_vSaveOrigin, FIELD_VECTOR ),
  40. DEFINE_FIELD( m_vSaveAngles, FIELD_VECTOR ),
  41. DEFINE_INPUTFUNC( FIELD_VOID, "Teleport", InputTeleport ),
  42. DEFINE_INPUTFUNC( FIELD_STRING, "TeleportEntity", InputTeleportEntity ),
  43. DEFINE_INPUTFUNC( FIELD_VOID, "TeleportToCurrentPos", InputTeleportToCurrentPos ),
  44. END_DATADESC()
  45. //-----------------------------------------------------------------------------
  46. // Returns true if the entity may be teleported
  47. //-----------------------------------------------------------------------------
  48. bool CPointTeleport::EntityMayTeleport( CBaseEntity *pTarget )
  49. {
  50. if ( pTarget->GetMoveParent() != NULL )
  51. {
  52. // Passengers in a vehicle are allowed to teleport; their behavior handles it
  53. CBaseCombatCharacter *pBCC = pTarget->MyCombatCharacterPointer();
  54. if ( pBCC == NULL || ( pBCC != NULL && pBCC->IsInAVehicle() == false ) )
  55. return false;
  56. }
  57. return true;
  58. }
  59. //------------------------------------------------------------------------------
  60. //------------------------------------------------------------------------------
  61. void CPointTeleport::Activate( void )
  62. {
  63. // Start with our origin point
  64. m_vSaveOrigin = GetAbsOrigin();
  65. m_vSaveAngles = GetAbsAngles();
  66. // Save off the spawn position of the target if instructed to do so
  67. if ( m_spawnflags & SF_TELEPORT_TO_SPAWN_POS )
  68. {
  69. CBaseEntity *pTarget = gEntList.FindEntityByName( NULL, m_target );
  70. if ( pTarget )
  71. {
  72. // If teleport object is in a movement hierarchy, remove it first
  73. if ( EntityMayTeleport( pTarget ) )
  74. {
  75. // Save the points
  76. m_vSaveOrigin = pTarget->GetAbsOrigin();
  77. m_vSaveAngles = pTarget->GetAbsAngles();
  78. }
  79. else
  80. {
  81. Warning("ERROR: (%s) can't teleport object (%s) as it has a parent (%s)!\n",GetDebugName(),pTarget->GetDebugName(),pTarget->GetMoveParent()->GetDebugName());
  82. BaseClass::Activate();
  83. return;
  84. }
  85. }
  86. else
  87. {
  88. Warning("ERROR: (%s) target '%s' not found. Deleting.\n", GetDebugName(), STRING(m_target));
  89. UTIL_Remove( this );
  90. return;
  91. }
  92. }
  93. BaseClass::Activate();
  94. }
  95. //------------------------------------------------------------------------------
  96. //------------------------------------------------------------------------------
  97. void CPointTeleport::InputTeleport( inputdata_t &inputdata )
  98. {
  99. DoTeleport( inputdata, m_vSaveOrigin, m_vSaveAngles );
  100. }
  101. //------------------------------------------------------------------------------
  102. // Purpose: Teleport the specified entity instead of the Teleporter's pre
  103. // determined entity.
  104. //------------------------------------------------------------------------------
  105. void CPointTeleport::InputTeleportEntity( inputdata_t &inputdata )
  106. {
  107. DoTeleport( inputdata, m_vSaveOrigin, m_vSaveAngles, true );
  108. }
  109. //------------------------------------------------------------------------------
  110. // Teleport the target to wherever the point_teleport entity is currently. The Teleport
  111. // input teleports to the initial position of the point_teleport, so this input
  112. // was added to avoid breaking old content.
  113. //------------------------------------------------------------------------------
  114. void CPointTeleport::InputTeleportToCurrentPos( inputdata_t &inputdata )
  115. {
  116. if ( m_spawnflags & SF_TELEPORT_TO_SPAWN_POS )
  117. {
  118. // This is a nonsensical spawnflag in combination with this input.
  119. Warning( "%s: TeleportToCurrentPos input received; ignoring 'Teleport Home' spawnflag.\n", GetDebugName() );
  120. }
  121. DoTeleport( inputdata, GetAbsOrigin(), GetAbsAngles() );
  122. }
  123. //------------------------------------------------------------------------------
  124. //------------------------------------------------------------------------------
  125. void CPointTeleport::DoTeleport( inputdata_t &inputdata, const Vector &vecOrigin, const QAngle &angRotation, bool bOverrideTarget )
  126. {
  127. // Attempt to find the entity in question
  128. CBaseEntity *pTarget;
  129. if( bOverrideTarget )
  130. {
  131. // Use the inputdata to find the entity that the designer supplied in the parameter override
  132. pTarget = gEntList.FindEntityByName( NULL, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller );
  133. }
  134. else
  135. {
  136. // Default behavior: Just find the entity that I am hardwired in Hammer to teleport.
  137. pTarget = gEntList.FindEntityByName( NULL, m_target, this, inputdata.pActivator, inputdata.pCaller );
  138. }
  139. if ( pTarget == NULL )
  140. return;
  141. // If teleport object is in a movement hierarchy, remove it first
  142. if ( EntityMayTeleport( pTarget ) == false )
  143. {
  144. Warning("ERROR: (%s) can't teleport object (%s) as it has a parent (%s)!\n",GetDebugName(),pTarget->GetDebugName(),pTarget->GetMoveParent()->GetDebugName());
  145. return;
  146. }
  147. // in episodic, we have a special spawn flag that forces Gordon into a duck
  148. #ifdef HL2_EPISODIC
  149. if ( (m_spawnflags & SF_TELEPORT_INTO_DUCK) && pTarget->IsPlayer() )
  150. {
  151. CBasePlayer *pPlayer = ToBasePlayer( pTarget );
  152. if ( pPlayer != NULL )
  153. {
  154. pPlayer->m_nButtons |= IN_DUCK;
  155. pPlayer->AddFlag( FL_DUCKING );
  156. pPlayer->m_Local.m_bDucked = true;
  157. pPlayer->m_Local.m_bDucking = true;
  158. pPlayer->m_Local.m_nDuckTimeMsecs = 0;
  159. pPlayer->SetViewOffset( VEC_DUCK_VIEW );
  160. pPlayer->SetCollisionBounds( VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX );
  161. }
  162. }
  163. #endif
  164. #if defined ( PORTAL2 )
  165. // Force the player to drop the object when teleported by a map entity
  166. CPortal_Player *pPlayer = (CPortal_Player*)GetPlayerHoldingEntity( pTarget );
  167. if ( pPlayer && pPlayer->IsUsingVMGrab() )
  168. {
  169. pPlayer->ForceDropOfCarriedPhysObjects( pTarget );
  170. }
  171. #endif
  172. pTarget->Teleport( &vecOrigin, &angRotation, NULL );
  173. }