//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #include "cbase.h" #include "cs_hud_achievement_announce.h" #include #include "vgui_controls/AnimationController.h" #include "iclientmode.h" #include "c_cs_player.h" #include "c_cs_playerresource.h" #include #include #include #include "fmtstr.h" #include "cs_gamerules.h" #include "view.h" #include "ivieweffects.h" #include "viewrender.h" #include "usermessages.h" #include "hud_macros.h" #include "c_baseanimating.h" #include "achievementmgr.h" #include "filesystem.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" DECLARE_HUDELEMENT_DEPTH( CCSAchievementAnnouncePanel, 1 ); #define CALLOUT_WIDE (XRES(100)) #define CALLOUT_TALL (XRES(50)) namespace Interpolators { inline float Linear( float t ) { return t; } inline float SmoothStep( float t ) { t = 3 * t * t - 2.0f * t * t * t; return t; } inline float SmoothStep2( float t ) { return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f); } inline float SmoothStepStart( float t ) { t = 0.5f * t; t = 3 * t * t - 2.0f * t * t * t; t = t* 2.0f; return t; } inline float SmoothStepEnd( float t ) { t = 0.5f * t + 0.5f; t = 3 * t * t - 2.0f * t * t * t; t = (t - 0.5f) * 2.0f; return t; } } //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- CCSAchievementAnnouncePanel::CCSAchievementAnnouncePanel( const char *pElementName ) : EditablePanel( NULL, "AchievementAnnouncePanel" ), CHudElement( pElementName ) { vgui::Panel *pParent = g_pClientMode->GetViewport(); SetParent( pParent ); m_bShouldBeVisible = false; SetScheme( "ClientScheme" ); m_currentDisplayedAchievement = CSInvalidAchievement; m_pGlowPanel = NULL; RegisterForRenderGroup( "hide_for_scoreboard" ); //Create the grey popup that has the name, text and icon. m_pAchievementInfoPanel = new CCSAchivementInfoPanel(this, "InfoPanel"); } CCSAchievementAnnouncePanel::~CCSAchievementAnnouncePanel() { if (m_pAchievementInfoPanel) { delete m_pAchievementInfoPanel; } } void CCSAchievementAnnouncePanel::Reset() { //We don't want to hide the UI here since we want the achievement popup to show through death } void CCSAchievementAnnouncePanel::Init() { ListenForGameEvent( "achievement_earned_local" ); Hide(); CHudElement::Init(); } void CCSAchievementAnnouncePanel::ApplySchemeSettings( vgui::IScheme *pScheme ) { BaseClass::ApplySchemeSettings( pScheme ); LoadControlSettings( "Resource/UI/Achievement_Glow.res" ); //This is the glowy flash that comes up under the popup m_pGlowPanel = dynamic_cast( FindChildByName("GlowPanel") ); Hide(); } ConVar cl_show_achievement_popups( "cl_show_achievement_popups", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); void CCSAchievementAnnouncePanel::FireGameEvent( IGameEvent * event ) { const char *pEventName = event->GetName(); if ( cl_show_achievement_popups.GetBool() ) { if ( Q_strcmp( "achievement_earned_local", pEventName ) == 0 ) { //Add achievement to queue and show the UI (since the UI doesn't "Think()" until it is shown Show(); m_achievementQueue.Insert((eCSAchievementType)event->GetInt("achievement")); } } } void CCSAchievementAnnouncePanel::Show() { m_bShouldBeVisible = true; } void CCSAchievementAnnouncePanel::Hide() { m_bShouldBeVisible = false; } bool CCSAchievementAnnouncePanel::ShouldDraw( void ) { return (m_bShouldBeVisible && CHudElement::ShouldDraw()); } void CCSAchievementAnnouncePanel::Paint( void ) { } void CCSAchievementAnnouncePanel::OnThink( void ) { BaseClass::OnThink(); if (!m_pAchievementInfoPanel) { return; } //if we have an achievement, update it if (m_currentDisplayedAchievement != CSInvalidAchievement) { //If the match restarts, we need to move the start time for the achievement back. if (m_displayStartTime > gpGlobals->curtime) { m_displayStartTime = gpGlobals->curtime; } float timeSinceDisplayStart = gpGlobals->curtime - m_displayStartTime; float glowAlpha; float achievementPanelAlpha; //Update the flash if (m_pGlowPanel) { GetGlowAlpha(timeSinceDisplayStart, glowAlpha); m_pGlowPanel->SetAlpha(glowAlpha); } if (GetAchievementPanelAlpha(timeSinceDisplayStart, achievementPanelAlpha)) { m_pAchievementInfoPanel->SetAlpha(achievementPanelAlpha); } else { //achievement is faded, so we are done m_pAchievementInfoPanel->SetAlpha(0); m_currentDisplayedAchievement = CSInvalidAchievement; if (m_achievementQueue.Count() == 0) { Hide(); } } } else { //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. if (m_achievementQueue.Count() > 0) { m_currentDisplayedAchievement = m_achievementQueue.RemoveAtHead(); m_displayStartTime = gpGlobals->curtime; //============================================================================= // HPE_BEGIN: // [dwenger] Play the achievement earned sound effect //============================================================================= vgui::surface()->PlaySound( "UI/achievement_earned.wav" ); //============================================================================= // HPE_END //============================================================================= //Here we get the achievement to be displayed and set that in the popup windows CAchievementMgr *pAchievementMgr = dynamic_cast( engine->GetAchievementMgr() ); if ( !pAchievementMgr ) return; IAchievement *pAchievement = pAchievementMgr->GetAchievementByID( m_currentDisplayedAchievement ); if ( pAchievement ) { m_pAchievementInfoPanel->SetAchievement(pAchievement); } } } } bool CCSAchievementAnnouncePanel::GetAlphaFromTime(float elapsedTime, float delay, float fadeInTime, float holdTime, float fadeOutTime, float&alpha) { //We just pass through each phase, subtracting off the full time if we are already done with that phase //We return whether the control should still be active //I. Delay before fading in if (elapsedTime > delay) { elapsedTime -= delay; } else { alpha = 0; return true; } //II. Fade in time if (elapsedTime > fadeInTime) { elapsedTime -= fadeInTime; } else { alpha = 255.0f * elapsedTime / fadeInTime; return true; } //III. Hold at full alpha time if (elapsedTime > holdTime) { elapsedTime -= holdTime; } else { alpha = 255.0f; return true; } //IV. Fade out time if (elapsedTime > fadeOutTime) { alpha = 0; return false; } else { alpha = 1.0f - (elapsedTime / fadeOutTime); alpha = Interpolators::SmoothStepStart(alpha); alpha *= 255.0f; if (m_achievementQueue.Count() > 0 && alpha < 128.0f) { return false; } return true; } } ConVar glow_delay( "glow_delay", "0", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY); ConVar glow_fadeInTime( "glow_fadeInTime", "0.1", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY); ConVar glow_holdTime( "glow_holdTime", "0.1", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY); ConVar glow_fadeOutTime( "glow_fadeOutTime", "2.5", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY); bool CCSAchievementAnnouncePanel::GetGlowAlpha (float time, float& alpha) { /* float delay = 0.0f; float fadeInTime = 0.3f; float holdTime = 0.1f; float fadeOutTime = 0.4f; */ //return GetAlphaFromTime(time, delay, fadeInTime, holdTime, fadeOutTime, alpha); return GetAlphaFromTime(time, glow_delay.GetFloat(), glow_fadeInTime.GetFloat(), glow_holdTime.GetFloat(), glow_fadeOutTime.GetFloat(), alpha); } ConVar popup_delay( "popup_delay", "0", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY); ConVar popup_fadeInTime( "popup_fadeInTime", "0.3", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY); ConVar popup_holdTime( "popup_holdTime", "3.5", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY); ConVar popup_fadeOutTime( "popup_fadeOutTime", "3.0", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY); bool CCSAchievementAnnouncePanel::GetAchievementPanelAlpha (float time, float& alpha) { /* float delay = 0.2f; float fadeInTime = 0.3f; float holdTime = 3.0f; float fadeOutTime = 2.0f; */ //return GetAlphaFromTime(time, delay, fadeInTime, holdTime, fadeOutTime, alpha); return GetAlphaFromTime(time, popup_delay.GetFloat(), popup_fadeInTime.GetFloat(), popup_holdTime.GetFloat(), popup_fadeOutTime.GetFloat(), alpha); } //----------------------------------------------------------------------------- // Purpose: creates child panels, passes down name to pick up any settings from res files. //----------------------------------------------------------------------------- CCSAchivementInfoPanel::CCSAchivementInfoPanel( vgui::Panel *parent, const char* name ) : BaseClass( parent, name ) { //Create the main components of the display and attach them to the panel m_pAchievementIcon = SETUP_PANEL(new vgui::ScalableImagePanel( this, "Icon" )); m_pAchievementNameLabel = new vgui::Label( this, "Name", "name" ); m_pAchievementDescLabel = new vgui::Label( this, "Description", "desc" ); } CCSAchivementInfoPanel::~CCSAchivementInfoPanel() { if (m_pAchievementIcon) { delete m_pAchievementIcon; } if (m_pAchievementNameLabel) { delete m_pAchievementNameLabel; } if (m_pAchievementDescLabel) { delete m_pAchievementDescLabel; } } void CCSAchivementInfoPanel::ApplySchemeSettings( vgui::IScheme *pScheme ) { LoadControlSettings( "Resource/UI/Achievement_Popup.res" ); BaseClass::ApplySchemeSettings( pScheme ); //Override the automatic scheme setting that happen above SetBgColor( pScheme->GetColor( "AchievementsLightGrey", Color(255, 0, 0, 255) ) ); m_pAchievementNameLabel->SetFgColor(pScheme->GetColor("SteamLightGreen", Color(255, 255, 255, 255))); m_pAchievementDescLabel->SetFgColor(pScheme->GetColor("White", Color(255, 255, 255, 255))); } void CCSAchivementInfoPanel::SetAchievement(IAchievement* pAchievement) { //============================================================================= // HPE_BEGIN: // [dwenger] Get achievement name and description text from the localized file //============================================================================= // Set name and description m_pAchievementNameLabel->SetText( ACHIEVEMENT_LOCALIZED_NAME( pAchievement ) ); m_pAchievementDescLabel->SetText( ACHIEVEMENT_LOCALIZED_DESC( pAchievement ) ); //Find, load and show the achievement icon char imagePath[_MAX_PATH]; Q_strncpy( imagePath, "achievements\\", sizeof(imagePath) ); Q_strncat( imagePath, pAchievement->GetName(), sizeof(imagePath), COPY_ALL_CHARACTERS ); Q_strncat( imagePath, ".vtf", sizeof(imagePath), COPY_ALL_CHARACTERS ); char checkFile[_MAX_PATH]; Q_snprintf( checkFile, sizeof(checkFile), "materials\\vgui\\%s", imagePath ); if ( !g_pFullFileSystem->FileExists( checkFile ) ) { Q_snprintf( imagePath, sizeof(imagePath), "hud\\icon_locked.vtf" ); } m_pAchievementIcon->SetImage( imagePath ); m_pAchievementIcon->SetVisible( true ); //============================================================================= // HPE_END //============================================================================= }