diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf/vgui/charinfo_armory_subpanel.cpp | |
| download | archived-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.cpp | 945 |
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 ); +} + |