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.

276 lines
9.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //=============================================================================//
  9. #include "cbase.h"
  10. #include "c_basetempentity.h"
  11. #include "iefx.h"
  12. #include "fx.h"
  13. #include "decals.h"
  14. #include "materialsystem/imaterialsystem.h"
  15. #include "filesystem.h"
  16. #include "materialsystem/imaterial.h"
  17. #include "materialsystem/itexture.h"
  18. #include "materialsystem/imaterialvar.h"
  19. #include "clienteffectprecachesystem.h"
  20. #include "tier0/vprof.h"
  21. // memdbgon must be the last include file in a .cpp file!!!
  22. #include "tier0/memdbgon.h"
  23. static ConVar cl_playerspraydisable( "cl_playerspraydisable", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Disable player sprays." );
  24. #ifndef _XBOX
  25. CLIENTEFFECT_REGISTER_BEGIN( PrecachePlayerDecal )
  26. CLIENTEFFECT_MATERIAL( "decals/playerlogo01" )
  27. #if !defined(HL2_DLL) || defined(HL2MP)
  28. CLIENTEFFECT_MATERIAL( "decals/playerlogo02" )
  29. CLIENTEFFECT_MATERIAL( "decals/playerlogo03" )
  30. CLIENTEFFECT_MATERIAL( "decals/playerlogo04" )
  31. CLIENTEFFECT_MATERIAL( "decals/playerlogo05" )
  32. CLIENTEFFECT_MATERIAL( "decals/playerlogo06" )
  33. CLIENTEFFECT_MATERIAL( "decals/playerlogo07" )
  34. CLIENTEFFECT_MATERIAL( "decals/playerlogo08" )
  35. CLIENTEFFECT_MATERIAL( "decals/playerlogo09" )
  36. CLIENTEFFECT_MATERIAL( "decals/playerlogo10" )
  37. CLIENTEFFECT_MATERIAL( "decals/playerlogo11" )
  38. CLIENTEFFECT_MATERIAL( "decals/playerlogo12" )
  39. CLIENTEFFECT_MATERIAL( "decals/playerlogo13" )
  40. CLIENTEFFECT_MATERIAL( "decals/playerlogo14" )
  41. CLIENTEFFECT_MATERIAL( "decals/playerlogo15" )
  42. CLIENTEFFECT_MATERIAL( "decals/playerlogo16" )
  43. CLIENTEFFECT_MATERIAL( "decals/playerlogo17" )
  44. CLIENTEFFECT_MATERIAL( "decals/playerlogo18" )
  45. CLIENTEFFECT_MATERIAL( "decals/playerlogo19" )
  46. CLIENTEFFECT_MATERIAL( "decals/playerlogo20" )
  47. CLIENTEFFECT_MATERIAL( "decals/playerlogo21" )
  48. CLIENTEFFECT_MATERIAL( "decals/playerlogo22" )
  49. CLIENTEFFECT_MATERIAL( "decals/playerlogo23" )
  50. CLIENTEFFECT_MATERIAL( "decals/playerlogo24" )
  51. CLIENTEFFECT_MATERIAL( "decals/playerlogo25" )
  52. CLIENTEFFECT_MATERIAL( "decals/playerlogo26" )
  53. CLIENTEFFECT_MATERIAL( "decals/playerlogo27" )
  54. CLIENTEFFECT_MATERIAL( "decals/playerlogo28" )
  55. CLIENTEFFECT_MATERIAL( "decals/playerlogo29" )
  56. CLIENTEFFECT_MATERIAL( "decals/playerlogo30" )
  57. CLIENTEFFECT_MATERIAL( "decals/playerlogo31" )
  58. CLIENTEFFECT_MATERIAL( "decals/playerlogo32" )
  59. CLIENTEFFECT_MATERIAL( "decals/playerlogo33" )
  60. CLIENTEFFECT_MATERIAL( "decals/playerlogo34" )
  61. CLIENTEFFECT_MATERIAL( "decals/playerlogo35" )
  62. CLIENTEFFECT_MATERIAL( "decals/playerlogo36" )
  63. CLIENTEFFECT_MATERIAL( "decals/playerlogo37" )
  64. CLIENTEFFECT_MATERIAL( "decals/playerlogo38" )
  65. CLIENTEFFECT_MATERIAL( "decals/playerlogo39" )
  66. CLIENTEFFECT_MATERIAL( "decals/playerlogo40" )
  67. CLIENTEFFECT_MATERIAL( "decals/playerlogo41" )
  68. CLIENTEFFECT_MATERIAL( "decals/playerlogo42" )
  69. CLIENTEFFECT_MATERIAL( "decals/playerlogo43" )
  70. CLIENTEFFECT_MATERIAL( "decals/playerlogo44" )
  71. CLIENTEFFECT_MATERIAL( "decals/playerlogo45" )
  72. CLIENTEFFECT_MATERIAL( "decals/playerlogo46" )
  73. CLIENTEFFECT_MATERIAL( "decals/playerlogo47" )
  74. CLIENTEFFECT_MATERIAL( "decals/playerlogo48" )
  75. CLIENTEFFECT_MATERIAL( "decals/playerlogo49" )
  76. CLIENTEFFECT_MATERIAL( "decals/playerlogo40" )
  77. CLIENTEFFECT_MATERIAL( "decals/playerlogo41" )
  78. CLIENTEFFECT_MATERIAL( "decals/playerlogo42" )
  79. CLIENTEFFECT_MATERIAL( "decals/playerlogo43" )
  80. CLIENTEFFECT_MATERIAL( "decals/playerlogo44" )
  81. CLIENTEFFECT_MATERIAL( "decals/playerlogo45" )
  82. CLIENTEFFECT_MATERIAL( "decals/playerlogo46" )
  83. CLIENTEFFECT_MATERIAL( "decals/playerlogo47" )
  84. CLIENTEFFECT_MATERIAL( "decals/playerlogo48" )
  85. CLIENTEFFECT_MATERIAL( "decals/playerlogo49" )
  86. CLIENTEFFECT_MATERIAL( "decals/playerlogo50" )
  87. CLIENTEFFECT_MATERIAL( "decals/playerlogo51" )
  88. CLIENTEFFECT_MATERIAL( "decals/playerlogo52" )
  89. CLIENTEFFECT_MATERIAL( "decals/playerlogo53" )
  90. CLIENTEFFECT_MATERIAL( "decals/playerlogo54" )
  91. CLIENTEFFECT_MATERIAL( "decals/playerlogo55" )
  92. CLIENTEFFECT_MATERIAL( "decals/playerlogo56" )
  93. CLIENTEFFECT_MATERIAL( "decals/playerlogo57" )
  94. CLIENTEFFECT_MATERIAL( "decals/playerlogo58" )
  95. CLIENTEFFECT_MATERIAL( "decals/playerlogo59" )
  96. CLIENTEFFECT_MATERIAL( "decals/playerlogo60" )
  97. CLIENTEFFECT_MATERIAL( "decals/playerlogo61" )
  98. CLIENTEFFECT_MATERIAL( "decals/playerlogo62" )
  99. CLIENTEFFECT_MATERIAL( "decals/playerlogo63" )
  100. CLIENTEFFECT_MATERIAL( "decals/playerlogo64" )
  101. #endif
  102. CLIENTEFFECT_REGISTER_END()
  103. #endif
  104. //-----------------------------------------------------------------------------
  105. // Purpose: Player Decal TE
  106. //-----------------------------------------------------------------------------
  107. class C_TEPlayerDecal : public C_BaseTempEntity
  108. {
  109. public:
  110. DECLARE_CLASS( C_TEPlayerDecal, C_BaseTempEntity );
  111. DECLARE_CLIENTCLASS();
  112. C_TEPlayerDecal( void );
  113. virtual ~C_TEPlayerDecal( void );
  114. virtual void PostDataUpdate( DataUpdateType_t updateType );
  115. virtual void Precache( void );
  116. public:
  117. int m_nPlayer;
  118. Vector m_vecOrigin;
  119. int m_nEntity;
  120. };
  121. //-----------------------------------------------------------------------------
  122. // Purpose:
  123. //-----------------------------------------------------------------------------
  124. C_TEPlayerDecal::C_TEPlayerDecal( void )
  125. {
  126. m_nPlayer = 0;
  127. m_vecOrigin.Init();
  128. m_nEntity = 0;
  129. }
  130. //-----------------------------------------------------------------------------
  131. // Purpose:
  132. //-----------------------------------------------------------------------------
  133. C_TEPlayerDecal::~C_TEPlayerDecal( void )
  134. {
  135. }
  136. //-----------------------------------------------------------------------------
  137. // Purpose:
  138. //-----------------------------------------------------------------------------
  139. void C_TEPlayerDecal::Precache( void )
  140. {
  141. }
  142. //-----------------------------------------------------------------------------
  143. // Purpose:
  144. //-----------------------------------------------------------------------------
  145. IMaterial *CreateTempMaterialForPlayerLogo( int iPlayerIndex, player_info_t *info, char *texname, int nchars )
  146. {
  147. // Doesn't have a logo?
  148. if ( !info->customFiles[0] )
  149. return NULL;
  150. IMaterial *logo = materials->FindMaterial( VarArgs("decals/playerlogo%2.2d", iPlayerIndex), TEXTURE_GROUP_DECAL );
  151. if ( IsErrorMaterial( logo ) )
  152. return NULL;
  153. char logohex[ 16 ];
  154. Q_binarytohex( (byte *)&info->customFiles[0], sizeof( info->customFiles[0] ), logohex, sizeof( logohex ) );
  155. // See if logo has been downloaded.
  156. Q_snprintf( texname, nchars, "temp/%s", logohex );
  157. char fulltexname[ 512 ];
  158. Q_snprintf( fulltexname, sizeof( fulltexname ), "materials/temp/%s.vtf", logohex );
  159. if ( !filesystem->FileExists( fulltexname ) )
  160. {
  161. char custname[ 512 ];
  162. Q_snprintf( custname, sizeof( custname ), "download/user_custom/%c%c/%s.dat", logohex[0], logohex[1], logohex );
  163. // it may have been downloaded but not copied under materials folder
  164. if ( !filesystem->FileExists( custname ) )
  165. return NULL; // not downloaded yet
  166. // copy from download folder to materials/temp folder
  167. // this is done since material system can access only materials/*.vtf files
  168. if ( !engine->CopyLocalFile( custname, fulltexname) )
  169. return NULL;
  170. }
  171. return logo;
  172. }
  173. //-----------------------------------------------------------------------------
  174. // Purpose:
  175. // Input : filter -
  176. // delay -
  177. // pos -
  178. // player -
  179. // entity -
  180. //-----------------------------------------------------------------------------
  181. void TE_PlayerDecal( IRecipientFilter& filter, float delay,
  182. const Vector* pos, int player, int entity )
  183. {
  184. if ( cl_playerspraydisable.GetBool() )
  185. return;
  186. // No valid target?
  187. C_BaseEntity *ent = cl_entitylist->GetEnt( entity );
  188. if ( !ent )
  189. return;
  190. // Find player logo for shooter
  191. player_info_t info;
  192. engine->GetPlayerInfo( player, &info );
  193. // Make sure we've got the material for this player's logo
  194. char texname[ 512 ];
  195. IMaterial *logo = CreateTempMaterialForPlayerLogo( player, &info, texname, 512 );
  196. if ( !logo )
  197. return;
  198. ITexture *texture = materials->FindTexture( texname, TEXTURE_GROUP_DECAL );
  199. if ( IsErrorTexture( texture ) )
  200. {
  201. return; // not found
  202. }
  203. // Update the texture used by the material if need be.
  204. bool bFound = false;
  205. IMaterialVar *pMatVar = logo->FindVar( "$basetexture", &bFound );
  206. if ( bFound && pMatVar )
  207. {
  208. if ( pMatVar->GetTextureValue() != texture )
  209. {
  210. pMatVar->SetTextureValue( texture );
  211. logo->RefreshPreservingMaterialVars();
  212. }
  213. }
  214. color32 rgbaColor = { 255, 255, 255, 255 };
  215. effects->PlayerDecalShoot(
  216. logo,
  217. (void *)player,
  218. entity,
  219. ent->GetModel(),
  220. ent->GetAbsOrigin(),
  221. ent->GetAbsAngles(),
  222. *pos,
  223. 0,
  224. 0,
  225. rgbaColor );
  226. }
  227. //-----------------------------------------------------------------------------
  228. // Purpose:
  229. // Input : bool -
  230. //-----------------------------------------------------------------------------
  231. void C_TEPlayerDecal::PostDataUpdate( DataUpdateType_t updateType )
  232. {
  233. #ifndef _XBOX
  234. VPROF( "C_TEPlayerDecal::PostDataUpdate" );
  235. // Decals disabled?
  236. if ( !r_decals.GetBool() )
  237. return;
  238. CLocalPlayerFilter filter;
  239. TE_PlayerDecal( filter, 0.0f, &m_vecOrigin, m_nPlayer, m_nEntity );
  240. #endif
  241. }
  242. IMPLEMENT_CLIENTCLASS_EVENT_DT(C_TEPlayerDecal, DT_TEPlayerDecal, CTEPlayerDecal)
  243. RecvPropVector( RECVINFO(m_vecOrigin)),
  244. RecvPropInt( RECVINFO(m_nEntity)),
  245. RecvPropInt( RECVINFO(m_nPlayer)),
  246. END_RECV_TABLE()