Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
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.

392 lines
12 KiB

5 years ago
//========= 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 );
}
}
}