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.
946 lines
29 KiB
946 lines
29 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
|
||
|
|
||
|
#include "cbase.h"
|
||
|
#include "charinfo_armory_subpanel.h"
|
||
|
#include "vgui/ISurface.h"
|
||
|
#include "vgui/IInput.h"
|
||
|
#include "vgui/ILocalize.h"
|
||
|
#include "c_tf_player.h"
|
||
|
#include "c_tf_gamestats.h"
|
||
|
#include "gamestringpool.h"
|
||
|
#include "tf_item_inventory.h"
|
||
|
#include "econ_item_system.h"
|
||
|
#include "iachievementmgr.h"
|
||
|
#include "store/store_panel.h"
|
||
|
#include "character_info_panel.h"
|
||
|
|
||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||
|
#include <tier0/memdbgon.h>
|
||
|
|
||
|
ConVar tf_explanations_charinfo_armory_panel( "tf_explanations_charinfo_armory_panel", "0", FCVAR_ARCHIVE, "Whether the user has seen explanations for this panel." );
|
||
|
|
||
|
const char *g_szArmoryFilterStrings[ARMFILT_TOTAL] =
|
||
|
{
|
||
|
"#ArmoryFilter_AllItems", // ARMFILT_ALL_ITEMS.
|
||
|
"#ArmoryFilter_Weapons", // ARMFILT_WEAPONS,
|
||
|
"#ArmoryFilter_Headgear", // ARMFILT_HEADGEAR,
|
||
|
"#ArmoryFilter_MiscItems", // ARMFILT_MISCITEMS,
|
||
|
"#ArmoryFilter_ActionItems", // ARMFILT_ACTIONITEMS,
|
||
|
"#ArmoryFilter_CraftItems", // ARMFILT_CRAFTITEMS,
|
||
|
"#ArmoryFilter_Tools", // ARMFILT_TOOLS,
|
||
|
"#ArmoryFilter_AllClass", // ARMFILT_CLASS_ALL,
|
||
|
"#ArmoryFilter_Scout", // ARMFILT_CLASS_SCOUT,
|
||
|
"#ArmoryFilter_Sniper", // ARMFILT_CLASS_SNIPER,
|
||
|
"#ArmoryFilter_Soldier", // ARMFILT_CLASS_SOLDIER,
|
||
|
"#ArmoryFilter_Demoman", // ARMFILT_CLASS_DEMOMAN,
|
||
|
"#ArmoryFilter_Medic", // ARMFILT_CLASS_MEDIC,
|
||
|
"#ArmoryFilter_Heavy", // ARMFILT_CLASS_HEAVY,
|
||
|
"#ArmoryFilter_Pyro", // ARMFILT_CLASS_PYRO,
|
||
|
"#ArmoryFilter_Spy", // ARMFILT_CLASS_SPY,
|
||
|
"#ArmoryFilter_Engineer", // ARMFILT_CLASS_ENGINEER,
|
||
|
"#ArmoryFilter_Donationitems", // ARMFILT_DONATIONITEMS,
|
||
|
|
||
|
"", // ARMFILT_NUM_IN_DROPDOWN
|
||
|
"Not Used", // ARMFILT_CUSTOM
|
||
|
};
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CArmoryPanel::CArmoryPanel(Panel *parent, const char *panelName) : vgui::EditablePanel( parent, panelName )
|
||
|
{
|
||
|
m_pSelectedItemModelPanel = new CItemModelPanel( this, "SelectedItemModelPanel" );
|
||
|
m_pSelectedItemImageModelPanel = new CItemModelPanel( this, "SelectedItemImageModelPanel" );
|
||
|
m_pThumbnailModelPanelKVs = NULL;
|
||
|
m_bReapplyItemKVs = false;
|
||
|
m_CurrentFilter = ARMFILT_ALL_ITEMS;
|
||
|
m_OldFilter = ARMFILT_ALL_ITEMS;
|
||
|
m_iFilterPage = 0;
|
||
|
m_pNextPageButton = NULL;
|
||
|
m_pPrevPageButton = NULL;
|
||
|
m_pViewSetButton = NULL;
|
||
|
m_pStoreButton = NULL;
|
||
|
m_bAllowGotoStore = false;
|
||
|
|
||
|
m_pDataPanel = new vgui::EditablePanel( this, "DataPanel" );
|
||
|
m_pDataTextRichText = NULL;
|
||
|
|
||
|
m_pMouseOverItemPanel = new CItemModelPanel( this, "mouseoveritempanel" );
|
||
|
m_pMouseOverTooltip = new CItemModelPanelToolTip( this );
|
||
|
m_pMouseOverTooltip->SetupPanels( this, m_pMouseOverItemPanel );
|
||
|
m_pMouseOverTooltip->SetPositioningStrategy( IPTTP_BOTTOM_SIDE );
|
||
|
|
||
|
m_pFilterComboBox = new vgui::ComboBox( this, "FilterComboBox", ARMFILT_NUM_IN_DROPDOWN, false );
|
||
|
m_pFilterComboBox->AddActionSignalTarget( this );
|
||
|
|
||
|
REGISTER_COLOR_AS_OVERRIDABLE( m_colThumbnailBG, "thumbnail_bgcolor" );
|
||
|
REGISTER_COLOR_AS_OVERRIDABLE( m_colThumbnailBGMouseover, "thumbnail_bgcolor_mouseover" );
|
||
|
REGISTER_COLOR_AS_OVERRIDABLE( m_colThumbnailBGSelected, "thumbnail_bgcolor_selected" );
|
||
|
|
||
|
m_bEventLogging = false;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CArmoryPanel::~CArmoryPanel()
|
||
|
{
|
||
|
if ( m_pThumbnailModelPanelKVs )
|
||
|
{
|
||
|
m_pThumbnailModelPanelKVs->deleteThis();
|
||
|
m_pThumbnailModelPanelKVs = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||
|
{
|
||
|
BaseClass::ApplySchemeSettings( pScheme );
|
||
|
|
||
|
LoadControlSettings( "Resource/UI/CharInfoArmorySubPanel.res" );
|
||
|
|
||
|
m_bReapplyItemKVs = true;
|
||
|
m_pMouseOverItemPanel->SetBorder( pScheme->GetBorder("LoadoutItemPopupBorder") );
|
||
|
|
||
|
m_pDataTextRichText = dynamic_cast<CEconItemDetailsRichText*>( m_pDataPanel->FindChildByName( "Data_TextRichText" ) );
|
||
|
m_pNextPageButton = dynamic_cast<CExButton*>( FindChildByName("NextPageButton") );
|
||
|
m_pPrevPageButton = dynamic_cast<CExButton*>( FindChildByName("PrevPageButton") );
|
||
|
m_pViewSetButton = dynamic_cast<CExButton*>( FindChildByName("ViewSetButton") );
|
||
|
m_pStoreButton = dynamic_cast<CExButton*>( FindChildByName("StoreButton") );
|
||
|
|
||
|
m_pDataTextRichText->SetURLClickedHandler( this );
|
||
|
|
||
|
m_colSetName = GetSchemeColor( "ItemSetName", Color(255, 255, 255, 255), pScheme );
|
||
|
|
||
|
SetupComboBox( NULL );
|
||
|
UpdateSelectedItem();
|
||
|
m_pFilterComboBox->SetBorder( NULL );
|
||
|
|
||
|
m_pMouseOverItemPanel->SetVisible( false );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::SetupComboBox( const char *pszCustomAddition )
|
||
|
{
|
||
|
m_pFilterComboBox->RemoveAll();
|
||
|
|
||
|
vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
|
||
|
vgui::HFont hFont = pScheme->GetFont( "HudFontSmallestBold", true );
|
||
|
m_pFilterComboBox->SetFont( hFont );
|
||
|
|
||
|
KeyValues *pKeyValues = new KeyValues( "data" );
|
||
|
for ( int i = 0; i < ARMFILT_NUM_IN_DROPDOWN; i++ )
|
||
|
{
|
||
|
pKeyValues->SetInt( "setfilter", i );
|
||
|
m_pFilterComboBox->AddItem( g_szArmoryFilterStrings[i], pKeyValues );
|
||
|
}
|
||
|
|
||
|
if ( pszCustomAddition )
|
||
|
{
|
||
|
pKeyValues->SetInt( "setfilter", ARMFILT_CUSTOM );
|
||
|
m_pFilterComboBox->AddItem( g_pVGuiLocalize->Find( pszCustomAddition ), pKeyValues );
|
||
|
|
||
|
// Start with the custom filter selected
|
||
|
m_pFilterComboBox->SetNumberOfEditLines( ARMFILT_NUM_IN_DROPDOWN + 1 );
|
||
|
m_pFilterComboBox->ActivateItemByRow( ARMFILT_NUM_IN_DROPDOWN );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pFilterComboBox->SetNumberOfEditLines( ARMFILT_NUM_IN_DROPDOWN );
|
||
|
m_pFilterComboBox->ActivateItemByRow( 0 );
|
||
|
}
|
||
|
|
||
|
pKeyValues->deleteThis();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::ApplySettings( KeyValues *inResourceData )
|
||
|
{
|
||
|
BaseClass::ApplySettings( inResourceData );
|
||
|
|
||
|
KeyValues *pItemKV = inResourceData->FindKey( "thumbnail_modelpanels_kv" );
|
||
|
if ( pItemKV )
|
||
|
{
|
||
|
if ( m_pThumbnailModelPanelKVs )
|
||
|
{
|
||
|
m_pThumbnailModelPanelKVs->deleteThis();
|
||
|
}
|
||
|
m_pThumbnailModelPanelKVs = new KeyValues("thumbnail_modelpanels_kv");
|
||
|
pItemKV->CopySubkeys( m_pThumbnailModelPanelKVs );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// C_CTF_GameStats.Event_Item( IE_ARMORY_EXITED );
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::OnShowPanel( void )
|
||
|
{
|
||
|
InvalidateLayout( true, true );
|
||
|
|
||
|
m_pMouseOverItemPanel->SetVisible( false );
|
||
|
|
||
|
UpdateSelectedItem();
|
||
|
|
||
|
// If this is the first time we've opened the armory, start the armory explanations
|
||
|
if ( !tf_explanations_charinfo_armory_panel.GetBool() && ShouldShowExplanations() )
|
||
|
{
|
||
|
m_flStartExplanationsAt = engine->Time() + 0.5;
|
||
|
}
|
||
|
|
||
|
SetVisible( true );
|
||
|
|
||
|
if ( !m_bEventLogging )
|
||
|
{
|
||
|
C_CTF_GameStats.Event_Catalog( IE_ARMORY_ENTERED );
|
||
|
m_bEventLogging = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Select the given item and jump to the appropriate page
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::JumpToItem( int iItemDef, armory_filters_t nFilter )
|
||
|
{
|
||
|
// Setup filter and select iItemDef
|
||
|
SetFilterTo( iItemDef, nFilter );
|
||
|
|
||
|
// If we have an item def, find out what page it's on and move to it
|
||
|
if ( iItemDef > 0 )
|
||
|
{
|
||
|
const CEconItemDefinition *pDef = ItemSystem()->GetStaticDataForItemByDefIndex( iItemDef );
|
||
|
if ( pDef )
|
||
|
{
|
||
|
// Attempt to get item def from armory remap parameter
|
||
|
int iArmoryRemap = pDef->GetArmoryRemap();
|
||
|
if ( iArmoryRemap > 0 )
|
||
|
{
|
||
|
iItemDef = iArmoryRemap;
|
||
|
|
||
|
SetSelectedItem( iItemDef );
|
||
|
}
|
||
|
|
||
|
// If the item specified is a stock item, find the upgradeable version of it instead
|
||
|
else if ( pDef->GetQuality() == AE_NORMAL )
|
||
|
{
|
||
|
// Prepend the upgradeable string
|
||
|
char szTmpName[256];
|
||
|
Q_snprintf( szTmpName, sizeof(szTmpName), "Upgradeable %s", pDef->GetDefinitionName() );
|
||
|
|
||
|
pDef = ItemSystem()->GetStaticDataForItemByName( szTmpName );
|
||
|
if ( pDef )
|
||
|
{
|
||
|
iItemDef = pDef->GetDefinitionIndex();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Find and select the page iItemDef is on
|
||
|
FOR_EACH_VEC( m_FilteredItemList, i )
|
||
|
{
|
||
|
if ( m_FilteredItemList[i] == (item_definition_index_t)iItemDef )
|
||
|
{
|
||
|
int iThumbnailsPerPage = (m_iThumbnailRows * m_iThumbnailColumns);
|
||
|
m_iFilterPage = floor( (float)i / (float)iThumbnailsPerPage );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Default behavior - select first item on first page
|
||
|
m_iFilterPage = 0;
|
||
|
SetSelectedItem( m_FilteredItemList[0] );
|
||
|
}
|
||
|
|
||
|
UpdateItemList();
|
||
|
UpdateSelectedItem();
|
||
|
|
||
|
m_pMouseOverItemPanel->SetVisible( false );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Show the armory with one of the default filters set
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::ShowPanel( int iItemDef, armory_filters_t nFilter )
|
||
|
{
|
||
|
JumpToItem( iItemDef, nFilter );
|
||
|
OnShowPanel();
|
||
|
m_pFilterComboBox->ActivateItemByRow( 0 );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Show the armory with a custom list of item definitions, and a custom filter string
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::ShowPanel( const char *pszFilterString, CUtlVector<item_definition_index_t> *vecItems )
|
||
|
{
|
||
|
m_CustomFilteredList = *vecItems;
|
||
|
SetupComboBox( pszFilterString );
|
||
|
ShowPanel( 0, ARMFILT_CUSTOM );
|
||
|
|
||
|
// Move to the custom entry
|
||
|
m_pFilterComboBox->ActivateItemByRow( ARMFILT_NUM_IN_DROPDOWN );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::OnClosing()
|
||
|
{
|
||
|
if ( m_bEventLogging )
|
||
|
{
|
||
|
C_CTF_GameStats.Event_Catalog( IE_ARMORY_EXITED );
|
||
|
m_bEventLogging = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::OnCommand( const char *command )
|
||
|
{
|
||
|
if ( !Q_strnicmp( command, "prevpage", 8 ) )
|
||
|
{
|
||
|
if ( m_iFilterPage > 0 )
|
||
|
{
|
||
|
m_iFilterPage--;
|
||
|
UpdateItemList();
|
||
|
UpdateSelectedItem();
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
else if ( !Q_strnicmp( command, "nextpage", 8 ) )
|
||
|
{
|
||
|
int nMaxPages = MAX( 1, ceil(m_FilteredItemList.Count() / (float)(m_iThumbnailRows * m_iThumbnailColumns)) );
|
||
|
if ( m_iFilterPage < (nMaxPages-1) )
|
||
|
{
|
||
|
m_iFilterPage++;
|
||
|
UpdateItemList();
|
||
|
UpdateSelectedItem();
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
else if ( !Q_strnicmp( command, "back", 4 ) )
|
||
|
{
|
||
|
PostMessage( GetParent(), new KeyValues("ArmoryClosed") );
|
||
|
return;
|
||
|
}
|
||
|
else if ( !Q_stricmp( command, "reloadscheme" ) )
|
||
|
{
|
||
|
InvalidateLayout( false, true );
|
||
|
SetTall( YRES(400) );
|
||
|
SetVisible( true );
|
||
|
}
|
||
|
else if ( !Q_stricmp( command, "openstore" ) )
|
||
|
{
|
||
|
// Only available in the loadout->catalog path. So we close down the character info, and move to the store.
|
||
|
// Bit of a hack.
|
||
|
EconUI()->CloseEconUI();
|
||
|
|
||
|
int iItemDef = m_SelectedItem.IsValid() ? m_SelectedItem.GetItemDefIndex() : 0;
|
||
|
EconUI()->OpenStorePanel( iItemDef, false );
|
||
|
return;
|
||
|
}
|
||
|
else if ( !Q_stricmp( command, "wiki" ) )
|
||
|
{
|
||
|
if ( steamapicontext && steamapicontext->SteamFriends() )
|
||
|
{
|
||
|
if ( IsVisible() && m_SelectedItem.IsValid() )
|
||
|
{
|
||
|
// Determine which language we should use
|
||
|
char uilanguage[ 64 ];
|
||
|
uilanguage[0] = 0;
|
||
|
engine->GetUILanguage( uilanguage, sizeof( uilanguage ) );
|
||
|
ELanguage iLang = PchLanguageToELanguage( uilanguage );
|
||
|
|
||
|
char szURL[512];
|
||
|
Q_snprintf( szURL, sizeof(szURL), "http://wiki.teamfortress.com/scripts/itemredirect.php?id=%d&lang=%s", m_SelectedItem.GetItemDefIndex(), GetLanguageICUName( iLang ) );
|
||
|
steamapicontext->SteamFriends()->ActivateGameOverlayToWebPage( szURL );
|
||
|
|
||
|
C_CTF_GameStats.Event_Catalog( IE_ARMORY_BROWSE_WIKI, NULL, &m_SelectedItem );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if ( !Q_stricmp( command, "viewset" ) )
|
||
|
{
|
||
|
if ( m_SelectedItem.IsValid() )
|
||
|
{
|
||
|
const CEconItemSetDefinition *pItemSet = m_SelectedItem.GetStaticData()->GetItemSetDefinition();
|
||
|
if ( pItemSet )
|
||
|
{
|
||
|
m_CustomFilteredList.Purge();
|
||
|
FOR_EACH_VEC( pItemSet->m_iItemDefs, i )
|
||
|
{
|
||
|
m_CustomFilteredList.AddToTail( pItemSet->m_iItemDefs[i] );
|
||
|
}
|
||
|
|
||
|
SetupComboBox( pItemSet->m_pszLocalizedName );
|
||
|
SetFilterTo( m_SelectedItem.GetItemDefIndex(), ARMFILT_CUSTOM );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BaseClass::OnCommand( command );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::MoveItem( int iDelta )
|
||
|
{
|
||
|
int iIdx = m_FilteredItemList.Find( m_SelectedItem.GetItemDefIndex() );
|
||
|
m_SelectedItem.Invalidate();
|
||
|
|
||
|
if ( iIdx != m_FilteredItemList.InvalidIndex() )
|
||
|
{
|
||
|
iIdx += iDelta;
|
||
|
if ( iIdx >= m_FilteredItemList.Count() )
|
||
|
{
|
||
|
iIdx = 0;
|
||
|
}
|
||
|
else if ( iIdx < 0 )
|
||
|
{
|
||
|
iIdx = m_FilteredItemList.Count() - 1;
|
||
|
}
|
||
|
|
||
|
if ( iIdx < m_FilteredItemList.Count() )
|
||
|
{
|
||
|
const CEconItemDefinition *pDef = ItemSystem()->GetStaticDataForItemByDefIndex( m_FilteredItemList[iIdx] );
|
||
|
if ( pDef )
|
||
|
{
|
||
|
SetSelectedItem( pDef->GetDefinitionIndex() );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
UpdateSelectedItem();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::PerformLayout( void )
|
||
|
{
|
||
|
if ( m_bReapplyItemKVs )
|
||
|
{
|
||
|
m_bReapplyItemKVs = false;
|
||
|
|
||
|
if ( m_pThumbnailModelPanelKVs )
|
||
|
{
|
||
|
FOR_EACH_VEC( m_pThumbnailModelPanels, i )
|
||
|
{
|
||
|
m_pThumbnailModelPanels[i]->ApplySettings( m_pThumbnailModelPanelKVs );
|
||
|
SetBorderForItem( m_pThumbnailModelPanels[i], false );
|
||
|
m_pThumbnailModelPanels[i]->InvalidateLayout();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BaseClass::PerformLayout();
|
||
|
|
||
|
if ( m_pThumbnailModelPanels.Count() > 0 && m_iThumbnailColumns )
|
||
|
{
|
||
|
int iThumbnailModelWide = m_pThumbnailModelPanels[0]->GetWide();
|
||
|
int iThumbnailModelTall = m_pThumbnailModelPanels[0]->GetTall();
|
||
|
FOR_EACH_VEC( m_pThumbnailModelPanels, i )
|
||
|
{
|
||
|
if ( m_pThumbnailModelPanels[i]->HasItem() )
|
||
|
{
|
||
|
m_pThumbnailModelPanels[i]->SetVisible( true );
|
||
|
}
|
||
|
|
||
|
int iXPos = ( i % m_iThumbnailColumns );
|
||
|
int iYPos = ( i / m_iThumbnailColumns );
|
||
|
|
||
|
int iX = m_iThumbnailX + (m_iThumbnailDeltaX * iXPos) + (iThumbnailModelWide * iXPos);
|
||
|
int iY = m_iThumbnailY + (m_iThumbnailDeltaY * iYPos) + (iThumbnailModelTall * iYPos);
|
||
|
m_pThumbnailModelPanels[i]->SetPos( iX, iY );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::SetFilterTo( int iItemDef, armory_filters_t nFilter )
|
||
|
{
|
||
|
m_FilteredItemList.Purge();
|
||
|
m_OldFilter = m_CurrentFilter;
|
||
|
m_CurrentFilter = nFilter;
|
||
|
m_iFilterPage = 0;
|
||
|
|
||
|
if ( nFilter == ARMFILT_CUSTOM )
|
||
|
{
|
||
|
m_FilteredItemList = m_CustomFilteredList;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// First, build a list of all the items that match the filter
|
||
|
const CEconItemSchema::SortedItemDefinitionMap_t& mapItemDefs = ItemSystem()->GetItemSchema()->GetSortedItemDefinitionMap();
|
||
|
FOR_EACH_MAP( mapItemDefs, i )
|
||
|
{
|
||
|
const CTFItemDefinition *pDef = dynamic_cast<const CTFItemDefinition *>( mapItemDefs[i] );
|
||
|
|
||
|
// Never show:
|
||
|
// - Hidden items
|
||
|
// - Items that don't have fixed qualities
|
||
|
// - Normal quality items
|
||
|
// - Items that haven't asked to be shown
|
||
|
if ( pDef->IsHidden() || pDef->GetQuality() == k_unItemQuality_Any || pDef->GetQuality() == AE_NORMAL || !pDef->ShouldShowInArmory() )
|
||
|
continue;
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
// In Debug, make sure that every item shows up in a filter other than the All Items list
|
||
|
bool bFoundMatchingFilter = false;
|
||
|
for ( int iFilter = ARMFILT_WEAPONS; iFilter < ARMFILT_NUM_IN_DROPDOWN; iFilter++ )
|
||
|
{
|
||
|
if ( DefPassesFilter(pDef,(armory_filters_t)iFilter) )
|
||
|
{
|
||
|
bFoundMatchingFilter = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
Assert( bFoundMatchingFilter );
|
||
|
#endif
|
||
|
|
||
|
if ( DefPassesFilter( pDef, m_CurrentFilter ) )
|
||
|
{
|
||
|
m_FilteredItemList.AddToTail( pDef->GetDefinitionIndex() );
|
||
|
|
||
|
if ( iItemDef == pDef->GetDefinitionIndex() )
|
||
|
{
|
||
|
SetSelectedItem( pDef->GetDefinitionIndex() );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Make sure our current item is in the list
|
||
|
if ( m_SelectedItem.IsValid() )
|
||
|
{
|
||
|
if ( m_FilteredItemList.Find( m_SelectedItem.GetItemDefIndex() ) == m_FilteredItemList.InvalidIndex() )
|
||
|
{
|
||
|
m_SelectedItem.Invalidate();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
UpdateItemList();
|
||
|
|
||
|
if ( m_CurrentFilter != m_OldFilter )
|
||
|
{
|
||
|
C_CTF_GameStats.Event_Catalog( IE_ARMORY_CHANGE_FILTER, g_szArmoryFilterStrings[m_CurrentFilter] );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CArmoryPanel::DefPassesFilter( const CTFItemDefinition *pDef, armory_filters_t iFilter )
|
||
|
{
|
||
|
bool bInList = false;
|
||
|
|
||
|
switch (iFilter)
|
||
|
{
|
||
|
case ARMFILT_ALL_ITEMS:
|
||
|
{
|
||
|
bInList = true;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case ARMFILT_WEAPONS:
|
||
|
{
|
||
|
int iSlot = pDef->GetDefaultLoadoutSlot();
|
||
|
bInList = ( iSlot == LOADOUT_POSITION_PRIMARY || iSlot == LOADOUT_POSITION_SECONDARY || iSlot == LOADOUT_POSITION_MELEE );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case ARMFILT_HEADGEAR:
|
||
|
{
|
||
|
bInList = (pDef->GetDefaultLoadoutSlot() == LOADOUT_POSITION_HEAD);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case ARMFILT_MISCITEMS:
|
||
|
{
|
||
|
bInList = (pDef->GetDefaultLoadoutSlot() == LOADOUT_POSITION_MISC);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case ARMFILT_ACTIONITEMS:
|
||
|
{
|
||
|
bInList = (pDef->GetDefaultLoadoutSlot() == LOADOUT_POSITION_ACTION);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case ARMFILT_CRAFTITEMS:
|
||
|
{
|
||
|
bInList = pDef->GetItemClass() && ( !V_strcmp( pDef->GetItemClass(), "craft_item" ) || !V_strcmp( pDef->GetItemClass(), "class_token" ) || !V_strcmp( pDef->GetItemClass(), "slot_token" ) );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case ARMFILT_TOOLS:
|
||
|
{
|
||
|
// For now, put the supply crates into the tool list, since it's the only item that shows up in no other lists
|
||
|
bInList = pDef->GetItemClass() && ( !V_strcmp( pDef->GetItemClass(), "tool" ) || !V_strcmp( pDef->GetItemClass(), "supply_crate" ) );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case ARMFILT_CLASS_ALL:
|
||
|
{
|
||
|
bInList = pDef->CanBeUsedByAllClasses();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case ARMFILT_CLASS_SCOUT:
|
||
|
case ARMFILT_CLASS_SNIPER:
|
||
|
case ARMFILT_CLASS_SOLDIER:
|
||
|
case ARMFILT_CLASS_DEMOMAN:
|
||
|
case ARMFILT_CLASS_MEDIC:
|
||
|
case ARMFILT_CLASS_HEAVY:
|
||
|
case ARMFILT_CLASS_PYRO:
|
||
|
case ARMFILT_CLASS_SPY:
|
||
|
case ARMFILT_CLASS_ENGINEER:
|
||
|
{
|
||
|
// Don't show class/slot usage for class/slot tokens
|
||
|
if ( pDef->GetItemClass() && !V_strcmp( pDef->GetItemClass(), "class_token" ) )
|
||
|
break;
|
||
|
|
||
|
bInList = ( !pDef->CanBeUsedByAllClasses() && pDef->CanBeUsedByClass( iFilter - ARMFILT_CLASS_SCOUT + 1 ) );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case ARMFILT_DONATIONITEMS:
|
||
|
{
|
||
|
// Don't show class/slot usage for class/slot tokens
|
||
|
bInList = pDef->GetItemClass() && !V_strcmp( pDef->GetItemClass(), "map_token" );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bInList;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::UpdateItemList( void )
|
||
|
{
|
||
|
int iMaxThumbnails = (m_iThumbnailRows * m_iThumbnailColumns);
|
||
|
int iNumThumbnails = MIN( m_FilteredItemList.Count(), iMaxThumbnails );
|
||
|
|
||
|
if ( m_pThumbnailModelPanels.Count() < iNumThumbnails )
|
||
|
{
|
||
|
for ( int i = m_pThumbnailModelPanels.Count(); i < iNumThumbnails; i++ )
|
||
|
{
|
||
|
CItemModelPanel *pPanel = vgui::SETUP_PANEL( new CItemModelPanel( this, VarArgs("thumbnailmodelpanel%d", i) ) );
|
||
|
pPanel->SetActAsButton( true, true );
|
||
|
pPanel->ApplySettings( m_pThumbnailModelPanelKVs );
|
||
|
SetBorderForItem( pPanel, false );
|
||
|
m_pThumbnailModelPanels.AddToTail( pPanel );
|
||
|
|
||
|
pPanel->SetTooltip( m_pMouseOverTooltip, "" );
|
||
|
}
|
||
|
}
|
||
|
else if ( m_pThumbnailModelPanels.Count() > iMaxThumbnails )
|
||
|
{
|
||
|
FOR_EACH_VEC_BACK( m_pThumbnailModelPanels, i )
|
||
|
{
|
||
|
if ( i < iMaxThumbnails )
|
||
|
break;
|
||
|
|
||
|
m_pThumbnailModelPanels[i]->MarkForDeletion();
|
||
|
m_pThumbnailModelPanels.Remove( i );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int iStartPos = (m_iFilterPage * iMaxThumbnails);
|
||
|
|
||
|
CEconItemView *pItemData = new CEconItemView();
|
||
|
FOR_EACH_VEC( m_pThumbnailModelPanels, i )
|
||
|
{
|
||
|
int iItemPos = iStartPos + i;
|
||
|
if ( iItemPos >= m_FilteredItemList.Count() )
|
||
|
{
|
||
|
m_pThumbnailModelPanels[i]->SetItem( NULL );
|
||
|
m_pThumbnailModelPanels[i]->SetVisible( false );
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
pItemData->Init( m_FilteredItemList[iItemPos], AE_USE_SCRIPT_VALUE, AE_USE_SCRIPT_VALUE, true );
|
||
|
m_pThumbnailModelPanels[i]->SetItem( pItemData );
|
||
|
m_pThumbnailModelPanels[i]->SetVisible( true );
|
||
|
}
|
||
|
delete pItemData;
|
||
|
|
||
|
char szTmp[16];
|
||
|
int nMaxPages = MAX( 1, ceil(m_FilteredItemList.Count() / (float)(m_iThumbnailRows * m_iThumbnailColumns)) );
|
||
|
Q_snprintf(szTmp, 16, "%d/%d", m_iFilterPage+1, nMaxPages );
|
||
|
SetDialogVariable( "thumbnailpage", szTmp );
|
||
|
|
||
|
bool bNextEnabled = m_iFilterPage < (nMaxPages-1);
|
||
|
m_pNextPageButton->SetEnabled( bNextEnabled );
|
||
|
m_pPrevPageButton->SetEnabled( m_iFilterPage > 0 );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::UpdateSelectedItem( void )
|
||
|
{
|
||
|
if ( !m_SelectedItem.IsValid() )
|
||
|
{
|
||
|
if ( m_FilteredItemList.Count() )
|
||
|
{
|
||
|
const CEconItemDefinition *pDef = ItemSystem()->GetStaticDataForItemByDefIndex( m_FilteredItemList[0] );
|
||
|
if ( pDef )
|
||
|
{
|
||
|
SetSelectedItem( pDef->GetDefinitionIndex() );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( m_pSelectedItemModelPanel )
|
||
|
{
|
||
|
m_pSelectedItemModelPanel->SetItem( &m_SelectedItem );
|
||
|
m_pSelectedItemModelPanel->InvalidateLayout( true );
|
||
|
|
||
|
int iYDelta = YRES(10);
|
||
|
|
||
|
// Resize & position the atribute background image
|
||
|
int iItemX, iItemY, iItemW, iItemH;
|
||
|
m_pSelectedItemModelPanel->GetBounds( iItemX, iItemY, iItemW, iItemH );
|
||
|
|
||
|
// Never shrink the attribute background below a certain size
|
||
|
int iNewPaperH = MAX( iItemH + (iYDelta*2), YRES(100) );
|
||
|
int iNewPaperY = iItemY - iYDelta;
|
||
|
|
||
|
int iNewY = iNewPaperY + iNewPaperH;
|
||
|
|
||
|
// Reposition the data panel now that we know how big the item is
|
||
|
int iX,iY;
|
||
|
m_pDataTextRichText->GetPos( iX, iY );
|
||
|
int iDataPanelX, iDataPanelY;
|
||
|
m_pDataPanel->GetPos( iDataPanelX, iDataPanelY );
|
||
|
int iRichTextYPosInDataPanel = iNewY - iDataPanelY;
|
||
|
m_pDataTextRichText->SetBounds( iX, iRichTextYPosInDataPanel, m_pDataTextRichText->GetWide(), m_pDataPanel->GetTall() - iRichTextYPosInDataPanel );
|
||
|
}
|
||
|
if ( m_pSelectedItemImageModelPanel )
|
||
|
{
|
||
|
m_pSelectedItemImageModelPanel->SetItem( &m_SelectedItem );
|
||
|
}
|
||
|
|
||
|
FOR_EACH_VEC( m_pThumbnailModelPanels, i )
|
||
|
{
|
||
|
if ( !m_pThumbnailModelPanels[i]->IsVisible() || !m_pThumbnailModelPanels[i]->HasItem() )
|
||
|
continue;
|
||
|
|
||
|
bool bSelected = (m_SelectedItem.GetItemDefIndex() == m_pThumbnailModelPanels[i]->GetItem()->GetItemDefIndex() );
|
||
|
if ( bSelected != m_pThumbnailModelPanels[i]->IsSelected() )
|
||
|
{
|
||
|
m_pThumbnailModelPanels[i]->SetSelected( bSelected );
|
||
|
SetBorderForItem( m_pThumbnailModelPanels[i], false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
UpdateDataBlock();
|
||
|
|
||
|
if ( m_pViewSetButton )
|
||
|
{
|
||
|
m_pViewSetButton->SetVisible( false );
|
||
|
if ( m_SelectedItem.IsValid() )
|
||
|
{
|
||
|
if ( m_SelectedItem.GetStaticData()->GetItemSetDefinition() )
|
||
|
{
|
||
|
m_pViewSetButton->SetVisible( true );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( m_pStoreButton )
|
||
|
{
|
||
|
bool bShowStoreButton = m_bAllowGotoStore && EconUI()->GetStorePanel() && EconUI()->GetStorePanel()->GetPriceSheet() && EconUI()->GetStorePanel()->GetPriceSheet()->GetEntry( m_SelectedItem.GetItemDefIndex() );
|
||
|
m_pStoreButton->SetVisible( bShowStoreButton );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::UpdateDataBlock( void )
|
||
|
{
|
||
|
if ( !CalculateDataText() )
|
||
|
{
|
||
|
m_pDataPanel->SetVisible( false );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_pDataPanel->SetVisible( true );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CArmoryPanel::CalculateDataText( void )
|
||
|
{
|
||
|
if ( !m_SelectedItem.IsValid() )
|
||
|
return false;
|
||
|
CTFItemDefinition *pDef = ItemSystem()->GetStaticDataForItemByDefIndex( m_SelectedItem.GetItemDefIndex() );
|
||
|
if ( !pDef )
|
||
|
return false;
|
||
|
|
||
|
m_pDataTextRichText->UpdateDetailsForItem( pDef );
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::OnItemPanelEntered( vgui::Panel *panel )
|
||
|
{
|
||
|
CItemModelPanel *pItemPanel = dynamic_cast < CItemModelPanel * > ( panel );
|
||
|
|
||
|
if ( pItemPanel && IsVisible() )
|
||
|
{
|
||
|
CEconItemView *pItem = pItemPanel->GetItem();
|
||
|
SetBorderForItem( pItemPanel, pItem != NULL );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::OnItemPanelExited( vgui::Panel *panel )
|
||
|
{
|
||
|
CItemModelPanel *pItemPanel = dynamic_cast < CItemModelPanel * > ( panel );
|
||
|
|
||
|
if ( pItemPanel && IsVisible() )
|
||
|
{
|
||
|
SetBorderForItem( pItemPanel, false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::OnItemPanelMouseReleased( vgui::Panel *panel )
|
||
|
{
|
||
|
CItemModelPanel *pItemPanel = dynamic_cast < CItemModelPanel * > ( panel );
|
||
|
|
||
|
if ( pItemPanel && IsVisible() && pItemPanel->HasItem() && !pItemPanel->IsSelected() )
|
||
|
{
|
||
|
SetSelectedItem( pItemPanel->GetItem() );
|
||
|
|
||
|
// Hide the mouseover panel now, so it doesn't obscure the rich text info
|
||
|
m_pMouseOverItemPanel->SetVisible( false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::SetSelectedItem( CEconItemView* newItem )
|
||
|
{
|
||
|
m_PreviousItem = m_SelectedItem;
|
||
|
m_SelectedItem = *newItem;
|
||
|
m_SelectedItem.SetClientItemFlags( kEconItemFlagClient_Preview );
|
||
|
UpdateSelectedItem();
|
||
|
|
||
|
if ( m_bEventLogging && m_SelectedItem.IsValid() && m_SelectedItem != m_PreviousItem )
|
||
|
{
|
||
|
C_CTF_GameStats.Event_Catalog( IE_ARMORY_SELECT_ITEM, g_szArmoryFilterStrings[m_CurrentFilter], &m_SelectedItem );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::SetSelectedItem( int newIndex )
|
||
|
{
|
||
|
m_PreviousItem = m_SelectedItem;
|
||
|
m_SelectedItem.Init( newIndex, AE_USE_SCRIPT_VALUE, AE_USE_SCRIPT_VALUE, true );
|
||
|
m_SelectedItem.SetClientItemFlags( kEconItemFlagClient_Preview );
|
||
|
|
||
|
if ( m_bEventLogging && m_SelectedItem.IsValid() && m_SelectedItem != m_PreviousItem )
|
||
|
{
|
||
|
C_CTF_GameStats.Event_Catalog( IE_ARMORY_SELECT_ITEM, g_szArmoryFilterStrings[m_CurrentFilter], &m_SelectedItem );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::SetBorderForItem( CItemModelPanel *pItemPanel, bool bMouseOver )
|
||
|
{
|
||
|
if ( !pItemPanel )
|
||
|
return;
|
||
|
|
||
|
// Store panels use backgrounds instead of borders
|
||
|
pItemPanel->SetBorder( NULL );
|
||
|
pItemPanel->SetPaintBackgroundEnabled( true );
|
||
|
|
||
|
if ( pItemPanel->IsSelected() )
|
||
|
{
|
||
|
pItemPanel->SetBgColor( m_colThumbnailBGSelected );
|
||
|
}
|
||
|
else if ( bMouseOver )
|
||
|
{
|
||
|
pItemPanel->SetBgColor( m_colThumbnailBGMouseover );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pItemPanel->SetBgColor( m_colThumbnailBG );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Called when text changes in combo box
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::OnTextChanged( KeyValues *data )
|
||
|
{
|
||
|
if ( !m_pFilterComboBox )
|
||
|
return;
|
||
|
|
||
|
Panel *pPanel = reinterpret_cast<vgui::Panel *>( data->GetPtr("panel") );
|
||
|
vgui::ComboBox *pComboBox = dynamic_cast<vgui::ComboBox *>( pPanel );
|
||
|
|
||
|
if ( pComboBox == m_pFilterComboBox )
|
||
|
{
|
||
|
// the class selection combo box changed, update class details
|
||
|
KeyValues *pUserData = m_pFilterComboBox->GetActiveItemUserData();
|
||
|
if ( !pUserData )
|
||
|
return;
|
||
|
|
||
|
armory_filters_t nFilter = (armory_filters_t)pUserData->GetInt( "setfilter", -1 );
|
||
|
if ( nFilter != armory_filters_t(-1) )
|
||
|
{
|
||
|
SetFilterTo( 0, nFilter );
|
||
|
UpdateSelectedItem();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CArmoryPanel::OnItemLinkClicked( KeyValues *pParams )
|
||
|
{
|
||
|
const char *pURL = pParams->GetString( "url" );
|
||
|
int iItemDef = atoi( pURL + 7 );
|
||
|
JumpToItem( iItemDef, ARMFILT_ALL_ITEMS );
|
||
|
m_pFilterComboBox->ActivateItemByRow( 0 );
|
||
|
}
|
||
|
|