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.

415 lines
12 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "cs_hud_achievement_announce.h"
  9. #include <vgui/IVGui.h>
  10. #include "vgui_controls/AnimationController.h"
  11. #include "iclientmode.h"
  12. #include "c_cs_player.h"
  13. #include "c_cs_playerresource.h"
  14. #include <vgui_controls/Label.h>
  15. #include <vgui/ILocalize.h>
  16. #include <vgui/ISurface.h>
  17. #include "fmtstr.h"
  18. #include "cs_gamerules.h"
  19. #include "view.h"
  20. #include "ivieweffects.h"
  21. #include "viewrender.h"
  22. #include "usermessages.h"
  23. #include "hud_macros.h"
  24. #include "c_baseanimating.h"
  25. #include "achievementmgr.h"
  26. #include "filesystem.h"
  27. // memdbgon must be the last include file in a .cpp file!!!
  28. #include "tier0/memdbgon.h"
  29. DECLARE_HUDELEMENT_DEPTH( CCSAchievementAnnouncePanel, 1 );
  30. #define CALLOUT_WIDE (XRES(100))
  31. #define CALLOUT_TALL (XRES(50))
  32. namespace Interpolators
  33. {
  34. inline float Linear( float t ) { return t; }
  35. inline float SmoothStep( float t )
  36. {
  37. t = 3 * t * t - 2.0f * t * t * t;
  38. return t;
  39. }
  40. inline float SmoothStep2( float t )
  41. {
  42. return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
  43. }
  44. inline float SmoothStepStart( float t )
  45. {
  46. t = 0.5f * t;
  47. t = 3 * t * t - 2.0f * t * t * t;
  48. t = t* 2.0f;
  49. return t;
  50. }
  51. inline float SmoothStepEnd( float t )
  52. {
  53. t = 0.5f * t + 0.5f;
  54. t = 3 * t * t - 2.0f * t * t * t;
  55. t = (t - 0.5f) * 2.0f;
  56. return t;
  57. }
  58. }
  59. //-----------------------------------------------------------------------------
  60. // Purpose: Constructor
  61. //-----------------------------------------------------------------------------
  62. CCSAchievementAnnouncePanel::CCSAchievementAnnouncePanel( const char *pElementName )
  63. : EditablePanel( NULL, "AchievementAnnouncePanel" ), CHudElement( pElementName )
  64. {
  65. vgui::Panel *pParent = g_pClientMode->GetViewport();
  66. SetParent( pParent );
  67. m_bShouldBeVisible = false;
  68. SetScheme( "ClientScheme" );
  69. m_currentDisplayedAchievement = CSInvalidAchievement;
  70. m_pGlowPanel = NULL;
  71. RegisterForRenderGroup( "hide_for_scoreboard" );
  72. //Create the grey popup that has the name, text and icon.
  73. m_pAchievementInfoPanel = new CCSAchivementInfoPanel(this, "InfoPanel");
  74. }
  75. CCSAchievementAnnouncePanel::~CCSAchievementAnnouncePanel()
  76. {
  77. if (m_pAchievementInfoPanel)
  78. {
  79. delete m_pAchievementInfoPanel;
  80. }
  81. }
  82. void CCSAchievementAnnouncePanel::Reset()
  83. {
  84. //We don't want to hide the UI here since we want the achievement popup to show through death
  85. }
  86. void CCSAchievementAnnouncePanel::Init()
  87. {
  88. ListenForGameEvent( "achievement_earned_local" );
  89. Hide();
  90. CHudElement::Init();
  91. }
  92. void CCSAchievementAnnouncePanel::ApplySchemeSettings( vgui::IScheme *pScheme )
  93. {
  94. BaseClass::ApplySchemeSettings( pScheme );
  95. LoadControlSettings( "Resource/UI/Achievement_Glow.res" );
  96. //This is the glowy flash that comes up under the popup
  97. m_pGlowPanel = dynamic_cast<EditablePanel *>( FindChildByName("GlowPanel") );
  98. Hide();
  99. }
  100. ConVar cl_show_achievement_popups( "cl_show_achievement_popups", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
  101. void CCSAchievementAnnouncePanel::FireGameEvent( IGameEvent * event )
  102. {
  103. const char *pEventName = event->GetName();
  104. if ( cl_show_achievement_popups.GetBool() )
  105. {
  106. if ( Q_strcmp( "achievement_earned_local", pEventName ) == 0 )
  107. {
  108. //Add achievement to queue and show the UI (since the UI doesn't "Think()" until it is shown
  109. Show();
  110. m_achievementQueue.Insert((eCSAchievementType)event->GetInt("achievement"));
  111. }
  112. }
  113. }
  114. void CCSAchievementAnnouncePanel::Show()
  115. {
  116. m_bShouldBeVisible = true;
  117. }
  118. void CCSAchievementAnnouncePanel::Hide()
  119. {
  120. m_bShouldBeVisible = false;
  121. }
  122. bool CCSAchievementAnnouncePanel::ShouldDraw( void )
  123. {
  124. return (m_bShouldBeVisible && CHudElement::ShouldDraw());
  125. }
  126. void CCSAchievementAnnouncePanel::Paint( void )
  127. {
  128. }
  129. void CCSAchievementAnnouncePanel::OnThink( void )
  130. {
  131. BaseClass::OnThink();
  132. if (!m_pAchievementInfoPanel)
  133. {
  134. return;
  135. }
  136. //if we have an achievement, update it
  137. if (m_currentDisplayedAchievement != CSInvalidAchievement)
  138. {
  139. //If the match restarts, we need to move the start time for the achievement back.
  140. if (m_displayStartTime > gpGlobals->curtime)
  141. {
  142. m_displayStartTime = gpGlobals->curtime;
  143. }
  144. float timeSinceDisplayStart = gpGlobals->curtime - m_displayStartTime;
  145. float glowAlpha;
  146. float achievementPanelAlpha;
  147. //Update the flash
  148. if (m_pGlowPanel)
  149. {
  150. GetGlowAlpha(timeSinceDisplayStart, glowAlpha);
  151. m_pGlowPanel->SetAlpha(glowAlpha);
  152. }
  153. if (GetAchievementPanelAlpha(timeSinceDisplayStart, achievementPanelAlpha))
  154. {
  155. m_pAchievementInfoPanel->SetAlpha(achievementPanelAlpha);
  156. }
  157. else
  158. {
  159. //achievement is faded, so we are done
  160. m_pAchievementInfoPanel->SetAlpha(0);
  161. m_currentDisplayedAchievement = CSInvalidAchievement;
  162. if (m_achievementQueue.Count() == 0)
  163. {
  164. Hide();
  165. }
  166. }
  167. }
  168. else
  169. {
  170. //Check if we need to start the next announcement in the queue. We won't update it this frame, but no time has elapsed anyway.
  171. if (m_achievementQueue.Count() > 0)
  172. {
  173. m_currentDisplayedAchievement = m_achievementQueue.RemoveAtHead();
  174. m_displayStartTime = gpGlobals->curtime;
  175. //=============================================================================
  176. // HPE_BEGIN:
  177. // [dwenger] Play the achievement earned sound effect
  178. //=============================================================================
  179. vgui::surface()->PlaySound( "UI/achievement_earned.wav" );
  180. //=============================================================================
  181. // HPE_END
  182. //=============================================================================
  183. //Here we get the achievement to be displayed and set that in the popup windows
  184. CAchievementMgr *pAchievementMgr = dynamic_cast<CAchievementMgr *>( engine->GetAchievementMgr() );
  185. if ( !pAchievementMgr )
  186. return;
  187. IAchievement *pAchievement = pAchievementMgr->GetAchievementByID( m_currentDisplayedAchievement );
  188. if ( pAchievement )
  189. {
  190. m_pAchievementInfoPanel->SetAchievement(pAchievement);
  191. }
  192. }
  193. }
  194. }
  195. bool CCSAchievementAnnouncePanel::GetAlphaFromTime(float elapsedTime, float delay, float fadeInTime, float holdTime, float fadeOutTime, float&alpha)
  196. {
  197. //We just pass through each phase, subtracting off the full time if we are already done with that phase
  198. //We return whether the control should still be active
  199. //I. Delay before fading in
  200. if (elapsedTime > delay)
  201. {
  202. elapsedTime -= delay;
  203. }
  204. else
  205. {
  206. alpha = 0;
  207. return true;
  208. }
  209. //II. Fade in time
  210. if (elapsedTime > fadeInTime)
  211. {
  212. elapsedTime -= fadeInTime;
  213. }
  214. else
  215. {
  216. alpha = 255.0f * elapsedTime / fadeInTime;
  217. return true;
  218. }
  219. //III. Hold at full alpha time
  220. if (elapsedTime > holdTime)
  221. {
  222. elapsedTime -= holdTime;
  223. }
  224. else
  225. {
  226. alpha = 255.0f;
  227. return true;
  228. }
  229. //IV. Fade out time
  230. if (elapsedTime > fadeOutTime)
  231. {
  232. alpha = 0;
  233. return false;
  234. }
  235. else
  236. {
  237. alpha = 1.0f - (elapsedTime / fadeOutTime);
  238. alpha = Interpolators::SmoothStepStart(alpha);
  239. alpha *= 255.0f;
  240. if (m_achievementQueue.Count() > 0 && alpha < 128.0f)
  241. {
  242. return false;
  243. }
  244. return true;
  245. }
  246. }
  247. ConVar glow_delay( "glow_delay", "0", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY);
  248. ConVar glow_fadeInTime( "glow_fadeInTime", "0.1", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY);
  249. ConVar glow_holdTime( "glow_holdTime", "0.1", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY);
  250. ConVar glow_fadeOutTime( "glow_fadeOutTime", "2.5", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY);
  251. bool CCSAchievementAnnouncePanel::GetGlowAlpha (float time, float& alpha)
  252. {
  253. /*
  254. float delay = 0.0f;
  255. float fadeInTime = 0.3f;
  256. float holdTime = 0.1f;
  257. float fadeOutTime = 0.4f;
  258. */
  259. //return GetAlphaFromTime(time, delay, fadeInTime, holdTime, fadeOutTime, alpha);
  260. return GetAlphaFromTime(time, glow_delay.GetFloat(), glow_fadeInTime.GetFloat(), glow_holdTime.GetFloat(), glow_fadeOutTime.GetFloat(), alpha);
  261. }
  262. ConVar popup_delay( "popup_delay", "0", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY);
  263. ConVar popup_fadeInTime( "popup_fadeInTime", "0.3", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY);
  264. ConVar popup_holdTime( "popup_holdTime", "3.5", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY);
  265. ConVar popup_fadeOutTime( "popup_fadeOutTime", "3.0", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY);
  266. bool CCSAchievementAnnouncePanel::GetAchievementPanelAlpha (float time, float& alpha)
  267. {
  268. /*
  269. float delay = 0.2f;
  270. float fadeInTime = 0.3f;
  271. float holdTime = 3.0f;
  272. float fadeOutTime = 2.0f;
  273. */
  274. //return GetAlphaFromTime(time, delay, fadeInTime, holdTime, fadeOutTime, alpha);
  275. return GetAlphaFromTime(time, popup_delay.GetFloat(), popup_fadeInTime.GetFloat(), popup_holdTime.GetFloat(), popup_fadeOutTime.GetFloat(), alpha);
  276. }
  277. //-----------------------------------------------------------------------------
  278. // Purpose: creates child panels, passes down name to pick up any settings from res files.
  279. //-----------------------------------------------------------------------------
  280. CCSAchivementInfoPanel::CCSAchivementInfoPanel( vgui::Panel *parent, const char* name ) : BaseClass( parent, name )
  281. {
  282. //Create the main components of the display and attach them to the panel
  283. m_pAchievementIcon = SETUP_PANEL(new vgui::ScalableImagePanel( this, "Icon" ));
  284. m_pAchievementNameLabel = new vgui::Label( this, "Name", "name" );
  285. m_pAchievementDescLabel = new vgui::Label( this, "Description", "desc" );
  286. }
  287. CCSAchivementInfoPanel::~CCSAchivementInfoPanel()
  288. {
  289. if (m_pAchievementIcon)
  290. {
  291. delete m_pAchievementIcon;
  292. }
  293. if (m_pAchievementNameLabel)
  294. {
  295. delete m_pAchievementNameLabel;
  296. }
  297. if (m_pAchievementDescLabel)
  298. {
  299. delete m_pAchievementDescLabel;
  300. }
  301. }
  302. void CCSAchivementInfoPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
  303. {
  304. LoadControlSettings( "Resource/UI/Achievement_Popup.res" );
  305. BaseClass::ApplySchemeSettings( pScheme );
  306. //Override the automatic scheme setting that happen above
  307. SetBgColor( pScheme->GetColor( "AchievementsLightGrey", Color(255, 0, 0, 255) ) );
  308. m_pAchievementNameLabel->SetFgColor(pScheme->GetColor("SteamLightGreen", Color(255, 255, 255, 255)));
  309. m_pAchievementDescLabel->SetFgColor(pScheme->GetColor("White", Color(255, 255, 255, 255)));
  310. }
  311. void CCSAchivementInfoPanel::SetAchievement(IAchievement* pAchievement)
  312. {
  313. //=============================================================================
  314. // HPE_BEGIN:
  315. // [dwenger] Get achievement name and description text from the localized file
  316. //=============================================================================
  317. // Set name and description
  318. m_pAchievementNameLabel->SetText( ACHIEVEMENT_LOCALIZED_NAME( pAchievement ) );
  319. m_pAchievementDescLabel->SetText( ACHIEVEMENT_LOCALIZED_DESC( pAchievement ) );
  320. //Find, load and show the achievement icon
  321. char imagePath[_MAX_PATH];
  322. Q_strncpy( imagePath, "achievements\\", sizeof(imagePath) );
  323. Q_strncat( imagePath, pAchievement->GetName(), sizeof(imagePath), COPY_ALL_CHARACTERS );
  324. Q_strncat( imagePath, ".vtf", sizeof(imagePath), COPY_ALL_CHARACTERS );
  325. char checkFile[_MAX_PATH];
  326. Q_snprintf( checkFile, sizeof(checkFile), "materials\\vgui\\%s", imagePath );
  327. if ( !g_pFullFileSystem->FileExists( checkFile ) )
  328. {
  329. Q_snprintf( imagePath, sizeof(imagePath), "hud\\icon_locked.vtf" );
  330. }
  331. m_pAchievementIcon->SetImage( imagePath );
  332. m_pAchievementIcon->SetVisible( true );
  333. //=============================================================================
  334. // HPE_END
  335. //=============================================================================
  336. }