summaryrefslogtreecommitdiff
path: root/game/client/tf/tf_hud_notification_panel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/client/tf/tf_hud_notification_panel.cpp')
-rw-r--r--game/client/tf/tf_hud_notification_panel.cpp581
1 files changed, 581 insertions, 0 deletions
diff --git a/game/client/tf/tf_hud_notification_panel.cpp b/game/client/tf/tf_hud_notification_panel.cpp
new file mode 100644
index 0000000..26333fe
--- /dev/null
+++ b/game/client/tf/tf_hud_notification_panel.cpp
@@ -0,0 +1,581 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================
+
+#include "cbase.h"
+#include "hud.h"
+#include "hud_macros.h"
+#include "c_tf_player.h"
+#include "iclientmode.h"
+#include "ienginevgui.h"
+#include <vgui/ILocalize.h>
+#include <vgui/ISurface.h>
+#include <vgui/IVGui.h>
+#include <vgui_controls/EditablePanel.h>
+#include <vgui_controls/Label.h>
+#include "tf_shareddefs.h"
+#include "tf_hud_notification_panel.h"
+#include "tf_hud_freezepanel.h"
+#include <filesystem.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+ConVar tf_hud_notification_duration( "tf_hud_notification_duration", "3.0", 0, "How long to display hud notification panels before fading them" );
+ConVar tf_hud_notification_show_count_kart_controls( "tf_hud_notification_show_count_kart_controls", "0", FCVAR_ARCHIVE );
+ConVar tf_hud_notification_show_count_ghost_controls( "tf_hud_notification_show_count_ghost_controls", "0", FCVAR_ARCHIVE );
+ConVar tf_hud_notification_show_count_ghost_controls_no_respawn( "tf_hud_notification_show_count_ghost_controls_no_respawn", "0", FCVAR_ARCHIVE );
+
+DECLARE_HUDELEMENT( CHudNotificationPanel );
+
+DECLARE_HUD_MESSAGE( CHudNotificationPanel, HudNotify );
+DECLARE_HUD_MESSAGE( CHudNotificationPanel, HudNotifyCustom );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudNotificationPanel::CHudNotificationPanel( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "NotificationPanel" )
+{
+ Panel *pParent = g_pClientMode->GetViewport();
+ SetParent( pParent );
+
+ SetHiddenBits( HIDEHUD_MISCSTATUS );
+
+ vgui::ivgui()->AddTickSignal( GetVPanel() );
+
+ m_flFadeTime = 0;
+
+ // listen for one version that just passes an int, for prebuilt notifications
+ // and another that takes a res file to load
+
+ m_pText = new Label( this, "Notification_Label", "" );
+ m_pIcon = new CIconPanel( this, "Notification_Icon" );
+ m_pBackground = new ImagePanel( this, "Notification_Background" );
+
+ RegisterForRenderGroup( "mid" );
+ RegisterForRenderGroup( "commentary" );
+
+ LoadManifest();
+ m_mapShowCounts.SetLessFunc( DefLessFunc( int ) ) ;
+ m_mapShowCounts.Insert( HUD_NOTIFY_HOW_TO_CONTROL_GHOST, ShowCount_t( 3, 300.f, &tf_hud_notification_show_count_ghost_controls ) );
+ m_mapShowCounts.Insert( HUD_NOTIFY_HOW_TO_CONTROL_KART, ShowCount_t( 3, 300.f, &tf_hud_notification_show_count_kart_controls ) );
+ m_mapShowCounts.Insert( HUD_NOTIFY_HOW_TO_CONTROL_GHOST_NO_RESPAWN, ShowCount_t( 3, 300.f, &tf_hud_notification_show_count_ghost_controls_no_respawn ) );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudNotificationPanel::Init( void )
+{
+ CHudElement::Init();
+
+ HOOK_HUD_MESSAGE( CHudNotificationPanel, HudNotify );
+ HOOK_HUD_MESSAGE( CHudNotificationPanel, HudNotifyCustom );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudNotificationPanel::ApplySchemeSettings( IScheme *pScheme )
+{
+ // load control settings...
+ LoadControlSettings( "resource/UI/notifications/base_notification.res" );
+
+ BaseClass::ApplySchemeSettings( pScheme );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudNotificationPanel::MsgFunc_HudNotify( bf_read &msg )
+{
+ int iType = msg.ReadByte();
+ bool bForceShow = msg.ReadByte();
+
+ // Ignore notifications in minmode
+ if ( !bForceShow )
+ {
+ ConVarRef cl_hud_minmode( "cl_hud_minmode", true );
+ if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() )
+ return;
+ }
+
+ float flDuration = tf_hud_notification_duration.GetFloat();
+
+ // Check if we're only supposed to show a limited number of times
+ auto idx = m_mapShowCounts.Find( iType );
+ if ( m_mapShowCounts.IsValidIndex( idx ) )
+ {
+ auto& showCount = m_mapShowCounts[ idx ];
+ // Stop here if we've met our max show count, or it's too soon
+ if ( showCount.m_pConVar->GetInt() >= showCount.m_nMaxShowCount
+ || showCount.m_flNextAllowedTime > Plat_FloatTime() )
+ {
+ return;
+ }
+
+ // Increment show count
+ showCount.m_pConVar->SetValue( showCount.m_pConVar->GetInt() + 1 );
+ // Set next time we're allowed to show
+ showCount.m_flNextAllowedTime = Plat_FloatTime() + showCount.m_flCooldown;
+ }
+
+
+ InvalidateLayout( true, true );
+ LoadControlSettings( GetNotificationByType( iType, flDuration ) );
+
+ // set up the fade time
+ m_flFadeTime = gpGlobals->curtime + flDuration;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudNotificationPanel::MsgFunc_HudNotifyCustom( bf_read &msg )
+{
+ // Ignore notifications in minmode
+ ConVarRef cl_hud_minmode( "cl_hud_minmode", true );
+ if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() )
+ return;
+
+ // Reload the base
+ LoadControlSettings( "resource/UI/notifications/base_notification.res" );
+
+ char szText[256];
+ char szIcon[256];
+
+ msg.ReadString( szText, sizeof(szText) );
+ msg.ReadString( szIcon, sizeof(szIcon) );
+ int iBackgroundTeam = msg.ReadByte();
+
+ SetupNotifyCustom( szText, szIcon, iBackgroundTeam );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudNotificationPanel::SetupNotifyCustom( const char *pszText, const char *pszIcon, int iBackgroundTeam )
+{
+ // Reload the base
+ LoadControlSettings( "resource/UI/notifications/base_notification.res" );
+
+ m_pIcon->SetIcon( pszIcon );
+ m_pText->SetText( pszText );
+
+ if ( iBackgroundTeam == TF_TEAM_RED )
+ {
+ m_pBackground->SetImage( "../hud/score_panel_red_bg" );
+ }
+ else if ( iBackgroundTeam == TF_TEAM_BLUE )
+ {
+ m_pBackground->SetImage( "../hud/score_panel_blue_bg" );
+ }
+ else
+ {
+ m_pBackground->SetImage( "../hud/notification_black" );
+ }
+
+ // set up the fade time
+ m_flFadeTime = gpGlobals->curtime + tf_hud_notification_duration.GetFloat();
+
+ InvalidateLayout();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudNotificationPanel::SetupNotifyCustom( const wchar_t *pszText, const char *pszIcon, int iBackgroundTeam )
+{
+ // Reload the base
+ LoadControlSettings( "resource/UI/notifications/base_notification.res" );
+
+ m_pIcon->SetIcon( pszIcon );
+ m_pText->SetText( pszText );
+
+ if ( iBackgroundTeam == TF_TEAM_RED )
+ {
+ m_pBackground->SetImage( "../hud/score_panel_red_bg" );
+ }
+ else if ( iBackgroundTeam == TF_TEAM_BLUE )
+ {
+ m_pBackground->SetImage( "../hud/score_panel_blue_bg" );
+ }
+ else
+ {
+ m_pBackground->SetImage( "../hud/notification_black" );
+ }
+
+ // set up the fade time
+ m_flFadeTime = gpGlobals->curtime + tf_hud_notification_duration.GetFloat();
+
+ InvalidateLayout();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudNotificationPanel::SetupNotifyCustom( const wchar_t *pszText, HudNotification_t type, float overrideDuration )
+{
+ float flDuration = tf_hud_notification_duration.GetFloat();
+
+ // Reload the base
+ LoadControlSettings( GetNotificationByType( type, flDuration ) );
+
+ m_pText->SetText( pszText );
+
+ // set up the fade time
+ m_flFadeTime = gpGlobals->curtime + ( overrideDuration > 0.f ? overrideDuration : flDuration );
+
+ InvalidateLayout();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudNotificationPanel::PerformLayout( void )
+{
+ BaseClass::PerformLayout();
+
+ // re-layout the panel manually so we fit the length of the string!
+ // **** this is super yucky, i'm going to cry myself to sleep tonight ****
+
+ int iTextWide, iTextTall;
+ m_pText->GetContentSize( iTextWide, iTextTall );
+
+ m_pText->SetSize( iTextWide, m_pText->GetTall() );
+
+ float flTextWide = m_pText->GetWide();
+ float flIconWide = m_pIcon->GetWide();
+
+ float flSpacer = XRES( 5 );
+ float flEndSpacer = XRES( 8 ) + XRES( 3 ) * ( flTextWide / 184 ); // total hackery
+
+ float flTotalWidth = flEndSpacer + flIconWide + flSpacer + flTextWide + flEndSpacer;
+
+ float flLeftSide = ( GetWide() - flTotalWidth ) * 0.5f;
+
+ // resize and position background
+ m_pBackground->SetPos( flLeftSide, 0 );
+
+ m_pBackground->SetWide( flTotalWidth );
+
+ // reposition icon
+ int iIconXPos, iIconYPos;
+ m_pIcon->GetPos( iIconXPos, iIconYPos );
+
+ m_pIcon->SetPos( flLeftSide + flEndSpacer, iIconYPos );
+
+ // reposition text
+ int iTextXPos, iTextYPos;
+ m_pText->GetPos( iTextXPos, iTextYPos );
+
+ m_pText->SetPos( flLeftSide + flEndSpacer + flIconWide + flSpacer, iTextYPos );
+
+ const unsigned short tempBufSize = 2048;
+ wchar_t tempBufIn[tempBufSize];
+ wchar_t tempBufOut[tempBufSize];
+ m_pText->GetText( tempBufIn, tempBufSize );
+ UTIL_ReplaceKeyBindings( tempBufIn, tempBufSize, tempBufOut, tempBufSize );
+ m_pText->SetText( tempBufOut );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudNotificationPanel::ShouldDraw( void )
+{
+ // only if we have a valid message to draw
+ if ( m_flFadeTime < gpGlobals->curtime )
+ return false;
+
+ if ( IsTakingAFreezecamScreenshot() )
+ return false;
+
+ return CHudElement::ShouldDraw();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudNotificationPanel::OnTick( void )
+{
+ // set alpha based on time left
+
+ // do this if we can fade the icons and the background
+
+ /*
+ float flLifeTime = m_flFadeTime - gpGlobals->curtime;
+
+ if ( flLifeTime >= 1 )
+ {
+ SetAlpha( 255 );
+ }
+ else
+ {
+ SetAlpha( (float)( 255.0f * flLifeTime ) );
+ }
+ */
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+const char *CHudNotificationPanel::GetNotificationByType( int iType, float& flDuration )
+{
+ bool bOnBlueTeam = false;
+
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+
+ if ( pLocalPlayer )
+ {
+ bOnBlueTeam = ( pLocalPlayer->GetTeamNumber() == TF_TEAM_BLUE );
+ }
+
+ const char *pszResult = "";
+
+ switch ( iType )
+ {
+ case HUD_NOTIFY_YOUR_FLAG_TAKEN:
+ if ( bOnBlueTeam )
+ {
+ pszResult = "resource/UI/notifications/notify_your_flag_taken_blue.res";
+ }
+ else
+ {
+ pszResult = "resource/UI/notifications/notify_your_flag_taken_red.res";
+ }
+ break;
+ case HUD_NOTIFY_YOUR_FLAG_DROPPED:
+ if ( bOnBlueTeam )
+ {
+ pszResult = "resource/UI/notifications/notify_your_flag_dropped_blue.res";
+ }
+ else
+ {
+ pszResult = "resource/UI/notifications/notify_your_flag_dropped_red.res";
+ }
+ break;
+ case HUD_NOTIFY_YOUR_FLAG_RETURNED:
+ if ( bOnBlueTeam )
+ {
+ pszResult = "resource/UI/notifications/notify_your_flag_returned_blue.res";
+ }
+ else
+ {
+ pszResult = "resource/UI/notifications/notify_your_flag_returned_red.res";
+ }
+ break;
+ case HUD_NOTIFY_YOUR_FLAG_CAPTURED:
+ if ( bOnBlueTeam )
+ {
+ pszResult = "resource/UI/notifications/notify_your_flag_captured_blue.res";
+ }
+ else
+ {
+ pszResult = "resource/UI/notifications/notify_your_flag_captured_red.res";
+ }
+ break;
+ case HUD_NOTIFY_ENEMY_FLAG_TAKEN:
+ if ( bOnBlueTeam )
+ {
+ pszResult = "resource/UI/notifications/notify_enemy_flag_taken_blue.res";
+ }
+ else
+ {
+ pszResult = "resource/UI/notifications/notify_enemy_flag_taken_red.res";
+ }
+ break;
+ case HUD_NOTIFY_ENEMY_FLAG_DROPPED:
+ if ( bOnBlueTeam )
+ {
+ pszResult = "resource/UI/notifications/notify_enemy_flag_dropped_blue.res";
+ }
+ else
+ {
+ pszResult = "resource/UI/notifications/notify_enemy_flag_dropped_red.res";
+ }
+ break;
+ case HUD_NOTIFY_ENEMY_FLAG_RETURNED:
+ if ( bOnBlueTeam )
+ {
+ pszResult = "resource/UI/notifications/notify_enemy_flag_returned_blue.res";
+ }
+ else
+ {
+ pszResult = "resource/UI/notifications/notify_enemy_flag_returned_red.res";
+ }
+ break;
+ case HUD_NOTIFY_ENEMY_FLAG_CAPTURED:
+ if ( bOnBlueTeam )
+ {
+ pszResult = "resource/UI/notifications/notify_enemy_flag_captured_blue.res";
+ }
+ else
+ {
+ pszResult = "resource/UI/notifications/notify_enemy_flag_captured_red.res";
+ }
+ break;
+
+ case HUD_NOTIFY_TOUCHING_ENEMY_CTF_CAP:
+ if ( bOnBlueTeam )
+ {
+ pszResult = "resource/UI/notifications/notify_touching_enemy_ctf_cap_blue.res";
+ }
+ else
+ {
+ pszResult = "resource/UI/notifications/notify_touching_enemy_ctf_cap_red.res";
+ }
+ break;
+
+ case HUD_NOTIFY_NO_INVULN_WITH_FLAG:
+ if ( bOnBlueTeam )
+ {
+ pszResult = "resource/UI/notifications/notify_no_invuln_with_flag_blue.res";
+ }
+ else
+ {
+ pszResult = "resource/UI/notifications/notify_no_invuln_with_flag_red.res";
+ }
+ break;
+
+ case HUD_NOTIFY_NO_TELE_WITH_FLAG:
+ if ( bOnBlueTeam )
+ {
+ pszResult = "resource/UI/notifications/notify_no_tele_with_flag_blue.res";
+ }
+ else
+ {
+ pszResult = "resource/UI/notifications/notify_no_tele_with_flag_red.res";
+ }
+ break;
+
+
+ case HUD_NOTIFY_SPECIAL:
+ pszResult = "resource/UI/notifications/notify_special.res";
+ break;
+
+ case HUD_NOTIFY_GOLDEN_WRENCH:
+ pszResult = "resource/UI/notifications/notify_golden_wrench.res";
+ break;
+
+ case HUD_NOTIFY_RD_ROBOT_UNDER_ATTACK:
+ if ( bOnBlueTeam )
+ {
+ pszResult = "resource/UI/notifications/notify_rd_robot_attacked_blue.res";
+ }
+ else
+ {
+ pszResult = "resource/UI/notifications/notify_rd_robot_attacked_red.res";
+ }
+ break;
+
+ case HUD_NOTIFY_HOW_TO_CONTROL_GHOST:
+ pszResult = "resource/UI/notifications/notify_how_to_control_ghost.res";
+ flDuration = 10.f;
+ break;
+
+ case HUD_NOTIFY_HOW_TO_CONTROL_KART:
+ pszResult = "resource/UI/notifications/notify_how_to_control_kart.res";
+ flDuration = 10.f;
+ break;
+
+ case HUD_NOTIFY_HOW_TO_CONTROL_GHOST_NO_RESPAWN:
+ pszResult = "resource/UI/notifications/notify_how_to_control_ghost_no_respawn.res";
+ flDuration = 10.f;
+ break;
+
+ // Passtime
+ case HUD_NOTIFY_PASSTIME_HOWTO:
+ pszResult = "resource/UI/notifications/notify_passtime_howto.res";
+ flDuration = 10.f;
+ break;
+
+ case HUD_NOTIFY_PASSTIME_NO_TELE:
+ pszResult = "resource/UI/notifications/notify_passtime_no_tele.res";
+ break;
+
+ case HUD_NOTIFY_PASSTIME_NO_CARRY:
+ pszResult = "resource/UI/notifications/notify_passtime_no_carry.res";
+ break;
+
+ case HUD_NOTIFY_PASSTIME_NO_INVULN:
+ pszResult = "resource/UI/notifications/notify_passtime_no_invuln.res";
+ break;
+
+ case HUD_NOTIFY_PASSTIME_NO_DISGUISE:
+ pszResult = "resource/UI/notifications/notify_passtime_no_disguise.res";
+ break;
+
+ case HUD_NOTIFY_PASSTIME_NO_CLOAK:
+ pszResult = "resource/UI/notifications/notify_passtime_no_cloak.res";
+ break;
+
+ case HUD_NOTIFY_PASSTIME_NO_OOB:
+ pszResult = "resource/UI/notifications/notify_passtime_no_oob.res";
+ break;
+
+ case HUD_NOTIFY_PASSTIME_NO_HOLSTER:
+ pszResult = "resource/UI/notifications/notify_passtime_no_holster.res";
+ break;
+
+ case HUD_NOTIFY_PASSTIME_NO_TAUNT:
+ pszResult = "resource/UI/notifications/notify_passtime_no_taunt.res";
+ break;
+
+ // Competitive
+ case HUD_NOTIFY_COMPETITIVE_GC_DOWN:
+ pszResult = "resource/UI/notifications/notify_competitive_gc_down.res";
+ flDuration = 20.f;
+ break;
+
+ case HUD_NOTIFY_TRUCE_START:
+ pszResult = "resource/UI/notifications/notify_truce_start.res";
+ flDuration = 10.f;
+ break;
+
+ case HUD_NOTIFY_TRUCE_END:
+ pszResult = "resource/UI/notifications/notify_truce_end.res";
+ flDuration = 10.f;
+ break;
+
+ default:
+ break;
+ }
+
+ return pszResult;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudNotificationPanel::LoadManifest( void )
+{
+ const char *pszManifestFile = "resource/UI/notifications/notification_manifest.txt";
+ KeyValues *manifest = new KeyValues( pszManifestFile );
+ if ( manifest->LoadFromFile( g_pFullFileSystem, pszManifestFile, "GAME" ) == false )
+ {
+ manifest->deleteThis();
+ return false;
+ }
+
+ // Load each file defined in the text
+ for ( KeyValues *sub = manifest->GetFirstSubKey(); sub != NULL; sub = sub->GetNextKey() )
+ {
+ if ( !Q_stricmp( sub->GetName(), "file" ) )
+ {
+ if ( BuildGroup::PrecacheResFile( sub->GetString() ) == false )
+ {
+ Warning("Failed to load notification res file '%s' specified in %s.\n", sub->GetString(), pszManifestFile );
+ }
+ }
+ }
+
+ manifest->deleteThis();
+ return true;
+} \ No newline at end of file