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.

384 lines
9.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "gamerules.h"
  8. #include "player.h"
  9. #include "items.h"
  10. #include "engine/IEngineSound.h"
  11. #include "hl1_items.h"
  12. #include "in_buttons.h"
  13. ConVar sk_healthkit( "sk_healthkit","0" );
  14. ConVar sk_healthvial( "sk_healthvial","0" );
  15. ConVar sk_healthcharger( "sk_healthcharger","0" );
  16. //-----------------------------------------------------------------------------
  17. // Small health kit. Heals the player when picked up.
  18. //-----------------------------------------------------------------------------
  19. class CHealthKit : public CHL1Item
  20. {
  21. public:
  22. DECLARE_CLASS( CHealthKit, CHL1Item );
  23. void Spawn( void );
  24. void Precache( void );
  25. bool MyTouch( CBasePlayer *pPlayer );
  26. };
  27. LINK_ENTITY_TO_CLASS( item_healthkit, CHealthKit );
  28. PRECACHE_REGISTER(item_healthkit);
  29. //-----------------------------------------------------------------------------
  30. // Purpose:
  31. //-----------------------------------------------------------------------------
  32. void CHealthKit::Spawn( void )
  33. {
  34. Precache();
  35. SetModel( "models/w_medkit.mdl" );
  36. BaseClass::Spawn();
  37. }
  38. //-----------------------------------------------------------------------------
  39. // Purpose:
  40. //-----------------------------------------------------------------------------
  41. void CHealthKit::Precache( void )
  42. {
  43. PrecacheModel("models/w_medkit.mdl");
  44. PrecacheScriptSound( "HealthKit.Touch" );
  45. }
  46. //-----------------------------------------------------------------------------
  47. // Purpose:
  48. // Input : *pPlayer -
  49. // Output :
  50. //-----------------------------------------------------------------------------
  51. bool CHealthKit::MyTouch( CBasePlayer *pPlayer )
  52. {
  53. if ( pPlayer->TakeHealth( sk_healthkit.GetFloat(), DMG_GENERIC ) )
  54. {
  55. CSingleUserRecipientFilter user( pPlayer );
  56. user.MakeReliable();
  57. UserMessageBegin( user, "ItemPickup" );
  58. WRITE_STRING( GetClassname() );
  59. MessageEnd();
  60. CPASAttenuationFilter filter( pPlayer, "HealthKit.Touch" );
  61. EmitSound( filter, pPlayer->entindex(), "HealthKit.Touch" );
  62. if ( g_pGameRules->ItemShouldRespawn( this ) )
  63. {
  64. Respawn();
  65. }
  66. else
  67. {
  68. UTIL_Remove(this);
  69. }
  70. return true;
  71. }
  72. return false;
  73. }
  74. //-----------------------------------------------------------------------------
  75. // Small dynamically dropped health kit
  76. //-----------------------------------------------------------------------------
  77. class CHealthVial : public CHL1Item
  78. {
  79. public:
  80. DECLARE_CLASS( CHealthVial, CHL1Item );
  81. void Spawn( void )
  82. {
  83. Precache();
  84. SetModel( "models/healthvial.mdl" );
  85. BaseClass::Spawn();
  86. }
  87. void Precache( void )
  88. {
  89. PrecacheModel("models/healthvial.mdl");
  90. PrecacheScriptSound( "HealthVial.Touch" );
  91. }
  92. bool MyTouch( CBasePlayer *pPlayer )
  93. {
  94. if ( pPlayer->TakeHealth( sk_healthvial.GetFloat(), DMG_GENERIC ) )
  95. {
  96. CSingleUserRecipientFilter user( pPlayer );
  97. user.MakeReliable();
  98. UserMessageBegin( user, "ItemPickup" );
  99. WRITE_STRING( GetClassname() );
  100. MessageEnd();
  101. CPASAttenuationFilter filter( pPlayer, "HealthVial.Touch" );
  102. EmitSound( filter, pPlayer->entindex(), "HealthVial.Touch" );
  103. if ( g_pGameRules->ItemShouldRespawn( this ) )
  104. {
  105. Respawn();
  106. }
  107. else
  108. {
  109. UTIL_Remove(this);
  110. }
  111. return true;
  112. }
  113. return false;
  114. }
  115. };
  116. LINK_ENTITY_TO_CLASS( item_healthvial, CHealthVial );
  117. PRECACHE_REGISTER( item_healthvial );
  118. //-----------------------------------------------------------------------------
  119. // Wall mounted health kit. Heals the player when used.
  120. //-----------------------------------------------------------------------------
  121. class CWallHealth : public CBaseToggle
  122. {
  123. public:
  124. DECLARE_CLASS( CWallHealth, CBaseToggle );
  125. void Spawn( );
  126. void Precache( void );
  127. bool CreateVPhysics(void);
  128. void Off(void);
  129. void Recharge(void);
  130. bool KeyValue( const char *szKeyName, const char *szValue );
  131. void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
  132. virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() | m_iCaps; }
  133. float m_flNextCharge;
  134. int m_iReactivate ; // DeathMatch Delay until reactvated
  135. int m_iJuice;
  136. int m_iOn; // 0 = off, 1 = startup, 2 = going
  137. float m_flSoundTime;
  138. int m_iCaps;
  139. DECLARE_DATADESC();
  140. };
  141. LINK_ENTITY_TO_CLASS(func_healthcharger, CWallHealth);
  142. BEGIN_DATADESC( CWallHealth )
  143. DEFINE_FIELD( m_flNextCharge, FIELD_TIME),
  144. DEFINE_FIELD( m_iReactivate, FIELD_INTEGER),
  145. DEFINE_FIELD( m_iJuice, FIELD_INTEGER),
  146. DEFINE_FIELD( m_iOn, FIELD_INTEGER),
  147. DEFINE_FIELD( m_flSoundTime, FIELD_TIME),
  148. DEFINE_FIELD( m_iCaps, FIELD_INTEGER ),
  149. // Function Pointers
  150. DEFINE_FUNCTION( Off ),
  151. DEFINE_FUNCTION( Recharge ),
  152. END_DATADESC()
  153. //-----------------------------------------------------------------------------
  154. // Purpose:
  155. // Input : *pkvd -
  156. //-----------------------------------------------------------------------------
  157. bool CWallHealth::KeyValue( const char *szKeyName, const char *szValue )
  158. {
  159. if (FStrEq(szKeyName, "style") ||
  160. FStrEq(szKeyName, "height") ||
  161. FStrEq(szKeyName, "value1") ||
  162. FStrEq(szKeyName, "value2") ||
  163. FStrEq(szKeyName, "value3"))
  164. {
  165. return(true);
  166. }
  167. else if (FStrEq(szKeyName, "dmdelay"))
  168. {
  169. m_iReactivate = atoi(szValue);
  170. return(true);
  171. }
  172. return(BaseClass::KeyValue( szKeyName, szValue ));
  173. }
  174. //-----------------------------------------------------------------------------
  175. // Purpose:
  176. //-----------------------------------------------------------------------------
  177. void CWallHealth::Spawn(void)
  178. {
  179. Precache( );
  180. SetSolid( SOLID_BSP );
  181. SetMoveType( MOVETYPE_PUSH );
  182. SetModel( STRING( GetModelName() ) );
  183. m_iJuice = sk_healthcharger.GetFloat();
  184. SetTextureFrameIndex( 0 );
  185. m_iCaps = FCAP_CONTINUOUS_USE;
  186. CreateVPhysics();
  187. }
  188. //-----------------------------------------------------------------------------
  189. bool CWallHealth::CreateVPhysics(void)
  190. {
  191. VPhysicsInitStatic();
  192. return true;
  193. }
  194. //-----------------------------------------------------------------------------
  195. // Purpose:
  196. //-----------------------------------------------------------------------------
  197. void CWallHealth::Precache(void)
  198. {
  199. PrecacheScriptSound( "WallHealth.Deny" );
  200. PrecacheScriptSound( "WallHealth.Start" );
  201. PrecacheScriptSound( "WallHealth.LoopingContinueCharge" );
  202. PrecacheScriptSound( "WallHealth.Recharge" );
  203. }
  204. //-----------------------------------------------------------------------------
  205. // Purpose:
  206. // Input : *pActivator -
  207. // *pCaller -
  208. // useType -
  209. // value -
  210. //-----------------------------------------------------------------------------
  211. void CWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
  212. {
  213. // Make sure that we have a caller
  214. if (!pActivator)
  215. return;
  216. // if it's not a player, ignore
  217. if ( !pActivator->IsPlayer() )
  218. return;
  219. // Reset to a state of continuous use.
  220. m_iCaps = FCAP_CONTINUOUS_USE;
  221. // if there is no juice left, turn it off
  222. if (m_iJuice <= 0)
  223. {
  224. Off();
  225. SetTextureFrameIndex( 1 );
  226. }
  227. CBasePlayer *pPlayer = ToBasePlayer( pActivator );
  228. // if the player doesn't have the suit, or there is no juice left, make the deny noise.
  229. if ((m_iJuice <= 0) || (!(pPlayer->m_Local.m_bWearingSuit)))
  230. {
  231. if (m_flSoundTime <= gpGlobals->curtime)
  232. {
  233. m_flSoundTime = gpGlobals->curtime + 0.62;
  234. EmitSound( "WallHealth.Deny" );
  235. }
  236. return;
  237. }
  238. if( pActivator->GetHealth() >= pActivator->GetMaxHealth() )
  239. {
  240. CBasePlayer *pPlayer = dynamic_cast<CBasePlayer *>(pActivator);
  241. if( pPlayer )
  242. {
  243. pPlayer->m_afButtonPressed &= ~IN_USE;
  244. }
  245. // Make the user re-use me to get started drawing health.
  246. m_iCaps = FCAP_IMPULSE_USE;
  247. EmitSound( "WallHealth.Deny" );
  248. return;
  249. }
  250. SetNextThink( gpGlobals->curtime + 0.25 );
  251. SetThink(&CWallHealth::Off);
  252. // Time to recharge yet?
  253. if (m_flNextCharge >= gpGlobals->curtime)
  254. return;
  255. // Play the on sound or the looping charging sound
  256. if (!m_iOn)
  257. {
  258. m_iOn++;
  259. EmitSound( "WallHealth.Start" );
  260. m_flSoundTime = 0.56 + gpGlobals->curtime;
  261. }
  262. if ((m_iOn == 1) && (m_flSoundTime <= gpGlobals->curtime))
  263. {
  264. m_iOn++;
  265. CPASAttenuationFilter filter( this, "WallHealth.LoopingContinueCharge" );
  266. filter.MakeReliable();
  267. EmitSound( filter, entindex(), "WallHealth.LoopingContinueCharge" );
  268. }
  269. // charge the player
  270. if ( pActivator->TakeHealth( 1, DMG_GENERIC ) )
  271. {
  272. m_iJuice--;
  273. }
  274. // govern the rate of charge
  275. m_flNextCharge = gpGlobals->curtime + 0.1;
  276. }
  277. //-----------------------------------------------------------------------------
  278. // Purpose:
  279. //-----------------------------------------------------------------------------
  280. void CWallHealth::Recharge(void)
  281. {
  282. EmitSound( "WallHealth.Recharge" );
  283. m_iJuice = sk_healthcharger.GetFloat();
  284. SetTextureFrameIndex( 0 );
  285. SetThink( NULL );
  286. }
  287. //-----------------------------------------------------------------------------
  288. // Purpose:
  289. //-----------------------------------------------------------------------------
  290. void CWallHealth::Off(void)
  291. {
  292. // Stop looping sound.
  293. if (m_iOn > 1)
  294. StopSound( "WallHealth.LoopingContinueCharge" );
  295. m_iOn = 0;
  296. if ((!m_iJuice) && ( ( m_iReactivate = g_pGameRules->FlHealthChargerRechargeTime() ) > 0) )
  297. {
  298. SetNextThink( gpGlobals->curtime + m_iReactivate );
  299. SetThink(&CWallHealth::Recharge);
  300. }
  301. else
  302. SetThink( NULL );
  303. }