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.

214 lines
5.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "cbase.h"
  8. #include <string.h>
  9. #include <stdio.h>
  10. #include "dod_headiconmanager.h"
  11. #include "c_playerresource.h"
  12. #include "cliententitylist.h"
  13. #include "c_baseplayer.h"
  14. #include "materialsystem/imesh.h"
  15. #include "view.h"
  16. #include "materialsystem/imaterial.h"
  17. #include "tier0/dbg.h"
  18. #include "cdll_int.h"
  19. #include "dod_shareddefs.h"
  20. #include "c_dod_player.h"
  21. #include "voice_status.h"
  22. // memdbgon must be the last include file in a .cpp file!!!
  23. #include "tier0/memdbgon.h"
  24. using namespace vgui;
  25. static CHeadIconManager s_HeadIconMgr;
  26. CHeadIconManager* HeadIconManager()
  27. {
  28. return &s_HeadIconMgr;
  29. }
  30. CHeadIconManager::CHeadIconManager()
  31. {
  32. m_pAlliesIconMaterial = NULL;
  33. m_pAxisIconMaterial = NULL;
  34. }
  35. CHeadIconManager::~CHeadIconManager()
  36. {
  37. Shutdown();
  38. }
  39. bool CHeadIconManager::Init()
  40. {
  41. if ( !m_pAlliesIconMaterial )
  42. {
  43. m_pAlliesIconMaterial = materials->FindMaterial( "sprites/player_icons/american", TEXTURE_GROUP_VGUI );
  44. }
  45. if ( !m_pAxisIconMaterial )
  46. {
  47. m_pAxisIconMaterial = materials->FindMaterial( "sprites/player_icons/german", TEXTURE_GROUP_VGUI );
  48. }
  49. if ( IsErrorMaterial( m_pAlliesIconMaterial ) ||
  50. IsErrorMaterial( m_pAxisIconMaterial ) )
  51. {
  52. Assert(!"Can't find head icon materials");
  53. return false;
  54. }
  55. m_pAlliesIconMaterial->IncrementReferenceCount();
  56. m_pAxisIconMaterial->IncrementReferenceCount();
  57. m_PlayerDrawn.ClearAll();
  58. return true;
  59. }
  60. void CHeadIconManager::Shutdown()
  61. {
  62. if ( m_pAlliesIconMaterial )
  63. {
  64. m_pAlliesIconMaterial->DecrementReferenceCount();
  65. m_pAlliesIconMaterial = NULL;
  66. }
  67. if ( m_pAxisIconMaterial )
  68. {
  69. m_pAxisIconMaterial->DecrementReferenceCount();
  70. m_pAxisIconMaterial = NULL;
  71. }
  72. }
  73. //-----------------------------------------------------------------------------
  74. // Call from player render calls to indicate a head icon should be drawn for this player this frame
  75. //-----------------------------------------------------------------------------
  76. void CHeadIconManager::PlayerDrawn( C_BasePlayer *pPlayer )
  77. {
  78. m_PlayerDrawn.Set( pPlayer->entindex() - 1 );
  79. }
  80. ConVar cl_headiconoffset( "cl_headiconoffset", "24", FCVAR_CHEAT );
  81. ConVar cl_headiconsize( "cl_headiconsize", "8", FCVAR_CHEAT );
  82. ConVar cl_identiconmode( "cl_identiconmode", "2", FCVAR_ARCHIVE, "2 - icons over teammates' heads\n1- icons over target teammate\n0 - no head icons" );
  83. void CHeadIconManager::DrawHeadIcons()
  84. {
  85. CMatRenderContextPtr pRenderContext( materials );
  86. CBitVec<MAX_PLAYERS> playerDrawn = m_PlayerDrawn;
  87. m_PlayerDrawn.ClearAll();
  88. if ( cl_identiconmode.GetInt() <= 0 )
  89. return;
  90. C_DODPlayer *pLocalPlayer = C_DODPlayer::GetLocalDODPlayer();
  91. if ( !pLocalPlayer )
  92. return;
  93. if ( pLocalPlayer->GetTeamNumber() != TEAM_ALLIES &&
  94. pLocalPlayer->GetTeamNumber() != TEAM_AXIS )
  95. {
  96. return;
  97. }
  98. Vector vUp = CurrentViewUp();
  99. Vector vRight = CurrentViewRight();
  100. if ( fabs( vRight.z ) > 0.95 ) // don't draw it edge-on
  101. return;
  102. vRight.z = 0;
  103. VectorNormalize( vRight );
  104. float flSize = cl_headiconsize.GetFloat();
  105. for(int i=0; i < MAX_PLAYERS; i++)
  106. {
  107. if ( !playerDrawn.IsBitSet( i ) )
  108. continue;
  109. if ( cl_identiconmode.GetInt() == 1 )
  110. {
  111. // only draw if this player is our status bar target
  112. if ( (i+1) != pLocalPlayer->GetIDTarget() )
  113. continue;
  114. }
  115. IClientNetworkable *pClient = cl_entitylist->GetClientEntity( i+1 );
  116. // Don't show an icon if the player is not in our PVS.
  117. if ( !pClient || pClient->IsDormant() )
  118. continue;
  119. C_DODPlayer *pPlayer = dynamic_cast<C_DODPlayer*>(pClient);
  120. if( !pPlayer )
  121. continue;
  122. // Don't show an icon for dead or spectating players (ie: invisible entities).
  123. if( pPlayer->IsPlayerDead() )
  124. continue;
  125. if( pPlayer == pLocalPlayer )
  126. continue;
  127. if( pPlayer->GetTeamNumber() != pLocalPlayer->GetTeamNumber() )
  128. continue;
  129. if ( GetClientVoiceMgr()->IsPlayerSpeaking( i+1 ) )
  130. continue;
  131. if ( C_BasePlayer::GetLocalPlayer()->GetObserverMode() == OBS_MODE_IN_EYE &&
  132. C_BasePlayer::GetLocalPlayer()->GetObserverTarget() == pPlayer )
  133. continue;
  134. IMaterial *pMaterial = pPlayer->GetHeadIconMaterial();
  135. if ( !pMaterial )
  136. continue;
  137. pRenderContext->Bind( pMaterial );
  138. Vector vOrigin;
  139. QAngle vAngle;
  140. int iHeadAttach = pPlayer->LookupAttachment( "head" );
  141. pPlayer->GetAttachment( iHeadAttach, vOrigin, vAngle );
  142. vOrigin.z += cl_headiconoffset.GetFloat();
  143. // Align it towards the viewer
  144. IMesh *pMesh = pRenderContext->GetDynamicMesh();
  145. CMeshBuilder meshBuilder;
  146. meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
  147. meshBuilder.Color3f( 1.0, 1.0, 1.0 );
  148. meshBuilder.TexCoord2f( 0,0,0 );
  149. meshBuilder.Position3fv( (vOrigin + (vRight * -flSize) + (vUp * flSize)).Base() );
  150. meshBuilder.AdvanceVertex();
  151. meshBuilder.Color3f( 1.0, 1.0, 1.0 );
  152. meshBuilder.TexCoord2f( 0,1,0 );
  153. meshBuilder.Position3fv( (vOrigin + (vRight * flSize) + (vUp * flSize)).Base() );
  154. meshBuilder.AdvanceVertex();
  155. meshBuilder.Color3f( 1.0, 1.0, 1.0 );
  156. meshBuilder.TexCoord2f( 0,1,1 );
  157. meshBuilder.Position3fv( (vOrigin + (vRight * flSize) + (vUp * -flSize)).Base() );
  158. meshBuilder.AdvanceVertex();
  159. meshBuilder.Color3f( 1.0, 1.0, 1.0 );
  160. meshBuilder.TexCoord2f( 0,0,1 );
  161. meshBuilder.Position3fv( (vOrigin + (vRight * -flSize) + (vUp * -flSize)).Base() );
  162. meshBuilder.AdvanceVertex();
  163. meshBuilder.End();
  164. pMesh->Draw();
  165. }
  166. }