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.
1244 lines
36 KiB
1244 lines
36 KiB
5 years ago
|
//========= 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 );
|
||
|
}
|