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.

873 lines
24 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Displays HUD elements for medals/achievements, and hint text
  4. //
  5. //=====================================================================================//
  6. #include "cbase.h"
  7. #include "hud.h"
  8. #include "hudelement.h"
  9. #include "hud_element_helper.h"
  10. #include "iclientmode.h"
  11. #include "view.h"
  12. #include "vgui_controls/Controls.h"
  13. #include "vgui/ISurface.h"
  14. #include "ivrenderview.h"
  15. #include "scaleformui/scaleformui.h"
  16. #include "sfhudinfopanel.h"
  17. #include "vgui/ILocalize.h"
  18. #include "text_message.h"
  19. #include "hud_macros.h"
  20. #include "achievementmgr.h"
  21. #include "fmtstr.h"
  22. #include "sfhudfreezepanel.h"
  23. #include "bannedwords.h"
  24. // memdbgon must be the last include file in a .cpp file!!!
  25. #include "tier0/memdbgon.h"
  26. DECLARE_HUDELEMENT( SFHudInfoPanel );
  27. DECLARE_HUD_MESSAGE( SFHudInfoPanel, HintText );
  28. DECLARE_HUD_MESSAGE( SFHudInfoPanel, KeyHintText );
  29. SFUI_BEGIN_GAME_API_DEF
  30. SFUI_END_GAME_API_DEF( SFHudInfoPanel, HelpAchievementModule ); // Asset named HelpAchievementModule to maintain consistency with Flash file naming
  31. // global tunables for this panel
  32. static float g_HintDisplayTime = 6.f;
  33. static float g_MedalDisplayTime = 5.f;
  34. extern ConVar cl_draw_only_deathnotices;
  35. SFHudInfoPanel::SFHudInfoPanel( const char *value ) : SFHudFlashInterface( value ),
  36. m_HelpPanelHandle(NULL),
  37. m_HelpBodyTextHandle(NULL),
  38. m_MedalPanelHandle(NULL),
  39. m_MedalTitleTextHandle(NULL),
  40. m_MedalBodyTextHandle(NULL),
  41. m_DefusePanelHandle(NULL),
  42. m_DefuseTitleTextHandle(NULL),
  43. m_DefuseBodyTextHandle(NULL),
  44. m_DefuseIconKit( NULL ),
  45. m_DefuseIconNoKit( NULL ),
  46. m_DefuseTimerTextHandle(NULL),
  47. m_PriorityMessagePanelHandle(NULL),
  48. m_PriorityMessageTitleTextHandle(NULL),
  49. m_PriorityMessageBodyTextHandle(NULL),
  50. m_activeAchievement(CSInvalidAchievement),
  51. m_PreviousDefusePercent(-1.0f),
  52. m_bDeferRaiseHelpPanel(false),
  53. m_bHintPanelHidden( false ),
  54. m_bDeferRaisePriorityMessagePanel(false),
  55. m_bIsVisible(false)
  56. {
  57. HOOK_HUD_MESSAGE( SFHudInfoPanel, HintText );
  58. HOOK_HUD_MESSAGE( SFHudInfoPanel, KeyHintText );
  59. SetHiddenBits( HIDEHUD_MISCSTATUS );
  60. m_HintDisplayTimer.Invalidate();
  61. m_AchievementDisplayTimer.Invalidate();
  62. m_PriorityMsgDisplayTimer.Invalidate();
  63. }
  64. SFHudInfoPanel::~SFHudInfoPanel()
  65. {
  66. }
  67. void SFHudInfoPanel::ShowPanel( HUDINFO_TYPE panelType, bool value )
  68. {
  69. if ( m_bActive && m_FlashAPI )
  70. {
  71. WITH_SLOT_LOCKED
  72. {
  73. ShowPanelNoLock( panelType, value );
  74. }
  75. }
  76. }
  77. // Caution! If you call this from code that isn't wrapped with Slot Locks, you will run into run-time multi-threading issues!
  78. void SFHudInfoPanel::ShowPanelNoLock( HUDINFO_TYPE panelType, bool value )
  79. {
  80. if ( m_bActive && FlashAPIIsValid() )
  81. {
  82. WITH_SFVALUEARRAY( data, 1 )
  83. {
  84. m_pScaleformUI->ValueArray_SetElement( data, 0, panelType );
  85. if ( value )
  86. {
  87. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showPanel", data, 1 );
  88. m_bIsVisible = true;
  89. }
  90. else
  91. {
  92. if ( panelType == SFHUDINFO_PriorityMessage ||
  93. panelType == SFHUDINFO_Help )
  94. {
  95. STEAMWORKS_TESTSECRET_AMORTIZE( 149 );
  96. }
  97. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hidePanel", data, 1 );
  98. m_bIsVisible = false;
  99. }
  100. }
  101. }
  102. else
  103. {
  104. // Set the flags so that panels will be raised once this HUD element is visible and loaded
  105. if ( value )
  106. {
  107. if ( panelType == SFHUDINFO_Help )
  108. {
  109. m_bDeferRaiseHelpPanel = true;
  110. }
  111. else if ( panelType == SFHUDINFO_PriorityMessage )
  112. {
  113. m_bDeferRaisePriorityMessagePanel = true;
  114. }
  115. }
  116. }
  117. }
  118. void SFHudInfoPanel::HideAll( void )
  119. {
  120. if ( m_FlashAPI )
  121. {
  122. WITH_SLOT_LOCKED
  123. {
  124. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hideAll", NULL, 0 );
  125. }
  126. m_bIsVisible = false;
  127. // Reset the defuse percent so that we detect the defuse panel needs to be shown again when we un-hide this HUD element
  128. m_PreviousDefusePercent = -1.0f;
  129. }
  130. }
  131. void SFHudInfoPanel::LockSlot( bool wantItLocked, bool& currentlyLocked )
  132. {
  133. if ( currentlyLocked != wantItLocked )
  134. {
  135. if ( wantItLocked )
  136. {
  137. LockScaleformSlot();
  138. }
  139. else
  140. {
  141. UnlockScaleformSlot();
  142. }
  143. currentlyLocked = wantItLocked;
  144. }
  145. }
  146. void SFHudInfoPanel::ProcessInput( void )
  147. {
  148. // Collect information about defuse progress
  149. float DefusePercent = -1.0f;
  150. int DefuseTimeRemaining = -1;
  151. bool bDefuseCanceled = false;
  152. C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer();
  153. bool bSpectating = ( pPlayer && ( pPlayer->GetObserverMode() == OBS_MODE_IN_EYE || pPlayer->GetObserverMode() == OBS_MODE_CHASE ) );
  154. if ( pPlayer && bSpectating )
  155. {
  156. C_BaseEntity *pTarget = pPlayer->GetObserverTarget();
  157. if ( pTarget && pTarget->IsPlayer() )
  158. {
  159. pPlayer = ToCSPlayer( pTarget );
  160. if ( pPlayer && !pPlayer->IsAlive() )
  161. {
  162. pPlayer = NULL;
  163. }
  164. }
  165. else
  166. {
  167. pPlayer = NULL;
  168. }
  169. }
  170. if ( pPlayer )
  171. {
  172. bDefuseCanceled = (pPlayer->m_iProgressBarDuration == 0);
  173. if ( pPlayer->m_iProgressBarDuration > 0 )
  174. {
  175. // ProgressBarStartTime is now with respect to m_flSimulationTime rather than local time
  176. DefusePercent = (pPlayer->m_flSimulationTime - pPlayer->m_flProgressBarStartTime) / (float)pPlayer->m_iProgressBarDuration;
  177. DefusePercent = clamp( DefusePercent, 0.f, 1.f );
  178. DefuseTimeRemaining = static_cast<int>( ceil( (float)pPlayer->m_iProgressBarDuration - (pPlayer->m_flSimulationTime - pPlayer->m_flProgressBarStartTime) ) );
  179. }
  180. }
  181. else
  182. {
  183. // if the player goes away (drops from server, dies, etc) remember to clear any defuse panel for them
  184. if ( m_PreviousDefusePercent >= 0.f )
  185. bDefuseCanceled = true;
  186. }
  187. // Updating flash, slot locking begins
  188. bool bSlotIsLocked = false;
  189. if ( m_HintDisplayTimer.HasStarted() )
  190. {
  191. // Check if the current hint text should go away
  192. if ( m_HintDisplayTimer.IsElapsed() )
  193. {
  194. LockSlot( true, bSlotIsLocked );
  195. // clear the hint, which also clears our timer
  196. SetHintText(NULL);
  197. m_bHintPanelHidden = false;
  198. }
  199. else if ( m_bHintPanelHidden && m_PriorityMsgDisplayTimer.IsElapsed() )
  200. {
  201. // Hint message was defered while a priority message was shown. Bring it back.
  202. LockSlot( true, bSlotIsLocked );
  203. m_bHintPanelHidden = false;
  204. ShowPanelNoLock( SFHUDINFO_Help, true );
  205. }
  206. else if ( m_bActive && m_bDeferRaiseHelpPanel )
  207. {
  208. // The help panel was triggered before the HUD was visible: raise it now
  209. LockSlot( true, bSlotIsLocked );
  210. ShowPanelNoLock( SFHUDINFO_Help, true );
  211. }
  212. }
  213. if ( m_PriorityMsgDisplayTimer.HasStarted() )
  214. {
  215. // Check if the priority message text should go away
  216. if ( m_PriorityMsgDisplayTimer.IsElapsed() )
  217. {
  218. LockSlot( true, bSlotIsLocked );
  219. // clear the hint, which also clears our timer
  220. SetPriorityText( static_cast<wchar_t*>(NULL) );
  221. }
  222. else if ( m_bActive && m_bDeferRaisePriorityMessagePanel )
  223. {
  224. // The priority message panel was triggered before the HUD was visible: raise it now
  225. LockSlot( true, bSlotIsLocked );
  226. ShowPanelNoLock( SFHUDINFO_PriorityMessage, true );
  227. }
  228. }
  229. // Update the defuse UI
  230. if ( DefusePercent >= 0.0f )
  231. {
  232. LockSlot( true, bSlotIsLocked );
  233. // Update the timer text and progress bar
  234. if ( DefuseTimeRemaining >= 0 && m_DefuseTimerTextHandle )
  235. {
  236. char cTimerStr[ 128 ];
  237. int clampedTime = MAX( DefuseTimeRemaining, 0 );
  238. Q_snprintf( cTimerStr, sizeof(cTimerStr), "%02d:%02d", ( clampedTime / 60 ), ( clampedTime % 60 ) );
  239. m_pScaleformUI->Value_SetText( m_DefuseTimerTextHandle, cTimerStr );
  240. }
  241. if ( DefusePercent >= 0.f )
  242. {
  243. WITH_SFVALUEARRAY( data, 1 )
  244. {
  245. m_pScaleformUI->ValueArray_SetElement( data, 0, DefusePercent);
  246. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setDefuseProgress", data, 1 );
  247. }
  248. }
  249. }
  250. if ( m_PreviousDefusePercent < 0.f && DefusePercent >= 0.f )
  251. {
  252. LockSlot( true, bSlotIsLocked );
  253. // activated the defuse process: set our static text once, and then show the panel
  254. if ( m_DefuseTitleTextHandle )
  255. {
  256. if ( pPlayer->m_bIsGrabbingHostage )
  257. m_pScaleformUI->Value_SetText( m_DefuseTitleTextHandle, "#SFUIHUD_InfoPanel_HostageTitle" );
  258. else
  259. m_pScaleformUI->Value_SetText( m_DefuseTitleTextHandle, "#SFUIHUD_InfoPanel_DefuseTitle" );
  260. }
  261. if ( m_DefuseBodyTextHandle )
  262. {
  263. if ( bSpectating )
  264. {
  265. C_CSPlayer *pTargetPlayer = ToCSPlayer( pPlayer->GetObserverTarget() );
  266. if ( pTargetPlayer )
  267. {
  268. wchar_t wszLocalized[100];
  269. wchar_t wszPlayerName[MAX_PLAYER_NAME_LENGTH];
  270. g_pVGuiLocalize->ConvertANSIToUnicode( pTargetPlayer->GetPlayerName(), wszPlayerName, sizeof(wszPlayerName) );
  271. if ( pTargetPlayer->HasDefuser() )
  272. g_pVGuiLocalize->ConstructString( wszLocalized, sizeof( wszLocalized ), g_pVGuiLocalize->Find( "#SFUIHUD_InfoPanel_Spec_DefuseText" ), 1, wszPlayerName );
  273. else
  274. g_pVGuiLocalize->ConstructString( wszLocalized, sizeof( wszLocalized ), g_pVGuiLocalize->Find( "#SFUIHUD_InfoPanel_Spec_DefuseText_NoKit" ), 1, wszPlayerName );
  275. m_pScaleformUI->Value_SetText( m_DefuseBodyTextHandle, wszLocalized );
  276. }
  277. else
  278. {
  279. m_pScaleformUI->Value_SetText( m_DefuseBodyTextHandle, "" );
  280. }
  281. }
  282. else
  283. {
  284. if ( pPlayer->m_bIsGrabbingHostage )
  285. m_pScaleformUI->Value_SetText( m_DefuseBodyTextHandle, "#SFUIHUD_InfoPanel_HostageText" );
  286. else if ( pPlayer->HasDefuser() )
  287. m_pScaleformUI->Value_SetText( m_DefuseBodyTextHandle, "#SFUIHUD_InfoPanel_DefuseText" );
  288. else
  289. m_pScaleformUI->Value_SetText( m_DefuseBodyTextHandle, "#SFUIHUD_InfoPanel_DefuseText_NoKit" );
  290. }
  291. }
  292. if ( m_DefuseIconKit && m_DefuseIconNoKit )
  293. {
  294. bool bHasDefuser = pPlayer->HasDefuser();
  295. m_pScaleformUI->Value_SetVisible( m_DefuseIconKit, bHasDefuser );
  296. m_pScaleformUI->Value_SetVisible( m_DefuseIconNoKit, !bHasDefuser );
  297. }
  298. ShowPanelNoLock( SFHUDINFO_Defuse, true );
  299. }
  300. if ( m_PreviousDefusePercent >= 0.f && bDefuseCanceled )
  301. {
  302. LockSlot( true, bSlotIsLocked );
  303. // stopped defusing: hide the panel
  304. ShowPanelNoLock( SFHUDINFO_Defuse, false );
  305. }
  306. m_PreviousDefusePercent = DefusePercent;
  307. // Update current achievement UI
  308. if ( m_activeAchievement != CSInvalidAchievement )
  309. {
  310. if ( m_AchievementDisplayTimer.HasStarted() && m_AchievementDisplayTimer.IsElapsed() )
  311. {
  312. LockSlot( true, bSlotIsLocked );
  313. m_AchievementDisplayTimer.Invalidate();
  314. // start the hide process on the panel
  315. ShowPanelNoLock( SFHUDINFO_Medal, false );
  316. }
  317. else
  318. {
  319. // Once the panel is fully gone, clear the active achievement so we can display the next one
  320. if ( m_MedalPanelHandle )
  321. {
  322. LockSlot( true, bSlotIsLocked );
  323. ScaleformDisplayInfo dinfo;
  324. m_pScaleformUI->Value_GetDisplayInfo( m_MedalPanelHandle, &dinfo );
  325. if ( !dinfo.GetVisibility() )
  326. {
  327. m_activeAchievement = CSInvalidAchievement;
  328. }
  329. }
  330. }
  331. }
  332. else if ( m_achievementQueue.Count() > 0 )
  333. {
  334. // Grab the next queued achievement and pop it up
  335. AchivementQueueInfo queueInfo = m_achievementQueue.RemoveAtHead();
  336. m_AchievementDisplayTimer.Start( g_MedalDisplayTime );
  337. m_activeAchievement = queueInfo.type;
  338. // [dwenger] Play the achievement earned sound effect
  339. vgui::surface()->PlaySound( "UI/achievement_earned.wav" );
  340. // Here we get the achievement to be displayed and set that in the popup windows
  341. IAchievementMgr *pAchievementMgr = engine->GetAchievementMgr();
  342. if ( !pAchievementMgr )
  343. return;
  344. IAchievement *pAchievement = pAchievementMgr->GetAchievementByID( m_activeAchievement, queueInfo.playerSlot );
  345. if ( pAchievement )
  346. {
  347. LockSlot( true, bSlotIsLocked );
  348. if ( m_MedalTitleTextHandle )
  349. {
  350. m_pScaleformUI->Value_SetText( m_MedalTitleTextHandle, ACHIEVEMENT_LOCALIZED_NAME( pAchievement ) );
  351. }
  352. if ( m_MedalBodyTextHandle )
  353. {
  354. // not showing the text for right now because the body field isn't incorperated into the design, will address later
  355. m_pScaleformUI->Value_SetText( m_MedalBodyTextHandle, "" );
  356. //m_pScaleformUI->Value_SetText( m_MedalBodyTextHandle, ACHIEVEMENT_LOCALIZED_DESC( pAchievement ) );
  357. }
  358. // Notify the panel of the achievement name, so we can display the appropriate icon (icon name MUST match the achievement short name, eg. "ENEMY_KILL_HIGH", "SAME_UNIFORM")
  359. WITH_SFVALUEARRAY( data, 1 )
  360. {
  361. m_pScaleformUI->ValueArray_SetElement( data, 0, pAchievement->GetName());
  362. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setMedalAnnouncement", data, 1 );
  363. }
  364. // Achievements and medals always take precedent over hints / priority messages.
  365. if ( m_PriorityMsgDisplayTimer.HasStarted() )
  366. {
  367. if ( m_bHintPanelHidden )
  368. {
  369. m_bHintPanelHidden = false;
  370. m_HintDisplayTimer.Invalidate();
  371. }
  372. SetPriorityText( static_cast<wchar_t*>(NULL) );
  373. }
  374. if ( m_HintDisplayTimer.HasStarted() )
  375. {
  376. SetHintText( NULL );
  377. }
  378. ShowPanelNoLock( SFHUDINFO_Medal, true );
  379. }
  380. }
  381. LockSlot( false, bSlotIsLocked );
  382. // Clear any transient data now
  383. if ( m_bActive )
  384. {
  385. m_bDeferRaiseHelpPanel = false;
  386. m_bDeferRaisePriorityMessagePanel = false;
  387. }
  388. }
  389. static void GetTextBoxForElement( IScaleformUI *pScaleformUI, SFVALUE root, const char *elementName, const char *textElementName, SFVALUE &sfv )
  390. {
  391. SFVALUE TempHandle = pScaleformUI->Value_GetMember( root, elementName );
  392. if ( TempHandle )
  393. {
  394. sfv = pScaleformUI->Value_GetMember( TempHandle, textElementName );
  395. pScaleformUI->ReleaseValue( TempHandle );
  396. }
  397. }
  398. void SFHudInfoPanel::FlashReady( void )
  399. {
  400. ListenForGameEvent( "achievement_earned_local" );
  401. m_HelpPanelHandle = m_pScaleformUI->Value_GetMember( m_FlashAPI, "HudPanelHelp" );
  402. if ( m_HelpPanelHandle )
  403. {
  404. SFVALUE AnimatedPanelHandle = m_pScaleformUI->Value_GetMember( m_HelpPanelHandle, "Panel" );
  405. if ( AnimatedPanelHandle )
  406. {
  407. GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "HelpText", "TextBox", m_HelpBodyTextHandle );
  408. m_pScaleformUI->ReleaseValue( AnimatedPanelHandle );
  409. }
  410. }
  411. m_PriorityMessagePanelHandle = m_pScaleformUI->Value_GetMember( m_FlashAPI, "HudPanelCenter" );
  412. if ( m_PriorityMessagePanelHandle )
  413. {
  414. SFVALUE AnimatedPanelHandle = m_pScaleformUI->Value_GetMember( m_PriorityMessagePanelHandle, "Panel" );
  415. if ( AnimatedPanelHandle )
  416. {
  417. GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "CenterTextTitle", "TextBox", m_PriorityMessageTitleTextHandle );
  418. GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "CenterText", "TextBox", m_PriorityMessageBodyTextHandle );
  419. m_pScaleformUI->ReleaseValue( AnimatedPanelHandle );
  420. }
  421. }
  422. m_MedalPanelHandle = m_pScaleformUI->Value_GetMember( m_FlashAPI, "HudPanelMedal" );
  423. if ( m_MedalPanelHandle )
  424. {
  425. SFVALUE AnimatedPanelHandle = m_pScaleformUI->Value_GetMember( m_MedalPanelHandle, "Panel" );
  426. if ( AnimatedPanelHandle )
  427. {
  428. GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "MedalTitleText", "TextBox", m_MedalTitleTextHandle );
  429. GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "MedalText", "TextBox", m_MedalBodyTextHandle );
  430. m_pScaleformUI->ReleaseValue( AnimatedPanelHandle );
  431. }
  432. }
  433. m_DefusePanelHandle = m_pScaleformUI->Value_GetMember( m_FlashAPI, "HudPanelDefuse" );
  434. if ( m_DefusePanelHandle )
  435. {
  436. SFVALUE AnimatedPanelHandle = m_pScaleformUI->Value_GetMember( m_DefusePanelHandle, "Panel" );
  437. m_DefuseIconKit = m_pScaleformUI->Value_GetMember( m_DefusePanelHandle, "icon_defuse" );
  438. m_DefuseIconNoKit = m_pScaleformUI->Value_GetMember( m_DefusePanelHandle, "icon_no_defusekit" );
  439. if ( AnimatedPanelHandle )
  440. {
  441. GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "DefuseText", "TextBox", m_DefuseBodyTextHandle );
  442. SFVALUE TitleBarHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "DefuseTextTitle" );
  443. if ( TitleBarHandle )
  444. {
  445. SFVALUE TitleTextHandle = m_pScaleformUI->Value_GetMember( TitleBarHandle, "DefuseTitle" );
  446. if ( TitleTextHandle )
  447. {
  448. GetTextBoxForElement( m_pScaleformUI, TitleTextHandle, "DefuseTitle", "TextBox1", m_DefuseTitleTextHandle );
  449. GetTextBoxForElement( m_pScaleformUI, TitleTextHandle, "DefuseTitle", "TextBox2", m_DefuseTimerTextHandle );
  450. m_pScaleformUI->ReleaseValue( TitleTextHandle );
  451. }
  452. m_pScaleformUI->ReleaseValue( TitleBarHandle );
  453. }
  454. m_pScaleformUI->ReleaseValue( AnimatedPanelHandle );
  455. }
  456. }
  457. // hide everything initially
  458. HideAll();
  459. }
  460. bool SFHudInfoPanel::PreUnloadFlash( void )
  461. {
  462. StopListeningForAllEvents();
  463. SafeReleaseSFVALUE( m_HelpPanelHandle );
  464. SafeReleaseSFVALUE( m_HelpBodyTextHandle );
  465. SafeReleaseSFVALUE( m_MedalPanelHandle );
  466. SafeReleaseSFVALUE( m_MedalTitleTextHandle );
  467. SafeReleaseSFVALUE( m_MedalBodyTextHandle );
  468. SafeReleaseSFVALUE( m_DefusePanelHandle );
  469. SafeReleaseSFVALUE( m_DefuseTitleTextHandle );
  470. SafeReleaseSFVALUE( m_DefuseTimerTextHandle );
  471. SafeReleaseSFVALUE( m_DefuseBodyTextHandle );
  472. SafeReleaseSFVALUE( m_DefuseIconKit );
  473. SafeReleaseSFVALUE( m_DefuseIconNoKit );
  474. SafeReleaseSFVALUE( m_PriorityMessagePanelHandle );
  475. SafeReleaseSFVALUE( m_PriorityMessageTitleTextHandle );
  476. SafeReleaseSFVALUE( m_PriorityMessageBodyTextHandle );
  477. return true;
  478. }
  479. void SFHudInfoPanel::LevelInit( void )
  480. {
  481. if ( !FlashAPIIsValid() )
  482. {
  483. SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudInfoPanel, this, HelpAchievementModule );
  484. }
  485. else
  486. {
  487. // When initially loaded, hide this panel
  488. HideAll();
  489. }
  490. }
  491. void SFHudInfoPanel::LevelShutdown( void )
  492. {
  493. if ( FlashAPIIsValid() )
  494. {
  495. RemoveFlashElement();
  496. }
  497. }
  498. void SFHudInfoPanel::Reset( void )
  499. {
  500. HideAll();
  501. }
  502. bool SFHudInfoPanel::ShouldDraw( void )
  503. {
  504. if ( IsTakingAFreezecamScreenshot() )
  505. return false;
  506. return cl_drawhud.GetBool() && cl_draw_only_deathnotices.GetBool() == false && CHudElement::ShouldDraw();
  507. }
  508. void SFHudInfoPanel::SetActive( bool bActive )
  509. {
  510. if ( m_bActive && !bActive )
  511. {
  512. HideAll();
  513. }
  514. CHudElement::SetActive( bActive );
  515. }
  516. bool SFHudInfoPanel::MsgFunc_HintText( const CCSUsrMsg_HintText &msg )
  517. {
  518. const char *tmpStr = hudtextmessage->LookupString( msg.text().c_str(), NULL );
  519. LocalizeAndDisplay( tmpStr, tmpStr );
  520. return true;
  521. }
  522. bool SFHudInfoPanel::MsgFunc_KeyHintText( const CCSUsrMsg_KeyHintText &msg )
  523. {
  524. const char *tmpStr = hudtextmessage->LookupString( msg.hints(0).c_str(), NULL );
  525. LocalizeAndDisplay( tmpStr, tmpStr );
  526. return true;
  527. }
  528. void SFHudInfoPanel::LocalizeAndDisplay( const char *pszHudTxtMsg, const char *szRawString )
  529. {
  530. wchar_t szBuf[255];
  531. wchar_t *pszBuf;
  532. // init buffers & pointers
  533. szBuf[0] = 0;
  534. pszBuf = szBuf;
  535. // try to localize
  536. if ( pszHudTxtMsg )
  537. {
  538. pszBuf = g_pVGuiLocalize->Find( pszHudTxtMsg );
  539. }
  540. else
  541. {
  542. pszBuf = g_pVGuiLocalize->Find( szRawString );
  543. }
  544. if ( !pszBuf )
  545. {
  546. // use plain ASCII string
  547. g_pVGuiLocalize->ConvertANSIToUnicode( szRawString, szBuf, sizeof(szBuf) );
  548. pszBuf = szBuf;
  549. }
  550. // replace key binding text
  551. wchar_t keyBindingBuf[512];
  552. UTIL_ReplaceKeyBindings( pszBuf, sizeof( szBuf ), keyBindingBuf, sizeof( keyBindingBuf ) );
  553. // make it visible
  554. SetHintText( pszBuf );
  555. }
  556. bool SFHudInfoPanel::SetHintText( wchar_t *text )
  557. {
  558. if ( FlashAPIIsValid() && !m_AchievementDisplayTimer.HasStarted() )
  559. {
  560. WITH_SLOT_LOCKED
  561. {
  562. if ( text )
  563. {
  564. if ( m_HelpBodyTextHandle )
  565. {
  566. WITH_SLOT_LOCKED
  567. {
  568. m_pScaleformUI->Value_SetTextHTML( m_HelpBodyTextHandle, m_pScaleformUI->ReplaceGlyphKeywordsWithHTML( text ) );
  569. }
  570. }
  571. if ( m_PriorityMsgDisplayTimer.HasStarted() )
  572. {
  573. // Defer display of the hint message until the priority message has finished displaying
  574. m_bHintPanelHidden = true;
  575. m_HintDisplayTimer.Start( g_HintDisplayTime + m_PriorityMsgDisplayTimer.GetRemainingTime() );
  576. }
  577. else
  578. {
  579. // start (or reset) the timer for auto-hiding this latest hint
  580. m_HintDisplayTimer.Start( g_HintDisplayTime );
  581. ShowPanelNoLock( SFHUDINFO_Help, true );
  582. }
  583. }
  584. else
  585. {
  586. m_HintDisplayTimer.Invalidate();
  587. ShowPanelNoLock( SFHUDINFO_Help, false );
  588. }
  589. }
  590. }
  591. return true;
  592. }
  593. #ifndef _GAMECONSOLE
  594. ConVar cl_display_scaleform_achievement_popups( "cl_display_scaleform_achievement_popups", "0", FCVAR_CLIENTDLL );
  595. #else
  596. ConVar cl_display_scaleform_achievement_popups( "cl_display_scaleform_achievement_popups", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
  597. #endif
  598. void SFHudInfoPanel::FireGameEvent( IGameEvent * event )
  599. {
  600. const char *pEventName = event->GetName();
  601. if ( cl_display_scaleform_achievement_popups.GetBool() )
  602. {
  603. if ( Q_strcmp( "achievement_earned_local", pEventName ) == 0 )
  604. {
  605. AchivementQueueInfo queueInfo;
  606. queueInfo.type = (eCSAchievementType)event->GetInt( "achievement" );
  607. queueInfo.playerSlot = event->GetInt( "splitscreenplayer" );
  608. // If this achievement is for this player, enqueue it to display on the next tick
  609. if ( queueInfo.playerSlot == engine->GetActiveSplitScreenPlayerSlot() )
  610. {
  611. m_achievementQueue.Insert(queueInfo);
  612. }
  613. }
  614. }
  615. }
  616. // Common code to setup the priority text window for a new message, or tear it down if the message is cleared
  617. void SFHudInfoPanel::ModifyPriorityTextWindow( bool bMsgSet )
  618. {
  619. if ( bMsgSet )
  620. {
  621. bool bAlreadyActive = m_PriorityMsgDisplayTimer.HasStarted() && !m_PriorityMsgDisplayTimer.IsElapsed();
  622. // start (or reset) the timer for auto-hiding this latest text
  623. static ConVarRef scr_centertime( "scr_centertime" );
  624. m_PriorityMsgDisplayTimer.Start( scr_centertime.GetFloat() );
  625. if ( m_PriorityMessageTitleTextHandle )
  626. {
  627. WITH_SLOT_LOCKED
  628. {
  629. m_pScaleformUI->Value_SetText( m_PriorityMessageTitleTextHandle, "#SFUIHUD_InfoPanel_PriorityMsgTitle" );
  630. }
  631. }
  632. if ( bAlreadyActive )
  633. {
  634. WITH_SLOT_LOCKED
  635. {
  636. // don't re-animate the window into position, just flash it and swap the text
  637. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "flashCenterText", NULL, 0 );
  638. }
  639. }
  640. else
  641. {
  642. if ( m_HintDisplayTimer.HasStarted() )
  643. {
  644. // Priority messages take precedent. Temporarily hide the hint panel.
  645. m_bHintPanelHidden = true;
  646. m_HintDisplayTimer.Start( m_HintDisplayTimer.GetElapsedTime() + scr_centertime.GetFloat() );
  647. ShowPanelNoLock( SFHUDINFO_Help, false );
  648. }
  649. ShowPanelNoLock( SFHUDINFO_PriorityMessage, true );
  650. }
  651. }
  652. else
  653. {
  654. m_PriorityMsgDisplayTimer.Invalidate();
  655. ShowPanelNoLock( SFHUDINFO_PriorityMessage, false );
  656. }
  657. }
  658. // ANSI C-string version
  659. void SFHudInfoPanel::SetPriorityText( char *pMsg )
  660. {
  661. if ( FlashAPIIsValid() && !m_AchievementDisplayTimer.HasStarted() )
  662. {
  663. WITH_SLOT_LOCKED
  664. {
  665. ModifyPriorityTextWindow( (pMsg != NULL) );
  666. if ( pMsg && m_PriorityMessageBodyTextHandle )
  667. {
  668. if ( g_BannedWords.BInitialized() )
  669. {
  670. int nLen = V_strlen( pMsg );
  671. int cubDestSizeInBytes = ( 1 + nLen ) * sizeof( wchar_t );
  672. wchar_t * pwchBuffer = ( wchar_t * ) stackalloc( cubDestSizeInBytes );
  673. V_UTF8ToUnicode( pMsg, pwchBuffer, cubDestSizeInBytes );
  674. if ( g_BannedWords.CensorBannedWordsInplace( pwchBuffer ) )
  675. {
  676. m_pScaleformUI->Value_SetText( m_PriorityMessageBodyTextHandle, pwchBuffer );
  677. pMsg = NULL;
  678. }
  679. }
  680. if ( pMsg )
  681. {
  682. m_pScaleformUI->Value_SetText( m_PriorityMessageBodyTextHandle, pMsg );
  683. }
  684. }
  685. }
  686. }
  687. }
  688. // TCHAR (multi-byte) string version
  689. void SFHudInfoPanel::SetPriorityText( wchar_t *pMsg )
  690. {
  691. if ( FlashAPIIsValid() && !m_AchievementDisplayTimer.HasStarted() )
  692. {
  693. WITH_SLOT_LOCKED
  694. {
  695. ModifyPriorityTextWindow( (pMsg != NULL) );
  696. if ( pMsg && m_PriorityMessageBodyTextHandle )
  697. {
  698. g_BannedWords.CensorBannedWordsInplace( pMsg );
  699. m_pScaleformUI->Value_SetTextHTML( m_PriorityMessageBodyTextHandle, m_pScaleformUI->ReplaceGlyphKeywordsWithHTML( pMsg ) );
  700. }
  701. }
  702. }
  703. }
  704. void SFHudInfoPanel::SetPriorityHintText( wchar_t *pMsg )
  705. {
  706. if ( FlashAPIIsValid() && !m_AchievementDisplayTimer.HasStarted() )
  707. {
  708. WITH_SLOT_LOCKED
  709. {
  710. //m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "flashCenterText", NULL, 0 );
  711. if ( pMsg )
  712. {
  713. // make it visible
  714. g_BannedWords.CensorBannedWordsInplace( pMsg );
  715. SetHintText( pMsg );
  716. }
  717. }
  718. }
  719. }
  720. void SFHudInfoPanel::ApplyYOffset( int nOffset )
  721. {
  722. if ( FlashAPIIsValid() )
  723. {
  724. WITH_SFVALUEARRAY_SLOT_LOCKED( data, 1 )
  725. {
  726. m_pScaleformUI->ValueArray_SetElement( data, 0, nOffset );
  727. m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setYOffset", data, 1 );
  728. }
  729. }
  730. }