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.

365 lines
12 KiB

  1. //====== Copyright � 1996-2009, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose: Projects a texture into the world (like the flashlight)
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include "shareddefs.h"
  8. #include "env_projectedtexture.h"
  9. #include "world.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include "tier0/memdbgon.h"
  12. LINK_ENTITY_TO_CLASS( env_projectedtexture, CEnvProjectedTexture );
  13. BEGIN_DATADESC( CEnvProjectedTexture )
  14. DEFINE_FIELD( m_hTargetEntity, FIELD_EHANDLE ),
  15. DEFINE_FIELD( m_bState, FIELD_BOOLEAN ),
  16. DEFINE_FIELD( m_bAlwaysUpdate, FIELD_BOOLEAN ),
  17. DEFINE_FIELD( m_bSimpleProjection, FIELD_BOOLEAN ),
  18. DEFINE_KEYFIELD( m_flLightFOV, FIELD_FLOAT, "lightfov" ),
  19. DEFINE_KEYFIELD( m_bEnableShadows, FIELD_BOOLEAN, "enableshadows" ),
  20. DEFINE_KEYFIELD( m_bSimpleProjection, FIELD_BOOLEAN, "simpleprojection" ),
  21. DEFINE_KEYFIELD( m_bLightOnlyTarget, FIELD_BOOLEAN, "lightonlytarget" ),
  22. DEFINE_KEYFIELD( m_bLightWorld, FIELD_BOOLEAN, "lightworld" ),
  23. DEFINE_KEYFIELD( m_bCameraSpace, FIELD_BOOLEAN, "cameraspace" ),
  24. DEFINE_KEYFIELD( m_flAmbient, FIELD_FLOAT, "ambient" ),
  25. DEFINE_AUTO_ARRAY_KEYFIELD( m_SpotlightTextureName, FIELD_CHARACTER, "texturename" ),
  26. DEFINE_KEYFIELD( m_nSpotlightTextureFrame, FIELD_INTEGER, "textureframe" ),
  27. DEFINE_KEYFIELD( m_flNearZ, FIELD_FLOAT, "nearz" ),
  28. DEFINE_KEYFIELD( m_flFarZ, FIELD_FLOAT, "farz" ),
  29. DEFINE_KEYFIELD( m_nShadowQuality, FIELD_INTEGER, "shadowquality" ),
  30. DEFINE_KEYFIELD( m_flBrightnessScale, FIELD_FLOAT, "brightnessscale" ),
  31. DEFINE_FIELD( m_LightColor, FIELD_COLOR32 ),
  32. DEFINE_KEYFIELD( m_flColorTransitionTime, FIELD_FLOAT, "colortransitiontime" ),
  33. DEFINE_KEYFIELD( m_flProjectionSize, FIELD_FLOAT, "projection_size" ),
  34. DEFINE_KEYFIELD( m_flRotation, FIELD_FLOAT, "projection_rotation" ),
  35. DEFINE_KEYFIELD( m_iStyle, FIELD_INTEGER, "style" ),
  36. DEFINE_KEYFIELD( m_iDefaultStyle, FIELD_INTEGER, "defaultstyle" ),
  37. DEFINE_KEYFIELD( m_iszPattern, FIELD_STRING, "pattern" ),
  38. DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ),
  39. DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ),
  40. DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysUpdateOn", InputAlwaysUpdateOn ),
  41. DEFINE_INPUTFUNC( FIELD_VOID, "AlwaysUpdateOff", InputAlwaysUpdateOff ),
  42. DEFINE_INPUTFUNC( FIELD_FLOAT, "FOV", InputSetFOV ),
  43. DEFINE_INPUTFUNC( FIELD_EHANDLE, "Target", InputSetTarget ),
  44. DEFINE_INPUTFUNC( FIELD_BOOLEAN, "CameraSpace", InputSetCameraSpace ),
  45. DEFINE_INPUTFUNC( FIELD_BOOLEAN, "LightOnlyTarget", InputSetLightOnlyTarget ),
  46. DEFINE_INPUTFUNC( FIELD_BOOLEAN, "LightWorld", InputSetLightWorld ),
  47. DEFINE_INPUTFUNC( FIELD_BOOLEAN, "EnableShadows", InputSetEnableShadows ),
  48. DEFINE_INPUTFUNC( FIELD_COLOR32, "LightColor", InputSetLightColor ),
  49. DEFINE_INPUTFUNC( FIELD_FLOAT, "Ambient", InputSetAmbient ),
  50. DEFINE_INPUTFUNC( FIELD_STRING, "SpotlightTexture", InputSetSpotlightTexture ),
  51. DEFINE_INPUTFUNC( FIELD_INTEGER, "SetLightStyle", InputSetLightStyle ),
  52. DEFINE_INPUTFUNC( FIELD_STRING, "SetPattern", InputSetPattern ),
  53. DEFINE_INPUTFUNC( FIELD_FLOAT, "SetNearZ", InputSetNearZ ),
  54. DEFINE_INPUTFUNC( FIELD_FLOAT, "SetFarZ", InputSetFarZ ),
  55. DEFINE_THINKFUNC( InitialThink ),
  56. END_DATADESC()
  57. IMPLEMENT_SERVERCLASS_ST( CEnvProjectedTexture, DT_EnvProjectedTexture )
  58. SendPropEHandle( SENDINFO( m_hTargetEntity ) ),
  59. SendPropBool( SENDINFO( m_bState ) ),
  60. SendPropBool( SENDINFO( m_bAlwaysUpdate ) ),
  61. SendPropFloat( SENDINFO( m_flLightFOV ) ),
  62. SendPropBool( SENDINFO( m_bEnableShadows ) ),
  63. SendPropBool( SENDINFO( m_bSimpleProjection ) ),
  64. SendPropBool( SENDINFO( m_bLightOnlyTarget ) ),
  65. SendPropBool( SENDINFO( m_bLightWorld ) ),
  66. SendPropBool( SENDINFO( m_bCameraSpace ) ),
  67. SendPropFloat( SENDINFO( m_flBrightnessScale ) ),
  68. SendPropInt( SENDINFO ( m_LightColor ), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt32 ),
  69. SendPropFloat( SENDINFO( m_flColorTransitionTime ) ),
  70. SendPropFloat( SENDINFO( m_flAmbient ) ),
  71. SendPropString( SENDINFO( m_SpotlightTextureName ) ),
  72. SendPropInt( SENDINFO( m_nSpotlightTextureFrame ) ),
  73. SendPropFloat( SENDINFO( m_flNearZ ), 16, SPROP_ROUNDDOWN, 0.0f, 500.0f ),
  74. SendPropFloat( SENDINFO( m_flFarZ ), 18, SPROP_ROUNDDOWN, 0.0f, 2500.0f ),
  75. SendPropInt( SENDINFO( m_nShadowQuality ), 1, SPROP_UNSIGNED ), // Just one bit for now
  76. SendPropFloat( SENDINFO( m_flProjectionSize ) ),
  77. SendPropFloat( SENDINFO( m_flRotation ) ),
  78. SendPropInt( SENDINFO( m_iStyle ) ),
  79. END_SEND_TABLE()
  80. //-----------------------------------------------------------------------------
  81. // Purpose:
  82. //-----------------------------------------------------------------------------
  83. CEnvProjectedTexture::CEnvProjectedTexture( void )
  84. {
  85. m_bState = true;
  86. m_bAlwaysUpdate = false;
  87. m_flLightFOV = 45.0f;
  88. m_bEnableShadows = false;
  89. m_bSimpleProjection = false;
  90. m_bLightOnlyTarget = false;
  91. m_bLightWorld = true;
  92. m_bCameraSpace = false;
  93. Q_strcpy( m_SpotlightTextureName.GetForModify(), "effects/flashlight_border" );
  94. Q_strcpy( m_SpotlightTextureName.GetForModify(), "effects/flashlight001" );
  95. m_nSpotlightTextureFrame = 0;
  96. m_flBrightnessScale = 1.0f;
  97. m_LightColor.Init( 255, 255, 255, 255 );
  98. m_flColorTransitionTime = 0.5f;
  99. m_flAmbient = 0.0f;
  100. m_flNearZ = 4.0f;
  101. m_flFarZ = 750.0f;
  102. m_nShadowQuality = 0;
  103. m_flProjectionSize = 500.0f;
  104. m_flRotation = 0.0f;
  105. }
  106. void UTIL_ColorStringToLinearFloatColor( Vector &color, const char *pString )
  107. {
  108. float tmp[4];
  109. UTIL_StringToFloatArray( tmp, 4, pString );
  110. if( tmp[3] <= 0.0f )
  111. {
  112. tmp[3] = 255.0f;
  113. }
  114. tmp[3] *= ( 1.0f / 255.0f );
  115. color.x = tmp[0] * ( 1.0f / 255.0f ) * tmp[3];
  116. color.y = tmp[1] * ( 1.0f / 255.0f ) * tmp[3];
  117. color.z = tmp[2] * ( 1.0f / 255.0f ) * tmp[3];
  118. }
  119. bool CEnvProjectedTexture::KeyValue( const char *szKeyName, const char *szValue )
  120. {
  121. if ( FStrEq( szKeyName, "lightcolor" ) )
  122. {
  123. float tmp[4];
  124. UTIL_StringToFloatArray( tmp, 4, szValue );
  125. m_LightColor.SetR( tmp[0] );
  126. m_LightColor.SetG( tmp[1] );
  127. m_LightColor.SetB( tmp[2] );
  128. m_LightColor.SetA( tmp[3] );
  129. }
  130. else if ( FStrEq( szKeyName, "texturename" ) )
  131. {
  132. #if defined( _GAMECONSOLE )
  133. if ( Q_strcmp( szValue, "effects/flashlight001" ) == 0 )
  134. {
  135. // Use this as the default for Xbox
  136. Q_strcpy( m_SpotlightTextureName.GetForModify(), "effects/flashlight_border" );
  137. }
  138. else
  139. {
  140. Q_strcpy( m_SpotlightTextureName.GetForModify(), szValue );
  141. }
  142. #else
  143. Q_strcpy( m_SpotlightTextureName.GetForModify(), szValue );
  144. #endif
  145. }
  146. else
  147. {
  148. return BaseClass::KeyValue( szKeyName, szValue );
  149. }
  150. return true;
  151. }
  152. bool CEnvProjectedTexture::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen )
  153. {
  154. if ( FStrEq( szKeyName, "lightcolor" ) )
  155. {
  156. Q_snprintf( szValue, iMaxLen, "%d %d %d %d", m_LightColor.GetR(), m_LightColor.GetG(), m_LightColor.GetB(), m_LightColor.GetA() );
  157. return true;
  158. }
  159. else if ( FStrEq( szKeyName, "texturename" ) )
  160. {
  161. Q_snprintf( szValue, iMaxLen, "%s", m_SpotlightTextureName.Get() );
  162. return true;
  163. }
  164. return BaseClass::GetKeyValue( szKeyName, szValue, iMaxLen );
  165. }
  166. void CEnvProjectedTexture::InputTurnOn( inputdata_t &inputdata )
  167. {
  168. // Force all other projected textures off
  169. EnforceSingleProjectionRules();
  170. m_bState = true;
  171. }
  172. void CEnvProjectedTexture::InputTurnOff( inputdata_t &inputdata )
  173. {
  174. m_bState = false;
  175. }
  176. void CEnvProjectedTexture::InputAlwaysUpdateOn( inputdata_t &inputdata )
  177. {
  178. m_bAlwaysUpdate = true;
  179. }
  180. void CEnvProjectedTexture::InputAlwaysUpdateOff( inputdata_t &inputdata )
  181. {
  182. m_bAlwaysUpdate = false;
  183. }
  184. void CEnvProjectedTexture::InputSetFOV( inputdata_t &inputdata )
  185. {
  186. m_flLightFOV = inputdata.value.Float();
  187. }
  188. void CEnvProjectedTexture::InputSetTarget( inputdata_t &inputdata )
  189. {
  190. m_hTargetEntity = inputdata.value.Entity();
  191. }
  192. void CEnvProjectedTexture::InputSetCameraSpace( inputdata_t &inputdata )
  193. {
  194. m_bCameraSpace = inputdata.value.Bool();
  195. }
  196. void CEnvProjectedTexture::InputSetLightOnlyTarget( inputdata_t &inputdata )
  197. {
  198. m_bLightOnlyTarget = inputdata.value.Bool();
  199. }
  200. void CEnvProjectedTexture::InputSetLightWorld( inputdata_t &inputdata )
  201. {
  202. m_bLightWorld = inputdata.value.Bool();
  203. }
  204. void CEnvProjectedTexture::InputSetEnableShadows( inputdata_t &inputdata )
  205. {
  206. m_bEnableShadows = inputdata.value.Bool();
  207. }
  208. void CEnvProjectedTexture::InputSetLightColor( inputdata_t &inputdata )
  209. {
  210. m_LightColor = inputdata.value.Color32();
  211. }
  212. void CEnvProjectedTexture::InputSetAmbient( inputdata_t &inputdata )
  213. {
  214. m_flAmbient = inputdata.value.Float();
  215. }
  216. void CEnvProjectedTexture::InputSetLightStyle( inputdata_t &inputdata )
  217. {
  218. m_iStyle = inputdata.value.Int();
  219. }
  220. void CEnvProjectedTexture::InputSetPattern( inputdata_t &inputdata )
  221. {
  222. m_iszPattern = inputdata.value.StringID();
  223. engine->LightStyle( m_iStyle, (char *) STRING( m_iszPattern ) );
  224. }
  225. void CEnvProjectedTexture::InputSetNearZ( inputdata_t &inputdata )
  226. {
  227. m_flNearZ = inputdata.value.Float();
  228. }
  229. void CEnvProjectedTexture::InputSetFarZ( inputdata_t &inputdata )
  230. {
  231. m_flFarZ = inputdata.value.Float();
  232. }
  233. void CEnvProjectedTexture::InputSetSpotlightTexture( inputdata_t &inputdata )
  234. {
  235. Assert( 0 );
  236. Warning( "SetSpotlightTexture is disabled. If you need this feature reimplemented, tell a programmer.\n" );
  237. //Q_strcpy( m_SpotlightTextureName.GetForModify(), inputdata.value.String() );
  238. }
  239. void CEnvProjectedTexture::Spawn( void )
  240. {
  241. m_bState = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_STARTON ) != 0 );
  242. m_bAlwaysUpdate = ( ( GetSpawnFlags() & ENV_PROJECTEDTEXTURE_ALWAYSUPDATE ) != 0 );
  243. // Update light styles
  244. if ( m_iStyle >= 32 )
  245. {
  246. if ( m_iszPattern == NULL_STRING && m_iDefaultStyle > 0 )
  247. {
  248. m_iszPattern = MAKE_STRING( GetDefaultLightstyleString( m_iDefaultStyle ) );
  249. }
  250. if ( m_bState == false )
  251. engine->LightStyle( m_iStyle, "a" );
  252. else if ( m_iszPattern != NULL_STRING )
  253. engine->LightStyle( m_iStyle, (char *) STRING( m_iszPattern ) );
  254. else
  255. engine->LightStyle( m_iStyle, "m" );
  256. }
  257. BaseClass::Spawn();
  258. }
  259. void CEnvProjectedTexture::EnforceSingleProjectionRules( bool bWarnOnEnforcement )
  260. {
  261. // Once a light is turned on, turn off all other possible lights in the level
  262. CBaseEntity *pFlashlight = NULL;
  263. while ( ( pFlashlight = gEntList.FindEntityByClassname( pFlashlight, "env_projectedtexture" ) ) != NULL )
  264. {
  265. // Obviously, don't turn yourself off
  266. if ( pFlashlight == this )
  267. continue;
  268. if ( bWarnOnEnforcement )
  269. {
  270. CEnvProjectedTexture *pProjTex = static_cast<CEnvProjectedTexture *>(pFlashlight);
  271. if ( pProjTex && pProjTex->m_bState )
  272. {
  273. Warning( "Warning: env_projected_texture (%s) forced off by (%s)\n", pProjTex->GetEntityNameAsCStr(), GetEntityNameAsCStr() );
  274. }
  275. }
  276. variant_t emptyVariant;
  277. pFlashlight->AcceptInput( "TurnOff", this, this, emptyVariant, 0 );
  278. }
  279. }
  280. void CEnvProjectedTexture::Activate( void )
  281. {
  282. SetThink( &CEnvProjectedTexture::InitialThink );
  283. SetNextThink( gpGlobals->curtime + 0.1f );
  284. BaseClass::Activate();
  285. if ( m_bState )
  286. {
  287. // Make sure that we stomp any other active projected texture off when we activate
  288. EnforceSingleProjectionRules( true );
  289. }
  290. }
  291. void CEnvProjectedTexture::InitialThink( void )
  292. {
  293. m_hTargetEntity = gEntList.FindEntityByName( NULL, m_target );
  294. }
  295. int CEnvProjectedTexture::UpdateTransmitState()
  296. {
  297. return SetTransmitState( FL_EDICT_ALWAYS );
  298. }
  299. // Console command for creating env_projectedtexture entities
  300. void CC_CreateFlashlight( const CCommand &args )
  301. {
  302. CBasePlayer *pPlayer = UTIL_GetCommandClient();
  303. if( !pPlayer )
  304. return;
  305. QAngle angles = pPlayer->EyeAngles();
  306. Vector origin = pPlayer->EyePosition();
  307. CEnvProjectedTexture *pFlashlight = dynamic_cast< CEnvProjectedTexture * >( CreateEntityByName("env_projectedtexture") );
  308. if( args.ArgC() > 1 )
  309. {
  310. pFlashlight->SetName( AllocPooledString( args[1] ) );
  311. }
  312. pFlashlight->Teleport( &origin, &angles, NULL );
  313. }
  314. static ConCommand create_flashlight("create_flashlight", CC_CreateFlashlight, 0, FCVAR_CHEAT);