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.

203 lines
5.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Dynamic light.
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "dlight.h"
  9. // memdbgon must be the last include file in a .cpp file!!!
  10. #include "tier0/memdbgon.h"
  11. #define NUM_DL_EXPONENT_BITS 8
  12. #define MIN_DL_EXPONENT_VALUE -((1 << (NUM_DL_EXPONENT_BITS-1)) - 1)
  13. #define MAX_DL_EXPONENT_VALUE ((1 << (NUM_DL_EXPONENT_BITS-1)) - 1)
  14. class CDynamicLight : public CBaseEntity
  15. {
  16. public:
  17. DECLARE_CLASS( CDynamicLight, CBaseEntity );
  18. void Spawn( void );
  19. void DynamicLightThink( void );
  20. bool KeyValue( const char *szKeyName, const char *szValue );
  21. DECLARE_SERVERCLASS();
  22. DECLARE_DATADESC();
  23. // Turn on and off the light
  24. void InputTurnOn( inputdata_t &inputdata );
  25. void InputTurnOff( inputdata_t &inputdata );
  26. void InputToggle( inputdata_t &inputdata );
  27. public:
  28. unsigned char m_ActualFlags;
  29. CNetworkVar( unsigned char, m_Flags );
  30. CNetworkVar( unsigned char, m_LightStyle );
  31. bool m_On;
  32. CNetworkVar( float, m_Radius );
  33. CNetworkVar( int, m_Exponent );
  34. CNetworkVar( float, m_InnerAngle );
  35. CNetworkVar( float, m_OuterAngle );
  36. CNetworkVar( float, m_SpotRadius );
  37. };
  38. LINK_ENTITY_TO_CLASS(light_dynamic, CDynamicLight);
  39. BEGIN_DATADESC( CDynamicLight )
  40. DEFINE_FIELD( m_ActualFlags, FIELD_CHARACTER ),
  41. DEFINE_FIELD( m_Flags, FIELD_CHARACTER ),
  42. DEFINE_FIELD( m_On, FIELD_BOOLEAN ),
  43. DEFINE_THINKFUNC( DynamicLightThink ),
  44. // Inputs
  45. DEFINE_INPUT( m_Radius, FIELD_FLOAT, "distance" ),
  46. DEFINE_INPUT( m_Exponent, FIELD_INTEGER, "brightness" ),
  47. DEFINE_INPUT( m_InnerAngle, FIELD_FLOAT, "_inner_cone" ),
  48. DEFINE_INPUT( m_OuterAngle, FIELD_FLOAT, "_cone" ),
  49. DEFINE_INPUT( m_SpotRadius, FIELD_FLOAT, "spotlight_radius" ),
  50. DEFINE_INPUT( m_LightStyle, FIELD_CHARACTER,"style" ),
  51. // Input functions
  52. DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ),
  53. DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ),
  54. DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ),
  55. END_DATADESC()
  56. IMPLEMENT_SERVERCLASS_ST(CDynamicLight, DT_DynamicLight)
  57. SendPropInt( SENDINFO(m_Flags), 4, SPROP_UNSIGNED ),
  58. SendPropInt( SENDINFO(m_LightStyle), 4, SPROP_UNSIGNED ),
  59. SendPropFloat( SENDINFO(m_Radius), 0, SPROP_NOSCALE),
  60. SendPropInt( SENDINFO(m_Exponent), NUM_DL_EXPONENT_BITS),
  61. SendPropFloat( SENDINFO(m_InnerAngle), 8, 0, 0.0, 360.0f ),
  62. SendPropFloat( SENDINFO(m_OuterAngle), 8, 0, 0.0, 360.0f ),
  63. SendPropFloat( SENDINFO(m_SpotRadius), 0, SPROP_NOSCALE),
  64. END_SEND_TABLE()
  65. //-----------------------------------------------------------------------------
  66. // Purpose:
  67. //-----------------------------------------------------------------------------
  68. bool CDynamicLight::KeyValue( const char *szKeyName, const char *szValue )
  69. {
  70. if ( FStrEq( szKeyName, "_light" ) )
  71. {
  72. color32 tmp;
  73. UTIL_StringToColor32( &tmp, szValue );
  74. SetRenderColor( tmp.r, tmp.g, tmp.b );
  75. }
  76. else if ( FStrEq( szKeyName, "pitch" ) )
  77. {
  78. float angle = atof(szValue);
  79. if ( angle )
  80. {
  81. QAngle angles = GetAbsAngles();
  82. angles[PITCH] = -angle;
  83. SetAbsAngles( angles );
  84. }
  85. }
  86. else if ( FStrEq( szKeyName, "spawnflags" ) )
  87. {
  88. m_ActualFlags = m_Flags = atoi(szValue);
  89. }
  90. else
  91. {
  92. return BaseClass::KeyValue( szKeyName, szValue );
  93. }
  94. return true;
  95. }
  96. //------------------------------------------------------------------------------
  97. // Turn on and off the light
  98. //------------------------------------------------------------------------------
  99. void CDynamicLight::InputTurnOn( inputdata_t &inputdata )
  100. {
  101. m_Flags = m_ActualFlags;
  102. m_On = true;
  103. }
  104. //-----------------------------------------------------------------------------
  105. // Purpose:
  106. // Input : &inputdata -
  107. //-----------------------------------------------------------------------------
  108. void CDynamicLight::InputTurnOff( inputdata_t &inputdata )
  109. {
  110. // This basically shuts it off
  111. m_Flags = DLIGHT_NO_MODEL_ILLUMINATION | DLIGHT_NO_WORLD_ILLUMINATION;
  112. m_On = false;
  113. }
  114. //-----------------------------------------------------------------------------
  115. // Purpose:
  116. // Input : &inputdata -
  117. //-----------------------------------------------------------------------------
  118. void CDynamicLight::InputToggle( inputdata_t &inputdata )
  119. {
  120. if (m_On)
  121. {
  122. InputTurnOff( inputdata );
  123. }
  124. else
  125. {
  126. InputTurnOn( inputdata );
  127. }
  128. }
  129. //------------------------------------------------------------------------------
  130. // Purpose :
  131. //------------------------------------------------------------------------------
  132. void CDynamicLight::Spawn( void )
  133. {
  134. Precache();
  135. SetSolid( SOLID_NONE );
  136. m_On = true;
  137. UTIL_SetSize( this, vec3_origin, vec3_origin );
  138. AddEFlags( EFL_FORCE_CHECK_TRANSMIT );
  139. // If we have a target, think so we can orient towards it
  140. if ( m_target != NULL_STRING )
  141. {
  142. SetThink( &CDynamicLight::DynamicLightThink );
  143. SetNextThink( gpGlobals->curtime + 0.1 );
  144. }
  145. int clampedExponent = clamp( (int) m_Exponent, MIN_DL_EXPONENT_VALUE, MAX_DL_EXPONENT_VALUE );
  146. if ( m_Exponent != clampedExponent )
  147. {
  148. Warning( "light_dynamic at [%d %d %d] has invalid exponent value (%d must be between %d and %d).\n",
  149. (int)GetAbsOrigin().x, (int)GetAbsOrigin().x, (int)GetAbsOrigin().x,
  150. m_Exponent.Get(),
  151. MIN_DL_EXPONENT_VALUE,
  152. MAX_DL_EXPONENT_VALUE );
  153. m_Exponent = clampedExponent;
  154. }
  155. }
  156. //-----------------------------------------------------------------------------
  157. // Purpose:
  158. //-----------------------------------------------------------------------------
  159. void CDynamicLight::DynamicLightThink( void )
  160. {
  161. if ( m_target == NULL_STRING )
  162. return;
  163. CBaseEntity *pEntity = GetNextTarget();
  164. if ( pEntity )
  165. {
  166. Vector vecToTarget = (pEntity->GetAbsOrigin() - GetAbsOrigin());
  167. QAngle vecAngles;
  168. VectorAngles( vecToTarget, vecAngles );
  169. SetAbsAngles( vecAngles );
  170. }
  171. SetNextThink( gpGlobals->curtime + 0.1 );
  172. }