summaryrefslogtreecommitdiff
path: root/game/client/tf/vgui/charinfo_armory_subpanel.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf/vgui/charinfo_armory_subpanel.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/tf/vgui/charinfo_armory_subpanel.cpp')
-rw-r--r--game/client/tf/vgui/charinfo_armory_subpanel.cpp945
1 files changed, 945 insertions, 0 deletions
diff --git a/game/client/tf/vgui/charinfo_armory_subpanel.cpp b/game/client/tf/vgui/charinfo_armory_subpanel.cpp
new file mode 100644
index 0000000..ceab6f7
--- /dev/null
+++ b/game/client/tf/vgui/charinfo_armory_subpanel.cpp
@@ -0,0 +1,945 @@
+//========= 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 );
+}
+