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.

634 lines
20 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include "c_baseentity.h"
  8. #include "hud.h"
  9. #include "hudelement.h"
  10. #include "clientmode.h"
  11. #include <vgui_controls/Panel.h>
  12. #include <vgui/ISurface.h>
  13. #include <vgui/ILocalize.h>
  14. #include <vgui/IScheme.h>
  15. #include <vgui_controls/AnimationController.h>
  16. #include "materialsystem/imaterialsystemhardwareconfig.h"
  17. #include "soundenvelope.h"
  18. #include "convar.h"
  19. #include "hud_closecaption.h"
  20. #include "in_buttons.h"
  21. // memdbgon must be the last include file in a .cpp file!!!
  22. #include "tier0/memdbgon.h"
  23. #define MAX_SPEAKER_NAME 256
  24. #define MAX_COUNT_STRING 64
  25. extern ConVar english;
  26. extern ConVar closecaption;
  27. class C_PointCommentaryNode;
  28. CUtlVector< CHandle<C_PointCommentaryNode> > g_CommentaryNodes;
  29. bool IsInCommentaryMode( void )
  30. {
  31. return (g_CommentaryNodes.Count() > 0);
  32. }
  33. static bool g_bTracingVsCommentaryNodes = false;
  34. //-----------------------------------------------------------------------------
  35. // Purpose:
  36. //-----------------------------------------------------------------------------
  37. class CHudCommentary : public CHudElement, public vgui::Panel
  38. {
  39. DECLARE_CLASS_SIMPLE( CHudCommentary, vgui::Panel );
  40. public:
  41. CHudCommentary( const char *name );
  42. virtual void Init( void );
  43. virtual void VidInit( void );
  44. virtual void LevelInit( void ) { g_CommentaryNodes.Purge(); }
  45. virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
  46. void StartCommentary( C_PointCommentaryNode *pNode, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime );
  47. void StopCommentary( void );
  48. bool IsTheActiveNode( C_PointCommentaryNode *pNode ) { return (pNode == m_hActiveNode); }
  49. bool HasActiveNode( void ) { return m_hActiveNode.Get() != NULL; }
  50. // vgui overrides
  51. virtual void Paint( void );
  52. virtual bool ShouldDraw( void );
  53. private:
  54. CHandle<C_PointCommentaryNode> m_hActiveNode;
  55. bool m_bShouldPaint;
  56. float m_flStartTime;
  57. float m_flEndTime;
  58. wchar_t m_szSpeakers[MAX_SPEAKER_NAME];
  59. wchar_t m_szCount[MAX_COUNT_STRING];
  60. CMaterialReference m_matIcon;
  61. bool m_bHiding;
  62. bool m_bSoundStarted;
  63. // Painting
  64. CPanelAnimationVarAliasType( int, m_iBarX, "bar_xpos", "8", "proportional_int" );
  65. CPanelAnimationVarAliasType( int, m_iBarY, "bar_ypos", "8", "proportional_int" );
  66. CPanelAnimationVarAliasType( int, m_iBarTall, "bar_height", "16", "proportional_int" );
  67. CPanelAnimationVarAliasType( int, m_iBarWide, "bar_width", "16", "proportional_int" );
  68. CPanelAnimationVarAliasType( int, m_iSpeakersX, "speaker_xpos", "8", "proportional_int" );
  69. CPanelAnimationVarAliasType( int, m_iSpeakersY, "speaker_ypos", "8", "proportional_int" );
  70. CPanelAnimationVarAliasType( int, m_iCountXFR, "count_xpos_from_right", "8", "proportional_int" );
  71. CPanelAnimationVarAliasType( int, m_iCountY, "count_ypos", "8", "proportional_int" );
  72. CPanelAnimationVarAliasType( int, m_iIconX, "icon_xpos", "8", "proportional_int" );
  73. CPanelAnimationVarAliasType( int, m_iIconY, "icon_ypos", "8", "proportional_int" );
  74. CPanelAnimationVarAliasType( int, m_iIconWide, "icon_width", "8", "proportional_int" );
  75. CPanelAnimationVarAliasType( int, m_iIconTall, "icon_height", "8", "proportional_int" );
  76. CPanelAnimationVarAliasType( int, m_nIconTextureId, "icon_texture", "vgui/hud/icon_commentary", "textureid" );
  77. CPanelAnimationVar( bool, m_bUseScriptBGColor, "use_script_bgcolor", "0" );
  78. CPanelAnimationVar( Color, m_BackgroundColor, "BackgroundColor", "0 0 0 0" );
  79. CPanelAnimationVar( Color, m_BGOverrideColor, "BackgroundOverrideColor", "Panel.BgColor" );
  80. };
  81. bool IsListeningToCommentary( void )
  82. {
  83. CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary );
  84. if ( !pHudCommentary )
  85. {
  86. return false;
  87. }
  88. return pHudCommentary->HasActiveNode();
  89. }
  90. //-----------------------------------------------------------------------------
  91. // Purpose:
  92. //-----------------------------------------------------------------------------
  93. class C_PointCommentaryNode : public C_BaseAnimating
  94. {
  95. DECLARE_CLASS( C_PointCommentaryNode, C_BaseAnimating );
  96. public:
  97. DECLARE_CLIENTCLASS();
  98. DECLARE_DATADESC();
  99. virtual void OnPreDataChanged( DataUpdateType_t type );
  100. virtual void OnDataChanged( DataUpdateType_t type );
  101. void OnRestore( void )
  102. {
  103. BaseClass::OnRestore();
  104. if ( m_bActive )
  105. {
  106. StopLoopingSounds();
  107. m_bRestartAfterRestore = true;
  108. }
  109. AddAndLockCommentaryHudGroup();
  110. }
  111. //-----------------------------------------------------------------------------
  112. // Purpose:
  113. //-----------------------------------------------------------------------------
  114. virtual void SetDormant( bool bDormant )
  115. {
  116. if ( !IsDormant() && bDormant )
  117. {
  118. RemoveAndUnlockCommentaryHudGroup();
  119. }
  120. BaseClass::SetDormant( bDormant );
  121. }
  122. //-----------------------------------------------------------------------------
  123. // Cleanup
  124. //-----------------------------------------------------------------------------
  125. void UpdateOnRemove( void )
  126. {
  127. RemoveAndUnlockCommentaryHudGroup();
  128. StopLoopingSounds();
  129. BaseClass::UpdateOnRemove();
  130. }
  131. void StopLoopingSounds( void );
  132. virtual bool TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace );
  133. void AddAndLockCommentaryHudGroup( void )
  134. {
  135. if ( !g_CommentaryNodes.Count() )
  136. {
  137. HACK_GETLOCALPLAYER_GUARD( "C_PointCommentaryNode::AddAndLockCommentaryHudGroup" );
  138. int iRenderGroup = GetHud().RegisterForRenderGroup( "commentary" );
  139. GetHud().LockRenderGroup( iRenderGroup );
  140. }
  141. if ( g_CommentaryNodes.Find( this ) == g_CommentaryNodes.InvalidIndex() )
  142. {
  143. g_CommentaryNodes.AddToTail( this );
  144. }
  145. }
  146. void RemoveAndUnlockCommentaryHudGroup( void )
  147. {
  148. g_CommentaryNodes.FindAndRemove( this );
  149. if ( !g_CommentaryNodes.Count() )
  150. {
  151. HACK_GETLOCALPLAYER_GUARD( "C_PointCommentaryNode::RemoveAndUnlockCommentaryHudGroup" );
  152. int iRenderGroup = GetHud().RegisterForRenderGroup( "commentary" );
  153. GetHud().UnlockRenderGroup( iRenderGroup );
  154. }
  155. }
  156. CSoundPatch *GetSoundPatch() const
  157. {
  158. return m_sndCommentary;
  159. }
  160. public:
  161. // Data received from the server
  162. bool m_bActive;
  163. bool m_bWasActive;
  164. float m_flStartTime;
  165. char m_iszCommentaryFile[MAX_PATH];
  166. char m_iszCommentaryFileNoHDR[MAX_PATH];
  167. char m_iszSpeakers[MAX_SPEAKER_NAME];
  168. int m_iNodeNumber;
  169. int m_iNodeNumberMax;
  170. CSoundPatch *m_sndCommentary;
  171. EHANDLE m_hViewPosition;
  172. bool m_bRestartAfterRestore;
  173. };
  174. IMPLEMENT_CLIENTCLASS_DT(C_PointCommentaryNode, DT_PointCommentaryNode, CPointCommentaryNode)
  175. RecvPropBool( RECVINFO( m_bActive ) ),
  176. RecvPropTime( RECVINFO( m_flStartTime ) ),
  177. RecvPropString( RECVINFO(m_iszCommentaryFile) ),
  178. RecvPropString( RECVINFO(m_iszCommentaryFileNoHDR) ),
  179. RecvPropString( RECVINFO(m_iszSpeakers) ),
  180. RecvPropInt( RECVINFO( m_iNodeNumber ) ),
  181. RecvPropInt( RECVINFO( m_iNodeNumberMax ) ),
  182. RecvPropEHandle( RECVINFO(m_hViewPosition) ),
  183. END_RECV_TABLE()
  184. BEGIN_DATADESC( C_PointCommentaryNode )
  185. DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ),
  186. DEFINE_FIELD( m_bWasActive, FIELD_BOOLEAN ),
  187. DEFINE_SOUNDPATCH( m_sndCommentary ),
  188. END_DATADESC()
  189. //-----------------------------------------------------------------------------
  190. // Purpose:
  191. //-----------------------------------------------------------------------------
  192. void C_PointCommentaryNode::OnPreDataChanged( DataUpdateType_t updateType )
  193. {
  194. BaseClass::OnPreDataChanged( updateType );
  195. m_bWasActive = m_bActive;
  196. }
  197. //-----------------------------------------------------------------------------
  198. // Purpose:
  199. //-----------------------------------------------------------------------------
  200. void C_PointCommentaryNode::OnDataChanged( DataUpdateType_t updateType )
  201. {
  202. BaseClass::OnDataChanged( updateType );
  203. if ( updateType == DATA_UPDATE_CREATED )
  204. {
  205. AddAndLockCommentaryHudGroup();
  206. }
  207. if ( m_bWasActive == m_bActive && !m_bRestartAfterRestore )
  208. return;
  209. HACK_GETLOCALPLAYER_GUARD( "C_PointCommentaryNode::OnDataChanged" );
  210. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  211. if ( m_bActive && pPlayer )
  212. {
  213. // Use the HDR / Non-HDR version based on whether we're running HDR or not
  214. char *pszCommentaryFile;
  215. if ( g_pMaterialSystemHardwareConfig->GetHDRType() == HDR_TYPE_NONE && m_iszCommentaryFileNoHDR && m_iszCommentaryFileNoHDR[0] )
  216. {
  217. pszCommentaryFile = m_iszCommentaryFileNoHDR;
  218. }
  219. else
  220. {
  221. pszCommentaryFile = m_iszCommentaryFile;
  222. }
  223. if ( !pszCommentaryFile || !pszCommentaryFile[0] )
  224. {
  225. engine->ServerCmd( "commentary_finishnode\n" );
  226. return;
  227. }
  228. EmitSound_t es;
  229. es.m_nChannel = CHAN_STATIC;
  230. es.m_pSoundName = pszCommentaryFile;
  231. es.m_SoundLevel = SNDLVL_GUNFIRE;
  232. es.m_nFlags = SND_SHOULDPAUSE;
  233. CBaseEntity *pSoundEntity;
  234. if ( m_hViewPosition )
  235. {
  236. pSoundEntity = m_hViewPosition;
  237. }
  238. else if ( render->GetViewEntity() )
  239. {
  240. pSoundEntity = cl_entitylist->GetEnt( render->GetViewEntity() );
  241. es.m_SoundLevel = SNDLVL_NONE;
  242. }
  243. else
  244. {
  245. pSoundEntity = pPlayer;
  246. }
  247. CSingleUserRecipientFilter filter( pPlayer );
  248. m_sndCommentary = (CSoundEnvelopeController::GetController()).SoundCreate( filter, pSoundEntity->entindex(), es );
  249. if ( m_sndCommentary )
  250. {
  251. (CSoundEnvelopeController::GetController()).SoundSetCloseCaptionDuration( m_sndCommentary, -1 );
  252. (CSoundEnvelopeController::GetController()).Play( m_sndCommentary, 1.0f, 100, m_flStartTime );
  253. }
  254. // Strip the #off of the commentary file path if there is one
  255. char *pcCommentaryWAVPath = V_stristr( (char*)STRING( CSoundEnvelopeController::GetController().SoundGetName( m_sndCommentary ) ) , "commentary" );
  256. // Get the duration so we know when it finishes
  257. float flDuration = enginesound->GetSoundDuration( pcCommentaryWAVPath ) ;
  258. CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_FULLSCREEN_HUDELEMENT( CHudCloseCaption );
  259. if ( pHudCloseCaption )
  260. {
  261. // This is where we play the commentary close caption (and lock the other captions out).
  262. // Also, if close captions are off we force a caption in non-English
  263. if ( closecaption.GetBool() || ( !closecaption.GetBool() && !english.GetBool() ) )
  264. {
  265. // Clear the close caption element in preparation
  266. pHudCloseCaption->Reset();
  267. // Process the commentary caption
  268. pHudCloseCaption->ProcessCaptionDirect( pszCommentaryFile, flDuration );
  269. // Find the close caption hud element & lock it
  270. pHudCloseCaption->Lock();
  271. }
  272. }
  273. // Tell the HUD element
  274. CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary );
  275. pHudCommentary->StartCommentary( this, m_iszSpeakers, m_iNodeNumber, m_iNodeNumberMax, m_flStartTime, m_flStartTime + flDuration );
  276. }
  277. else if ( m_bWasActive )
  278. {
  279. StopLoopingSounds();
  280. CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary );
  281. if ( pHudCommentary->IsTheActiveNode(this) )
  282. {
  283. pHudCommentary->StopCommentary();
  284. }
  285. }
  286. m_bRestartAfterRestore = false;
  287. }
  288. //-----------------------------------------------------------------------------
  289. // Purpose: Shut down the commentary
  290. //-----------------------------------------------------------------------------
  291. void C_PointCommentaryNode::StopLoopingSounds( void )
  292. {
  293. if ( m_sndCommentary != NULL )
  294. {
  295. (CSoundEnvelopeController::GetController()).SoundDestroy( m_sndCommentary );
  296. m_sndCommentary = NULL;
  297. }
  298. }
  299. //-----------------------------------------------------------------------------
  300. // Purpose: No client side trace collisions
  301. //-----------------------------------------------------------------------------
  302. bool C_PointCommentaryNode::TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace )
  303. {
  304. if ( !g_bTracingVsCommentaryNodes )
  305. return false;
  306. return BaseClass::TestCollision( ray, mask, trace );
  307. }
  308. //-----------------------------------------------------------------------------
  309. // Purpose:
  310. //-----------------------------------------------------------------------------
  311. bool IsNodeUnderCrosshair( C_BasePlayer *pPlayer )
  312. {
  313. // See if the player's looking at a commentary node
  314. trace_t tr;
  315. Vector vecSrc = pPlayer->EyePosition();
  316. Vector vecForward;
  317. AngleVectors( pPlayer->EyeAngles(), &vecForward );
  318. g_bTracingVsCommentaryNodes = true;
  319. UTIL_TraceLine( vecSrc, vecSrc + vecForward * MAX_TRACE_LENGTH, MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr );
  320. g_bTracingVsCommentaryNodes = false;
  321. if ( !tr.m_pEnt )
  322. return false;
  323. return dynamic_cast<C_PointCommentaryNode*>(tr.m_pEnt) ? true : false;
  324. }
  325. //===================================================================================================================
  326. // COMMENTARY HUD ELEMENT
  327. //===================================================================================================================
  328. DECLARE_HUDELEMENT( CHudCommentary );
  329. //-----------------------------------------------------------------------------
  330. // Purpose:
  331. //-----------------------------------------------------------------------------
  332. CHudCommentary::CHudCommentary( const char *name ) : vgui::Panel( NULL, "HudCommentary" ), CHudElement( name )
  333. {
  334. vgui::Panel *pParent = GetClientMode()->GetViewport();
  335. SetParent( pParent );
  336. SetPaintBorderEnabled( false );
  337. SetHiddenBits( HIDEHUD_PLAYERDEAD );
  338. m_hActiveNode = NULL;
  339. m_bShouldPaint = true;
  340. m_bSoundStarted = false;
  341. SetScheme( "basemodui_scheme" );
  342. }
  343. void CHudCommentary::ApplySchemeSettings( vgui::IScheme *pScheme )
  344. {
  345. BaseClass::ApplySchemeSettings( pScheme );
  346. if ( m_bUseScriptBGColor )
  347. {
  348. SetBgColor( m_BGOverrideColor );
  349. }
  350. }
  351. //-----------------------------------------------------------------------------
  352. // Purpose:
  353. //-----------------------------------------------------------------------------
  354. void CHudCommentary::Paint()
  355. {
  356. float flDuration = (m_flEndTime - m_flStartTime);
  357. float flPercentage = 1.0f;
  358. if ( !m_hActiveNode )
  359. {
  360. if ( !m_bHiding )
  361. {
  362. m_bHiding = true;
  363. GetClientMode()->GetViewportAnimationController()->StartAnimationSequence( "HideCommentary" );
  364. CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_FULLSCREEN_HUDELEMENT( CHudCloseCaption );
  365. if ( pHudCloseCaption )
  366. {
  367. pHudCloseCaption->Reset();
  368. }
  369. }
  370. }
  371. else
  372. {
  373. CSoundPatch *pSoundPatch = m_hActiveNode->GetSoundPatch();
  374. float fElapsedTime = CSoundEnvelopeController::GetController().SoundGetElapsedTime( pSoundPatch );
  375. flPercentage = clamp( fElapsedTime / flDuration, 0.0f, 1.0f );
  376. // Detect if we started the commentary (we may not always reach 100% from the elapsed time, and then it gets back to 0% directly)
  377. if ( flPercentage > 0.00f )
  378. {
  379. m_bSoundStarted = true;
  380. }
  381. if ( m_bSoundStarted && ( flPercentage == 0.0f ) && m_hActiveNode )
  382. {
  383. // The sound started and is now finished (elapsed time is 0% as the sound is not present anymore), time to stop.
  384. m_hActiveNode = NULL;
  385. GetClientMode()->GetViewportAnimationController()->StartAnimationSequence( "HideCommentary" );
  386. engine->ServerCmd( "commentary_finishnode\n" );
  387. flPercentage = 1.0f; // Set the percentage to 1, so we don't see the progress bar go back to 0 when it reached the end.
  388. }
  389. }
  390. if ( !m_bShouldPaint )
  391. return;
  392. int x, y, wide, tall;
  393. GetBounds( x, y, wide, tall );
  394. int xOffset = m_iBarX;
  395. int yOffset = m_iBarY;
  396. // Find our fade based on our time shown
  397. Color clr = Color( 255, 170, 0, GetAlpha() );
  398. // Draw the progress bar
  399. vgui::surface()->DrawSetColor( clr );
  400. vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset+m_iBarWide, yOffset+m_iBarTall );
  401. vgui::surface()->DrawSetColor( clr );
  402. vgui::surface()->DrawFilledRect( xOffset+2, yOffset+2, xOffset+(int)(flPercentage*m_iBarWide)-2, yOffset+m_iBarTall-2 );
  403. // Draw the speaker names
  404. // Get our scheme and font information
  405. vgui::HScheme scheme = GetScheme();
  406. vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault", true );
  407. if ( !hFont )
  408. {
  409. hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default", true );
  410. }
  411. vgui::surface()->DrawSetTextFont( hFont );
  412. vgui::surface()->DrawSetTextColor( clr );
  413. vgui::surface()->DrawSetTextPos( m_iSpeakersX, m_iSpeakersY );
  414. vgui::surface()->DrawPrintText( m_szSpeakers, wcslen(m_szSpeakers) );
  415. if ( COMMENTARY_BUTTONS & IN_ATTACK )
  416. {
  417. int iY = m_iBarY + m_iBarTall + YRES(4);
  418. wchar_t wzFinal[512] = L"";
  419. wchar_t *pszText = g_pVGuiLocalize->Find( "#Commentary_PrimaryAttack" );
  420. if ( pszText )
  421. {
  422. UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ) );
  423. vgui::surface()->DrawSetTextPos( m_iSpeakersX, iY );
  424. vgui::surface()->DrawPrintText( wzFinal, wcslen(wzFinal) );
  425. }
  426. pszText = g_pVGuiLocalize->Find( "#Commentary_SecondaryAttack" );
  427. if ( pszText )
  428. {
  429. int w, h;
  430. UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ) );
  431. vgui::surface()->GetTextSize( hFont, wzFinal, w, h );
  432. vgui::surface()->DrawSetTextPos( m_iBarX + m_iBarWide - w, iY );
  433. vgui::surface()->DrawPrintText( wzFinal, wcslen(wzFinal) );
  434. }
  435. }
  436. // Draw the commentary count
  437. // Determine our text size, and move that far in from the right hand size (plus the offset)
  438. int iCountWide, iCountTall;
  439. vgui::surface()->GetTextSize( hFont, m_szCount, iCountWide, iCountTall );
  440. vgui::surface()->DrawSetTextPos( wide - m_iCountXFR - iCountWide, m_iCountY );
  441. vgui::surface()->DrawPrintText( m_szCount, wcslen(m_szCount) );
  442. // Draw the icon
  443. vgui::surface()->DrawSetColor( Color(255,170,0,GetAlpha()) );
  444. vgui::surface()->DrawSetTexture(m_nIconTextureId);
  445. vgui::surface()->DrawTexturedRect( m_iIconX, m_iIconY, m_iIconWide, m_iIconTall );
  446. }
  447. //-----------------------------------------------------------------------------
  448. // Purpose:
  449. //-----------------------------------------------------------------------------
  450. bool CHudCommentary::ShouldDraw()
  451. {
  452. return ( m_hActiveNode || GetAlpha() > 0 );
  453. }
  454. //-----------------------------------------------------------------------------
  455. // Purpose:
  456. //-----------------------------------------------------------------------------
  457. void CHudCommentary::Init( void )
  458. {
  459. m_matIcon.Init( "vgui/hud/icon_commentary", TEXTURE_GROUP_VGUI );
  460. }
  461. //-----------------------------------------------------------------------------
  462. // Purpose:
  463. //-----------------------------------------------------------------------------
  464. void CHudCommentary::VidInit( void )
  465. {
  466. SetAlpha(0);
  467. StopCommentary();
  468. }
  469. //-----------------------------------------------------------------------------
  470. // Purpose:
  471. //-----------------------------------------------------------------------------
  472. void CHudCommentary::StartCommentary( C_PointCommentaryNode *pNode, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime )
  473. {
  474. if ( (flEndTime - flStartTime) <= 0 )
  475. return;
  476. m_hActiveNode = pNode;
  477. m_flStartTime = flStartTime;
  478. m_flEndTime = flEndTime;
  479. m_bSoundStarted = false;
  480. m_bHiding = false;
  481. g_pVGuiLocalize->ConvertANSIToUnicode( pszSpeakers, m_szSpeakers, sizeof(m_szSpeakers) );
  482. // Don't draw the element itself if closecaptions are on (and captions are always on in non-english mode)
  483. ConVarRef pCVar( "closecaption" );
  484. if ( pCVar.IsValid() )
  485. {
  486. m_bShouldPaint = ( !pCVar.GetBool() && english.GetBool() );
  487. }
  488. else
  489. {
  490. m_bShouldPaint = true;
  491. }
  492. SetPaintBackgroundEnabled( m_bShouldPaint );
  493. char sz[MAX_COUNT_STRING];
  494. Q_snprintf( sz, sizeof(sz), "%d \\ %d", iNode, iNodeMax );
  495. g_pVGuiLocalize->ConvertANSIToUnicode( sz, m_szCount, sizeof(m_szCount) );
  496. // If the commentary just started, play the commentary fade in.
  497. if ( fabs(flStartTime - gpGlobals->curtime) < 1.0 )
  498. {
  499. GetClientMode()->GetViewportAnimationController()->StartAnimationSequence( "ShowCommentary" );
  500. }
  501. else
  502. {
  503. // We're reloading a savegame that has an active commentary going in it. Don't fade in.
  504. SetAlpha( 255 );
  505. }
  506. }
  507. //-----------------------------------------------------------------------------
  508. // Purpose:
  509. //-----------------------------------------------------------------------------
  510. void CHudCommentary::StopCommentary( void )
  511. {
  512. m_hActiveNode = NULL;
  513. }
  514. //-----------------------------------------------------------------------------
  515. // Purpose:
  516. //-----------------------------------------------------------------------------
  517. bool CommentaryModeShouldSwallowInput( C_BasePlayer *pPlayer )
  518. {
  519. if ( !IsInCommentaryMode() )
  520. return false;
  521. if ( pPlayer->m_nButtons & COMMENTARY_BUTTONS )
  522. {
  523. // Always steal the secondary attack
  524. if ( pPlayer->m_nButtons & IN_ATTACK2 )
  525. return true;
  526. // See if there's any nodes ahead of us.
  527. if ( IsNodeUnderCrosshair( pPlayer ) )
  528. return true;
  529. }
  530. return false;
  531. }