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.
391 lines
12 KiB
391 lines
12 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "tf_item_inspection_panel.h" |
|
#include "item_model_panel.h" |
|
#include "navigationpanel.h" |
|
#include "gc_clientsystem.h" |
|
#include "econ_ui.h" |
|
#include "backpack_panel.h" |
|
#include "vgui_int.h" |
|
#include "cdll_client_int.h" |
|
#include "clientmode_tf.h" |
|
#include "ienginevgui.h" |
|
#include "tf_hud_mainmenuoverride.h" |
|
#include "econ_item_system.h" |
|
|
|
using namespace vgui; |
|
|
|
#ifdef STAGING_ONLY |
|
void cc_toggle_debug_inspect( IConVar *pConVar, const char *pOldString, float flOldValue ) |
|
{ |
|
// Too early? |
|
if ( ItemSystem()->GetItemSchema()->GetVersion() == 0 ) |
|
return; |
|
|
|
ConVarRef var( pConVar ); |
|
if ( var.IsValid() ) |
|
{ |
|
CTFItemInspectionPanel* pInspectionPanel = dynamic_cast< CTFItemInspectionPanel* >( EconUI()->GetBackpackPanel()->FindChildByName( "InspectionPanel" ) ); |
|
if ( pInspectionPanel ) |
|
{ |
|
bool bVisible = pInspectionPanel->IsVisible(); // Save visibility |
|
pInspectionPanel->Reset(); |
|
pInspectionPanel->SetVisible( bVisible ); // Restore visibility |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
ConVar tf_use_debug_inspection_panel( "tf_use_debug_inspection_panel", "0", FCVAR_ARCHIVE, "Toggles developer controls for the item inspection panel", cc_toggle_debug_inspect ); |
|
extern ConVar tf_paint_kit_force_regen; |
|
#endif |
|
|
|
|
|
|
|
// ******************************************************************************************************************************** |
|
// Given proto data, create an inspect panel |
|
static void Helper_LaunchPreviewWithPreviewDataBlock( CEconItemPreviewDataBlock const &protoData ) |
|
{ |
|
// Create an econ item view |
|
CEconItem econItem; |
|
econItem.DeserializeFromProtoBufItem( protoData.econitem() ); |
|
|
|
CEconItemView itemView; |
|
itemView.Init( econItem.GetDefinitionIndex(), econItem.GetQuality(), econItem.GetItemLevel(), econItem.GetAccountID() ); |
|
itemView.SetNonSOEconItem( &econItem ); |
|
|
|
// Get the Backpack to tell the inspect panel to render |
|
if ( EconUI()->GetBackpackPanel() ) |
|
{ |
|
EconUI()->GetBackpackPanel()->OpenInspectModelPanelAndCopyItem( &itemView ); |
|
} |
|
} |
|
|
|
// ******************************************************************************************************************************** |
|
// Request an item from the GC to inspect |
|
static void Helper_RequestEconActionPreview( uint64 paramS, uint64 paramA, uint64 paramD, uint64 paramM ) |
|
{ |
|
if ( !paramA || !paramD ) |
|
return; |
|
if ( !paramS && !paramM ) |
|
return; |
|
|
|
static double s_flTime = 0.0f; |
|
double flNow = Plat_FloatTime(); |
|
if ( s_flTime && ( flNow - s_flTime <= 2.5 ) ) |
|
return; |
|
|
|
s_flTime = flNow; |
|
GCSDK::CProtoBufMsg< CMsgGC_Client2GCEconPreviewDataBlockRequest > msg( k_EMsgGC_Client2GCEconPreviewDataBlockRequest ); |
|
msg.Body().set_param_s( paramS ); |
|
msg.Body().set_param_a( paramA ); |
|
msg.Body().set_param_d( paramD ); |
|
msg.Body().set_param_m( paramM ); |
|
GCClientSystem()->GetGCClient()->BSendMessage( msg ); |
|
} |
|
|
|
// ******************************************************************************************************************************** |
|
class CGCClient2GCEconPreviewDataBlockResponse : public GCSDK::CGCClientJob |
|
{ |
|
public: |
|
CGCClient2GCEconPreviewDataBlockResponse( GCSDK::CGCClient *pGCClient ) : GCSDK::CGCClientJob( pGCClient ) { } |
|
|
|
virtual bool BYieldingRunJobFromMsg( GCSDK::IMsgNetPacket *pNetPacket ) |
|
{ |
|
GCSDK::CProtoBufMsg<CMsgGC_Client2GCEconPreviewDataBlockResponse> msg( pNetPacket ); |
|
Helper_LaunchPreviewWithPreviewDataBlock( msg.Body().iteminfo() ); |
|
return true; |
|
} |
|
}; |
|
GC_REG_JOB( GCSDK::CGCClient, CGCClient2GCEconPreviewDataBlockResponse, "CGCClient2GCEconPreviewDataBlockResponse", k_EMsgGC_Client2GCEconPreviewDataBlockResponse, GCSDK::k_EServerTypeGCClient ); |
|
|
|
// ******************************************************************************************************************************** |
|
CON_COMMAND_F( tf_econ_item_preview, "Preview an economy item", FCVAR_DONTRECORD | FCVAR_HIDDEN | FCVAR_CLIENTCMD_CAN_EXECUTE ) |
|
{ |
|
if ( args.ArgC() < 2 ) |
|
return; |
|
|
|
//// kill the workshop preview dialog if it's up |
|
//if ( g_pWorkshopWorkbenchDialog ) |
|
//{ |
|
// delete g_pWorkshopWorkbenchDialog; |
|
// g_pWorkshopWorkbenchDialog = NULL; |
|
//} |
|
|
|
//extern float g_flReadyToCheckForPCBootInvite; |
|
//if ( !g_flReadyToCheckForPCBootInvite || !gpGlobals->curtime || !gpGlobals->framecount ) |
|
//{ |
|
// ConMsg( "Deferring csgo_econ_action_preview command!\n" ); |
|
// return; |
|
//} |
|
|
|
// Encoded parameter, validate basic length |
|
char const *pchEncodedAscii = args.Arg( 1 ); |
|
int nLen = Q_strlen( pchEncodedAscii ); |
|
if ( nLen <= 16 ) { Assert( 0 ); return; } |
|
|
|
// If we are launched with new format requesting steam_ownerid and assetid then do async query |
|
if ( *pchEncodedAscii == 'S' ) |
|
{ |
|
uint64 uiParamS = Q_atoui64( pchEncodedAscii + 1 ); |
|
uint64 uiParamA = 0; |
|
uint64 uiParamD = 0; |
|
if ( char const *pchParamA = strchr( pchEncodedAscii, 'A' ) ) |
|
{ |
|
uiParamA = Q_atoui64( pchParamA + 1 ); |
|
if ( char const *pchParamD = strchr( pchEncodedAscii, 'D' ) ) |
|
{ |
|
uiParamD = Q_atoui64( pchParamD + 1 ); |
|
Helper_RequestEconActionPreview( uiParamS, uiParamA, uiParamD, 0ull ); |
|
} |
|
} |
|
return; |
|
} |
|
|
|
// Else if we are launched with new format requesting market listing id and assetid then do async query |
|
if ( *pchEncodedAscii == 'M' ) |
|
{ |
|
uint64 uiParamM = Q_atoui64( pchEncodedAscii + 1 ); |
|
uint64 uiParamA = 0; |
|
uint64 uiParamD = 0; |
|
if ( char const *pchParamA = strchr( pchEncodedAscii, 'A' ) ) |
|
{ |
|
uiParamA = Q_atoui64( pchParamA + 1 ); |
|
if ( char const *pchParamD = strchr( pchEncodedAscii, 'D' ) ) |
|
{ |
|
uiParamD = Q_atoui64( pchParamD + 1 ); |
|
Helper_RequestEconActionPreview( 0ull, uiParamA, uiParamD, uiParamM ); |
|
} |
|
} |
|
return; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTFItemInspectionPanel::CTFItemInspectionPanel( Panel* pPanel, const char *pszName ) |
|
: BaseClass( pPanel, pszName ) |
|
, m_pModelInspectPanel( NULL ) |
|
, m_pItemViewData( NULL ) |
|
, m_pSOEconItemData( NULL ) |
|
{ |
|
m_pModelInspectPanel = new CEmbeddedItemModelPanel( this, "ModelInspectionPanel" ); |
|
m_pTeamColorNavPanel = new CNavigationPanel( this, "TeamNavPanel" ); |
|
m_pItemNamePanel = new CItemModelPanel( this, "ItemName" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFItemInspectionPanel::ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
const char* pszFileName = "Resource/UI/econ/InspectionPanel.res"; |
|
#ifdef STAGING_ONLY |
|
if ( tf_use_debug_inspection_panel.GetBool() ) |
|
{ |
|
pszFileName = "Resource/UI/econ/InspectionPanel_Dev.res"; |
|
} |
|
#endif |
|
|
|
LoadControlSettings( pszFileName ); |
|
|
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFItemInspectionPanel::PerformLayout() |
|
{ |
|
CEconItemView* pItem = m_pModelInspectPanel->GetItem(); |
|
if ( pItem && pItem->IsValid() ) |
|
{ |
|
// Find out if we should show the team buttons if the item has team skins |
|
if ( m_pTeamColorNavPanel ) |
|
{ |
|
static CSchemaAttributeDefHandle pAttrTeamColoredPaintkit( "has team color paintkit" ); |
|
uint32 iHasTeamColoredPaintkit = 0; |
|
|
|
// Find out if the item has the attribute |
|
bool bShowTeamButton = FindAttribute_UnsafeBitwiseCast<attrib_value_t>( pItem, pAttrTeamColoredPaintkit, &iHasTeamColoredPaintkit ) && iHasTeamColoredPaintkit > 0; |
|
|
|
m_pTeamColorNavPanel->SetVisible( bShowTeamButton ); |
|
} |
|
|
|
// Show only the name if there's no rarity |
|
//m_pItemNamePanel->SetNameOnly( true ); |
|
|
|
// Force the description to update right now, or else it might be caught up |
|
// in the queue of 50 panels in the backpack which want to load their crap first |
|
m_pItemNamePanel->UpdateDescription(); |
|
} |
|
|
|
BaseClass::PerformLayout(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFItemInspectionPanel::OnCommand( const char *command ) |
|
{ |
|
if ( FStrEq( command, "close" ) ) |
|
{ |
|
// Clean up after ourselves and set the item back to red |
|
CEconItemView* pItem = m_pModelInspectPanel->GetItem(); |
|
if ( pItem ) |
|
{ |
|
pItem->SetTeamNumber( TF_TEAM_RED ); |
|
// We need to recomposite again because we might have a blue version |
|
// in the cache that might get used in a tooltip. |
|
RecompositeItem(); |
|
} |
|
|
|
SetVisible( false ); |
|
return; |
|
} |
|
#ifdef STAGING_ONLY |
|
else if ( FStrEq( command, "newseed" ) ) |
|
{ |
|
ConVarRef cv_seed( "tf_paint_kit_seed_override" ); |
|
cv_seed.SetValue( RandomInt( 0, 10000000 ) ); |
|
RecompositeItem(); |
|
return; |
|
} |
|
else if ( FStrEq( command, "changeteam" ) ) |
|
{ |
|
ConVarRef cv_team( "tf_paint_kit_team_override" ); |
|
cv_team.SetValue ( cv_team.GetInt() == 0 ? 1 : 0 ); |
|
RecompositeItem(); |
|
return; |
|
} |
|
else if ( V_strncmp( "wear", command, 4 ) == 0 ) |
|
{ |
|
int nWearLevel = atoi( command + 4 ); |
|
ConVarRef cv_wear( "tf_paint_kit_force_wear" ); |
|
cv_wear.SetValue( nWearLevel ); |
|
RecompositeItem(); |
|
return; |
|
} |
|
else if ( FStrEq( command, "refresh_skin" ) ) |
|
{ |
|
engine->ClientCmd_Unrestricted( "tf_paint_kit_override_refresh" ); |
|
RecompositeItem(); |
|
return; |
|
} |
|
#endif |
|
|
|
BaseClass::OnCommand( command ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFItemInspectionPanel::SetItem( CEconItemView *pItem ) |
|
{ |
|
m_pItemNamePanel->SetItem( pItem ); |
|
m_pModelInspectPanel->SetItem( pItem ); |
|
RecompositeItem(); |
|
InvalidateLayout(); |
|
m_pTeamColorNavPanel->UpdateButtonSelectionStates( 0 ); |
|
} |
|
//----------------------------------------------------------------------------- |
|
void CTFItemInspectionPanel::SetSpecialAttributesOnly( bool bSpecialOnly ) |
|
{ |
|
if ( m_pItemNamePanel ) |
|
{ |
|
if ( bSpecialOnly ) |
|
{ |
|
m_pItemNamePanel->SetNameOnly( false ); |
|
} |
|
m_pItemNamePanel->SetSpecialAttributesOnly( bSpecialOnly ); |
|
} |
|
} |
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFItemInspectionPanel::Reset() |
|
{ |
|
InvalidateLayout( true, true ); |
|
SetItem( m_pItemViewData ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
void CTFItemInspectionPanel::SetItemCopy( CEconItemView *pItem ) |
|
{ |
|
// Make a copy of SO data since it comes from the market and will fall out of scope |
|
if ( m_pItemViewData ) |
|
{ |
|
delete m_pItemViewData; |
|
m_pItemViewData = NULL; |
|
} |
|
|
|
if ( m_pSOEconItemData ) |
|
{ |
|
delete m_pSOEconItemData; |
|
m_pSOEconItemData = NULL; |
|
} |
|
|
|
if ( pItem ) |
|
{ |
|
m_pItemViewData = new CEconItemView( *pItem ); |
|
m_pSOEconItemData = new CEconItem( *pItem->GetSOCData() ); |
|
m_pItemViewData->SetNonSOEconItem( m_pSOEconItemData ); |
|
// always use high res for inspect |
|
m_pItemViewData->SetWeaponSkinUseHighRes( true ); |
|
} |
|
SetItem( m_pItemViewData ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFItemInspectionPanel::OnRadioButtonChecked( vgui::Panel *panel ) |
|
{ |
|
OnCommand( panel->GetName() ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFItemInspectionPanel::OnNavButtonSelected( KeyValues *pData ) |
|
{ |
|
const int iTeam = pData->GetInt( "userdata", -1 ); AssertMsg( iTeam >= 0, "Bad filter" ); |
|
if ( iTeam < 0 ) |
|
return; |
|
|
|
CEconItemView* pItem = m_pModelInspectPanel->GetItem(); |
|
if ( pItem ) |
|
{ |
|
pItem->SetTeamNumber( iTeam ); |
|
|
|
RecompositeItem(); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFItemInspectionPanel::RecompositeItem() |
|
{ |
|
// Force a reload of the skin |
|
CEconItemView* pItem = m_pModelInspectPanel->GetItem(); |
|
if ( pItem ) |
|
{ |
|
#ifdef STAGING_ONLY |
|
if ( !tf_paint_kit_force_regen.GetBool() ) |
|
#endif |
|
{ |
|
pItem->CancelWeaponSkinComposite(); |
|
pItem->SetWeaponSkinBase( NULL ); |
|
pItem->SetWeaponSkinBaseCompositor( NULL ); |
|
} |
|
} |
|
}
|
|
|