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.

255 lines
5.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Implements a moving target that moves along a path of path_tracks
  4. // and can be shot and killed. When the target it killed it fires an
  5. // OnDeath output.
  6. //
  7. // m_flSpeed is the travel speed
  8. // m_iHealth is current health
  9. // m_iMaxHealth is the amount to reset to each time it starts
  10. //
  11. // $NoKeywords: $
  12. //=============================================================================//
  13. #include "cbase.h"
  14. #include "entityoutput.h"
  15. // memdbgon must be the last include file in a .cpp file!!!
  16. #include "tier0/memdbgon.h"
  17. #define FGUNTARGET_START_ON 0x0001
  18. class CGunTarget : public CBaseToggle
  19. {
  20. DECLARE_CLASS( CGunTarget, CBaseToggle );
  21. public:
  22. virtual void Spawn( void );
  23. virtual void Activate( void );
  24. bool CreateVPhysics( void );
  25. virtual int BloodColor( void ) { return DONT_BLEED; }
  26. #if defined( HL2_DLL )
  27. virtual Class_T Classify( void ) { return CLASS_MILITARY; }
  28. #elif defined( HL1_DLL )
  29. virtual Class_T Classify( void ) { return CLASS_MACHINE; }
  30. #else
  31. virtual Class_T Classify( void ) { return CLASS_NONE; }
  32. #endif
  33. virtual int OnTakeDamage( const CTakeDamageInfo &info );
  34. virtual Vector BodyTarget( const Vector &posSrc, bool bNoisy = true ) { return GetAbsOrigin(); }
  35. // Input handlers
  36. void InputStart( inputdata_t &inputdata );
  37. void InputStop( inputdata_t &inputdata );
  38. void InputToggle( inputdata_t &inputdata );
  39. DECLARE_DATADESC();
  40. protected:
  41. void Next( void );
  42. void Start( void );
  43. void Wait( void );
  44. void Stop( void );
  45. private:
  46. bool m_on;
  47. EHANDLE m_hTargetEnt;
  48. // Outputs
  49. COutputEvent m_OnDeath;
  50. };
  51. LINK_ENTITY_TO_CLASS( func_guntarget, CGunTarget );
  52. BEGIN_DATADESC( CGunTarget )
  53. DEFINE_FIELD( m_on, FIELD_BOOLEAN ),
  54. DEFINE_FIELD( m_hTargetEnt, FIELD_EHANDLE ),
  55. // Function Pointers
  56. DEFINE_FUNCTION( Next ),
  57. DEFINE_FUNCTION( Start ),
  58. DEFINE_FUNCTION( Wait ),
  59. // Inputs
  60. DEFINE_INPUTFUNC( FIELD_VOID, "Start", InputStart ),
  61. DEFINE_INPUTFUNC( FIELD_VOID, "Stop", InputStop ),
  62. DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ),
  63. // Outputs
  64. DEFINE_OUTPUT(m_OnDeath, "OnDeath"),
  65. END_DATADESC()
  66. void CGunTarget::Spawn( void )
  67. {
  68. SetSolid( SOLID_BSP );
  69. SetMoveType( MOVETYPE_PUSH );
  70. SetModel( STRING( GetModelName() ) );
  71. if ( m_flSpeed == 0 )
  72. m_flSpeed = 100;
  73. // Don't take damage until "on"
  74. m_takedamage = DAMAGE_NO;
  75. AddFlag( FL_NPC );
  76. m_on = false;
  77. m_iMaxHealth = m_iHealth;
  78. if ( HasSpawnFlags(FGUNTARGET_START_ON) )
  79. {
  80. SetMoveDone( &CGunTarget::Start );
  81. SetMoveDoneTime( 0.3 );
  82. }
  83. CreateVPhysics();
  84. }
  85. bool CGunTarget::CreateVPhysics( void )
  86. {
  87. VPhysicsInitShadow( false, false );
  88. return true;
  89. }
  90. void CGunTarget::Activate( void )
  91. {
  92. BaseClass::Activate();
  93. CBaseEntity *pTarg;
  94. // now find our next target
  95. pTarg = GetNextTarget();
  96. if ( pTarg )
  97. {
  98. m_hTargetEnt = pTarg;
  99. Vector nextPos = pTarg->GetAbsOrigin();
  100. Teleport( &nextPos, NULL, NULL );
  101. }
  102. }
  103. void CGunTarget::Start( void )
  104. {
  105. m_takedamage = DAMAGE_YES;
  106. AddFlag( FL_AIMTARGET );
  107. m_hTargetEnt = GetNextTarget();
  108. if ( m_hTargetEnt == NULL )
  109. return;
  110. m_iHealth = m_iMaxHealth;
  111. Next();
  112. }
  113. void CGunTarget::Next( void )
  114. {
  115. SetThink( NULL );
  116. m_hTargetEnt = GetNextTarget();
  117. CBaseEntity *pTarget = m_hTargetEnt;
  118. if ( !pTarget )
  119. {
  120. Stop();
  121. return;
  122. }
  123. SetMoveDone( &CGunTarget::Wait );
  124. LinearMove( pTarget->GetLocalOrigin(), m_flSpeed );
  125. }
  126. void CGunTarget::Wait( void )
  127. {
  128. CBaseEntity *pTarget = m_hTargetEnt;
  129. if ( !pTarget )
  130. {
  131. Stop();
  132. return;
  133. }
  134. variant_t emptyVariant;
  135. pTarget->AcceptInput( "InPass", this, this, emptyVariant, 0 );
  136. m_flWait = pTarget->GetDelay();
  137. m_target = pTarget->m_target;
  138. SetMoveDone( &CGunTarget::Next );
  139. if (m_flWait != 0)
  140. {// -1 wait will wait forever!
  141. SetMoveDoneTime( m_flWait );
  142. }
  143. else
  144. {
  145. Next();// do it RIGHT now!
  146. }
  147. }
  148. void CGunTarget::Stop( void )
  149. {
  150. SetAbsVelocity( vec3_origin );
  151. SetMoveDoneTime( -1 );
  152. m_takedamage = DAMAGE_NO;
  153. }
  154. int CGunTarget::OnTakeDamage( const CTakeDamageInfo &info )
  155. {
  156. if ( m_iHealth > 0 )
  157. {
  158. m_iHealth -= info.GetDamage();
  159. if ( m_iHealth <= 0 )
  160. {
  161. m_iHealth = 0;
  162. Stop();
  163. m_OnDeath.FireOutput( info.GetInflictor(), this );
  164. }
  165. }
  166. return 0;
  167. }
  168. //-----------------------------------------------------------------------------
  169. // Purpose: Input handler that starts the target moving.
  170. //-----------------------------------------------------------------------------
  171. void CGunTarget::InputStart( inputdata_t &inputdata )
  172. {
  173. Start();
  174. }
  175. //-----------------------------------------------------------------------------
  176. // Purpose: Input handler that stops the target from moving.
  177. //-----------------------------------------------------------------------------
  178. void CGunTarget::InputStop( inputdata_t &inputdata )
  179. {
  180. Stop();
  181. }
  182. //-----------------------------------------------------------------------------
  183. // Purpose: Input handler that toggles the start/stop state of the target.
  184. //-----------------------------------------------------------------------------
  185. void CGunTarget::InputToggle( inputdata_t &inputdata )
  186. {
  187. if ( m_on )
  188. {
  189. Stop();
  190. }
  191. else
  192. {
  193. Start();
  194. }
  195. }