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.

379 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: HUD Target ID element
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "hud.h"
  9. #include "hudelement.h"
  10. #include "c_cs_player.h"
  11. #include "c_playerresource.h"
  12. #include "c_cs_playerresource.h"
  13. #include "vgui_entitypanel.h"
  14. #include "iclientmode.h"
  15. #include "vgui/ILocalize.h"
  16. #include "c_cs_hostage.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. #define PLAYER_HINT_DISTANCE 150
  20. #define PLAYER_HINT_DISTANCE_SQ (PLAYER_HINT_DISTANCE*PLAYER_HINT_DISTANCE)
  21. extern CUtlVector< C_CHostage* > g_Hostages;
  22. static ConVar hud_showtargetpos( "hud_showtargetpos", "0", FCVAR_ARCHIVE, "0: center, 1: upper left, 2 upper right, 3: lower left, 4: lower right" );
  23. static ConVar hud_showtargetid( "hud_showtargetid", "1", FCVAR_ARCHIVE, "Enables display of target names" );
  24. //-----------------------------------------------------------------------------
  25. // Purpose:
  26. //-----------------------------------------------------------------------------
  27. class CTargetID : public CHudElement, public vgui::Panel
  28. {
  29. DECLARE_CLASS_SIMPLE( CTargetID, vgui::Panel );
  30. public:
  31. CTargetID( const char *pElementName );
  32. void Init( void );
  33. virtual void ApplySchemeSettings( vgui::IScheme *scheme );
  34. virtual void Paint( void );
  35. void VidInit( void );
  36. private:
  37. Color GetColorForTargetTeam( int iTeamNumber );
  38. vgui::HFont m_hFont;
  39. int m_iLastEntIndex;
  40. float m_flLastChangeTime;
  41. Color m_cCTColor;
  42. Color m_cTerroristColor;
  43. Color m_cHostageColor;
  44. };
  45. DECLARE_HUDELEMENT( CTargetID );
  46. using namespace vgui;
  47. //-----------------------------------------------------------------------------
  48. // Purpose:
  49. //-----------------------------------------------------------------------------
  50. CTargetID::CTargetID( const char *pElementName ) :
  51. CHudElement( pElementName ), BaseClass( NULL, "TargetID" )
  52. {
  53. vgui::Panel *pParent = g_pClientMode->GetViewport();
  54. SetParent( pParent );
  55. m_hFont = g_hFontTrebuchet24;
  56. m_flLastChangeTime = 0;
  57. m_iLastEntIndex = 0;
  58. SetHiddenBits( HIDEHUD_MISCSTATUS );
  59. }
  60. //-----------------------------------------------------------------------------
  61. // Purpose: Setup
  62. //-----------------------------------------------------------------------------
  63. void CTargetID::Init( void )
  64. {
  65. };
  66. void CTargetID::ApplySchemeSettings( vgui::IScheme *scheme )
  67. {
  68. BaseClass::ApplySchemeSettings( scheme );
  69. m_cTerroristColor = scheme->GetColor( "T_Red", Color( 255, 64, 64, 255 ) );
  70. m_cCTColor = scheme->GetColor( "CT_Blue", Color( 255, 64, 64, 255 ) );
  71. m_cHostageColor = scheme->GetColor( "Hostage_yellow", Color( 255, 160, 0, 255 ) );
  72. m_hFont = scheme->GetFont( "TargetID", true );
  73. SetPaintBackgroundEnabled( false );
  74. }
  75. //-----------------------------------------------------------------------------
  76. // Purpose: clear out string etc between levels
  77. //-----------------------------------------------------------------------------
  78. void CTargetID::VidInit()
  79. {
  80. CHudElement::VidInit();
  81. // set our size to the current viewport size
  82. SetSize(g_pClientMode->GetViewport()->GetWide(), g_pClientMode->GetViewport()->GetTall());
  83. m_flLastChangeTime = 0;
  84. m_iLastEntIndex = 0;
  85. }
  86. Color CTargetID::GetColorForTargetTeam( int iTeamNumber )
  87. {
  88. switch( iTeamNumber )
  89. {
  90. case TEAM_CT:
  91. return m_cCTColor;
  92. break;
  93. case TEAM_TERRORIST:
  94. return m_cTerroristColor;
  95. break;
  96. default:
  97. return m_cHostageColor;
  98. break;
  99. }
  100. }
  101. //-----------------------------------------------------------------------------
  102. // Purpose: Draw function for the element
  103. //-----------------------------------------------------------------------------
  104. void CTargetID::Paint()
  105. {
  106. if ( hud_showtargetid.GetBool() == false )
  107. return;
  108. #define MAX_ID_STRING 256
  109. wchar_t sIDString[ MAX_ID_STRING ];
  110. sIDString[0] = 0;
  111. Color c = m_cHostageColor;
  112. C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer();
  113. if ( !pPlayer )
  114. return;
  115. // don't show target IDs when flashed
  116. if ( pPlayer->m_flFlashBangTime > (gpGlobals->curtime+0.5) )
  117. return;
  118. //=============================================================================
  119. // HPE_BEGIN:
  120. // [menglish] Don't show target ID's when in freezecam mode
  121. //=============================================================================
  122. if ( pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM )
  123. return;
  124. //=============================================================================
  125. // HPE_END
  126. //=============================================================================
  127. // Get our target's ent index
  128. int iEntIndex = pPlayer->GetIDTarget();
  129. // Didn't find one?
  130. if ( !iEntIndex )
  131. {
  132. // Check to see if we should clear our ID
  133. if ( m_flLastChangeTime && (gpGlobals->curtime > (m_flLastChangeTime + 0.5)) )
  134. {
  135. m_flLastChangeTime = 0;
  136. sIDString[0] = 0;
  137. m_iLastEntIndex = 0;
  138. }
  139. else
  140. {
  141. // Keep re-using the old one
  142. iEntIndex = m_iLastEntIndex;
  143. }
  144. }
  145. else
  146. {
  147. m_flLastChangeTime = gpGlobals->curtime;
  148. }
  149. // Is this an entindex sent by the server?
  150. if ( iEntIndex )
  151. {
  152. C_BasePlayer *pPlayer = static_cast<C_BasePlayer*>(cl_entitylist->GetEnt( iEntIndex ));
  153. C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  154. const char *printFormatString = NULL;
  155. wchar_t wszClanTag[ MAX_PLAYER_NAME_LENGTH ];
  156. wchar_t wszPlayerName[ MAX_PLAYER_NAME_LENGTH ];
  157. wchar_t wszHealthText[ 10 ];
  158. bool bShowHealth = false;
  159. bool bShowPlayerName = false;
  160. // Some entities we always want to check, cause the text may change
  161. // even while we're looking at it
  162. // Is it a player?
  163. if ( IsPlayerIndex( iEntIndex ) )
  164. {
  165. if ( !pPlayer )
  166. {
  167. // This can happen because the object was destroyed
  168. sIDString[0] = 0;
  169. m_iLastEntIndex = 0;
  170. }
  171. else
  172. {
  173. c = GetColorForTargetTeam( pPlayer->GetTeamNumber() );
  174. bShowPlayerName = true;
  175. g_pVGuiLocalize->ConvertANSIToUnicode( pPlayer->GetPlayerName(), wszPlayerName, sizeof(wszPlayerName) );
  176. C_CS_PlayerResource *cs_PR = dynamic_cast<C_CS_PlayerResource *>( g_PR );
  177. char szClan[MAX_PLAYER_NAME_LENGTH];
  178. if ( cs_PR && Q_strlen( cs_PR->GetClanTag( iEntIndex ) ) > 1 )
  179. {
  180. Q_snprintf( szClan, sizeof( szClan ), "%s ", cs_PR->GetClanTag( iEntIndex ) );
  181. }
  182. else
  183. {
  184. szClan[ 0 ] = 0;
  185. }
  186. g_pVGuiLocalize->ConvertANSIToUnicode( szClan, wszClanTag, sizeof( wszClanTag ) );
  187. if ( pPlayer->InSameTeam(pLocalPlayer) )
  188. {
  189. printFormatString = "#Cstrike_playerid_sameteam";
  190. bShowHealth = true;
  191. }
  192. else if ( pLocalPlayer->GetTeamNumber() != TEAM_CT && pLocalPlayer->GetTeamNumber() != TEAM_TERRORIST )
  193. {
  194. printFormatString = "#Cstrike_playerid_noteam";
  195. bShowHealth = true;
  196. }
  197. else
  198. {
  199. printFormatString = "#Cstrike_playerid_diffteam";
  200. }
  201. if ( bShowHealth )
  202. {
  203. _snwprintf( wszHealthText, ARRAYSIZE(wszHealthText) - 1, L"%.0f%%", ((float)pPlayer->GetHealth() / (float)pPlayer->GetMaxHealth() ) * 100 );
  204. wszHealthText[ ARRAYSIZE(wszHealthText)-1 ] = '\0';
  205. }
  206. }
  207. }
  208. else
  209. {
  210. C_BaseEntity *pEnt = cl_entitylist->GetEnt( iEntIndex );
  211. //Hostages!
  212. //"Hostage : Health 100%"
  213. /*
  214. if( long range )
  215. {
  216. m_flDisplayHistory |= DHF_HOSTAGE_SEEN_FAR;
  217. switch ( pLocalPlayer->GetTeamNumber() )
  218. {
  219. case TERRORIST:
  220. HintMessage( "#Hint_prevent_hostage_rescue", TRUE );
  221. break;
  222. case CT:
  223. HintMessage( "#Hint_rescue_the_hostages", TRUE );
  224. break;
  225. }
  226. }
  227. else
  228. {
  229. m_flDisplayHistory |= DHF_HOSTAGE_SEEN_NEAR;
  230. m_flDisplayHistory |= DHF_HOSTAGE_SEEN_FAR; // Don't want the other msg to appear now
  231. HintMessage( "#Hint_press_use_so_hostage_will_follow", FALSE );
  232. }
  233. */
  234. C_CHostage *pHostage = NULL;
  235. for( int i=0;i<g_Hostages.Count();i++ )
  236. {
  237. // compare entity pointers
  238. if( g_Hostages[i] == pEnt )
  239. {
  240. pHostage = g_Hostages[i];
  241. break;
  242. }
  243. }
  244. if( pHostage != NULL )
  245. {
  246. c = m_cHostageColor;
  247. printFormatString = "#Cstrike_playerid_hostage";
  248. _snwprintf( wszHealthText, ARRAYSIZE(wszHealthText) - 1, L"%.0f%%", ((float)pHostage->GetHealth() / (float)pHostage->GetMaxHealth() ) * 100 );
  249. wszHealthText[ ARRAYSIZE(wszHealthText)-1 ] = '\0';
  250. bShowHealth = true;
  251. }
  252. else if ( !pEnt || !pEnt->InSameTeam(pLocalPlayer) )
  253. {
  254. // This can happen because the object was destroyed
  255. sIDString[0] = 0;
  256. m_iLastEntIndex = 0;
  257. }
  258. else
  259. {
  260. // Don't check validity if it's sent by the server
  261. c = m_cHostageColor;
  262. g_pVGuiLocalize->ConvertANSIToUnicode( pEnt->GetIDString(), sIDString, sizeof(sIDString) );
  263. m_iLastEntIndex = iEntIndex;
  264. }
  265. }
  266. if ( printFormatString )
  267. {
  268. if ( bShowPlayerName && bShowHealth )
  269. {
  270. g_pVGuiLocalize->ConstructString( sIDString, sizeof(sIDString), g_pVGuiLocalize->Find(printFormatString), 3, wszClanTag, wszPlayerName, wszHealthText );
  271. }
  272. else if ( bShowPlayerName )
  273. {
  274. g_pVGuiLocalize->ConstructString( sIDString, sizeof(sIDString), g_pVGuiLocalize->Find(printFormatString), 2, wszClanTag, wszPlayerName );
  275. }
  276. else if ( bShowHealth )
  277. {
  278. g_pVGuiLocalize->ConstructString( sIDString, sizeof(sIDString), g_pVGuiLocalize->Find(printFormatString), 1, wszHealthText );
  279. }
  280. else
  281. {
  282. g_pVGuiLocalize->ConstructString( sIDString, sizeof(sIDString), g_pVGuiLocalize->Find(printFormatString), 0 );
  283. }
  284. }
  285. if ( sIDString[0] )
  286. {
  287. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  288. bool bObserverMode = pPlayer && pPlayer->IsObserver();
  289. int wide, tall;
  290. vgui::surface()->GetTextSize( m_hFont, sIDString, wide, tall );
  291. int ypos;
  292. int xpos;
  293. switch ( hud_showtargetpos.GetInt() )
  294. {
  295. case 0: // center
  296. default:
  297. xpos = (ScreenWidth() - wide) / 2;
  298. ypos = YRES(260) - tall / 2;
  299. break;
  300. case 1: // upper left
  301. xpos = XRES(10);
  302. ypos = bObserverMode ? YRES(55) : YRES(5);
  303. break;
  304. case 2: // upper right
  305. xpos = XRES(630) - wide;
  306. ypos = bObserverMode ? YRES(55) : YRES(5);
  307. break;
  308. case 3: // lower left
  309. xpos = XRES(10);
  310. ypos = bObserverMode ? YRES(415) : YRES(445) - tall;
  311. break;
  312. case 4: // lower right
  313. xpos = XRES(630) - wide;
  314. ypos = bObserverMode ? YRES(415) : YRES(410) - tall;
  315. break;
  316. }
  317. vgui::surface()->DrawSetTextFont( m_hFont );
  318. vgui::surface()->DrawSetTextPos( xpos, ypos );
  319. vgui::surface()->DrawSetTextColor( c );
  320. vgui::surface()->DrawPrintText( sIDString, wcslen(sIDString) );
  321. }
  322. }
  323. }