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.
4273 lines
143 KiB
4273 lines
143 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
|
||
|
|
||
|
#include "cbase.h"
|
||
|
#include "backpack_panel.h"
|
||
|
#include "item_confirm_delete_dialog.h"
|
||
|
#include "vgui/ISurface.h"
|
||
|
#include "gamestringpool.h"
|
||
|
#include "iclientmode.h"
|
||
|
#include "econ_item_inventory.h"
|
||
|
#include "ienginevgui.h"
|
||
|
#include <vgui/ILocalize.h>
|
||
|
#include "vgui_controls/TextImage.h"
|
||
|
#include "vgui_controls/CheckButton.h"
|
||
|
#include "vgui_controls/ComboBox.h"
|
||
|
#include "vgui_controls/ScalableImagePanel.h"
|
||
|
#include "vgui/IInput.h"
|
||
|
#include "econ/tool_items/tool_items.h"
|
||
|
#include "econ_gcmessages.h"
|
||
|
#include "item_style_select_dialog.h"
|
||
|
#include "econ_item_system.h"
|
||
|
#include "econ_item_tools.h"
|
||
|
#include "econ_ui.h"
|
||
|
#include "gc_clientsystem.h"
|
||
|
#include "econ_store.h"
|
||
|
#include "rtime.h"
|
||
|
#include "econ_item_description.h"
|
||
|
#include "dynamic_recipe_subpanel.h"
|
||
|
#include "item_slot_panel.h"
|
||
|
#include "crate_detail_panels.h"
|
||
|
#include "tf_warinfopanel.h"
|
||
|
#include "character_info_panel.h"
|
||
|
#include "trading_start_dialog.h"
|
||
|
#include "vgui_controls/MenuItem.h"
|
||
|
#include "tf_duckleaderboard.h"
|
||
|
#include "tf_item_inventory.h"
|
||
|
#include "store/store_panel.h"
|
||
|
#include "strange_count_transfer_panel.h"
|
||
|
#include "collection_crafting_panel.h"
|
||
|
#include "halloween_offering_panel.h"
|
||
|
#include "store/v2/tf_store_preview_item2.h"
|
||
|
#include "item_ad_panel.h"
|
||
|
#include "client_community_market.h"
|
||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||
|
#include <tier0/memdbgon.h>
|
||
|
|
||
|
|
||
|
#ifdef STAGING_ONLY
|
||
|
extern ConVar tf_use_card_tooltips;
|
||
|
extern ConVar tf_weapon_force_allow_inspect;
|
||
|
#endif // STAGING_ONLY
|
||
|
|
||
|
ConVar tf_trade_up_use_count( "tf_trade_up_use_count", "3", FCVAR_ARCHIVE | FCVAR_HIDDEN );
|
||
|
|
||
|
|
||
|
void UseConsumableItem( CEconItemView *pItem, vgui::Panel* pParent );
|
||
|
|
||
|
const ItemSortTypeData_t g_BackpackSortTypes[] =
|
||
|
{
|
||
|
{ "#Backpack_SortBy_Header", kGCItemSort_NoSort },
|
||
|
{ "#Backpack_SortBy_Rarity", kGCItemSort_SortByRarity },
|
||
|
{ "#Backpack_SortBy_Type", kGCItemSort_SortByType },
|
||
|
{ "#Backpack_SortBy_Class", kTFGCItemSort_SortByClass },
|
||
|
{ "#Backpack_SortBy_Slot", kTFGCItemSort_SortBySlot },
|
||
|
{ "#Backpack_SortBy_Date", kGCItemSort_SortByDate },
|
||
|
};
|
||
|
|
||
|
// Array of borders for rarities. Three borders for each rarity: Base, Mouseover, and Selected
|
||
|
const char *g_szItemBorders[][5] =
|
||
|
{
|
||
|
{ "BackpackItemBorder", "BackpackItemMouseOverBorder", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder", "BackpackItemGreyedOutSelectedBorder" }, // AE_NORMAL = 0
|
||
|
{ "BackpackItemBorder_1", "BackpackItemMouseOverBorder_1", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_1", "BackpackItemGreyedOutSelectedBorder_1" }, // AE_RARITY1 = 1
|
||
|
{ "BackpackItemBorder_2", "BackpackItemMouseOverBorder_2", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_2", "BackpackItemGreyedOutSelectedBorder_2" }, // AE_RARITY2 = 2
|
||
|
{ "BackpackItemBorder_Vintage", "BackpackItemMouseOverBorder_Vintage", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_Vintage", "BackpackItemGreyedOutSelectedBorder_Vintage" }, // AE_VINTAGE = 3
|
||
|
{ "BackpackItemBorder_3", "BackpackItemMouseOverBorder_3", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_3", "BackpackItemGreyedOutSelectedBorder_3" }, // AE_RARITY3
|
||
|
{ "BackpackItemBorder_4", "BackpackItemMouseOverBorder_4", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_4", "BackpackItemGreyedOutSelectedBorder_4" }, // AE_RARITY4
|
||
|
{ "BackpackItemBorder_Unique", "BackpackItemMouseOverBorder_Unique", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_Unique", "BackpackItemGreyedOutSelectedBorder_Unique" }, // AE_UNIQUE
|
||
|
{ "BackpackItemBorder_Community", "BackpackItemMouseOverBorder_Community", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_Community", "BackpackItemGreyedOutSelectedBorder_Community" }, // AE_COMMUNITY
|
||
|
{ "BackpackItemBorder_Developer", "BackpackItemMouseOverBorder_Developer", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_Developer", "BackpackItemGreyedOutSelectedBorder_Developer" }, // AE_DEVELOPER
|
||
|
{ "BackpackItemBorder_SelfMade", "BackpackItemMouseOverBorder_SelfMade", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_SelfMade", "BackpackItemGreyedOutSelectedBorder_SelfMade" }, // AE_SELFMADE
|
||
|
{ "BackpackItemBorder_Customized", "BackpackItemMouseOverBorder_Customized", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_Customized", "BackpackItemGreyedOutSelectedBorder_Customized" }, // AE_CUSTOMIZED
|
||
|
{ "BackpackItemBorder_Strange", "BackpackItemMouseOverBorder_Strange", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_Strange", "BackpackItemGreyedOutSelectedBorder_Strange" }, // AE_STRANGE
|
||
|
{ "BackpackItemBorder_Completed", "BackpackItemMouseOverBorder_Completed", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_Completed", "BackpackItemGreyedOutSelectedBorder_Completed" }, // AE_COMPLETED
|
||
|
{ "BackpackItemBorder_Haunted", "BackpackItemMouseOverBorder_Haunted", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_Haunted", "BackpackItemGreyedOutSelectedBorder_Haunted" }, // AE_HAUNTED
|
||
|
{ "BackpackItemBorder_Collectors", "BackpackItemMouseOverBorder_Collectors", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_Collectors", "BackpackItemGreyedOutSelectedBorder_Collectors" }, // AE_COLLECTORS
|
||
|
|
||
|
{ "BackpackItemBorder_PaintkitWeapon", "BackpackItemMouseOverBorder_PaintkitWeapon", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_PaintkitWeapon", "BackpackItemGreyedOutSelectedBorder_PaintkitWeapon" }, // AE_Paintkit
|
||
|
{ "BackpackItemBorder_RarityDefault", "BackpackItemMouseOverBorder_RarityDefault", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_RarityDefault", "BackpackItemGreyedOutSelectedBorder_RarityDefault" }, // AE_RARITY_DEFAULT,
|
||
|
{ "BackpackItemBorder_RarityCommon", "BackpackItemMouseOverBorder_RarityCommon", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_RarityCommon", "BackpackItemGreyedOutSelectedBorder_RarityCommon" }, // AE_RARITY_COMMON,
|
||
|
{ "BackpackItemBorder_RarityUncommon", "BackpackItemMouseOverBorder_RarityUncommon", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_RarityUncommon", "BackpackItemGreyedOutSelectedBorder_RarityUncommon" }, // AE_RARITY_UNCOMMON,
|
||
|
{ "BackpackItemBorder_RarityRare", "BackpackItemMouseOverBorder_RarityRare", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_RarityRare", "BackpackItemGreyedOutSelectedBorder_RarityRare" }, // AE_RARITY_RARE,
|
||
|
{ "BackpackItemBorder_RarityMythical", "BackpackItemMouseOverBorder_RarityMythical", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_RarityMythical", "BackpackItemGreyedOutSelectedBorder_RarityMythical" }, // AE_RARITY_MYTHICAL,
|
||
|
{ "BackpackItemBorder_RarityLegendary", "BackpackItemMouseOverBorder_RarityLegendary", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_RarityLegendary", "BackpackItemGreyedOutSelectedBorder_RarityLegendary" }, // AE_RARITY_LEGENDARY,
|
||
|
{ "BackpackItemBorder_RarityAncient", "BackpackItemMouseOverBorder_RarityAncient", "BackpackItemSelectedBorder", "BackpackItemGreyedOutBorder_RarityAncient", "BackpackItemGreyedOutSelectedBorder_RarityAncient" }, // AE_RARITY_ANCIENT,
|
||
|
};
|
||
|
|
||
|
COMPILE_TIME_ASSERT( ARRAYSIZE(g_szItemBorders) == AE_MAX_TYPES );
|
||
|
|
||
|
enum { kNoUserData = -1 };
|
||
|
|
||
|
static bool HasPaint ( const CEconItemView *pEconItemView, const char *, int )
|
||
|
{
|
||
|
static CSchemaAttributeDefHandle pAttrDef_PaintRGB( "set item tint RGB" );
|
||
|
static CSchemaAttributeDefHandle pAttrDef_PaintRGB2( "set item tint RGB 2" );
|
||
|
|
||
|
return pEconItemView->FindAttribute( pAttrDef_PaintRGB )
|
||
|
|| pEconItemView->FindAttribute( pAttrDef_PaintRGB2 );
|
||
|
}
|
||
|
|
||
|
static bool HasCustomAttribute ( const CEconItemView *pEconItemView, const char *szAttrName, int )
|
||
|
{
|
||
|
const CEconItemAttributeDefinition *pAttrDef = GetItemSchema()->GetAttributeDefinitionByName( szAttrName );
|
||
|
|
||
|
return pAttrDef
|
||
|
? pEconItemView->FindAttribute( pAttrDef )
|
||
|
: NULL;
|
||
|
}
|
||
|
|
||
|
static bool HasCustomUserAttribute ( const CEconItemView *pEconItemView, const char *, int iUserData )
|
||
|
{
|
||
|
Assert( iUserData != kNoUserData );
|
||
|
|
||
|
CCountUserGeneratedAttributeIterator countIterator;
|
||
|
pEconItemView->IterateAttributes( &countIterator );
|
||
|
|
||
|
return countIterator.GetCount() > iUserData;
|
||
|
}
|
||
|
|
||
|
static bool HasRemovableCustomName ( const CEconItemView *pEconItemView, const char *, int )
|
||
|
{
|
||
|
if ( !pEconItemView->GetItemDefinition() )
|
||
|
return false;
|
||
|
|
||
|
if ( pEconItemView->GetQuality() == AE_UNIQUE && pEconItemView->GetItemDefinition()->GetArmoryDescString() && !V_stricmp( pEconItemView->GetItemDefinition()->GetArmoryDescString(), "stockitem" ) )
|
||
|
return false;
|
||
|
|
||
|
return pEconItemView->GetSOCData() && pEconItemView->GetSOCData()->GetCustomName();
|
||
|
}
|
||
|
|
||
|
static bool HasRemovableCustomDesc ( const CEconItemView *pEconItemView, const char *, int )
|
||
|
{
|
||
|
if ( !pEconItemView->GetItemDefinition() )
|
||
|
return false;
|
||
|
|
||
|
if ( pEconItemView->GetQuality() == AE_UNIQUE && pEconItemView->GetItemDefinition()->GetArmoryDescString() && !V_stricmp( pEconItemView->GetItemDefinition()->GetArmoryDescString(), "stockitem" ) )
|
||
|
return false;
|
||
|
|
||
|
return pEconItemView->GetSOCData() && pEconItemView->GetSOCData()->GetCustomDesc();
|
||
|
}
|
||
|
|
||
|
enum EItemCustomizationRemoveType
|
||
|
{
|
||
|
kCustomizationRemove_Paint,
|
||
|
kCustomizationRemove_Name,
|
||
|
kCustomizationRemove_Desc,
|
||
|
kCustomizationRemove_CustomTexture,
|
||
|
kCustomizationRemove_MakersMark,
|
||
|
kCustomizationRemove_UniqueCraftIndex,
|
||
|
kCustomizationRemove_StrangePart,
|
||
|
kCustomizationRemove_StrangeScores,
|
||
|
kCustomizationRemove_UpgradeCard,
|
||
|
kCustomizationRemove_KillStreak,
|
||
|
kCustomizationRemove_GiftedBy,
|
||
|
kCustomizationRemove_Festivizer,
|
||
|
};
|
||
|
|
||
|
typedef bool (* HasRefurbishablePropertyFunc_t)( const CEconItemView *pEconItemView, const char *pArg, int iUserData );
|
||
|
|
||
|
void GetCustomDialogToken_PaintName( const CEconItemView *pEconItemView, int iUserData, CUtlConstWideString& out_String )
|
||
|
{
|
||
|
extern const CEconItemDefinition *GetPaintItemDefinitionForPaintedItem( const IEconItemInterface *pEconItem );
|
||
|
|
||
|
Assert( iUserData == kNoUserData );
|
||
|
|
||
|
const CEconItemDefinition *pPaintItemDef = GetPaintItemDefinitionForPaintedItem( pEconItemView );
|
||
|
if ( !pPaintItemDef )
|
||
|
{
|
||
|
out_String = L"";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
out_String = GLocalizationProvider()->Find( pPaintItemDef->GetItemBaseName() );
|
||
|
}
|
||
|
|
||
|
void GetCustomDialogToken_StrangePartName( const CEconItemView *pEconItemView, int iUserData, CUtlConstWideString& out_String )
|
||
|
{
|
||
|
extern uint32 GetScoreTypeForKillEaterAttr( const IEconItemInterface *pEconItem, const CEconItemAttributeDefinition *pAttribDef );
|
||
|
extern const wchar_t *GetLocalizedStringForKillEaterTypeAttr( const CLocalizationProvider *pLocalizationProvider, uint32 unKillEaterEventType ); // return type changed from locchar_t * because the backpack panel only exists on the client
|
||
|
|
||
|
uint32 unKillEaterBaseType = GetScoreTypeForKillEaterAttr( pEconItemView, GetKillEaterAttr_Type( iUserData ) );
|
||
|
|
||
|
out_String = GetLocalizedStringForKillEaterTypeAttr( GLocalizationProvider(), unKillEaterBaseType );
|
||
|
}
|
||
|
|
||
|
void GetCustomDialogToken_UserAttributeName( const CEconItemView *pEconItemView, int iUserData, CUtlConstWideString& out_String )
|
||
|
{
|
||
|
Assert( pEconItemView );
|
||
|
|
||
|
const CEconItemAttributeDefinition *pAttrDef = GetCardUpgradeForIndex( pEconItemView, iUserData );
|
||
|
if ( !pAttrDef )
|
||
|
{
|
||
|
out_String = L"unknown";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
attrib_value_t attrVal;
|
||
|
Verify( pEconItemView->FindAttribute( pAttrDef, &attrVal ) );
|
||
|
CEconAttributeDescription attrDesc( GLocalizationProvider(), pAttrDef, attrVal );
|
||
|
out_String = attrDesc.GetShortDescription();
|
||
|
}
|
||
|
|
||
|
typedef void (* GetCustomDialogLocalizationTokenFunc_t)( const CEconItemView *pEconItemView, int iUserData, CUtlConstWideString& out_String );
|
||
|
|
||
|
struct RefurbishableProperty
|
||
|
{
|
||
|
HasRefurbishablePropertyFunc_t m_pFunc;
|
||
|
GetCustomDialogLocalizationTokenFunc_t m_pGetCustomDialogLocalizationTokenFunc;
|
||
|
const char *m_szArg;
|
||
|
const char *m_pszSelectionUILocalizationToken;
|
||
|
const char *m_szDialogTitle;
|
||
|
const char *m_szDialogDesc;
|
||
|
EItemCustomizationRemoveType m_eRemovalType;
|
||
|
int m_iUserData;
|
||
|
};
|
||
|
|
||
|
// TODO: Add Gifted by Tag here
|
||
|
static RefurbishableProperty g_RemoveableAttributes[] =
|
||
|
{
|
||
|
{ &HasRemovableCustomName, NULL, NULL, "#RefurbishItem_RemoveNameCombo", "#RefurbishItem_RemoveNameTitle", "#RefurbishItem_RemoveName", kCustomizationRemove_Name, kNoUserData }, // does this item have a custom name?
|
||
|
{ &HasRemovableCustomDesc, NULL, NULL, "#RefurbishItem_RemoveDescCombo", "#RefurbishItem_RemoveDescTitle", "#RefurbishItem_RemoveDesc", kCustomizationRemove_Desc, kNoUserData }, // does this item have a custom description?
|
||
|
{ &HasPaint, &GetCustomDialogToken_PaintName, "set item tint rgb", "#RefurbishItem_RemovePaintCombo", "#RefurbishItem_RemovePaintTitle", "#RefurbishItem_RemovePaint", kCustomizationRemove_Paint, kNoUserData }, // is this item painted?
|
||
|
{ &HasCustomAttribute, NULL, "custom texture hi", "#RefurbishItem_RemoveCustomTextureCombo", "#RefurbishItem_RemoveCustomTextureTitle", "#RefurbishItem_RemoveCustomTexture", kCustomizationRemove_CustomTexture, kNoUserData }, // does this have a custom texture applied?
|
||
|
{ &HasCustomAttribute, NULL, "makers mark id", "#RefurbishItem_RemoveMakersMarkCombo", "#RefurbishItem_RemoveMakersMarkTitle", "#RefurbishItem_RemoveMakersMark", kCustomizationRemove_MakersMark, kNoUserData }, // was this item crafted by a specific dude?
|
||
|
{ &HasCustomAttribute, NULL, "killstreak tier", "#RefurbishItem_RemoveKillStreakCombo", "#RefurbishItem_RemoveKillStreakTitle", "#RefurbishItem_RemoveKillStreak", kCustomizationRemove_KillStreak, kNoUserData }, // Killstreak Effect
|
||
|
{ &HasCustomAttribute, NULL, "gifter account id", "#RefurbishItem_RemoveGifterCombo", "#RefurbishItem_RemoveGifterTitle", "#RefurbishItem_RemoveGifter", kCustomizationRemove_GiftedBy, kNoUserData }, // Gifted by
|
||
|
{ &HasCustomAttribute, NULL, "is_festivized", "#RefurbishItem_RemoveFestivizerCombo", "#RefurbishItem_RemoveFestivizerTitle", "#RefurbishItem_RemoveFestivizer", kCustomizationRemove_Festivizer, kNoUserData }, // Festivizer
|
||
|
|
||
|
//"gifter account id", // who gifted us this item? (will also remove "event date")
|
||
|
};
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Look over this weapon to see if it has any strange stat counters to reset optionally.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
static bool HasResettableScoreAttributes ( const CEconItemView *pEconItemView, const char *, int )
|
||
|
{
|
||
|
if ( !pEconItemView )
|
||
|
return false;
|
||
|
|
||
|
for ( int i = 0; i < GetKillEaterAttrCount(); i++ )
|
||
|
{
|
||
|
uint32 unScore;
|
||
|
if ( pEconItemView->FindAttribute( GetKillEaterAttr_Score( i ), &unScore ) && unScore > 0 )
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
int GetRemovableAttributesCount()
|
||
|
{
|
||
|
return ARRAYSIZE( g_RemoveableAttributes )
|
||
|
+ GetKillEaterAttrCount()
|
||
|
+ GetMaxCardUpgradesPerItem() // remove card upgrades
|
||
|
+ 1; // strange quality item score reset
|
||
|
}
|
||
|
|
||
|
RefurbishableProperty RemovableAttributes_GetAttributeDetails( int i )
|
||
|
{
|
||
|
Assert( i >= 0 );
|
||
|
Assert( i < GetRemovableAttributesCount() );
|
||
|
|
||
|
if ( i < ARRAYSIZE( g_RemoveableAttributes ) )
|
||
|
return g_RemoveableAttributes[i];
|
||
|
|
||
|
// Which attribute in particular are we looking for?
|
||
|
int iStrangePartIndex = i - ARRAYSIZE( g_RemoveableAttributes );
|
||
|
if ( iStrangePartIndex < GetKillEaterAttrCount() )
|
||
|
{
|
||
|
int iKillEaterAttrIndex = (GetKillEaterAttrCount() - GetKillEaterAttrCount()) + iStrangePartIndex;
|
||
|
|
||
|
// if we're looking at strange attributes...
|
||
|
if ( GetKillEaterAttr_IsUserCustomizable( iKillEaterAttrIndex ) )
|
||
|
{
|
||
|
// Common properties for all strange part attributes.
|
||
|
static RefurbishableProperty sStrangePartProperty = { &HasCustomAttribute, &GetCustomDialogToken_StrangePartName, NULL, "#RefurbishItem_RemoveStrangePartCombo", "#RefurbishItem_RemoveStrangePartTitle", "#RefurbishItem_RemoveStrangePart", kCustomizationRemove_StrangePart, kNoUserData };
|
||
|
|
||
|
RefurbishableProperty partReturnProp = sStrangePartProperty;
|
||
|
partReturnProp.m_szArg = GetKillEaterAttr_Score( iKillEaterAttrIndex )->GetDefinitionName(); // ...then we check for the presence of a score attribute if this slot is a strange part...
|
||
|
partReturnProp.m_iUserData = iKillEaterAttrIndex;
|
||
|
|
||
|
return partReturnProp;
|
||
|
}
|
||
|
|
||
|
// ...or the presence of a restriction attribute if this slot is a base slot that might have a filter
|
||
|
static RefurbishableProperty sStrangeFilterProperty = { &HasCustomAttribute, &GetCustomDialogToken_StrangePartName, NULL, "#RefurbishItem_RemoveStrangeFilterCombo", "#RefurbishItem_RemoveStrangeFilterTitle", "#RefurbishItem_RemoveStrangeFilter", kCustomizationRemove_StrangePart, kNoUserData };
|
||
|
|
||
|
RefurbishableProperty filterReturnProp = sStrangeFilterProperty;
|
||
|
filterReturnProp.m_szArg = GetKillEaterAttr_Restriction( iKillEaterAttrIndex )->GetDefinitionName();
|
||
|
filterReturnProp.m_iUserData = iKillEaterAttrIndex;
|
||
|
|
||
|
return filterReturnProp;
|
||
|
}
|
||
|
|
||
|
// Look for any properties that were user-assigned. We allow users to remove them.
|
||
|
int iCardUpgradeIndex = iStrangePartIndex - GetKillEaterAttrCount();
|
||
|
if ( iCardUpgradeIndex < GetMaxCardUpgradesPerItem() )
|
||
|
{
|
||
|
// Common properties for all card upgrade attributes.
|
||
|
static RefurbishableProperty sCardUpgradeProperty = { &HasCustomUserAttribute, &GetCustomDialogToken_UserAttributeName, NULL, "#RefurbishItem_RemoveSpellCombo", "#RefurbishItem_RemoveSpellTitle", "#RefurbishItem_RemoveSpellUpgrade", kCustomizationRemove_UpgradeCard, kNoUserData };
|
||
|
|
||
|
RefurbishableProperty returnProp = sCardUpgradeProperty;
|
||
|
// FIX THIS FOR CARDS / SPELLS?
|
||
|
// returnProp.m_szArg = GetCustomDialogToken_UserAttributeName ?
|
||
|
returnProp.m_iUserData = iCardUpgradeIndex;
|
||
|
|
||
|
return returnProp;
|
||
|
}
|
||
|
|
||
|
// We might also be trying to reset the strange score counters.
|
||
|
Assert( iStrangePartIndex == GetKillEaterAttrCount() + GetMaxCardUpgradesPerItem() );
|
||
|
Assert( i == GetRemovableAttributesCount() - 1 );
|
||
|
|
||
|
static RefurbishableProperty sStrangeScoreReset = { &HasResettableScoreAttributes, NULL, NULL, "#RefurbishItem_RemoveStrangeScoresCombo", "#RefurbishItem_RemoveStrangeScoresTitle", "#RefurbishItem_RemoveStrangeScores", kCustomizationRemove_StrangeScores, kNoUserData };
|
||
|
return sStrangeScoreReset;
|
||
|
}
|
||
|
|
||
|
bool RemovableAttributes_DoesAttributeApply( int i, const CEconItemView *pEconItemView )
|
||
|
{
|
||
|
static CSchemaAttributeDefHandle pAttr_CannotRestore( "cannot restore" );
|
||
|
if ( pEconItemView->FindAttribute( pAttr_CannotRestore ) )
|
||
|
return false;
|
||
|
|
||
|
RefurbishableProperty attr = RemovableAttributes_GetAttributeDetails( i );
|
||
|
|
||
|
return attr.m_pFunc( pEconItemView, attr.m_szArg, attr.m_iUserData );
|
||
|
}
|
||
|
|
||
|
bool RemovableAttributes_DoAnyAttributesApply( const CEconItemView *pEconItemView )
|
||
|
{
|
||
|
static CSchemaAttributeDefHandle pAttr_CannotRestore( "cannot restore" );
|
||
|
if ( pEconItemView->FindAttribute( pAttr_CannotRestore ) )
|
||
|
return false;
|
||
|
|
||
|
for ( int i = 0; i < GetRemovableAttributesCount(); i++ )
|
||
|
{
|
||
|
if ( RemovableAttributes_DoesAttributeApply( i, pEconItemView ) )
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
ConVar cl_showbackpackrarities( "cl_showbackpackrarities", "0", FCVAR_ARCHIVE, "0 = Show no backpack icon border colors. 1 = Show item rarities within the backpack. 2 = Show item rarities only for Market-listable items." );
|
||
|
ConVar cl_show_market_data_on_items( "cl_show_market_data_on_items", "1", FCVAR_ARCHIVE, "0 = Never. 1 = Only when showing borders for Market-listable items. 2 = Always." );
|
||
|
|
||
|
ConVar tf_explanations_backpackpanel( "tf_explanations_backpackpanel", "0", FCVAR_ARCHIVE, "Whether the user has seen explanations for this panel." );
|
||
|
|
||
|
ConVar tf_backpack_page_button_delay( "tf_backpack_page_button_delay", "0.5", FCVAR_ARCHIVE, "Amount of time the mouse cursor needs to hover over the page button to select the page." );
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CBackpackPanel::CBackpackPanel( vgui::Panel *parent, const char *panelName ) : CBaseLoadoutPanel( parent, panelName )
|
||
|
{
|
||
|
m_nQuickOpenTxn = 0;
|
||
|
m_pContextMenu = NULL;
|
||
|
m_pPageButtonKVs = NULL;
|
||
|
m_mapSeenItems.SetLessFunc( DefLessFunc( itemid_t ) );
|
||
|
m_bInitializedSeenItems = false;
|
||
|
m_pNameFilterTextEntry = NULL;
|
||
|
m_flFilterItemTime = 0.f;
|
||
|
m_mapFilteringItems.SetLessFunc( DefLessFunc(int) );
|
||
|
|
||
|
m_pNextPageButton = NULL;
|
||
|
m_pPrevPageButton = NULL;
|
||
|
m_pShowExplanationsButton = NULL;
|
||
|
m_pCurPageLabel = NULL;
|
||
|
m_pSortByComboBox = NULL;
|
||
|
m_pShowRarityComboBox = NULL;
|
||
|
m_pShowBaseItemsCheckbox = NULL;
|
||
|
m_pDragToNextPageButton = NULL;
|
||
|
m_pDragToPrevPageButton = NULL;
|
||
|
m_flPreventDragPageSwitchUntil = 0;
|
||
|
m_flStartExplanationsAt = 0;
|
||
|
|
||
|
m_flMouseDownTime = 0;
|
||
|
m_pItemDraggedFromPanel = NULL;
|
||
|
m_iDraggedFromPage = 0;
|
||
|
m_bMouseDownOnItemPanel = false;
|
||
|
m_bDragging = false;
|
||
|
m_iMouseDownX = m_iMouseDownY = 0;
|
||
|
|
||
|
m_pMouseDragItemPanel = vgui::SETUP_PANEL( new CItemModelPanel( this, "mousedragitempanel" ) );
|
||
|
m_pCancelToolButton = NULL;
|
||
|
m_pCraftButton = NULL;
|
||
|
m_bShowBaseItems = false;
|
||
|
m_pConfirmDeleteDialog = NULL;
|
||
|
m_pToolIcon = NULL;
|
||
|
m_eSelectionMode = StandardSelection;
|
||
|
m_nLastToolPage = 0;
|
||
|
m_pDynamicRecipePanel = NULL;
|
||
|
m_pItemSlotPanel = NULL;
|
||
|
m_pStrangeToolPanel = NULL;
|
||
|
|
||
|
m_nNumActivePages = 0;
|
||
|
|
||
|
m_pInspectPanel = new CTFItemInspectionPanel( this, "InspectionPanel" );
|
||
|
m_pInspectCosmeticPanel = new CTFStorePreviewItemPanel2( this, "Resource/UI/econ/InspectionPanel_Cosmetic.res", "storepreviewitem", NULL );
|
||
|
m_pCollectionCraftPanel = NULL;
|
||
|
m_pHalloweenOfferingPanel = NULL;
|
||
|
m_pMannCoTradePanel = NULL;
|
||
|
|
||
|
CancelToolSelection();
|
||
|
|
||
|
ListenForGameEvent( "gc_connected" );
|
||
|
}
|
||
|
|
||
|
CBackpackPanel::~CBackpackPanel()
|
||
|
{
|
||
|
if ( m_pPageButtonKVs )
|
||
|
{
|
||
|
m_pPageButtonKVs->deleteThis();
|
||
|
m_pPageButtonKVs = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||
|
{
|
||
|
if ( !m_pSortByComboBox && UsesRarityControls() )
|
||
|
{
|
||
|
m_pSortByComboBox = new vgui::ComboBox( this, "SortByComboBox", 5, false );
|
||
|
m_pSortByComboBox->AddActionSignalTarget( this );
|
||
|
}
|
||
|
|
||
|
LoadControlSettings( GetResFile() );
|
||
|
|
||
|
BaseClass::ApplySchemeSettings( pScheme );
|
||
|
|
||
|
m_pNameFilterTextEntry = FindControl<vgui::TextEntry>( "NameFilterTextEntry" );
|
||
|
if ( m_pNameFilterTextEntry )
|
||
|
{
|
||
|
m_pNameFilterTextEntry->AddActionSignalTarget( this );
|
||
|
}
|
||
|
|
||
|
m_pCancelToolButton = dynamic_cast<CExButton*>( FindChildByName("CancelApplyToolButton") );
|
||
|
m_pCraftButton = dynamic_cast<CExButton*>( FindChildByName("CraftButton") );
|
||
|
m_pToolIcon = dynamic_cast<vgui::ScalableImagePanel*>( FindChildByName("tool_icon") );
|
||
|
|
||
|
m_pNextPageButton = dynamic_cast<CExButton*>( FindChildByName("NextPageButton") );
|
||
|
m_pPrevPageButton = dynamic_cast<CExButton*>( FindChildByName("PrevPageButton") );
|
||
|
m_pShowExplanationsButton = dynamic_cast<CExButton*>( FindChildByName("ShowExplanationsButton") );
|
||
|
m_pDragToNextPageButton = dynamic_cast<CExButton*>( FindChildByName("DragToNextPageButton") );
|
||
|
m_pDragToPrevPageButton = dynamic_cast<CExButton*>( FindChildByName("DragToPrevPageButton") );
|
||
|
m_pCurPageLabel = dynamic_cast<vgui::Label*>( FindChildByName("CurPageLabel") );
|
||
|
m_pShowRarityComboBox = dynamic_cast<vgui::ComboBox*>( FindChildByName( "ShowRarityComboBox" ) );
|
||
|
if ( m_pShowRarityComboBox )
|
||
|
{
|
||
|
m_pShowRarityComboBox->AddActionSignalTarget( this );
|
||
|
|
||
|
m_pShowRarityComboBox->AddItem( "#TF_Backpack_ShowNoBorders", NULL );
|
||
|
m_pShowRarityComboBox->AddItem( "#TF_Backpack_ShowQualityBorders", NULL );
|
||
|
m_pShowRarityComboBox->AddItem( "#TF_Backpack_ShowMarketableBorders", NULL );
|
||
|
|
||
|
m_pShowRarityComboBox->ActivateItemByRow( cl_showbackpackrarities.GetInt() );
|
||
|
}
|
||
|
m_pShowBaseItemsCheckbox = dynamic_cast<vgui::CheckButton*>( FindChildByName( "ShowBaseItemsCheckbox" ) );
|
||
|
if ( m_pShowBaseItemsCheckbox )
|
||
|
{
|
||
|
m_pShowBaseItemsCheckbox->AddActionSignalTarget( this );
|
||
|
m_pShowBaseItemsCheckbox->SetSelected( m_bShowBaseItems );
|
||
|
}
|
||
|
|
||
|
m_pMouseDragItemPanel->SetBorder( pScheme->GetBorder("BackpackItemMouseOverBorder") );
|
||
|
|
||
|
// Setup our combo box
|
||
|
if ( m_pSortByComboBox )
|
||
|
{
|
||
|
m_pSortByComboBox->RemoveAll();
|
||
|
vgui::HFont hFont = pScheme->GetFont( "HudFontSmallestBold", true );
|
||
|
m_pSortByComboBox->SetFont( hFont );
|
||
|
KeyValues *pKeyValues = new KeyValues( "data" );
|
||
|
for ( int i = 0; i < ARRAYSIZE(g_BackpackSortTypes); i++ )
|
||
|
{
|
||
|
pKeyValues->SetInt( "sortby", i );
|
||
|
m_pSortByComboBox->AddItem( g_BackpackSortTypes[i].szSortDesc, pKeyValues );
|
||
|
}
|
||
|
pKeyValues->deleteThis();
|
||
|
m_pSortByComboBox->ActivateItemByRow( 0 );
|
||
|
m_pSortByComboBox->GetMenu()->SetNumberOfVisibleItems( ARRAYSIZE(g_BackpackSortTypes) );
|
||
|
}
|
||
|
|
||
|
// Create page buttons
|
||
|
const int nNumMaxPages = GetNumMaxPages();
|
||
|
for ( int i=m_Pages.Count(); i<nNumMaxPages; ++i )
|
||
|
{
|
||
|
EditablePanel *pPage = vgui::SETUP_PANEL( new EditablePanel( this, CFmtStr( "page_%d", i ) ) );
|
||
|
m_Pages.AddToTail( pPage );
|
||
|
}
|
||
|
|
||
|
if ( m_pInspectCosmeticPanel )
|
||
|
{
|
||
|
// Force it to load it's scheme now, because it needs to be done before we set it's visibility below
|
||
|
m_pInspectCosmeticPanel->InvalidateLayout( false, true );
|
||
|
m_pInspectCosmeticPanel->SetVisible( false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CBackpackPanel::ApplySettings( KeyValues *inResourceData )
|
||
|
{
|
||
|
BaseClass::ApplySettings( inResourceData );
|
||
|
|
||
|
KeyValues *pItemKV = inResourceData->FindKey( "pagebuttons_kv" );
|
||
|
if ( pItemKV )
|
||
|
{
|
||
|
if ( m_pPageButtonKVs )
|
||
|
{
|
||
|
m_pPageButtonKVs->deleteThis();
|
||
|
}
|
||
|
m_pPageButtonKVs = new KeyValues("pagebuttons_kv");
|
||
|
pItemKV->CopySubkeys( m_pPageButtonKVs );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::AddNewItemPanel( int iPanelIndex )
|
||
|
{
|
||
|
BaseClass::AddNewItemPanel( iPanelIndex );
|
||
|
|
||
|
// Store a position for our new panel
|
||
|
m_ItemModelPanelPos.AddToTail();
|
||
|
m_ItemModelPanelPos[iPanelIndex].x = m_ItemModelPanelPos[iPanelIndex].y = 0;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CItemModelPanel *CBackpackPanel::GetItemPanelAtPos( int x, int y )
|
||
|
{
|
||
|
if ( !m_pItemModelPanels.Count() )
|
||
|
return NULL;
|
||
|
|
||
|
int iW = m_pItemModelPanels[0]->GetWide();
|
||
|
int iH = m_pItemModelPanels[0]->GetTall();
|
||
|
for ( int i = 0; i < m_ItemModelPanelPos.Count(); i++ )
|
||
|
{
|
||
|
if ( (x < m_ItemModelPanelPos[i].x) || (x > (m_ItemModelPanelPos[i].x + iW)) )
|
||
|
continue;
|
||
|
if ( (y < m_ItemModelPanelPos[i].y) || (y > (m_ItemModelPanelPos[i].y + iH)) )
|
||
|
continue;
|
||
|
return m_pItemModelPanels[i];
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
int CBackpackPanel::GetPageButtonIndexAtPos( int x, int y )
|
||
|
{
|
||
|
if ( !m_Pages.Count() )
|
||
|
return -1;
|
||
|
|
||
|
int iW = m_Pages[0]->GetWide();
|
||
|
int iH = m_Pages[0]->GetTall();
|
||
|
for ( int i = 0; i < m_PageButtonPos.Count(); i++ )
|
||
|
{
|
||
|
if ( (x < m_PageButtonPos[i].x) || (x > (m_PageButtonPos[i].x + iW)) )
|
||
|
continue;
|
||
|
if ( (y < m_PageButtonPos[i].y) || (y > (m_PageButtonPos[i].y + iH)) )
|
||
|
continue;
|
||
|
return m_Pages[i]->IsVisible() ? i : -1;
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Change the text color on the page buttons based on the context of the
|
||
|
// page they represent.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::SetPageButtonTextColorBasedOnContents()
|
||
|
{
|
||
|
vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
|
||
|
|
||
|
if ( m_Pages.Count() == 0 )
|
||
|
return;
|
||
|
|
||
|
if ( !pScheme )
|
||
|
return;
|
||
|
|
||
|
const Color& colorEmpty = pScheme->GetColor( "TanDarker", Color( 235, 226, 202, 255 ) );
|
||
|
const Color& colorPartial = Color( 170, 161, 137, 255 );
|
||
|
const Color& colorFull = pScheme->GetColor( "TanLight", Color( 235, 226, 202, 255 ) );
|
||
|
const Color& colorSelected = pScheme->GetColor( "TFOrange", Color( 145, 73, 59, 255 ) );
|
||
|
|
||
|
CUtlVector<int> vecPageCount;
|
||
|
CUtlVector<int> vecNewPageCount;
|
||
|
vecPageCount.EnsureCount( m_Pages.Count() );
|
||
|
vecNewPageCount.EnsureCount( m_Pages.Count() );
|
||
|
// Initialize to 0
|
||
|
FOR_EACH_VEC( vecPageCount, i )
|
||
|
{
|
||
|
vecPageCount[i] = 0;
|
||
|
vecNewPageCount[i] = 0;
|
||
|
}
|
||
|
|
||
|
CPlayerInventory *pInv = InventoryManager()->GetLocalInventory();
|
||
|
Assert( pInv );
|
||
|
// Tally up how many items are on each page
|
||
|
if ( pInv )
|
||
|
{
|
||
|
for ( int i = 0 ; i < pInv->GetItemCount() ; ++i )
|
||
|
{
|
||
|
CEconItemView *pItem = pInv->GetItem( i );
|
||
|
const int nSlot = InventoryManager()->GetBackpackPositionFromBackend( pItem->GetInventoryPosition() ) - 1;
|
||
|
const int nPage = nSlot / GetNumSlotsPerPage();
|
||
|
if ( nPage >= 0 && nPage < m_Pages.Count() )
|
||
|
{
|
||
|
vecPageCount[ nPage ] = vecPageCount[ nPage ] + 1;
|
||
|
|
||
|
// Unackknowledged items technically are on the 1st page, so dont count them
|
||
|
if ( m_mapSeenItems.Find( pItem->GetItemID() ) == m_mapSeenItems.InvalidIndex()
|
||
|
&& IsUnacknowledged( pItem->GetInventoryPosition() ) == false && !m_bShowBaseItems && !HasNameFilter() )
|
||
|
{
|
||
|
vecNewPageCount[ nPage ] = vecNewPageCount[ nPage ] + 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Set the color for each page button
|
||
|
FOR_EACH_VEC( m_Pages, i )
|
||
|
{
|
||
|
const int nNewCount = vecNewPageCount[i];
|
||
|
const int nCount = vecPageCount[i];
|
||
|
CExButton* pButton = dynamic_cast<CExButton*>( m_Pages[i]->FindChildByName( "Button" ) );
|
||
|
if ( pButton )
|
||
|
{
|
||
|
Color setColor = colorEmpty;
|
||
|
const Color& bgColor = GetCurrentPage() == i ? colorSelected : pButton->GetButtonDefaultBgColor();
|
||
|
|
||
|
if ( nCount == GetNumSlotsPerPage() )
|
||
|
setColor = colorFull;
|
||
|
else if ( nCount > 0 )
|
||
|
setColor = colorPartial;
|
||
|
|
||
|
pButton->SetSelectedColor( setColor, pButton->GetButtonSelectedBgColor() );
|
||
|
pButton->SetDefaultColor( setColor, bgColor );
|
||
|
pButton->SetArmedColor( setColor, pButton->GetButtonArmedBgColor() );
|
||
|
pButton->SetDepressedColor( setColor, pButton->GetButtonDepressedBgColor() );
|
||
|
}
|
||
|
|
||
|
// Show our "NEW!" label if there's any unseen items on that page
|
||
|
CExLabel* pNew = dynamic_cast<CExLabel*>( m_Pages[i]->FindChildByName( "New" ) );
|
||
|
if ( pNew )
|
||
|
{
|
||
|
pNew->SetVisible( nNewCount > 0 );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::MarkItemIDDirty( itemid_t itemID )
|
||
|
{
|
||
|
if ( m_vecDirtyItems.Find( itemID ) == m_vecDirtyItems.InvalidIndex() )
|
||
|
{
|
||
|
m_vecDirtyItems.AddToTail( itemID );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::PositionItemPanel( CItemModelPanel *pPanel, int iIndex )
|
||
|
{
|
||
|
int iCenter = GetWide() * 0.5;
|
||
|
int iButtonX = (iIndex % GetNumColumns());
|
||
|
int iButtonY = (iIndex / GetNumColumns());
|
||
|
int iXPos = (iCenter + m_iItemBackpackOffcenterX) + (iButtonX * m_pItemModelPanels[iIndex]->GetWide()) + (m_iItemBackpackXDelta * iButtonX);
|
||
|
int iYPos = m_iItemYPos + (iButtonY * m_pItemModelPanels[iIndex]->GetTall() ) + (m_iItemBackpackYDelta * iButtonY);
|
||
|
|
||
|
m_pItemModelPanels[iIndex]->SetPos( iXPos, iYPos );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::PerformLayout( void )
|
||
|
{
|
||
|
BaseClass::PerformLayout();
|
||
|
|
||
|
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
|
||
|
{
|
||
|
// Viewing the backpack. Layout all the buttons and hide the class image.
|
||
|
m_pItemModelPanels[i]->SetVisible( true );
|
||
|
m_pItemModelPanels[i]->SetNoItemText( "#SelectNoItemSlot" );
|
||
|
|
||
|
PositionItemPanel( m_pItemModelPanels[i], i );
|
||
|
|
||
|
// Cache off where we put the panel
|
||
|
m_pItemModelPanels[i]->GetPos( m_ItemModelPanelPos[i].x, m_ItemModelPanelPos[i].y );
|
||
|
|
||
|
// Take into account parent's position
|
||
|
Panel* pParent = m_pItemModelPanels[i]->GetParent();
|
||
|
if( pParent )
|
||
|
{
|
||
|
int x = 0,y = 0;
|
||
|
pParent->GetPos( x, y );
|
||
|
m_ItemModelPanelPos[i].x += x;
|
||
|
m_ItemModelPanelPos[i].y += y;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// adjust page buttons
|
||
|
{
|
||
|
m_nNumActivePages = GetNumPages();
|
||
|
|
||
|
int iCenter = GetWide() * 0.5;
|
||
|
|
||
|
int iPageBarWidth = 2 * abs( m_iItemBackpackOffcenterX );
|
||
|
int iPageButtonWidth = ( iPageBarWidth - ( m_iPageButtonPerRow - 1 ) * m_iPageButtonXDelta ) / m_iPageButtonPerRow;
|
||
|
int iPageButtonWidthPlusDelta = iPageButtonWidth + m_iPageButtonXDelta;
|
||
|
int iPageButtonHeightPlusDelta = m_iPageButtonHeight + m_iPageButtonYDelta;
|
||
|
int iStart = iCenter + m_iItemBackpackOffcenterX;
|
||
|
|
||
|
m_PageButtonPos.EnsureCount( m_Pages.Count() );
|
||
|
for ( int i=0; i<m_Pages.Count(); ++i )
|
||
|
{
|
||
|
EditablePanel *pPage = m_Pages[i];
|
||
|
if ( pPage )
|
||
|
{
|
||
|
// Apply control settings here
|
||
|
if ( m_pPageButtonKVs )
|
||
|
pPage->ApplySettings( m_pPageButtonKVs );
|
||
|
CExButton* pButton = dynamic_cast<CExButton*>( pPage->FindChildByName( "Button" ) );
|
||
|
pPage->InvalidateLayout( true, true );
|
||
|
// Make the button have the right command and send it's signals to us
|
||
|
if ( pButton )
|
||
|
{
|
||
|
pButton->SetSelected( false );
|
||
|
pButton->SetCommand( CFmtStr( "goto_page_%d", i ) );
|
||
|
pButton->AddActionSignalTarget( this );
|
||
|
}
|
||
|
pPage->SetDialogVariable( "page", i+1 );
|
||
|
|
||
|
bool bVisible = i < m_nNumActivePages;
|
||
|
if ( bVisible )
|
||
|
{
|
||
|
int iRow = i /m_iPageButtonPerRow;
|
||
|
int iColumn = i % m_iPageButtonPerRow;
|
||
|
pPage->SetBounds( iStart + iColumn * iPageButtonWidthPlusDelta, m_iPageButtonYPos + iRow * iPageButtonHeightPlusDelta, iPageButtonWidth, m_iPageButtonHeight );
|
||
|
pPage->GetPos( m_PageButtonPos[i].x , m_PageButtonPos[i].y );
|
||
|
}
|
||
|
pPage->SetVisible( bVisible );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Update colors and the "NEW!" labels
|
||
|
SetPageButtonTextColorBasedOnContents();
|
||
|
}
|
||
|
|
||
|
if ( m_pNextPageButton )
|
||
|
{
|
||
|
m_pNextPageButton->SetVisible( true );
|
||
|
}
|
||
|
if ( m_pPrevPageButton )
|
||
|
{
|
||
|
m_pPrevPageButton->SetVisible( true );
|
||
|
}
|
||
|
if ( m_pCurPageLabel )
|
||
|
{
|
||
|
m_pCurPageLabel->SetVisible( true );
|
||
|
}
|
||
|
|
||
|
if ( m_pSortByComboBox )
|
||
|
{
|
||
|
m_pSortByComboBox->SetVisible( !InToolSelectionMode() );
|
||
|
}
|
||
|
if ( m_pShowRarityComboBox )
|
||
|
{
|
||
|
m_pShowRarityComboBox->SetVisible( true );
|
||
|
}
|
||
|
|
||
|
if ( m_pNextPageButton )
|
||
|
{
|
||
|
m_pNextPageButton->SetEnabled( GetNumPages() > 1 );
|
||
|
}
|
||
|
if ( m_pPrevPageButton )
|
||
|
{
|
||
|
m_pPrevPageButton->SetEnabled( GetNumPages() > 1 );
|
||
|
}
|
||
|
|
||
|
if ( !m_bDragging )
|
||
|
{
|
||
|
if ( m_pDragToNextPageButton && m_pDragToPrevPageButton )
|
||
|
{
|
||
|
m_pDragToNextPageButton->SetVisible( false );
|
||
|
m_pDragToPrevPageButton->SetVisible( false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool bShowActions = (!m_bItemsOnly && !InToolSelectionMode());
|
||
|
if ( m_pCraftButton )
|
||
|
{
|
||
|
m_pCraftButton->SetVisible( bShowActions );
|
||
|
}
|
||
|
if ( m_pCancelToolButton )
|
||
|
{
|
||
|
m_pCancelToolButton->SetVisible( InToolSelectionMode() );
|
||
|
}
|
||
|
|
||
|
if ( m_pShowExplanationsButton )
|
||
|
{
|
||
|
m_pShowExplanationsButton->SetVisible( !m_bItemsOnly );
|
||
|
}
|
||
|
if ( m_pShowBaseItemsCheckbox )
|
||
|
{
|
||
|
m_pShowBaseItemsCheckbox->SetVisible( !m_bItemsOnly );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::FireGameEvent( IGameEvent *event )
|
||
|
{
|
||
|
static CSchemaItemDefHandle pItemDef_BasePaintCan( "Paint Can" );
|
||
|
const char *type = event->GetName();
|
||
|
if ( Q_strcmp( "gc_connected", type ) == 0 )
|
||
|
{
|
||
|
if ( !m_bInitializedSeenItems )
|
||
|
{
|
||
|
CPlayerInventory *pInventory = InventoryManager()->GetLocalInventory();
|
||
|
if ( pInventory )
|
||
|
{
|
||
|
for ( int i = 0; i < pInventory->GetItemCount(); i++ )
|
||
|
{
|
||
|
CEconItemView *pItem = pInventory->GetItem(i);
|
||
|
m_mapSeenItems.Insert( pItem->GetItemID() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_bInitializedSeenItems = true;
|
||
|
}
|
||
|
|
||
|
m_vecPaintCans.Purge();
|
||
|
m_vecStrangeParts.Purge();
|
||
|
const CEconItemSchema::ToolsItemDefinitionMap_t &toolDefs = GetItemSchema()->GetToolsItemDefinitionMap();
|
||
|
|
||
|
// Store all of the active paint can item defs
|
||
|
FOR_EACH_MAP_FAST( toolDefs, i )
|
||
|
{
|
||
|
const CEconItemDefinition *pItemDef = toolDefs[i];
|
||
|
const IEconTool *pEconTool = pItemDef->GetEconTool();
|
||
|
if ( !pEconTool )
|
||
|
continue;
|
||
|
|
||
|
// Paint can list
|
||
|
// Ignore the stock paintcan thats only for armory purposes
|
||
|
if ( !V_strcmp( pEconTool->GetTypeName(), "paint_can" ) && pItemDef_BasePaintCan != pItemDef )
|
||
|
{
|
||
|
// Paint Can
|
||
|
m_vecPaintCans.AddToTail( pItemDef->GetDefinitionIndex() );
|
||
|
}
|
||
|
// Strange Parts List
|
||
|
else if ( !V_strcmp( pEconTool->GetTypeName(), "strange_part" ) )
|
||
|
{
|
||
|
m_vecStrangeParts.AddToTail( pItemDef->GetDefinitionIndex() );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BaseClass::FireGameEvent( event );
|
||
|
}
|
||
|
|
||
|
void CBackpackPanel::CheckForQuickOpenKey()
|
||
|
{
|
||
|
if ( !m_hQuickOpenCrate )
|
||
|
return;
|
||
|
|
||
|
// We only want to continue if it's the transaction we're listening for
|
||
|
if ( EconUI()->GetStorePanel()->GetMostRecentSuccessfulTransactionID() != m_nQuickOpenTxn )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CPlayerInventory *pInventory = InventoryManager()->GetLocalInventory();
|
||
|
if ( pInventory )
|
||
|
{
|
||
|
for ( int i = 0; i < pInventory->GetItemCount(); i++ )
|
||
|
{
|
||
|
CEconItemView *pInvItem = pInventory->GetItem( i );
|
||
|
|
||
|
uint32 iPosition = pInvItem->GetInventoryPosition();
|
||
|
if ( IsUnacknowledged( iPosition ) == false )
|
||
|
continue;
|
||
|
|
||
|
if ( InventoryManager()->GetBackpackPositionFromBackend( iPosition ) != 0 )
|
||
|
continue;
|
||
|
|
||
|
// Now make sure we haven't got a clientside saved ack for this item.
|
||
|
if ( InventoryManager()->HasBeenAckedByClient( pInvItem ) )
|
||
|
continue;
|
||
|
|
||
|
// If item is not a drop we want to show the notification otherwise they'll get the notification on death
|
||
|
int iFoundMethod = GetUnacknowledgedReason( iPosition );
|
||
|
if ( iFoundMethod != UNACK_ITEM_PURCHASED )
|
||
|
continue;
|
||
|
|
||
|
if ( !pInvItem->GetStaticData()->IsTool() )
|
||
|
continue;
|
||
|
|
||
|
if( !CEconSharedToolSupport::ToolCanApplyTo( pInvItem, m_hQuickOpenCrate ) )
|
||
|
continue;
|
||
|
|
||
|
if ( !pInvItem->GetStaticData()->GetEconTool() )
|
||
|
continue;
|
||
|
|
||
|
if ( !Q_strcmp( pInvItem->GetStaticData()->GetEconTool()->GetTypeName(), "decoder_ring" ) == 0 )
|
||
|
continue;
|
||
|
|
||
|
ApplyTool( this, pInvItem, m_hQuickOpenCrate );
|
||
|
CloseStoreStatusDialog();
|
||
|
|
||
|
m_hQuickOpenCrate = NULL;
|
||
|
m_nQuickOpenTxn = 0;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_hQuickOpenCrate = NULL;
|
||
|
m_nQuickOpenTxn = 0;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: When the store get's a new transaction ID, it comes here as well
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::SetCurrentTransactionID( uint64 nTxnID )
|
||
|
{
|
||
|
// If we've got a quick open crate st, and no quick open transaction ID,
|
||
|
// then we want to capture the incoming transaction ID so that we can
|
||
|
// compare future incoming successful transactions to see if they have
|
||
|
// the key we're expecting
|
||
|
if ( m_hQuickOpenCrate && m_nQuickOpenTxn == 0 )
|
||
|
{
|
||
|
m_nQuickOpenTxn = nTxnID;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnShowPanel( bool bVisible, bool bReturningFromArmory )
|
||
|
{
|
||
|
if ( bVisible )
|
||
|
{
|
||
|
m_pMouseDragItemPanel->SetVisible( false );
|
||
|
|
||
|
if( m_pDynamicRecipePanel )
|
||
|
{
|
||
|
m_pDynamicRecipePanel->SetVisible( false );
|
||
|
}
|
||
|
|
||
|
if ( m_pItemSlotPanel )
|
||
|
{
|
||
|
m_pItemSlotPanel->SetVisible( false );
|
||
|
}
|
||
|
|
||
|
m_bShowBaseItems = false;
|
||
|
if ( m_pShowBaseItemsCheckbox )
|
||
|
{
|
||
|
m_pShowBaseItemsCheckbox->SetSelected( m_bShowBaseItems );
|
||
|
}
|
||
|
|
||
|
if ( !bReturningFromArmory )
|
||
|
{
|
||
|
SetCurrentPage( 0 );
|
||
|
CancelToolSelection();
|
||
|
}
|
||
|
|
||
|
m_nNumActivePages = 0;
|
||
|
|
||
|
#ifdef STAGING_ONLY
|
||
|
// Reset pinned-state of the card
|
||
|
m_pMouseOverCardPanel->PinCard( false );
|
||
|
#endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( m_bDragging )
|
||
|
{
|
||
|
StopDrag( false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( m_pInspectPanel )
|
||
|
{
|
||
|
m_pInspectPanel->SetVisible( false );
|
||
|
}
|
||
|
|
||
|
if ( m_pInspectCosmeticPanel )
|
||
|
{
|
||
|
m_pInspectCosmeticPanel->SetVisible( false );
|
||
|
}
|
||
|
|
||
|
if ( m_pCollectionCraftPanel )
|
||
|
{
|
||
|
m_pCollectionCraftPanel->SetVisible( false );
|
||
|
}
|
||
|
|
||
|
if ( m_pHalloweenOfferingPanel )
|
||
|
{
|
||
|
m_pHalloweenOfferingPanel->SetVisible( false );
|
||
|
}
|
||
|
|
||
|
if ( m_pMannCoTradePanel )
|
||
|
{
|
||
|
m_pMannCoTradePanel->SetVisible( false );
|
||
|
}
|
||
|
|
||
|
if ( m_pStrangeToolPanel )
|
||
|
{
|
||
|
m_pStrangeToolPanel->MarkForDeletion();
|
||
|
m_pStrangeToolPanel = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::PostShowPanel( bool bVisible )
|
||
|
{
|
||
|
if ( bVisible )
|
||
|
{
|
||
|
DeSelectAllBackpackItemPanels();
|
||
|
|
||
|
RequestFocus();
|
||
|
|
||
|
// Clear out text field
|
||
|
ClearNameFilter( true );
|
||
|
}
|
||
|
|
||
|
// If this is the first time we've opened the loadout, start the loadout explanations
|
||
|
ConVar *pConVar = GetExplanationConVar();
|
||
|
if ( bVisible && pConVar && !pConVar->GetBool() && ShouldShowExplanations() )
|
||
|
{
|
||
|
m_flStartExplanationsAt = Plat_FloatTime() + 0.5;
|
||
|
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
int CBackpackPanel::GetNumPages( void )
|
||
|
{
|
||
|
int iMaxItems = InventoryManager()->GetLocalInventory()->GetMaxItemCount();
|
||
|
return (int)(ceil((float)iMaxItems / (float)BACKPACK_SLOTS_PER_PAGE));
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::AssignItemToPanel( CItemModelPanel *pPanel, int iIndex )
|
||
|
{
|
||
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ );
|
||
|
|
||
|
static int iItemBackpackPos = 0;
|
||
|
if ( iIndex == 0 )
|
||
|
{
|
||
|
iItemBackpackPos = 0;
|
||
|
}
|
||
|
int iPanelBackpackPos = GetBackpackPosForPanelIndex(iIndex);
|
||
|
|
||
|
static int iLastMapItem = -1;
|
||
|
|
||
|
pPanel->SetShowQuantity( true );
|
||
|
|
||
|
const wchar_t* wszFilter = GetNameFilter();
|
||
|
bool bInToolSelection = InToolSelectionMode() && m_ToolSelectionItem.IsValid();
|
||
|
|
||
|
CEconItemView *pItemData = NULL;
|
||
|
CEconItemView tempItem;
|
||
|
if ( m_bShowBaseItems )
|
||
|
{
|
||
|
const CEconItemDefinition* pItemDef = NULL;
|
||
|
|
||
|
const CEconItemSchema::BaseItemDefinitionMap_t& mapItems = GetItemSchema()->GetBaseItemDefinitionMap();
|
||
|
int iStart = iIndex == 0 ? mapItems.FirstInorder() : mapItems.NextInorder( iLastMapItem );
|
||
|
for ( int it = iStart; it != mapItems.InvalidIndex(); it = mapItems.NextInorder( it ) )
|
||
|
{
|
||
|
iLastMapItem = it;
|
||
|
|
||
|
if ( mapItems[it]->IsBaseItem() && !mapItems[it]->IsHidden() )
|
||
|
{
|
||
|
// Instead of linking to this base item definition, link to the definition of what it will become
|
||
|
// when we customize it.
|
||
|
CFmtStr fmtStrCustomizedDefName( "Upgradeable %s", mapItems[it]->GetDefinitionName() );
|
||
|
pItemDef = GetItemSchema()->GetItemDefinitionByName( fmtStrCustomizedDefName.Access() );
|
||
|
|
||
|
// If we don't have an upgradeable version, we assume that we can't upgrade it and link to the base
|
||
|
// definition instead. We expect this to only happen if the item won't actually be useable for whatever
|
||
|
// purpose (name tags, etc.). We sanity-check this on the GC.
|
||
|
if ( !pItemDef )
|
||
|
{
|
||
|
pItemDef = mapItems[it];
|
||
|
}
|
||
|
|
||
|
tempItem.Init( pItemDef->GetDefinitionIndex(), AE_UNIQUE, AE_USE_SCRIPT_VALUE, true );
|
||
|
|
||
|
// skip this item if the tool cannot be applied to it
|
||
|
if ( bInToolSelection && !CEconSharedToolSupport::ToolCanApplyTo( &m_ToolSelectionItem, &tempItem ) )
|
||
|
{
|
||
|
pItemDef = NULL;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ( DoesItemPassSearchFilter( tempItem.GetDescription(), wszFilter ) )
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pItemDef = NULL;
|
||
|
}
|
||
|
|
||
|
if ( pItemDef )
|
||
|
{
|
||
|
pItemData = &tempItem;
|
||
|
|
||
|
++iItemBackpackPos;
|
||
|
}
|
||
|
}
|
||
|
else if ( HasNameFilter() )
|
||
|
{
|
||
|
int iStart = iIndex == 0 ? m_mapFilteringItems.FirstInorder() : m_mapFilteringItems.NextInorder( iLastMapItem );
|
||
|
for ( int it = iStart; it != m_mapFilteringItems.InvalidIndex(); it = m_mapFilteringItems.NextInorder( it ) )
|
||
|
{
|
||
|
iLastMapItem = it;
|
||
|
|
||
|
CEconItemView *pItem = m_mapFilteringItems[it];
|
||
|
|
||
|
// skip this item if the tool cannot be applied to it
|
||
|
if ( bInToolSelection && !CEconSharedToolSupport::ToolCanApplyTo( &m_ToolSelectionItem, pItem ) )
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ( !DoesItemPassSearchFilter( pItem->GetDescription(), wszFilter ) )
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ( ++iItemBackpackPos != iPanelBackpackPos )
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
pItemData = pItem;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if ( bInToolSelection )
|
||
|
{
|
||
|
CPlayerInventory *pInventory = InventoryManager()->GetLocalInventory();
|
||
|
if ( pInventory )
|
||
|
{
|
||
|
// Backpack positions start from 1
|
||
|
Assert( iPanelBackpackPos > 0 && iPanelBackpackPos <= pInventory->GetMaxItemCount() );
|
||
|
int iStart = iIndex == 0 ? 0 : iLastMapItem + 1;
|
||
|
for ( int i = iStart; i < pInventory->GetItemCount(); i++ )
|
||
|
{
|
||
|
iLastMapItem = i;
|
||
|
|
||
|
CEconItemView *pItem = pInventory->GetItem(i);
|
||
|
|
||
|
if ( m_ToolSelectionItem.GetStaticData()->IsTool() )
|
||
|
{
|
||
|
if ( !CEconSharedToolSupport::ToolCanApplyTo( &m_ToolSelectionItem, pItem ) )
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( !pItem->GetStaticData()->IsTool() )
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ( !CEconSharedToolSupport::ToolCanApplyTo( pItem, &m_ToolSelectionItem ) )
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ( ( m_ToolSelectionItem.GetStaticData()->GetCapabilities() & ITEM_CAP_DECODABLE ) && pItem->GetStaticData()->GetEconTool() && ( Q_strcmp( pItem->GetStaticData()->GetEconTool()->GetTypeName(), "decoder_ring" ) != 0 ) )
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( ++iItemBackpackPos != iPanelBackpackPos )
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
pItemData = pItem;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pItemData = InventoryManager()->GetItemByBackpackPosition( iPanelBackpackPos );
|
||
|
iItemBackpackPos = iPanelBackpackPos;
|
||
|
|
||
|
if ( pItemData == NULL && pPanel->GetItem() == NULL )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
int nDirtyIndex = pItemData ? m_vecDirtyItems.Find( pItemData->GetItemID() ) : m_vecDirtyItems.InvalidIndex();
|
||
|
|
||
|
if ( pItemData // Want to put in an item
|
||
|
&& pPanel->GetItem() // Panel has an item
|
||
|
&& pItemData->GetItemID() == pPanel->GetItem()->GetItemID() // That panel has the same item that we want to put in
|
||
|
&& nDirtyIndex == m_vecDirtyItems.InvalidIndex() ) // And that item is not dirtied.
|
||
|
{
|
||
|
// We dont do anything
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( nDirtyIndex != m_vecDirtyItems.InvalidIndex() )
|
||
|
{
|
||
|
m_vecDirtyItems.Remove( nDirtyIndex );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( iItemBackpackPos != iPanelBackpackPos )
|
||
|
{
|
||
|
pItemData = NULL;
|
||
|
}
|
||
|
|
||
|
pPanel->SetItem( pItemData );
|
||
|
|
||
|
bool bSeen = true;
|
||
|
// Have we not seen this item before?
|
||
|
if ( !m_bShowBaseItems && pItemData && m_mapSeenItems.Find( pItemData->GetItemID() ) == m_mapSeenItems.InvalidIndex() )
|
||
|
{
|
||
|
bSeen = false;
|
||
|
}
|
||
|
|
||
|
// Show our "NEW!" label if this item hasnt been seen
|
||
|
CExLabel *pNewPanel = dynamic_cast< CExLabel* >( pPanel->FindChildByName( "New" ) );
|
||
|
if ( pNewPanel )
|
||
|
{
|
||
|
pNewPanel->SetVisible( !bSeen );
|
||
|
}
|
||
|
|
||
|
pPanel->DirtyDescription();
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::ClearNameFilter( bool bUpdateModelPanels )
|
||
|
{
|
||
|
if ( m_wNameFilter.Count() == 0 )
|
||
|
return;
|
||
|
|
||
|
m_wNameFilter.RemoveAll();
|
||
|
if( m_pNameFilterTextEntry )
|
||
|
{
|
||
|
m_pNameFilterTextEntry->SetText( "" );
|
||
|
}
|
||
|
|
||
|
if ( bUpdateModelPanels )
|
||
|
{
|
||
|
m_flFilterItemTime = gpGlobals->curtime + 0.1f;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::UpdateFilteringItems()
|
||
|
{
|
||
|
m_mapFilteringItems.RemoveAll();
|
||
|
|
||
|
if ( !HasNameFilter() )
|
||
|
return;
|
||
|
|
||
|
CPlayerInventory *pInventory = InventoryManager()->GetLocalInventory();
|
||
|
if ( !pInventory )
|
||
|
return;
|
||
|
|
||
|
for ( int i = 0; i < pInventory->GetItemCount(); i++ )
|
||
|
{
|
||
|
CEconItemView *pItem = pInventory->GetItem(i);
|
||
|
|
||
|
if ( pItem->GetItemDefinition()->IsHidden() )
|
||
|
continue;
|
||
|
|
||
|
int iBackpackPosition = InventoryManager()->GetBackpackPositionFromBackend( pItem->GetInventoryPosition() );
|
||
|
m_mapFilteringItems.Insert( iBackpackPosition, pItem );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::UpdateModelPanels( void )
|
||
|
{
|
||
|
tmZone( TELEMETRY_LEVEL1, TMZF_NONE, "%s", __FUNCTION__ );
|
||
|
|
||
|
UpdateFilteringItems();
|
||
|
|
||
|
// We're showing the backpack. Show all the items in our inventory
|
||
|
FOR_EACH_VEC( m_pItemModelPanels, i )
|
||
|
{
|
||
|
m_pItemModelPanels[i]->SetShowEquipped( true );
|
||
|
m_pItemModelPanels[i]->SetShowGreyedOutTooltip( true );
|
||
|
AssignItemToPanel( m_pItemModelPanels[i], i );
|
||
|
|
||
|
if ( !m_pItemModelPanels[i]->HasItem() && m_pItemModelPanels[i]->IsSelected() )
|
||
|
{
|
||
|
m_pItemModelPanels[i]->SetSelected( false );
|
||
|
}
|
||
|
|
||
|
SetBorderForItem( m_pItemModelPanels[i], false );
|
||
|
}
|
||
|
|
||
|
// Clean out. We just did all the heavy lifting.
|
||
|
m_vecDirtyItems.Purge();
|
||
|
|
||
|
if ( InToolSelectionMode() && m_ToolSelectionItem.IsValid() )
|
||
|
{
|
||
|
wchar_t wTemp[256];
|
||
|
g_pVGuiLocalize->ConstructString_safe( wTemp, g_pVGuiLocalize->Find( "BackpackApplyTool" ), 1, m_ToolSelectionItem.GetItemName() );
|
||
|
SetDialogVariable( "loadoutclass", wTemp );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetDialogVariable( "loadoutclass", g_pVGuiLocalize->Find( "BackpackTitle" ) );
|
||
|
}
|
||
|
|
||
|
char szTmp[16];
|
||
|
V_sprintf_safe( szTmp, "%d/%d", GetCurrentPage()+1, GetNumPages() );
|
||
|
SetDialogVariable( "backpackpage", szTmp );
|
||
|
|
||
|
// Now layout again to position our item buttons
|
||
|
InvalidateLayout();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Mark visited item model panels as seen
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnItemPanelEntered( vgui::Panel *panel )
|
||
|
{
|
||
|
if ( m_pContextMenu && m_pContextMenu->IsVisible() )
|
||
|
return;
|
||
|
|
||
|
CItemModelPanel *pItemPanel = dynamic_cast < CItemModelPanel * > ( panel );
|
||
|
if ( pItemPanel )
|
||
|
{
|
||
|
// Hide the "NEW!" label
|
||
|
CExLabel *pNewPanel = dynamic_cast< CExLabel* >( pItemPanel->FindChildByName( "New" ) );
|
||
|
if ( pNewPanel )
|
||
|
{
|
||
|
pNewPanel->SetVisible( false );
|
||
|
}
|
||
|
|
||
|
// Mark this item as "seen"
|
||
|
CEconItemView *pItem = pItemPanel->GetItem();
|
||
|
if ( pItem )
|
||
|
{
|
||
|
if ( m_mapSeenItems.Find( pItem->GetItemID() ) == m_mapSeenItems.InvalidIndex() )
|
||
|
{
|
||
|
m_mapSeenItems.Insert( pItem->GetItemID() );
|
||
|
SetPageButtonTextColorBasedOnContents();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BaseClass::OnItemPanelEntered( panel );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnItemPanelMousePressed( vgui::Panel *panel )
|
||
|
{
|
||
|
CItemModelPanel *pItemPanel = dynamic_cast < CItemModelPanel * > ( panel );
|
||
|
|
||
|
if ( pItemPanel && IsVisible() && pItemPanel->IsGreyedOut() == false && AllowDragging( pItemPanel ) )
|
||
|
{
|
||
|
m_flMouseDownTime = gpGlobals->curtime;
|
||
|
m_iMouseDownX = m_iMouseDownY = 0;
|
||
|
m_pItemDraggedFromPanel = pItemPanel;
|
||
|
m_iDraggedFromPage = GetCurrentPage();
|
||
|
m_bDragging = false;
|
||
|
m_bMouseDownOnItemPanel = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Handle the escape key since it doesn't show up in OnKeyCodePressed
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnKeyCodeTyped(vgui::KeyCode code)
|
||
|
{
|
||
|
if ( code == KEY_ESCAPE && InToolSelectionMode() )
|
||
|
{
|
||
|
CancelToolSelection();
|
||
|
}
|
||
|
else if ( code == KEY_ENTER )
|
||
|
{
|
||
|
// Do nothing. This gets hit frequently when people type in the filter
|
||
|
// text entry and then hit 'Enter', expecting it to execute the filter.
|
||
|
// We automatically apply it, so let's just eat 'Enter', which was causing
|
||
|
// us to activate some button on the main menu.
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
BaseClass::OnKeyCodeTyped( code );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Handles key press events in the backpack
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnKeyCodePressed( vgui::KeyCode code )
|
||
|
{
|
||
|
// Ignore key events while the confirm delete dialog is up
|
||
|
if( m_pConfirmDeleteDialog )
|
||
|
return;
|
||
|
|
||
|
// let our parent class handle all the arrow key/dpad stuff
|
||
|
if( HandleItemSelectionKeyPressed( code ) )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Handle close here, CBasePanel parent doesn't support "DialogClosing" command
|
||
|
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
|
||
|
|
||
|
if ( (nButtonCode == KEY_XBUTTON_B || nButtonCode == STEAMCONTROLLER_B) && InToolSelectionMode() )
|
||
|
{
|
||
|
CancelToolSelection();
|
||
|
}
|
||
|
else if( code == KEY_PAGEDOWN )
|
||
|
{
|
||
|
OnCommand( "nextpage" );
|
||
|
}
|
||
|
else if( code == KEY_PAGEUP )
|
||
|
{
|
||
|
OnCommand( "prevpage" );
|
||
|
}
|
||
|
else if ( ( nButtonCode == KEY_XBUTTON_A || code == KEY_ENTER || nButtonCode == STEAMCONTROLLER_A ) )
|
||
|
{
|
||
|
if( InToolSelectionMode() )
|
||
|
{
|
||
|
HandleToolItemSelection( GetFirstSelectedItem() );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
OpenContextMenu();
|
||
|
}
|
||
|
}
|
||
|
else if ( nButtonCode == KEY_XBUTTON_X || nButtonCode == STEAMCONTROLLER_X )
|
||
|
{
|
||
|
if( !InToolSelectionMode() )
|
||
|
{
|
||
|
OnCommand( "deleteitem" );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
BaseClass::OnKeyCodePressed( code );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Handles key press events in the backpack
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnKeyCodeReleased( vgui::KeyCode code )
|
||
|
{
|
||
|
if( ! HandleItemSelectionKeyReleased( code ) )
|
||
|
BaseClass::OnKeyCodeReleased( code );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnMouseCaptureLost( void )
|
||
|
{
|
||
|
if ( m_bDragging )
|
||
|
{
|
||
|
StopDrag( false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnMouseReleased(vgui::MouseCode code)
|
||
|
{
|
||
|
if ( code == MOUSE_LEFT )
|
||
|
{
|
||
|
if ( m_bDragging )
|
||
|
{
|
||
|
// When we're dragging, we have mouse capture, so the item panels aren't getting mouse input.
|
||
|
// We need to find out what item panel we're over, and let it know.
|
||
|
if ( m_pPrevDragOverItemPanel )
|
||
|
{
|
||
|
OnItemPanelMouseReleased( m_pPrevDragOverItemPanel );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
StopDrag( false );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BaseClass::OnMouseReleased( code );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnConfirmDelete( KeyValues *data )
|
||
|
{
|
||
|
// Delete all the selected item
|
||
|
if ( data )
|
||
|
{
|
||
|
int iConfirmed = data->GetInt( "confirmed", 0 );
|
||
|
if ( iConfirmed )
|
||
|
{
|
||
|
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
|
||
|
{
|
||
|
if ( m_pItemModelPanels[i]->IsSelected() && m_pItemModelPanels[i]->HasItem() )
|
||
|
{
|
||
|
EconUI()->Gamestats_ItemTransaction( IE_ITEM_DELETED, m_pItemModelPanels[i]->GetItem() );
|
||
|
InventoryManager()->DropItem( m_pItemModelPanels[i]->GetItem()->GetItemID() );
|
||
|
}
|
||
|
}
|
||
|
DeSelectAllBackpackItemPanels();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_pConfirmDeleteDialog = NULL;
|
||
|
|
||
|
// If we're embedded in the discard item panel, it needs to know we made room. Send a message to our parent that it can catch.
|
||
|
PostMessage( GetParent(), new KeyValues("ConfirmDlgResult", "confirmed", 2 ) );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnItemPanelMouseReleased( vgui::Panel *panel )
|
||
|
{
|
||
|
CItemModelPanel *pItemPanel = dynamic_cast < CItemModelPanel * > ( panel );
|
||
|
|
||
|
if ( pItemPanel && IsVisible() )
|
||
|
{
|
||
|
if ( InToolSelectionMode() )
|
||
|
{
|
||
|
// They're selecting the item they'd like to apply a tool to
|
||
|
HandleToolItemSelection( pItemPanel->GetItem() );
|
||
|
}
|
||
|
else if ( !m_bDragging )
|
||
|
{
|
||
|
// If they're not holding down ctrl, deselect all existing selections
|
||
|
if ( !vgui::input()->IsKeyDown(KEY_LCONTROL) && !vgui::input()->IsKeyDown(KEY_RCONTROL) )
|
||
|
{
|
||
|
DeSelectAllBackpackItemPanels();
|
||
|
}
|
||
|
|
||
|
// Quick clicks just select the item
|
||
|
ToggleSelectBackpackItemPanel( pItemPanel );
|
||
|
|
||
|
if ( pItemPanel->IsSelected() )
|
||
|
{
|
||
|
OpenContextMenu();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int iPanelIndex = GetBackpackPositionForPanel( pItemPanel );
|
||
|
if ( !CanDragTo(pItemPanel, iPanelIndex) )
|
||
|
{
|
||
|
StopDrag(false);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
StopDrag( true );
|
||
|
if ( (pItemPanel != m_pItemDraggedFromPanel || m_iDraggedFromPage != GetCurrentPage() ) && m_pMouseDragItemPanel->HasItem() )
|
||
|
{
|
||
|
HandleDragTo( pItemPanel, iPanelIndex );
|
||
|
}
|
||
|
else if ( m_iDraggedFromPage == GetCurrentPage() )
|
||
|
{
|
||
|
m_pItemDraggedFromPanel->SetItem( m_pMouseDragItemPanel->GetItem() );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_pItemDraggedFromPanel = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
bool GetDecodedByItemDefIndex( const CEconItemView *pItem, uint32 *pDecodedBy = NULL )
|
||
|
{
|
||
|
static CSchemaAttributeDefHandle pAttrDef_DecodedBy( "decoded by itemdefindex" );
|
||
|
|
||
|
if ( pDecodedBy )
|
||
|
{
|
||
|
return pItem->FindAttribute( pAttrDef_DecodedBy, pDecodedBy );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return pItem->FindAttribute( pAttrDef_DecodedBy );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CEconItemView* GetFirstCompatibleKeyForCrate( const CEconItemView *pItem )
|
||
|
{
|
||
|
// Check if we have any decoder rings that can be applied onto this
|
||
|
CPlayerInventory *pInv = InventoryManager()->GetLocalInventory();
|
||
|
Assert( pInv );
|
||
|
if ( pInv )
|
||
|
{
|
||
|
for ( int i = 0; i < pInv->GetItemCount(); ++i )
|
||
|
{
|
||
|
CEconItemView *pInvItem = pInv->GetItem( i );
|
||
|
|
||
|
if ( pInvItem->GetQuality() == AE_SELFMADE )
|
||
|
continue;
|
||
|
|
||
|
if ( pInvItem->GetStaticData()->IsTool() && CEconSharedToolSupport::ToolCanApplyTo( pInvItem, pItem ) && pInvItem->GetStaticData()->GetEconTool() && ( Q_strcmp( pInvItem->GetStaticData()->GetEconTool()->GetTypeName(), "decoder_ring" ) == 0 ) )
|
||
|
{
|
||
|
return pInvItem;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
bool CanInventoryItemsApplyTo( const CEconItemView *pItem )
|
||
|
{
|
||
|
// Check if we have any tools that can be applied onto this
|
||
|
CPlayerInventory *pInv = InventoryManager()->GetLocalInventory();
|
||
|
Assert( pInv );
|
||
|
if ( pInv )
|
||
|
{
|
||
|
for ( int i = 0 ; i < pInv->GetItemCount() ; ++i )
|
||
|
{
|
||
|
CEconItemView *pInvItem = pInv->GetItem( i );
|
||
|
if ( pInvItem->GetStaticData()->IsTool() && CEconSharedToolSupport::ToolCanApplyTo( pInvItem, pItem ) )
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CreateMarketPriceString( item_definition_index_t iDefIndex, wchar_t *pszString, int iBufferSize )
|
||
|
{
|
||
|
// Get Market Price
|
||
|
steam_market_gc_identifier_t ident;
|
||
|
ident.m_unDefIndex = iDefIndex;
|
||
|
ident.m_unQuality = AE_UNIQUE; // Get this from default item def?
|
||
|
|
||
|
const client_market_data_t *pClientMarketData = GetClientMarketData( ident );
|
||
|
if ( !pClientMarketData )
|
||
|
return false;
|
||
|
|
||
|
const ECurrency eCurrency = EconUI()->GetStorePanel()->GetCurrency();
|
||
|
|
||
|
// Set that price into the button
|
||
|
wchar_t pszCurrencyString[kLocalizedPriceSizeInChararacters];
|
||
|
MakeMoneyString( pszCurrencyString, ARRAYSIZE( pszCurrencyString ), pClientMarketData->m_unLowestPrice, eCurrency );
|
||
|
|
||
|
wchar_t pszConstructed[kLocalizedPriceSizeInChararacters];
|
||
|
g_pVGuiLocalize->ConstructString_safe( pszConstructed, g_pVGuiLocalize->Find( "#TF_MarketPrice" ), 1, pszCurrencyString );
|
||
|
|
||
|
// copy result;
|
||
|
V_wcsncpy( pszString, pszConstructed, iBufferSize );
|
||
|
return true;
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CreateStorePriceString( item_definition_index_t iDefIndex, wchar_t *pszString, int iBufferSize )
|
||
|
{
|
||
|
// Get Market Price
|
||
|
steam_market_gc_identifier_t ident;
|
||
|
ident.m_unDefIndex = iDefIndex;
|
||
|
ident.m_unQuality = AE_UNIQUE; // Get this from default item def?
|
||
|
|
||
|
// Get the price of the item
|
||
|
const econ_store_entry_t *pEntry = EconUI()->GetStorePanel()->GetPriceSheet()->GetEntry( iDefIndex );
|
||
|
if ( !pEntry )
|
||
|
return false;
|
||
|
|
||
|
const ECurrency eCurrency = EconUI()->GetStorePanel()->GetCurrency();
|
||
|
|
||
|
// Set that price into the button
|
||
|
wchar_t pszCurrencyString[kLocalizedPriceSizeInChararacters];
|
||
|
MakeMoneyString( pszCurrencyString, ARRAYSIZE( pszCurrencyString ), pEntry->GetCurrentPrice( eCurrency ), eCurrency );
|
||
|
|
||
|
wchar_t pszConstructed[kLocalizedPriceSizeInChararacters];
|
||
|
g_pVGuiLocalize->ConstructString_safe( pszConstructed, g_pVGuiLocalize->Find( "#TF_StorePrice" ), 1, pszCurrencyString );
|
||
|
|
||
|
// copy result;
|
||
|
V_wcsncpy( pszString, pszConstructed, iBufferSize );
|
||
|
return true;
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::AddCommerceSubmenus( Menu *pSubMenu, item_definition_index_t iItemDef, const char* pszActionFmt )
|
||
|
{
|
||
|
wchar_t wPriceListing[256];
|
||
|
// Store
|
||
|
if ( CreateStorePriceString( iItemDef, wPriceListing, sizeof( wPriceListing ) ) )
|
||
|
{
|
||
|
int nIndex = pSubMenu->AddMenuItem( "", new KeyValues( "Command", "command", CFmtStr( "%s%s%d", "store_", pszActionFmt, iItemDef ) ), this );
|
||
|
vgui::MenuItem *pMenuItem = pSubMenu->GetMenuItem( nIndex );
|
||
|
pMenuItem->SetText( wPriceListing );
|
||
|
pMenuItem->InvalidateLayout( true, false );
|
||
|
}
|
||
|
|
||
|
// Market
|
||
|
if ( CreateMarketPriceString( iItemDef, wPriceListing, sizeof( wPriceListing ) ) )
|
||
|
{
|
||
|
int nIndex = pSubMenu->AddMenuItem( "", new KeyValues( "Command", "command", CFmtStr( "%s%s%d", "market_", pszActionFmt, iItemDef ) ), this );
|
||
|
vgui::MenuItem *pMenuItem = pSubMenu->GetMenuItem( nIndex );
|
||
|
pMenuItem->SetText( wPriceListing );
|
||
|
pMenuItem->InvalidateLayout( true, false );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int nIndex = pSubMenu->AddMenuItem( "", new KeyValues( "Command", "command", CFmtStr( "%s%s%d", "market_", pszActionFmt, iItemDef ) ), this );
|
||
|
vgui::MenuItem *pMenuItem = pSubMenu->GetMenuItem( nIndex );
|
||
|
pMenuItem->SetText( g_pVGuiLocalize->Find( "#TF_MarketUnavailable" ) );
|
||
|
pMenuItem->InvalidateLayout( true, false );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::AddPaintToContextMenu( Menu *pPaintSubMenu, item_definition_index_t iPaintDef, bool bAddCommerce )
|
||
|
{
|
||
|
GameItemDefinition_t * pPaintCanDef = dynamic_cast<GameItemDefinition_t*>( GEconItemSchema().GetItemDefinition( iPaintDef ) );
|
||
|
if ( !pPaintCanDef )
|
||
|
return;
|
||
|
|
||
|
wchar_t wBuff[256];
|
||
|
char cBuff[256];
|
||
|
V_swprintf_safe( wBuff, L" %ls", g_pVGuiLocalize->Find( pPaintCanDef->GetItemBaseName() ) );
|
||
|
|
||
|
char szItemName[256];
|
||
|
g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( pPaintCanDef->GetItemBaseName() ), szItemName, sizeof( szItemName ) );
|
||
|
V_sprintf_safe( cBuff, " %s", szItemName );
|
||
|
|
||
|
uint32 unPaintRGB0 = 0;
|
||
|
uint32 unPaintRGB1 = 0;
|
||
|
|
||
|
static CSchemaAttributeDefHandle pAttrDef_PaintRGB( "set item tint RGB" );
|
||
|
static CSchemaAttributeDefHandle pAttrDef_PaintRGB2( "set item tint RGB 2" );
|
||
|
|
||
|
float fRGB = 0.0f;
|
||
|
|
||
|
if ( FindAttribute_UnsafeBitwiseCast<attrib_value_t>( pPaintCanDef, pAttrDef_PaintRGB, &fRGB ) && fRGB != 0.0f )
|
||
|
{
|
||
|
unPaintRGB0 = fRGB;
|
||
|
|
||
|
// We may or may not have a secondary paint color as well. If we don't, we just use the primary
|
||
|
// paint color to fill both slots.
|
||
|
if ( FindAttribute_UnsafeBitwiseCast<attrib_value_t>( pPaintCanDef, pAttrDef_PaintRGB2, &fRGB ) )
|
||
|
{
|
||
|
unPaintRGB1 = fRGB;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
unPaintRGB1 = unPaintRGB0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !bAddCommerce )
|
||
|
{
|
||
|
int nIndex = pPaintSubMenu->AddMenuItem( "", new KeyValues( "Command", "command", CFmtStr( "paint%d", iPaintDef ) ), this );
|
||
|
vgui::MenuItem *pMenuItem = pPaintSubMenu->GetMenuItem( nIndex );
|
||
|
pMenuItem->SetText( wBuff );
|
||
|
pMenuItem->InvalidateLayout( true, false );
|
||
|
|
||
|
CItemMaterialCustomizationIconPanel *pCustomPanel = new CItemMaterialCustomizationIconPanel( pMenuItem, "paint" );
|
||
|
pCustomPanel->SetZPos( -100 );
|
||
|
pCustomPanel->SetTall( 30 );
|
||
|
pCustomPanel->SetWide( 30 );
|
||
|
pCustomPanel->m_colPaintColors.AddToTail( Color( clamp( ( unPaintRGB0 & 0xFF0000 ) >> 16, 0, 255 ), clamp( ( unPaintRGB0 & 0xFF00 ) >> 8, 0, 255 ), clamp( ( unPaintRGB0 & 0xFF ), 0, 255 ), 255 ) );
|
||
|
pCustomPanel->m_colPaintColors.AddToTail( Color( clamp( ( unPaintRGB1 & 0xFF0000 ) >> 16, 0, 255 ), clamp( ( unPaintRGB1 & 0xFF00 ) >> 8, 0, 255 ), clamp( ( unPaintRGB1 & 0xFF ), 0, 255 ), 255 ) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
const char *pszContextMenuBorder = "NotificationDefault";
|
||
|
const char *pszContextMenuFont = "HudFontMediumSecondary";
|
||
|
|
||
|
Menu *pSubMenu = new Menu( this, "PaintSubMenu" );
|
||
|
pSubMenu->SetBorder( scheme()->GetIScheme( GetScheme() )->GetBorder( pszContextMenuBorder ) );
|
||
|
pSubMenu->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( pszContextMenuFont ) );
|
||
|
int iPos = pPaintSubMenu->AddCascadingMenuItem( cBuff, this, pSubMenu );
|
||
|
|
||
|
CItemMaterialCustomizationIconPanel *pCustomPanel = new CItemMaterialCustomizationIconPanel( pPaintSubMenu, "paint" );
|
||
|
pCustomPanel->SetZPos( 100 );
|
||
|
pCustomPanel->SetPos( 0, iPos * pPaintSubMenu->GetMenuItemHeight() );
|
||
|
pCustomPanel->SetTall( 30 );
|
||
|
pCustomPanel->SetWide( 30 );
|
||
|
pCustomPanel->m_colPaintColors.AddToTail( Color( clamp( ( unPaintRGB0 & 0xFF0000 ) >> 16, 0, 255 ), clamp( ( unPaintRGB0 & 0xFF00 ) >> 8, 0, 255 ), clamp( ( unPaintRGB0 & 0xFF ), 0, 255 ), 255 ) );
|
||
|
pCustomPanel->m_colPaintColors.AddToTail( Color( clamp( ( unPaintRGB1 & 0xFF0000 ) >> 16, 0, 255 ), clamp( ( unPaintRGB1 & 0xFF00 ) >> 8, 0, 255 ), clamp( ( unPaintRGB1 & 0xFF ), 0, 255 ), 255 ) );
|
||
|
|
||
|
AddCommerceSubmenus( pSubMenu, iPaintDef, "paint" );
|
||
|
}
|
||
|
}
|
||
|
//
|
||
|
// Add commerce context options for an item. Adds 'Store' and 'Market' options if appropriate (and Pricing) other wise just click to use
|
||
|
//
|
||
|
void CBackpackPanel::AddCommerceToContextMenu( Menu *pMenu, const char* pszActionFmt, item_definition_index_t iItemDefIndex, bool bAddMarket, bool bAddStore )
|
||
|
{
|
||
|
GameItemDefinition_t * pItemDef = dynamic_cast<GameItemDefinition_t*>( GEconItemSchema().GetItemDefinition( iItemDefIndex ) );
|
||
|
if ( !pItemDef )
|
||
|
return;
|
||
|
|
||
|
//
|
||
|
if ( !bAddMarket && !bAddStore )
|
||
|
{
|
||
|
int nIndex = pMenu->AddMenuItem( "", new KeyValues( "Command", "command", CFmtStr( "%s%d", pszActionFmt, iItemDefIndex ) ), this );
|
||
|
vgui::MenuItem *pMenuItem = pMenu->GetMenuItem( nIndex );
|
||
|
pMenuItem->SetText( g_pVGuiLocalize->Find( pItemDef->GetItemBaseName() ) );
|
||
|
pMenuItem->InvalidateLayout( true, false );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
const char *pszContextMenuBorder = "NotificationDefault";
|
||
|
const char *pszContextMenuFont = "HudFontMediumSecondary";
|
||
|
|
||
|
Menu *pSubMenu = new Menu( this, "CommerceSubMenu" );
|
||
|
pSubMenu->SetBorder( scheme()->GetIScheme( GetScheme() )->GetBorder( pszContextMenuBorder ) );
|
||
|
pSubMenu->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( pszContextMenuFont ) );
|
||
|
pMenu->AddCascadingMenuItem( pItemDef->GetItemBaseName(), this, pSubMenu );
|
||
|
|
||
|
AddCommerceSubmenus( pSubMenu, iItemDefIndex, pszActionFmt );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Opens a context menu with actions relevant for the passed in item
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OpenContextMenu()
|
||
|
{
|
||
|
CUtlVector<CEconItemView*> vecSelectedItems;
|
||
|
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
|
||
|
{
|
||
|
if ( m_pItemModelPanels[i]->IsSelected() && m_pItemModelPanels[i]->GetItem() )
|
||
|
{
|
||
|
vecSelectedItems.AddToTail( m_pItemModelPanels[i]->GetItem() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( m_pContextMenu )
|
||
|
delete m_pContextMenu;
|
||
|
|
||
|
m_pContextMenu = new Menu( this, "ContextMenu" );
|
||
|
MenuBuilder contextMenuBuilder( m_pContextMenu, this );
|
||
|
const char *pszContextMenuBorder = "NotificationDefault";
|
||
|
const char *pszContextMenuFont = "HudFontMediumSecondary";
|
||
|
m_pContextMenu->SetBorder( scheme()->GetIScheme( GetScheme() )->GetBorder( pszContextMenuBorder ) );
|
||
|
m_pContextMenu->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( pszContextMenuFont ) );
|
||
|
|
||
|
if ( vecSelectedItems.Count() == 1 )
|
||
|
{
|
||
|
const CEconItemView *pItem = vecSelectedItems.Head();
|
||
|
const CTFItemDefinition *pItemDef = pItem->GetStaticData();
|
||
|
static CSchemaItemDefHandle DuckBadgeItemDef( "Duck Badge" );
|
||
|
static CSchemaItemDefHandle StrangeCountTransferItemDef( "Strange Count Transfer Tool" );
|
||
|
|
||
|
// Tools of any kind can't be used if they are in escrow.
|
||
|
static CSchemaAttributeDefHandle pAttrib_ToolEscrowUntil( "tool escrow until date" );
|
||
|
uint32 unEscrowTime;
|
||
|
const bool bToolIsInEscrow = pItem->FindAttribute( pAttrib_ToolEscrowUntil, &unEscrowTime )
|
||
|
&& unEscrowTime > CRTime::RTime32TimeCur();
|
||
|
|
||
|
const IEconTool *pEconTool = pItem->GetItemDefinition()->GetEconTool();
|
||
|
|
||
|
const bool bIsTool = pItem->GetStaticData()->IsTool() && (pEconTool != NULL);
|
||
|
const bool bIsGCConsumable = ( ( pItem->GetStaticData()->GetCapabilities() & ITEM_CAP_USABLE_GC ) != 0 );
|
||
|
bool bSkipAddTrade = false; // Hack: We should really ask the tool if the command supplants trade.
|
||
|
|
||
|
// Tool usage goes first. The cursor starts on this element, so double-clicks will work like how they used to.
|
||
|
// Strange Count Transfer
|
||
|
if ( StrangeCountTransferItemDef == pItem->GetItemDefinition() )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#ApplyOnItem", new KeyValues( "Context_OpenStrangeCountTransfer" ), "primaryaction" );
|
||
|
}
|
||
|
else if ( pItem->GetStaticData()->IsTool() && pEconTool == NULL )
|
||
|
{
|
||
|
// do nothing. not a real tool (basic balloons with color that we don't want to 'remove' the paint)
|
||
|
}
|
||
|
else if ( (bIsTool || bIsGCConsumable) && !bToolIsInEscrow && pEconTool->CanBeUsedNow( pItem ) )
|
||
|
{
|
||
|
Assert( pEconTool );
|
||
|
|
||
|
const int nTokens = pEconTool->GetUseCommandCount( pItem );
|
||
|
for ( int i = 0; i < nTokens; ++i )
|
||
|
{
|
||
|
const char *pszToolUsageString = pEconTool->GetUseCommandLocalizationToken( pItem, i );
|
||
|
|
||
|
// If we didn't have a custom usage string, fall back to a sane default based on whether or
|
||
|
// not we're a consumable or not.
|
||
|
if ( !pszToolUsageString )
|
||
|
{
|
||
|
pszToolUsageString = bIsGCConsumable ? "#ConsumeItem" : "#ApplyOnItem";
|
||
|
}
|
||
|
|
||
|
const char *pszContext = pEconTool->GetUseCommand( pItem, i );
|
||
|
contextMenuBuilder.AddMenuItem( pszToolUsageString, new KeyValues( pszContext ), "primaryaction" );
|
||
|
}
|
||
|
|
||
|
// Hack: We should really ask the tool if the command supplants trade. For now, if we have two
|
||
|
// things, then one of them is trade, so skip it.
|
||
|
bSkipAddTrade = nTokens > 1;
|
||
|
}
|
||
|
else if ( pItem->GetItemDefinition()->GetCapabilities() & ITEM_CAP_DECODABLE )
|
||
|
{
|
||
|
|
||
|
static CSchemaAttributeDefHandle pAttrDef_CanShuffleCrateContents( "can shuffle crate contents" );
|
||
|
|
||
|
if ( pItem->FindAttribute( pAttrDef_CanShuffleCrateContents ) )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#ShuffleContents", new KeyValues( "Context_Shuffle" ), "primaryaction" );
|
||
|
}
|
||
|
|
||
|
if ( GetFirstCompatibleKeyForCrate( pItem ) != NULL )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#UseKey", new KeyValues( "Context_OpenCrateWithKey" ), "primaryaction" );
|
||
|
}
|
||
|
|
||
|
if ( GetDecodedByItemDefIndex( pItem ) )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#GetKey", new KeyValues( "Context_GetItemFromStore" ), "primaryaction" );
|
||
|
contextMenuBuilder.AddMenuItem( "#BuyAndUseKey", new KeyValues( "Context_BuyKeyAndOpenCrate" ), "primaryaction" );
|
||
|
}
|
||
|
}
|
||
|
else if ( pItem->GetItemDefinition()->GetCapabilities() & ITEM_CAP_HAS_SLOTS )
|
||
|
{
|
||
|
// check if we have at least 1 slot criteria
|
||
|
static CSchemaAttributeDefHandle pAttrDef_Slot( "item slot criteria 1" );
|
||
|
if ( pItem->FindAttribute( pAttrDef_Slot ) )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#EditSlots", new KeyValues( "Context_EditSlot" ), "primaryaction" );
|
||
|
}
|
||
|
}
|
||
|
else if ( DuckBadgeItemDef == pItem->GetItemDefinition() )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#Duck_ViewLeaderboards", new KeyValues( "Context_OpenDuckLeaderboards" ), "primaryaction" );
|
||
|
|
||
|
if ( CanInventoryItemsApplyTo( pItem ) )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#UseDuckToken", new KeyValues( "Context_ApplyByItem" ), "primaryaction" );
|
||
|
}
|
||
|
|
||
|
if ( GetDecodedByItemDefIndex( pItem ) )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#GetDuckToken", new KeyValues( "Context_GetItemFromStore" ), "primaryaction" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 3D Inspect
|
||
|
float flInspect = 0;
|
||
|
static CSchemaAttributeDefHandle pAttrib_WeaponAllowInspect( "weapon_allow_inspect" );
|
||
|
static CSchemaAttributeDefHandle pAttrib_CosmeticAllowInspect( "cosmetic_allow_inspect" );
|
||
|
if ( pItem && pItem->IsValid() &&
|
||
|
( FindAttribute_UnsafeBitwiseCast<attrib_value_t>( pItem, pAttrib_WeaponAllowInspect, &flInspect ) || FindAttribute_UnsafeBitwiseCast<attrib_value_t>( pItem, pAttrib_CosmeticAllowInspect, &flInspect )
|
||
|
#ifdef STAGING_ONLY
|
||
|
|| tf_weapon_force_allow_inspect.GetBool()
|
||
|
#endif
|
||
|
) )
|
||
|
{
|
||
|
if ( flInspect != 0
|
||
|
#ifdef STAGING_ONLY
|
||
|
|| tf_weapon_force_allow_inspect.GetBool()
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#Context_InspectModel", new KeyValues( "Context_InspectModel" ), "primaryaction" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Add equip sub menu
|
||
|
{
|
||
|
Menu *pEquipSubMenu = NULL;
|
||
|
for ( int iClass = TF_FIRST_NORMAL_CLASS; iClass < TF_LAST_NORMAL_CLASS; iClass++ )
|
||
|
{
|
||
|
if ( !pItemDef->CanBeUsedByClass( iClass ) )
|
||
|
continue;
|
||
|
|
||
|
if ( pEquipSubMenu == NULL )
|
||
|
{
|
||
|
pEquipSubMenu = new Menu( this, "EquipMenu" );
|
||
|
pEquipSubMenu->SetBorder( scheme()->GetIScheme( GetScheme() )->GetBorder( pszContextMenuBorder ) );
|
||
|
pEquipSubMenu->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( pszContextMenuFont ) );
|
||
|
|
||
|
contextMenuBuilder.AddCascadingMenuItem( "#Context_Equip", pEquipSubMenu, "primaryaction" );
|
||
|
}
|
||
|
|
||
|
const char *pszClassName = NULL;
|
||
|
switch ( iClass )
|
||
|
{
|
||
|
case TF_CLASS_SCOUT: pszClassName = "#TF_Class_Name_Scout"; break;
|
||
|
case TF_CLASS_SNIPER: pszClassName = "#TF_Class_Name_Sniper"; break;
|
||
|
case TF_CLASS_SOLDIER: pszClassName = "#TF_Class_Name_Soldier"; break;
|
||
|
case TF_CLASS_DEMOMAN: pszClassName = "#TF_Class_Name_Demoman"; break;
|
||
|
case TF_CLASS_MEDIC: pszClassName = "#TF_Class_Name_Medic"; break;
|
||
|
case TF_CLASS_HEAVYWEAPONS: pszClassName = "#TF_Class_Name_HWGuy"; break;
|
||
|
case TF_CLASS_PYRO: pszClassName = "#TF_Class_Name_Pyro"; break;
|
||
|
case TF_CLASS_SPY: pszClassName = "#TF_Class_Name_Spy"; break;
|
||
|
case TF_CLASS_ENGINEER: pszClassName = "#TF_Class_Name_Engineer"; break;
|
||
|
}
|
||
|
|
||
|
pEquipSubMenu->AddMenuItem( pszClassName, new KeyValues( "Command", "command", CFmtStr( "equipclass%d", iClass ) ), this );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// For customizable items only
|
||
|
if ( !pItem->IsTemporaryItem() )
|
||
|
{
|
||
|
bool bCanCraftUp = GetCollectionCraftingInvalidReason(pItem, NULL) == NULL;
|
||
|
bool bCanStatClockTrade = GetCraftCommonStatClockInvalidReason(pItem, NULL) == NULL;
|
||
|
Menu *pMannCoTradeSubMenu = NULL;
|
||
|
|
||
|
if ( bCanCraftUp || bCanStatClockTrade )
|
||
|
{
|
||
|
pMannCoTradeSubMenu = new Menu(this, "MannCoTradeSubMenu");
|
||
|
pMannCoTradeSubMenu->SetBorder(scheme()->GetIScheme(GetScheme())->GetBorder(pszContextMenuBorder));
|
||
|
pMannCoTradeSubMenu->SetFont(scheme()->GetIScheme(GetScheme())->GetFont(pszContextMenuFont));
|
||
|
contextMenuBuilder.AddCascadingMenuItem("#Context_MannCoTrade", pMannCoTradeSubMenu, "customization");
|
||
|
|
||
|
if ( bCanCraftUp )
|
||
|
{
|
||
|
int nIndex = pMannCoTradeSubMenu->AddMenuItem("", new KeyValues("Command", "command", "Context_CraftUpCollection"), this);
|
||
|
vgui::MenuItem *pMenuItem = pMannCoTradeSubMenu->GetMenuItem(nIndex);
|
||
|
pMenuItem->SetText("#Context_TradeUp");
|
||
|
pMenuItem->InvalidateLayout(true, false);
|
||
|
}
|
||
|
|
||
|
if ( bCanStatClockTrade )
|
||
|
{
|
||
|
int nIndex = pMannCoTradeSubMenu->AddMenuItem("", new KeyValues("Command", "command", "Context_CraftCommonStatClock"), this);
|
||
|
vgui::MenuItem *pMenuItem = pMannCoTradeSubMenu->GetMenuItem(nIndex);
|
||
|
pMenuItem->SetText("#Context_CommonStatClock");
|
||
|
pMenuItem->InvalidateLayout(true, false);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// Campaign coin access trades
|
||
|
static CSchemaAttributeDefHandle pAttrDef_IsOperationPass( "is_operation_pass" );
|
||
|
if ( pItem->FindAttribute( pAttrDef_IsOperationPass ) )
|
||
|
{
|
||
|
Menu *pMannCoCoinTradeSubMenu = new Menu( this, "MannCoTradeSubMenu" );
|
||
|
pMannCoCoinTradeSubMenu->SetBorder( scheme()->GetIScheme( GetScheme() )->GetBorder( pszContextMenuBorder ) );
|
||
|
pMannCoCoinTradeSubMenu->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( pszContextMenuFont ) );
|
||
|
contextMenuBuilder.AddCascadingMenuItem( "#Context_MannCoTrade", pMannCoCoinTradeSubMenu, "customization" );
|
||
|
|
||
|
int nIndex = pMannCoCoinTradeSubMenu->AddMenuItem( "", new KeyValues( "Command", "command", "Context_CraftUpCollection" ), this );
|
||
|
vgui::MenuItem *pMenuItem = pMannCoCoinTradeSubMenu->GetMenuItem( nIndex );
|
||
|
pMenuItem->SetText( "#Context_TradeUp" );
|
||
|
pMenuItem->InvalidateLayout( true, false );
|
||
|
|
||
|
nIndex = pMannCoCoinTradeSubMenu->AddMenuItem("", new KeyValues("Command", "command", "Context_CraftCommonStatClock"), this);
|
||
|
pMenuItem = pMannCoCoinTradeSubMenu->GetMenuItem(nIndex);
|
||
|
pMenuItem->SetText("#Context_CommonStatClock");
|
||
|
pMenuItem->InvalidateLayout(true, false);
|
||
|
}
|
||
|
|
||
|
// Halloween trade up offering.
|
||
|
// Needs two attrs
|
||
|
static CSchemaAttributeDefHandle pAttrDef_HalloweenOffering( "allow_halloween_offering" );
|
||
|
static CSchemaAttributeDefHandle pAttrDef_DeactiveDate( "deactive date" );
|
||
|
|
||
|
// Check the date
|
||
|
uint32 unDeactiveDate = 0;
|
||
|
uint32 unCurrentDate = CRTime::RTime32TimeCur();
|
||
|
if ( pAttrDef_HalloweenOffering && pItem->FindAttribute( pAttrDef_HalloweenOffering ) && pItem->FindAttribute( pAttrDef_DeactiveDate, &unDeactiveDate ) && unDeactiveDate > unCurrentDate )
|
||
|
{
|
||
|
vgui::MenuItem *pMenuItem = contextMenuBuilder.AddMenuItem( "#Context_HalloweenOffering", new KeyValues( "Context_HalloweenOffering" ), "customization" );
|
||
|
|
||
|
ImagePanel *pNewImage = new ImagePanel( pMenuItem, "new" );
|
||
|
pNewImage->SetZPos( 100 );
|
||
|
pNewImage->SetWide( 40 );
|
||
|
pNewImage->SetTall( 40 );
|
||
|
pNewImage->SetPos( 220, -5 );
|
||
|
pNewImage->SetMouseInputEnabled( false );
|
||
|
pNewImage->SetShouldScaleImage( true );
|
||
|
pNewImage->SetImage( "new" );
|
||
|
}
|
||
|
|
||
|
// Change name
|
||
|
GameItemDefinition_t * pNameTagDef = dynamic_cast<GameItemDefinition_t*>( GEconItemSchema().GetItemDefinitionByName( "Name Tag" ) );
|
||
|
if ( CEconSharedToolSupport::ToolCanApplyToDefinition( dynamic_cast<const GameItemDefinition_t *>( pNameTagDef ), pItemDef ) )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#Context_Rename", new KeyValues( "DoRename" ), "customization" );
|
||
|
}
|
||
|
|
||
|
// Change description
|
||
|
GameItemDefinition_t * pDescTagDef = dynamic_cast<GameItemDefinition_t*>( GEconItemSchema().GetItemDefinitionByName( "Description Tag" ) );
|
||
|
if ( CEconSharedToolSupport::ToolCanApplyToDefinition( dynamic_cast<const GameItemDefinition_t *>( pDescTagDef ), pItemDef ) )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#Context_Description", new KeyValues( "DoDescription" ), "customization" );
|
||
|
}
|
||
|
|
||
|
// Add paint options sub menu
|
||
|
if ( m_vecPaintCans.Count() > 0 )
|
||
|
{
|
||
|
GameItemDefinition_t * pPaintCanDef = dynamic_cast<GameItemDefinition_t*>( GEconItemSchema().GetItemDefinition( m_vecPaintCans[0] ) );
|
||
|
if ( pPaintCanDef && CEconSharedToolSupport::ToolCanApplyToDefinition( dynamic_cast<const GameItemDefinition_t *>( pPaintCanDef ), pItemDef ) )
|
||
|
{
|
||
|
Menu *pPaintSubMenu = NULL;
|
||
|
pPaintSubMenu = new Menu( this, "PaintSubMenu" );
|
||
|
pPaintSubMenu->SetBorder( scheme()->GetIScheme( GetScheme() )->GetBorder( pszContextMenuBorder ) );
|
||
|
pPaintSubMenu->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( pszContextMenuFont ) );
|
||
|
contextMenuBuilder.AddCascadingMenuItem( "#Context_Paint", pPaintSubMenu, "customization" );
|
||
|
|
||
|
CUtlVector<item_definition_index_t> vecOwnedPaints;
|
||
|
CUtlVector<item_definition_index_t> vecStorePaints;
|
||
|
|
||
|
// Find out if the user owns this item or not and place in the proper bucket
|
||
|
CPlayerInventory *pLocalInv = TFInventoryManager()->GetLocalInventory();
|
||
|
|
||
|
FOR_EACH_VEC( m_vecPaintCans, i )
|
||
|
{
|
||
|
if ( pLocalInv && pLocalInv->FindFirstItembyItemDef( m_vecPaintCans[i] ) )
|
||
|
{
|
||
|
vecOwnedPaints.AddToTail( m_vecPaintCans[i] );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
vecStorePaints.AddToTail( m_vecPaintCans[i] );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( vecOwnedPaints.Count() > 0 )
|
||
|
{
|
||
|
// Add Header and loop
|
||
|
int nIndex = pPaintSubMenu->AddMenuItem( "", new KeyValues( "Command", "command", "" ), this );
|
||
|
vgui::MenuItem *pMenuItem = pPaintSubMenu->GetMenuItem( nIndex );
|
||
|
pMenuItem->SetText( g_pVGuiLocalize->Find( "#TF_Owned" ) );
|
||
|
pMenuItem->InvalidateLayout( true, false );
|
||
|
|
||
|
FOR_EACH_VEC( vecOwnedPaints, i )
|
||
|
{
|
||
|
AddPaintToContextMenu( pPaintSubMenu, vecOwnedPaints[i], false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pPaintSubMenu->AddSeparator();
|
||
|
if ( vecStorePaints.Count() > 0 )
|
||
|
{
|
||
|
// Add Header and loop
|
||
|
int nIndex = pPaintSubMenu->AddMenuItem( "", new KeyValues( "Command", "command", "" ), this );
|
||
|
vgui::MenuItem *pMenuItem = pPaintSubMenu->GetMenuItem( nIndex );
|
||
|
pMenuItem->SetText( g_pVGuiLocalize->Find( "#TF_Commerce" ) );
|
||
|
pMenuItem->InvalidateLayout( true, false );
|
||
|
|
||
|
FOR_EACH_VEC( vecStorePaints, i )
|
||
|
{
|
||
|
AddPaintToContextMenu( pPaintSubMenu, vecStorePaints[i], true );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Strange Parts
|
||
|
if ( BIsItemStrange( pItem ) )
|
||
|
{
|
||
|
Menu *pStrangePartsSubMenu = NULL;
|
||
|
CUtlVector<item_definition_index_t> vecOwnedParts;
|
||
|
CUtlVector<item_definition_index_t> vecStoreParts;
|
||
|
|
||
|
// Find out if the user owns this item or not and place in the proper bucket
|
||
|
CPlayerInventory *pLocalInv = TFInventoryManager()->GetLocalInventory();
|
||
|
FOR_EACH_VEC( m_vecStrangeParts, i )
|
||
|
{
|
||
|
// Determine if this can be applied
|
||
|
//GameItemDefinition_t *pStrangePartDef = dynamic_cast<GameItemDefinition_t*>( GEconItemSchema().GetItemDefinition( m_vecStrangeParts[i] ) );
|
||
|
CEconItemView partItemView;
|
||
|
partItemView.Init( m_vecStrangeParts[i], AE_USE_SCRIPT_VALUE, 1 );
|
||
|
if ( CEconSharedToolSupport::ToolCanApplyTo( &partItemView, pItem ) )
|
||
|
{
|
||
|
// Create menu
|
||
|
if ( !pStrangePartsSubMenu )
|
||
|
{
|
||
|
pStrangePartsSubMenu = new Menu( this, "StrangePartsSubMenu" );
|
||
|
pStrangePartsSubMenu->SetBorder( scheme()->GetIScheme( GetScheme() )->GetBorder( pszContextMenuBorder ) );
|
||
|
pStrangePartsSubMenu->SetFont( scheme()->GetIScheme( GetScheme() )->GetFont( pszContextMenuFont ) );
|
||
|
contextMenuBuilder.AddCascadingMenuItem( "#Context_StrangeParts", pStrangePartsSubMenu, "customization" );
|
||
|
}
|
||
|
|
||
|
if ( pLocalInv && pLocalInv->FindFirstItembyItemDef( m_vecStrangeParts[i] ) )
|
||
|
{
|
||
|
vecOwnedParts.AddToTail( m_vecStrangeParts[i] );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
vecStoreParts.AddToTail( m_vecStrangeParts[i] );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( pStrangePartsSubMenu )
|
||
|
{
|
||
|
if ( vecOwnedParts.Count() > 0 )
|
||
|
{
|
||
|
// Add Header and loop
|
||
|
int nIndex = pStrangePartsSubMenu->AddMenuItem( "", new KeyValues( "Command", "command", "" ), this );
|
||
|
vgui::MenuItem *pMenuItem = pStrangePartsSubMenu->GetMenuItem( nIndex );
|
||
|
pMenuItem->SetText( g_pVGuiLocalize->Find( "#TF_Owned" ) );
|
||
|
pMenuItem->InvalidateLayout( true, false );
|
||
|
|
||
|
FOR_EACH_VEC( vecOwnedParts, i )
|
||
|
{
|
||
|
AddCommerceToContextMenu( pStrangePartsSubMenu, "strangepart_", vecOwnedParts[i], false, false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pStrangePartsSubMenu->AddSeparator();
|
||
|
if ( vecStoreParts.Count() > 0 )
|
||
|
{
|
||
|
// Add Header and loop
|
||
|
int nIndex = pStrangePartsSubMenu->AddMenuItem( "", new KeyValues( "Command", "command", "" ), this );
|
||
|
vgui::MenuItem *pMenuItem = pStrangePartsSubMenu->GetMenuItem( nIndex );
|
||
|
pMenuItem->SetText( g_pVGuiLocalize->Find( "#TF_Market" ) );
|
||
|
pMenuItem->InvalidateLayout( true, false );
|
||
|
|
||
|
FOR_EACH_VEC( vecStoreParts, i )
|
||
|
{
|
||
|
AddCommerceToContextMenu( pStrangePartsSubMenu, "strangepart_", vecStoreParts[i], true, false );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( pItem->IsMarketable() )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#Context_MarketPlaceSell", new KeyValues( "DoSellMarketplace" ), "economy" );
|
||
|
}
|
||
|
|
||
|
// Trade to another player
|
||
|
if ( pItem->IsTradable() && !bSkipAddTrade )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#Context_Trade", new KeyValues( "DoTradeToPlayer" ), "economy" );
|
||
|
}
|
||
|
|
||
|
if ( pItem->GetItemDefinition()->GetCapabilities() & ITEM_CAP_CAN_BE_RESTORED )
|
||
|
{
|
||
|
if ( RemovableAttributes_DoAnyAttributesApply( pItem ) )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#RefurbishItem", new KeyValues( "Context_RefurbishItem" ), "destructive" );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Check if ALL selected items can be crafted together
|
||
|
bool bCanCraftUp = true;
|
||
|
for( int i=0; i < COLLECTION_CRAFTING_ITEM_COUNT && i < vecSelectedItems.Count(); ++i )
|
||
|
{
|
||
|
CEconItemView* pPrevItem = ( i - 1 ) < 0 ? NULL : vecSelectedItems[ i - 1 ];
|
||
|
bCanCraftUp &= GetCollectionCraftingInvalidReason( vecSelectedItems[ i ], pPrevItem ) == NULL;
|
||
|
}
|
||
|
|
||
|
bool bCanStatClockTrade = true;
|
||
|
for (int i = 0; i < COLLECTION_CRAFTING_ITEM_COUNT && i < vecSelectedItems.Count(); ++i)
|
||
|
{
|
||
|
CEconItemView* pPrevItem = (i - 1) < 0 ? NULL : vecSelectedItems[i - 1];
|
||
|
bCanStatClockTrade &= GetCraftCommonStatClockInvalidReason(vecSelectedItems[i], pPrevItem) == NULL;
|
||
|
}
|
||
|
|
||
|
Menu *pMannCoTradeSubMenu = NULL;
|
||
|
|
||
|
if ( bCanCraftUp || bCanStatClockTrade )
|
||
|
{
|
||
|
pMannCoTradeSubMenu = new Menu(this, "MannCoTradeSubMenu");
|
||
|
pMannCoTradeSubMenu->SetBorder(scheme()->GetIScheme(GetScheme())->GetBorder(pszContextMenuBorder));
|
||
|
pMannCoTradeSubMenu->SetFont(scheme()->GetIScheme(GetScheme())->GetFont(pszContextMenuFont));
|
||
|
contextMenuBuilder.AddCascadingMenuItem("#Context_MannCoTrade", pMannCoTradeSubMenu, "customization");
|
||
|
|
||
|
if (bCanCraftUp)
|
||
|
{
|
||
|
int nIndex = pMannCoTradeSubMenu->AddMenuItem("", new KeyValues("Command", "command", "Context_CraftUpCollection"), this);
|
||
|
vgui::MenuItem *pMenuItem = pMannCoTradeSubMenu->GetMenuItem(nIndex);
|
||
|
pMenuItem->SetText("#Context_TradeUp");
|
||
|
pMenuItem->InvalidateLayout(true, false);
|
||
|
}
|
||
|
|
||
|
if (bCanStatClockTrade)
|
||
|
{
|
||
|
int nIndex = pMannCoTradeSubMenu->AddMenuItem("", new KeyValues("Command", "command", "Context_CraftCommonStatClock"), this);
|
||
|
vgui::MenuItem *pMenuItem = pMannCoTradeSubMenu->GetMenuItem(nIndex);
|
||
|
pMenuItem->SetText("#Context_CommonStatClock");
|
||
|
pMenuItem->InvalidateLayout(true, false);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !m_bShowBaseItems )
|
||
|
{
|
||
|
bool bDeleteAvailable = true;
|
||
|
// Check that all of the selected items are deletable
|
||
|
for( int i=0; i < vecSelectedItems.Count() && bDeleteAvailable; ++i )
|
||
|
{
|
||
|
static CSchemaAttributeDefHandle pAttrDef_NoDelete( "cannot delete" );
|
||
|
bDeleteAvailable &= !vecSelectedItems[i]->FindAttribute( pAttrDef_NoDelete );
|
||
|
}
|
||
|
|
||
|
// Only show the delete button if every slected item is deletable
|
||
|
if ( bDeleteAvailable )
|
||
|
{
|
||
|
contextMenuBuilder.AddMenuItem( "#TF_SteamWorkshop_Delete", new KeyValues( "DoDelete" ), "destructive" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Position to the cursor's position
|
||
|
int nX, nY;
|
||
|
g_pVGuiInput->GetCursorPosition( nX, nY );
|
||
|
m_pContextMenu->SetPos( nX - 1, nY - 1 );
|
||
|
|
||
|
m_pContextMenu->SetVisible(true);
|
||
|
m_pContextMenu->AddActionSignalTarget(this);
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnItemPanelMouseRightRelease( vgui::Panel *panel )
|
||
|
{
|
||
|
#ifdef STAGING_ONLY
|
||
|
if ( tf_use_card_tooltips.GetBool() )
|
||
|
{
|
||
|
m_pMouseOverCardPanel->PinCard( true );
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
{
|
||
|
CItemModelPanel *pItemPanel = dynamic_cast < CItemModelPanel * > ( panel );
|
||
|
if ( pItemPanel && pItemPanel->IsVisible() )
|
||
|
{
|
||
|
// If they're not holding down ctrl, deselect all existing selections
|
||
|
if ( !vgui::input()->IsKeyDown(KEY_LCONTROL) && !vgui::input()->IsKeyDown(KEY_RCONTROL) )
|
||
|
{
|
||
|
DeSelectAllBackpackItemPanels();
|
||
|
ToggleSelectBackpackItemPanel( pItemPanel );
|
||
|
}
|
||
|
else if ( AllowSelection() && !pItemPanel->IsGreyedOut() )
|
||
|
{
|
||
|
if ( !pItemPanel->IsSelected() && pItemPanel->HasItem() )
|
||
|
{
|
||
|
pItemPanel->SetSelected( true );
|
||
|
}
|
||
|
SetBorderForItem( pItemPanel, false );
|
||
|
}
|
||
|
|
||
|
OpenContextMenu();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CBackpackPanel::OnMouseMismatchedRelease( MouseCode code, Panel* pPressedPanel )
|
||
|
{
|
||
|
if ( pPressedPanel )
|
||
|
{
|
||
|
OnMouseReleased( code );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::StartDrag( int x, int y )
|
||
|
{
|
||
|
// don't allow item drag if there's a filter
|
||
|
if ( HasNameFilter() )
|
||
|
return;
|
||
|
|
||
|
m_bDragging = true;
|
||
|
HideMouseOverPanel();
|
||
|
|
||
|
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||
|
|
||
|
m_pMouseDragItemPanel->SetItem( m_pItemDraggedFromPanel->GetItem() );
|
||
|
m_pMouseDragItemPanel->InvalidateLayout( true );
|
||
|
|
||
|
m_pItemDraggedFromPanel->Dragged( true );
|
||
|
|
||
|
// Calculate the mouse offset from the top left of the panel we're going to drag
|
||
|
m_iDragOffsetX = m_pMouseDragItemPanel->GetWide() * 0.5f;
|
||
|
m_iDragOffsetY = m_pMouseDragItemPanel->GetTall() * 0.5f;
|
||
|
m_flPreventDragPageSwitchUntil = 0;
|
||
|
|
||
|
m_pMouseDragItemPanel->SetVisible( true );
|
||
|
|
||
|
m_pItemDraggedFromPanel->SetItem( NULL );
|
||
|
SetBorderForItem( m_pItemDraggedFromPanel, false );
|
||
|
m_pPrevDragOverItemPanel = NULL;
|
||
|
|
||
|
vgui::input()->SetMouseCapture( GetVPanel() );
|
||
|
|
||
|
if ( m_pDragToNextPageButton && m_pDragToPrevPageButton )
|
||
|
{
|
||
|
m_pDragToNextPageButton->SetVisible( GetNumPages() > 1 );
|
||
|
m_pDragToPrevPageButton->SetVisible( GetNumPages() > 1 );
|
||
|
}
|
||
|
|
||
|
// play pickup sound
|
||
|
CEconItemView *item = m_pMouseDragItemPanel->GetItem();
|
||
|
if ( item )
|
||
|
{
|
||
|
const char *soundFilename = item->GetDefinitionString( "pickup_sound", "" );
|
||
|
if ( soundFilename[0] )
|
||
|
{
|
||
|
vgui::surface()->PlaySound( soundFilename );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::StopDrag( bool bSucceeded )
|
||
|
{
|
||
|
if ( !m_pItemDraggedFromPanel )
|
||
|
return;
|
||
|
|
||
|
if ( !bSucceeded )
|
||
|
{
|
||
|
if ( m_iDraggedFromPage == GetCurrentPage() )
|
||
|
{
|
||
|
m_pItemDraggedFromPanel->SetItem( m_pMouseDragItemPanel->GetItem() );
|
||
|
}
|
||
|
m_pItemDraggedFromPanel = NULL;
|
||
|
}
|
||
|
|
||
|
m_pMouseDragItemPanel->SetVisible( false );
|
||
|
m_bDragging = false;
|
||
|
|
||
|
vgui::input()->SetMouseCapture( NULL );
|
||
|
|
||
|
if ( m_pDragToNextPageButton && m_pDragToPrevPageButton )
|
||
|
{
|
||
|
m_pDragToNextPageButton->SetVisible( false );
|
||
|
m_pDragToPrevPageButton->SetVisible( false );
|
||
|
}
|
||
|
|
||
|
// play drop sound
|
||
|
CEconItemView *item = m_pMouseDragItemPanel->GetItem();
|
||
|
if ( item )
|
||
|
{
|
||
|
const char *soundFilename = item->GetDefinitionString( "drop_sound", "ui/item_default_drop.wav" );
|
||
|
vgui::surface()->PlaySound( soundFilename );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
int CBackpackPanel::GetBackpackPositionForPanel( CItemModelPanel *pItemPanel )
|
||
|
{
|
||
|
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
|
||
|
{
|
||
|
if ( m_pItemModelPanels[i] == pItemPanel )
|
||
|
return i;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::HandleDragTo( CItemModelPanel *pItemPanel, int iPanelIndex )
|
||
|
{
|
||
|
// Find the position based on the panel we're dragging to
|
||
|
if ( iPanelIndex != -1 )
|
||
|
{
|
||
|
// If the current panel is selected, unselect it
|
||
|
if ( m_pItemModelPanels[iPanelIndex]->IsSelected() )
|
||
|
{
|
||
|
ToggleSelectBackpackItemPanel( m_pItemModelPanels[iPanelIndex] );
|
||
|
}
|
||
|
if ( m_pItemDraggedFromPanel->IsSelected() )
|
||
|
{
|
||
|
ToggleSelectBackpackItemPanel( m_pItemDraggedFromPanel );
|
||
|
}
|
||
|
|
||
|
// We "move" the items in the backpack immediately, because when the messages come back
|
||
|
// from steam they'll fix the positions if the move fails for some reason.
|
||
|
CEconItemView *pItem = NULL;
|
||
|
if ( m_pItemModelPanels[iPanelIndex]->HasItem() )
|
||
|
{
|
||
|
// We need to copy it because it's about to get stomped by the other item
|
||
|
pItem = new CEconItemView( *m_pItemModelPanels[iPanelIndex]->GetItem() );
|
||
|
}
|
||
|
m_pItemModelPanels[iPanelIndex]->SetItem( m_pMouseDragItemPanel->GetItem() );
|
||
|
|
||
|
if ( m_iDraggedFromPage == GetCurrentPage() )
|
||
|
{
|
||
|
m_pItemDraggedFromPanel->SetItem( pItem );
|
||
|
}
|
||
|
|
||
|
if ( pItem )
|
||
|
{
|
||
|
delete pItem;
|
||
|
}
|
||
|
|
||
|
// Tell the inventory to move the item
|
||
|
// Translate it to the right page
|
||
|
int iBackpackPosition = GetBackpackPosForPanelIndex( iPanelIndex );
|
||
|
InventoryManager()->MoveItemToBackpackPosition( m_pMouseDragItemPanel->GetItem(), iBackpackPosition );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnTick( void )
|
||
|
{
|
||
|
BaseClass::OnTick();
|
||
|
|
||
|
bool bNeedsTick = false;
|
||
|
if ( m_flStartExplanationsAt && m_flStartExplanationsAt < Plat_FloatTime() )
|
||
|
{
|
||
|
m_flStartExplanationsAt = 0;
|
||
|
|
||
|
if ( ShouldShowExplanations() )
|
||
|
{
|
||
|
ConVar *pConVar = GetExplanationConVar();
|
||
|
if ( pConVar )
|
||
|
{
|
||
|
pConVar->SetValue( 1 );
|
||
|
}
|
||
|
|
||
|
CExplanationPopup *pPopup = dynamic_cast<CExplanationPopup*>( FindChildByName("StartExplanation") );
|
||
|
if ( pPopup )
|
||
|
{
|
||
|
pPopup->Popup();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bNeedsTick = true;
|
||
|
}
|
||
|
|
||
|
// To handle page movement while holding the mouse still over the page buttons,
|
||
|
// we need to keep calling OnCursorMoved() whenever we're dragging.
|
||
|
if ( m_bDragging && m_pMouseDragItemPanel && m_pItemDraggedFromPanel && IsVisible() )
|
||
|
{
|
||
|
int mx,my;
|
||
|
vgui::input()->GetCursorPos( mx, my );
|
||
|
ScreenToLocal( mx, my );
|
||
|
OnCursorMoved( mx,my );
|
||
|
|
||
|
bNeedsTick = true;
|
||
|
}
|
||
|
|
||
|
if ( !bNeedsTick && !NeedsDerivedTickSignal() )
|
||
|
{
|
||
|
vgui::ivgui()->RemoveTickSignal( GetVPanel() );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnThink( void )
|
||
|
{
|
||
|
BaseClass::OnThink();
|
||
|
|
||
|
if ( m_flFilterItemTime > 0 && gpGlobals->curtime >= m_flFilterItemTime )
|
||
|
{
|
||
|
SetCurrentPage( 0 );
|
||
|
DeSelectAllBackpackItemPanels();
|
||
|
UpdateModelPanels();
|
||
|
|
||
|
m_flFilterItemTime = 0.0f;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnCursorMoved( int x, int y )
|
||
|
{
|
||
|
if ( !m_pItemDraggedFromPanel )
|
||
|
return;
|
||
|
|
||
|
if ( m_bDragging && m_pMouseDragItemPanel )
|
||
|
{
|
||
|
m_pMouseDragItemPanel->SetPos( x - m_iDragOffsetX, y - m_iDragOffsetY );
|
||
|
|
||
|
// When we're dragging, we have mouse capture, so the item panels aren't getting mouse input.
|
||
|
// We need to find out what item panel we're over, and let it know.
|
||
|
|
||
|
if ( m_flPreventDragPageSwitchUntil < Plat_FloatTime() )
|
||
|
{
|
||
|
// First, are we over the page turning areas?
|
||
|
bool bDragNext = false;
|
||
|
if ( m_pDragToNextPageButton && m_pDragToNextPageButton->IsVisible() )
|
||
|
{
|
||
|
int iDragX, iDragY;
|
||
|
m_pDragToNextPageButton->GetPos( iDragX, iDragY );
|
||
|
bDragNext = ( x >= iDragX && x <= (iDragX + m_pDragToNextPageButton->GetWide() ) );
|
||
|
}
|
||
|
if ( !bDragNext && m_pNextPageButton && m_pNextPageButton->IsEnabled() )
|
||
|
{
|
||
|
int iDragX, iDragY;
|
||
|
m_pNextPageButton->GetPos( iDragX, iDragY );
|
||
|
bDragNext = ( x >= iDragX && x <= (iDragX + m_pNextPageButton->GetWide()) && y >= iDragY && y <= (iDragY + m_pNextPageButton->GetTall()) );
|
||
|
}
|
||
|
if ( bDragNext )
|
||
|
{
|
||
|
OnCommand( "nextpage" );
|
||
|
m_flPreventDragPageSwitchUntil = Plat_FloatTime() + tf_backpack_page_button_delay.GetFloat();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
bool bDragPrev = false;
|
||
|
if ( m_pDragToPrevPageButton && m_pDragToPrevPageButton->IsVisible() )
|
||
|
{
|
||
|
int iDragX, iDragY;
|
||
|
m_pDragToPrevPageButton->GetPos( iDragX, iDragY );
|
||
|
bDragPrev = ( x >= iDragX && x <= (iDragX + m_pDragToPrevPageButton->GetWide() ) );
|
||
|
}
|
||
|
if ( !bDragPrev && m_pPrevPageButton && m_pPrevPageButton->IsEnabled() )
|
||
|
{
|
||
|
int iDragX, iDragY;
|
||
|
m_pPrevPageButton->GetPos( iDragX, iDragY );
|
||
|
bDragPrev = ( x >= iDragX && x <= (iDragX + m_pPrevPageButton->GetWide()) && y >= iDragY && y <= (iDragY + m_pPrevPageButton->GetTall()) );
|
||
|
}
|
||
|
if ( bDragPrev )
|
||
|
{
|
||
|
OnCommand( "prevpage" );
|
||
|
m_flPreventDragPageSwitchUntil = Plat_FloatTime() + tf_backpack_page_button_delay.GetFloat();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// check if we're hovering page button
|
||
|
static int iPrevHoveringPage = -1;
|
||
|
static float flLastPageButtonEnterTime = 0.f;
|
||
|
int iHoveringPage = GetPageButtonIndexAtPos( x, y );
|
||
|
if ( iHoveringPage != -1 )
|
||
|
{
|
||
|
if ( iHoveringPage == GetCurrentPage() )
|
||
|
{
|
||
|
iPrevHoveringPage = -1;
|
||
|
flLastPageButtonEnterTime = 0.f;
|
||
|
}
|
||
|
else if ( iPrevHoveringPage != iHoveringPage )
|
||
|
{
|
||
|
iPrevHoveringPage = iHoveringPage;
|
||
|
flLastPageButtonEnterTime = Plat_FloatTime() + tf_backpack_page_button_delay.GetFloat();
|
||
|
}
|
||
|
else if ( flLastPageButtonEnterTime > 0 && flLastPageButtonEnterTime < Plat_FloatTime() )
|
||
|
{
|
||
|
flLastPageButtonEnterTime = 0.f;
|
||
|
SetCurrentPage( iHoveringPage );
|
||
|
UpdateModelPanels();
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// reset hovering page buttons data
|
||
|
iPrevHoveringPage = -1;
|
||
|
flLastPageButtonEnterTime = 0.f;
|
||
|
}
|
||
|
|
||
|
CItemModelPanel *pOverPanel = GetItemPanelAtPos( x, y );
|
||
|
if ( m_pPrevDragOverItemPanel != pOverPanel )
|
||
|
{
|
||
|
if ( m_pPrevDragOverItemPanel )
|
||
|
{
|
||
|
OnItemPanelExited( m_pPrevDragOverItemPanel );
|
||
|
}
|
||
|
|
||
|
m_pPrevDragOverItemPanel = pOverPanel;
|
||
|
|
||
|
if ( m_pPrevDragOverItemPanel )
|
||
|
{
|
||
|
OnItemPanelEntered( m_pPrevDragOverItemPanel );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnItemPanelCursorMoved( int x, int y )
|
||
|
{
|
||
|
if ( !m_pItemDraggedFromPanel )
|
||
|
return;
|
||
|
|
||
|
if ( !m_bDragging && m_pItemDraggedFromPanel->HasItem() && !InToolSelectionMode() )
|
||
|
{
|
||
|
// Don't drag instantly, so it's easy to select
|
||
|
if ( (gpGlobals->curtime - m_flMouseDownTime) > 0.3 )
|
||
|
{
|
||
|
StartDrag( x,y );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( !m_iMouseDownX )
|
||
|
{
|
||
|
m_iMouseDownX = x;
|
||
|
m_iMouseDownY = y;
|
||
|
}
|
||
|
else if ( abs(m_iMouseDownX - x) > XRES(10) || abs(m_iMouseDownY - y) > YRES(10) )
|
||
|
{
|
||
|
StartDrag( x,y );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
OnCursorMoved( x, y );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::ToggleSelectBackpackItemPanel( CItemModelPanel *pPanel )
|
||
|
{
|
||
|
if ( !AllowSelection() || pPanel->IsGreyedOut() )
|
||
|
return;
|
||
|
|
||
|
if ( pPanel->IsSelected() || !pPanel->HasItem() )
|
||
|
{
|
||
|
pPanel->SetSelected( false );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pPanel->SetSelected( true );
|
||
|
}
|
||
|
SetBorderForItem( pPanel, false );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DeSelectAllBackpackItemPanels( void )
|
||
|
{
|
||
|
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
|
||
|
{
|
||
|
if ( m_pItemModelPanels[i]->IsSelected() )
|
||
|
{
|
||
|
m_pItemModelPanels[i]->SetSelected( false );
|
||
|
SetBorderForItem( m_pItemModelPanels[i], false );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Called whenever the selection changes in the item loadout panel
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnItemContentsChanged( CEconItemView *pEconItemView )
|
||
|
{
|
||
|
Assert( pEconItemView );
|
||
|
|
||
|
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
|
||
|
{
|
||
|
CEconItemView *pInternalItem = m_pItemModelPanels[i] && m_pItemModelPanels[i]->HasItem()
|
||
|
? m_pItemModelPanels[i]->GetItem()
|
||
|
: NULL;
|
||
|
|
||
|
if ( *pInternalItem == *pEconItemView )
|
||
|
{
|
||
|
m_pItemModelPanels[i]->DirtyDescription();
|
||
|
OnItemSelectionChanged();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Called when text changes in combo box
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnTextChanged( KeyValues *data )
|
||
|
{
|
||
|
Panel *pPanel = reinterpret_cast<vgui::Panel *>( data->GetPtr("panel") );
|
||
|
|
||
|
vgui::TextEntry *pTextEntry = dynamic_cast<vgui::TextEntry *>( pPanel );
|
||
|
if ( pTextEntry )
|
||
|
{
|
||
|
if ( pTextEntry == m_pNameFilterTextEntry )
|
||
|
{
|
||
|
m_wNameFilter.RemoveAll();
|
||
|
if ( m_pNameFilterTextEntry->GetTextLength() )
|
||
|
{
|
||
|
m_wNameFilter.EnsureCount( m_pNameFilterTextEntry->GetTextLength() + 1 );
|
||
|
m_pNameFilterTextEntry->GetText( m_wNameFilter.Base(), m_wNameFilter.Count() * sizeof(wchar_t) );
|
||
|
V_wcslower( m_wNameFilter.Base() );
|
||
|
}
|
||
|
m_flFilterItemTime = gpGlobals->curtime + 0.5f;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
vgui::ComboBox *pComboBox = dynamic_cast<vgui::ComboBox *>( pPanel );
|
||
|
if ( pComboBox )
|
||
|
{
|
||
|
if ( pComboBox == m_pSortByComboBox )
|
||
|
{
|
||
|
// the class selection combo box changed, update class details
|
||
|
KeyValues *pUserData = m_pSortByComboBox->GetActiveItemUserData();
|
||
|
if ( !pUserData )
|
||
|
return;
|
||
|
|
||
|
enum { kSortType_Dummy = -1 };
|
||
|
int iSortTypeSelectionIndex = pUserData->GetInt( "sortby", kSortType_Dummy );
|
||
|
if ( iSortTypeSelectionIndex != kSortType_Dummy )
|
||
|
{
|
||
|
uint32 iSortType = g_BackpackSortTypes[iSortTypeSelectionIndex].iSortType;
|
||
|
if ( iSortType != kGCItemSort_NoSort )
|
||
|
{
|
||
|
InventoryManager()->SortBackpackBy( iSortType );
|
||
|
|
||
|
// Now go back to the "Sort by" header, and move the focus to the close button.
|
||
|
m_pSortByComboBox->ActivateItemByRow( 0 );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if ( pComboBox == m_pShowRarityComboBox )
|
||
|
{
|
||
|
cl_showbackpackrarities.SetValue( m_pShowRarityComboBox->GetActiveItem() );
|
||
|
|
||
|
// Refresh all item borders
|
||
|
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
|
||
|
{
|
||
|
SetBorderForItem( m_pItemModelPanels[i], false );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnButtonChecked( KeyValues *pData )
|
||
|
{
|
||
|
Panel *pPanel = reinterpret_cast<vgui::Panel *>( pData->GetPtr("panel") );
|
||
|
|
||
|
if ( m_bShowBaseItems != m_pShowBaseItemsCheckbox->IsSelected() && m_pShowBaseItemsCheckbox == pPanel && IsVisible() )
|
||
|
{
|
||
|
SetShowBaseItems( m_pShowBaseItemsCheckbox->IsSelected() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnCancelSelection( void )
|
||
|
{
|
||
|
if ( m_pConfirmDeleteDialog )
|
||
|
{
|
||
|
m_pConfirmDeleteDialog->MarkForDeletion();
|
||
|
m_pConfirmDeleteDialog = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
const char *CBackpackPanel::GetGreyOutItemPanelReason( CItemModelPanel *pItemPanel )
|
||
|
{
|
||
|
if ( InToolSelectionMode() )
|
||
|
{
|
||
|
bool bIsSelectedTool = (m_ToolSelectionItem.IsValid() && pItemPanel->HasItem()) ? (m_ToolSelectionItem == *pItemPanel->GetItem()) : false;
|
||
|
if ( !bIsSelectedTool )
|
||
|
{
|
||
|
if ( m_ToolSelectionItem.GetStaticData()->IsTool() )
|
||
|
{
|
||
|
if ( !CEconSharedToolSupport::ToolCanApplyTo( &m_ToolSelectionItem, pItemPanel->GetItem() ) )
|
||
|
{
|
||
|
return "#Econ_GreyOutReason_ToolCannotApply";
|
||
|
}
|
||
|
}
|
||
|
else if ( pItemPanel->GetItem() && pItemPanel->GetItem()->GetStaticData()->IsTool() )
|
||
|
{
|
||
|
if ( !CEconSharedToolSupport::ToolCanApplyTo( pItemPanel->GetItem(), &m_ToolSelectionItem ) )
|
||
|
{
|
||
|
return "#Econ_GreyOutReason_ToolCannotApply";
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::SetBorderForItem( CItemModelPanel *pItemPanel, bool bMouseOver )
|
||
|
{
|
||
|
tmZone( TELEMETRY_LEVEL1, TMZF_NONE, "%s", __FUNCTION__ );
|
||
|
|
||
|
if ( !pItemPanel )
|
||
|
return;
|
||
|
|
||
|
const char *pszBorder = NULL;
|
||
|
|
||
|
bool bIsSelectedTool = (m_ToolSelectionItem.IsValid() && pItemPanel->HasItem()) ? (m_ToolSelectionItem == *pItemPanel->GetItem()) : false;
|
||
|
|
||
|
// Handle grey out
|
||
|
const char *pszGreyOutReason = GetGreyOutItemPanelReason( pItemPanel );
|
||
|
const bool bGreyOut = pszGreyOutReason != NULL;
|
||
|
|
||
|
pItemPanel->SetGreyedOut( pszGreyOutReason );
|
||
|
|
||
|
int iRarity = GetItemQualityForBorder( pItemPanel );
|
||
|
|
||
|
if ( InToolSelectionMode() && bIsSelectedTool )
|
||
|
{
|
||
|
// We're in tool application mode, and this panel is the tool being used
|
||
|
pszBorder = "BackpackItemBorder_SelfMade";
|
||
|
|
||
|
if ( m_pToolIcon )
|
||
|
{
|
||
|
int iX, iY;
|
||
|
pItemPanel->GetPos( iX, iY );
|
||
|
m_pToolIcon->SetPos( iX, iY );
|
||
|
m_pToolIcon->SetVisible( true );
|
||
|
}
|
||
|
}
|
||
|
else if ( bGreyOut )
|
||
|
{
|
||
|
if( pItemPanel->IsSelected() )
|
||
|
{
|
||
|
pszBorder = g_szItemBorders[iRarity][4];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pszBorder = g_szItemBorders[iRarity][3];
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
if ( pItemPanel->IsSelected() )
|
||
|
{
|
||
|
pszBorder = g_szItemBorders[iRarity][2];
|
||
|
}
|
||
|
else if ( bMouseOver )
|
||
|
{
|
||
|
pszBorder = g_szItemBorders[iRarity][1];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pszBorder = g_szItemBorders[iRarity][0];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
|
||
|
pItemPanel->SetBorder( pScheme->GetBorder( pszBorder ) );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
class CTFRemoveItemCustomizationConfirmDialog : public CTFGenericConfirmDialog
|
||
|
{
|
||
|
DECLARE_CLASS_SIMPLE( CTFRemoveItemCustomizationConfirmDialog, CTFGenericConfirmDialog );
|
||
|
public:
|
||
|
CTFRemoveItemCustomizationConfirmDialog( const RefurbishableProperty& prop, CEconItemView *pItem )
|
||
|
: CTFGenericConfirmDialog( prop.m_szDialogTitle, // dialog title
|
||
|
prop.m_szDialogDesc, // dialog text
|
||
|
"#RefurbishItem_Yes", // confirm button text
|
||
|
"#RefurbishItem_No", // cancel button text
|
||
|
NULL, // callback
|
||
|
NULL ) // parent
|
||
|
, m_prop( prop )
|
||
|
, m_Item( *pItem ) // copy in case our UI changes behind us
|
||
|
{
|
||
|
GetCustomDialogLocalizationTokenFunc_t m_pDialogCustomTokenFunc = m_prop.m_pGetCustomDialogLocalizationTokenFunc;
|
||
|
if ( m_pDialogCustomTokenFunc )
|
||
|
{
|
||
|
CUtlConstWideString wsDialogCustomToken;
|
||
|
(*m_pDialogCustomTokenFunc)( &m_Item, m_prop.m_iUserData, wsDialogCustomToken );
|
||
|
if ( !wsDialogCustomToken.IsEmpty() )
|
||
|
{
|
||
|
AddStringToken( "confirm_dialog_token", wsDialogCustomToken.Get() );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
virtual ~CTFRemoveItemCustomizationConfirmDialog() { }
|
||
|
|
||
|
virtual void OnCommand( const char *command );
|
||
|
|
||
|
private:
|
||
|
RefurbishableProperty m_prop;
|
||
|
CEconItemView m_Item;
|
||
|
};
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void SendGCSimpleAttributeRemovalMessage( CEconItemView *pEconItemView, const char *szDesc, EGCItemMsg eItemMsg )
|
||
|
{
|
||
|
EconUI()->Gamestats_ItemTransaction( IE_ITEM_REMOVED_ATTRIB, pEconItemView, szDesc );
|
||
|
GCSDK::CProtoBufMsg<CMsgGCRemoveCustomizationAttributeSimple> msg( eItemMsg );
|
||
|
msg.Body().set_item_id( pEconItemView->GetItemID() );
|
||
|
GCClientSystem()->BSendMessage( msg );
|
||
|
}
|
||
|
|
||
|
void CTFRemoveItemCustomizationConfirmDialog::OnCommand( const char *command )
|
||
|
{
|
||
|
BaseClass::OnCommand( command );
|
||
|
|
||
|
// Did the user say "yes, remove this particular attribute"? If so, notify the GC. We can't
|
||
|
// remove multiple attributes at a time because each removal will cause a new item to be created,
|
||
|
// invalidating the item reference we've got in this dialog.
|
||
|
if ( !Q_strnicmp( command, "confirm", 7 ) )
|
||
|
{
|
||
|
// remove the attribute
|
||
|
switch( m_prop.m_eRemovalType )
|
||
|
{
|
||
|
case kCustomizationRemove_Paint:
|
||
|
SendGCSimpleAttributeRemovalMessage( &m_Item, "paint", k_EMsgGCRemoveItemPaint );
|
||
|
break;
|
||
|
|
||
|
case kCustomizationRemove_Name:
|
||
|
{
|
||
|
EconUI()->Gamestats_ItemTransaction( IE_ITEM_REMOVED_ATTRIB, &m_Item, "name" );
|
||
|
GCSDK::CGCMsg< MsgGCRemoveItemName_t > msg( k_EMsgGCRemoveItemName );
|
||
|
msg.Body().m_unItemID = m_Item.GetItemID();
|
||
|
msg.Body().m_bDescription = false;
|
||
|
GCClientSystem()->BSendMessage( msg );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case kCustomizationRemove_Desc:
|
||
|
{
|
||
|
EconUI()->Gamestats_ItemTransaction( IE_ITEM_REMOVED_ATTRIB, &m_Item, "description" );
|
||
|
GCSDK::CGCMsg< MsgGCRemoveItemName_t > msg( k_EMsgGCRemoveItemName );
|
||
|
msg.Body().m_unItemID = m_Item.GetItemID();
|
||
|
msg.Body().m_bDescription = true;
|
||
|
GCClientSystem()->BSendMessage( msg );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case kCustomizationRemove_CustomTexture:
|
||
|
SendGCSimpleAttributeRemovalMessage( &m_Item, "custom_texture", k_EMsgGCRemoveCustomTexture );
|
||
|
break;
|
||
|
|
||
|
case kCustomizationRemove_MakersMark:
|
||
|
SendGCSimpleAttributeRemovalMessage( &m_Item, "makers_mark", k_EMsgGCRemoveMakersMark );
|
||
|
break;
|
||
|
|
||
|
case kCustomizationRemove_StrangePart:
|
||
|
{
|
||
|
Assert( m_prop.m_iUserData != kNoUserData );
|
||
|
int iKillEaterAttrIndex = m_prop.m_iUserData;
|
||
|
|
||
|
// What attribute did we select?
|
||
|
const CEconItemAttributeDefinition *pAttrDef = GetKillEaterAttr_Type( iKillEaterAttrIndex );
|
||
|
Assert( pAttrDef );
|
||
|
|
||
|
// Make sure this item has this attribute.
|
||
|
float fScoreType = kKillEaterEvent_PlayerKill;
|
||
|
Verify( FindAttribute_UnsafeBitwiseCast<attrib_value_t>( &m_Item, pAttrDef, &fScoreType ) || iKillEaterAttrIndex == 0 );
|
||
|
|
||
|
// Dispatch message.
|
||
|
EconUI()->Gamestats_ItemTransaction( IE_ITEM_REMOVED_ATTRIB, &m_Item, "strange_part" );
|
||
|
GCSDK::CProtoBufMsg<CMsgGCRemoveStrangePart> msg( k_EMsgGCRemoveStrangePart );
|
||
|
|
||
|
msg.Body().set_item_id( m_Item.GetItemID() );
|
||
|
msg.Body().set_strange_part_score_type( (int)fScoreType );
|
||
|
GCClientSystem()->BSendMessage( msg );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case kCustomizationRemove_StrangeScores:
|
||
|
{
|
||
|
Assert( m_prop.m_iUserData == kNoUserData );
|
||
|
|
||
|
EconUI()->Gamestats_ItemTransaction( IE_ITEM_RESET_STRANGE_COUNTERS, &m_Item );
|
||
|
GCSDK::CProtoBufMsg<CMsgGCResetStrangeScores> msg( k_EMsgGCResetStrangeScores );
|
||
|
msg.Body().set_item_id( m_Item.GetItemID() );
|
||
|
GCClientSystem()->BSendMessage( msg );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case kCustomizationRemove_UpgradeCard:
|
||
|
{
|
||
|
Assert( m_prop.m_iUserData != kNoUserData );
|
||
|
|
||
|
// Make sure we selected a valid attribute that this item has.
|
||
|
const CEconItemAttributeDefinition *pAttrDef = GetCardUpgradeForIndex( &m_Item, m_prop.m_iUserData );
|
||
|
Assert( pAttrDef );
|
||
|
Verify( m_Item.FindAttribute( pAttrDef ) );
|
||
|
|
||
|
// Dispatch message.
|
||
|
EconUI()->Gamestats_ItemTransaction( IE_ITEM_REMOVED_ATTRIB, &m_Item, "upgrade_card" );
|
||
|
GCSDK::CProtoBufMsg<CMsgGCRemoveUpgradeCard> msg( k_EMsgGCRemoveUpgradeCard );
|
||
|
|
||
|
msg.Body().set_item_id( m_Item.GetItemID() );
|
||
|
msg.Body().set_attribute_index( pAttrDef->GetDefinitionIndex() );
|
||
|
GCClientSystem()->BSendMessage( msg );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case kCustomizationRemove_KillStreak:
|
||
|
SendGCSimpleAttributeRemovalMessage( &m_Item, "killstreak", k_EMsgGCRemoveKillStreak );
|
||
|
break;
|
||
|
case kCustomizationRemove_GiftedBy:
|
||
|
SendGCSimpleAttributeRemovalMessage( &m_Item, "giftedby", k_EMsgGCRemoveGiftedBy );
|
||
|
break;
|
||
|
case kCustomizationRemove_Festivizer:
|
||
|
SendGCSimpleAttributeRemovalMessage( &m_Item, "festivizer", k_EMsgGCRemoveFestivizer );
|
||
|
break;
|
||
|
default:
|
||
|
AssertMsg( false, "Unknown item customization removal type!" );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SetVisible( false );
|
||
|
MarkForDeletion();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
class CRefurbishItemDialog : public CComboBoxBackpackOverlayDialogBase
|
||
|
{
|
||
|
public:
|
||
|
DECLARE_CLASS_SIMPLE( CRefurbishItemDialog, CComboBoxBackpackOverlayDialogBase );
|
||
|
|
||
|
public:
|
||
|
CRefurbishItemDialog( vgui::Panel *pParent, CEconItemView *m_pItem ) : CComboBoxBackpackOverlayDialogBase( pParent, m_pItem ) { }
|
||
|
|
||
|
private:
|
||
|
virtual void PopulateComboBoxOptions()
|
||
|
{
|
||
|
Assert( m_pItem );
|
||
|
|
||
|
KeyValues *pKeyValues = new KeyValues( "data" );
|
||
|
for ( int i = 0; i < GetRemovableAttributesCount(); i++ )
|
||
|
{
|
||
|
if ( RemovableAttributes_DoesAttributeApply( i, m_pItem ) )
|
||
|
{
|
||
|
pKeyValues->SetInt( "data", i );
|
||
|
|
||
|
RefurbishableProperty prop = RemovableAttributes_GetAttributeDetails( i );
|
||
|
|
||
|
CUtlConstWideString wsDialogCustomToken;
|
||
|
if ( prop.m_pGetCustomDialogLocalizationTokenFunc )
|
||
|
{
|
||
|
(*prop.m_pGetCustomDialogLocalizationTokenFunc)( m_pItem, prop.m_iUserData, wsDialogCustomToken );
|
||
|
}
|
||
|
CConstructLocalizedString localizedUI( GLocalizationProvider()->Find( prop.m_pszSelectionUILocalizationToken ), wsDialogCustomToken.IsEmpty() ? L"" : wsDialogCustomToken.Get() );
|
||
|
GetComboBox()->AddItem( localizedUI, pKeyValues );
|
||
|
}
|
||
|
}
|
||
|
pKeyValues->deleteThis();
|
||
|
|
||
|
Assert( GetComboBox()->GetItemCount() > 0 );
|
||
|
|
||
|
GetComboBox()->ActivateItemByRow( 0 );
|
||
|
}
|
||
|
|
||
|
virtual void OnComboBoxApplication()
|
||
|
{
|
||
|
if ( !m_pItem )
|
||
|
return;
|
||
|
|
||
|
KeyValues *pKVActiveUserData = GetComboBox()->GetActiveItemUserData();
|
||
|
int iIndex = pKVActiveUserData ? pKVActiveUserData->GetInt( "data", -1 ) : -1;
|
||
|
if ( iIndex < 0 )
|
||
|
return;
|
||
|
|
||
|
const RefurbishableProperty RefurbProp = RemovableAttributes_GetAttributeDetails( iIndex );
|
||
|
|
||
|
CTFRemoveItemCustomizationConfirmDialog *pDialog = new CTFRemoveItemCustomizationConfirmDialog( RefurbProp, m_pItem );
|
||
|
if ( pDialog )
|
||
|
{
|
||
|
pDialog->Show();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
virtual const char *GetTitleLabelLocalizationToken() const { return "#TF_Item_RefurbishItemHeader"; }
|
||
|
};
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Handles item selection while in tool selection mode
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::HandleToolItemSelection( CEconItemView *pItem )
|
||
|
{
|
||
|
if ( !InToolSelectionMode() )
|
||
|
{
|
||
|
// must be in tool selection mode
|
||
|
Assert( InToolSelectionMode() );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( pItem )
|
||
|
{
|
||
|
// Check if we should bring up the shuffle dialog instead of directly using the tool
|
||
|
static CSchemaAttributeDefHandle pAttrDef_CanShuffleCrateContents( "can shuffle crate contents" );
|
||
|
if ( pItem->FindAttribute( pAttrDef_CanShuffleCrateContents ) )
|
||
|
{
|
||
|
CInputStringForItemBackpackOverlayDialog *pDialog = vgui::SETUP_PANEL( new CInputStringForItemBackpackOverlayDialog( this, pItem, &m_ToolSelectionItem ) );
|
||
|
if ( pDialog )
|
||
|
{
|
||
|
pDialog->Show();
|
||
|
CancelToolSelection();
|
||
|
}
|
||
|
}
|
||
|
else if ( m_ToolSelectionItem.FindAttribute( pAttrDef_CanShuffleCrateContents ) )
|
||
|
{
|
||
|
CInputStringForItemBackpackOverlayDialog *pDialog = vgui::SETUP_PANEL( new CInputStringForItemBackpackOverlayDialog( this, &m_ToolSelectionItem, pItem ) );
|
||
|
if ( pDialog )
|
||
|
{
|
||
|
pDialog->Show();
|
||
|
CancelToolSelection();
|
||
|
}
|
||
|
}
|
||
|
// is a tool being applied onto this item
|
||
|
else if ( m_ToolSelectionItem.GetStaticData()->IsTool() && ApplyTool( this, &m_ToolSelectionItem, pItem ) )
|
||
|
{
|
||
|
CancelToolSelection();
|
||
|
UpdateModelPanels();
|
||
|
}
|
||
|
// is this item a tool that can be applied on a selected item
|
||
|
else if ( pItem->GetStaticData()->IsTool() && ApplyTool( this, pItem, &m_ToolSelectionItem ) )
|
||
|
{
|
||
|
CancelToolSelection();
|
||
|
UpdateModelPanels();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Tries to use the item. This might switch the panel to a tool item
|
||
|
// selection mode, or launch the recipe crafting panel.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::SetupToolSelectionItem()
|
||
|
{
|
||
|
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
|
||
|
{
|
||
|
if ( m_pItemModelPanels[i]->IsSelected() && m_pItemModelPanels[i]->HasItem() )
|
||
|
{
|
||
|
m_ToolSelectionItem = *m_pItemModelPanels[i]->GetItem();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Open up the trade dialog
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoTradeToPlayer()
|
||
|
{
|
||
|
OpenTradingStartDialog( this );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Use the trade dialog to send a gift to a player.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoGiftToPlayer()
|
||
|
{
|
||
|
OpenTradingStartDialog( this, &m_ToolSelectionItem );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Open up the overlay to sell the selected item
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoSellMarketplace()
|
||
|
{
|
||
|
CUtlVector< CItemModelPanel* > m_vecSelected;
|
||
|
GetSelectedPanels( SELECT_FIRST, m_vecSelected );
|
||
|
Assert( m_vecSelected.Count() );
|
||
|
if( !m_vecSelected.Count() )
|
||
|
return;
|
||
|
|
||
|
if ( m_vecSelected.Count() && steamapicontext && steamapicontext->SteamFriends() && steamapicontext->SteamUtils() )
|
||
|
{
|
||
|
CEconItemView *pItem = m_vecSelected.Head()->GetItem();
|
||
|
const char *pszPrefix = "";
|
||
|
if ( GetUniverse() == k_EUniverseBeta )
|
||
|
{
|
||
|
pszPrefix = "beta.";
|
||
|
}
|
||
|
uint32 nAssetContext = 2; // k_EEconContextBackpack
|
||
|
char szURL[512];
|
||
|
V_snprintf( szURL, sizeof(szURL), "http://%ssteamcommunity.com/my/inventory/?sellOnLoad=1#%d_%d_%llu", pszPrefix, engine->GetAppID(), nAssetContext, pItem->GetItemID() );
|
||
|
steamapicontext->SteamFriends()->ActivateGameOverlayToWebPage( szURL );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Use a description tag, or offer to buy one
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoDescription()
|
||
|
{
|
||
|
static CSchemaItemDefHandle pItemDef_DescTag( "Description Tag" );
|
||
|
if ( !AttemptToUseItem( pItemDef_DescTag->GetDefinitionIndex() ) )
|
||
|
{
|
||
|
AttemptToShowItemInStore( pItemDef_DescTag->GetDefinitionIndex() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Use a name tag, or offer to buy one
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoRename()
|
||
|
{
|
||
|
static CSchemaItemDefHandle pItemDef_NameTag( "Name Tag" );
|
||
|
if ( !AttemptToUseItem( pItemDef_NameTag->GetDefinitionIndex() ) )
|
||
|
{
|
||
|
AttemptToShowItemInStore( pItemDef_NameTag->GetDefinitionIndex() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Delete the selected items
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoDelete()
|
||
|
{
|
||
|
// Hide the mouseover panel
|
||
|
HideMouseOverPanel();
|
||
|
|
||
|
int iItemsToDelete = 0;
|
||
|
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
|
||
|
{
|
||
|
if ( m_pItemModelPanels[i]->IsSelected() && m_pItemModelPanels[i]->HasItem() )
|
||
|
{
|
||
|
iItemsToDelete++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Bring up confirm dialog
|
||
|
CConfirmDeleteItemDialog *pConfirm = vgui::SETUP_PANEL( new CConfirmDeleteItemDialog( this, ( iItemsToDelete > 1 ) ) );
|
||
|
if ( pConfirm )
|
||
|
{
|
||
|
pConfirm->Show();
|
||
|
|
||
|
m_pConfirmDeleteDialog = pConfirm;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Use the selected tool
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoApplyOnItem()
|
||
|
{
|
||
|
SetupToolSelectionItem();
|
||
|
|
||
|
if ( m_ToolSelectionItem.IsValid() )
|
||
|
{
|
||
|
const IEconTool *pEconTool = m_ToolSelectionItem.GetItemDefinition()->GetEconTool();
|
||
|
|
||
|
// Gather all quest objective attributes
|
||
|
CRecipeComponentMatchingIterator recipeIterator( NULL, NULL );
|
||
|
if ( m_ToolSelectionItem.GetSOCData() )
|
||
|
{
|
||
|
m_ToolSelectionItem.GetSOCData()->IterateAttributes( &recipeIterator );
|
||
|
}
|
||
|
|
||
|
if( pEconTool && recipeIterator.GetMatchingComponentInputs().Count() > 0 )
|
||
|
{
|
||
|
// Launch new crafting window if we need to
|
||
|
if( m_pDynamicRecipePanel == NULL )
|
||
|
{
|
||
|
m_pDynamicRecipePanel = vgui::SETUP_PANEL( new CDynamicRecipePanel( this, "dynamic_recipe_panel", &m_ToolSelectionItem ) );
|
||
|
}
|
||
|
|
||
|
// Set recipe item into panel
|
||
|
if ( m_pDynamicRecipePanel )
|
||
|
{
|
||
|
m_pDynamicRecipePanel->SetVisible( true );
|
||
|
m_pDynamicRecipePanel->SetNewRecipe( &m_ToolSelectionItem );
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Check if we actually have any items we can use this tool on
|
||
|
bool bHasValidTargetItem = false;
|
||
|
CPlayerInventory *pInv = InventoryManager()->GetLocalInventory();
|
||
|
Assert( pInv );
|
||
|
if ( pInv )
|
||
|
{
|
||
|
for ( int i = 0 ; i < pInv->GetItemCount() ; ++i )
|
||
|
{
|
||
|
CEconItemView *pItem = pInv->GetItem( i );
|
||
|
if ( CEconSharedToolSupport::ToolCanApplyTo( &m_ToolSelectionItem, pItem ) )
|
||
|
{
|
||
|
bHasValidTargetItem = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If no applicable items, try stock items
|
||
|
if ( !bHasValidTargetItem )
|
||
|
{
|
||
|
// this is really inefficient, maybe have a list of baseitems somewhere
|
||
|
CEconItemView tempItem;
|
||
|
const CEconItemDefinition* pItemDef = NULL;
|
||
|
|
||
|
const CEconItemSchema::SortedItemDefinitionMap_t& mapItems = GetItemSchema()->GetSortedItemDefinitionMap();
|
||
|
for ( int it = mapItems.FirstInorder(); it != mapItems.InvalidIndex(); it = mapItems.NextInorder( it ) )
|
||
|
{
|
||
|
if ( mapItems[it]->IsBaseItem() && !mapItems[it]->IsHidden() )
|
||
|
{
|
||
|
CFmtStr fmtStrCustomizedDefName( "Upgradeable %s", mapItems[it]->GetDefinitionName() );
|
||
|
pItemDef = GetItemSchema()->GetItemDefinitionByName( fmtStrCustomizedDefName.Access() );
|
||
|
if ( pItemDef )
|
||
|
{
|
||
|
tempItem.Init( pItemDef->GetDefinitionIndex(), AE_UNIQUE, AE_USE_SCRIPT_VALUE, true );
|
||
|
if ( CEconSharedToolSupport::ToolCanApplyTo( &m_ToolSelectionItem, &tempItem ) )
|
||
|
{
|
||
|
bHasValidTargetItem = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( bHasValidTargetItem )
|
||
|
{
|
||
|
// automatically switch to stock items
|
||
|
OnCommand( "showbaseitems" );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !bHasValidTargetItem )
|
||
|
{
|
||
|
ShowMessageBox( NULL, "#ToolNoTargetItems", "#GameUI_OK" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_eSelectionMode = ToolSelection;
|
||
|
m_nLastToolPage = GetCurrentPage();
|
||
|
|
||
|
if ( m_pMouseOverTooltip )
|
||
|
{
|
||
|
m_pMouseOverTooltip->HideTooltip();
|
||
|
}
|
||
|
|
||
|
ClearNameFilter( true );
|
||
|
SetCurrentPage( 0 );
|
||
|
UpdateModelPanels();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: use a consumable item directly from the backpack
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoUseConsumableItem()
|
||
|
{
|
||
|
SetupToolSelectionItem();
|
||
|
|
||
|
#ifdef TF_CLIENT_DLL
|
||
|
UseConsumableItem( &m_ToolSelectionItem, this );
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Use the tool to unwrap an item
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoUnwrapItem()
|
||
|
{
|
||
|
DoUseConsumableItem();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Use the tool to deliver an item
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoDeliverItem()
|
||
|
{
|
||
|
SetupToolSelectionItem();
|
||
|
|
||
|
#ifdef TF_CLIENT_DLL
|
||
|
const CEconTool_WrappedGift *pWrappedGiftTool = m_ToolSelectionItem.GetItemDefinition()
|
||
|
? m_ToolSelectionItem.GetItemDefinition()->GetTypedEconTool<CEconTool_WrappedGift>()
|
||
|
: NULL;
|
||
|
|
||
|
if ( pWrappedGiftTool && pWrappedGiftTool->BIsDirectGift() )
|
||
|
{
|
||
|
DoUseConsumableItem();
|
||
|
return;
|
||
|
}
|
||
|
else if ( pWrappedGiftTool && pWrappedGiftTool->BIsGlobalGift() )
|
||
|
{
|
||
|
// If this is a global gift, we don't let the user pick a target so we're done as of now.
|
||
|
extern void UseUntargetedGiftConfirm( bool bConfirmed, void *pContext );
|
||
|
CTFGenericConfirmDialog *pDialog = ShowConfirmDialog( "#TF_DeliverGiftDialog_Title", "#TF_DeliverGiftDialog_Random_Text",
|
||
|
"#TF_DeliverGiftDialog_Confirm", "#TF_DeliverGiftDialog_Cancel",
|
||
|
&UseUntargetedGiftConfirm );
|
||
|
|
||
|
pDialog->SetContext( &m_ToolSelectionItem );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
DoGiftToPlayer();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Show
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoApplyByItem()
|
||
|
{
|
||
|
SetupToolSelectionItem();
|
||
|
|
||
|
m_eSelectionMode = ToolSelection;
|
||
|
m_nLastToolPage = GetCurrentPage();
|
||
|
|
||
|
if ( m_pMouseOverTooltip )
|
||
|
{
|
||
|
m_pMouseOverTooltip->HideTooltip();
|
||
|
}
|
||
|
|
||
|
ClearNameFilter( true );
|
||
|
SetCurrentPage( 0 );
|
||
|
UpdateModelPanels();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: open shuffle items dialog
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoShuffle()
|
||
|
{
|
||
|
SetupToolSelectionItem();
|
||
|
|
||
|
CInputStringForItemBackpackOverlayDialog *pDialog = vgui::SETUP_PANEL( new CInputStringForItemBackpackOverlayDialog( this, &m_ToolSelectionItem ) );
|
||
|
if ( pDialog )
|
||
|
{
|
||
|
pDialog->Show();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CBackpackPanel::DoEditSlot()
|
||
|
{
|
||
|
SetupToolSelectionItem();
|
||
|
|
||
|
// Launch new slot window if we need to
|
||
|
if( m_pItemSlotPanel == NULL )
|
||
|
{
|
||
|
m_pItemSlotPanel = vgui::SETUP_PANEL( new CItemSlotPanel( this ) );
|
||
|
}
|
||
|
|
||
|
// Set item into panel
|
||
|
if ( m_pItemSlotPanel )
|
||
|
{
|
||
|
m_pItemSlotPanel->SetVisible( true );
|
||
|
m_pItemSlotPanel->SetItem( m_ToolSelectionItem.GetSOCData() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Refurbish item
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoRefurbishItem()
|
||
|
{
|
||
|
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
|
||
|
{
|
||
|
if ( m_pItemModelPanels[i]->IsSelected() && m_pItemModelPanels[i]->HasItem() )
|
||
|
{
|
||
|
m_ComboBoxOverlaySelectionItem = *m_pItemModelPanels[i]->GetItem();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CRefurbishItemDialog *pRefurbishDialog = vgui::SETUP_PANEL( new CRefurbishItemDialog( this, &m_ComboBoxOverlaySelectionItem ) );
|
||
|
if ( pRefurbishDialog )
|
||
|
{
|
||
|
pRefurbishDialog->Show();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Deode by item
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoGetItemFromStore()
|
||
|
{
|
||
|
SetupToolSelectionItem();
|
||
|
|
||
|
uint32 iDecoableItemDef = 0;
|
||
|
if ( GetDecodedByItemDefIndex( &m_ToolSelectionItem, &iDecoableItemDef ) )
|
||
|
{
|
||
|
// casting to the proper type since our econ system is dumb
|
||
|
const float& value_as_float = (float&)iDecoableItemDef;
|
||
|
CEconItemDefinition * pDefIndex = GetItemSchema()->GetItemDefinition( (int)value_as_float );
|
||
|
|
||
|
EconUI()->GetStorePanel()->AddToCartAndCheckoutImmediately( pDefIndex->GetDefinitionIndex() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Open End of the Line duck leaderboards
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoOpenDuckLeaderboards()
|
||
|
{
|
||
|
CCharacterInfoPanel* pCharInfo = dynamic_cast< CCharacterInfoPanel* >( EconUI() );
|
||
|
CDucksLeaderboardManager *pDuckLeaderboards = vgui::SETUP_PANEL( new CDucksLeaderboardManager( pCharInfo, "DucksLeaderboardPanel" ) );
|
||
|
pDuckLeaderboards->SetVisible( true );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Strange Count Transfer Dialog
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoStrangeCountTransfer()
|
||
|
{
|
||
|
CUtlVector< CItemModelPanel* > vecSelected;
|
||
|
GetSelectedPanels( SELECT_FIRST, vecSelected );
|
||
|
|
||
|
Assert( vecSelected.Count() );
|
||
|
if ( vecSelected.IsEmpty() )
|
||
|
return;
|
||
|
|
||
|
m_pStrangeToolPanel = vgui::SETUP_PANEL( new CStrangeCountTransferPanel( this, vecSelected[0]->GetItem() ) );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Collection crafting
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoCraftUpCollection()
|
||
|
{
|
||
|
CUtlVector< CItemModelPanel* > vecSelected;
|
||
|
GetSelectedPanels( SELECT_ALL, vecSelected );
|
||
|
|
||
|
//Assert( vecSelected.Count() );
|
||
|
//if ( vecSelected.IsEmpty() )
|
||
|
// return;
|
||
|
|
||
|
// Get all the items that were selected
|
||
|
CUtlVector< const CEconItemView* > vecSelectedItems;
|
||
|
FOR_EACH_VEC( vecSelected, i )
|
||
|
{
|
||
|
if ( vecSelected[ i ]->GetItem() && GetCollectionCraftingInvalidReason( vecSelected[ i ]->GetItem(), NULL ) == NULL )
|
||
|
{
|
||
|
vecSelectedItems.AddToTail( vecSelected[ i ]->GetItem() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// For tracking how many times they've opened this menu
|
||
|
tf_trade_up_use_count.SetValue( tf_trade_up_use_count.GetInt() - 1 );
|
||
|
|
||
|
// Open it up!
|
||
|
GetCollectionCraftPanel()->Show( vecSelectedItems );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Collection crafting
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoHalloweenOffering()
|
||
|
{
|
||
|
// Open it up!
|
||
|
if ( !m_pHalloweenOfferingPanel )
|
||
|
{
|
||
|
m_pHalloweenOfferingPanel = vgui::SETUP_PANEL( new CHalloweenOfferingPanel( this, m_pMouseOverTooltip ) );
|
||
|
m_pHalloweenOfferingPanel->InvalidateLayout( true, true );
|
||
|
}
|
||
|
// empty
|
||
|
CUtlVector< const CEconItemView* > vecSelectedItems;
|
||
|
m_pHalloweenOfferingPanel->Show( vecSelectedItems );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Craft Common StatClock
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoCraftCommonStatClock()
|
||
|
{
|
||
|
// Open it up!
|
||
|
if ( !m_pMannCoTradePanel )
|
||
|
{
|
||
|
m_pMannCoTradePanel = vgui::SETUP_PANEL( new CCraftCommonStatClockPanel( this, m_pMouseOverTooltip ) ); // make this more generic
|
||
|
m_pMannCoTradePanel->InvalidateLayout( true, true );
|
||
|
}
|
||
|
|
||
|
CUtlVector< CItemModelPanel* > vecSelected;
|
||
|
GetSelectedPanels(SELECT_ALL, vecSelected);
|
||
|
|
||
|
CUtlVector< const CEconItemView* > vecSelectedItems;
|
||
|
FOR_EACH_VEC(vecSelected, i)
|
||
|
{
|
||
|
if (vecSelected[i]->GetItem() && GetCraftCommonStatClockInvalidReason(vecSelected[i]->GetItem(), NULL) == NULL)
|
||
|
{
|
||
|
vecSelectedItems.AddToTail(vecSelected[i]->GetItem());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_pMannCoTradePanel->Show( vecSelectedItems );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Bring up the 3D inspect panel for the selected item
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoInspectModel()
|
||
|
{
|
||
|
CUtlVector< CItemModelPanel* > vecSelected;
|
||
|
GetSelectedPanels( SELECT_FIRST, vecSelected );
|
||
|
|
||
|
if ( vecSelected.IsEmpty() )
|
||
|
return;
|
||
|
|
||
|
CEconItemView *pItem = vecSelected[0]->GetItem();
|
||
|
if ( pItem )
|
||
|
{
|
||
|
float flInspect = 0;
|
||
|
static CSchemaAttributeDefHandle pAttrib_WeaponAllowInspect( "weapon_allow_inspect" );
|
||
|
if ( ( FindAttribute_UnsafeBitwiseCast<attrib_value_t>( pItem, pAttrib_WeaponAllowInspect, &flInspect ) && flInspect != 0.f )
|
||
|
#ifdef STAGING_ONLY
|
||
|
|| tf_weapon_force_allow_inspect.GetBool()
|
||
|
#endif
|
||
|
)
|
||
|
{
|
||
|
m_pInspectPanel->SetVisible( true );
|
||
|
m_pInspectPanel->SetItemCopy( vecSelected[0]->GetItem() );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for ( int iClass = TF_FIRST_NORMAL_CLASS; iClass < TF_LAST_NORMAL_CLASS; ++iClass )
|
||
|
{
|
||
|
if ( pItem->GetStaticData()->CanBeUsedByClass( iClass ) )
|
||
|
{
|
||
|
m_pInspectCosmeticPanel->PreviewItem( iClass, pItem );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
m_pInspectCosmeticPanel->SetVisible( true );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OpenInspectModelPanelAndCopyItem( CEconItemView *pItemView )
|
||
|
{
|
||
|
if ( !pItemView )
|
||
|
return;
|
||
|
|
||
|
EconUI()->OpenEconUI( ECONUI_BACKPACK );
|
||
|
|
||
|
// Figure out which preview to show
|
||
|
float flInspect = 0;
|
||
|
static CSchemaAttributeDefHandle pAttrib_WeaponAllowInspect( "weapon_allow_inspect" );
|
||
|
if ( FindAttribute_UnsafeBitwiseCast<attrib_value_t>( pItemView, pAttrib_WeaponAllowInspect, &flInspect ) && flInspect != 0.f )
|
||
|
{
|
||
|
m_pInspectPanel->SetVisible( true );
|
||
|
m_pInspectPanel->SetItemCopy( pItemView );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for ( int iClass = TF_FIRST_NORMAL_CLASS; iClass < TF_LAST_NORMAL_CLASS; ++iClass )
|
||
|
{
|
||
|
if ( pItemView->GetStaticData()->CanBeUsedByClass( iClass ) )
|
||
|
{
|
||
|
m_pInspectCosmeticPanel->PreviewItemCopy( iClass, pItemView );
|
||
|
m_pInspectCosmeticPanel->SetVisible( true );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CCollectionCraftingPanel* CBackpackPanel::GetCollectionCraftPanel()
|
||
|
{
|
||
|
if ( !m_pCollectionCraftPanel )
|
||
|
{
|
||
|
m_pCollectionCraftPanel = vgui::SETUP_PANEL( new CCollectionCraftingPanel( this, m_pMouseOverTooltip ) );
|
||
|
m_pCollectionCraftPanel->InvalidateLayout( true, true );
|
||
|
}
|
||
|
|
||
|
return m_pCollectionCraftPanel;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Buy a key, and then immediately use it on the selected crate once
|
||
|
// tbe store transaction completes
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoBuyKeyAndOpenCrate()
|
||
|
{
|
||
|
CUtlVector< CItemModelPanel* > vecSelected;
|
||
|
GetSelectedPanels( SELECT_FIRST, vecSelected );
|
||
|
|
||
|
if ( vecSelected.IsEmpty() )
|
||
|
return;
|
||
|
|
||
|
m_hQuickOpenCrate.SetItem( vecSelected.Head()->GetItem() );
|
||
|
|
||
|
uint32 iDecoableItemDef = 0;
|
||
|
if ( GetDecodedByItemDefIndex( m_hQuickOpenCrate, &iDecoableItemDef ) )
|
||
|
{
|
||
|
// casting to the proper type since our econ system is dumb
|
||
|
const float& value_as_float = (float&)iDecoableItemDef;
|
||
|
CEconItemDefinition * pDefIndex = GetItemSchema()->GetItemDefinition( (int)value_as_float );
|
||
|
|
||
|
EconUI()->GetStorePanel()->AddToCartAndCheckoutImmediately( pDefIndex->GetDefinitionIndex() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Find the first compatible key in our inventory, and use it on the
|
||
|
// selected crate
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoOpenCrateWithKey()
|
||
|
{
|
||
|
CUtlVector< CItemModelPanel* > vecSelected;
|
||
|
GetSelectedPanels( SELECT_FIRST, vecSelected );
|
||
|
|
||
|
if ( vecSelected.IsEmpty() )
|
||
|
return;
|
||
|
|
||
|
CEconItemView *pCrate = vecSelected.Head()->GetItem();
|
||
|
|
||
|
CEconItemView *pKey = GetFirstCompatibleKeyForCrate( pCrate );
|
||
|
if ( !pKey )
|
||
|
return;
|
||
|
|
||
|
ApplyTool( this, pKey, pCrate );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Open up the loadout for a class
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoEquipForClass( int nClass )
|
||
|
{
|
||
|
// Negative because reasons
|
||
|
EconUI()->OpenEconUI( -nClass );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Given a paint can index, offer to use one or buy one
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoPaint( int nPaintItemIndex, bool bUseStore, bool bUseMarket )
|
||
|
{
|
||
|
if ( !bUseStore && !bUseMarket )
|
||
|
{
|
||
|
AttemptToUseItem( nPaintItemIndex );
|
||
|
}
|
||
|
|
||
|
if ( bUseStore )
|
||
|
{
|
||
|
AttemptToShowItemInStore( nPaintItemIndex );
|
||
|
}
|
||
|
else if ( bUseMarket )
|
||
|
{
|
||
|
AttemptToShowItemInMarket( nPaintItemIndex );
|
||
|
}
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Given a strange part index, offer to use one or buy one (Market)
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::DoStrangePart( int nStrangePartIndex, bool bUseMarket )
|
||
|
{
|
||
|
if ( !bUseMarket )
|
||
|
{
|
||
|
AttemptToUseItem( nStrangePartIndex );
|
||
|
}
|
||
|
|
||
|
if ( bUseMarket )
|
||
|
{
|
||
|
AttemptToShowItemInMarket( nStrangePartIndex );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Try to find the first item with the passed-in item name in our inventory
|
||
|
// and try to use it on the selected panel's item. If we dont have an item
|
||
|
// matching the name passed in, go to the store and prompt the user to buy one.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CBackpackPanel::AttemptToUseItem( item_definition_index_t iItemDefIndex )
|
||
|
{
|
||
|
CUtlVector< CItemModelPanel* > m_vecSelected;
|
||
|
GetSelectedPanels( SELECT_FIRST, m_vecSelected );
|
||
|
Assert( m_vecSelected.Count() );
|
||
|
if ( !m_vecSelected.Count() )
|
||
|
return false;
|
||
|
|
||
|
CEconItemView *pSelectedItem = m_vecSelected.Head()->GetItem();
|
||
|
Assert( pSelectedItem );
|
||
|
if ( !pSelectedItem )
|
||
|
return false;
|
||
|
|
||
|
CEconItemView *pNameTag = CTFPlayerInventory::GetFirstItemOfItemDef( iItemDefIndex );
|
||
|
if ( pNameTag )
|
||
|
{
|
||
|
if ( ApplyTool( this, pNameTag, pSelectedItem ) )
|
||
|
{
|
||
|
CancelToolSelection();
|
||
|
UpdateModelPanels();
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::AttemptToShowItemInStore( item_definition_index_t iItemDefIndex )
|
||
|
{
|
||
|
CUtlVector< CItemModelPanel* > m_vecSelected;
|
||
|
GetSelectedPanels( SELECT_FIRST, m_vecSelected );
|
||
|
Assert( m_vecSelected.Count() );
|
||
|
if( !m_vecSelected.Count() )
|
||
|
return;
|
||
|
|
||
|
CEconItemView *pSelectedItem = m_vecSelected.Head()->GetItem();
|
||
|
Assert( pSelectedItem );
|
||
|
if ( !pSelectedItem )
|
||
|
return;
|
||
|
|
||
|
EconUI()->OpenStorePanel( iItemDefIndex, false );
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::AttemptToShowItemInMarket( item_definition_index_t iItemDefIndex )
|
||
|
{
|
||
|
CUtlVector< CItemModelPanel* > m_vecSelected;
|
||
|
GetSelectedPanels( SELECT_FIRST, m_vecSelected );
|
||
|
Assert( m_vecSelected.Count() );
|
||
|
if ( !m_vecSelected.Count() )
|
||
|
return;
|
||
|
|
||
|
CEconItemView *pSelectedItem = m_vecSelected.Head()->GetItem();
|
||
|
Assert( pSelectedItem );
|
||
|
if ( !pSelectedItem )
|
||
|
return;
|
||
|
|
||
|
CEconItemDefinition *pItemDef = GetItemSchema()->GetItemDefinition( iItemDefIndex );
|
||
|
Assert( pItemDef );
|
||
|
if ( !pItemDef )
|
||
|
return;
|
||
|
|
||
|
if ( !CBaseAdPanel::CheckForRequiredSteamComponents( "#StoreUpdate_SteamRequired", "#MMenu_OverlayRequired" ) )
|
||
|
return;
|
||
|
|
||
|
if ( pItemDef && steamapicontext && steamapicontext->SteamFriends() )
|
||
|
{
|
||
|
const char *pszPrefix = "";
|
||
|
if ( GetUniverse() == k_EUniverseBeta )
|
||
|
{
|
||
|
pszPrefix = "beta.";
|
||
|
}
|
||
|
|
||
|
static char pszItemName[256];
|
||
|
g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( pItemDef->GetItemBaseName() ), pszItemName, sizeof( pszItemName ) );
|
||
|
|
||
|
char szURL[512];
|
||
|
V_snprintf( szURL, sizeof( szURL ), "http://%ssteamcommunity.com/market/listings/%d/%s", pszPrefix, engine->GetAppID(), pszItemName );
|
||
|
steamapicontext->SteamFriends()->ActivateGameOverlayToWebPage( szURL );
|
||
|
}
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Get the first, or all selected item model panels
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::GetSelectedPanels( ESelection eSelection, CUtlVector< CItemModelPanel* >& m_vecSelected ) const
|
||
|
{
|
||
|
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
|
||
|
{
|
||
|
if ( m_pItemModelPanels[i]->IsSelected() && m_pItemModelPanels[i]->HasItem() )
|
||
|
{
|
||
|
m_vecSelected.AddToTail( m_pItemModelPanels[i] );
|
||
|
|
||
|
if ( eSelection == SELECT_FIRST )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OnCommand( const char *command )
|
||
|
{
|
||
|
if ( V_strncasecmp( command, "goto_page_", V_strlen( "goto_page_" ) ) == 0 )
|
||
|
{
|
||
|
int iPage = V_atoi( &command[ V_strlen( "goto_page_" ) ] );
|
||
|
SetCurrentPage( iPage );
|
||
|
UpdateModelPanels();
|
||
|
return;
|
||
|
}
|
||
|
else if ( !Q_strnicmp( command, "nextpage", 8 ) )
|
||
|
{
|
||
|
if ( !m_bDragging )
|
||
|
{
|
||
|
DeSelectAllBackpackItemPanels();
|
||
|
}
|
||
|
|
||
|
SetCurrentPage( GetCurrentPage() + 1 );
|
||
|
UpdateModelPanels();
|
||
|
return;
|
||
|
}
|
||
|
else if ( !Q_strnicmp( command, "prevpage", 8 ) )
|
||
|
{
|
||
|
if ( !m_bDragging )
|
||
|
{
|
||
|
DeSelectAllBackpackItemPanels();
|
||
|
}
|
||
|
|
||
|
SetCurrentPage( GetCurrentPage() - 1 );
|
||
|
UpdateModelPanels();
|
||
|
return;
|
||
|
}
|
||
|
else if ( !Q_strnicmp( command, "useitem", 7 ) )
|
||
|
{
|
||
|
AssertMsg( 0, "Everything should be going through the context menu. Fix the calling code." );
|
||
|
return;
|
||
|
}
|
||
|
else if ( !Q_strnicmp( command, "showbackpackitems", 17 ) )
|
||
|
{
|
||
|
SetShowBaseItems( false );
|
||
|
if ( m_pShowBaseItemsCheckbox )
|
||
|
{
|
||
|
m_pShowBaseItemsCheckbox->SetSelected( false );
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
else if ( !Q_strnicmp( command, "showbaseitems", 13 ) )
|
||
|
{
|
||
|
SetShowBaseItems( true );
|
||
|
if ( m_pShowBaseItemsCheckbox )
|
||
|
{
|
||
|
m_pShowBaseItemsCheckbox->SetSelected( true );
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
else if ( !Q_strnicmp( command, "canceltool", 10 ) )
|
||
|
{
|
||
|
CancelToolSelection();
|
||
|
UpdateModelPanels();
|
||
|
return;
|
||
|
}
|
||
|
else if ( !Q_stricmp( command, "show_explanations" ) )
|
||
|
{
|
||
|
if ( !m_flStartExplanationsAt )
|
||
|
{
|
||
|
m_flStartExplanationsAt = Plat_FloatTime();
|
||
|
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||
|
}
|
||
|
RequestFocus();
|
||
|
}
|
||
|
else if ( !Q_stricmp( command, "showdetails" ) )
|
||
|
{
|
||
|
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
|
||
|
{
|
||
|
if ( m_pItemModelPanels[i]->IsSelected() && m_pItemModelPanels[i]->HasItem() )
|
||
|
{
|
||
|
OpenArmory( m_pItemModelPanels[i]->GetItem() );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
UpdateModelPanels();
|
||
|
return;
|
||
|
}
|
||
|
else if ( !V_strnicmp( command, "equipclass", 10 ) )
|
||
|
{
|
||
|
int nClass = atoi( command + 10 );
|
||
|
DoEquipForClass( nClass );
|
||
|
}
|
||
|
else if ( !V_strnicmp( command, "paint", 5 ) )
|
||
|
{
|
||
|
int nIndex = atoi( command + 5 );
|
||
|
DoPaint( nIndex, false, false );
|
||
|
}
|
||
|
else if ( !V_strnicmp( command, "market_paint", 12 ) )
|
||
|
{
|
||
|
int nIndex = atoi( command + 12 );
|
||
|
DoPaint( nIndex, false, true );
|
||
|
}
|
||
|
else if ( !V_strnicmp( command, "store_paint", 11 ) )
|
||
|
{
|
||
|
int nIndex = atoi( command + 11 );
|
||
|
DoPaint( nIndex, true, false );
|
||
|
}
|
||
|
else if ( !V_strnicmp( command, "strangepart_", 12 ) )
|
||
|
{
|
||
|
int nIndex = atoi( command + 12 );
|
||
|
DoStrangePart( nIndex, false );
|
||
|
}
|
||
|
else if ( !V_strnicmp( command, "market_strangepart_", 19 ) )
|
||
|
{
|
||
|
int nIndex = atoi( command + 19 );
|
||
|
DoStrangePart( nIndex, true );
|
||
|
}
|
||
|
else if ( !V_strnicmp( command, "Context_CraftUpCollection", 25 ) )
|
||
|
{
|
||
|
DoCraftUpCollection();
|
||
|
}
|
||
|
else if ( !V_strnicmp( command, "Context_CraftCommonStatClock", 25 ) )
|
||
|
{
|
||
|
DoCraftCommonStatClock();
|
||
|
}
|
||
|
#ifdef STAGING_ONLY
|
||
|
else if ( !V_strnicmp( command, "unpin", 5 ) )
|
||
|
{
|
||
|
m_pMouseOverCardPanel->PinCard( false );
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
BaseClass::OnCommand( command );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::OpenArmory( CEconItemView* item )
|
||
|
{
|
||
|
PostMessage( GetParent()->GetParent()->GetParent(), new KeyValues("OpenArmoryDirect", "itemdef", item->GetItemDefIndex() ) );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::CancelToolSelection( void )
|
||
|
{
|
||
|
if ( m_eSelectionMode == StandardSelection )
|
||
|
return;
|
||
|
|
||
|
m_eSelectionMode = StandardSelection;
|
||
|
|
||
|
ClearNameFilter( false );
|
||
|
|
||
|
OnCommand( "showbackpackitems" );
|
||
|
|
||
|
SetCurrentPage( m_nLastToolPage );
|
||
|
m_nLastToolPage = 0;
|
||
|
|
||
|
m_ToolSelectionItem.Invalidate();
|
||
|
if ( m_pToolIcon )
|
||
|
{
|
||
|
m_pToolIcon->SetVisible( false );
|
||
|
}
|
||
|
DeSelectAllBackpackItemPanels();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::SetShowBaseItems( bool bShow )
|
||
|
{
|
||
|
bool bGoToFirstPage = m_bShowBaseItems != bShow;
|
||
|
m_bShowBaseItems = bShow;
|
||
|
if( bGoToFirstPage )
|
||
|
{
|
||
|
SetCurrentPage( 0 );
|
||
|
}
|
||
|
|
||
|
DeSelectAllBackpackItemPanels();
|
||
|
if ( m_pToolIcon )
|
||
|
{
|
||
|
m_pToolIcon->SetVisible( false );
|
||
|
}
|
||
|
UpdateModelPanels();
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
ConVar *CBackpackPanel::GetExplanationConVar( void )
|
||
|
{
|
||
|
return &tf_explanations_backpackpanel;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CBackpackPanel::SetCurrentPage( int nNewPage )
|
||
|
{
|
||
|
if( m_pToolIcon )
|
||
|
{
|
||
|
m_pToolIcon->SetVisible( false );
|
||
|
}
|
||
|
|
||
|
if ( nNewPage < 0 )
|
||
|
{
|
||
|
nNewPage = GetNumPages() - 1;
|
||
|
}
|
||
|
else if ( nNewPage >= GetNumPages() )
|
||
|
{
|
||
|
nNewPage = 0;
|
||
|
}
|
||
|
|
||
|
// deselect old page button
|
||
|
if ( m_Pages.Count() > GetCurrentPage() && m_Pages[GetCurrentPage()] )
|
||
|
{
|
||
|
CExButton* pButton = dynamic_cast<CExButton*>( m_Pages[GetCurrentPage()]->FindChildByName( "Button" ) );
|
||
|
if ( pButton )
|
||
|
{
|
||
|
pButton->SetSelected( false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BaseClass::SetCurrentPage( nNewPage );
|
||
|
|
||
|
// mark new page button as selected
|
||
|
if ( m_Pages.Count() > GetCurrentPage() && m_Pages[GetCurrentPage()] )
|
||
|
{
|
||
|
CExButton* pButton = dynamic_cast<CExButton*>( m_Pages[GetCurrentPage()]->FindChildByName( "Button" ) );
|
||
|
if ( pButton )
|
||
|
{
|
||
|
pButton->SetSelected( true );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
int CBackpackPanel::GetItemQualityForBorder( CItemModelPanel* pItemPanel ) const
|
||
|
{
|
||
|
if ( pItemPanel->HasItem() && ( cl_showbackpackrarities.GetInt() > 0 || m_bForceShowBackpackRarities )
|
||
|
&& ( cl_showbackpackrarities.GetInt() < 2 || pItemPanel->GetItem()->IsMarketable() ) )
|
||
|
{
|
||
|
uint8 nRarity = pItemPanel->GetItem()->GetItemDefinition()->GetRarity();
|
||
|
if ( ( nRarity != k_unItemRarity_Any ) && ( pItemPanel->GetItem()->GetItemQuality() != AE_SELFMADE ) )
|
||
|
{
|
||
|
// translate this quality to rarity
|
||
|
return nRarity + AE_RARITY_DEFAULT;
|
||
|
}
|
||
|
|
||
|
return pItemPanel->GetItem()->GetItemQuality();
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|