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.

272 lines
7.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Alyx's EMP effect
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "env_alyxemp_shared.h"
  8. // memdbgon must be the last include file in a .cpp file!!!
  9. #include "tier0/memdbgon.h"
  10. #define EMP_BEAM_SPRITE "effects/laser1.vmt"
  11. LINK_ENTITY_TO_CLASS( env_alyxemp, CAlyxEmpEffect );
  12. BEGIN_DATADESC( CAlyxEmpEffect )
  13. DEFINE_KEYFIELD( m_nType, FIELD_INTEGER, "Type" ),
  14. DEFINE_KEYFIELD( m_strTargetName, FIELD_STRING, "EndTargetName" ),
  15. DEFINE_FIELD( m_nState, FIELD_INTEGER ),
  16. DEFINE_FIELD( m_flDuration, FIELD_FLOAT ),
  17. DEFINE_FIELD( m_flStartTime, FIELD_TIME ),
  18. DEFINE_FIELD( m_hTargetEnt, FIELD_EHANDLE ),
  19. DEFINE_FIELD( m_hBeam, FIELD_EHANDLE ),
  20. DEFINE_FIELD( m_iState, FIELD_INTEGER ),
  21. DEFINE_FIELD( m_bAutomated, FIELD_BOOLEAN ),
  22. DEFINE_THINKFUNC( AutomaticThink ),
  23. DEFINE_INPUTFUNC( FIELD_FLOAT, "StartCharge", InputStartCharge ),
  24. DEFINE_INPUTFUNC( FIELD_VOID, "StartDischarge", InputStartDischarge ),
  25. DEFINE_INPUTFUNC( FIELD_FLOAT, "Stop", InputStop ),
  26. DEFINE_INPUTFUNC( FIELD_STRING, "SetTargetEnt", InputSetTargetEnt ),
  27. END_DATADESC()
  28. IMPLEMENT_SERVERCLASS_ST( CAlyxEmpEffect, DT_AlyxEmpEffect )
  29. SendPropInt( SENDINFO(m_nState), 8, SPROP_UNSIGNED),
  30. SendPropFloat( SENDINFO(m_flDuration), 0, SPROP_NOSCALE),
  31. SendPropFloat( SENDINFO(m_flStartTime), 0, SPROP_NOSCALE),
  32. END_SEND_TABLE()
  33. //-----------------------------------------------------------------------------
  34. // Purpose:
  35. //-----------------------------------------------------------------------------
  36. void CAlyxEmpEffect::Spawn( void )
  37. {
  38. Precache();
  39. // No model but we still need to force this!
  40. AddEFlags( EFL_FORCE_CHECK_TRANSMIT );
  41. // No shadows
  42. AddEffects( EF_NOSHADOW | EF_NORECEIVESHADOW );
  43. }
  44. //-----------------------------------------------------------------------------
  45. // Purpose:
  46. //-----------------------------------------------------------------------------
  47. void CAlyxEmpEffect::Activate( void )
  48. {
  49. // Start out with a target entity
  50. SetTargetEntity( STRING(m_strTargetName) );
  51. BaseClass::Activate();
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Purpose:
  55. // Input : *szEntityName -
  56. //-----------------------------------------------------------------------------
  57. void CAlyxEmpEffect::SetTargetEntity( const char *szEntityName )
  58. {
  59. // Find and store off our target entity
  60. CBaseEntity *pTargetEnt = NULL;
  61. if ( szEntityName && szEntityName[0] )
  62. {
  63. pTargetEnt = gEntList.FindEntityByName( NULL, szEntityName );
  64. if ( pTargetEnt == NULL )
  65. {
  66. Assert(0);
  67. DevMsg( "Unable to find env_alyxemp (%s) target %s!\n", GetEntityName().ToCStr(), szEntityName );
  68. }
  69. }
  70. SetTargetEntity( pTargetEnt );
  71. }
  72. //-----------------------------------------------------------------------------
  73. // Passing NULL is ok!
  74. //-----------------------------------------------------------------------------
  75. void CAlyxEmpEffect::SetTargetEntity( CBaseEntity *pTarget )
  76. {
  77. m_hTargetEnt.Set( pTarget );
  78. }
  79. //-----------------------------------------------------------------------------
  80. //
  81. //-----------------------------------------------------------------------------
  82. void CAlyxEmpEffect::ActivateAutomatic( CBaseEntity *pAlyx, CBaseEntity *pTarget )
  83. {
  84. Assert( pAlyx->GetBaseAnimating() != NULL );
  85. SetParent( pAlyx, pAlyx->GetBaseAnimating()->LookupAttachment("LeftHand") );
  86. SetLocalOrigin( vec3_origin );
  87. m_iState = ALYXEMP_STATE_OFF;
  88. SetTargetEntity( pTarget );
  89. SetThink( &CAlyxEmpEffect::AutomaticThink );
  90. SetNextThink( gpGlobals->curtime );
  91. m_bAutomated = true;
  92. }
  93. //-----------------------------------------------------------------------------
  94. //-----------------------------------------------------------------------------
  95. void CAlyxEmpEffect::AutomaticThink()
  96. {
  97. bool bSetNextThink = true;
  98. switch( m_iState )
  99. {
  100. case ALYXEMP_STATE_OFF:
  101. StartCharge( 0.05f );
  102. break;
  103. case ALYXEMP_STATE_CHARGING:
  104. StartDischarge();
  105. break;
  106. case ALYXEMP_STATE_DISCHARGING:
  107. Stop( 1.0f );
  108. bSetNextThink = false;
  109. break;
  110. }
  111. m_iState++;
  112. }
  113. //-----------------------------------------------------------------------------
  114. // Purpose:
  115. //-----------------------------------------------------------------------------
  116. void CAlyxEmpEffect::Precache( void )
  117. {
  118. PrecacheModel( EMP_BEAM_SPRITE );
  119. PrecacheScriptSound( "AlyxEmp.Charge" );
  120. PrecacheScriptSound( "AlyxEmp.Discharge" );
  121. PrecacheScriptSound( "AlyxEmp.Stop" );
  122. }
  123. //-----------------------------------------------------------------------------
  124. // Purpose:
  125. // Input : &inputdata -
  126. //-----------------------------------------------------------------------------
  127. void CAlyxEmpEffect::InputStartCharge( inputdata_t &inputdata )
  128. {
  129. StartCharge( inputdata.value.Float() );
  130. }
  131. //-----------------------------------------------------------------------------
  132. //-----------------------------------------------------------------------------
  133. void CAlyxEmpEffect::StartCharge( float flDuration )
  134. {
  135. EmitSound( "AlyxEmp.Charge" );
  136. m_nState = (int)ALYXEMP_STATE_CHARGING;
  137. m_flDuration = flDuration;
  138. m_flStartTime = gpGlobals->curtime;
  139. if( m_bAutomated )
  140. {
  141. SetNextThink( gpGlobals->curtime + m_flDuration );
  142. }
  143. }
  144. //-----------------------------------------------------------------------------
  145. // Purpose:
  146. // Input : &inputdata -
  147. //-----------------------------------------------------------------------------
  148. void CAlyxEmpEffect::InputStartDischarge( inputdata_t &inputdata )
  149. {
  150. StartDischarge();
  151. }
  152. void CAlyxEmpEffect::StartDischarge()
  153. {
  154. EmitSound( "AlyxEmp.Discharge" );
  155. m_nState = (int)ALYXEMP_STATE_DISCHARGING;
  156. m_flStartTime = gpGlobals->curtime;
  157. // Beam effects on the target entity!
  158. if ( !m_hBeam && m_hTargetEnt )
  159. {
  160. // Check to store off our view model index
  161. m_hBeam = CBeam::BeamCreate( EMP_BEAM_SPRITE, 8 );
  162. if ( m_hBeam != NULL )
  163. {
  164. m_hBeam->PointEntInit( m_hTargetEnt->GetAbsOrigin(), this );
  165. m_hBeam->SetStartEntity( m_hTargetEnt );
  166. m_hBeam->SetWidth( 4 );
  167. m_hBeam->SetEndWidth( 8 );
  168. m_hBeam->SetBrightness( 255 );
  169. m_hBeam->SetColor( 255, 255, 255 );
  170. m_hBeam->LiveForTime( 999.0f );
  171. m_hBeam->RelinkBeam();
  172. m_hBeam->SetNoise( 16 );
  173. }
  174. // End hit
  175. Vector shotDir = ( GetAbsOrigin() - m_hTargetEnt->GetAbsOrigin() );
  176. VectorNormalize( shotDir );
  177. CPVSFilter filter( m_hTargetEnt->GetAbsOrigin() );
  178. te->GaussExplosion( filter, 0.0f, m_hTargetEnt->GetAbsOrigin() - ( shotDir * 4.0f ), RandomVector(-1.0f, 1.0f), 0 );
  179. }
  180. if( m_bAutomated )
  181. {
  182. SetNextThink( gpGlobals->curtime + 0.5f );
  183. }
  184. }
  185. //-----------------------------------------------------------------------------
  186. // Purpose:
  187. // Input : &inputdata -
  188. //-----------------------------------------------------------------------------
  189. void CAlyxEmpEffect::InputStop( inputdata_t &inputdata )
  190. {
  191. float flDuration = inputdata.value.Float();
  192. Stop( flDuration );
  193. }
  194. //-----------------------------------------------------------------------------
  195. //-----------------------------------------------------------------------------
  196. void CAlyxEmpEffect::Stop( float flDuration )
  197. {
  198. EmitSound( "AlyxEmp.Stop" );
  199. m_nState = (int)ALYXEMP_STATE_OFF;
  200. m_flDuration = flDuration;
  201. m_flStartTime = gpGlobals->curtime;
  202. if ( m_hBeam != NULL )
  203. {
  204. UTIL_Remove( m_hBeam );
  205. m_hBeam = NULL;
  206. }
  207. if( m_bAutomated )
  208. {
  209. SetThink( &CAlyxEmpEffect::SUB_Remove );
  210. SetNextThink( gpGlobals->curtime + flDuration + 1.0f );
  211. }
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Purpose:
  215. // Input : &inputdata -
  216. //-----------------------------------------------------------------------------
  217. void CAlyxEmpEffect::InputSetTargetEnt( inputdata_t &inputdata )
  218. {
  219. SetTargetEntity( inputdata.value.String() );
  220. }