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.

1900 lines
53 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include "hud_controlpointicons.h"
  8. #include "teamplayroundbased_gamerules.h"
  9. #include "iclientmode.h"
  10. #include "c_team_objectiveresource.h"
  11. #include "c_playerresource.h"
  12. #include "c_baseplayer.h"
  13. #include "VGuiMatSurface/IMatSystemSurface.h"
  14. #include "hud_macros.h"
  15. #include "spectatorgui.h"
  16. #include "c_team.h"
  17. #include "tf_hud_freezepanel.h"
  18. #include "tf_hud_objectivestatus.h"
  19. //-----------------------------------------------------------------------------
  20. // Purpose:
  21. //-----------------------------------------------------------------------------
  22. void CControlPointIconPulseable::ApplySchemeSettings( IScheme *pScheme )
  23. {
  24. BaseClass::ApplySchemeSettings( pScheme );
  25. if ( !m_pPulseImage )
  26. {
  27. m_pPulseImage = scheme()->GetImage( "../sprites/obj_icons/icon_obj_white", true );
  28. }
  29. }
  30. //-----------------------------------------------------------------------------
  31. // Purpose:
  32. //-----------------------------------------------------------------------------
  33. void CControlPointIconPulseable::OnSizeChanged(int newWide, int newTall)
  34. {
  35. if ( m_pPulseImage )
  36. {
  37. // scaling, force the image size to be our size
  38. m_pPulseImage->SetSize(newWide, newTall);
  39. }
  40. BaseClass::OnSizeChanged(newWide, newTall);
  41. }
  42. //-----------------------------------------------------------------------------
  43. // Purpose:
  44. //-----------------------------------------------------------------------------
  45. void CControlPointIconPulseable::PaintBackground( void )
  46. {
  47. if ( IsInFreezeCam() == true )
  48. return;
  49. if ( GetImage() )
  50. {
  51. SetAlpha(255);
  52. BaseClass::PaintBackground();
  53. }
  54. if ( m_flStartCapAnimStart && gpGlobals->curtime > m_flStartCapAnimStart )
  55. {
  56. float flElapsedTime = (gpGlobals->curtime - m_flStartCapAnimStart);
  57. // Pulse the white over the underlying color
  58. float flPulseSpeed = 20;
  59. if ( m_bAccelerateOverCapture )
  60. {
  61. float flCapPercentage = ObjectiveResource()->GetCPCapPercentage( m_iCPIndex );
  62. flPulseSpeed = RemapValClamped( flCapPercentage, 0, 1, 2, 5 );
  63. }
  64. float flPulseMod = fabs(sin( flElapsedTime * flPulseSpeed ));
  65. SetAlpha( 255 * flPulseMod );
  66. int wide, tall;
  67. GetSize( wide, tall );
  68. // Have to reset these - we're only referencing a material so the
  69. // size can be changed by CControlPointIconCapturePulse on a successful cap
  70. m_pPulseImage->SetPos( 0, 0 );
  71. m_pPulseImage->SetSize( wide, tall );
  72. m_pPulseImage->Paint();
  73. // Stop if we're only supposed to do this for a short time
  74. if ( m_flPulseTime && flElapsedTime >= m_flPulseTime )
  75. {
  76. StopPulsing();
  77. }
  78. }
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Purpose:
  82. //-----------------------------------------------------------------------------
  83. void CControlPointIconPulseable::StartPulsing( float flDelay, float flPulseTime, bool bAccelerate )
  84. {
  85. m_flStartCapAnimStart = gpGlobals->curtime + flDelay;
  86. m_bAccelerateOverCapture = bAccelerate;
  87. m_flPulseTime = flPulseTime;
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Purpose:
  91. //-----------------------------------------------------------------------------
  92. void CControlPointIconPulseable::StopPulsing( void )
  93. {
  94. m_flStartCapAnimStart = 0;
  95. }
  96. //-----------------------------------------------------------------------------
  97. // Purpose:
  98. //-----------------------------------------------------------------------------
  99. CControlPointIcon::CControlPointIcon( Panel *parent, const char *pName, int iIndex ) : vgui::EditablePanel( parent, "ControlPointIcon" ), CHudElement( pName )
  100. {
  101. SetHiddenBits( HIDEHUD_MISCSTATUS );
  102. m_iCPIndex = iIndex;
  103. m_pBaseImage = NULL;
  104. m_pOverlayImage = NULL;
  105. m_pCapImage = NULL;
  106. m_pCapHighlightImage = NULL;
  107. m_pCapPulseImage = NULL;
  108. m_pCapPlayerImage = NULL;
  109. m_pCapNumPlayers = NULL;
  110. m_bSwipeUp = false;
  111. m_flStartCapAnimStart = 0;
  112. m_iCapProgressDir = CP_DIR_N;
  113. m_iPrevCappers = 0;
  114. m_pCountdown = NULL;
  115. m_pCPTimerLabel = NULL;
  116. m_pCPTimerBG = NULL;
  117. m_flCPTimerTime = -1.0;
  118. m_bRedText = false;
  119. ListenForGameEvent( "controlpoint_unlock_updated" );
  120. ListenForGameEvent( "controlpoint_timer_updated" );
  121. ivgui()->AddTickSignal( GetVPanel(), 150 );
  122. }
  123. //-----------------------------------------------------------------------------
  124. // Purpose:
  125. //-----------------------------------------------------------------------------
  126. void CControlPointIcon::ApplySchemeSettings( IScheme *pScheme )
  127. {
  128. BaseClass::ApplySchemeSettings( pScheme );
  129. m_cRegularColor = pScheme->GetColor( "TanLight", Color( 235, 226, 202 ) );
  130. m_cHighlightColor = pScheme->GetColor( "RedSolid", Color( 192, 28, 0 ) );
  131. if ( !m_pCapHighlightImage )
  132. {
  133. m_pCapHighlightImage = new CControlPointIconSwoop( this, "CapHighlightImage" );
  134. m_pCapHighlightImage->SetParent( g_pClientMode->GetViewport() );
  135. m_pCapHighlightImage->SetZPos( 10 );
  136. m_pCapHighlightImage->SetShouldScaleImage( true );
  137. }
  138. if ( !m_pCapPulseImage )
  139. {
  140. m_pCapPulseImage = new CControlPointIconCapturePulse( this, "CapPulse" );
  141. m_pCapPulseImage->SetParent( g_pClientMode->GetViewport() );
  142. m_pCapPulseImage->SetZPos( -1 );
  143. m_pCapPulseImage->SetVisible( false );
  144. m_pCapPulseImage->SetShouldScaleImage( true );
  145. }
  146. if ( !m_pBaseImage )
  147. {
  148. m_pBaseImage = new CControlPointIconPulseable( this, "BaseImage", m_iCPIndex );
  149. m_pBaseImage->SetShouldScaleImage( true );
  150. }
  151. if ( !m_pCapImage )
  152. {
  153. m_pCapImage = new CControlPointIconCapArrow( this, this, "CapImage" );
  154. m_pCapImage->SetZPos( 2 );
  155. m_pCapImage->SetVisible( false );
  156. }
  157. if ( !m_pCountdown )
  158. {
  159. m_pCountdown = new CControlPointCountdown( this, "Countdown" );
  160. m_pCountdown->SetZPos( 4 );
  161. m_pCountdown->SetVisible( true );
  162. }
  163. if ( !m_pCPTimerLabel )
  164. {
  165. m_pCPTimerLabel = new CExLabel( this, "CPTimerLabel", L"" );
  166. m_pCPTimerLabel->SetZPos( 0 );
  167. }
  168. if ( !m_pCPTimerBG )
  169. {
  170. m_pCPTimerBG = new vgui::ImagePanel( this, "CPTimerBG" );
  171. m_pCPTimerBG->SetZPos( -1 );
  172. m_pCPTimerBG->SetShouldScaleImage( true );
  173. }
  174. LoadControlSettings( "resource/UI/ControlPointIcon.res" );
  175. m_pCapPlayerImage = dynamic_cast<vgui::ImagePanel *>( FindChildByName("CapPlayerImage") );
  176. m_pCapNumPlayers = dynamic_cast<vgui::Label *>( FindChildByName("CapNumPlayers") );
  177. m_pOverlayImage = dynamic_cast<vgui::ImagePanel *>( FindChildByName("OverlayImage") );
  178. if ( m_pCPTimerLabel )
  179. {
  180. m_pCPTimerLabel->SetParent( GetParent() );
  181. }
  182. if ( m_pCPTimerBG )
  183. {
  184. m_pCPTimerBG->SetParent( GetParent() );
  185. }
  186. UpdateImage();
  187. UpdateCapImage();
  188. }
  189. //-----------------------------------------------------------------------------
  190. // Purpose:
  191. //-----------------------------------------------------------------------------
  192. void CControlPointIcon::FireGameEvent( IGameEvent *event )
  193. {
  194. const char *pszEventName = event->GetName();
  195. if ( FStrEq( pszEventName, "controlpoint_unlock_updated" ) )
  196. {
  197. int iIndex = event->GetInt( "index" );
  198. if ( iIndex == m_iCPIndex )
  199. {
  200. float flTime = event->GetFloat( "time" );
  201. SetUnlockTime( flTime );
  202. }
  203. }
  204. else if ( FStrEq( pszEventName, "controlpoint_timer_updated" ) )
  205. {
  206. int iIndex = event->GetInt( "index" );
  207. if ( iIndex == m_iCPIndex )
  208. {
  209. float flTime = event->GetFloat( "time" );
  210. SetTimerTime( flTime );
  211. }
  212. }
  213. }
  214. //-----------------------------------------------------------------------------
  215. // Purpose:
  216. //-----------------------------------------------------------------------------
  217. CControlPointIcon::~CControlPointIcon( void )
  218. {
  219. if ( m_pCapHighlightImage )
  220. {
  221. m_pCapHighlightImage->MarkForDeletion();
  222. m_pCapHighlightImage = NULL;
  223. }
  224. if ( m_pCapPulseImage )
  225. {
  226. m_pCapPulseImage->MarkForDeletion();
  227. m_pCapPulseImage = NULL;
  228. }
  229. if ( m_pCPTimerLabel )
  230. {
  231. m_pCPTimerLabel->MarkForDeletion();
  232. m_pCPTimerLabel = NULL;
  233. }
  234. if ( m_pCPTimerBG )
  235. {
  236. m_pCPTimerBG->MarkForDeletion();
  237. m_pCPTimerBG = NULL;
  238. }
  239. }
  240. //-----------------------------------------------------------------------------
  241. // Purpose:
  242. //-----------------------------------------------------------------------------
  243. void CControlPointIcon::UpdateImage( void )
  244. {
  245. if ( !ObjectiveResource() )
  246. return;
  247. int iOwner = ObjectiveResource()->GetOwningTeam( m_iCPIndex );
  248. if ( m_pBaseImage )
  249. {
  250. int iOwnerIcon = ObjectiveResource()->GetCPCurrentOwnerIcon( m_iCPIndex, iOwner );
  251. const char *szMatName = GetMaterialNameFromIndex( iOwnerIcon );
  252. if ( IsPointLocked() && !IsPointUnlockCountdownRunning() )
  253. {
  254. m_pBaseImage->SetImage( VarArgs("..\\%s_locked", szMatName ) );
  255. }
  256. else
  257. {
  258. m_pBaseImage->SetImage( VarArgs("..\\%s", szMatName ) );
  259. }
  260. }
  261. if ( m_pOverlayImage )
  262. {
  263. int iOverlayIcon = ObjectiveResource()->GetOverlayForTeam( m_iCPIndex, iOwner );
  264. if ( iOverlayIcon )
  265. {
  266. const char *szMatName = GetMaterialNameFromIndex( iOverlayIcon );
  267. m_pOverlayImage->SetImage( VarArgs("..\\%s", szMatName ) );
  268. m_pOverlayImage->SetVisible( true );
  269. }
  270. else
  271. {
  272. m_pOverlayImage->SetVisible( false );
  273. }
  274. }
  275. // Whenever a successful cap occurs, flash the cap point
  276. if ( m_pCapPulseImage )
  277. {
  278. if ( m_iPrevCappers != 0 && iOwner == m_iPrevCappers )
  279. {
  280. m_iPrevCappers = 0;
  281. if ( ShouldDraw() )
  282. {
  283. m_pCapPulseImage->SetVisible( true );
  284. m_pCapPulseImage->StartPulse( gpGlobals->curtime, GetWide() );
  285. }
  286. m_pBaseImage->StartPulsing( FINISHCAPANIM_SWOOP_LENGTH, 0.5, false );
  287. }
  288. }
  289. }
  290. //-----------------------------------------------------------------------------
  291. // Purpose:
  292. //-----------------------------------------------------------------------------
  293. void CControlPointIcon::UpdateCapImage( void )
  294. {
  295. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  296. if ( !pPlayer )
  297. return;
  298. if ( m_pCapImage )
  299. {
  300. int iCappingTeam = ObjectiveResource()->GetCappingTeam( m_iCPIndex );
  301. int iOwningTeam = ObjectiveResource()->GetOwningTeam( m_iCPIndex );
  302. if ( iCappingTeam != TEAM_UNASSIGNED && iCappingTeam != iOwningTeam )
  303. {
  304. const char *pszCapSwipe = ObjectiveResource()->GetGameSpecificCPCappingSwipe( m_iCPIndex, iCappingTeam );
  305. if ( m_bSwipeUp )
  306. {
  307. m_pCapImage->SetImage( VarArgs("%s_up",pszCapSwipe) );
  308. }
  309. else
  310. {
  311. m_pCapImage->SetImage( pszCapSwipe );
  312. }
  313. m_pCapImage->SetVisible( true );
  314. // Tell the cap highlight image to fire up if it's our point being capped
  315. if ( m_pCapHighlightImage && pPlayer->GetTeamNumber() != iCappingTeam && pPlayer->GetTeamNumber() > LAST_SHARED_TEAM )
  316. {
  317. if ( ShouldDraw() && GetParent() && GetParent()->IsVisible() )
  318. {
  319. m_pCapHighlightImage->SetVisible( true );
  320. m_pCapHighlightImage->StartSwoop();
  321. }
  322. m_pBaseImage->StartPulsing( STARTCAPANIM_ICON_SWITCH, 0, true );
  323. }
  324. else
  325. {
  326. m_pBaseImage->StartPulsing( 0, 0, true );
  327. }
  328. if ( m_pCapPlayerImage )
  329. {
  330. m_pCapPlayerImage->SetVisible( true );
  331. }
  332. m_iPrevCappers = iCappingTeam;
  333. InvalidateLayout( true );
  334. }
  335. else
  336. {
  337. m_pBaseImage->StopPulsing();
  338. m_pCapImage->SetVisible( false );
  339. if ( m_pCapHighlightImage )
  340. {
  341. m_pCapHighlightImage->SetVisible( false );
  342. }
  343. if ( m_pCapPlayerImage )
  344. {
  345. m_pCapPlayerImage->SetVisible( false );
  346. }
  347. if ( m_pCapNumPlayers )
  348. {
  349. m_pCapNumPlayers->SetVisible( false );
  350. }
  351. }
  352. }
  353. }
  354. //-----------------------------------------------------------------------------
  355. // Purpose: Lock cap points when neither team can cap them for map-specific reasons
  356. //-----------------------------------------------------------------------------
  357. bool CControlPointIcon::IsPointLocked( void )
  358. {
  359. bool bAnyTeamCanCap = false;
  360. for ( int gameteam = FIRST_GAME_TEAM; gameteam < GetNumberOfTeams(); gameteam++ )
  361. {
  362. // Ignore teams that already own the point
  363. if ( ObjectiveResource()->GetOwningTeam(m_iCPIndex) != gameteam )
  364. {
  365. if ( (ObjectiveResource()->TeamCanCapPoint( m_iCPIndex, gameteam)) )
  366. {
  367. if ( TeamplayGameRules()->TeamMayCapturePoint( gameteam, m_iCPIndex ) )
  368. {
  369. bAnyTeamCanCap = true;
  370. }
  371. }
  372. }
  373. }
  374. return ( !bAnyTeamCanCap );
  375. }
  376. //-----------------------------------------------------------------------------
  377. // Purpose: Lock cap points when neither team can cap them for map-specific reasons
  378. //-----------------------------------------------------------------------------
  379. bool CControlPointIcon::IsPointUnlockCountdownRunning( void )
  380. {
  381. if ( m_pCountdown && ( TeamplayRoundBasedRules() && !TeamplayRoundBasedRules()->IsInWaitingForPlayers() ) )
  382. {
  383. if ( m_pCountdown->GetUnlockTime() > 0 )
  384. {
  385. int nTimeToUnlock = m_pCountdown->GetUnlockTime() - gpGlobals->curtime;
  386. if ( nTimeToUnlock < 6 )
  387. {
  388. return true;
  389. }
  390. }
  391. }
  392. return false;
  393. }
  394. //-----------------------------------------------------------------------------
  395. // Purpose: Used by the intro to fake the pulsing of this icon
  396. //-----------------------------------------------------------------------------
  397. void CControlPointIcon::FakePulse( float flTime )
  398. {
  399. if ( m_pCapPulseImage )
  400. {
  401. m_pCapPulseImage->SetVisible( true );
  402. m_pCapPulseImage->StartPulse( flTime, GetWide() );
  403. m_pBaseImage->StartPulsing( flTime + FINISHCAPANIM_SWOOP_LENGTH - gpGlobals->curtime, 0.8, false );
  404. InvalidateLayout();
  405. }
  406. }
  407. //-----------------------------------------------------------------------------
  408. // Purpose:
  409. //-----------------------------------------------------------------------------
  410. bool CControlPointIcon::IsVisible( void )
  411. {
  412. if ( IsInFreezeCam() == true )
  413. return false;
  414. return BaseClass::IsVisible();
  415. }
  416. //-----------------------------------------------------------------------------
  417. // Purpose:
  418. //-----------------------------------------------------------------------------
  419. void CControlPointIcon::Paint( void )
  420. {
  421. if ( m_bCachedLockedState != IsPointLocked() ||
  422. m_bCachedCountdownState != IsPointUnlockCountdownRunning() )
  423. {
  424. UpdateImage();
  425. }
  426. m_bCachedCountdownState = IsPointUnlockCountdownRunning();
  427. m_bCachedLockedState = IsPointLocked();
  428. BaseClass::Paint();
  429. }
  430. //-----------------------------------------------------------------------------
  431. // Purpose:
  432. //-----------------------------------------------------------------------------
  433. void CControlPointIcon::PerformLayout( void )
  434. {
  435. BaseClass::PerformLayout();
  436. int iBaseXPos, iBaseYPos;
  437. ipanel()->GetAbsPos(GetVPanel(), iBaseXPos, iBaseYPos );
  438. m_pBaseImage->SetBounds( 0, 0, GetWide(), GetTall() );
  439. m_pCountdown->SetBounds( 0, 0, GetWide(), GetTall() );
  440. if ( m_pCapImage->IsVisible() )
  441. {
  442. m_pCapImage->SetBounds( 0, 0, GetWide(), GetTall() );
  443. }
  444. if ( m_pCapHighlightImage->IsVisible() )
  445. {
  446. int iHeight = ScreenHeight() * 0.75;
  447. m_pCapHighlightImage->SetBounds( iBaseXPos + CAP_BOX_INDENT_X, iBaseYPos - iHeight, GetWide() - (CAP_BOX_INDENT_X*2), iHeight + GetTall() -CAP_BOX_INDENT_Y );
  448. }
  449. int iCappingTeam = ObjectiveResource()->GetCappingTeam( m_iCPIndex );
  450. int iPlayers = ObjectiveResource()->GetNumPlayersInArea( m_iCPIndex, iCappingTeam );
  451. if ( m_pCapPlayerImage && !m_pCapPlayerImage->IsVisible() && iPlayers )
  452. {
  453. m_pCapPlayerImage->SetVisible(true);
  454. }
  455. if ( m_pCapPlayerImage && m_pCapPlayerImage->IsVisible() )
  456. {
  457. if ( !iPlayers )
  458. {
  459. // We're a deteriorating point
  460. m_pCapPlayerImage->SetVisible( false );
  461. if ( m_pCapNumPlayers )
  462. {
  463. m_pCapNumPlayers->SetVisible( false );
  464. }
  465. }
  466. else
  467. {
  468. int iXPos, iYPos;
  469. if ( ( iPlayers < 2 ) || !m_pCapNumPlayers )
  470. {
  471. iXPos = (GetWide() - m_pCapPlayerImage->GetWide()) * 0.5;
  472. }
  473. else
  474. {
  475. iXPos = (GetWide() - m_pCapPlayerImage->GetWide()) * 0.5 - XRES(4);
  476. }
  477. iYPos = (GetTall() - m_pCapPlayerImage->GetTall()) * 0.5;
  478. m_pCapPlayerImage->SetPos( iXPos, iYPos );
  479. if ( m_pCapNumPlayers )
  480. {
  481. m_pCapNumPlayers->SetVisible( (iPlayers>1) );
  482. SetDialogVariable( "numcappers", iPlayers );
  483. m_pCapNumPlayers->SetFgColor( Color(0,0,0,255) );
  484. }
  485. }
  486. }
  487. if ( m_pCapPulseImage )
  488. {
  489. int iSize = GetWide() * 3;
  490. int iXpos = iBaseXPos - ((iSize-GetWide()) * 0.5);
  491. int iYpos = iBaseYPos - ((iSize-GetTall()) * 0.5);
  492. m_pCapPulseImage->SetBounds( iXpos, iYpos, iSize, iSize );
  493. }
  494. SetTimerTime( m_flCPTimerTime );
  495. }
  496. //-----------------------------------------------------------------------------
  497. // Purpose:
  498. //-----------------------------------------------------------------------------
  499. void CControlPointIcon::OnTick( void )
  500. {
  501. if ( m_flCPTimerTime < 0 )
  502. return;
  503. if ( !m_pCPTimerLabel || !m_pCPTimerLabel->IsVisible() )
  504. return;
  505. int nTime = 0;
  506. if ( m_flCPTimerTime - gpGlobals->curtime > 0 )
  507. {
  508. nTime = ceil( m_flCPTimerTime - gpGlobals->curtime );
  509. }
  510. if ( nTime <= 10 ) // start flashing with 10 seconds left
  511. {
  512. if ( m_bRedText )
  513. {
  514. m_bRedText = false;
  515. m_pCPTimerLabel->SetFgColor( m_cRegularColor );
  516. }
  517. else
  518. {
  519. m_bRedText = true;
  520. m_pCPTimerLabel->SetFgColor( m_cHighlightColor );
  521. }
  522. }
  523. char szTime[4];
  524. Q_snprintf( szTime, sizeof( szTime ), "%d", nTime );
  525. m_pCPTimerLabel->SetText( szTime );
  526. }
  527. //-----------------------------------------------------------------------------
  528. // Purpose:
  529. //-----------------------------------------------------------------------------
  530. void CControlPointIcon::SetTimerTime( float flTime )
  531. {
  532. m_flCPTimerTime = flTime;
  533. if ( m_pCPTimerBG && m_pCPTimerLabel )
  534. {
  535. if ( flTime < 0 )
  536. {
  537. m_pCPTimerBG->SetVisible( false );
  538. m_pCPTimerLabel->SetVisible( false );
  539. }
  540. else
  541. {
  542. int xPos, yPos;
  543. GetPos( xPos, yPos );
  544. m_pCPTimerBG->SetPos( xPos, yPos );
  545. m_pCPTimerBG->SetVisible( true );
  546. m_bRedText = false;
  547. m_pCPTimerLabel->SetFgColor( m_cRegularColor ); // reset our color
  548. m_pCPTimerLabel->SetPos( xPos + GetWide() - XRES(1), yPos + ( GetTall() / 2 ) - ( m_pCPTimerLabel->GetTall() / 2 ) );
  549. m_pCPTimerLabel->SetVisible( true );
  550. OnTick(); // call this now so our time gets initialized
  551. }
  552. }
  553. }
  554. //-----------------------------------------------------------------------------
  555. // Purpose:
  556. //-----------------------------------------------------------------------------
  557. CHudControlPointIcons::CHudControlPointIcons( const char *pName ) : vgui::Panel( NULL, "HudControlPointIcons" ), CHudElement( pName )
  558. {
  559. SetParent( g_pClientMode->GetViewport() );
  560. SetHiddenBits( HIDEHUD_MISCSTATUS );
  561. m_iBackgroundTexture = vgui::surface()->DrawGetTextureId( "vgui/white" );
  562. if ( m_iBackgroundTexture == -1 )
  563. {
  564. m_iBackgroundTexture = vgui::surface()->CreateNewTextureID();
  565. vgui::surface()->DrawSetTextureFile( m_iBackgroundTexture, "vgui/white", true, true );
  566. }
  567. Reset();
  568. // Initialize textures to invalid
  569. for( int i = 0; i < ARRAYSIZE( m_iCPTextures ); i++ )
  570. {
  571. m_iCPTextures[i] = -1;
  572. m_iCPCappingTextures[i] = -1;
  573. }
  574. for( int i = FIRST_GAME_TEAM; i < MAX_TEAMS; i++ )
  575. {
  576. m_iTeamBaseTextures[i] = -1;
  577. }
  578. }
  579. DECLARE_HUDELEMENT( CHudControlPointIcons );
  580. //-----------------------------------------------------------------------------
  581. // Purpose:
  582. //-----------------------------------------------------------------------------
  583. CHudControlPointIcons::~CHudControlPointIcons( void )
  584. {
  585. ShutdownIcons();
  586. if ( vgui::surface() )
  587. {
  588. // Clear out all the texture IDs
  589. for( int i = 0; i < ARRAYSIZE( m_iCPTextures ); i++ )
  590. {
  591. if ( m_iCPTextures[i] != -1 )
  592. {
  593. vgui::surface()->DestroyTextureID( m_iCPTextures[i] );
  594. m_iCPTextures[i] = -1;
  595. }
  596. if ( m_iCPCappingTextures[i] != -1 )
  597. {
  598. vgui::surface()->DestroyTextureID( m_iCPCappingTextures[i] );
  599. m_iCPCappingTextures[i] = -1;
  600. }
  601. }
  602. for( int i = FIRST_GAME_TEAM; i < MAX_TEAMS; i++ )
  603. {
  604. if ( m_iTeamBaseTextures[i] != -1 )
  605. {
  606. vgui::surface()->DestroyTextureID( m_iTeamBaseTextures[i] );
  607. m_iTeamBaseTextures[i] = -1;
  608. }
  609. }
  610. }
  611. }
  612. //-----------------------------------------------------------------------------
  613. // Purpose:
  614. //-----------------------------------------------------------------------------
  615. void CHudControlPointIcons::Init( void )
  616. {
  617. for( int i = 0; i < ARRAYSIZE( m_iCPTextures ); i++ )
  618. {
  619. if ( m_iCPTextures[i] == -1 )
  620. {
  621. m_iCPTextures[i] = vgui::surface()->CreateNewTextureID();
  622. }
  623. if ( m_iCPCappingTextures[i] == -1 )
  624. {
  625. m_iCPCappingTextures[i] = vgui::surface()->CreateNewTextureID();
  626. }
  627. }
  628. for( int i = FIRST_GAME_TEAM; i < MAX_TEAMS; i++ )
  629. {
  630. if ( m_iTeamBaseTextures[i] == -1 )
  631. {
  632. m_iTeamBaseTextures[i] = vgui::surface()->CreateNewTextureID();
  633. }
  634. }
  635. ListenForGameEvent( "controlpoint_initialized" );
  636. ListenForGameEvent( "controlpoint_updateimages" );
  637. ListenForGameEvent( "controlpoint_updatelayout" );
  638. ListenForGameEvent( "controlpoint_updatecapping" );
  639. ListenForGameEvent( "controlpoint_starttouch" );
  640. ListenForGameEvent( "controlpoint_endtouch" );
  641. ListenForGameEvent( "controlpoint_pulse_element" );
  642. ListenForGameEvent( "controlpoint_fake_capture" );
  643. ListenForGameEvent( "controlpoint_fake_capture_mult" );
  644. ListenForGameEvent( "intro_nextcamera" );
  645. ListenForGameEvent( "intro_finish" );
  646. }
  647. //-----------------------------------------------------------------------------
  648. // Purpose:
  649. //-----------------------------------------------------------------------------
  650. void CHudControlPointIcons::Reset( void )
  651. {
  652. m_iCurrentCP = -1;
  653. m_iLastCP = -1;
  654. m_flIconExpand = 0;
  655. m_flPulseTime = 0;
  656. }
  657. //-----------------------------------------------------------------------------
  658. // Purpose:
  659. //-----------------------------------------------------------------------------
  660. bool CHudControlPointIcons::IsVisible( void )
  661. {
  662. if ( IsInFreezeCam() == true )
  663. return false;
  664. if ( CHudElement::ShouldDraw() == false )
  665. return false;
  666. return BaseClass::IsVisible();
  667. }
  668. //-----------------------------------------------------------------------------
  669. // Purpose:
  670. //-----------------------------------------------------------------------------
  671. void CHudControlPointIcons::LevelShutdown( void )
  672. {
  673. ShutdownIcons();
  674. }
  675. //-----------------------------------------------------------------------------
  676. // Purpose:
  677. //-----------------------------------------------------------------------------
  678. void CHudControlPointIcons::FireGameEvent( IGameEvent *event )
  679. {
  680. const char *eventname = event->GetName();
  681. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  682. if ( FStrEq( "controlpoint_initialized", eventname ) )
  683. {
  684. // Create our control points
  685. InitIcons();
  686. return;
  687. }
  688. if ( FStrEq( "controlpoint_updateimages", eventname ) )
  689. {
  690. // Update the images of our control point icons
  691. int iIndex = event->GetInt( "index" );
  692. if ( iIndex == -1 )
  693. {
  694. for (int i = 0; i < m_Icons.Count(); i++)
  695. {
  696. m_Icons[i]->UpdateImage();
  697. }
  698. }
  699. else
  700. {
  701. // Only invalidate the specified cap point
  702. for (int i = 0; i < m_Icons.Count(); i++)
  703. {
  704. if ( m_Icons[i]->GetCapIndex() == iIndex )
  705. {
  706. m_Icons[i]->UpdateImage();
  707. }
  708. }
  709. }
  710. UpdateProgressBarFor( iIndex );
  711. return;
  712. }
  713. if ( FStrEq( "controlpoint_updatelayout", eventname ) )
  714. {
  715. // Update the layout of our control point icons
  716. int iIndex = event->GetInt( "index" );
  717. if ( iIndex == -1 )
  718. {
  719. InvalidateLayout();
  720. }
  721. else
  722. {
  723. // Only invalidate the specified cap point
  724. for (int i = 0; i < m_Icons.Count(); i++)
  725. {
  726. if ( m_Icons[i]->GetCapIndex() == iIndex )
  727. {
  728. m_Icons[i]->InvalidateLayout();
  729. }
  730. }
  731. }
  732. UpdateProgressBarFor( iIndex );
  733. return;
  734. }
  735. if ( FStrEq( "controlpoint_updatecapping", eventname ) )
  736. {
  737. // Update the capping status of our control point icons
  738. int iIndex = event->GetInt( "index" );
  739. if ( iIndex == -1 )
  740. {
  741. for (int i = 0; i < m_Icons.Count(); i++)
  742. {
  743. m_Icons[i]->UpdateCapImage();
  744. }
  745. }
  746. else
  747. {
  748. // Only invalidate the specified cap point
  749. for (int i = 0; i < m_Icons.Count(); i++)
  750. {
  751. if ( m_Icons[i]->GetCapIndex() == iIndex )
  752. {
  753. m_Icons[i]->UpdateCapImage();
  754. }
  755. }
  756. }
  757. UpdateProgressBarFor( iIndex );
  758. return;
  759. }
  760. if ( FStrEq( "controlpoint_starttouch", eventname ) )
  761. {
  762. int iPlayer = event->GetInt( "player" );
  763. if ( pPlayer && iPlayer == pPlayer->entindex() )
  764. {
  765. m_iCurrentCP = event->GetInt( "area" );
  766. UpdateProgressBarFor( m_iCurrentCP );
  767. }
  768. }
  769. else if ( FStrEq( "controlpoint_endtouch", eventname ) )
  770. {
  771. int iPlayer = event->GetInt( "player" );
  772. if ( pPlayer && iPlayer == pPlayer->entindex() )
  773. {
  774. m_iCurrentCP = -1;
  775. UpdateProgressBarFor( m_iCurrentCP );
  776. }
  777. }
  778. else if ( FStrEq( "controlpoint_pulse_element", eventname ) )
  779. {
  780. int iPlayer = event->GetInt( "player" );
  781. if ( pPlayer && iPlayer == pPlayer->entindex() )
  782. {
  783. for (int i = 0; i < m_Icons.Count(); i++)
  784. {
  785. m_Icons[i]->FakePulse( gpGlobals->curtime + (i * PULSE_TIME_PER_ICON) );
  786. }
  787. }
  788. }
  789. else if ( FStrEq( "controlpoint_fake_capture", eventname ) )
  790. {
  791. int iPlayer = event->GetInt( "player" );
  792. if ( pPlayer && iPlayer == pPlayer->entindex() )
  793. {
  794. m_iCurrentCP = event->GetInt( "int_data" );
  795. m_bFakingCapture = true;
  796. m_bFakingCaptureMult = false;
  797. m_flFakeCaptureTime = gpGlobals->curtime + FAKE_CAPTURE_TIME + FAKE_CAPTURE_POST_PAUSE;
  798. UpdateProgressBarFor( -1 );
  799. }
  800. }
  801. else if ( FStrEq( "controlpoint_fake_capture_mult", eventname ) )
  802. {
  803. int iPlayer = event->GetInt( "player" );
  804. if ( pPlayer && iPlayer == pPlayer->entindex() )
  805. {
  806. m_iCurrentCP = event->GetInt( "int_data" );
  807. m_bFakingCapture = true;
  808. m_bFakingCaptureMult = true;
  809. m_flFakeCaptureTime = gpGlobals->curtime + FAKE_CAPTURE_TIME + FAKE_CAPTURE_POST_PAUSE;
  810. UpdateProgressBarFor( -1 );
  811. }
  812. }
  813. else if ( FStrEq( "intro_nextcamera", eventname ) )
  814. {
  815. int iPlayer = event->GetInt( "player" );
  816. if ( pPlayer && iPlayer == pPlayer->entindex() )
  817. {
  818. m_iCurrentCP = -1;
  819. m_bFakingCapture = false;
  820. m_bFakingCaptureMult = false;
  821. UpdateProgressBarFor( -1 );
  822. }
  823. }
  824. else if ( FStrEq( "intro_finish", eventname ) )
  825. {
  826. int iPlayer = event->GetInt( "player" );
  827. if ( pPlayer && iPlayer == pPlayer->entindex() )
  828. {
  829. m_iCurrentCP = -1;
  830. m_flPulseTime = 0;
  831. m_bFakingCapture = false;
  832. m_bFakingCaptureMult = false;
  833. InitIcons();
  834. }
  835. }
  836. }
  837. //-----------------------------------------------------------------------------
  838. // Purpose:
  839. //-----------------------------------------------------------------------------
  840. void CHudControlPointIcons::ApplySchemeSettings( IScheme *pScheme )
  841. {
  842. BaseClass::ApplySchemeSettings( pScheme );
  843. m_hTextFont = pScheme->GetFont( "ChatFont" );
  844. m_clrBackground = pScheme->GetColor( "HudPanelBackground", GetFgColor() );
  845. m_clrBorder = pScheme->GetColor( "HudPanelBorder", GetBgColor() );
  846. }
  847. //-----------------------------------------------------------------------------
  848. // Purpose:
  849. //-----------------------------------------------------------------------------
  850. void CHudControlPointIcons::PerformLayout( void )
  851. {
  852. BaseClass::PerformLayout();
  853. int iCapPointLines[MAX_CONTROL_POINTS][MAX_CONTROL_POINTS];
  854. memset( iCapPointLines, 0, sizeof(int) * MAX_CONTROL_POINTS * MAX_CONTROL_POINTS );
  855. bool bUseDefaultLines = true;
  856. if ( ObjectiveResource() )
  857. {
  858. // Allow the objective resource to override it
  859. const char *pszLayout = ObjectiveResource()->GetCapLayoutInHUD();
  860. if ( pszLayout && pszLayout[0] )
  861. {
  862. bUseDefaultLines = false;
  863. // Cap layout is a string with indexes of cap points seperated by ',' to denote
  864. // a new line. So "3,1 2" would create a pyramid, with cap point 3 on the
  865. // first line, and caps 1 & 2 on the second line.
  866. int iLine = 0;
  867. int iCapIndex = 0;
  868. char szBuffer[MAX_CAPLAYOUT_LENGTH];
  869. Q_strncpy( szBuffer, pszLayout, MAX_CAPLAYOUT_LENGTH );
  870. char *pszChar = szBuffer;
  871. char *pszLastNumber = pszChar;
  872. while ( *pszChar )
  873. {
  874. pszChar++;
  875. if ( *pszChar == ' ' || *pszChar == ',' )
  876. {
  877. // Get the number
  878. char cOrg = *pszChar;
  879. *pszChar = '\0';
  880. int iCPIndex = atoi( pszLastNumber );
  881. int iIconIndex = -1;
  882. for (int i = 0; i < m_Icons.Count(); i++)
  883. {
  884. if ( m_Icons[i]->GetCapIndex() == iCPIndex )
  885. {
  886. iIconIndex = i;
  887. break;
  888. }
  889. }
  890. if ( iIconIndex != -1 )
  891. {
  892. iCapPointLines[iLine][iCapIndex] = iIconIndex+1;
  893. *pszChar = cOrg;
  894. if ( *pszChar == ',' )
  895. {
  896. iLine++;
  897. iCapIndex = 0;
  898. }
  899. else
  900. {
  901. iCapIndex++;
  902. }
  903. }
  904. // Walk past the ,/space
  905. pszChar++;
  906. pszLastNumber = pszChar;
  907. }
  908. }
  909. // Now get the trailing number
  910. int iCPIndex = atoi( pszLastNumber );
  911. for (int i = 0; i < m_Icons.Count(); i++)
  912. {
  913. if ( m_Icons[i]->GetCapIndex() == iCPIndex )
  914. {
  915. iCapPointLines[iLine][iCapIndex] = i+1;
  916. break;
  917. }
  918. }
  919. }
  920. }
  921. if ( bUseDefaultLines )
  922. {
  923. // By default, put all the caps on a single line
  924. int iCPIndex = 0;
  925. for (int iIcon = 0; iIcon < m_Icons.Count(); iIcon++)
  926. {
  927. iCapPointLines[0][iCPIndex] = iIcon+1;
  928. iCPIndex++;
  929. }
  930. }
  931. int iTall = m_iIconGapHeight;
  932. int iTallest = m_iIconGapHeight;
  933. int iWidest = m_iIconGapWidth;
  934. int iTotalIconsPerLine[MAX_CONTROL_POINTS];
  935. int iLineWidth[MAX_CONTROL_POINTS];
  936. memset( iTotalIconsPerLine, 0, sizeof(int) * MAX_CONTROL_POINTS );
  937. memset( iLineWidth, 0, sizeof(int) * MAX_CONTROL_POINTS );
  938. int iTotalLines = 0;
  939. // Search through the lines and figure out our overall width & height
  940. for ( int iLine = 0; iLine < MAX_CONTROL_POINTS; iLine++ )
  941. {
  942. // If we've hit a line with nothing in it, we're done
  943. if ( !iCapPointLines[iLine][0] )
  944. break;
  945. iTotalLines++;
  946. iLineWidth[iLine] = m_iIconGapWidth;
  947. int iLineTall = 0;
  948. for ( int iPosition = 0; iPosition < MAX_CONTROL_POINTS; iPosition++ )
  949. {
  950. int iIconIndex = iCapPointLines[iLine][iPosition];
  951. if ( !iIconIndex )
  952. break;
  953. iIconIndex--;
  954. // Add the icon dimensions to our counts.
  955. if ( iIconIndex >= 0 && iIconIndex < m_Icons.Count() )
  956. {
  957. m_Icons[iIconIndex]->PerformLayout();
  958. iTotalIconsPerLine[iLine]++;
  959. iLineWidth[iLine] += m_Icons[iIconIndex]->GetWide() + m_iIconGapWidth;
  960. int iHeight = m_Icons[iIconIndex]->GetTall();
  961. if ( iHeight > iLineTall )
  962. {
  963. iLineTall = iHeight;
  964. }
  965. }
  966. }
  967. if ( iLineWidth[iLine] > iWidest )
  968. {
  969. iWidest = iLineWidth[iLine];
  970. }
  971. if ( iLineTall > iTallest )
  972. {
  973. iTallest = iLineTall;
  974. }
  975. iTall += iLineTall + m_iIconGapHeight;
  976. }
  977. // Setup the main panel
  978. float flPositionX = (ScreenWidth() - iWidest) * 0.5;
  979. float flPositionY = ScreenHeight() - iTall - m_nHeightOffset;
  980. if ( ObjectiveResource() )
  981. {
  982. float flCustomPositionX = -1.f;
  983. float flCustomPositionY = -1.f;
  984. ObjectiveResource()->GetCapLayoutCustomPosition( flCustomPositionX, flCustomPositionY );
  985. if ( flCustomPositionX != -1.f )
  986. {
  987. flPositionX = flCustomPositionX * ScreenWidth();
  988. }
  989. if ( flCustomPositionY != -1.f )
  990. {
  991. flPositionY = flCustomPositionY * ScreenHeight();
  992. }
  993. }
  994. SetBounds( flPositionX, flPositionY, iWidest, iTall );
  995. // Now that we know how wide we are, and how many icons are in each line,
  996. // we can lay the icons out, centered in the lines.
  997. for ( int iLine = 0; iLine < MAX_CONTROL_POINTS; iLine++ )
  998. {
  999. if ( !iTotalIconsPerLine[iLine] )
  1000. break;
  1001. int iLineXPos = ((iWidest - iLineWidth[iLine]) * 0.5) + m_iIconGapWidth;
  1002. int iLineYPos = (iLine * m_iIconGapHeight) + ( iLine * iTallest ) + m_iIconGapHeight;
  1003. for ( int iPosition = 0; iPosition < MAX_CONTROL_POINTS; iPosition++ )
  1004. {
  1005. int iIconIndex = iCapPointLines[iLine][iPosition];
  1006. if ( !iIconIndex )
  1007. break;
  1008. iIconIndex--;
  1009. if ( iIconIndex >= 0 && iIconIndex < m_Icons.Count() )
  1010. {
  1011. m_Icons[iIconIndex]->SetPos( iLineXPos, iLineYPos );
  1012. iLineXPos += m_Icons[iIconIndex]->GetWide() + m_iIconGapWidth;
  1013. // If we have multiple lines, swipe up when capping
  1014. m_Icons[iIconIndex]->SetSwipeUp( iTotalLines > 1 );
  1015. // Set the progress extrusion dir:
  1016. // N if we're on the top line. Otherwise:
  1017. // NW if we're left of the center.
  1018. // NE if we're at or right of the center.
  1019. int iDir = CP_DIR_N;
  1020. if ( iLine > 0 )
  1021. {
  1022. if ( ((float)(iPosition+1) / (float)iTotalIconsPerLine[iLine]) > 0.5 )
  1023. {
  1024. iDir = CP_DIR_NE;
  1025. }
  1026. else
  1027. {
  1028. iDir = CP_DIR_NW;
  1029. }
  1030. }
  1031. m_Icons[iIconIndex]->SetCapProgressDir( iDir );
  1032. }
  1033. }
  1034. }
  1035. }
  1036. //-----------------------------------------------------------------------------
  1037. // Purpose:
  1038. //-----------------------------------------------------------------------------
  1039. void CHudControlPointIcons::UpdateProgressBarFor( int iIndex )
  1040. {
  1041. // If they tell us to update all progress bars, update only the one we're standing on
  1042. if ( iIndex == -1 )
  1043. {
  1044. iIndex = m_iCurrentCP;
  1045. }
  1046. // Ignore requests to display progress bars for points we're not standing on
  1047. if ( ( m_iCurrentCP != iIndex ) )
  1048. return;
  1049. // This can happen at level load
  1050. CTFHudObjectiveStatus *pStatus = GET_HUDELEMENT( CTFHudObjectiveStatus );
  1051. if ( pStatus && pStatus->GetControlPointProgressBar() )
  1052. {
  1053. CControlPointProgressBar *pProgressBar = pStatus->GetControlPointProgressBar();
  1054. if ( !IsVisible() || iIndex < 0 || iIndex >= ObjectiveResource()->GetNumControlPoints() )
  1055. {
  1056. pProgressBar->SetupForPoint( NULL );
  1057. }
  1058. else
  1059. {
  1060. for (int i = 0; i < m_Icons.Count(); i++)
  1061. {
  1062. if ( m_Icons[i]->GetCapIndex() == iIndex )
  1063. {
  1064. pProgressBar->SetupForPoint( m_Icons[i] );
  1065. break;
  1066. }
  1067. }
  1068. }
  1069. }
  1070. }
  1071. //-----------------------------------------------------------------------------
  1072. // Purpose: Create the icons we need to display the state of this map's control points
  1073. //-----------------------------------------------------------------------------
  1074. void CHudControlPointIcons::InitIcons( void )
  1075. {
  1076. ShutdownIcons();
  1077. CTFHudObjectiveStatus *pStatus = GET_HUDELEMENT( CTFHudObjectiveStatus );
  1078. if ( pStatus )
  1079. {
  1080. CControlPointProgressBar *pProgressBar = pStatus->GetControlPointProgressBar();
  1081. if ( pProgressBar )
  1082. {
  1083. m_iCurrentCP = -1;
  1084. pProgressBar->SetupForPoint( NULL );
  1085. }
  1086. }
  1087. // Create an icon for each visible control point in this miniround
  1088. int iPoints = ObjectiveResource()->GetNumControlPoints();
  1089. for ( int i = 0; i < iPoints; i++ )
  1090. {
  1091. if ( ObjectiveResource()->IsInMiniRound(i) && ObjectiveResource()->IsCPVisible(i) )
  1092. {
  1093. CControlPointIcon *pIcon = new CControlPointIcon( this, VarArgs( "ControlPointIcon%d", i ), i );
  1094. m_Icons.AddToTail( vgui::SETUP_PANEL(pIcon) );
  1095. }
  1096. }
  1097. InvalidateLayout();
  1098. }
  1099. //-----------------------------------------------------------------------------
  1100. // Purpose:
  1101. //-----------------------------------------------------------------------------
  1102. void CHudControlPointIcons::ShutdownIcons( void )
  1103. {
  1104. for ( int i = 0; i < m_Icons.Count(); i++ )
  1105. {
  1106. m_Icons[i]->MarkForDeletion();
  1107. }
  1108. m_Icons.RemoveAll();
  1109. // if we remove all the icons, we need to make sure the progress bar isn't holding onto one
  1110. CTFHudObjectiveStatus *pStatus = GET_HUDELEMENT( CTFHudObjectiveStatus );
  1111. if ( pStatus )
  1112. {
  1113. CControlPointProgressBar *pProgressBar = pStatus->GetControlPointProgressBar();
  1114. if ( pProgressBar )
  1115. {
  1116. m_iCurrentCP = -1;
  1117. pProgressBar->SetupForPoint( NULL );
  1118. }
  1119. }
  1120. }
  1121. //-----------------------------------------------------------------------------
  1122. // Purpose:
  1123. //-----------------------------------------------------------------------------
  1124. void CHudControlPointIcons::DrawBackgroundBox( int xpos, int ypos, int nBoxWidth, int nBoxHeight, bool bCutCorner )
  1125. {
  1126. int nCornerCutSize = bCutCorner ? m_nCornerCutSize : 0;
  1127. vgui::Vertex_t verts[5];
  1128. verts[0].Init( Vector2D( xpos, ypos ) );
  1129. verts[1].Init( Vector2D( xpos + nBoxWidth, ypos ) );
  1130. verts[2].Init( Vector2D( xpos + nBoxWidth + 1, ypos + nBoxHeight - nCornerCutSize + 1 ) );
  1131. verts[3].Init( Vector2D( xpos + nBoxWidth - nCornerCutSize + 1, ypos + nBoxHeight + 1 ) );
  1132. verts[4].Init( Vector2D( xpos, ypos + nBoxHeight ) );
  1133. vgui::surface()->DrawSetTexture( m_iBackgroundTexture );
  1134. vgui::surface()->DrawSetColor( Color( m_clrBackground ) );
  1135. vgui::surface()->DrawTexturedPolygon( 5, verts );
  1136. vgui::Vertex_t borderverts[5];
  1137. borderverts[0].Init( Vector2D( xpos, ypos ) );
  1138. borderverts[1].Init( Vector2D( xpos + nBoxWidth, ypos ) );
  1139. borderverts[2].Init( Vector2D( xpos + nBoxWidth, ypos + nBoxHeight - nCornerCutSize ) );
  1140. borderverts[3].Init( Vector2D( xpos + nBoxWidth - nCornerCutSize, ypos + nBoxHeight ) );
  1141. borderverts[4].Init( Vector2D( xpos, ypos + nBoxHeight ) );
  1142. vgui::surface()->DrawSetColor( Color( m_clrBorder ) );
  1143. vgui::surface()->DrawTexturedPolyLine( borderverts, 5 );
  1144. }
  1145. //-----------------------------------------------------------------------------
  1146. // Purpose: Draw the team's base icon at either end of the icon panel
  1147. //-----------------------------------------------------------------------------
  1148. bool CHudControlPointIcons::PaintTeamBaseIcon( int index, float flXPos, float flYPos, float flIconSize )
  1149. {
  1150. float uv1 = 0.0f;
  1151. float uv2 = 1.0f;
  1152. // Find out which team owns the far left
  1153. for ( int i = 0; i < MAX_TEAMS; i++ )
  1154. {
  1155. if ( ObjectiveResource()->GetBaseControlPointForTeam(i) == index )
  1156. {
  1157. int iTeamBaseIcon = ObjectiveResource()->GetBaseIconForTeam(i);
  1158. if ( iTeamBaseIcon )
  1159. {
  1160. // Draw the Team's Base texture
  1161. const char *szMatName = GetMaterialNameFromIndex( iTeamBaseIcon );
  1162. vgui::surface()->DrawSetTextureFile( m_iTeamBaseTextures[i], szMatName, true, false );
  1163. Vector2D uv11( uv1, uv1 );
  1164. Vector2D uv21( uv2, uv1 );
  1165. Vector2D uv22( uv2, uv2 );
  1166. Vector2D uv12( uv1, uv2 );
  1167. vgui::Vertex_t vert[4];
  1168. vert[0].Init( Vector2D( flXPos, flYPos ), uv11 );
  1169. vert[1].Init( Vector2D( flXPos + flIconSize, flYPos ), uv21 );
  1170. vert[2].Init( Vector2D( flXPos + flIconSize, flYPos + flIconSize ), uv22 );
  1171. vert[3].Init( Vector2D( flXPos, flYPos + flIconSize ), uv12 );
  1172. vgui::surface()->DrawSetColor( Color(255,255,255,255) );
  1173. vgui::surface()->DrawTexturedPolygon( 4, vert );
  1174. return true;
  1175. }
  1176. }
  1177. }
  1178. return false;
  1179. }
  1180. //-----------------------------------------------------------------------------
  1181. // Purpose:
  1182. //-----------------------------------------------------------------------------
  1183. void CHudControlPointIcons::Paint()
  1184. {
  1185. if ( IsInFreezeCam() == true )
  1186. return;
  1187. if( !ObjectiveResource() )
  1188. return;
  1189. int num = ObjectiveResource()->GetNumControlPoints();
  1190. if ( num <= 0 )
  1191. return; // nothing to draw yet
  1192. //DrawBackgroundBox( 0, 0, GetWide(), GetTall(), false );
  1193. BaseClass::Paint();
  1194. }
  1195. //========================================================================================================================
  1196. // CONTROL POINT PROGRESS BAR
  1197. //========================================================================================================================
  1198. CControlPointProgressBar::CControlPointProgressBar(Panel *parent) : vgui::EditablePanel( parent, "ControlPointProgressBar" )
  1199. {
  1200. m_pAttachedToIcon = NULL;
  1201. m_pBar = NULL;
  1202. m_pBarText = NULL;
  1203. m_pTeardrop = NULL;
  1204. m_pTeardropSide = NULL;
  1205. m_pBlocked = NULL;
  1206. m_iOrgHeight = 0;
  1207. m_iMidGroupIndex = -1;
  1208. }
  1209. //-----------------------------------------------------------------------------
  1210. // Purpose:
  1211. //-----------------------------------------------------------------------------
  1212. void CControlPointProgressBar::ApplySchemeSettings( IScheme *pScheme )
  1213. {
  1214. BaseClass::ApplySchemeSettings( pScheme );
  1215. LoadControlSettings( "resource/UI/ControlPointProgressBar.res" );
  1216. m_pBar = dynamic_cast<vgui::CircularProgressBar *>( FindChildByName("ProgressBar") );
  1217. m_pBarText = dynamic_cast<vgui::Label *>( FindChildByName("ProgressText") );
  1218. m_pTeardrop = dynamic_cast<CIconPanel *>( FindChildByName("Teardrop") );
  1219. m_pTeardropSide = dynamic_cast<CIconPanel *>( FindChildByName("TeardropSide") );
  1220. m_pBlocked = dynamic_cast<CIconPanel *>( FindChildByName("Blocked") );
  1221. m_iOrgHeight = GetTall();
  1222. m_pBar->SetProgressDirection( vgui::CircularProgressBar::PROGRESS_CW );
  1223. m_pBar->SetReverseProgress( true );
  1224. m_iMidGroupIndex = gHUD.LookupRenderGroupIndexByName( "mid" );
  1225. }
  1226. //-----------------------------------------------------------------------------
  1227. // Purpose:
  1228. //-----------------------------------------------------------------------------
  1229. void CControlPointProgressBar::PerformLayout( void )
  1230. {
  1231. BaseClass::PerformLayout();
  1232. if ( m_pAttachedToIcon && m_pTeardrop && m_pTeardropSide && m_pAttachedToIcon->GetVPanel() )
  1233. {
  1234. int iIconX, iIconY;
  1235. ipanel()->GetAbsPos(m_pAttachedToIcon->GetVPanel(), iIconX, iIconY );
  1236. int iDir = m_pAttachedToIcon->GetCapProgressDir();
  1237. int iXPos = 0;
  1238. int iYPos = 0;
  1239. int iEdgeSpace = (GetWide() - m_pTeardrop->GetWide()) * 0.5;
  1240. // Line up our middle with the middle of the icon
  1241. switch ( iDir )
  1242. {
  1243. default:
  1244. case CP_DIR_N:
  1245. SetSize( GetWide(), m_iOrgHeight );
  1246. m_pTeardrop->SetVisible( true );
  1247. m_pTeardropSide->SetVisible( false );
  1248. iXPos = iIconX - ((GetWide() - m_pAttachedToIcon->GetWide()) * 0.5);
  1249. iYPos = iIconY - GetTall();
  1250. break;
  1251. case CP_DIR_NE:
  1252. SetSize( GetWide(), m_iOrgHeight );
  1253. m_pTeardropSide->SetIcon( "cappoint_progressbar_teardrop_right" );
  1254. m_pTeardrop->SetVisible( false );
  1255. m_pTeardropSide->SetVisible( true );
  1256. iXPos = iIconX + m_pAttachedToIcon->GetWide() - iEdgeSpace;
  1257. iYPos = iIconY - GetTall();
  1258. break;
  1259. case CP_DIR_NW:
  1260. SetSize( GetWide(), m_iOrgHeight );
  1261. m_pTeardropSide->SetIcon( "cappoint_progressbar_teardrop_left" );
  1262. m_pTeardrop->SetVisible( false );
  1263. m_pTeardropSide->SetVisible( true );
  1264. iXPos = iIconX - GetWide() + iEdgeSpace;
  1265. iYPos = iIconY - GetTall();
  1266. break;
  1267. }
  1268. SetPos( iXPos, iYPos );
  1269. }
  1270. }
  1271. //-----------------------------------------------------------------------------
  1272. // Purpose:
  1273. //-----------------------------------------------------------------------------
  1274. void CControlPointProgressBar::Reset( void )
  1275. {
  1276. m_pAttachedToIcon = NULL;
  1277. }
  1278. //-----------------------------------------------------------------------------
  1279. // Purpose:
  1280. //-----------------------------------------------------------------------------
  1281. bool CControlPointProgressBar::IsVisible( void )
  1282. {
  1283. if ( IsInFreezeCam() == true )
  1284. return false;
  1285. if ( m_iMidGroupIndex != -1 && gHUD.IsRenderGroupLockedFor( NULL, m_iMidGroupIndex ) )
  1286. return false;
  1287. return BaseClass::IsVisible();
  1288. }
  1289. //-----------------------------------------------------------------------------
  1290. // Purpose:
  1291. //-----------------------------------------------------------------------------
  1292. void CControlPointProgressBar::Paint( void )
  1293. {
  1294. if ( m_pAttachedToIcon )
  1295. {
  1296. int iCP = m_pAttachedToIcon->GetCapIndex();
  1297. if ( m_pBar && m_pBar->IsVisible() )
  1298. {
  1299. m_pBar->SetProgress( ObjectiveResource()->GetCPCapPercentage( iCP ) );
  1300. }
  1301. }
  1302. BaseClass::Paint();
  1303. }
  1304. //-----------------------------------------------------------------------------
  1305. // Purpose:
  1306. //-----------------------------------------------------------------------------
  1307. void CControlPointProgressBar::SetupForPoint( CControlPointIcon *pIcon )
  1308. {
  1309. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  1310. if ( !pPlayer )
  1311. return;
  1312. m_pAttachedToIcon = pIcon;
  1313. bool bInWinState = TeamplayRoundBasedRules() ? TeamplayRoundBasedRules()->RoundHasBeenWon() : false;
  1314. if ( m_pAttachedToIcon && !bInWinState )
  1315. {
  1316. SetVisible( true );
  1317. int iCP = m_pAttachedToIcon->GetCapIndex();
  1318. int iCappingTeam = ObjectiveResource()->GetCappingTeam( iCP );
  1319. int iOwnerTeam = ObjectiveResource()->GetOwningTeam( iCP );
  1320. int iPlayerTeam = pPlayer->GetTeamNumber();
  1321. bool bCapBlocked = ObjectiveResource()->CapIsBlocked( iCP );
  1322. if ( !bCapBlocked && iCappingTeam != TEAM_UNASSIGNED && iCappingTeam != iOwnerTeam && iCappingTeam == iPlayerTeam )
  1323. {
  1324. m_pBar->SetBgImage( ObjectiveResource()->GetGameSpecificCPBarBG( iCP, iCappingTeam ) );
  1325. m_pBar->SetFgImage( ObjectiveResource()->GetGameSpecificCPBarFG( iCP, iOwnerTeam ) );
  1326. m_pBar->SetVisible( true );
  1327. m_pBlocked->SetVisible( false );
  1328. m_pBarText->SetVisible( false );
  1329. }
  1330. else
  1331. {
  1332. m_pBar->SetVisible( false );
  1333. m_pBlocked->SetVisible( true );
  1334. UpdateBarText();
  1335. }
  1336. InvalidateLayout();
  1337. }
  1338. else
  1339. {
  1340. SetVisible( false );
  1341. }
  1342. }
  1343. //-----------------------------------------------------------------------------
  1344. // Purpose:
  1345. //-----------------------------------------------------------------------------
  1346. void CControlPointProgressBar::UpdateBarText( void )
  1347. {
  1348. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  1349. if ( !pPlayer || !m_pBarText || !m_pAttachedToIcon )
  1350. return;
  1351. m_pBarText->SetVisible( true );
  1352. int iCP = m_pAttachedToIcon->GetCapIndex();
  1353. int iCappingTeam = ObjectiveResource()->GetCappingTeam( iCP );
  1354. int iPlayerTeam = pPlayer->GetTeamNumber();
  1355. int iOwnerTeam = ObjectiveResource()->GetOwningTeam( iCP );
  1356. if ( !TeamplayGameRules()->PointsMayBeCaptured() )
  1357. {
  1358. m_pBarText->SetText( "#Team_Capture_NotNow" );
  1359. return;
  1360. }
  1361. if ( ObjectiveResource()->GetCPLocked( iCP ) )
  1362. {
  1363. m_pBarText->SetText( "#Team_Capture_NotNow" );
  1364. return;
  1365. }
  1366. if ( mp_blockstyle.GetInt() == 1 && iCappingTeam != TEAM_UNASSIGNED && iCappingTeam != iPlayerTeam )
  1367. {
  1368. if ( ObjectiveResource()->IsCPBlocked(iCP) )
  1369. {
  1370. m_pBarText->SetText( "#Team_Blocking_Capture" );
  1371. return;
  1372. }
  1373. else if ( iOwnerTeam == TEAM_UNASSIGNED )
  1374. {
  1375. m_pBarText->SetText( "#Team_Reverting_Capture" );
  1376. return;
  1377. }
  1378. }
  1379. if ( ObjectiveResource()->GetOwningTeam(iCP) == iPlayerTeam )
  1380. {
  1381. // If the opponents can never recapture this point back, we use a different string
  1382. if ( iPlayerTeam != TEAM_UNASSIGNED )
  1383. {
  1384. int iEnemyTeam = ( iPlayerTeam == TF_TEAM_RED ) ? TF_TEAM_BLUE : TF_TEAM_RED;
  1385. if ( !ObjectiveResource()->TeamCanCapPoint( iCP, iEnemyTeam ) )
  1386. {
  1387. m_pBarText->SetText( "#Team_Capture_Owned" );
  1388. return;
  1389. }
  1390. }
  1391. m_pBarText->SetText( "#Team_Capture_OwnPoint" );
  1392. return;
  1393. }
  1394. if ( !TeamplayGameRules()->TeamMayCapturePoint( iPlayerTeam, iCP ) )
  1395. {
  1396. if ( TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->IsInArenaMode() == true )
  1397. {
  1398. m_pBarText->SetText( "#Team_Capture_NotNow" );
  1399. }
  1400. else
  1401. {
  1402. m_pBarText->SetText( "#Team_Capture_Linear" );
  1403. }
  1404. return;
  1405. }
  1406. char szReason[256];
  1407. if ( !TeamplayGameRules()->PlayerMayCapturePoint( pPlayer, iCP, szReason, sizeof(szReason) ) )
  1408. {
  1409. m_pBarText->SetText( szReason );
  1410. return;
  1411. }
  1412. bool bHaveRequiredPlayers = true;
  1413. // In Capstyle 1, more players simply cap faster, no required amounts.
  1414. if ( mp_capstyle.GetInt() != 1 )
  1415. {
  1416. int nNumTeammates = ObjectiveResource()->GetNumPlayersInArea( iCP, iPlayerTeam );
  1417. int nRequiredTeammates = ObjectiveResource()->GetRequiredCappers( iCP, iPlayerTeam );
  1418. bHaveRequiredPlayers = (nNumTeammates >= nRequiredTeammates);
  1419. }
  1420. if ( iCappingTeam == iPlayerTeam && bHaveRequiredPlayers )
  1421. {
  1422. m_pBarText->SetText( "#Team_Capture_Blocked" );
  1423. return;
  1424. }
  1425. if ( !ObjectiveResource()->TeamCanCapPoint( iCP, iPlayerTeam ) )
  1426. {
  1427. m_pBarText->SetText( "#Team_Cannot_Capture" );
  1428. return;
  1429. }
  1430. m_pBarText->SetText( "#Team_Waiting_for_teammate" );
  1431. }
  1432. //========================================================================================================================
  1433. // CONTROL POINT CAPTURE ARROW SWIPE
  1434. //========================================================================================================================
  1435. //-----------------------------------------------------------------------------
  1436. // Purpose:
  1437. //-----------------------------------------------------------------------------
  1438. CControlPointIconCapArrow::CControlPointIconCapArrow( CControlPointIcon *pIcon, Panel *parent, const char *name)
  1439. : vgui::Panel( parent, name )
  1440. {
  1441. m_pArrowMaterial = NULL;
  1442. m_pAttachedToIcon = pIcon;
  1443. Assert( m_pAttachedToIcon );
  1444. }
  1445. bool CControlPointIconCapArrow::IsVisible( void )
  1446. {
  1447. if ( IsInFreezeCam() == true )
  1448. return false;
  1449. return BaseClass::IsVisible();
  1450. }
  1451. //-----------------------------------------------------------------------------
  1452. // Purpose:
  1453. //-----------------------------------------------------------------------------
  1454. void CControlPointIconCapArrow::Paint( void )
  1455. {
  1456. if ( !m_pArrowMaterial || !m_pAttachedToIcon )
  1457. return;
  1458. int x = 0;
  1459. int y = 0;
  1460. ipanel()->GetAbsPos(GetVPanel(), x,y );
  1461. int iWidth = GetWide();
  1462. int iHeight = GetTall();
  1463. // Position the arrow based on the cap percentage
  1464. float flXa = 0;
  1465. float flXb = 1.0;
  1466. float flYa = 0;
  1467. float flYb = 1.0;
  1468. int iCappingTeam = ObjectiveResource()->GetCappingTeam( m_pAttachedToIcon->GetCapIndex() );
  1469. float flCapPercentage = ObjectiveResource()->GetCPCapPercentage( m_pAttachedToIcon->GetCapIndex() );
  1470. // The image needs to be remapped to the width of the underlying box,
  1471. // because we want the arrow head to move off the box at the exact time the cap ends.
  1472. float flArrowHeadPixelWidth = 15.0;
  1473. float flArrowBodyPixelWidth = 54.0;
  1474. float flBoxSize = 33.0;
  1475. // HACK: The arrow has an arrowhead portion that looks like this: >
  1476. // We want to start with the arrow entering the image, but we want to keep
  1477. // going until the arrow is fully off the edge. So we include extra width for it.
  1478. float flImageSize = (flArrowHeadPixelWidth+flArrowBodyPixelWidth);
  1479. float flMovementInTextureSpace = ( (flBoxSize+flArrowHeadPixelWidth) / flImageSize );
  1480. float flArrowSizeInTextureSpace = ( flArrowHeadPixelWidth / flImageSize );
  1481. // To help players spot the start & end of a cap, we indent a little on either side.
  1482. float flIndent = 0.07;
  1483. if ( m_pAttachedToIcon->ShouldSwipeUp() )
  1484. {
  1485. flYa = RemapVal( flCapPercentage, 0.0, 1.0, -flMovementInTextureSpace - flIndent, flArrowSizeInTextureSpace - flIndent );
  1486. flYb = RemapVal( flCapPercentage, 0.0, 1.0, flIndent, flMovementInTextureSpace - flIndent );
  1487. }
  1488. else
  1489. {
  1490. flIndent = 0.1;
  1491. float flStart = 1.0 - flIndent;
  1492. float flEnd = 1.0 + flIndent;
  1493. bool bSwipeLeftToRight = ( iCappingTeam % 2 ) ? false : true;
  1494. if ( bSwipeLeftToRight )
  1495. {
  1496. flXa = RemapVal( flCapPercentage, 0.0, 1.0, flStart + flMovementInTextureSpace, flEnd - flArrowSizeInTextureSpace );
  1497. flXb = RemapVal( flCapPercentage, 0.0, 1.0, flStart, 0.0 );
  1498. }
  1499. else
  1500. {
  1501. flXa = RemapVal( flCapPercentage, 0.0, 1.0, flStart, 0.0 );
  1502. flXb = RemapVal( flCapPercentage, 0.0, 1.0, flStart + flMovementInTextureSpace, flEnd - flArrowSizeInTextureSpace );
  1503. }
  1504. }
  1505. CMatRenderContextPtr pRenderContext( materials );
  1506. pRenderContext->Bind( m_pArrowMaterial );
  1507. IMesh* pMesh = pRenderContext->GetDynamicMesh( true );
  1508. CMeshBuilder meshBuilder;
  1509. meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
  1510. meshBuilder.Position3f( x, y, 0.0f );
  1511. meshBuilder.TexCoord2f( 0, flXa, flYa );
  1512. meshBuilder.TexCoord2f( 1, 0.0f, 0.0f );
  1513. meshBuilder.Color4ub( 255, 255, 255, 255 );
  1514. meshBuilder.AdvanceVertex();
  1515. meshBuilder.Position3f( x + iWidth, y, 0.0f );
  1516. meshBuilder.TexCoord2f( 0, flXb, flYa );
  1517. meshBuilder.TexCoord2f( 1, 1.0f, 0.0f );
  1518. meshBuilder.Color4ub( 255, 255, 255, 255 );
  1519. meshBuilder.AdvanceVertex();
  1520. meshBuilder.Position3f( x + iWidth, y + iHeight, 0.0f );
  1521. meshBuilder.TexCoord2f( 0, flXb, flYb );
  1522. meshBuilder.TexCoord2f( 1, 1.0f, 1.0f );
  1523. meshBuilder.Color4ub( 255, 255, 255, 255 );
  1524. meshBuilder.AdvanceVertex();
  1525. meshBuilder.Position3f( x, y + iHeight, 0.0f );
  1526. meshBuilder.TexCoord2f( 0, flXa, flYb );
  1527. meshBuilder.TexCoord2f( 1, 0.0f, 1.0f );
  1528. meshBuilder.Color4ub( 255, 255, 255, 255 );
  1529. meshBuilder.AdvanceVertex();
  1530. meshBuilder.End();
  1531. pMesh->Draw();
  1532. }
  1533. //-----------------------------------------------------------------------------
  1534. // Purpose:
  1535. //-----------------------------------------------------------------------------
  1536. CControlPointCountdown::CControlPointCountdown(Panel *parent, const char *name) : vgui::EditablePanel( parent, name )
  1537. {
  1538. m_bFire5SecRemain = true;
  1539. m_bFire4SecRemain = true;
  1540. m_bFire3SecRemain = true;
  1541. m_bFire2SecRemain = true;
  1542. m_bFire1SecRemain = true;
  1543. m_bFire0SecRemain = true;
  1544. m_flUnlockTime = 0.0f;
  1545. vgui::ivgui()->AddTickSignal( GetVPanel(), 100 );
  1546. SetVisible( true );
  1547. SetDialogVariable( "capturetime", "" );
  1548. }
  1549. //-----------------------------------------------------------------------------
  1550. // Purpose:
  1551. //-----------------------------------------------------------------------------
  1552. void CControlPointCountdown::ApplySchemeSettings( IScheme *pScheme )
  1553. {
  1554. BaseClass::ApplySchemeSettings( pScheme );
  1555. // load control settings...
  1556. LoadControlSettings( "resource/UI/ControlPointCountdown.res" );
  1557. }
  1558. //-----------------------------------------------------------------------------
  1559. // Purpose:
  1560. //-----------------------------------------------------------------------------
  1561. void CControlPointCountdown::PerformLayout()
  1562. {
  1563. CExLabel *pLabel = dynamic_cast<CExLabel *>( FindChildByName( "CapCountdownLabel" ) );
  1564. if ( pLabel )
  1565. {
  1566. pLabel->SetBounds( 0, 0, GetWide(), GetTall() );
  1567. }
  1568. }
  1569. //-----------------------------------------------------------------------------
  1570. // Purpose:
  1571. //-----------------------------------------------------------------------------
  1572. void CControlPointCountdown::SetUnlockTime( float flTime )
  1573. {
  1574. m_flUnlockTime = flTime;
  1575. float flTimeDiff = m_flUnlockTime - gpGlobals->curtime;
  1576. m_bFire5SecRemain = ( flTimeDiff >= 5.0f );
  1577. m_bFire4SecRemain = ( flTimeDiff >= 4.0f );
  1578. m_bFire3SecRemain = ( flTimeDiff >= 3.0f );
  1579. m_bFire2SecRemain = ( flTimeDiff >= 2.0f );
  1580. m_bFire1SecRemain = ( flTimeDiff >= 1.0f );
  1581. }
  1582. //-----------------------------------------------------------------------------
  1583. // Purpose:
  1584. //-----------------------------------------------------------------------------
  1585. void CControlPointCountdown::OnTick( void )
  1586. {
  1587. BaseClass::OnTick();
  1588. C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  1589. if ( !pLocalPlayer || ( m_flUnlockTime <= 0.0f ) )
  1590. {
  1591. if ( IsVisible() )
  1592. {
  1593. SetVisible( false );
  1594. }
  1595. return;
  1596. }
  1597. if ( TeamplayRoundBasedRules() )
  1598. {
  1599. if ( TeamplayRoundBasedRules()->IsInWaitingForPlayers() || TeamplayRoundBasedRules()->State_Get() != GR_STATE_RND_RUNNING )
  1600. {
  1601. return;
  1602. }
  1603. }
  1604. int iTimeLeft = m_flUnlockTime - gpGlobals->curtime;
  1605. if ( iTimeLeft > 5 || iTimeLeft <= 0 )
  1606. {
  1607. if ( iTimeLeft <= 0 && m_bFire0SecRemain )
  1608. {
  1609. m_bFire0SecRemain = false;
  1610. pLocalPlayer->EmitSound( "Announcer.AM_CapEnabledRandom" );
  1611. m_flUnlockTime = 0.0f;
  1612. }
  1613. if ( IsVisible() )
  1614. {
  1615. SetVisible( false );
  1616. }
  1617. return;
  1618. }
  1619. if ( !IsVisible() )
  1620. {
  1621. SetVisible( true );
  1622. }
  1623. wchar_t wzTimeLeft[128];
  1624. _snwprintf( wzTimeLeft, ARRAYSIZE( wzTimeLeft ), L"%i", iTimeLeft );
  1625. SetDialogVariable( "capturetime", wzTimeLeft );
  1626. if ( iTimeLeft <= 5 && m_bFire5SecRemain )
  1627. {
  1628. m_bFire5SecRemain = false;
  1629. pLocalPlayer->EmitSound( "Announcer.RoundBegins5Seconds" );
  1630. }
  1631. else if ( iTimeLeft <= 4 && m_bFire4SecRemain )
  1632. {
  1633. m_bFire4SecRemain = false;
  1634. pLocalPlayer->EmitSound( "Announcer.RoundBegins4Seconds" );
  1635. }
  1636. else if ( iTimeLeft <= 3 && m_bFire3SecRemain )
  1637. {
  1638. m_bFire3SecRemain = false;
  1639. pLocalPlayer->EmitSound( "Announcer.RoundBegins3Seconds" );
  1640. }
  1641. else if ( iTimeLeft <= 2 && m_bFire2SecRemain )
  1642. {
  1643. m_bFire2SecRemain = false;
  1644. pLocalPlayer->EmitSound( "Announcer.RoundBegins2Seconds" );
  1645. }
  1646. else if ( iTimeLeft <= 1 && m_bFire1SecRemain )
  1647. {
  1648. m_bFire1SecRemain = false;
  1649. m_bFire0SecRemain = true;
  1650. pLocalPlayer->EmitSound( "Announcer.RoundBegins1Seconds" );
  1651. }
  1652. }