summaryrefslogtreecommitdiff
path: root/game/client/tf/vgui/charinfo_loadout_subpanel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/client/tf/vgui/charinfo_loadout_subpanel.cpp')
-rw-r--r--game/client/tf/vgui/charinfo_loadout_subpanel.cpp1244
1 files changed, 1244 insertions, 0 deletions
diff --git a/game/client/tf/vgui/charinfo_loadout_subpanel.cpp b/game/client/tf/vgui/charinfo_loadout_subpanel.cpp
new file mode 100644
index 0000000..42a7989
--- /dev/null
+++ b/game/client/tf/vgui/charinfo_loadout_subpanel.cpp
@@ -0,0 +1,1244 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+
+#include "cbase.h"
+#include "charinfo_loadout_subpanel.h"
+#include "vgui/ISurface.h"
+#include "vgui/IInput.h"
+#include "vgui/ILocalize.h"
+#include "c_tf_freeaccount.h"
+#include "c_tf_player.h"
+#include "confirm_dialog.h"
+#include "gamestringpool.h"
+#include "c_tf_objective_resource.h"
+#include "tf_gamerules.h"
+#include "tf_item_inventory.h"
+#include "trading_start_dialog.h"
+#include "gc_clientsystem.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+
+DECLARE_BUILD_FACTORY( CImageButton );
+
+
+ConVar tf_explanations_charinfopanel( "tf_explanations_charinfopanel", "0", FCVAR_ARCHIVE, "Whether the user has seen explanations for this panel." );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CImageButton::CImageButton( vgui::Panel *parent, const char *panelName ) : BaseClass( parent, panelName, "" )
+{
+ m_pszActiveImageName = NULL;
+ m_pszInactiveImageName = NULL;
+
+ m_pActiveImage = NULL;
+ m_pInactiveImage = NULL;
+
+ m_ActiveDrawColor = Color(255,255,255,255);
+ m_InactiveDrawColor = Color(255,255,255,255);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CImageButton::ApplySettings( KeyValues *inResourceData )
+{
+ m_bScaleImage = inResourceData->GetInt( "scaleImage", 0 );
+
+ // Active Image
+ delete [] m_pszActiveImageName;
+ m_pszActiveImageName = NULL;
+
+ const char *activeImageName = inResourceData->GetString( "activeimage", "" );
+ if ( *activeImageName )
+ {
+ SetActiveImage( activeImageName );
+ }
+
+ // Inactive Image
+ delete [] m_pszInactiveImageName;
+ m_pszInactiveImageName = NULL;
+
+ const char *inactiveImageName = inResourceData->GetString( "inactiveimage", "" );
+ if ( *inactiveImageName )
+ {
+ SetInactiveImage( inactiveImageName );
+ }
+
+ const char *pszDrawColor = inResourceData->GetString("activedrawcolor", "");
+ if (*pszDrawColor)
+ {
+ int r = 0, g = 0, b = 0, a = 255;
+ if (sscanf(pszDrawColor, "%d %d %d %d", &r, &g, &b, &a) >= 3)
+ {
+ m_ActiveDrawColor = Color(r, g, b, a);
+ }
+ else
+ {
+ vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
+ m_ActiveDrawColor = pScheme->GetColor(pszDrawColor, Color(0, 0, 0, 0));
+ }
+ }
+
+ pszDrawColor = inResourceData->GetString("inactivedrawcolor", "");
+ if (*pszDrawColor)
+ {
+ int r = 0, g = 0, b = 0, a = 255;
+ if (sscanf(pszDrawColor, "%d %d %d %d", &r, &g, &b, &a) >= 3)
+ {
+ m_InactiveDrawColor = Color(r, g, b, a);
+ }
+ else
+ {
+ vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
+ m_InactiveDrawColor = pScheme->GetColor(pszDrawColor, Color(0, 0, 0, 0));
+ }
+ }
+
+ BaseClass::ApplySettings( inResourceData );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CImageButton::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ if ( m_pszActiveImageName && strlen( m_pszActiveImageName ) > 0 )
+ {
+ SetActiveImage(vgui::scheme()->GetImage( m_pszActiveImageName, m_bScaleImage ) );
+ }
+
+ if ( m_pszInactiveImageName && strlen( m_pszInactiveImageName ) > 0 )
+ {
+ SetInactiveImage(vgui::scheme()->GetImage( m_pszInactiveImageName, m_bScaleImage ) );
+ }
+
+ vgui::IBorder *pBorder = pScheme->GetBorder( "NoBorder" );
+ SetDefaultBorder( pBorder);
+ SetDepressedBorder( pBorder );
+ SetKeyFocusBorder( pBorder );
+
+ Color defaultFgColor = GetSchemeColor( "Button.TextColor", Color(255, 255, 255, 255), pScheme );
+ Color armedFgColor = GetSchemeColor( "Button.ArmedTextColor", Color(255, 255, 255, 255), pScheme );
+ Color depressedFgColor = GetSchemeColor( "Button.DepressedTextColor", Color(255, 255, 255, 255), pScheme );
+
+ Color blank(0,0,0,0);
+ SetDefaultColor( defaultFgColor, blank );
+ SetArmedColor( armedFgColor, blank );
+ SetDepressedColor( depressedFgColor, blank );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CImageButton::SetActiveImage( const char *imagename )
+{
+ int len = Q_strlen( imagename ) + 1;
+ m_pszActiveImageName = new char[ len ];
+ Q_strncpy( m_pszActiveImageName, imagename, len );
+
+ SetActiveImage(vgui::scheme()->GetImage( m_pszActiveImageName, m_bScaleImage ) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CImageButton::SetInactiveImage( const char *imagename )
+{
+ int len = Q_strlen( imagename ) + 1;
+ m_pszInactiveImageName = new char[ len ];
+ Q_strncpy( m_pszInactiveImageName, imagename, len );
+
+ SetInactiveImage(vgui::scheme()->GetImage( m_pszInactiveImageName, m_bScaleImage ) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CImageButton::SetActiveImage( vgui::IImage *image )
+{
+ m_pActiveImage = image;
+
+ if ( m_pActiveImage )
+ {
+ int wide, tall;
+ if ( m_bScaleImage )
+ {
+ // scaling, force the image size to be our size
+ GetSize( wide, tall );
+ m_pActiveImage->SetSize( wide, tall );
+ }
+ else
+ {
+ // not scaling, so set our size to the image size
+ m_pActiveImage->GetSize( wide, tall );
+ SetSize( wide, tall );
+ }
+ }
+
+ Repaint();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CImageButton::SetInactiveImage( vgui::IImage *image )
+{
+ m_pInactiveImage = image;
+
+ if ( m_pInactiveImage )
+ {
+ int wide, tall;
+ if ( m_bScaleImage)
+ {
+ // scaling, force the image size to be our size
+ GetSize( wide, tall );
+ m_pInactiveImage->SetSize( wide, tall );
+ }
+ else
+ {
+ // not scaling, so set our size to the image size
+ m_pInactiveImage->GetSize( wide, tall );
+ SetSize( wide, tall );
+ }
+ }
+
+ Repaint();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CImageButton::OnSizeChanged( int newWide, int newTall )
+{
+ if ( m_bScaleImage )
+ {
+ // scaling, force the image size to be our size
+ if ( m_pActiveImage )
+ m_pActiveImage->SetSize( newWide, newTall );
+
+ if ( m_pInactiveImage )
+ m_pInactiveImage->SetSize( newWide, newTall );
+ }
+ BaseClass::OnSizeChanged( newWide, newTall );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CImageButton::Paint()
+{
+ if ( IsArmed() || _buttonFlags.IsFlagSet( FORCE_DEPRESSED ) )
+ {
+ // draw the active image
+ if ( m_pActiveImage )
+ {
+ m_pActiveImage->SetColor( m_ActiveDrawColor );
+ m_pActiveImage->SetPos( 0, 0 );
+ m_pActiveImage->Paint();
+ }
+ }
+ else
+ {
+ // draw the inactive image
+ if ( m_pInactiveImage )
+ {
+ m_pActiveImage->SetColor( m_InactiveDrawColor );
+ m_pInactiveImage->SetPos( 0, 0 );
+ m_pInactiveImage->Paint();
+ }
+ }
+
+ BaseClass::Paint();
+}
+
+const char *g_pszSubButtonNames[CHSB_NUM_BUTTONS] =
+{
+ "ShowBackpackButton", // CHSB_BACKPACK,
+ "ShowCraftingButton", // CHSB_CRAFTING,
+ "ShowArmoryButton", // CHSB_ARMORY,
+ "ShowTradeButton", // CHSB_TRADING,
+};
+const char *g_pszSubButtonLabelNames[CHSB_NUM_BUTTONS] =
+{
+ "ShowBackpackLabel", // CHSB_BACKPACK,
+ "ShowCraftingLabel", // CHSB_CRAFTING,
+ "ShowArmoryLabel", // CHSB_ARMORY,
+ "ShowTradeLabel", // CHSB_TRADING,
+};
+
+int g_nLoadoutClassOrder[] =
+{
+ TF_CLASS_SCOUT,
+ TF_CLASS_SOLDIER,
+ TF_CLASS_PYRO,
+ TF_CLASS_DEMOMAN,
+ TF_CLASS_HEAVYWEAPONS,
+ TF_CLASS_ENGINEER,
+ TF_CLASS_MEDIC,
+ TF_CLASS_SNIPER,
+ TF_CLASS_SPY
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CCharInfoLoadoutSubPanel::CCharInfoLoadoutSubPanel(Panel *parent) : vgui::PropertyPage(parent, "CharInfoLoadoutSubPanel")
+{
+ m_iCurrentClassIndex = TF_CLASS_UNDEFINED;
+ m_iCurrentTeamIndex = TF_TEAM_RED;
+ m_iShowingPanel = CHAP_LOADOUT;
+ m_iPrevShowingPanel = CHAP_LOADOUT;
+
+ memset( m_pClassButtons, 0, sizeof( m_pClassButtons ) );
+
+ m_pClassButtons[ TF_CLASS_SCOUT ] = new CImageButton( this, "scout" );
+ m_pClassButtons[ TF_CLASS_SOLDIER ] = new CImageButton( this, "soldier" );
+ m_pClassButtons[ TF_CLASS_PYRO ] = new CImageButton( this, "pyro" );
+ m_pClassButtons[ TF_CLASS_DEMOMAN ] = new CImageButton( this, "demoman" );
+ m_pClassButtons[ TF_CLASS_HEAVYWEAPONS ] = new CImageButton( this, "heavyweapons" );
+ m_pClassButtons[ TF_CLASS_ENGINEER ] = new CImageButton( this, "engineer" );
+ m_pClassButtons[ TF_CLASS_MEDIC ] = new CImageButton( this, "medic" );
+ m_pClassButtons[ TF_CLASS_SNIPER ] = new CImageButton( this, "sniper" );
+ m_pClassButtons[ TF_CLASS_SPY ] = new CImageButton( this, "spy" );
+
+ for( int i = 0; i < Q_ARRAYSIZE( m_pClassButtons ); i++ )
+ {
+ if( m_pClassButtons[ i ] )
+ m_pClassButtons[ i ]->SetParentNeedsCursorMoveEvents( true );
+ }
+
+ for ( int i = 0; i < CHSB_NUM_BUTTONS; i++ )
+ {
+ m_pSubButtons[i] = new CImageButton( this, g_pszSubButtonNames[i] );
+ m_pButtonLabels[i] = new CExLabel( this, g_pszSubButtonLabelNames[i], "" );
+ }
+ m_iOverSubButton = -1;
+
+ m_pClassLoadoutPanel = new CClassLoadoutPanel( this );
+ m_pBackpackPanel = new CBackpackPanel( this, "backpack_panel" );
+ m_pCraftingPanel = new CCraftingPanel( this, "crafting_panel" );
+ m_pArmoryPanel = new CArmoryPanel( this, "armory_panel" );
+ m_pArmoryPanel->AllowGotoStore();
+ m_pSelectLabel = NULL;
+ m_pLoadoutChangesLabel = NULL;
+ m_pNoSteamLabel = NULL;
+ m_pNoGCLabel = NULL;
+ m_pClassLabel = NULL;
+ m_pItemsLabel = NULL;
+ m_bSnapClassLayout = false;
+ m_bClassLayoutDirty = false;
+ m_bRequestingInventoryRefresh = false;
+ m_flStartExplanationsAt = 0;
+
+ vgui::ivgui()->AddTickSignal( GetVPanel() );
+
+ REGISTER_COLOR_AS_OVERRIDABLE( m_ItemColorNone, "itemcountcolor_noitems" );
+ REGISTER_COLOR_AS_OVERRIDABLE( m_ItemColor, "itemcountcolor" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CCharInfoLoadoutSubPanel::~CCharInfoLoadoutSubPanel()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ LoadControlSettings( "Resource/UI/CharInfoLoadoutSubPanel.res" );
+
+ m_pSelectLabel = dynamic_cast<vgui::Label*>( FindChildByName("SelectLabel") );
+ m_pLoadoutChangesLabel = dynamic_cast<vgui::Label*>( FindChildByName("LoadoutChangesLabel") );
+ m_pNoSteamLabel = dynamic_cast<vgui::Label*>( FindChildByName("NoSteamLabel") );
+ m_pNoGCLabel = dynamic_cast<vgui::Label*>( FindChildByName("NoGCLabel") );
+ m_pClassLabel = dynamic_cast<vgui::Label*>( FindChildByName("ClassLabel") );
+ int ignored;
+ if ( m_pClassLabel )
+ {
+ m_pClassLabel->GetPos( ignored, m_iClassLabelYPos );
+ }
+ m_pItemsLabel = dynamic_cast<CExLabel*>( FindChildByName("ItemsLabel") );
+ if ( m_pItemsLabel )
+ {
+ m_pItemsLabel->GetPos( ignored, m_iItemLabelYPos );
+ }
+
+ // Start classes sized as if the mouse is in the middle of the screen
+ m_iMouseXPos = -1;
+ m_bSnapClassLayout = true;
+ RecalculateTargetClassLayout();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::OnPageShow( void )
+{
+ SetVisible( true );
+
+ BaseClass::OnPageShow();
+
+ if( m_iCurrentClassIndex != TF_CLASS_UNDEFINED )
+ {
+ m_pClassButtons[ m_iCurrentClassIndex ]->GetPos( m_iMouseXPos, m_iMouseYPos );
+ m_bClassLayoutDirty = true;
+ InvalidateLayout();
+ }
+
+ // If this is the first time we've opened the loadout, start the loadout explanations
+ if ( !tf_explanations_charinfopanel.GetBool() && ShouldShowExplanations() )
+ {
+ m_flStartExplanationsAt = engine->Time() + 0.5;
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::OnSelectionStarted( void )
+{
+ PostActionSignal( new KeyValues("SelectionUpdate", "open", 1 ) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::OnSelectionEnded( void )
+{
+ PostActionSignal( new KeyValues("SelectionUpdate", "open", 0 ) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::OnCancelSelection( void )
+{
+ PostMessage( m_pClassLoadoutPanel, new KeyValues("CancelSelection") );
+ PostMessage( m_pBackpackPanel, new KeyValues("CancelSelection") );
+ PostMessage( m_pCraftingPanel, new KeyValues("CancelSelection") );
+ PostMessage( m_pArmoryPanel, new KeyValues("CancelSelection") );
+ RequestFocus();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::OnCharInfoClosing( void )
+{
+ switch ( m_iShowingPanel )
+ {
+ case CHAP_CRAFTING:
+ PostMessage( m_pCraftingPanel, new KeyValues("Closing") );
+ break;
+ case CHAP_BACKPACK:
+ break;
+ case CHAP_ARMORY:
+ PostMessage( m_pArmoryPanel, new KeyValues("Closing") );
+ break;
+ case CHAP_LOADOUT:
+ PostMessage( m_pClassLoadoutPanel, new KeyValues("Closing") );
+ break;
+ default: // Class loadout.
+ break;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::OnOpenCrafting( void )
+{
+ OpenToCrafting();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::OnCraftingClosed( void )
+{
+ PostMessage( m_pCraftingPanel, new KeyValues("Closing") );
+ m_iShowingPanel = CHAP_LOADOUT;
+ m_iPrevShowingPanel = CHAP_CRAFTING;
+ m_flStartExplanationsAt = 0;
+ m_iCurrentClassIndex = TF_CLASS_UNDEFINED;
+ UpdateModelPanels();
+ RequestFocus();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::OnArmoryClosed( void )
+{
+ // Return to whatever we were on before opening the armory
+ PostMessage( m_pArmoryPanel, new KeyValues("Closing") );
+ m_iShowingPanel = m_iPrevShowingPanel;
+ m_iPrevShowingPanel = CHAP_ARMORY;
+ m_flStartExplanationsAt = 0;
+ m_iCurrentClassIndex = TF_CLASS_UNDEFINED;
+ UpdateModelPanels();
+ RequestFocus();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::OnCommand( const char *command )
+{
+ if ( !Q_strnicmp( command, "loadout ", 8 ) )
+ {
+ // Ignore selection while we don't have a steam connection
+ if ( !TFInventoryManager()->GetLocalTFInventory()->RetrievedInventoryFromSteam() )
+ return;
+
+ m_flStartExplanationsAt = 0;
+
+ const char *pszClass = command+8;
+ if ( pszClass[0] != '\0' )
+ {
+ int nClassIndex = GetClassIndexFromString( pszClass, NUM_CLASSES_IN_LOADOUT_PANEL );
+ if ( nClassIndex != TF_CLASS_UNDEFINED && m_iCurrentClassIndex != nClassIndex )
+ {
+ SetClassIndex( nClassIndex, true );
+ return;
+ }
+ }
+ }
+ else if ( !Q_strnicmp( command, "backpack", 8 ) )
+ {
+ OpenToBackpack();
+ }
+ else if ( !Q_strnicmp( command, "crafting", 8 ) )
+ {
+ OpenToCrafting();
+ }
+ else if ( !Q_strnicmp( command, "armory", 6 ) )
+ {
+ OpenToArmory();
+ }
+ else if ( !Q_strnicmp( command, "trading", 7 ) )
+ {
+ OpenTradingStartDialog( this );
+ }
+ else if ( !Q_stricmp( command, "show_explanations" ) )
+ {
+ if ( !m_flStartExplanationsAt )
+ {
+ m_flStartExplanationsAt = engine->Time();
+ }
+ RequestFocus();
+ }
+ else
+ {
+ engine->ClientCmd( const_cast<char *>( command ) );
+ }
+
+ BaseClass::OnCommand( command );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::RequestInventoryRefresh()
+{
+ m_bRequestingInventoryRefresh = false;
+
+ // Don't respond to the mouse if we don't have items
+ if ( !TFInventoryManager()->GetLocalTFInventory()->RetrievedInventoryFromSteam() )
+ {
+ ShowWaitingDialog( new CGenericWaitingDialog(this), "#NoSteamNoItems_Refresh", true, true, 30.0f );
+ if ( !m_bRequestingInventoryRefresh )
+ {
+ // make sure the local inventory is added as a listener
+ TFInventoryManager()->UpdateLocalInventory();
+ m_bRequestingInventoryRefresh = true;
+ // ask GC for refresh
+ GCSDK::CProtoBufMsg< CMsgRequestInventoryRefresh > msg( k_EMsgGCRequestInventoryRefresh );
+ GCClientSystem()->BSendMessage( msg );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::SetClassIndex( int iClassIndex, bool bOpenClassLoadout )
+{
+ Assert(iClassIndex >= TF_CLASS_UNDEFINED && iClassIndex <= NUM_CLASSES_IN_LOADOUT_PANEL);
+ m_iCurrentClassIndex = iClassIndex;
+ m_iShowingPanel = CHAP_LOADOUT;
+ UpdateModelPanels( bOpenClassLoadout );
+
+ RequestInventoryRefresh();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::SetTeamIndex( int iTeam )
+{
+ Assert( IsValidTFTeam( iTeam ) );
+ m_iCurrentTeamIndex = iTeam;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::OpenSubPanel( charinfo_activepanels_t iPanel )
+{
+ m_flStartExplanationsAt = 0;
+ m_iCurrentClassIndex = TF_CLASS_UNDEFINED;
+ m_iPrevShowingPanel = m_iShowingPanel;
+ m_iShowingPanel = iPanel;
+
+ UpdateModelPanels();
+
+ RequestInventoryRefresh();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::UpdateModelPanels( bool bOpenClassLoadout )
+{
+ int iLabelClassToSet = -1;
+ int iClassIndexToSet = 0;
+
+ if ( m_iShowingPanel == CHAP_CRAFTING )
+ {
+ m_pClassLoadoutPanel->SetVisible( false );
+ m_pBackpackPanel->SetVisible( false );
+ m_pArmoryPanel->SetVisible( false );
+ m_pCraftingPanel->ShowPanel( m_iCurrentClassIndex, true, (m_iPrevShowingPanel == CHAP_ARMORY) );
+ }
+ else if ( m_iShowingPanel == CHAP_BACKPACK )
+ {
+ m_pClassLoadoutPanel->SetVisible( false );
+ m_pCraftingPanel->SetVisible( false );
+ m_pArmoryPanel->SetVisible( false );
+ m_pBackpackPanel->ShowPanel( m_iCurrentClassIndex, true, (m_iPrevShowingPanel == CHAP_ARMORY) );
+ }
+ else if ( m_iShowingPanel == CHAP_ARMORY )
+ {
+ m_pClassLoadoutPanel->SetVisible( false );
+ m_pCraftingPanel->SetVisible( false );
+ m_pBackpackPanel->SetVisible( false );
+ m_pArmoryPanel->ShowPanel( m_iArmoryItemDef );
+ }
+ else
+ {
+ iClassIndexToSet = bOpenClassLoadout ? m_iCurrentClassIndex : TF_CLASS_UNDEFINED;
+ m_pArmoryPanel->SetVisible( false );
+ m_pBackpackPanel->SetVisible( false );
+ m_pCraftingPanel->SetVisible( false );
+ m_pClassLoadoutPanel->SetTeam( m_iCurrentTeamIndex );
+ m_pClassLoadoutPanel->SetClass( iClassIndexToSet );
+ m_pClassLoadoutPanel->ShowPanel( iClassIndexToSet, false, (m_iPrevShowingPanel == CHAP_ARMORY) );
+
+ iLabelClassToSet = m_iCurrentClassIndex;
+ }
+
+ m_iCurrentClassIndex = iClassIndexToSet;
+
+ if( bOpenClassLoadout )
+ {
+ PostActionSignal( new KeyValues("ClassSelected", "class", m_iCurrentClassIndex ) );
+ }
+ else
+ {
+ m_iLabelSetToClass = iLabelClassToSet;
+ m_bClassLayoutDirty = true;
+ InvalidateLayout();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::PerformLayout( void )
+{
+ BaseClass::PerformLayout();
+
+ // Show our changes label if we're alive, and hence won't get the changes immediately
+ bool bChangesLabel = false;
+ if ( engine->IsInGame() )
+ {
+ C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
+ if ( pLocalPlayer && pLocalPlayer->IsAlive() && pLocalPlayer->GetObserverMode() == OBS_MODE_NONE )
+ {
+ bChangesLabel = true;
+ }
+ }
+
+ if ( !TFInventoryManager()->GetLocalTFInventory()->RetrievedInventoryFromSteam() )
+ {
+ bool bLoggedIntoSteam = steamapicontext && steamapicontext->SteamUser() && steamapicontext->SteamUser()->BLoggedOn();
+ if ( m_pItemsLabel )
+ m_pNoGCLabel->SetVisible( bLoggedIntoSteam );
+ if ( m_pNoSteamLabel )
+ m_pNoSteamLabel->SetVisible( !bLoggedIntoSteam );
+ if ( m_pSelectLabel )
+ m_pSelectLabel->SetVisible( false );
+ if ( m_pLoadoutChangesLabel)
+ m_pLoadoutChangesLabel->SetVisible( false );
+
+ for ( int i = 0; i < CHSB_NUM_BUTTONS; i++ )
+ {
+ m_pSubButtons[i]->SetVisible( false );
+ m_pButtonLabels[i]->SetVisible( false );
+ }
+ }
+ else
+ {
+ if ( m_pNoSteamLabel )
+ m_pNoSteamLabel->SetVisible( false );
+ if ( m_pNoGCLabel )
+ m_pNoGCLabel->SetVisible( false );
+ if ( m_pSelectLabel )
+ m_pSelectLabel->SetVisible( true );
+
+ for ( int i = 0; i < CHSB_NUM_BUTTONS; i++ )
+ {
+ m_pSubButtons[i]->SetVisible( true );
+ m_pButtonLabels[i]->SetVisible( true );
+ }
+ if ( !bChangesLabel )
+ {
+ if ( m_pSelectLabel )
+ m_pSelectLabel->SetPos( 0, m_iSelectLabelY );
+ if ( m_pLoadoutChangesLabel )
+ m_pLoadoutChangesLabel->SetVisible( false );
+ }
+ else
+ {
+ if ( m_pSelectLabel )
+ m_pSelectLabel->SetPos( 0, m_iSelectLabelOnChangesY );
+ if ( m_pLoadoutChangesLabel )
+ m_pLoadoutChangesLabel->SetVisible( true );
+ }
+ }
+
+ m_iOverSubButton = -1;
+ if ( m_pSelectLabel )
+ m_pClassLabel->SetVisible( false );
+ if ( m_pItemsLabel )
+ m_pItemsLabel->SetVisible( false );
+
+ m_bClassLayoutDirty = false;
+
+ // Now Layout the class images.
+ for ( int iPanel = 0; iPanel < ARRAYSIZE( g_nLoadoutClassOrder ); iPanel++ )
+ {
+ int i = g_nLoadoutClassOrder[iPanel];
+
+ int iX = m_iClassLayout[i][0];
+ int iY = m_iClassLayout[i][1];
+ int iWide = m_iClassLayout[i][2];
+ int iTall = m_iClassLayout[i][3];
+
+ if ( m_bSnapClassLayout )
+ {
+ m_pClassButtons[i]->SetBounds( iX, iY, iWide, iTall );
+ }
+ else
+ {
+ // Lerp towards the target
+ int iCurX, iCurY, iCurWide, iCurTall;
+ m_pClassButtons[i]->GetBounds( iCurX, iCurY, iCurWide, iCurTall );
+ int iNewX = Lerp( 0.2, iCurX, iX );
+ int iNewY = Lerp( 0.2, iCurY, iY );
+ int iNewWide = Lerp( 0.2, iCurWide, iWide );
+ int iNewTall = Lerp( 0.2, iCurTall, iTall );
+ m_pClassButtons[i]->SetBounds( iNewX, iNewY, iNewWide, iNewTall );
+ if ( abs(iNewX-iX) > 5 || abs(iNewY-iY) > 5 || abs(iNewWide-iWide) > 5 || abs(iNewTall-iTall) > 5 )
+ {
+ m_bClassLayoutDirty = true;
+ }
+ }
+ }
+
+ // We need to do our own management of cursor arming in the buttons, because the curserentered/exited code can't
+ // deal with the way we resize the buttons without the cursor moving.
+ int iBestButton = -1;
+ int iBestZ = 0;
+ int x = m_iMouseXPos, y = m_iMouseYPos;
+
+ // only get the actual cursor pos if we don't have a cached cursor pos. THe
+ // cached pos might have come from the keyboard.
+ if( x < 0 )
+ vgui::input()->GetCursorPos(x, y);
+ for ( int iPanel = 0; iPanel < ARRAYSIZE( g_nLoadoutClassOrder ); iPanel++ )
+ {
+ int i = g_nLoadoutClassOrder[iPanel];
+ m_pClassButtons[i]->SetArmed( false );
+
+ m_pClassButtons[i]->SetEnabled( TFInventoryManager()->GetLocalTFInventory()->RetrievedInventoryFromSteam() );
+
+ if ( m_pClassButtons[i]->IsWithin( x,y ) && iBestZ < m_pClassButtons[i]->GetZPos() )
+ {
+ iBestButton = i;
+ iBestZ = m_pClassButtons[i]->GetZPos();
+ }
+ }
+
+ if ( iBestButton >= 0 && iBestButton < ARRAYSIZE( m_pClassButtons ) )
+ {
+ m_pClassButtons[iBestButton]->SetArmed( true );
+
+ if ( m_iLabelSetToClass != iBestButton )
+ {
+ m_iLabelSetToClass = iBestButton;
+ }
+
+ UpdateLabelFromClass( m_iLabelSetToClass );
+ }
+
+ m_bSnapClassLayout = false;
+}
+
+void CCharInfoLoadoutSubPanel::UpdateLabelFromClass( int nClass )
+{
+ if ( nClass < 0 )
+ return;
+
+ const wchar_t *wszClassName = g_pVGuiLocalize->Find( g_aPlayerClassNames[nClass] );
+ if ( m_pClassLabel )
+ {
+ m_pClassLabel->SetText( wszClassName );
+ m_pClassLabel->SetVisible( true );
+ }
+
+ if ( m_pItemsLabel )
+ {
+ m_pItemsLabel->SetVisible( true );
+ }
+
+ CUtlVector<CEconItemView*> pList;
+ int iNumItems = TFInventoryManager()->GetAllUsableItemsForSlot( nClass, -1, &pList );
+
+ if ( !iNumItems )
+ {
+ const wchar_t *wszItemsName = g_pVGuiLocalize->Find( "#NoItemsFoundShort" );
+ m_pItemsLabel->SetText( wszItemsName );
+ m_pItemsLabel->SetColorStr( m_ItemColorNone );
+ }
+ else if ( iNumItems == 1 )
+ {
+ const wchar_t *wszItemsName = g_pVGuiLocalize->Find( "#ItemsFoundShortOne" );
+ m_pItemsLabel->SetText( wszItemsName );
+ m_pItemsLabel->SetColorStr( m_ItemColor );
+ }
+ else
+ {
+ wchar_t wzCount[10];
+ _snwprintf( wzCount, ARRAYSIZE( wzCount ), L"%d", iNumItems );
+ wchar_t wTemp[32];
+ g_pVGuiLocalize->ConstructString_safe( wTemp, g_pVGuiLocalize->Find("ItemsFoundShort"), 1, wzCount );
+ m_pItemsLabel->SetText( wTemp );
+ m_pItemsLabel->SetColorStr( m_ItemColor );
+ }
+
+ int iPos = 0;
+ for ( int i = TF_FIRST_NORMAL_CLASS; i <= NUM_CLASSES_IN_LOADOUT_PANEL; i++ )
+ {
+ if ( iRemapIndexToClass[i] == nClass )
+ {
+ iPos = i;
+ break;
+ }
+ }
+ Assert(iPos != 0 );
+ int iXLeft = (GetWide() - ((m_iClassWideMin * NUM_CLASSES_IN_LOADOUT_PANEL) + (m_iClassXDelta * (NUM_CLASSES_IN_LOADOUT_PANEL-1)))) * 0.5;
+ int iBaseX = iXLeft + ((m_iClassWideMin + m_iClassXDelta) * (iPos-1));
+ int iCenterX = iBaseX + (m_iClassWideMin * 0.5);
+
+ m_pClassLabel->SetVisible( true );
+ m_pClassLabel->SetPos( iCenterX - (m_pClassLabel->GetWide() * 0.5), m_iClassLabelYPos );
+ m_pItemsLabel->SetVisible( true );
+ m_pItemsLabel->SetPos( iCenterX - (m_pItemsLabel->GetWide() * 0.5), m_iItemLabelYPos );
+}
+
+void CCharInfoLoadoutSubPanel::UpdateLabelFromSubButton( int nButton )
+{
+ if( nButton < 0 )
+ nButton = CHSB_NUM_BUTTONS - 1;
+ else if( nButton >= CHSB_NUM_BUTTONS )
+ nButton = 0;
+
+ if ( m_iOverSubButton == nButton )
+ return;
+
+ m_iOverSubButton = nButton;
+
+ switch ( nButton )
+ {
+ default:
+ case CHSB_BACKPACK:
+ {
+ int iNumItems = TFInventoryManager()->GetLocalTFInventory()->GetItemCount();
+ if ( iNumItems == 1 )
+ {
+ const wchar_t *wszItemsName = g_pVGuiLocalize->Find( "#Loadout_OpenBackpackDesc1" );
+ m_pItemsLabel->SetText( wszItemsName );
+ }
+ else
+ {
+ wchar_t wzCount[10];
+ _snwprintf( wzCount, ARRAYSIZE( wzCount ), L"%d", iNumItems );
+ wchar_t wTemp[32];
+ g_pVGuiLocalize->ConstructString_safe( wTemp, g_pVGuiLocalize->Find("Loadout_OpenBackpackDesc"), 1, wzCount );
+ m_pItemsLabel->SetText( wTemp );
+ }
+ }
+ break;
+ case CHSB_CRAFTING:
+ m_pItemsLabel->SetText( g_pVGuiLocalize->Find( "Loadout_OpenCraftingDesc" ) );
+ break;
+ case CHSB_ARMORY:
+ m_pItemsLabel->SetText( g_pVGuiLocalize->Find( "Loadout_OpenArmoryDesc" ) );
+ break;
+ case CHSB_TRADING:
+ m_pItemsLabel->SetText( g_pVGuiLocalize->Find( "Loadout_OpenTradingDesc" ) );
+ break;
+ }
+
+ int iX, iY;
+ m_pSubButtons[nButton]->GetPos( iX, iY );
+ iX += (m_pSubButtons[nButton]->GetWide() * 0.5);
+ iY += m_pSubButtons[nButton]->GetTall() + YRES(5);
+
+ m_pItemsLabel->SetVisible( true );
+ m_pItemsLabel->SetPos( iX - (m_pItemsLabel->GetWide() * 0.5), iY + (m_iItemLabelYPos - m_iClassLabelYPos) );
+ m_pItemsLabel->SetColorStr( m_ItemColor );
+
+ for ( int i = 0; i < CHSB_NUM_BUTTONS; i++ )
+ {
+ m_pSubButtons[i]->SetArmed( false );
+ }
+
+ m_pSubButtons[nButton]->SetArmed( true );
+ m_pSubButtons[nButton]->RequestFocus();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::OnTick( void )
+{
+ if ( m_iCurrentClassIndex != TF_CLASS_UNDEFINED )
+ return;
+ if ( !IsVisible() )
+ return;
+
+ if ( m_bRequestingInventoryRefresh && TFInventoryManager()->GetLocalTFInventory()->RetrievedInventoryFromSteam() )
+ {
+ m_bRequestingInventoryRefresh = false;
+ CloseWaitingDialog();
+ return;
+ }
+
+ // if the class layout is dirty, invalidate our layout so that
+ // we'll animate the class buttons.
+ if ( m_bClassLayoutDirty )
+ {
+ InvalidateLayout();
+ }
+
+ if ( !HasFocus() )
+ return;
+
+ // Don't respond to the mouse if we don't have items
+ if ( !TFInventoryManager()->GetLocalTFInventory()->RetrievedInventoryFromSteam() )
+ return;
+
+ if ( m_flStartExplanationsAt && m_flStartExplanationsAt < engine->Time() )
+ {
+ m_flStartExplanationsAt = 0;
+
+ if ( ShouldShowExplanations() )
+ {
+ tf_explanations_charinfopanel.SetValue( 1 );
+
+ CExplanationPopup *pPopup = dynamic_cast<CExplanationPopup*>( FindChildByName("StartExplanation") );
+ if ( pPopup )
+ {
+ pPopup->Popup();
+ }
+ }
+ }
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles mousing over classes
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::OnCursorMoved( int x, int y )
+{
+ RecalculateTargetClassLayoutAtPos( x, y );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles setting the highlighted class for both mouse and keyboard
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::RecalculateTargetClassLayoutAtPos( int x, int y )
+{
+ // Ignore mouse movement outside the buttons
+ bool bWithin = false;
+ for ( int i = TF_FIRST_NORMAL_CLASS; i <= NUM_CLASSES_IN_LOADOUT_PANEL; i++ )
+ {
+ if ( m_pClassButtons[i]->IsWithin(x,y) )
+ {
+ bWithin = true;
+ break;
+ }
+ }
+
+ if ( bWithin )
+ {
+ m_iMouseXPos = x;
+ m_iMouseYPos = y;
+ RecalculateTargetClassLayout();
+ m_bClassLayoutDirty = true;
+ }
+ else
+ {
+ // See if we're over a sub button
+ bool bOverSubButton = false;
+ for ( int i = 0; i < CHSB_NUM_BUTTONS; i++ )
+ {
+ if ( m_pSubButtons[i]->IsWithin(x,y) )
+ {
+ bOverSubButton = true;
+ UpdateLabelFromSubButton( i );
+ }
+ }
+
+ if ( !bOverSubButton && m_pClassLabel->IsVisible() )
+ {
+ // Hide the class label
+ if ( m_iMouseXPos != -1 )
+ {
+ m_iMouseXPos = -1;
+ RecalculateTargetClassLayout();
+ m_bClassLayoutDirty = true;
+ }
+
+ m_iOverSubButton = -1;
+ m_iLabelSetToClass = -1;
+ m_pClassLabel->SetVisible( false );
+ m_pItemsLabel->SetVisible( false );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCharInfoLoadoutSubPanel::RecalculateTargetClassLayout( void )
+{
+ // Now Layout the class images.
+ for ( int i = TF_FIRST_NORMAL_CLASS; i <= NUM_CLASSES_IN_LOADOUT_PANEL; i++ )
+ {
+ int iIndex = GetRemappedMenuIndexForClass(i);
+
+ // Figure out where we'd be unscaled
+ int iXLeft = (GetWide() - ((m_iClassWideMin * NUM_CLASSES_IN_LOADOUT_PANEL) + (m_iClassXDelta * (NUM_CLASSES_IN_LOADOUT_PANEL-1)))) * 0.5;
+ int iBaseX = iXLeft + ((m_iClassWideMin + m_iClassXDelta) * (iIndex-1));
+
+ // Scale based on distance from the mouse cursor.
+ int iCenterX = iBaseX + (m_iClassWideMin * 0.5);
+
+ float flScale = 0.0;
+ if ( m_iMouseXPos >= 0 )
+ {
+ flScale = RemapValClamped( abs(m_iMouseXPos - iCenterX), m_iClassDistanceMin, m_iClassDistanceMax, 1.0, 0.0 );
+ }
+
+ float iWide = RemapValClamped( flScale, 0.0, 1.0, m_iClassWideMin, m_iClassWideMax );
+ float iTall = RemapValClamped( flScale, 0.0, 1.0, m_iClassTallMin, m_iClassTallMax );
+
+ int iY = m_iClassYPos - ((iTall - m_iClassTallMin) * 0.5);
+ int iX = iBaseX - ((iWide - m_iClassWideMin) * 0.5);
+
+ m_pClassButtons[i]->SetZPos( flScale * 100 );
+
+ // Cache off the target bounds for this class button
+ m_iClassLayout[i][0] = iX;
+ m_iClassLayout[i][1] = iY;
+ m_iClassLayout[i][2] = iWide;
+ m_iClassLayout[i][3] = iTall;
+ }
+}
+
+void CCharInfoLoadoutSubPanel::MoveCharacterSelection( int nDirection )
+{
+ int nCurrent = 0;
+
+ if ( m_iLabelSetToClass != -1 )
+ {
+ for ( int i = 0; i < ARRAYSIZE( g_nLoadoutClassOrder ); i++ )
+ {
+ if ( m_iLabelSetToClass == g_nLoadoutClassOrder[ i ] )
+ {
+ nCurrent = i;
+ break;
+ }
+ }
+
+ nCurrent += nDirection;
+
+ if ( nCurrent < 0 )
+ {
+ nCurrent = ARRAYSIZE( g_nLoadoutClassOrder ) - 1;
+ }
+ else if ( nCurrent >= ARRAYSIZE( g_nLoadoutClassOrder ) )
+ {
+ nCurrent = 0;
+ }
+ }
+
+ for ( int i = 0; i < ARRAYSIZE( g_nLoadoutClassOrder ); i++ )
+ {
+ m_pClassButtons[ g_nLoadoutClassOrder[ i ] ]->SetArmed( false );
+ }
+
+ // animate the class buttons
+ CImageButton *pButton = m_pClassButtons[ g_nLoadoutClassOrder[ nCurrent ] ];
+ int x, y, wide, tall;
+ pButton->GetBounds( x, y, wide, tall );
+ RecalculateTargetClassLayoutAtPos( x + wide/2, y + tall/2 );
+
+ pButton->RequestFocus();
+}
+
+void CCharInfoLoadoutSubPanel::OnKeyCodeTyped(vgui::KeyCode code)
+{
+ // turn off key handling in this panel when we're showing a loadout
+ // for one class
+ if ( m_iCurrentClassIndex != TF_CLASS_UNDEFINED )
+ {
+ // let escape and B (aka "go back") through so we
+ // can actually get out of the loadout screen
+ if ( code == KEY_ESCAPE )
+ {
+ BaseClass::OnKeyCodePressed( code );
+ }
+ return;
+ }
+
+ BaseClass::OnKeyCodeTyped( code );
+}
+
+void CCharInfoLoadoutSubPanel::OnKeyCodePressed(vgui::KeyCode code)
+{
+ ButtonCode_t nButtonCode = GetBaseButtonCode( code );
+
+ // turn off key handling in this panel when we're showing a loadout
+ // for one class
+ if( m_iCurrentClassIndex != TF_CLASS_UNDEFINED )
+ {
+ // let escape and B (aka "go back") through so we
+ // can actually get out of the loadout screen
+ if ( nButtonCode == KEY_XBUTTON_B )
+ {
+ BaseClass::OnKeyCodePressed( code );
+ }
+ return;
+ }
+
+ if ( nButtonCode == KEY_XBUTTON_LEFT ||
+ nButtonCode == KEY_XSTICK1_LEFT ||
+ nButtonCode == KEY_XSTICK2_LEFT ||
+ nButtonCode == STEAMCONTROLLER_DPAD_LEFT ||
+ code == KEY_LEFT )
+ {
+ if ( m_iLabelSetToClass != -1 )
+ {
+ MoveCharacterSelection( -1 );
+ }
+ else
+ {
+ UpdateLabelFromSubButton( m_iOverSubButton - 1 );
+ }
+ return;
+ }
+ else if ( nButtonCode == KEY_XBUTTON_RIGHT ||
+ nButtonCode == KEY_XSTICK1_RIGHT ||
+ nButtonCode == KEY_XSTICK2_RIGHT ||
+ nButtonCode == STEAMCONTROLLER_DPAD_RIGHT ||
+ code == KEY_RIGHT )
+ {
+ if ( m_iLabelSetToClass != -1 )
+ {
+ MoveCharacterSelection( 1 );
+ }
+ else
+ {
+ UpdateLabelFromSubButton( m_iOverSubButton + 1 );
+ }
+ return;
+ }
+ else if ( nButtonCode == KEY_XBUTTON_UP ||
+ nButtonCode == KEY_XSTICK1_UP ||
+ nButtonCode == KEY_XSTICK2_UP ||
+ nButtonCode == STEAMCONTROLLER_DPAD_UP ||
+ code == KEY_UP )
+ {
+ if ( m_iLabelSetToClass == -1 )
+ {
+ m_iLabelSetToClass = g_nLoadoutClassOrder[ 0 ];
+ CImageButton *pButton = m_pClassButtons[ m_iLabelSetToClass ];
+ UpdateLabelFromClass( m_iLabelSetToClass );
+
+ int x, y, wide, tall;
+ pButton->GetBounds( x, y, wide, tall );
+ RecalculateTargetClassLayoutAtPos( x + wide/2, y + tall/2 );
+ pButton->RequestFocus();
+
+ }
+ return;
+ }
+ else if ( nButtonCode == KEY_XBUTTON_DOWN ||
+ nButtonCode == KEY_XSTICK1_DOWN ||
+ nButtonCode == KEY_XSTICK2_DOWN ||
+ nButtonCode == STEAMCONTROLLER_DPAD_DOWN ||
+ code == KEY_DOWN )
+ {
+ if ( m_iLabelSetToClass != -1 )
+ {
+ m_iLabelSetToClass = -1;
+ m_pClassLabel->SetVisible( false );
+ m_pItemsLabel->SetVisible( false );
+
+ for ( int iPanel = 0; iPanel < ARRAYSIZE( g_nLoadoutClassOrder ); iPanel++ )
+ {
+ int i = g_nLoadoutClassOrder[iPanel];
+ m_pClassButtons[i]->SetArmed( false );
+ }
+
+ UpdateLabelFromSubButton( 0 );
+ }
+ return;
+ }
+
+ BaseClass::OnKeyCodePressed( code );
+} \ No newline at end of file