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.

525 lines
13 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "dod_hud_winpanel.h"
  9. #include "vgui_controls/AnimationController.h"
  10. #include "iclientmode.h"
  11. #include "c_dod_playerresource.h"
  12. #include <vgui_controls/Label.h>
  13. #include <vgui/ILocalize.h>
  14. #include <vgui/ISurface.h>
  15. #include "vgui_avatarimage.h"
  16. #include "fmtstr.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. DECLARE_HUDELEMENT_DEPTH( CDODWinPanel_Allies, 1 ); // 1 is foreground
  20. DECLARE_HUDELEMENT_DEPTH( CDODWinPanel_Axis, 1 );
  21. CDODWinPanel_Allies::CDODWinPanel_Allies( const char *pElementName ) : CDODWinPanel( "WinPanel_Allies", TEAM_ALLIES )
  22. {
  23. LoadControlSettings("Resource/UI/Win_Allies.res");
  24. }
  25. void CDODWinPanel_Allies::OnScreenSizeChanged( int iOldWide, int iOldTall )
  26. {
  27. LoadControlSettings( "resource/UI/Win_Allies.res" );
  28. }
  29. void CDODWinPanel_Allies::ApplySchemeSettings( vgui::IScheme *pScheme )
  30. {
  31. m_pIcon = gHUD.GetIcon( "icon_obj_allies" );
  32. LoadControlSettings( "resource/UI/Win_Allies.res" );
  33. BaseClass::ApplySchemeSettings( pScheme );
  34. }
  35. //============================
  36. CDODWinPanel_Axis::CDODWinPanel_Axis( const char *pElementName ) : CDODWinPanel( "WinPanel_Axis", TEAM_AXIS )
  37. {
  38. LoadControlSettings("Resource/UI/Win_Axis.res");
  39. }
  40. void CDODWinPanel_Axis::OnScreenSizeChanged( int iOldWide, int iOldTall )
  41. {
  42. LoadControlSettings( "resource/UI/Win_Axis.res" );
  43. }
  44. void CDODWinPanel_Axis::ApplySchemeSettings( vgui::IScheme *pScheme )
  45. {
  46. m_pIcon = gHUD.GetIcon( "icon_obj_axis" );
  47. LoadControlSettings( "resource/UI/Win_Axis.res" );
  48. BaseClass::ApplySchemeSettings( pScheme );
  49. }
  50. //============================
  51. //-----------------------------------------------------------------------------
  52. // Purpose: Constructor
  53. //-----------------------------------------------------------------------------
  54. CDODWinPanel::CDODWinPanel( const char *pElementName, int iTeam )
  55. : EditablePanel( NULL, pElementName ), CHudElement( pElementName )
  56. {
  57. vgui::Panel *pParent = g_pClientMode->GetViewport();
  58. SetParent( pParent );
  59. SetVisible( false );
  60. SetAlpha( 0 );
  61. SetScheme( "ClientScheme" );
  62. m_iTeam = iTeam;
  63. m_pTimerStatusLabel = new vgui::Label( this, "TimerInfo", "" );
  64. m_pLastCapperHeader = new vgui::Label( this, "LastCapperHeader", "" );
  65. m_pLastBomberHeader = new vgui::Label( this, "LastBomberHeader", "" );
  66. m_pLastCapperLabel = new vgui::Label( this, "LastCapper", "" );
  67. m_pLastCapperLabel_Avatar = new vgui::Label( this, "LastCapper_Avatar", "" );
  68. m_pLeftCategoryHeader = new vgui::Label( this, "LeftCategoryHeader", "..." );
  69. m_pRightCategoryHeader = new vgui::Label( this, "RightCategoryHeader", "..." );
  70. m_pLeftCategoryLabels[0] = new vgui::Label( this, "LeftCategory1", "" );
  71. m_pLeftCategoryLabels[1] = new vgui::Label( this, "LeftCategory2", "" );
  72. m_pLeftCategoryLabels[2] = new vgui::Label( this, "LeftCategory3", "" );
  73. m_pRightCategoryLabels[0] = new vgui::Label( this, "RightCategory1", "" );
  74. m_pRightCategoryLabels[1] = new vgui::Label( this, "RightCategory2", "" );
  75. m_pRightCategoryLabels[2] = new vgui::Label( this, "RightCategory3", "" );
  76. RegisterForRenderGroup( "winpanel" );
  77. }
  78. //-----------------------------------------------------------------------------
  79. // Purpose:
  80. //-----------------------------------------------------------------------------
  81. void CDODWinPanel::Reset()
  82. {
  83. Hide();
  84. }
  85. void CDODWinPanel::Init()
  86. {
  87. // listen for events
  88. ListenForGameEvent( "dod_round_win" );
  89. ListenForGameEvent( "dod_round_start" );
  90. ListenForGameEvent( "dod_point_captured" );
  91. ListenForGameEvent( "dod_win_panel" );
  92. Hide();
  93. SetFinalCaptureLabel( "", false );
  94. m_pTimerStatusLabel->SetText( "" );
  95. m_bShowTimerDefend = false;
  96. m_bShowTimerAttack = false;
  97. m_iTimerTime = 0;
  98. m_iFinalEventType = CAP_EVENT_NONE;
  99. m_iLeftCategory = WINPANEL_TOP3_NONE;
  100. m_iRightCategory = WINPANEL_TOP3_NONE;
  101. for ( int i=0;i<3;i++ )
  102. {
  103. m_iLeftCategoryScores[i] = 0;
  104. m_iRightCategoryScores[i] = 0;
  105. }
  106. CHudElement::Init();
  107. }
  108. void CDODWinPanel::VidInit()
  109. {
  110. m_pIconCap = gHUD.GetIcon( "stats_cap" );
  111. m_pIconDefended = gHUD.GetIcon( "stats_defended" );
  112. m_pIconBomb = gHUD.GetIcon( "icon_c4" );
  113. m_pIconKill = gHUD.GetIcon( "stats_kill" );
  114. }
  115. void SetPlayerNameLabel( vgui::Label *pLabel, int clientIndex )
  116. {
  117. if ( !pLabel )
  118. return;
  119. if ( clientIndex >= 1 && clientIndex <= MAX_PLAYERS )
  120. {
  121. char buf[48];
  122. Q_snprintf( buf, sizeof(buf), "%s:", g_PR->GetPlayerName(clientIndex) );
  123. pLabel->SetText( buf );
  124. }
  125. pLabel->SetVisible( clientIndex > 0 );
  126. }
  127. void CDODWinPanel::FireGameEvent( IGameEvent * event )
  128. {
  129. const char *pEventName = event->GetName();
  130. if ( Q_strcmp( "dod_round_win", pEventName ) == 0 )
  131. {
  132. if ( event->GetInt( "team" ) == m_iTeam )
  133. {
  134. Show();
  135. }
  136. }
  137. else if ( Q_strcmp( "dod_round_start", pEventName ) == 0 )
  138. {
  139. Hide();
  140. m_pLastCapperHeader->SetVisible( false );
  141. m_pLastBomberHeader->SetVisible( false );
  142. }
  143. else if ( Q_strcmp( "dod_point_captured", pEventName ) == 0 )
  144. {
  145. if ( !g_PR )
  146. return;
  147. // Array of capper indeces
  148. const char *cappers = event->GetString("cappers");
  149. char szCappers[256];
  150. szCappers[0] = '\0';
  151. int len = Q_strlen(cappers);
  152. bool bShowAvatar = ( len == 1 );
  153. if ( !bShowAvatar )
  154. {
  155. SetupAvatar( "top", 1, 0 ); // hide it
  156. }
  157. for( int i=0;i<len;i++ )
  158. {
  159. int iPlayerIndex = (int)cappers[i];
  160. Assert( iPlayerIndex > 0 && iPlayerIndex <= gpGlobals->maxClients );
  161. const char *pPlayerName = g_PR->GetPlayerName( iPlayerIndex );
  162. if ( bShowAvatar )
  163. {
  164. SetupAvatar( "top", 1, iPlayerIndex );
  165. }
  166. if ( i > 0 )
  167. {
  168. Q_strncat( szCappers, ", ", sizeof(szCappers), 2 );
  169. }
  170. Q_strncat( szCappers, pPlayerName, sizeof(szCappers), COPY_ALL_CHARACTERS );
  171. }
  172. if ( event->GetBool( "bomb" ) )
  173. {
  174. m_pLastCapperHeader->SetVisible( false );
  175. m_pLastBomberHeader->SetVisible( true );
  176. }
  177. else
  178. {
  179. m_pLastCapperHeader->SetVisible( true );
  180. m_pLastBomberHeader->SetVisible( false );
  181. }
  182. SetFinalCaptureLabel( szCappers, bShowAvatar );
  183. }
  184. else if ( Q_strcmp( "dod_win_panel", pEventName ) == 0 )
  185. {
  186. /*
  187. "show_timer_defend" "bool"
  188. "show_timer_attack" "bool"
  189. "timer_time" "int"
  190. "final_event" "byte" // 0 - no event, 1 - bomb exploded, 2 - flag capped, 3 - timer expired
  191. "category_left" "byte" // 0-4: none, bombers, cappers, defenders, killers
  192. "left_1" "byte" // player index if first
  193. "left_score_1" "byte"
  194. "left_2" "byte"
  195. "left_score_2" "byte"
  196. "left_3" "byte"
  197. "left_score_3" "byte"
  198. "right_1" "byte"
  199. "right_score_1" "byte"
  200. "right_2" "byte"
  201. "right_score_2" "byte"
  202. "right_3" "byte"
  203. "right_score_3" "byte"
  204. */
  205. if ( !g_PR )
  206. return;
  207. m_bShowTimerDefend = event->GetBool( "show_timer_defend" );
  208. m_bShowTimerAttack = event->GetBool( "show_timer_attack" );
  209. m_iTimerTime = event->GetInt( "timer_time" );
  210. int minutes = clamp( m_iTimerTime / 60, 0, 99 );
  211. int seconds = clamp( m_iTimerTime % 60, 0, 59 );
  212. if ( m_bShowTimerDefend )
  213. {
  214. // defenders win, show total time defended
  215. // "Total Time Defended: 4:28"
  216. wchar_t time[8];
  217. _snwprintf( time, ARRAYSIZE( time ), L"%d:%02d", minutes, seconds );
  218. wchar_t timerText[128];
  219. g_pVGuiLocalize->ConstructString( timerText, sizeof( timerText ), g_pVGuiLocalize->Find( "#winpanel_total_time" ), 1, time );
  220. m_pTimerStatusLabel->SetText( timerText );
  221. // zero out the final capture label, they won by timer
  222. m_pLastCapperHeader->SetVisible( false );
  223. m_pLastBomberHeader->SetVisible( false );
  224. SetFinalCaptureLabel( "", false );
  225. SetupAvatar( "top", 1, 0 ); // hide it
  226. }
  227. else if ( m_bShowTimerAttack )
  228. {
  229. // attackers win, show time elapsed
  230. // "Time Elapsed: 4:12"
  231. wchar_t time[8];
  232. _snwprintf( time, ARRAYSIZE( time ), L"%d:%02d", minutes, seconds );
  233. wchar_t timerText[128];
  234. g_pVGuiLocalize->ConstructString( timerText, sizeof( timerText ), g_pVGuiLocalize->Find( "#winpanel_attack_time" ), 1, time );
  235. m_pTimerStatusLabel->SetText( timerText );
  236. }
  237. else
  238. {
  239. m_pTimerStatusLabel->SetText( "" );
  240. }
  241. m_iFinalEventType = event->GetInt( "final_event" );
  242. // up to client to fill in who completed the final event
  243. m_iLeftCategory = event->GetInt( "category_left" );
  244. m_iRightCategory = event->GetInt( "category_right" );
  245. m_pLeftCategoryHeader->SetText( g_pVGuiLocalize->Find( pszWinPanelCategoryHeaders[m_iLeftCategory] ) );
  246. m_pRightCategoryHeader->SetText( g_pVGuiLocalize->Find( pszWinPanelCategoryHeaders[m_iRightCategory] ) );
  247. int iPlayer;
  248. // Left Top 3 Category
  249. iPlayer = event->GetInt( "left_1" );
  250. SetPlayerNameLabel( m_pLeftCategoryLabels[0], iPlayer );
  251. SetupAvatar( "left", 1, iPlayer );
  252. iPlayer = event->GetInt( "left_2" );
  253. SetPlayerNameLabel( m_pLeftCategoryLabels[1], iPlayer );
  254. SetupAvatar( "left", 2, iPlayer );
  255. iPlayer = event->GetInt( "left_3" );
  256. SetPlayerNameLabel( m_pLeftCategoryLabels[2], iPlayer );
  257. SetupAvatar( "left", 3, iPlayer );
  258. m_iLeftCategoryScores[0] = event->GetInt( "left_score_1" );
  259. m_iLeftCategoryScores[1] = event->GetInt( "left_score_2" );
  260. m_iLeftCategoryScores[2] = event->GetInt( "left_score_3" );
  261. // Right Top 3 Category
  262. iPlayer = event->GetInt( "right_1" );
  263. SetPlayerNameLabel( m_pRightCategoryLabels[0], iPlayer );
  264. SetupAvatar( "right", 1, iPlayer );
  265. iPlayer = event->GetInt( "right_2" );
  266. SetPlayerNameLabel( m_pRightCategoryLabels[1], iPlayer );
  267. SetupAvatar( "right", 2, iPlayer );
  268. iPlayer = event->GetInt( "right_3" );
  269. SetPlayerNameLabel( m_pRightCategoryLabels[2], iPlayer );
  270. SetupAvatar( "right", 3, iPlayer );
  271. m_iRightCategoryScores[0] = event->GetInt( "right_score_1" );
  272. m_iRightCategoryScores[1] = event->GetInt( "right_score_2" );
  273. m_iRightCategoryScores[2] = event->GetInt( "right_score_3" );
  274. m_pRightCategoryHeader->SetVisible( ( m_iRightCategoryScores[0] > 0 ) );
  275. }
  276. }
  277. void CDODWinPanel::SetupAvatar( const char *pSide, int pos, int iPlayerIndex )
  278. {
  279. #if !defined( _X360 )
  280. bool bVisible = ( iPlayerIndex > 0 );
  281. CAvatarImagePanel *pPlayerAvatar = dynamic_cast<CAvatarImagePanel *>( FindChildByName( CFmtStr( "%s_%d_avatar", pSide, pos ) ) );
  282. if ( pPlayerAvatar )
  283. {
  284. pPlayerAvatar->SetShouldScaleImage( true );
  285. pPlayerAvatar->SetShouldDrawFriendIcon( false );
  286. if ( bVisible )
  287. {
  288. CBasePlayer *pPlayer = UTIL_PlayerByIndex( iPlayerIndex );
  289. pPlayerAvatar->SetPlayer( pPlayer );
  290. }
  291. pPlayerAvatar->SetVisible( bVisible );
  292. }
  293. #endif
  294. }
  295. void CDODWinPanel::SetFinalCaptureLabel( const char *szCappers, bool bShowAvatar )
  296. {
  297. SetDialogVariable( "lastcappers", szCappers );
  298. m_pLastCapperLabel->SetVisible( !bShowAvatar );
  299. m_pLastCapperLabel_Avatar->SetVisible( bShowAvatar );
  300. }
  301. void CDODWinPanel::Show( void )
  302. {
  303. SetAlpha( 255 );
  304. int iRenderGroup = gHUD.LookupRenderGroupIndexByName( "winpanel" );
  305. if ( iRenderGroup >= 0 )
  306. {
  307. gHUD.LockRenderGroup( iRenderGroup );
  308. }
  309. }
  310. void CDODWinPanel::Hide( void )
  311. {
  312. SetAlpha( 0 );
  313. int iRenderGroup = gHUD.LookupRenderGroupIndexByName( "winpanel" );
  314. if ( iRenderGroup >= 0 )
  315. {
  316. gHUD.UnlockRenderGroup( iRenderGroup );
  317. }
  318. }
  319. void CDODWinPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
  320. {
  321. BaseClass::ApplySchemeSettings( pScheme );
  322. SetBgColor( GetSchemeColor("TransparentLightBlack", pScheme) );
  323. }
  324. bool CDODWinPanel::ShouldDraw( void )
  325. {
  326. return ( GetAlpha() > 0 );
  327. }
  328. CHudTexture *CDODWinPanel::GetIconForCategory( int category )
  329. {
  330. CHudTexture *pTex = NULL;
  331. switch( category )
  332. {
  333. case WINPANEL_TOP3_BOMBERS:
  334. pTex = m_pIconBomb;
  335. break;
  336. case WINPANEL_TOP3_CAPPERS:
  337. pTex = m_pIconCap;
  338. break;
  339. case WINPANEL_TOP3_DEFENDERS:
  340. pTex = m_pIconDefended;
  341. break;
  342. case WINPANEL_TOP3_KILLERS:
  343. pTex = m_pIconKill;
  344. break;
  345. default:
  346. break;
  347. }
  348. return pTex;
  349. }
  350. void CDODWinPanel::Paint( void )
  351. {
  352. if ( m_pIcon )
  353. {
  354. Color c(255,255,255,255);
  355. m_pIcon->DrawSelf( m_iIconX_left, m_iIconY, m_iIconW, m_iIconH, c );
  356. m_pIcon->DrawSelf( m_iIconX_right, m_iIconY, m_iIconW, m_iIconH, c );
  357. }
  358. int i;
  359. int x, y, w, h;
  360. Color c(255,255,255,255);
  361. // Draw Left Category Icons
  362. CHudTexture *pIcon = GetIconForCategory( m_iLeftCategory );
  363. if ( pIcon )
  364. {
  365. for ( i=0;i<3;i++ )
  366. {
  367. if ( m_iLeftCategoryScores[i] > 0 )
  368. {
  369. m_pLeftCategoryLabels[i]->GetBounds( x, y, w, h );
  370. x = x + w + XRES(2);
  371. y = y + ( h - m_iIconSize ) * 0.5;
  372. // too many, do a "(icon) 8"
  373. pIcon->DrawSelf( x, y, m_iIconSize, m_iIconSize, c );
  374. x += m_iIconSize;
  375. char buf[10];
  376. Q_snprintf( buf, sizeof(buf), " %d", m_iLeftCategoryScores[i] );
  377. DrawText( buf, x, y, c );
  378. }
  379. }
  380. }
  381. // Draw Right Category Icons
  382. pIcon = GetIconForCategory( m_iRightCategory );
  383. if ( pIcon )
  384. {
  385. for ( i=0;i<3;i++ )
  386. {
  387. if ( m_iRightCategoryScores[i] > 0 )
  388. {
  389. m_pRightCategoryLabels[i]->GetBounds( x, y, w, h );
  390. x = x + w + XRES(2);
  391. y = y + ( h - m_iIconSize ) * 0.5;
  392. // too many, do a "(icon) 8"
  393. pIcon->DrawSelf( x, y, m_iIconSize, m_iIconSize, c );
  394. x += m_iIconSize;
  395. char buf[10];
  396. Q_snprintf( buf, sizeof(buf), " %d", m_iRightCategoryScores[i] );
  397. DrawText( buf, x, y, c );
  398. }
  399. }
  400. }
  401. }
  402. void CDODWinPanel::DrawText( char *text, int x, int y, Color clrText )
  403. {
  404. vgui::surface()->DrawSetTextColor( clrText );
  405. vgui::surface()->DrawSetTextFont( m_hNumberFont );
  406. vgui::surface()->DrawSetTextPos( x, y );
  407. for (char *pch = text; *pch != 0; pch++)
  408. {
  409. vgui::surface()->DrawUnicodeChar(*pch);
  410. }
  411. }