This commit is contained in:
FluorescentCIAAfricanAmerican
2020-04-22 12:56:21 -04:00
commit 3bf9df6b27
15370 changed files with 5489726 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+268
View File
@@ -0,0 +1,268 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef BACKPACK_PANEL_H
#define BACKPACK_PANEL_H
#ifdef _WIN32
#pragma once
#endif
#include "base_loadout_panel.h"
#include "tf_item_inspection_panel.h"
#define BACKPACK_SLOTS_PER_PAGE 50
#define BACKPACK_ROWS 5
#define BACKPACK_COLUMNS (BACKPACK_SLOTS_PER_PAGE / BACKPACK_ROWS)
#define BACKPACK_MAX_PAGES (MAX_NUM_BACKPACK_SLOTS / BACKPACK_SLOTS_PER_PAGE)
class CDynamicRecipePanel;
class CItemSlotPanel;
class CStrangeCountTransferPanel;
class CCollectionCraftingPanel;
class CHalloweenOfferingPanel;
class CCraftCommonStatClockPanel;
class CTFStorePreviewItemPanel2;
//-----------------------------------------------------------------------------
// An inventory screen that handles displaying the backpack
//-----------------------------------------------------------------------------
class CBackpackPanel : public CBaseLoadoutPanel
{
DECLARE_CLASS_SIMPLE( CBackpackPanel, CBaseLoadoutPanel );
public:
CBackpackPanel( vgui::Panel *parent, const char *panelName );
virtual ~CBackpackPanel();
virtual const char *GetResFile( void ) { return "Resource/UI/econ/BackpackPanel.res"; }
virtual void ApplySchemeSettings( vgui::IScheme *pScheme ) OVERRIDE;
virtual void ApplySettings( KeyValues *inResourceData ) OVERRIDE;
virtual void PerformLayout( void ) OVERRIDE;
virtual void FireGameEvent( IGameEvent *event ) OVERRIDE;
virtual void UpdateModelPanels( void );
virtual int GetNumItemPanels( void ) { return BACKPACK_SLOTS_PER_PAGE; };
virtual void OnShowPanel( bool bVisible, bool bReturningFromArmory );
virtual void PostShowPanel( bool bVisible );
virtual bool UsesRarityControls( void ) { return true; }
virtual bool AllowSelection( void ) { return true; }
virtual bool AllowDragging( CItemModelPanel *panel ) { return true; }
virtual int GetNumSlotsPerPage( void ) OVERRIDE { return BACKPACK_SLOTS_PER_PAGE; }
virtual int GetNumColumns( void ) OVERRIDE { return BACKPACK_COLUMNS; }
virtual int GetNumRows( void ) OVERRIDE { return BACKPACK_ROWS; }
virtual int GetNumPages( void ) OVERRIDE;
virtual void SetCurrentPage( int nNewPage ) OVERRIDE;
virtual void AssignItemToPanel( CItemModelPanel *pPanel, int iIndex );
virtual void OnItemPanelEntered( vgui::Panel *panel ) OVERRIDE;
virtual void OpenContextMenu();
MESSAGE_FUNC_PTR( OnItemPanelMousePressed, "ItemPanelMousePressed", panel );
MESSAGE_FUNC_PTR( OnItemPanelMouseReleased, "ItemPanelMouseReleased", panel );
MESSAGE_FUNC_PTR( OnItemPanelMouseRightRelease, "ItemPanelMouseRightRelease", panel );
MESSAGE_FUNC_INT_INT( OnCursorMoved, "OnCursorMoved", x, y );
MESSAGE_FUNC_INT_INT( OnItemPanelCursorMoved, "ItemPanelCursorMoved", x, y );
MESSAGE_FUNC_PARAMS( OnConfirmDelete, "ConfirmDlgResult", data );
MESSAGE_FUNC_PARAMS( OnTextChanged, "TextChanged", data );
MESSAGE_FUNC_PARAMS( OnButtonChecked, "CheckButtonChecked", pData );
MESSAGE_FUNC( OnCancelSelection, "CancelSelection" );
MESSAGE_FUNC( DoTradeToPlayer, "DoTradeToPlayer" );
MESSAGE_FUNC( DoSellMarketplace, "DoSellMarketplace" );
MESSAGE_FUNC( DoDescription, "DoDescription" );
MESSAGE_FUNC( DoRename, "DoRename" );
MESSAGE_FUNC( DoDelete, "DoDelete" );
MESSAGE_FUNC( DoApplyOnItem, "Context_ApplyOnItem" );
MESSAGE_FUNC( DoUseConsumableItem, "Context_UseConsumableItem" );
MESSAGE_FUNC( DoUnwrapItem, "Context_UnwrapItem" );
MESSAGE_FUNC( DoDeliverItem, "Context_DeliverItem" );
MESSAGE_FUNC( DoApplyByItem, "Context_ApplyByItem" );
MESSAGE_FUNC( DoShuffle, "Context_Shuffle" );
MESSAGE_FUNC( DoEditSlot, "Context_EditSlot" );
MESSAGE_FUNC( DoRefurbishItem, "Context_RefurbishItem" );
MESSAGE_FUNC( DoGetItemFromStore, "Context_GetItemFromStore" );
MESSAGE_FUNC( DoOpenDuckLeaderboards, "Context_OpenDuckLeaderboards" );
MESSAGE_FUNC( DoInspectModel, "Context_InspectModel" );
MESSAGE_FUNC( DoBuyKeyAndOpenCrate, "Context_BuyKeyAndOpenCrate" );
MESSAGE_FUNC( DoOpenCrateWithKey, "Context_OpenCrateWithKey" );
MESSAGE_FUNC( DoStrangeCountTransfer, "Context_OpenStrangeCountTransfer" );
MESSAGE_FUNC( DoCraftUpCollection, "Context_CraftUpCollection" );
MESSAGE_FUNC( DoHalloweenOffering, "Context_HalloweenOffering" );
MESSAGE_FUNC( DoCraftCommonStatClock, "Context_CraftCommonStatClock" );
void DoEquipForClass( int nClass );
void DoPaint( int nPaintItemIndex, bool bUseStore, bool bUseMarket );
void DoStrangePart( int nStrangePartIndex, bool bUseMarket );
enum ESelection
{
SELECT_FIRST,
SELECT_ALL
};
bool AttemptToUseItem( item_definition_index_t iItemDefIndex );
void AttemptToShowItemInStore( item_definition_index_t iItemDefIndex );
void AttemptToShowItemInMarket( item_definition_index_t iItemDefIndex );
void GetSelectedPanels( ESelection eSelection, CUtlVector< CItemModelPanel* >& m_vecSelected ) const;
virtual void OnCommand( const char *command );
virtual void OnTick( void );
virtual void OnThink( void );
virtual void OnKeyCodePressed( vgui::KeyCode code ) OVERRIDE;
virtual void OnKeyCodeReleased( vgui::KeyCode code ) OVERRIDE;
virtual void OnKeyCodeTyped(vgui::KeyCode code) OVERRIDE;
virtual void OnMouseReleased(vgui::MouseCode code) OVERRIDE;
virtual void OnMouseMismatchedRelease( vgui::MouseCode code, Panel* pPressedPanel ) OVERRIDE;
virtual void OnMouseCaptureLost() OVERRIDE;
void OnItemContentsChanged( CEconItemView *pEconItemView );
virtual void OpenArmory( CEconItemView* item );
void ToggleSelectBackpackItemPanel( CItemModelPanel *pPanel );
void DeSelectAllBackpackItemPanels( void );
CEconItemView* GetComboBoxOverlayUISeletionItem() { return &m_ComboBoxOverlaySelectionItem; }
void SetComboBoxOverlaySelectionItem( const CEconItemView *pEconItemView ) { m_ComboBoxOverlaySelectionItem = *pEconItemView; }
void SetCurrentTransactionID( uint64 nTxnID );
void CheckForQuickOpenKey();
void MarkItemIDDirty( itemid_t itemID );
void OpenInspectModelPanelAndCopyItem( CEconItemView *pItemView );
CCollectionCraftingPanel *GetCollectionCraftPanel();
protected:
virtual void StartDrag( int x, int y );
virtual void StopDrag( bool bSucceeded );
virtual bool CanDragTo( CItemModelPanel *pItemPanel, int iPanelIndex ) { return true; }
virtual void HandleDragTo( CItemModelPanel *pItemPanel, int iPanelIndex );
virtual int GetBackpackPosForPanelIndex( int iPanelIndex ) { return iPanelIndex + 1 + (GetCurrentPage() * GetNumSlotsPerPage()); }
virtual bool NeedsDerivedTickSignal( void ) { return false; }
int GetBackpackPositionForPanel( CItemModelPanel *pItemPanel );
virtual const char *GetGreyOutItemPanelReason( CItemModelPanel *pItemPanel );
virtual void SetBorderForItem( CItemModelPanel *pItemPanel, bool bMouseOver );
virtual bool IsIgnoringItemPanelEnters( void ) { return m_bDragging; }
virtual void AddNewItemPanel( int iPanelIndex );
virtual CItemModelPanel *GetItemPanelAtPos( int x, int y );
virtual void PositionItemPanel( CItemModelPanel *pPanel, int iIndex );
void CancelToolSelection( void );
void SetShowBaseItems( bool bShow );
virtual ConVar *GetExplanationConVar( void );
bool ShouldShowExplanations( void ) { return (!m_bItemsOnly && !InToolSelectionMode()); }
bool InToolSelectionMode() const { return m_eSelectionMode != StandardSelection; }
void SetupToolSelectionItem();
void HandleToolItemSelection( CEconItemView *pItem );
void ClearNameFilter( bool bUpdateModelPanels );
bool HasNameFilter() const { return m_wNameFilter.Count() > 0; }
const wchar_t* GetNameFilter() const { return HasNameFilter() ? m_wNameFilter.Base() : NULL; }
void UpdateFilteringItems();
int GetItemQualityForBorder( CItemModelPanel* pItemPanel ) const;
int GetNumMaxPages() const { return BACKPACK_MAX_PAGES; }
int GetPageButtonIndexAtPos( int x, int y );
void SetPageButtonTextColorBasedOnContents();
void AddPaintToContextMenu( Menu *pPaintSubMenu, item_definition_index_t iPaintDef, bool bAddCommerce );
void AddCommerceToContextMenu( Menu *pMenu, const char* pszActionFmt, item_definition_index_t iItemDefIndex, bool bAddMarket, bool bAddStore );
void AddCommerceSubmenus( Menu *pSubMenu, item_definition_index_t iItemDef, const char* pszActionFmt );
void DoGiftToPlayer( );
protected:
vgui::TextEntry *m_pNameFilterTextEntry;
CUtlVector<wchar_t> m_wNameFilter;
float m_flFilterItemTime;
CUtlMap< int, CEconItemView*, int > m_mapFilteringItems;
CUtlMap< itemid_t, char > m_mapSeenItems;
bool m_bInitializedSeenItems;
CUtlVector< itemid_t > m_vecDirtyItems;
CExButton *m_pNextPageButton;
CExButton *m_pPrevPageButton;
CExButton *m_pShowExplanationsButton;
vgui::Label *m_pCurPageLabel;
vgui::ComboBox *m_pSortByComboBox;
vgui::ComboBox *m_pShowRarityComboBox;
vgui::CheckButton *m_pShowBaseItemsCheckbox;
CExButton *m_pDragToNextPageButton;
CExButton *m_pDragToPrevPageButton;
float m_flPreventDragPageSwitchUntil;
float m_flStartExplanationsAt;
// Dragging support
float m_flMouseDownTime;
int m_iMouseDownX;
int m_iMouseDownY;
CItemModelPanel *m_pItemDraggedFromPanel;
int m_iDraggedFromPage;
bool m_bMouseDownOnItemPanel;
bool m_bDragging;
CItemModelPanel *m_pMouseDragItemPanel;
int m_iDragOffsetX;
int m_iDragOffsetY;
CItemModelPanel *m_pPrevDragOverItemPanel;
// Deletion
vgui::EditablePanel *m_pConfirmDeleteDialog;
// Tool support
enum SelectionMode_t
{
StandardSelection,
ToolSelection,
};
SelectionMode_t m_eSelectionMode;
int m_nLastToolPage;
CEconItemView m_ToolSelectionItem;
CExButton *m_pCancelToolButton;
vgui::ScalableImagePanel *m_pToolIcon;
CEconItemView m_ComboBoxOverlaySelectionItem;
CExButton *m_pCraftButton;
// base items or backpack items
bool m_bShowBaseItems;
// positions of all our item panels, so we can handle drag & drop
struct backpackitempos_t
{
int x,y;
};
CUtlVector<backpackitempos_t> m_ItemModelPanelPos;
KeyValues *m_pPageButtonKVs;
int m_nNumActivePages;
CUtlVector< EditablePanel* > m_Pages;
CUtlVector<backpackitempos_t> m_PageButtonPos;
CDynamicRecipePanel* m_pDynamicRecipePanel;
CItemSlotPanel* m_pItemSlotPanel;
CUtlVector< item_definition_index_t > m_vecPaintCans;
CUtlVector< item_definition_index_t > m_vecStrangeParts;
DHANDLE<CStrangeCountTransferPanel> m_pStrangeToolPanel;
DHANDLE<CCollectionCraftingPanel> m_pCollectionCraftPanel;
DHANDLE<CHalloweenOfferingPanel> m_pHalloweenOfferingPanel;
DHANDLE<CCraftCommonStatClockPanel> m_pMannCoTradePanel; // Make this Panel Generic
CTFItemInspectionPanel *m_pInspectPanel;
CTFStorePreviewItemPanel2 *m_pInspectCosmeticPanel;
vgui::Menu *m_pContextMenu;
CEconItemViewHandle m_hQuickOpenCrate;
uint64 m_nQuickOpenTxn;
CPanelAnimationVarAliasType( int, m_iPageButtonYPos, "page_button_y", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iPageButtonXDelta, "page_button_x_delta", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iPageButtonYDelta, "page_button_y_delta", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iPageButtonPerRow, "page_button_per_row", "20", "int" );
CPanelAnimationVarAliasType( int, m_iPageButtonHeight, "page_button_height", "0", "proportional_int" );
};
#endif // BACKPACK_PANEL_H
+803
View File
@@ -0,0 +1,803 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "base_loadout_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/IInput.h"
#include "econ_ui.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
#ifdef STAGING_ONLY
ConVar tf_use_card_tooltips( "tf_use_card_tooltips", "0", FCVAR_ARCHIVE );
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CBaseLoadoutPanel::CBaseLoadoutPanel( vgui::Panel *parent, const char *panelName ) : EditablePanel(parent, panelName )
{
SetParent( parent );
// Use the client scheme
vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
SetScheme(scheme);
SetProportional( true );
m_pItemModelPanelKVs = NULL;
m_pMouseOverItemPanel = vgui::SETUP_PANEL( new CItemModelPanel( this, "mouseoveritempanel" ) );
m_pMouseOverTooltip = new CItemModelPanelToolTip( this );
m_pMouseOverTooltip->SetupPanels( this, m_pMouseOverItemPanel );
#ifdef STAGING_ONLY
m_pMouseOverCardPanel = vgui::SETUP_PANEL( new CTFItemCardPanel( this, "mouseovercardpanel" ) );
m_pMouseOverCardTooltip = new CItemCardPanelToolTip( this );
m_pMouseOverCardTooltip->SetupPanels( this, m_pMouseOverCardPanel );
#endif
m_pItemPanelBeingMousedOver = NULL;
m_pCaratLabel = NULL;
m_pClassLabel = NULL;
m_nCurrentPage = 0;
m_bTooltipKeyPressed = false;
SetMouseInputEnabled( true );
SetKeyBoardInputEnabled( true );
ListenForGameEvent( "inventory_updated" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CBaseLoadoutPanel::~CBaseLoadoutPanel()
{
if ( m_pItemModelPanelKVs )
{
m_pItemModelPanelKVs->deleteThis();
m_pItemModelPanelKVs = NULL;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
m_pCaratLabel = dynamic_cast<vgui::Label*>( FindChildByName("CaratLabel") );
m_pClassLabel = dynamic_cast<vgui::Label*>( FindChildByName("ClassLabel") );
m_bReapplyItemKVs = true;
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
{
SetBorderForItem( m_pItemModelPanels[i], false );
}
m_pMouseOverItemPanel->SetBorder( pScheme->GetBorder("LoadoutItemPopupBorder") );
CreateItemPanels();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::ApplySettings( KeyValues *inResourceData )
{
BaseClass::ApplySettings( inResourceData );
KeyValues *pItemKV = inResourceData->FindKey( "modelpanels_kv" );
if ( pItemKV )
{
if ( m_pItemModelPanelKVs )
{
m_pItemModelPanelKVs->deleteThis();
}
m_pItemModelPanelKVs = new KeyValues("modelpanels_kv");
pItemKV->CopySubkeys( m_pItemModelPanelKVs );
}
}
extern const char *g_szItemBorders[AE_MAX_TYPES][5];
extern ConVar cl_showbackpackrarities;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::SetBorderForItem( CItemModelPanel *pItemPanel, bool bMouseOver )
{
if ( !pItemPanel )
return;
const char *pszBorder = NULL;
if ( pItemPanel->IsGreyedOut() )
{
if( pItemPanel->IsSelected() )
{
pszBorder = "BackpackItemGrayedOut_Selected";
}
else
{
pszBorder = "BackpackItemGrayedOut";
}
}
else
{
int iRarity = 0;
if ( pItemPanel->HasItem() && cl_showbackpackrarities.GetBool() )
{
iRarity = pItemPanel->GetItem()->GetItemQuality() ;
uint8 nRarity = pItemPanel->GetItem()->GetItemDefinition()->GetRarity();
if ( ( nRarity != k_unItemRarity_Any ) && ( iRarity != AE_SELFMADE ) )
{
// translate this quality to rarity
iRarity = nRarity + AE_RARITY_DEFAULT;
}
}
if ( pItemPanel->IsSelected() )
{
pszBorder = g_szItemBorders[iRarity][2];
}
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 ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::ApplyKVsToItemPanels( void )
{
if ( m_pItemModelPanelKVs )
{
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
{
m_pItemModelPanels[i]->ApplySettings( m_pItemModelPanelKVs );
SetBorderForItem( m_pItemModelPanels[i], false );
m_pItemModelPanels[i]->InvalidateLayout();
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::PerformLayout( void )
{
if ( m_bReapplyItemKVs )
{
m_bReapplyItemKVs = false;
ApplyKVsToItemPanels();
}
BaseClass::PerformLayout();
// If we're items only, we hide various elements
if ( m_pCaratLabel )
{
m_pCaratLabel->SetVisible( !m_bItemsOnly );
}
if ( m_pClassLabel )
{
m_pClassLabel->SetVisible( !m_bItemsOnly );
}
if ( m_pMouseOverItemPanel->IsVisible() )
{
// The mouseover panel was visible. Fake a panel entry into the original panel to get it to show up again properly.
if ( m_pItemPanelBeingMousedOver )
{
OnItemPanelEntered( m_pItemPanelBeingMousedOver );
}
else
{
HideMouseOverPanel();
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::AddNewItemPanel( int iPanelIndex )
{
CItemModelPanel *pPanel = vgui::SETUP_PANEL( new CItemModelPanel( this, VarArgs("modelpanel%d", iPanelIndex) ) );
pPanel->SetActAsButton( true, true );
m_pItemModelPanels.AddToTail( pPanel );
#ifdef STAGING_ONLY
if ( tf_use_card_tooltips.GetBool() )
{
pPanel->SetTooltip( m_pMouseOverCardTooltip, "" );
}
else
#endif
pPanel->SetTooltip( m_pMouseOverTooltip, "" );
Assert( iPanelIndex == (m_pItemModelPanels.Count()-1) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::CreateItemPanels( void )
{
int iNumPanels = GetNumItemPanels();
if ( m_pItemModelPanels.Count() < iNumPanels )
{
for ( int i = m_pItemModelPanels.Count(); i < iNumPanels; i++ )
{
AddNewItemPanel(i);
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::ShowPanel( int iClass, bool bBackpack, bool bReturningFromArmory )
{
bool bShow = (iClass != 0 || bBackpack);
OnShowPanel( bShow, bReturningFromArmory );
SetVisible( bShow );
if ( bShow )
{
HideMouseOverPanel();
CreateItemPanels();
UpdateModelPanels();
// make the first slot be selected so controller input will work
static ConVarRef joystick( "joystick" );
if( joystick.IsValid() && joystick.GetBool() && m_pItemModelPanels.Count() && m_pItemModelPanels[0] )
{
m_pItemModelPanels[0]->SetSelected( true );
m_pItemModelPanels[0]->RequestFocus();
}
}
else
{
// clear items from panels to make sure that items get invalidate on show panel
FOR_EACH_VEC( m_pItemModelPanels, i )
{
m_pItemModelPanels[i]->SetItem( NULL );
}
}
if ( !bReturningFromArmory )
{
PostShowPanel( bShow );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::OnCommand( const char *command )
{
engine->ClientCmd( const_cast<char *>( command ) );
BaseClass::OnCommand( command );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::FireGameEvent( IGameEvent *event )
{
// If we're not visible, ignore all events
if ( !IsVisible() )
return;
const char *type = event->GetName();
if ( Q_strcmp( "inventory_updated", type ) == 0 )
{
// We need to refresh our model panels, because the items may have changed.
UpdateModelPanels();
}
}
CItemModelPanel *CBaseLoadoutPanel::FindBestPanelNavigationForDirection( const CItemModelPanel *pCurrentPanel, const Vector2D &vPos, const Vector2D &vDirection )
{
CItemModelPanel *pBestPanel = NULL;
// Start with the worst allowable score
float flDistance = GetWide() + GetTall();
float flDot = -1.0f;
float flClosenessScore = flDistance * ( 1.5f - flDot );
for ( int j = 0; j < m_pItemModelPanels.Count(); j++ )
{
CItemModelPanel *pTempPanel = m_pItemModelPanels[ j ];
if ( !pTempPanel || pTempPanel == pCurrentPanel )
continue;
// Get temp center position
int nX, nY;
pTempPanel->GetPos( nX, nY );
nX += pTempPanel->GetWide() / 2;
nY += pTempPanel->GetTall() / 2;
Vector2D vTempPos( nX, nY );
// Get distance and dot
Vector2D vDiff = vTempPos - vPos;
float flTempDistance = Vector2DNormalize( vDiff );
float flTempDot = vDiff.Dot( vDirection );
// Must be somewhat in the correct direction
if ( flTempDot <= 0.0f )
continue;
float flTempScore = flTempDistance * ( 1.5f - flTempDot );
if ( flClosenessScore > flTempScore )
{
flClosenessScore = flTempScore;
flDistance = flTempDistance;
flDot = flTempDot;
pBestPanel = pTempPanel;
}
}
return pBestPanel;
}
void CBaseLoadoutPanel::LinkModelPanelControllerNavigation( bool bForceRelink )
{
if ( m_pItemModelPanels.Count() < 2 )
return;
// first unlink everything
if( bForceRelink )
{
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
{
CItemModelPanel *pCurrentPanel = m_pItemModelPanels[ i ];
if ( !pCurrentPanel )
continue;
pCurrentPanel->SetNavUp( (vgui::Panel*)NULL );
pCurrentPanel->SetNavDown( (vgui::Panel*)NULL );
pCurrentPanel->SetNavLeft( (vgui::Panel*)NULL );
pCurrentPanel->SetNavRight( (vgui::Panel*)NULL );
}
}
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
{
CItemModelPanel *pCurrentPanel = m_pItemModelPanels[ i ];
if ( !pCurrentPanel )
continue;
// Get center position
int nX, nY;
pCurrentPanel->GetPos( nX, nY );
nX += pCurrentPanel->GetWide() / 2;
nY += pCurrentPanel->GetTall() / 2;
Vector2D vPos( nX, nY );
if ( !pCurrentPanel->GetNavUpName() || pCurrentPanel->GetNavUpName()[ 0 ] == '\0' )
{
CItemModelPanel *pBestPanel = FindBestPanelNavigationForDirection( pCurrentPanel, vPos, Vector2D( 0, -1 ) );
if ( pBestPanel )
{
pCurrentPanel->SetNavUp( pBestPanel->GetName() );
pBestPanel->SetNavDown( pCurrentPanel->GetName() );
}
}
if ( !pCurrentPanel->GetNavDownName() || pCurrentPanel->GetNavDownName()[ 0 ] == '\0' )
{
CItemModelPanel *pBestPanel = FindBestPanelNavigationForDirection( pCurrentPanel, vPos, Vector2D( 0, 1 ) );
if ( pBestPanel )
{
pCurrentPanel->SetNavDown( pBestPanel->GetName() );
pBestPanel->SetNavUp( pCurrentPanel->GetName() );
}
}
if ( !pCurrentPanel->GetNavLeftName() || pCurrentPanel->GetNavLeftName()[ 0 ] == '\0' )
{
CItemModelPanel *pBestPanel = FindBestPanelNavigationForDirection( pCurrentPanel, vPos, Vector2D( -1, 0 ) );
if ( pBestPanel )
{
pCurrentPanel->SetNavLeft( pBestPanel->GetName() );
pBestPanel->SetNavRight( pCurrentPanel->GetName() );
}
}
if ( !pCurrentPanel->GetNavRightName() || pCurrentPanel->GetNavRightName()[ 0 ] == '\0' )
{
CItemModelPanel *pBestPanel = FindBestPanelNavigationForDirection( pCurrentPanel, vPos, Vector2D( 1, 0 ) );
if ( pBestPanel )
{
pCurrentPanel->SetNavRight( pBestPanel->GetName() );
pBestPanel->SetNavLeft( pCurrentPanel->GetName() );
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::OnItemPanelEntered( vgui::Panel *panel )
{
CItemModelPanel *pItemPanel = dynamic_cast < CItemModelPanel * > ( panel );
if ( pItemPanel && IsVisible() )
{
CEconItemView *pItem = pItemPanel->GetItem();
if ( pItem && !IsIgnoringItemPanelEnters() && !pItemPanel->IsGreyedOut() )
{
m_pItemPanelBeingMousedOver = pItemPanel;
}
if ( !pItemPanel->IsSelected() )
{
SetBorderForItem( pItemPanel, true );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::OnItemPanelExited( vgui::Panel *panel )
{
CItemModelPanel *pItemPanel = dynamic_cast < CItemModelPanel * > ( panel );
if ( pItemPanel && IsVisible() )
{
if ( !pItemPanel->IsSelected() )
{
SetBorderForItem( pItemPanel, false );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::HideMouseOverPanel( void )
{
if ( m_pMouseOverItemPanel->IsVisible() )
{
m_pMouseOverItemPanel->SetVisible( false );
m_pItemPanelBeingMousedOver = NULL;
}
#ifdef STAGING_ONLY
if ( m_pMouseOverCardPanel->IsVisible() )
{
m_pMouseOverCardPanel->SetVisible( false );
m_pItemPanelBeingMousedOver = NULL;
}
#endif
}
//-----------------------------------------------------------------------------
// Purpose: Returns the index of the first selected item.
//-----------------------------------------------------------------------------
int CBaseLoadoutPanel::GetFirstSelectedItemIndex( bool bIncludeEmptySlots )
{
for ( int i = 0; i < m_pItemModelPanels.Count(); i++ )
{
if ( m_pItemModelPanels[i]->IsSelected() && ( bIncludeEmptySlots || m_pItemModelPanels[i]->HasItem() ) )
{
return i;
}
}
return -1;
}
//-----------------------------------------------------------------------------
// Purpose: Returns the first selected item model panel or NULL if there is no
// such panel.
//-----------------------------------------------------------------------------
CItemModelPanel *CBaseLoadoutPanel::GetFirstSelectedItemModelPanel (bool bIncludeEmptySlots )
{
int i = GetFirstSelectedItemIndex( bIncludeEmptySlots );
if( i == -1 )
return NULL;
else
return m_pItemModelPanels[ i ];
}
//-----------------------------------------------------------------------------
// Purpose: Returns the first selected econ item view or NULL if there is no
// selected item
//-----------------------------------------------------------------------------
CEconItemView *CBaseLoadoutPanel::GetFirstSelectedItem()
{
CItemModelPanel *pItemModelPanel = GetFirstSelectedItemModelPanel( false );
if( pItemModelPanel )
return pItemModelPanel->GetItem();
else
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Returns the next item in the specified direction, possibly switching
// pages to get there
//-----------------------------------------------------------------------------
bool CBaseLoadoutPanel::GetAdjacentItemIndex( int nIndex, int nPage, int *pnNewIndex, int *pnNewPage, int dx, int dy )
{
// if we don't have a valid index the right answer is always the first item on the first page
if( nIndex == -1 )
{
*pnNewIndex = 0;
*pnNewPage = nPage;
return true;
}
int nRow = nIndex / GetNumColumns() + dy;
int nColumn = nIndex % GetNumColumns() + dx;
// just limit us to the top and bottom edges
if( nRow < 0 || nRow >= GetNumRows() )
return false;
// for columns, try to switch pages
int nNewPage = nPage;
while( nColumn < 0 )
{
if( nNewPage == 0 )
break;
nNewPage--;
nColumn += GetNumColumns();
}
while( nColumn >= GetNumColumns() )
{
if( nNewPage == GetNumPages() - 1 )
break;
nNewPage++;
nColumn -= GetNumColumns();
}
if( nColumn < 0 )
{
if( nNewPage != nPage )
{
nColumn = 0;
}
else
{
return false;
}
}
else if( nColumn >= GetNumColumns() )
{
if( nNewPage != nPage )
{
nColumn = GetNumColumns() - 1;
}
else
{
return false;
}
}
// never change to an invisible panel
int nNewIndex = nRow * GetNumColumns() + nColumn;
if( nNewIndex >= m_pItemModelPanels.Count() || !m_pItemModelPanels[ nNewIndex ]->IsVisible() )
{
// try to find a model panel that's still valid so we find the last one on the last valid row
while( nNewIndex >= 0 && !m_pItemModelPanels[ nNewIndex ]->IsVisible() )
nNewIndex--;
if( nNewIndex < 0 || nNewIndex == nIndex )
return false;
}
*pnNewPage = nNewPage;
*pnNewIndex = nNewIndex;
return true;
}
//-----------------------------------------------------------------------------
// Purpose: selects the next item in the specified direction, possibly switching
// pages to get there
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::SelectAdjacentItem( int dx, int dy )
{
int nSelected = GetFirstSelectedItemIndex( true );
int nNewPage, nNewSelected;
bool bFoundNext = GetAdjacentItemIndex( nSelected, m_nCurrentPage, &nNewSelected, &nNewPage, dx, dy );
if( !bFoundNext )
{
vgui::surface()->PlaySound( "player/suit_denydevice.wav" );
return;
}
// change pages
if( nNewPage != m_nCurrentPage )
{
Assert( nNewPage >= 0 && nNewPage < GetNumPages() );
SetCurrentPage( nNewPage );
UpdateModelPanels();
}
// select the new model
if( nSelected != nNewSelected )
{
if( nSelected != -1 && m_pItemModelPanels[ nSelected ]->IsSelected() )
{
m_pItemModelPanels[ nSelected ]->SetSelected( false );
SetBorderForItem( m_pItemModelPanels[ nSelected ], false );
}
if( nNewSelected != -1 && !m_pItemModelPanels[ nNewSelected ]->IsSelected() )
{
m_pItemModelPanels[ nNewSelected ]->SetSelected( true );
SetBorderForItem( m_pItemModelPanels[ nNewSelected ], false );
if( m_bTooltipKeyPressed )
{
if( m_pItemModelPanels[ nNewSelected ]->HasItem() )
{
m_pMouseOverTooltip->ShowTooltip( m_pItemModelPanels[ nNewSelected ] );
}
else
{
m_pMouseOverTooltip->HideTooltip();
}
}
}
}
OnItemSelectionChanged();
}
//-----------------------------------------------------------------------------
// Purpose: Processes up/down/left/right keys for selecting items in the panel
//-----------------------------------------------------------------------------
bool CBaseLoadoutPanel::HandleItemSelectionKeyPressed( vgui::KeyCode code )
{
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
if ( nButtonCode == KEY_XBUTTON_UP ||
nButtonCode == KEY_XSTICK1_UP ||
nButtonCode == KEY_XSTICK2_UP ||
nButtonCode == KEY_UP )
{
SelectAdjacentItem( 0, -1 );
return true;
}
else if ( nButtonCode == KEY_XBUTTON_DOWN ||
nButtonCode == KEY_XSTICK1_DOWN ||
nButtonCode == KEY_XSTICK2_DOWN ||
nButtonCode == STEAMCONTROLLER_DPAD_DOWN ||
nButtonCode == KEY_DOWN )
{
SelectAdjacentItem( 0, 1 );
return true;
}
else if ( nButtonCode == KEY_XBUTTON_RIGHT ||
nButtonCode == KEY_XSTICK1_RIGHT ||
nButtonCode == KEY_XSTICK2_RIGHT ||
nButtonCode == STEAMCONTROLLER_DPAD_RIGHT ||
nButtonCode == KEY_RIGHT )
{
SelectAdjacentItem( 1, 0 );
return true;
}
else if ( nButtonCode == KEY_XBUTTON_LEFT ||
nButtonCode == KEY_XSTICK1_LEFT ||
nButtonCode == KEY_XSTICK2_LEFT ||
nButtonCode == STEAMCONTROLLER_DPAD_LEFT ||
nButtonCode == KEY_LEFT )
{
SelectAdjacentItem( -1, 0 );
return true;
}
else if ( code == KEY_PAGEDOWN ||
nButtonCode == KEY_XBUTTON_RIGHT_SHOULDER )
{
if( m_nCurrentPage < GetNumPages() - 1 )
{
SetCurrentPage( m_nCurrentPage + 1 );
UpdateModelPanels();
}
return true;
}
else if ( code == KEY_PAGEUP ||
nButtonCode == KEY_XBUTTON_LEFT_SHOULDER )
{
if( m_nCurrentPage > 0 )
{
SetCurrentPage( m_nCurrentPage - 1 );
UpdateModelPanels();
}
return true;
}
else if ( nButtonCode == KEY_XBUTTON_Y )
{
m_bTooltipKeyPressed = true;
CItemModelPanel *pSelection = GetFirstSelectedItemModelPanel( false );
if( pSelection )
{
m_pMouseOverTooltip->ResetDelay();
m_pMouseOverTooltip->ShowTooltip( pSelection );
}
return true;
}
else
{
return false;
}
}
//-----------------------------------------------------------------------------
// Purpose: Processes up/down/left/right keys for selecting items in the panel
//-----------------------------------------------------------------------------
bool CBaseLoadoutPanel::HandleItemSelectionKeyReleased( vgui::KeyCode code )
{
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
if( nButtonCode == KEY_XBUTTON_Y )
{
m_bTooltipKeyPressed = false;
m_pMouseOverTooltip->HideTooltip();
return true;
}
else
{
return false;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseLoadoutPanel::SetCurrentPage( int nNewPage )
{
if( nNewPage < 0 || nNewPage >= GetNumPages() )
return;
m_nCurrentPage = nNewPage;
}
+115
View File
@@ -0,0 +1,115 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef BASE_LOADOUT_PANEL_H
#define BASE_LOADOUT_PANEL_H
#ifdef _WIN32
#pragma once
#endif
#include "vgui_controls/EditablePanel.h"
#include "econ_controls.h"
#include "item_pickup_panel.h"
#include "GameEventListener.h"
#include "tf_item_card_panel.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CBaseLoadoutPanel : public vgui::EditablePanel, public CGameEventListener
{
DECLARE_CLASS_SIMPLE( CBaseLoadoutPanel, vgui::EditablePanel );
public:
CBaseLoadoutPanel( vgui::Panel *parent, const char *panelName );
virtual ~CBaseLoadoutPanel();
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void ApplySettings( KeyValues *inResourceData );
virtual void PerformLayout( void );
virtual void OnCommand( const char *command );
void ShowPanel( int iClass, bool bBackpack, bool bReturningFromArmory = false );
virtual void FireGameEvent( IGameEvent *event );
virtual int GetNumSlotsPerPage( void ) { return 1; }
virtual int GetNumColumns( void ) { return 99; }
virtual int GetNumRows( void ) { return 99; }
virtual int GetNumPages( void ) { return 1; }
virtual int GetCurrentPage() const { return m_nCurrentPage; }
virtual void SetCurrentPage( int nNewPage );
virtual int GetNumItemPanels( void ) { Assert(0); return 0; };
virtual void OnShowPanel( bool bVisible, bool bReturningFromArmory ) { return; }
virtual void PostShowPanel( bool bVisible ) { return; }
CItemModelPanel *FindBestPanelNavigationForDirection( const CItemModelPanel *pCurrentPanel, const Vector2D &vPos, const Vector2D &vDirection );
void LinkModelPanelControllerNavigation( bool bForceRelink );
virtual void AddNewItemPanel( int iPanelIndex );
MESSAGE_FUNC_PTR( OnItemPanelEntered, "ItemPanelEntered", panel );
MESSAGE_FUNC_PTR( OnItemPanelExited, "ItemPanelExited", panel );
void HideMouseOverPanel( void );
CItemModelPanel *GetMouseOverPanel( void ) { return m_pMouseOverItemPanel; }
CItemModelPanelToolTip *GetMouseOverToolTipPanel( void ) { return m_pMouseOverTooltip; }
protected:
virtual void UpdateModelPanels( void ) { return; }
virtual void SetBorderForItem( CItemModelPanel *pItemPanel, bool bMouseOver );
virtual bool IsIgnoringItemPanelEnters( void ) { return false; }
virtual void ApplyKVsToItemPanels( void );
virtual void CreateItemPanels( void );
virtual void OnItemSelectionChanged() {}
bool HandleItemSelectionKeyPressed( vgui::KeyCode code ) ;
bool HandleItemSelectionKeyReleased( vgui::KeyCode code ) ;
// helpers to get selected items
int GetFirstSelectedItemIndex( bool bIncludeEmptySlots );
CItemModelPanel *GetFirstSelectedItemModelPanel( bool bIncludeEmptySlots );
CEconItemView *GetFirstSelectedItem();
bool GetAdjacentItemIndex( int nIndex, int nPage, int *pnNewIndex, int *pnNewPage, int dx, int dy );
void SelectAdjacentItem( int dx, int dy );
protected:
CUtlVector<CItemModelPanel*> m_pItemModelPanels;
vgui::Label *m_pTitleLabel;
KeyValues *m_pItemModelPanelKVs;
bool m_bReapplyItemKVs;
bool m_bTooltipKeyPressed;
int m_nCurrentPage;
vgui::Label *m_pCaratLabel;
vgui::Label *m_pClassLabel;
CPanelAnimationVarAliasType( int, m_iItemXPosOffcenterA, "item_xpos_offcenter_a", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iItemXPosOffcenterB, "item_xpos_offcenter_b", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iItemYPos, "item_ypos", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iItemYDelta, "item_ydelta", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iButtonXPosOffcenter, "button_xpos_offcenter", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iButtonYPos, "button_ypos", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iButtonYDelta, "button_ydelta", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iItemBackpackOffcenterX, "item_backpack_offcenter_x", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iItemBackpackXDelta, "item_backpack_xdelta", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iItemBackpackYDelta, "item_backpack_ydelta", "0", "proportional_int" );
CPanelAnimationVar( bool, m_bItemsOnly, "items_only", "0" );
CPanelAnimationVar( bool, m_bForceShowBackpackRarities, "force_show_backpack_rarities", "0" );
CPanelAnimationVarAliasType( int, m_iDeleteButtonXPos, "button_override_delete_xpos", "0", "proportional_int" );
protected:
CItemModelPanel *m_pMouseOverItemPanel;
CItemModelPanelToolTip *m_pMouseOverTooltip;
CItemModelPanel *m_pItemPanelBeingMousedOver;
#ifdef STAGING_ONLY
CTFItemCardPanel *m_pMouseOverCardPanel;
CItemCardPanelToolTip *m_pMouseOverCardTooltip;
#endif
};
#endif // BASE_LOADOUT_PANEL_H
@@ -0,0 +1,107 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
#include "cbase.h"
#include "econ_gcmessages.h"
#include "econ_item_system.h"
#include "econ_ui.h"
#include "store/store_panel.h"
#include "gc_clientsystem.h"
#include "client_community_market.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
static const float s_fUpdateTimeInSeconds = 60.0f * 15.0f;
typedef CUtlMap< steam_market_gc_identifier_t, client_market_data_t, unsigned int > ClientMarketDataMap_t;
static ClientMarketDataMap_t s_mapClientMarketData;
static float g_fClientMarketDataLastUpdateTime = -s_fUpdateTimeInSeconds;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
static void ClientMarketData_Refresh()
{
if ( !EconUI() || !EconUI()->GetStorePanel() )
return;
GCSDK::CProtoBufMsg<CMsgGCClientMarketDataRequest> msg( k_EMsgGCClientRequestMarketData );
msg.Body().set_user_currency( EconUI()->GetStorePanel()->GetCurrency() );
GCClientSystem()->BSendMessage( msg );
g_fClientMarketDataLastUpdateTime = engine->Time();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const client_market_data_t *GetClientMarketData( const steam_market_gc_identifier_t& ident )
{
// If our data is out of date, request fresh data from the GC. We don't need up-to-the-minute
// numbers but we don't want to fall too far behind. THe GC itself doesn't update in realtime
// so constantly querying for updates isn't really useful. We'll still use whatever data if any
// we have for this call.
if ( (engine->Time() - g_fClientMarketDataLastUpdateTime) >= s_fUpdateTimeInSeconds )
{
ClientMarketData_Refresh();
}
// Not having any data on this item isn't an error. We might be requesting something for an
// unlistable item, or we might not have current information from the GC yet.
if ( s_mapClientMarketData.Count() == 0 )
return NULL;
// Remap this index?
steam_market_gc_identifier_t searchIdent = ident;
searchIdent.m_unDefIndex = GetItemSchema()->GetCommunityMarketRemappedDefinitionIndex( ident.m_unDefIndex );
ClientMarketDataMap_t::IndexType_t index = s_mapClientMarketData.Find( searchIdent );
if ( index == s_mapClientMarketData.InvalidIndex() )
return NULL;
return &s_mapClientMarketData[index];
}
//-----------------------------------------------------------------------------
const client_market_data_t *GetClientMarketData( item_definition_index_t iItemDef, uint8 unQuality )
{
steam_market_gc_identifier_t ident;
ident.m_unDefIndex = iItemDef;
ident.m_unQuality = unQuality;
return GetClientMarketData( ident );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CGCClientRequestMarketDataResponse : public GCSDK::CGCClientJob
{
public:
CGCClientRequestMarketDataResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CProtoBufMsg<CMsgGCClientMarketData> msg( pNetPacket );
s_mapClientMarketData.RemoveAll();
s_mapClientMarketData.SetLessFunc( DefLessFunc( ClientMarketDataMap_t::KeyType_t ) );
for ( int i = 0; i < msg.Body().entries_size(); i++ )
{
const CMsgGCClientMarketDataEntry& entry = msg.Body().entries( i );
steam_market_gc_identifier_t ident;
ident.m_unDefIndex = entry.item_def_index();
ident.m_unQuality = entry.item_quality();
client_market_data_t data;
data.m_unQuantityAvailable = entry.item_sell_listings();
data.m_unLowestPrice = entry.price_in_local_currency();
s_mapClientMarketData.Insert( ident, data );
}
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCClientRequestMarketDataResponse, "CGCClientRequestMarketDataResponse", k_EMsgGCClientRequestMarketDataResponse, GCSDK::k_EServerTypeGCClient );
@@ -0,0 +1,19 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
#ifndef CLIENT_COMMUNITY_MARKET_H
#define CLIENT_COMMUNITY_MARKET_H
#ifdef _WIN32
#pragma once
#endif
struct client_market_data_t
{
uint32 m_unQuantityAvailable;
float m_unLowestPrice;
};
const client_market_data_t *GetClientMarketData( item_definition_index_t iItemDef, uint8 unQuality );
const client_market_data_t *GetClientMarketData( const steam_market_gc_identifier_t& ident );
#endif // CLIENT_COMMUNITY_MARKET_H
@@ -0,0 +1,37 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "confirm_delete_dialog.h"
#include "vgui_controls/TextImage.h"
#include "econ_controls.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CConfirmDeleteDialog::CConfirmDeleteDialog( vgui::Panel *parent )
: BaseClass(parent)
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmDeleteDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
// Set the X to be bright, and the rest dull
if ( m_pConfirmButton )
{
m_pConfirmButton->SetText( "#X_DeleteConfirmButton" );
SetXToRed( m_pConfirmButton );
}
}
+28
View File
@@ -0,0 +1,28 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef CONFIRM_DELETE_DIALOG_H
#define CONFIRM_DELETE_DIALOG_H
#ifdef _WIN32
#pragma once
#endif
#include "confirm_dialog.h"
//-----------------------------------------------------------------------------
// Purpose: A generic delete confirmation dialog - see CConfirmDialog.
//-----------------------------------------------------------------------------
class CConfirmDeleteDialog : public CConfirmDialog
{
DECLARE_CLASS_SIMPLE( CConfirmDeleteDialog,CConfirmDialog );
public:
CConfirmDeleteDialog( vgui::Panel *parent );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
};
#endif // CONFIRM_DELETE_DIALOG_H
+932
View File
@@ -0,0 +1,932 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "confirm_dialog.h"
#include "ienginevgui.h"
#include "econ_controls.h"
#include "vgui/IInput.h"
#include "vgui/ISurface.h"
#include "vgui_controls/TextImage.h"
#include "vgui_controls/CheckButton.h"
#include "econ_ui.h"
#include "store/store_panel.h"
#ifdef TF_CLIENT_DLL
#include "tf_playerpanel.h"
#endif // TF_CLIENT_DLL
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
static const wchar_t* GetSCGlyph( const char* action )
{
auto origin = g_pInputSystem->GetSteamControllerActionOrigin( action, GAME_ACTION_SET_FPSCONTROLS );
return g_pInputSystem->GetSteamControllerFontCharacterForActionOrigin( origin );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CConfirmDialog::CConfirmDialog( vgui::Panel *parent )
: BaseClass( parent, "ConfirmDialog" ),
m_pCancelButton( NULL ),
m_pConfirmButton( NULL ),
m_pIcon( NULL )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
LoadControlSettings( GetResFile(), "GAME" );
SetBorder( pScheme->GetBorder("EconItemBorder") );
// Cache off button ptrs
m_pConfirmButton = dynamic_cast< CExButton* >( FindChildByName( "ConfirmButton" ) );
m_pCancelButton = dynamic_cast< CExButton* >( FindChildByName( "CancelButton" ) );
m_pIcon = dynamic_cast< vgui::ImagePanel* >( FindChildByName( "Icon" ) );
SetDialogVariable( "text", GetText() );
if ( ::input->IsSteamControllerActive() )
{
auto iconConfirm = GetSCGlyph( "cl_trigger_first_notification" );
auto iconCancel = GetSCGlyph( "cl_decline_first_notification" );
auto confirmHint = dynamic_cast< CExLabel* >( FindChildByName( "ConfirmButtonHintIcon" ) );
auto cancelHint = dynamic_cast< CExLabel* >( FindChildByName( "CancelButtonHintIcon" ) );
if ( confirmHint )
{
confirmHint->SetText( iconConfirm );
}
if ( cancelHint )
{
cancelHint->SetText( iconCancel );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmDialog::Show( bool bMakePopup )
{
SetVisible( true );
if ( bMakePopup )
{
MakePopup();
}
MoveToFront();
SetKeyBoardInputEnabled( true );
InvalidateLayout( true, true );
if ( ::input->IsSteamControllerActive() )
{
auto iconConfirm = GetSCGlyph( "vote_option1" );
auto iconCancel = GetSCGlyph( "vote_option2" );
bool bControllerMapped = iconConfirm[0] && iconCancel[0];
if ( bControllerMapped )
{
SetMouseInputEnabled( false );
}
else
{
SetMouseInputEnabled( true );
}
}
else
{
SetMouseInputEnabled( true );
}
TFModalStack()->PushModal( this );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmDialog::SetIconImage( const char *pszIcon )
{
Assert( m_pIcon );
if ( m_pIcon )
{
m_pIcon->SetImage( pszIcon );
m_pIcon->SetVisible( ( pszIcon ? true : false ) );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmDialog::OnCommand( const char *command )
{
if ( !Q_strnicmp( command, "cancel", 6 ) )
{
FinishUp();
PostMessage( GetParent(), new KeyValues( "ConfirmDlgResult", "confirmed", 0 ) );
}
else if ( !Q_strnicmp( command, "confirm", 7 ) )
{
FinishUp();
PostMessage( GetParent(), new KeyValues( "ConfirmDlgResult", "confirmed", 1 ) );
}
else
{
engine->ClientCmd( const_cast<char *>( command ) );
}
BaseClass::OnCommand( command );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmDialog::OnKeyCodeTyped( vgui::KeyCode code )
{
if( code == KEY_ESCAPE )
{
OnCommand( "cancel" );
}
else
{
BaseClass::OnKeyCodePressed( code );
}
}
///-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmDialog::OnKeyCodePressed( vgui::KeyCode code )
{
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
// We map the voting action buttons to the pseudo-buttons F1/F2 so that players can use them to interact with dialogs on the fly
if( nButtonCode == KEY_XBUTTON_B || nButtonCode == STEAMCONTROLLER_F2 || nButtonCode == STEAMCONTROLLER_B )
{
OnCommand( "cancel" );
}
else if ( nButtonCode == KEY_ENTER || nButtonCode == KEY_SPACE || nButtonCode == KEY_XBUTTON_A || nButtonCode == STEAMCONTROLLER_F1 || nButtonCode == STEAMCONTROLLER_A )
{
OnCommand( "confirm" );
}
else
{
BaseClass::OnKeyCodePressed( code );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const char *CConfirmDialog::GetResFile()
{
if ( ::input->IsSteamControllerActive() )
{
return "Resource/UI/econ/ConfirmDialog_SC.res";
}
else
{
return "Resource/UI/econ/ConfirmDialog.res";
}
}
//-----------------------------------------------------------------------------
// Purpose: Hide the panel, mark for deletion, remove from modal stack.
//-----------------------------------------------------------------------------
void CConfirmDialog::FinishUp()
{
SetVisible( false );
TFModalStack()->PopModal( this );
MarkForDeletion();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmDialog::OnSizeChanged( int nNewWide, int nNewTall )
{
int nX, nY;
// Shift buttons up
if ( m_pCancelButton )
{
m_pCancelButton->GetPos( nX, nY );
m_pCancelButton->SetPos( nX, nNewTall - m_pCancelButton->GetTall() - YRES(15) );
}
if ( m_pConfirmButton )
{
m_pConfirmButton->GetPos( nX, nY );
m_pConfirmButton->SetPos( nX, nNewTall - m_pConfirmButton->GetTall() - YRES(15) );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFGenericConfirmDialog::CTFGenericConfirmDialog( const char *pTitle, const char *pTextKey,
const char *pConfirmBtnText, const char *pCancelBtnText,
GenericConfirmDialogCallback callback, vgui::Panel *pParent )
: BaseClass( pParent ),
m_pTextKey( pTextKey )
{
CommonInit( pTitle, pConfirmBtnText, pCancelBtnText, callback, pParent );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFGenericConfirmDialog::CTFGenericConfirmDialog( const char *pTitle, const wchar_t *pText,
const char *pConfirmBtnText, const char *pCancelBtnText,
GenericConfirmDialogCallback callback, vgui::Panel *pParent )
: BaseClass( pParent ),
m_pTextKey( NULL )
{
CommonInit( pTitle, pConfirmBtnText, pCancelBtnText, callback, pParent );
V_wcsncpy( m_wszBuffer, pText, sizeof( m_wszBuffer ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGenericConfirmDialog::CommonInit( const char *pTitle, const char *pConfirmBtnText, const char *pCancelBtnText,
GenericConfirmDialogCallback callback, vgui::Panel *pParent )
{
if ( pParent == NULL )
{
vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
SetScheme(scheme);
SetProportional( true );
}
m_pTitle = pTitle;
m_pConfirmBtnText = pConfirmBtnText;
m_pCancelBtnText = pCancelBtnText;
m_pCallback = callback;
m_pContext = NULL;
m_pKeyValues = NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFGenericConfirmDialog::~CTFGenericConfirmDialog()
{
if ( m_pKeyValues )
{
m_pKeyValues->deleteThis();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const wchar_t *CTFGenericConfirmDialog::GetText()
{
if ( m_pTextKey )
{
g_pVGuiLocalize->ConstructString_safe( m_wszBuffer, m_pTextKey, m_pKeyValues );
return m_wszBuffer;
}
return m_wszBuffer;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGenericConfirmDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
if ( m_pConfirmButton && m_pConfirmBtnText )
{
m_pConfirmButton->SetText( m_pConfirmBtnText );
}
if ( m_pCancelButton && m_pCancelBtnText )
{
m_pCancelButton->SetText (m_pCancelBtnText );
}
SetXToRed( m_pConfirmButton );
SetXToRed( m_pCancelButton );
CExLabel *pTitle = dynamic_cast< CExLabel* >( FindChildByName( "TitleLabel" ) );
if ( pTitle )
{
pTitle->SetText( m_pTitle );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGenericConfirmDialog::PerformLayout()
{
// Center it, keeping requested size
int x, y, ww, wt, wide, tall;
vgui::surface()->GetWorkspaceBounds( x, y, ww, wt );
GetSize(wide, tall);
SetPos(x + ((ww - wide) / 2), y + ((wt - tall) / 2));
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGenericConfirmDialog::OnCommand( const char *command )
{
bool bFinishUp = false;
bool bConfirmed = false;
if ( !Q_strnicmp( command, "cancel", 6 ) )
{
bConfirmed = false;
bFinishUp = true;
}
else if ( !Q_strnicmp( command, "confirm", 7 ) )
{
bConfirmed = true;
bFinishUp = true;
}
if ( bFinishUp )
{
FinishUp();
if ( m_pCallback )
{
m_pCallback( bConfirmed, m_pContext );
}
return;
}
BaseClass::OnCommand( command );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGenericConfirmDialog::SetStringTokens( KeyValues *pKeyValues )
{
if ( m_pKeyValues != NULL )
{
m_pKeyValues->deleteThis();
}
m_pKeyValues = pKeyValues->MakeCopy();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGenericConfirmDialog::AddStringToken( const char* pToken, const wchar_t* pValue )
{
if ( m_pKeyValues == NULL )
{
m_pKeyValues = new KeyValues( "GenericConfirmDialog" );
}
m_pKeyValues->SetWString( pToken, pValue );
InvalidateLayout( false, true );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGenericConfirmDialog::SetContext( void *pContext )
{
m_pContext = pContext;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFGenericConfirmOptOutDialog::CTFGenericConfirmOptOutDialog( const char *pTitle,
const char *pText,
const char *pConfirmBtnText,
const char *pCancelBtnText,
const char *pOptOutText,
const char *pOptOutConVarName,
GenericConfirmDialogCallback callback,
vgui::Panel *parent ) :
CTFGenericConfirmDialog( pTitle, pText, pConfirmBtnText, pCancelBtnText, callback, parent )
{
m_optOutText = pOptOutText;
m_optOutCheckbox = NULL;
m_optOutConVarName = pOptOutConVarName;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGenericConfirmOptOutDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
m_optOutCheckbox = dynamic_cast< vgui::CheckButton * >( FindChildByName( "OptOutCheckbox" ) );
if ( m_optOutCheckbox && m_optOutText )
{
m_optOutCheckbox->SetMouseInputEnabled( true );
m_optOutCheckbox->SetText( m_optOutText );
// center horizontally
vgui::Panel *parent = m_optOutCheckbox->GetParent();
if ( parent )
{
float parentWidth = parent->GetWide();
int checkBoxWidth, checkBoxHeight;
m_optOutCheckbox->GetContentSize( checkBoxWidth, checkBoxHeight );
// fudge in checkbox width
checkBoxWidth += 34.0f;
int checkX, checkY;
m_optOutCheckbox->GetPos( checkX, checkY );
m_optOutCheckbox->SetPos( ( parentWidth - checkBoxWidth ) / 2.0f, checkY );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const char *CTFGenericConfirmOptOutDialog::GetResFile()
{
return "Resource/UI/econ/ConfirmDialogOptOut.res";
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFGenericConfirmOptOutDialog::OnButtonChecked( KeyValues *pData )
{
ConVarRef var( m_optOutConVarName );
if ( !var.IsValid() )
return;
if ( !m_optOutCheckbox )
return;
var.SetValue( m_optOutCheckbox->IsSelected() );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFUpgradeBoxDialog::OnCommand( const char *command )
{
if ( !Q_stricmp( command, "upgrade" ) )
{
FinishUp();
// Open the store, and show the upgrade advice
EconUI()->CloseEconUI();
EconUI()->OpenStorePanel( STOREPANEL_SHOW_UPGRADESTEPS, false );
}
else
{
BaseClass::OnCommand( command );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFGenericConfirmDialog *ShowConfirmDialog( const char *pTitle, const char *pText, const char *pConfirmBtnText, const char *pCancelBtnText, GenericConfirmDialogCallback callback,
vgui::Panel *parent/*=NULL*/, void *pContext/*=NULL*/, const char *pSound/*=NULL*/ )
{
CTFGenericConfirmDialog *pDialog = vgui::SETUP_PANEL(
new CTFGenericConfirmDialog(
pTitle, pText,
pConfirmBtnText, pCancelBtnText,
callback, parent
)
);
if ( pDialog )
{
pDialog->Show();
// Play a sound, if one was supplied.
if ( pSound && pSound[0] )
{
vgui::surface()->PlaySound( pSound );
}
}
if ( pContext )
{
pDialog->SetContext( pContext );
}
return pDialog;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFMessageBoxDialog *ShowMessageBox( const char *pTitle, const char *pText, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent, void *pContext )
{
return ShowMessageBox( pTitle, pText, NULL, pConfirmBtnText, callback, parent, pContext );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFMessageBoxDialog *ShowMessageBox( const char *pTitle, const wchar_t *pText, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent , void *pContext)
{
CTFMessageBoxDialog *pDialog = vgui::SETUP_PANEL(
new CTFMessageBoxDialog(
pTitle, pText,
pConfirmBtnText,
callback, parent
)
);
if ( pDialog )
{
if ( pContext )
{
pDialog->SetContext( pContext );
}
pDialog->Show();
}
return pDialog;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFMessageBoxDialog *ShowMessageBox( const char *pTitle, const char *pText, KeyValues *pKeyValues, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent , void *pContext)
{
CTFMessageBoxDialog *pDialog = vgui::SETUP_PANEL( new CTFMessageBoxDialog( pTitle, pText,
pConfirmBtnText,
callback, parent ) );
if ( pDialog )
{
if ( pContext )
{
pDialog->SetContext( pContext );
}
if ( pKeyValues )
{
pDialog->SetStringTokens( pKeyValues );
pDialog->SetDialogVariable( "text", pDialog->GetText() );
}
pDialog->Show();
}
return pDialog;
}
//-----------------------------------------------------------------------------
// Purpose: Pop up a model yes/no dialog with an "opt out" checkbox that persists via a ConVar
//-----------------------------------------------------------------------------
CTFGenericConfirmOptOutDialog *ShowConfirmOptOutDialog( const char *pTitle, const char *pText, const char *pConfirmBtnText, const char *pCancelBtnText, const char *pOptOutText, const char *pOptOutConVarName, GenericConfirmDialogCallback callback, vgui::Panel *parent)
{
CTFGenericConfirmOptOutDialog *pDialog = vgui::SETUP_PANEL( new CTFGenericConfirmOptOutDialog( pTitle, pText,
pConfirmBtnText, pCancelBtnText,
pOptOutText, pOptOutConVarName,
callback, parent ) );
if ( pDialog )
{
pDialog->Show();
}
return pDialog;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFMessageBoxDialog *ShowUpgradeMessageBox( const char *pTitle, const char *pText,
const char *pConfirmBtnText,
GenericConfirmDialogCallback callback,
vgui::Panel *parent, void *pContext )
{
CTFMessageBoxDialog *pDialog = vgui::SETUP_PANEL(
new CTFUpgradeBoxDialog(
pTitle, pText,
pConfirmBtnText, callback, parent
)
);
if ( pDialog )
{
pDialog->SetContext( pContext );
pDialog->Show();
}
return pDialog;
}
//-----------------------------------------------------------------------------
// Purpose: Pop up a dialog prompting the player to go to the store to upgrade
//-----------------------------------------------------------------------------
CTFMessageBoxDialog *ShowUpgradeMessageBox( const char *pTitle, const char *pText )
{
return ShowUpgradeMessageBox( pTitle, pText, "#GameUI_OK", NULL, NULL, NULL );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFMessageBoxDialogWithSound *ShowMessageBoxWithSound( const char *pTitle, const char *pText, const char *pszSound, float flDelay, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent, void *pContext )
{
return ShowMessageBoxWithSound( pTitle, pText, NULL, pszSound, flDelay, pConfirmBtnText, callback, parent, pContext );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFMessageBoxDialogWithSound *ShowMessageBoxWithSound( const char *pTitle, const wchar_t *pText, const char *pszSound, float flDelay, const char *pConfirmBtnText , GenericConfirmDialogCallback callback, vgui::Panel *parent, void *pContext )
{
CTFMessageBoxDialogWithSound *pDialog = vgui::SETUP_PANEL( new CTFMessageBoxDialogWithSound( pTitle, pText, pszSound, flDelay, pConfirmBtnText, callback, parent ) );
if ( pDialog )
{
if ( pContext )
{
pDialog->SetContext( pContext );
}
pDialog->Show();
}
return pDialog;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFMessageBoxDialogWithSound *ShowMessageBoxWithSound( const char *pTitle, const char *pText, KeyValues *pKeyValues, const char *pszSound, float flDelay, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent, void *pContext )
{
CTFMessageBoxDialogWithSound *pDialog = vgui::SETUP_PANEL( new CTFMessageBoxDialogWithSound( pTitle, pText, pszSound, flDelay, pConfirmBtnText, callback, parent ) );
if ( pDialog )
{
if ( pContext )
{
pDialog->SetContext( pContext );
}
if ( pKeyValues )
{
pDialog->SetStringTokens( pKeyValues );
pDialog->SetDialogVariable( "text", pDialog->GetText() );
}
pDialog->Show();
}
return pDialog;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFMessageBoxDialogWithSound::CTFMessageBoxDialogWithSound( const char *pTitle, const char *pText, const char *pszSound, float flDelay, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent )
: CTFMessageBoxDialog( pTitle, pText, pConfirmBtnText, callback, parent )
{
m_szSound[0] = 0;
if ( pszSound )
{
V_strcpy_safe( m_szSound, pszSound );
}
m_flSoundTime = gpGlobals->curtime + flDelay;
m_bPlayedSound = false;
vgui::ivgui()->AddTickSignal( GetVPanel(), 50 );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFMessageBoxDialogWithSound::CTFMessageBoxDialogWithSound( const char *pTitle, const wchar_t *pText, const char *pszSound, float flDelay, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent )
: CTFMessageBoxDialog( pTitle, pText, pConfirmBtnText, callback, parent )
{
m_szSound[0] = 0;
if ( pszSound )
{
V_strcpy_safe( m_szSound, pszSound );
}
m_flSoundTime = gpGlobals->curtime + flDelay;
m_bPlayedSound = false;
vgui::ivgui()->AddTickSignal( GetVPanel(), 50 );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFMessageBoxDialogWithSound::OnTick()
{
BaseClass::OnTick();
if ( !m_bPlayedSound && ( m_flSoundTime < gpGlobals->curtime ) )
{
m_bPlayedSound = true;
if ( Q_strlen( m_szSound ) > 0 )
{
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
if ( pLocalPlayer )
{
pLocalPlayer->EmitSound( m_szSound );
}
}
}
}
#ifdef TF_CLIENT_DLL
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFReviveDialog::CTFReviveDialog( const char *pTitle, const char *pText, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent )
: CTFMessageBoxDialog( pTitle, pText, pConfirmBtnText, callback, parent )
{
m_pTargetHealth = new CTFSpectatorGUIHealth( this, "SpectatorGUIHealth" );
m_pTargetHealth->SetAllowAnimations( false );
m_pTargetHealth->HideHealthBonusImage();
vgui::ivgui()->AddTickSignal( GetVPanel(), 50 );
OnTick();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFReviveDialog::PerformLayout()
{
// Skipping base class
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFReviveDialog::OnTick()
{
BaseClass::OnTick();
if ( !m_pTargetHealth )
return;
if ( !m_hEntity )
return;
float flHealth = m_hEntity->GetHealth();
if ( flHealth != m_flPrevHealth )
{
float flMaxHealth = m_hEntity->GetMaxHealth();
m_pTargetHealth->SetHealth( flHealth, flMaxHealth, flMaxHealth );
m_flPrevHealth = flHealth;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFReviveDialog::SetOwner( CBaseEntity *pEntity )
{
if ( pEntity )
{
m_hEntity = pEntity;
}
}
//-----------------------------------------------------------------------------
// Purpose: In-game dialog that avoids the crosshair area and is much smaller
//-----------------------------------------------------------------------------
CTFReviveDialog *ShowRevivePrompt( CBaseEntity *pOwner,
const char *pTitle,
const char *pText,
const char *pConfirmBtnText,
GenericConfirmDialogCallback callback,
vgui::Panel *parent, void *pContext )
{
CTFReviveDialog *pDialog = vgui::SETUP_PANEL( new CTFReviveDialog( pTitle, pText, pConfirmBtnText, callback, parent ) );
if ( pDialog )
{
if ( pContext )
{
pDialog->SetContext( pContext );
}
pDialog->SetOwner( pOwner );
pDialog->Show();
}
return pDialog;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CEconRequirementDialog::CEconRequirementDialog( const char *pTitle, const char *pTextKey, const char *pItemDefName )
: CTFGenericConfirmDialog( pTitle, pTextKey, NULL, NULL, NULL, NULL )
, m_hItemDef( pItemDefName )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const char *CEconRequirementDialog::GetResFile()
{
return "Resource/UI/MvMEconRequirementDialog.res";
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconRequirementDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
vgui::ImagePanel *pItemImagePanel = dynamic_cast<vgui::ImagePanel *>( FindChildByName( "ItemImagePanel", true ) ); Assert( pItemImagePanel );
Assert( pItemImagePanel );
if ( pItemImagePanel && m_hItemDef )
{
pItemImagePanel->SetImage( CFmtStr( "../%s_large", m_hItemDef->GetInventoryImage() ) );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconRequirementDialog::OnCommand( const char *command )
{
if ( m_hItemDef && !Q_stricmp( command, "show_in_store" ) )
{
FinishUp();
// Open the store, and show the upgrade advice
EconUI()->CloseEconUI();
EconUI()->OpenStorePanel( m_hItemDef->GetDefinitionIndex(), false );
}
else
{
BaseClass::OnCommand( command );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ShowEconRequirementDialog( const char *pTitle, const char *pText, const char *pItemDefName )
{
CEconRequirementDialog *pDialog = vgui::SETUP_PANEL( new CEconRequirementDialog( pTitle, pText, pItemDefName ) );
if ( pDialog )
{
pDialog->Show();
}
}
//-----------------------------------------------------------------------------
// Purpose: Get the correct res file to use (depends on Steam Controller state)
//-----------------------------------------------------------------------------
const char* CTFMessageBoxDialog::GetResFile()
{
if ( ::input->IsSteamControllerActive() )
{
return "Resource/UI/econ/MessageBoxDialog_SC.res";
}
else
{
return "Resource/UI/econ/MessageBoxDialog.res";
}
}
#endif // TF_CLIENT_DLL
+230
View File
@@ -0,0 +1,230 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
//=======================================================================================//
#ifndef CONFIRM_DIALOG_H
#define CONFIRM_DIALOG_H
#ifdef _WIN32
#pragma once
#endif
#include "vgui_controls/EditablePanel.h"
#include "vgui_controls/CheckButton.h"
#include "inputsystem/iinputsystem.h"
//-----------------------------------------------------------------------------
// Purpose:
// - Basic confirm dialog - derive from this and implement GetText().
// - The user will have two options, essentially yes or no.
// - A "ConfirmDlgResult" message is sent to the parent with the result.
// Check the "confirmed" parameter.
// - Panel deletes itself.
// - See CConfirmDeleteDialog for a generic delete confirmation dialog.
//-----------------------------------------------------------------------------
class CExButton;
#ifdef TF_CLIENT_DLL
class CTFSpectatorGUIHealth;
#endif // TF_CLIENT_DLL
class CConfirmDialog : public vgui::EditablePanel
{
DECLARE_CLASS_SIMPLE( CConfirmDialog, vgui::EditablePanel );
public:
CConfirmDialog( vgui::Panel *parent );
virtual const wchar_t *GetText() = 0;
void Show( bool bMakePopup = true );
void SetIconImage( const char *pszIcon );
protected:
virtual void OnSizeChanged(int nNewWide, int nNewTall );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void OnCommand( const char *command );
virtual void OnKeyCodeTyped( vgui::KeyCode code );
virtual void OnKeyCodePressed( vgui::KeyCode code );
virtual const char *GetResFile();
void FinishUp(); // Hide the panel, mark for deletion, remove from modal stack.
CExButton *m_pConfirmButton;
CExButton *m_pCancelButton;
vgui::ImagePanel *m_pIcon;
};
//-----------------------------------------------------------------------------
typedef void (*GenericConfirmDialogCallback)( bool bConfirmed, void *pContext );
// An implementation of the Confirm Dialog that is "generic"
class CTFGenericConfirmDialog : public CConfirmDialog
{
DECLARE_CLASS_SIMPLE( CTFGenericConfirmDialog, CConfirmDialog );
public:
CTFGenericConfirmDialog( const char *pTitle, const char *pTextKey, const char *pConfirmBtnText,
const char *pCancelBtnText, GenericConfirmDialogCallback callback, vgui::Panel *pParent );
CTFGenericConfirmDialog( const char *pTitle, const wchar_t *pText, const char *pConfirmBtnText,
const char *pCancelBtnText, GenericConfirmDialogCallback callback, vgui::Panel *pParent );
virtual ~CTFGenericConfirmDialog();
virtual const wchar_t *GetText();
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void PerformLayout();
virtual void OnCommand( const char *command );
void SetStringTokens( KeyValues *pKeyValues );
void AddStringToken( const char* pToken, const wchar_t* pValue );
void SetContext( void *pContext );
protected:
void CommonInit( const char *pTitle, const char *pConfirmBtnText, const char *pCancelBtnText,
GenericConfirmDialogCallback callback, vgui::Panel *pParent );
const char *m_pTitle;
const char *m_pTextKey;
const char *m_pConfirmBtnText;
const char *m_pCancelBtnText;
KeyValues *m_pKeyValues;
wchar_t m_wszBuffer[1024];
GenericConfirmDialogCallback m_pCallback;
void *m_pContext;
};
// A generic message dialog, which is just a generic confirm dialog w/o the cancel button
class CTFMessageBoxDialog : public CTFGenericConfirmDialog
{
DECLARE_CLASS_SIMPLE( CTFMessageBoxDialog, CTFGenericConfirmDialog );
public:
CTFMessageBoxDialog( const char *pTitle, const char *pText, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent )
: CTFGenericConfirmDialog( pTitle, pText, pConfirmBtnText, NULL, callback, parent ) {}
CTFMessageBoxDialog( const char *pTitle, const wchar_t *pText, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent )
: CTFGenericConfirmDialog( pTitle, pText, pConfirmBtnText, NULL, callback, parent ) {}
virtual const char* GetResFile();
};
// A generic message dialog, which is just a generic confirm dialog w/o the cancel button that plays a sound with optional delay
class CTFMessageBoxDialogWithSound : public CTFMessageBoxDialog
{
DECLARE_CLASS_SIMPLE( CTFMessageBoxDialogWithSound, CTFMessageBoxDialog );
public:
CTFMessageBoxDialogWithSound( const char *pTitle, const char *pText, const char *pszSound, float flDelay, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent );
CTFMessageBoxDialogWithSound( const char *pTitle, const wchar_t *pText, const char *pszSound, float flDelay, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent );
virtual void OnTick() OVERRIDE;
private:
char m_szSound[MAX_PATH];
float m_flSoundTime;
bool m_bPlayedSound;
};
// A dialog with an upgrade button that takes them to the mann co store
class CTFUpgradeBoxDialog : public CTFMessageBoxDialog
{
DECLARE_CLASS_SIMPLE( CTFUpgradeBoxDialog, CTFMessageBoxDialog );
public:
CTFUpgradeBoxDialog( const char *pTitle, const char *pText, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent )
: CTFMessageBoxDialog( pTitle, pText, pConfirmBtnText, callback, parent ) {}
CTFUpgradeBoxDialog( const char *pTitle, const wchar_t *pText, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent )
: CTFMessageBoxDialog( pTitle, pText, pConfirmBtnText, callback, parent ) {}
virtual const char *GetResFile()
{
return "Resource/UI/UpgradeBoxDialog.res";
}
virtual void OnCommand( const char *command );
};
// An implementation of the Confirm Dialog with a persistant "opt out" checkbox stored via ConVar
class CTFGenericConfirmOptOutDialog : public CTFGenericConfirmDialog
{
DECLARE_CLASS_SIMPLE( CTFGenericConfirmOptOutDialog, CTFGenericConfirmDialog );
public:
CTFGenericConfirmOptOutDialog( const char *pTitle, const char *pText, const char *pConfirmBtnText, const char *pCancelBtnText, const char *pOptOutText, const char *pOptOutConVarName, GenericConfirmDialogCallback callback, vgui::Panel *parent ) ;
virtual ~CTFGenericConfirmOptOutDialog() { }
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
MESSAGE_FUNC_PARAMS( OnButtonChecked, "CheckButtonChecked", pData );
protected:
virtual const char *GetResFile();
const char *m_optOutText;
vgui::CheckButton *m_optOutCheckbox;
const char *m_optOutConVarName;
};
#ifdef TF_CLIENT_DLL
// A dialog presented to dead players when being revived
class CTFReviveDialog : public CTFMessageBoxDialog
{
DECLARE_CLASS_SIMPLE( CTFReviveDialog, CTFMessageBoxDialog );
public:
CTFReviveDialog( const char *pTitle, const char *pText, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent );
virtual ~CTFReviveDialog() { }
virtual void PerformLayout() OVERRIDE;
virtual void OnTick() OVERRIDE;
virtual const char *GetResFile() OVERRIDE { return "Resource/UI/ReviveDialog.res"; }
void SetOwner( CBaseEntity *pEntity );
CTFSpectatorGUIHealth *m_pTargetHealth;
CHandle< C_BaseEntity > m_hEntity;
float m_flPrevHealth;
};
CTFReviveDialog *ShowRevivePrompt( CBaseEntity *pOwner,
const char *pTitle = "#TF_Prompt_Revive_Title",
const char *pText = "#TF_Prompt_Revive_Message",
const char *pConfirmBtnText = "#TF_Prompt_Revive_Cancel",
GenericConfirmDialogCallback callback = NULL,
vgui::Panel *parent = NULL,
void *pContext = NULL );
// A generic message dialog, which is just a generic confirm dialog w/o the cancel button
class CEconRequirementDialog : public CTFGenericConfirmDialog
{
DECLARE_CLASS_SIMPLE( CEconRequirementDialog, CTFGenericConfirmDialog );
public:
CEconRequirementDialog( const char *pTitle, const char *pTextKey, const char *pItemDefName );
virtual const char *GetResFile() OVERRIDE;
virtual void ApplySchemeSettings( vgui::IScheme *pScheme ) OVERRIDE;
virtual void OnCommand( const char *command ) OVERRIDE;
CSchemaItemDefHandle m_hItemDef;
};
void ShowEconRequirementDialog( const char *pTitle, const char *pText, const char *pItemDefName );
#endif // TF_CLIENT_DLL
//-----------------------------------------------------------------------------
CTFGenericConfirmOptOutDialog *ShowConfirmOptOutDialog( const char *pTitle, const char *pText, const char *pConfirmBtnText, const char *pCancelBtnText, const char *pOptOutText, const char *pOptOutConVarName, GenericConfirmDialogCallback callback, vgui::Panel *parent = NULL );
//-----------------------------------------------------------------------------
CTFGenericConfirmDialog *ShowConfirmDialog( const char *pTitle, const char *pText, const char *pConfirmBtnText, const char *pCancelBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent = NULL, void *pContext = NULL, const char *pSound = NULL );
//-----------------------------------------------------------------------------
CTFMessageBoxDialog *ShowMessageBox( const char *pTitle, const char *pText, const char *pConfirmBtnText = "#GameUI_OK", GenericConfirmDialogCallback callback = NULL, vgui::Panel *parent = NULL, void *pContext = NULL );
CTFMessageBoxDialog *ShowMessageBox( const char *pTitle, const wchar_t *pText, const char *pConfirmBtnText = "#GameUI_OK", GenericConfirmDialogCallback callback = NULL, vgui::Panel *parent = NULL, void *pContext = NULL );
CTFMessageBoxDialog *ShowMessageBox( const char *pTitle, const char *pText, KeyValues *pKeyValues, const char *pConfirmBtnText = "#GameUI_OK", GenericConfirmDialogCallback callback = NULL, vgui::Panel *parent = NULL, void *pContext = NULL );
CTFMessageBoxDialog *ShowUpgradeMessageBox( const char *pTitle, const char *pText );
CTFMessageBoxDialog *ShowUpgradeMessageBox( const char *pTitle, const char *pText, const char *pConfirmBtnText, GenericConfirmDialogCallback callback, vgui::Panel *parent = NULL, void *pContext = NULL );
//-----------------------------------------------------------------------------
CTFMessageBoxDialogWithSound *ShowMessageBoxWithSound( const char *pTitle, const char *pText, const char *pszSound, float flDelay = 0.0, const char *pConfirmBtnText = "#GameUI_OK", GenericConfirmDialogCallback callback = NULL, vgui::Panel *parent = NULL, void *pContext = NULL );
CTFMessageBoxDialogWithSound *ShowMessageBoxWithSound( const char *pTitle, const wchar_t *pText, const char *pszSound, float flDelay = 0.0, const char *pConfirmBtnText = "#GameUI_OK", GenericConfirmDialogCallback callback = NULL, vgui::Panel *parent = NULL, void *pContext = NULL );
CTFMessageBoxDialogWithSound *ShowMessageBoxWithSound( const char *pTitle, const char *pText, KeyValues *pKeyValues, const char *pszSound, float flDelay = 0.0, const char *pConfirmBtnText = "#GameUI_OK", GenericConfirmDialogCallback callback = NULL, vgui::Panel *parent = NULL, void *pContext = NULL );
#endif // CONFIRM_DIALOG_H
+266
View File
@@ -0,0 +1,266 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
#include "cbase.h"
#include "econ_item_tools.h"
//---------------------------------------------------------------------------------------
// Purpose:
//---------------------------------------------------------------------------------------
const char *IEconTool::GetUseCommandLocalizationToken( const IEconItemInterface *pItem, int i ) const
{
Assert( i == 0 ); // Default only has 1 use, so this should be 0.
Assert( pItem );
Assert( pItem->GetItemDefinition() );
Assert( pItem->GetItemDefinition()->GetEconTool() == this );
// If we have a custom schema-specified use string, use that.
return GetUseString();
}
//---------------------------------------------------------------------------------------
// Purpose:
//---------------------------------------------------------------------------------------
const char* IEconTool::GetUseCommand( const IEconItemInterface *pItem, int i ) const
{
Assert( i == 0 ); // Default only has 1 use, so this should be 0.
Assert( pItem );
Assert( pItem->GetItemDefinition() );
Assert( pItem->GetItemDefinition()->GetEconTool() == this );
const bool bIsGCConsumable = ( ( pItem->GetItemDefinition()->GetCapabilities() & ITEM_CAP_USABLE_GC ) != 0 );
return bIsGCConsumable ? "Context_UseConsumableItem" : "Context_ApplyOnItem";
}
//---------------------------------------------------------------------------------------
// Purpose:
//---------------------------------------------------------------------------------------
bool IsLocalPlayerWrappedGift( const IEconItemInterface *pItem )
{
Assert( pItem );
Assert( pItem->GetItemDefinition() );
Assert( pItem->GetItemDefinition()->GetTypedEconTool<CEconTool_WrappedGift>() );
static CSchemaAttributeDefHandle pAttr_GifterAccountID( "gifter account id" );
uint32 unGifterAccountID;
if ( !pItem->FindAttribute( pAttr_GifterAccountID, &unGifterAccountID ) )
return false;
const uint32 unLocalAccountID = steamapicontext->SteamUser()->GetSteamID().GetAccountID();
return unGifterAccountID == unLocalAccountID;
}
//---------------------------------------------------------------------------------------
// Purpose:
//---------------------------------------------------------------------------------------
bool CEconTool_WrappedGift::CanBeUsedNow( const IEconItemInterface *pItem ) const
{
static CSchemaItemDefHandle pItemDef_WrappedGiftapultPackage( "Wrapped Giftapult Package" );
static CSchemaItemDefHandle pItemDef_DeliveredGiftapultPackage( "Delivered Giftapult Package" );
static CSchemaItemDefHandle pItemDef_CompetitiveBetaPassGift( "Competitive Matchmaking Beta Giftable Invite" );
Assert( pItem );
Assert( pItem->GetItemDefinition() );
Assert( pItem->GetItemDefinition()->GetEconTool() == this );
if ( ( pItem->GetItemDefinition() == pItemDef_WrappedGiftapultPackage ) ||
( pItem->GetItemDefinition() == pItemDef_CompetitiveBetaPassGift ) ||
( pItem->GetItemDefinition() == pItemDef_DeliveredGiftapultPackage ) )
return true;
return pItem->IsTradable();
}
//---------------------------------------------------------------------------------------
// Purpose:
//---------------------------------------------------------------------------------------
bool CEconTool_WrappedGift::ShouldShowContainedItemPanel( const IEconItemInterface *pItem ) const
{
Assert( pItem );
Assert( pItem->GetItemDefinition() );
Assert( pItem->GetItemDefinition()->GetEconTool() == this );
return IsLocalPlayerWrappedGift( pItem );
}
//---------------------------------------------------------------------------------------
// Purpose:
//---------------------------------------------------------------------------------------
const char *CEconTool_WrappedGift::GetUseCommandLocalizationToken( const IEconItemInterface *pItem, int i ) const
{
Assert( pItem );
Assert( pItem->GetItemDefinition() );
Assert( pItem->GetItemDefinition()->GetEconTool() == this );
Assert( i == 0 || ( IsLocalPlayerWrappedGift( pItem ) && i == 1 ) );
// NOTE! Keep in sync with CEconTool_WrappedGift::GetUseCommand
if ( BIsDirectGift() ||
( IsLocalPlayerWrappedGift( pItem ) && i == 0 ) )
return "#DeliverGift";
return "#UnwrapGift";
}
//---------------------------------------------------------------------------------------
// Purpose:
//---------------------------------------------------------------------------------------
int CEconTool_WrappedGift::GetUseCommandCount( const IEconItemInterface *pItem ) const
{
Assert( pItem );
Assert( pItem->GetItemDefinition() );
Assert( pItem->GetItemDefinition()->GetEconTool() == this );
if ( IsLocalPlayerWrappedGift( pItem ) )
return 2;
return 1;
}
//---------------------------------------------------------------------------------------
// Purpose:
//---------------------------------------------------------------------------------------
const char* CEconTool_WrappedGift::GetUseCommand( const IEconItemInterface *pItem, int i ) const
{
// NOTE! Keep in sync with CEconTool_WrappedGift::GetUseCommandLocalizationToken
Assert( pItem );
Assert( pItem->GetItemDefinition() );
Assert( pItem->GetItemDefinition()->GetEconTool() == this );
Assert( i == 0 || ( IsLocalPlayerWrappedGift( pItem ) && i == 1 ) );
// NOTE! Keep in sync with CEconTool_WrappedGift::GetUseCommand
if ( BIsDirectGift() ||
( IsLocalPlayerWrappedGift( pItem ) && i == 0 ) )
return "Context_DeliverItem";
return "Context_UnwrapItem";
}
//---------------------------------------------------------------------------------------
// Purpose:
//---------------------------------------------------------------------------------------
const char *CEconTool_WeddingRing::GetUseCommandLocalizationToken( const IEconItemInterface *pItem, int i ) const
{
Assert( i == 0 ); // We only have one action.
Assert( pItem );
Assert( pItem->GetItemDefinition() );
Assert( pItem->GetItemDefinition()->GetEconTool() == this );
// If the wedding ring has been gifted to us, we can use it to accept/reject the proposal.
// If it hasn't been gifted we can't use it at all.
static CSchemaAttributeDefHandle pAttrDef_GifterAccountID( "gifter account id" );
if ( !pItem->FindAttribute( pAttrDef_GifterAccountID ) )
return NULL;
return "#ToolAction_WeddingRing_AcceptReject";
}
#ifndef TF_CLIENT_DLL
//---------------------------------------------------------------------------------------
// Purpose:
//---------------------------------------------------------------------------------------
void CEconTool_Noisemaker::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_Noisemaker::OnClientUseConsumable() is unimplemented!" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_WrappedGift::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_WrappedGift::OnClientUseConsumable() is unimplemented!" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_WeddingRing::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_WeddingRing::OnClientUseConsumable() is unimplemented!" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_BackpackExpander::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_BackpackExpander::OnClientUseConsumable() is unimplemented!" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_AccountUpgradeToPremium::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_AccountUpgradeToPremium::OnClientUseConsumable() is unimplemented!" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_ClaimCode::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_ClaimCode::OnClientUseConsumable() is unimplemented!" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_Collection::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_Collection::OnClientUseConsumable() is unimplemented!" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_StrangifierBase::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_StrangifierBase::OnClientUseConsumable() is unimplemented!" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_PaintCan::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_PaintCan::OnClientUseConsumable() is unimplemented!" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_Gift::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_Gift::OnClientUseConsumable() is unimplemented!" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_DuelingMinigame::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_DuelingMinigame::OnClientUseConsumable() is unimplemented!" );
}
//-----------------------------------------------------------------------------
void CEconTool_DuckToken::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_DuckToken::OnClientUseConsumable() is unimplemented!" );
}
//-----------------------------------------------------------------------------
void CEconTool_GrantOperationPass::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_DuckToken::CEconTool_GrantOperationPass() is unimplemented!" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_Default::OnClientUseConsumable( CEconItemView *pItem, vgui::Panel *pParent ) const
{
Assert( !"CEconTool_Default::OnClientUseConsumable() is unimplemented!" );
}
#endif // !defined( TF_CLIENT_DLL )
File diff suppressed because it is too large Load Diff
+429
View File
@@ -0,0 +1,429 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef ECON_CONTROLS_H
#define ECON_CONTROLS_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui/IScheme.h>
#include <vgui/KeyCode.h>
#include <KeyValues.h>
#include <vgui/IVGui.h>
#include <vgui_controls/ScrollBar.h>
#include <vgui_controls/EditablePanel.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/RichText.h>
#include <vgui_controls/ImagePanel.h>
#include "utlvector.h"
#include "vgui_controls/PHandle.h"
#include <vgui_controls/Tooltip.h>
#include "GameEventListener.h"
//-----------------------------------------------------------------------------
// Purpose: Changes the visibility of the child panel if it is different.
// Returns true if the child exists, false otherwise.
//-----------------------------------------------------------------------------
bool SetChildPanelVisible( vgui::Panel *pParent, const char *pChildName, bool bVisible, bool bSearchForChildRecursively = false );
//-----------------------------------------------------------------------------
// Purpose: Changes the enable state of the child panel if it is different.
// Returns true if the child exists, false otherwise.
//-----------------------------------------------------------------------------
bool SetChildPanelEnabled( vgui::Panel *pParent, const char *pChildName, bool bEnabled, bool bSearchForChildRecursively = false );
//-----------------------------------------------------------------------------
// Purpose: Changes the selected state of the child button if it is different.
// Returns true if the child exists, false otherwise.
//-----------------------------------------------------------------------------
bool SetChildButtonSelected( vgui::Panel *pParent, const char *pChildName, bool bSelected, bool bSearchForChildRecursively = false );
//-----------------------------------------------------------------------------
// Purpose: Returns true if the child button exists and is selected, false otherwise.
//-----------------------------------------------------------------------------
bool IsChildButtonSelected( vgui::Panel *pParent, const char *pChildName, bool bSearchForChildRecursively = false );
//-----------------------------------------------------------------------------
// Purpose: Adds the child panel as an action signal target. Returns true if the child exists, false otherwise.
//-----------------------------------------------------------------------------
bool AddChildActionSignalTarget( vgui::Panel *pParent, const char *pChildName, vgui::Panel *messageTarget, bool bSearchForChildRecursively = false );
//-----------------------------------------------------------------------------
// Purpose: Modify the color of a label/button's text - if it starts with "X "
// or "x ", set the X to red.
//-----------------------------------------------------------------------------
bool SetXToRed( vgui::Label *pPanel );
//-----------------------------------------------------------------------------
// Purpose: Simple panel tooltip. Just calls setvisible on the other panel.
// Ignores all other input.
//-----------------------------------------------------------------------------
class CSimplePanelToolTip : public vgui::BaseTooltip
{
DECLARE_CLASS_SIMPLE( CSimplePanelToolTip, vgui::BaseTooltip );
public:
CSimplePanelToolTip(vgui::Panel *parent, const char *text = NULL) : vgui::BaseTooltip( parent, text )
{
m_pControlledPanel = NULL;
}
void SetText(const char *text) { return; }
const char *GetText() { return NULL; }
virtual void ShowTooltip( vgui::Panel *currentPanel ) { if ( m_pControlledPanel ) m_pControlledPanel->SetVisible( true ); }
virtual void HideTooltip() { if ( m_pControlledPanel ) m_pControlledPanel->SetVisible( false ); }
void SetControlledPanel( vgui::EditablePanel *pPanel ) { m_pControlledPanel = pPanel; }
protected:
vgui::Panel *m_pControlledPanel;
};
//-----------------------------------------------------------------------------
// Purpose: Expanded Button class that allows font & color overriding in .res files
//-----------------------------------------------------------------------------
class CExButton : public vgui::Button
{
public:
DECLARE_CLASS_SIMPLE( CExButton, vgui::Button );
CExButton( vgui::Panel *parent, const char *name, const char *text, vgui::Panel *pActionSignalTarget = NULL, const char *cmd = NULL );
CExButton( vgui::Panel *parent, const char *name, const wchar_t *wszText, vgui::Panel *pActionSignalTarget = NULL, const char *cmd = NULL );
virtual void ApplySettings( KeyValues *inResourceData );
void SetFontStr( const char *pFont );
void SetColorStr( const char *pColor );
virtual vgui::IBorder *GetBorder(bool depressed, bool armed, bool selected, bool keyfocus);
virtual void OnMouseFocusTicked() OVERRIDE;
virtual void OnCursorEntered() OVERRIDE;
virtual void OnCursorExited() OVERRIDE;
void PassMouseTicksTo( vgui::Panel *pPanel, bool bCursorEnterExitEvent = false )
{
m_hMouseTickTarget.Set( pPanel ? pPanel->GetVPanel() : NULL );
m_bbCursorEnterExitEvent = bCursorEnterExitEvent;
}
private:
char m_szFont[64];
char m_szColor[64];
vgui::IBorder *m_pArmedBorder;
vgui::IBorder *m_pDefaultBorderOverride;
vgui::IBorder *m_pSelectedBorder;
vgui::IBorder *m_pDisabledBorder;
vgui::VPanelHandle m_hMouseTickTarget;
bool m_bbCursorEnterExitEvent;
};
//-----------------------------------------------------------------------------
// Purpose: Expanded image button, that handles images per button state, and color control in the .res file
//-----------------------------------------------------------------------------
class CExImageButton : public CExButton
{
public:
DECLARE_CLASS_SIMPLE( CExImageButton, CExButton );
CExImageButton( vgui::Panel *parent, const char *name, const char *text = "", vgui::Panel *pActionSignalTarget = NULL, const char *cmd = NULL );
CExImageButton( vgui::Panel *parent, const char *name, const wchar_t *wszText = L"", vgui::Panel *pActionSignalTarget = NULL, const char *cmd = NULL );
~CExImageButton( void );
virtual void ApplySettings( KeyValues *inResourceData );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void SetArmed(bool state);
virtual void SetEnabled(bool state);
virtual void SetSelected(bool state);
void SetSubImage( const char *pszImage );
void SetImageDefault( const char *pszImageDefault );
void SetImageArmed( const char *pszImageArmed );
void SetImageSelected( const char *pszImageSelected );
Color GetImageColor( void );
vgui::ImagePanel *GetImage( void ) { return m_pEmbeddedImagePanel; }
private:
// Embedded image panels
vgui::ImagePanel *m_pEmbeddedImagePanel;
Color m_ImageDrawColor;
Color m_ImageArmedColor;
Color m_ImageDisabledColor;
Color m_ImageSelectedColor;
Color m_ImageDepressedColor;
char m_szImageDefault[MAX_PATH];
char m_szImageArmed[MAX_PATH];
char m_szImageSelected[MAX_PATH];
};
//-----------------------------------------------------------------------------
// Purpose: Expanded Label class that allows color control in .res files
//-----------------------------------------------------------------------------
class CExLabel : public vgui::Label
{
public:
DECLARE_CLASS_SIMPLE( CExLabel, vgui::Label );
CExLabel( vgui::Panel *parent, const char *panelName, const char *text );
CExLabel( vgui::Panel *parent, const char *panelName, const wchar_t *wszText );
virtual void ApplySettings( KeyValues *inResourceData );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
void SetColorStr( const char *pColor );
void SetColorStr( Color cColor );
private:
char m_szColor[64];
};
//-----------------------------------------------------------------------------
// Purpose: Expanded Richtext control that allows customization of scrollbar display, font, and color .res controls.
//-----------------------------------------------------------------------------
class CExRichText : public vgui::RichText
{
public:
DECLARE_CLASS_SIMPLE( CExRichText, vgui::RichText );
CExRichText( vgui::Panel *parent, const char *panelName );
virtual void ApplySettings( KeyValues *inResourceData );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void PerformLayout();
virtual void SetText( const char *text );
virtual void SetText( const wchar_t *text );
virtual void OnTick( void );
void SetScrollBarImagesVisible( bool visible );
void SetFontStr( const char *pFont );
void SetColorStr( const char *pColor );
void SetCustomImage( vgui::Panel *pImage, const char *pszImage, char *pszStorage );
void CreateImagePanels( void );
protected:
char m_szFont[64];
char m_szColor[64];
char m_szImageUpArrow[MAX_PATH];
char m_szImageDownArrow[MAX_PATH];
char m_szImageLine[MAX_PATH];
char m_szImageBox[MAX_PATH];
bool m_bUseImageBorders;
CExImageButton *m_pUpArrow;
vgui::Panel *m_pLine;
CExImageButton *m_pDownArrow;
vgui::Panel *m_pBox;
};
//-----------------------------------------------------------------------------
// Purpose: Rich text control that knows how to fill itself with information
// that describes a specific item definition.
//-----------------------------------------------------------------------------
class CRichTextWithScrollbarBorders : public CExRichText
{
public:
DECLARE_CLASS_SIMPLE( CRichTextWithScrollbarBorders, CExRichText );
CRichTextWithScrollbarBorders( vgui::Panel *parent, const char *panelName ) : BaseClass( parent, panelName )
{
m_bUseImageBorders = true;
}
};
//-----------------------------------------------------------------------------
// Purpose: Rich text control that knows how to fill itself with information
// that describes a specific item definition.
//-----------------------------------------------------------------------------
class CEconItemDetailsRichText : public CRichTextWithScrollbarBorders
{
public:
DECLARE_CLASS_SIMPLE( CEconItemDetailsRichText, CRichTextWithScrollbarBorders );
CEconItemDetailsRichText( vgui::Panel *parent, const char *panelName );
virtual void ApplySettings( KeyValues *inResourceData );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
void UpdateDetailsForItem( const CEconItemDefinition *pDef );
void AllowItemSetLinks( bool bAllow ) { m_bAllowItemSetLinks = bAllow; }
void SetLimitedItem( bool bLimited ) { m_bLimitedItem = bLimited; }
private:
void InsertItemLink( const wchar_t *pwzItemName, int nItemIndex, Color *pColorOverride = NULL );
void AddDataText( const char *pszText, bool bAddPostLines = true, const wchar_t *wpszArg = NULL, const wchar_t *wpszArg2 = NULL, const int *pItemDefIndex = NULL );
void DataText_AppendStoreFlags( const CEconItemDefinition *pDef );
void DataText_AppendItemData( const CEconItemDefinition *pDef );
void DataText_AppendBundleData( const CEconItemDefinition *pDef );
void DataText_AppendUsageData( const CEconItemDefinition *pBaseDef );
void DataText_AppendAttributeData( const CEconItemDefinition *pDef );
void DataText_AppendSetData( const CEconItemDefinition *pDef );
void DataText_AppendToolUsage( const CEconItemDefinition *pDef );
void UpdateToolList( void );
private:
Color m_colTextHighlight;
Color m_colItemSet;
Color m_colLink;
bool m_bAllowItemSetLinks;
vgui::HFont m_hLinkFont;
CUtlVector<item_definition_index_t> m_ToolList;
bool m_bLimitedItem;
};
#define EXC_SIDE_TOP 0
#define EXC_SIDE_RIGHT 1
#define EXC_SIDE_BOTTOM 2
#define EXC_SIDE_LEFT 3
//-----------------------------------------------------------------------------
// Purpose: A small callout arrow that's created by a CExplanationPopup to
// connect to the point that the explanation is referring to.
//-----------------------------------------------------------------------------
class CExplanationPopupCalloutArrow : public vgui::Panel
{
public:
CExplanationPopupCalloutArrow( Panel *parent ) : vgui::Panel( parent, "calloutarrow" )
{
SetPaintBackgroundEnabled( false );
SetMouseInputEnabled( false );
PrecacheMaterial( "vgui/callout_tail" );
}
void SetArrowPoints( int iAx, int iAy, int iBx, int iBy, int iCx, int iCy )
{
m_iArrowA[0] = iAx;
m_iArrowA[1] = iAy;
m_iArrowB[0] = iBx;
m_iArrowB[1] = iBy;
m_iArrowC[0] = iCx;
m_iArrowC[1] = iCy;
}
virtual void Paint( void );
private:
int m_iArrowA[2];
int m_iArrowB[2];
int m_iArrowC[2];
};
//-----------------------------------------------------------------------------
// Purpose: A bubble that contains a blob of text and an arrow to a specific place onscreen
//-----------------------------------------------------------------------------
class CExplanationPopup : public vgui::EditablePanel, public CGameEventListener
{
DECLARE_CLASS_SIMPLE( CExplanationPopup, vgui::EditablePanel );
public:
CExplanationPopup(Panel *parent, const char *panelName);
~CExplanationPopup( void );
void SetCalloutInParentsX( int nXPos ) { m_iCalloutInParentsX = nXPos; }
void SetCalloutInParentsY( int nYPos ) { m_iCalloutInParentsY = nYPos; }
void Popup( int iPosition = 0, int iTotalPanels = 0 );
void Hide( int iExplanationDelta = 0 );
const char *GetNextExplanation( void ) { return m_szNextExplanation; }
void SetPrevExplanation( const char *pszPrev );
virtual void ApplySettings( KeyValues *inResourceData );
virtual void OnCommand( const char *command );
virtual void OnTick( void );
virtual void OnKeyCodeTyped( vgui::KeyCode code );
virtual void OnKeyCodePressed( vgui::KeyCode code );
void PositionCallout( float flElapsed );
virtual void FireGameEvent( IGameEvent *event );
private:
int m_iCalloutSide;
float m_flStartTime;
float m_flEndTime;
char m_szNextExplanation[128];
char m_szPrevExplanation[128];
CExplanationPopupCalloutArrow *m_pCallout;
int m_iPositionInChain;
int m_iTotalInChain;
bool m_bFinishedPopup;
CPanelAnimationVar( bool, m_bForceClose, "force_close", "0" );
CPanelAnimationVarAliasType( int, m_iCalloutInParentsX, "callout_inparents_x", "0", "proportional_xpos" );
CPanelAnimationVarAliasType( int, m_iCalloutInParentsY, "callout_inparents_y", "0", "proportional_ypos" );
CPanelAnimationVarAliasType( int, m_iStartX, "start_x", "0", "proportional_xpos" );
CPanelAnimationVarAliasType( int, m_iStartY, "start_y", "0", "proportional_ypos" );
CPanelAnimationVarAliasType( int, m_iStartW, "start_wide", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iStartH, "start_tall", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iEndX, "end_x", "0", "proportional_xpos" );
CPanelAnimationVarAliasType( int, m_iEndY, "end_y", "0", "proportional_ypos" );
CPanelAnimationVarAliasType( int, m_iEndW, "end_wide", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iEndH, "end_tall", "0", "proportional_int" );
};
//-----------------------------------------------------------------------------
// Purpose: A stack to keep track of the modal dialogs that have been popped up.
//-----------------------------------------------------------------------------
class CPanelModalStack
{
public:
void PushModal( vgui::Panel *pDialog );
void PopModal( vgui::Panel *pDialog );
void Update( void );
vgui::VPanelHandle Top();
bool IsEmpty() const;
private:
void PopModal( int iIdx );
private:
CUtlVector<vgui::VPanelHandle> m_pDialogs;
};
CPanelModalStack *TFModalStack( void );
//-----------------------------------------------------------------------------
// Purpose: Generic waiting dialog
//-----------------------------------------------------------------------------
class CGenericWaitingDialog : public vgui::EditablePanel
{
DECLARE_CLASS_SIMPLE( CGenericWaitingDialog, vgui::EditablePanel );
public:
CGenericWaitingDialog( vgui::Panel *pParent );
void Close();
void ShowStatusUpdate( bool bAnimateEllipses, bool bAllowClose, float flMaxWaitTime = 0 );
protected:
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void OnCommand( const char *command );
virtual void OnTick( void );
virtual void OnTimeout();
virtual void OnUserClose();
virtual const char *GetResFile() const { return "resource/UI/econ/GenericWaitingDialog.res"; }
virtual const char *GetResFilePathId() const { return "MOD"; }
bool m_bAnimateEllipses;
int m_iNumEllipses;
CountdownTimer m_timer;
};
void ShowWaitingDialog( CGenericWaitingDialog *pWaitingDialog, const char* pUpdateText, bool bAnimate, bool bShowCancel, float flMaxDuration );
void CloseWaitingDialog();
#endif // ECON_CONTROLS_H
File diff suppressed because it is too large Load Diff
+214
View File
@@ -0,0 +1,214 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef ECON_NOTIFICATIONS_H
#define ECON_NOTIFICATIONS_H
#ifdef _WIN32
#pragma once
#endif
// forward declarations
class KeyValues;
namespace vgui
{
class EditablePanel;
};
class CEconNotificationQueue;
/**
* Base class for notifications, but is generic enough to use
*/
class CEconNotification
{
public:
CEconNotification();
virtual ~CEconNotification();
void SetText( const char *pText );
void AddStringToken( const char* pToken, const wchar_t* pValue );
void SetKeyValues( KeyValues *pKeyValues );
KeyValues *GetKeyValues() const;
const char* GetUnlocalizedText() { return m_pText; }
const wchar_t *GetText();
int GetID() const;
virtual void SetLifetime( float flSeconds );
virtual float GetExpireTime() const;
virtual float GetInGameLifeTime() const;
void SetIsInUse( bool bInUse );
bool GetIsInUse() const;
void SetSteamID( const CSteamID &steamID );
const CSteamID &GetSteamID() const;
virtual bool BShowInGameElements() const { return true; }
virtual void MarkForDeletion();
enum EType {
// Can only be deleted
eType_Basic,
// Can be accept or declined
eType_AcceptDecline,
// Can be triggered or deleted
eType_Trigger,
// Can only be triggered
eType_MustTrigger,
};
virtual EType NotificationType();
// Is this an important/high priority notification. Triggers higher visibility etc..
virtual bool BHighPriority();
// eType_Trigger or eType_MustTrigger
virtual void Trigger();
// eType_AcceptDecline
virtual void Accept();
virtual void Decline();
// eType_Basic or eType_Trigger
virtual void Deleted();
// All types, if expire time is set
virtual void Expired();
virtual void UpdateTick() { }
virtual const char *GetUnlocalizedHelpText();
virtual vgui::EditablePanel *CreateUIElement( bool bMainMenu ) const;
void SetSoundFilename( const char *filename )
{
m_pSoundFilename = filename;
}
const char *GetSoundFilename() const
{
if ( m_pSoundFilename )
{
return m_pSoundFilename;
}
return "ui/notification_alert.wav";
}
protected:
const char *m_pText;
const char *m_pSoundFilename;
float m_flExpireTime;
KeyValues *m_pKeyValues;
wchar_t m_wszBuffer[1024];
CSteamID m_steamID;
private:
friend class CEconNotificationQueue;
int m_iID;
bool m_bInUse;
};
/**
* Filter function for CEconNotification's, used to remove them
* @return true if the notification matches, false otherwise
*/
typedef bool (*NotificationFilterFunc)( CEconNotification *pNotification );
/**
* Visitor object for notifications.
*/
class CEconNotificationVisitor
{
public:
virtual void Visit( CEconNotification &notification ) = 0;
};
/**
* Adds the notification to the notification queue
* @param pNotification
* @return id to retrieve the notification later if necessary
*/
int NotificationQueue_Add( CEconNotification *pNotification );
/**
* Retrieves a notification by ID
* @param iID id of the notification
* @return the CEconNotification, NULL if not found
*/
CEconNotification *NotificationQueue_Get( int iID );
/**
* Retrieves a notification by index
* @param idx Index of the notification relative to GetNumNotifications
* @return the CEconNotification, NULL if not found
*/
CEconNotification *NotificationQueue_GetByIndex( int idx );
/**
* Removes all notifications from the queue and deletes them
* @param iID
*/
void NotificationQueue_RemoveAll();
/**
* Removes the notification from the queue and deletes it
* @param iID
*/
void NotificationQueue_Remove( int iID );
/**
* Removes the notification from the queue and deletes it
* @param pNotification
*/
void NotificationQueue_Remove( CEconNotification *pNotification );
/**
* Removes notifications that pass the specified filter
* @param func
*/
void NotificationQueue_Remove( NotificationFilterFunc func );
/**
* Count up how many notifications of the given kind are already in the queue
* @param func
*/
int NotificationQueue_Count( NotificationFilterFunc func );
/**
* The visitor object will "visit" each notification and perform any work necessary.
* @param visitor object
*/
void NotificationQueue_Visit( CEconNotificationVisitor &visitor );
/**
* Update the notification queue
*/
void NotificationQueue_Update();
/**
* @return the number of notifications
*/
int NotificationQueue_GetNumNotifications();
/**
* Create the main menu ui element
* @param pParent
* @param pElementName
* @return the control that was created
*/
vgui::EditablePanel* NotificationQueue_CreateMainMenuUIElement( vgui::EditablePanel *pParent, const char *pElementName );
#endif // endif
+458
View File
@@ -0,0 +1,458 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "econ_sample_rootui.h"
#include "vgui/IInput.h"
#include <vgui/ILocalize.h>
#include "ienginevgui.h"
#include "econ_item_inventory.h"
#include "backpack_panel.h"
#include "item_pickup_panel.h"
#include "store/store_panel.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
static vgui::DHANDLE<CEconSampleRootUI> g_EconSampleRootUIPanel;
#if !defined (TF_CLIENT_DLL)
IEconRootUI *EconUI( void )
{
if (!g_EconSampleRootUIPanel.Get())
{
g_EconSampleRootUIPanel = vgui::SETUP_PANEL( new CEconSampleRootUI( NULL ) );
g_EconSampleRootUIPanel->InvalidateLayout( false, true );
}
return g_EconSampleRootUIPanel;
}
#endif
//-----------------------------------------------------------------------------
// Purpose: Basic help dialog
//-----------------------------------------------------------------------------
CEconSampleRootUI::CEconSampleRootUI( vgui::Panel *parent ) : vgui::Frame(parent, "econ_sample_rootui")
{
// Econ UI is parented to the game UI panel (not the client DLL panel).
vgui::VPANEL gameuiPanel = enginevgui->GetPanel( PANEL_GAMEUIDLL );
SetParent( gameuiPanel );
// We don't want the gameui to delete us, or things get messy
SetAutoDelete( false );
SetMoveable( false );
SetSizeable( false );
SetCloseButtonVisible( false );
vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
SetScheme(scheme);
SetProportional( true );
ListenForGameEvent( "gameui_hidden" );
// Create our subpanels
m_pBackpackPanel = new CBackpackPanel( this, "backpack_panel" );
// Start with just the base UI visible
m_nVisiblePanel = ECONUI_BASEUI;
UpdateSubPanelVisibility();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CEconSampleRootUI::~CEconSampleRootUI()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconSampleRootUI::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
LoadControlSettings( "Resource/UI/Econ/RootUI.res" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconSampleRootUI::PerformLayout( void )
{
if ( GetVParent() )
{
int w,h;
vgui::ipanel()->GetSize( GetVParent(), w, h );
SetBounds(0,0,w,h);
}
BaseClass::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconSampleRootUI::ShowPanel(bool bShow)
{
m_bPreventClosure = false;
SetVisible( bShow );
if ( bShow )
{
MoveToFront();
m_nVisiblePanel = ECONUI_BASEUI;
UpdateSubPanelVisibility();
InventoryManager()->ShowItemsPickedUp( true, false );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconSampleRootUI::FireGameEvent( IGameEvent *event )
{
const char * type = event->GetName();
if ( Q_strcmp(type, "gameui_hidden") == 0 )
{
if ( m_bPreventClosure )
{
engine->ClientCmd_Unrestricted( "gameui_activate" );
}
else
{
ShowPanel( false );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconSampleRootUI::OnCommand( const char *command )
{
if ( !Q_stricmp( command, "close" ) )
{
ShowPanel( false );
// If we're connected to a game server, we also close the game UI.
if ( engine->IsInGame() )
{
bool bClose = true;
if ( m_bCheckForRoomOnExit )
{
// Check to make sure the player has room for all his items. If not, bring up the discard panel. Otherwise, go away.
// We need to do this to catch players who used the "Change Loadout" button in the pickup panel, and may be out of room.
bClose = !InventoryManager()->CheckForRoomAndForceDiscard();
}
if ( bClose )
{
engine->ClientCmd_Unrestricted( "gameui_hide" );
}
}
}
else if ( !Q_stricmp( command, "back" ) )
{
ShowPanel( true );
}
else if ( !Q_stricmp( command, "loadout" ) )
{
// Ignore selection while we don't have a steam connection
if ( !InventoryManager()->GetLocalInventory()->RetrievedInventoryFromSteam() )
return;
OpenSubPanel( ECONUI_LOADOUT );
}
else if ( !Q_strnicmp( command, "backpack", 8 ) )
{
OpenSubPanel( ECONUI_BACKPACK );
}
else if ( !Q_strnicmp( command, "crafting", 8 ) )
{
OpenSubPanel( ECONUI_CRAFTING );
}
else if ( !Q_strnicmp( command, "armory", 6 ) )
{
OpenSubPanel( ECONUI_ARMORY );
}
else if ( !Q_strnicmp( command, "store", 5 ) )
{
EconUI()->OpenStorePanel( 0, false );
}
else if ( !Q_strnicmp( command, "trading", 7 ) )
{
// if ( IsFreeTrialAccount() )
// {
// ShowMessageBox( "#TF_Trial_CannotTrade_Title", "#TF_Trial_CannotTrade_Text", "#GameUI_OK" );
// return;
// }
OpenTradingStartDialog();
}
else
{
engine->ClientCmd( const_cast<char *>( command ) );
}
BaseClass::OnCommand( command );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconSampleRootUI::OnKeyCodeTyped(vgui::KeyCode code)
{
if ( code == KEY_ESCAPE )
{
if ( !m_bPreventClosure )
{
ShowPanel( false );
}
}
else
{
BaseClass::OnKeyCodeTyped( code );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
IEconRootUI *CEconSampleRootUI::OpenEconUI( int iDirectToPage, bool bCheckForInventorySpaceOnExit )
{
engine->ClientCmd_Unrestricted( "gameui_activate" );
ShowPanel( true );
if ( iDirectToPage == ECONUI_BACKPACK )
{
}
else if ( iDirectToPage == ECONUI_CRAFTING )
{
}
else if ( iDirectToPage == ECONUI_ARMORY )
{
}
SetCheckForRoomOnExit( bCheckForInventorySpaceOnExit );
return this;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconSampleRootUI::CloseEconUI( void )
{
if ( IsVisible() )
{
ShowPanel( false );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CEconSampleRootUI::IsUIPanelVisible( EconBaseUIPanels_t iPanel )
{
if ( !IsVisible() )
return false;
switch ( iPanel )
{
case ECONUI_BASEUI:
return true;
case ECONUI_BACKPACK:
return (GetBackpackPanel() && GetBackpackPanel()->IsVisible());
case ECONUI_CRAFTING:
//return (GetCraftingPanel() && GetCraftingPanel()->IsVisible());
break;
case ECONUI_ARMORY:
break;
case ECONUI_TRADING:
break;
case ECONUI_LOADOUT:
break;
default:
Assert(0);
break;
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconSampleRootUI::OpenSubPanel( EconBaseUIPanels_t nPanel )
{
m_nVisiblePanel = nPanel;
UpdateSubPanelVisibility();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconSampleRootUI::OpenTradingStartDialog( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconSampleRootUI::UpdateSubPanelVisibility( void )
{
bool bBackpackVisible = (m_nVisiblePanel == ECONUI_BACKPACK);
if ( m_pBackpackPanel->IsVisible() != bBackpackVisible )
{
m_pBackpackPanel->ShowPanel( false, bBackpackVisible );
}
//m_pClassLoadoutPanel->SetVisible( false );
//m_pArmoryPanel->SetVisible( false );
//m_pCraftingPanel->ShowPanel( m_iCurrentClassIndex, true, (m_iPrevShowingPanel == CHAP_ARMORY) );
}
static vgui::DHANDLE<CItemPickupPanel> g_ItemPickupPanel;
static vgui::DHANDLE<CItemDiscardPanel> g_ItemDiscardPanel;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CItemPickupPanel *CEconSampleRootUI::OpenItemPickupPanel( void )
{
if (!g_ItemPickupPanel.Get())
{
g_ItemPickupPanel = vgui::SETUP_PANEL( new CItemPickupPanel( NULL ) );
g_ItemPickupPanel->InvalidateLayout( false, true );
}
engine->ClientCmd_Unrestricted( "gameui_activate" );
g_ItemPickupPanel->ShowPanel( true );
return g_ItemPickupPanel;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CItemDiscardPanel *CEconSampleRootUI::OpenItemDiscardPanel( void )
{
if (!g_ItemDiscardPanel.Get())
{
g_ItemDiscardPanel = vgui::SETUP_PANEL( new CItemDiscardPanel( NULL ) );
g_ItemDiscardPanel->InvalidateLayout( false, true );
}
engine->ClientCmd_Unrestricted( "gameui_activate" );
g_ItemDiscardPanel->ShowPanel( true );
return g_ItemDiscardPanel;
}
static vgui::DHANDLE<CStorePanel> g_StorePanel;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconSampleRootUI::CreateStorePanel( void )
{
// Clean up previous store panel?
if ( g_StorePanel.Get() != NULL )
{
g_StorePanel->MarkForDeletion();
}
// Create the store panel
g_StorePanel = vgui::SETUP_PANEL( new CStorePanel( NULL ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStorePanel *CEconSampleRootUI::OpenStorePanel( int iItemDef, bool bAddToCart )
{
// Make sure we've got the appropriate connections to Steam
if ( !steamapicontext || !steamapicontext->SteamUtils() )
{
OpenStoreStatusDialog( NULL, "#StoreUpdate_SteamRequired", true, false );
return NULL;
}
if ( !steamapicontext->SteamUtils()->IsOverlayEnabled() )
{
OpenStoreStatusDialog( NULL, "#StoreUpdate_OverlayRequired", true, false );
return NULL;
}
if ( !CStorePanel::IsPricesheetLoaded() )
{
OpenStoreStatusDialog( NULL, "#StoreUpdate_Loading", false, false );
CStorePanel::SetShouldShowWarnings( true );
CStorePanel::RequestPricesheet();
return NULL;
}
if ( !g_StorePanel )
return NULL;
engine->ClientCmd_Unrestricted( "gameui_activate" );
if ( iItemDef )
{
g_StorePanel->StartAtItemDef( iItemDef, bAddToCart );
}
g_StorePanel->ShowPanel( true );
return g_StorePanel;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStorePanel *CEconSampleRootUI::GetStorePanel( void )
{
return g_StorePanel;
}
#ifdef _DEBUG
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Open_EconUI( const CCommand &args )
{
EconUI()->OpenEconUI();
}
ConCommand open_econui( "open_econui", Open_EconUI );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Open_EconUIBackpack( const CCommand &args )
{
EconUI()->OpenEconUI( ECONUI_BACKPACK );
}
ConCommand open_econui_backpack( "open_econui_backpack", Open_EconUIBackpack, "Open the backpack.", FCVAR_NONE );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void Open_EconUICrafting( const CCommand &args )
{
EconUI()->OpenEconUI( ECONUI_CRAFTING );
}
ConCommand open_econui_crafting( "open_econui_crafting", Open_EconUICrafting, "Open the crafting screen.", FCVAR_NONE );
#endif // _DEBUG
+88
View File
@@ -0,0 +1,88 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef ECON_SAMPLE_ROOTUI_H
#define ECON_SAMPLE_ROOTUI_H
#ifdef _WIN32
#pragma once
#endif
#include "econ_ui.h"
#include "vgui_controls/Frame.h"
#include "GameEventListener.h"
#include "backpack_panel.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CEconSampleRootUI : public vgui::Frame, public IEconRootUI, public CGameEventListener
{
DECLARE_CLASS_SIMPLE( CEconSampleRootUI, vgui::Frame );
public:
CEconSampleRootUI( vgui::Panel *parent );
virtual ~CEconSampleRootUI();
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void PerformLayout( void );
virtual void OnCommand( const char *command );
virtual void ShowPanel( bool bShow );
virtual void OnKeyCodeTyped(vgui::KeyCode code);
void SetCheckForRoomOnExit( bool bCheck ) { m_bCheckForRoomOnExit = bCheck; }
void FireGameEvent( IGameEvent *event );
//---------------------------------------
// IEconRootUI
virtual IEconRootUI *OpenEconUI( int iDirectToPage = 0, bool bCheckForInventorySpaceOnExit = false );
virtual void CloseEconUI( void );
virtual bool IsUIPanelVisible( EconBaseUIPanels_t iPanel );
virtual void SetPreventClosure( bool bPrevent ) { m_bPreventClosure = bPrevent; }
// Sub panel access.
// These are panels that are parented to the root EconUI.
virtual CBackpackPanel *GetBackpackPanel( void ) { return NULL; }
virtual CCraftingPanel *GetCraftingPanel( void ) { return NULL; }
// Gamestats access
virtual void Gamestats_ItemTransaction( int eventID, CEconItemView *item, const char *pszReason = NULL, int iQuality = 0 ) { return; }
virtual void Gamestats_Store( int eventID, CEconItemView* item=NULL, const char* panelName=NULL,
int classId=0, const cart_item_t* in_cartItem=NULL, int in_checkoutAttempts=0, const char* storeError=NULL, int in_totalPrice=0, int in_currencyCode=0 ) { return; }
virtual void SetExperimentValue( uint64 experimentValue ) { return; }
// Open separate economy panels (they're not parented to the root EconUI)
// This is here so that games can customize the implementation of these panels.
CItemPickupPanel *OpenItemPickupPanel( void );
CItemDiscardPanel *OpenItemDiscardPanel( void );
// Store
virtual void CreateStorePanel( void );
virtual CStorePanel *OpenStorePanel( int iItemDef, bool bAddToCart );
virtual CStorePanel *GetStorePanel( void );
// When the root UI is closed, send an "EconUIClosed" message to pListener.
virtual void AddPanelCloseListener( vgui::Panel *pListener ) { AssertMsg( 0, "Implement me!" ); }
// The panel at which we want back to actually close the UI - defaults to the root panel - a negative value can be passed in for class loadout panels
virtual void SetClosePanel( int iPanel ) { AssertMsg( 0, "Implement me!" ); }
// Call this to set which team the class loadout should display
virtual void SetDefaultTeam( int iTeam ) { AssertMsg( 0, "Implement me!" ); }
protected:
void OpenSubPanel( EconBaseUIPanels_t nPanel );
void UpdateSubPanelVisibility( void );
void OpenTradingStartDialog( void );
private:
bool m_bPreventClosure;
bool m_bCheckForRoomOnExit;
EconBaseUIPanels_t m_nVisiblePanel;
CBackpackPanel *m_pBackpackPanel;
};
#endif // ECON_SAMPLE_ROOTUI_H
+645
View File
@@ -0,0 +1,645 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "cbase.h"
#include "econ_trading.h"
// for messaging with the GC
#include "econ_gcmessages.h"
#include "econ_item_inventory.h"
#include "econ_gcmessages.h"
#include "econ_ui.h"
// other
#include "c_baseplayer.h"
#include "c_playerresource.h"
// UI
#include "confirm_dialog.h"
#include "econ_controls.h"
#include "vgui/ILocalize.h"
#include "econ_notifications.h"
#ifdef TF_CLIENT_DLL
#include "c_tf_gamestats.h"
#endif
#include "gc_clientsystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
//-----------------------------------------------------------------------------
const char *g_FriendRelationship[] =
{
"none"
"blocked",
"request_recipient",
"friend",
"request_initiator",
"ignored",
"ignored_friend"
};
const char *g_RejectedReasons[] =
{
"accepted",
"declined",
"vac_banned_initiator",
"vac_banned_target",
"target_already_trading",
"trading_disabled",
"user_not_logged_in"
};
const char *g_ClosedReasons[] =
{
"traded",
"canceled",
"error",
"does_not_own_items",
"untradable_items",
"no_items",
"trading_disabled"
};
enum
{
kShowTradeRequestsFrom_FriendsOnly = 1,
kShowTradeRequestsFrom_FriendsAndCurrentServer = 2,
kShowTradeRequestsFrom_Anyone = 3,
kShowTradeRequestsFrom_NoOne = 4,
};
ConVar cl_trading_show_requests_from( "cl_trading_show_requests_from", "3", FCVAR_ARCHIVE, "View trade requests from a certain group only." );
static bool sbTestingSelfTrade = false;
static int iTradeRequests = 0;
static int iTradeAttempts = 0;
static int iTradeOffers = 0;
static int iGiftsGiven = 0;
const uint32 kTradeRequestLifetime = 30.0f;
// waiting dialog
class CTradingWaitDialog : public CGenericWaitingDialog
{
public:
CTradingWaitDialog( const char *pText = "#TF_Trading_Timeout_Text", const wchar_t *pPlayerName = NULL )
: CGenericWaitingDialog( NULL )
, m_pText( pText )
, m_pKeyValues( NULL )
{
if ( pPlayerName != NULL && wcsicmp( pPlayerName, L"" ) != 0 )
{
m_pKeyValues = new KeyValues( "CTradingWaitDialog" );
m_pKeyValues->SetWString( "other_player", pPlayerName );
}
}
virtual ~CTradingWaitDialog()
{
if ( m_pKeyValues != NULL )
{
m_pKeyValues->deleteThis();
}
}
protected:
virtual void OnTimeout()
{
ShowMessageBox( "#TF_Trading_Timeout_Title", m_pText, m_pKeyValues, "#GameUI_OK" );
}
virtual void OnUserClose()
{
GCSDK::CGCMsg< MsgGCTrading_CancelSession_t > msg( k_EMsgGCTrading_CancelSession );
GCClientSystem()->BSendMessage( msg );
// @note not sure we need to wait for the GC here, but we will just in case...
ShowWaitingDialog( new CTradingWaitDialog(), "#TF_Trading_WaitingForCancel", true, false, 20.0f );
}
KeyValues *m_pKeyValues;
const char* m_pText;
};
// used by the waiting dialogs
static void TradeCompleteDialogClosed( bool bConfirmed, void *pContext )
{
if ( bConfirmed )
{
InventoryManager()->ShowItemsPickedUp( true );
}
}
//-----------------------------------------------------------------------------
// jobs
class CTFTradeRequestNotification : public CEconNotification
{
public:
CTFTradeRequestNotification( uint64 ulInitiatorSteamID, uint32 unTradeRequestID, const char* pPlayerName )
: CEconNotification()
, m_unTradeRequestID( unTradeRequestID )
{
SetSteamID( ulInitiatorSteamID );
g_pVGuiLocalize->ConvertANSIToUnicode( pPlayerName, m_wszPlayerName, sizeof(m_wszPlayerName) );
SetLifetime( kTradeRequestLifetime );
SetText( "#TF_Trading_JoinText" );
AddStringToken( "initiator", m_wszPlayerName );
}
virtual EType NotificationType() { return eType_AcceptDecline; }
/// XXX(JohnS): Dead code? Was always accept/decline AFAICT
virtual void Trigger()
{
CTFGenericConfirmDialog *pDialog = ShowConfirmDialog( "#TF_Trading_JoinTitle", "#TF_Trading_JoinText", "#GameUI_OK", "#TF_Trading_JoinCancel", &ConfirmJoinTradeSession );
pDialog->SetContext( this );
pDialog->AddStringToken( "initiator", m_wszPlayerName );
// so we aren't deleted
SetIsInUse( true );
}
virtual void Accept()
{
ConfirmJoinTradeSession( true, this );
}
virtual void Decline()
{
ConfirmJoinTradeSession( false, this );
}
static void ConfirmJoinTradeSession( bool bConfirmed, void *pContext )
{
CTFTradeRequestNotification *pNotification = (CTFTradeRequestNotification*)pContext;
GCSDK::CGCMsg< MsgGCTrading_InitiateTradeResponse_t > msg( k_EMsgGCTrading_InitiateTradeResponse );
msg.Body().m_eResponse = bConfirmed ? k_EGCMsgInitiateTradeResponse_Accepted : k_EGCMsgInitiateTradeResponse_Declined;
msg.Body().m_unTradeRequestID = pNotification->m_unTradeRequestID;
GCClientSystem()->BSendMessage( msg );
if ( bConfirmed )
{
ShowWaitingDialog( new CTradingWaitDialog(), "#TF_Trading_WaitingForServer", true, false, kTradeRequestLifetime );
}
// now we can be deleted
pNotification->SetIsInUse( false );
pNotification->MarkForDeletion();
}
static bool IsTradingNotification( CEconNotification * pNotification )
{
return dynamic_cast< CTFTradeRequestNotification * >( pNotification ) != NULL;
}
public:
uint32 m_unTradeRequestID;
wchar_t m_wszPlayerName[MAX_PLAYER_NAME_LENGTH];
};
// request from party A (through GC) to start trading
class CGCTrading_InitiateTradeRequest : public GCSDK::CGCClientJob
{
public:
CGCTrading_InitiateTradeRequest( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
void SendDeclinedMessage( uint32 unTradeRequestID )
{
GCSDK::CGCMsg< MsgGCTrading_InitiateTradeResponse_t > msgResponse( k_EMsgGCTrading_InitiateTradeResponse );
msgResponse.Body().m_eResponse = k_EGCMsgInitiateTradeResponse_Declined;
msgResponse.Body().m_unTradeRequestID = unTradeRequestID;
GCClientSystem()->BSendMessage( msgResponse );
}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CGCMsg<MsgGCTrading_InitiateTradeRequest_t> msg( pNetPacket );
CUtlString playerName;
msg.BReadStr( &playerName );
if ( sbTestingSelfTrade )
{
CloseWaitingDialog();
}
else if ( msg.Body().m_ulOtherSteamID == Trading_GetLocalPlayerSteamID().ConvertToUint64() )
{
CloseWaitingDialog();
}
iTradeRequests++;
#ifdef TF_CLIENT_DLL
C_CTF_GameStats.Event_Trading( IE_TRADING_REQUEST_RECEIVED, msg.Body().m_ulOtherSteamID, iTradeRequests );
#endif
// auto-decline for ignored or blocked peoples
if ( steamapicontext == NULL || steamapicontext->SteamFriends() == NULL )
{
return true;
}
CSteamID steamIDOther( msg.Body().m_ulOtherSteamID );
EFriendRelationship eRelationship = steamapicontext->SteamFriends()->GetFriendRelationship( steamIDOther );
switch ( eRelationship )
{
case k_EFriendRelationshipBlocked:
case k_EFriendRelationshipIgnored:
case k_EFriendRelationshipIgnoredFriend:
{
SendDeclinedMessage( msg.Body().m_unTradeRequestID );
return true;
}
break;
} // switch
switch ( cl_trading_show_requests_from.GetInt() )
{
case kShowTradeRequestsFrom_FriendsOnly:
{
if ( eRelationship != k_EFriendRelationshipFriend )
{
SendDeclinedMessage( msg.Body().m_unTradeRequestID );
return true;
}
}
break;
case kShowTradeRequestsFrom_FriendsAndCurrentServer:
{
if ( eRelationship == k_EFriendRelationshipFriend )
break;
bool bInCurrentGame = false;
if ( engine->IsInGame() )
{
// otherwise, test if they are in the current game
for( int iPlayerIndex = 1 ; iPlayerIndex <= MAX_PLAYERS; iPlayerIndex++ )
{
if ( g_PR && g_PR->IsConnected( iPlayerIndex ) )
{
player_info_t pi;
if ( !engine->GetPlayerInfo( iPlayerIndex, &pi ) )
continue;
if ( !pi.friendsID )
continue;
CSteamID steamID( pi.friendsID, 1, GetUniverse(), k_EAccountTypeIndividual );
if ( steamID == steamIDOther )
{
bInCurrentGame = true;
break;
}
}
}
}
if ( bInCurrentGame == false )
{
SendDeclinedMessage( msg.Body().m_unTradeRequestID );
return true;
}
}
break;
case kShowTradeRequestsFrom_Anyone:
{
// nothing to check
}
break;
case kShowTradeRequestsFrom_NoOne:
{
SendDeclinedMessage( msg.Body().m_unTradeRequestID );
return true;
}
break;
}
NotificationQueue_Add( new CTFTradeRequestNotification( msg.Body().m_ulOtherSteamID, msg.Body().m_unTradeRequestID, playerName.Get() ) );
return true;
}
protected:
};
GC_REG_JOB( GCSDK::CGCClient, CGCTrading_InitiateTradeRequest, "CGCTrading_InitiateTradeRequest", k_EMsgGCTrading_InitiateTradeRequest, GCSDK::k_EServerTypeGCClient );
#ifdef _DEBUG
#ifdef CLIENT_DLL
CON_COMMAND( cl_trading_test, "Tests the trade ui notification." )
{
if ( steamapicontext == NULL || steamapicontext->SteamUser() == NULL )
return;
CSteamID steamID = steamapicontext->SteamUser()->GetSteamID();
NotificationQueue_Add( new CTFTradeRequestNotification( steamID.ConvertToUint64(), steamID.ConvertToUint64(), "Biff" ) );
}
#endif
#endif // _DEBUG
/**
* Remove notification that matches the trade request
*/
class CEconNotificationVisitor_RemoveTradeRequest : public CEconNotificationVisitor
{
public:
CEconNotificationVisitor_RemoveTradeRequest( uint32 unTradeRequestID ) : m_unTradeRequestID( unTradeRequestID ) {}
virtual void Visit( CEconNotification &notification )
{
if ( CTFTradeRequestNotification::IsTradingNotification( &notification ) )
{
CTFTradeRequestNotification &tradeNotification = dynamic_cast< CTFTradeRequestNotification& >( notification );
if ( tradeNotification.m_unTradeRequestID == m_unTradeRequestID )
{
tradeNotification.MarkForDeletion();
}
}
}
private:
uint32 m_unTradeRequestID;
};
// GC notification of trade request status
static const char *g_pszTradeResponseDescLocKeys[] =
{
"#TF_Trading_BusyText", // k_EGCMsgInitiateTradeResponse_Accepted (should never be used!)
"#TF_Trading_DeclinedText", // k_EGCMsgInitiateTradeResponse_Declined
"#TF_Trading_VACBannedText", // k_EGCMsgInitiateTradeResponse_VAC_Banned_Initiator
"#TF_Trading_VACBanned2Text", // k_EGCMsgInitiateTradeResponse_VAC_Banned_Target
"#TF_Trading_BusyText", // k_EGCMsgInitiateTradeResponse_Target_Already_Trading
"#TF_Trading_DisabledText", // k_EGCMsgInitiateTradeResponse_Disabled
"#TF_Trading_NotLoggedIn", // k_EGCMsgInitiateTradeResponse_NotLoggedIn
"#TF_Trading_BusyText", // k_EGCMsgInitiateTradeResponse_Cancel (should never be used!)
"#TF_Trading_TooSoon", // k_EGCMsgInitiateTradeResponse_TooSoon
"#TF_Trading_TooSoonPenalty", // k_EGCMsgInitiateTradeResponse_TooSoonPenalty
"#TF_Trading_TradeBannedText", // (was k_EGCMsgInitiateTradeResponse_Free_Account_Initiator_DEPRECATED)
"#TF_Trading_TradeBanned2Text", // k_EGCMsgInitiateTradeResponse_Trade_Banned_Target
"#TF_Trading_FreeAccountInitiate", // k_EGCMsgInitiateTradeResponse_Free_Account_Initiator
"#TF_Trading_SharedAccountInitiate", // k_EGCMsgInitiateTradeResponse_Shared_Account_Initiator
"#TF_Trading_Service_Unavailable", // k_EGCMsgInitiateTradeResponse_Service_Unavailable
"#TF_Trading_YouBlockedThem", // k_EGCMsgInitiateTradeResponse_Target_Blocked
"#TF_Trading_NeedVerifiedEmail", // k_EGCMsgInitiateTradeResponse_NeedVerifiedEmail
"#TF_Trading_NeedSteamGuard", // k_EGCMsgInitiateTradeResponse_NeedSteamGuard
"#TF_Trading_SteamGuardDuration", // k_EGCMsgInitiateTradeResponse_SteamGuardDuration
"#TF_Trading_TheyCannotTrade", // k_EGCMsgInitiateTradeResponse_TheyCannotTrade
"#TF_Trading_PasswordChanged", // k_EGCMsgInitiateTradeResponse_Recent_Password_Reset = 20,
"#TF_Trading_NewDevice", // k_EGCMsgInitiateTradeResponse_Using_New_Device = 21,
"#TF_Trading_InvalidCookie" // k_EGCMsgInitiateTradeResponse_Sent_Invalid_Cookie = 22,
};
class CGCTrading_InitiateTradeResponse : public GCSDK::CGCClientJob
{
public:
CGCTrading_InitiateTradeResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
// If this assertion fails it probably means you added a new value to EGCMsgInitiateTradeResponse
// but didn't add a string to the array that tracks the user-facing response strings.
Assert( ARRAYSIZE( g_pszTradeResponseDescLocKeys ) == k_EGCMsgInitiateTradeResponse_Count );
CloseWaitingDialog();
GCSDK::CGCMsg<MsgGCTrading_InitiateTradeResponse_t> msg( pNetPacket );
const uint32 eResponse = msg.Body().m_eResponse;
switch ( eResponse )
{
case k_EGCMsgInitiateTradeResponse_Accepted:
#ifdef TF_CLIENT_DLL
C_CTF_GameStats.Event_Trading( IE_TRADING_REQUEST_ACCEPTED, iTradeRequests, g_RejectedReasons[msg.Body().m_eResponse] );
#endif
ShowWaitingDialog( new CTradingWaitDialog(), "#TF_Trading_WaitingForStart", true, false, 30.0f );
return true; // !
case k_EGCMsgInitiateTradeResponse_Cancel:
{
CEconNotificationVisitor_RemoveTradeRequest visitor( msg.Body().m_unTradeRequestID );
NotificationQueue_Visit( visitor );
break;
}
case k_EGCMsgInitiateTradeResponse_Declined:
case k_EGCMsgInitiateTradeResponse_VAC_Banned_Initiator:
case k_EGCMsgInitiateTradeResponse_VAC_Banned_Target:
case k_EGCMsgInitiateTradeResponse_Target_Already_Trading:
case k_EGCMsgInitiateTradeResponse_Disabled:
case k_EGCMsgInitiateTradeResponse_NotLoggedIn:
case k_EGCMsgInitiateTradeResponse_TooSoon:
case k_EGCMsgInitiateTradeResponse_TooSoonPenalty:
case k_EGCMsgInitiateTradeResponse_Trade_Banned_Initiator:
case k_EGCMsgInitiateTradeResponse_Trade_Banned_Target:
case k_EGCMsgInitiateTradeResponse_Shared_Account_Initiator:
case k_EGCMsgInitiateTradeResponse_Service_Unavailable:
case k_EGCMsgInitiateTradeResponse_Target_Blocked:
case k_EGCMsgInitiateTradeResponse_NeedVerifiedEmail:
case k_EGCMsgInitiateTradeResponse_NeedSteamGuard:
case k_EGCMsgInitiateTradeResponse_TheyCannotTrade:
case k_EGCMsgInitiateTradeResponse_Recent_Password_Reset:
case k_EGCMsgInitiateTradeResponse_Using_New_Device:
case k_EGCMsgInitiateTradeResponse_Sent_Invalid_Cookie:
ShowMessageBox( "#TF_Trading_StatusTitle", g_pszTradeResponseDescLocKeys[eResponse], "#GameUI_OK" );
break;
case k_EGCMsgInitiateTradeResponse_SteamGuardDuration:
{
KeyValuesAD kvTokens( "CTradingWaitDialog" );
kvTokens->SetWString( "days", L"15" ); // Ideally this would come from the GC, which would get the value from Steam
ShowMessageBox( "#TF_Trading_StatusTitle", g_pszTradeResponseDescLocKeys[eResponse], kvTokens, "#GameUI_OK" );
break;
}
default:
#ifdef TF_CLIENT_DLL
C_CTF_GameStats.Event_Trading( IE_TRADING_REQUEST_REJECTED, iTradeRequests, "unknown" );
#endif
ShowMessageBox( "#TF_Trading_StatusTitle", "#TF_Trading_BusyText", "#GameUI_OK" );
return true;
} // switch
#ifdef TF_CLIENT_DLL
C_CTF_GameStats.Event_Trading( IE_TRADING_REQUEST_REJECTED, iTradeRequests, g_RejectedReasons[msg.Body().m_eResponse] );
#endif
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCTrading_InitiateTradeResponse, "CGCTrading_InitiateTradeResponse", k_EMsgGCTrading_InitiateTradeResponse, GCSDK::k_EServerTypeGCClient );
// start trading session
class CGCTrading_StartSession : public GCSDK::CGCClientJob
{
public:
CGCTrading_StartSession( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CGCMsg<MsgGCTrading_StartSession_t> msg( pNetPacket );
steamapicontext->SteamFriends()->ActivateGameOverlayToUser( "jointrade", msg.Body().m_ulSteamIDPartyB );
CloseWaitingDialog();
// remove all trading notifications
NotificationQueue_Remove( &CTFTradeRequestNotification::IsTradingNotification );
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCTrading_StartSession, "CGCTrading_StartSession", k_EMsgGCTrading_StartSession, GCSDK::k_EServerTypeGCClient );
//-----------------------------------------------------------------------------
// External interface
CSteamID Trading_GetLocalPlayerSteamID()
{
if ( steamapicontext && steamapicontext->SteamUser() )
{
return steamapicontext->SteamUser()->GetSteamID();
}
return CSteamID();
}
void Trading_RequestTrade( int iPlayerIdx )
{
CSteamID steamID;
C_BasePlayer *pPlayer = ToBasePlayer( UTIL_PlayerByIndex( iPlayerIdx ) );
if ( pPlayer && pPlayer->GetSteamID( &steamID ) )
{
Trading_RequestTrade( steamID );
}
}
void Trading_RequestTrade( const CSteamID &steamID )
{
sbTestingSelfTrade = false;
GCSDK::CGCMsg< MsgGCTrading_InitiateTradeRequest_t > msg( k_EMsgGCTrading_InitiateTradeRequest );
msg.Body().m_ulOtherSteamID = steamID.ConvertToUint64();
bool bSent = GCClientSystem()->BSendMessage( msg );
if ( bSent )
{
iTradeRequests++;
#ifdef TF_CLIENT_DLL
C_CTF_GameStats.Event_Trading( IE_TRADING_REQUEST_SENT, msg.Body().m_ulOtherSteamID, iTradeRequests );
#endif
const char* pPlayerName = InventoryManager()->PersonaName_Get( steamID.GetAccountID() );
if ( pPlayerName != NULL && FStrEq( pPlayerName, "" ) == false )
{
wchar_t wszPlayerName[MAX_PLAYER_NAME_LENGTH];
g_pVGuiLocalize->ConvertANSIToUnicode( pPlayerName, wszPlayerName, sizeof(wszPlayerName) );
CTradingWaitDialog *pDialog = new CTradingWaitDialog( "#TF_Trading_TimeoutPartyB_Named", wszPlayerName );
ShowWaitingDialog( pDialog, "#TF_Trading_WaitingForPartyB", true, true, 30.0f );
wchar_t wszConstructedString[1024];
g_pVGuiLocalize->ConstructString_safe( wszConstructedString, g_pVGuiLocalize->Find( "#TF_Trading_WaitingForPartyB_Named" ), 1, wszPlayerName );
pDialog->SetDialogVariable( "updatetext", wszConstructedString );
}
else
{
CTradingWaitDialog *pDialog = new CTradingWaitDialog( "#TF_Trading_TimeoutPartyB" );
ShowWaitingDialog( pDialog, "#TF_Trading_WaitingForPartyB", true, true, 30.0f );
}
}
}
const char* UniverseToCommunityURL( EUniverse universe )
{
switch( universe )
{
default: // return public if we don't have a better guess.
case k_EUniversePublic: return "https://steamcommunity.com";
case k_EUniverseBeta: return "https://beta.steamcommunity.com";
case k_EUniverseDev: return "https://localhost/community";
}
// Should never get here.
return UniverseToCommunityURL( k_EUniversePublic );
}
const char* GetCommunityURL()
{
if ( GetUniverse() == k_EUniverseInvalid )
{
Assert( !"calling GetCommunityURL when not connected. This is allowed, but will return public universe." );
return UniverseToCommunityURL( k_EUniversePublic );
}
return UniverseToCommunityURL( GetUniverse() );
}
void Trading_SendGift( const CSteamID& steamID, const CEconItemView& giftItem )
{
if ( !steamapicontext || !steamapicontext->SteamFriends() )
{
// TODO: Error dialog.
return;
}
#ifdef TF_CLIENT_DLL
C_CTF_GameStats.Event_Trading( IE_TRADING_ITEM_GIFTED, steamID.ConvertToUint64(), iGiftsGiven );
#endif
// Build up the steam URL and send it over.
// Should look like this: https://steamcommunity.com/trade/1/sendgift/?appid=&contextid=&assetid=&steamid_target=
steamapicontext->SteamFriends()->ActivateGameOverlayToWebPage(
CFmtStrMax( "%s/trade/1/sendgift/?appid=%d&contextid=%d&assetid=%llu&steamid_target=%llu",
GetCommunityURL(),
engine->GetAppID(),
2, // k_EEconContextBackpack
giftItem.GetItemID(),
steamID.ConvertToUint64()
)
);
}
CON_COMMAND( cl_trade, "Trade with a person by player name" )
{
if ( args.ArgC() < 2 )
return;
if ( GetUniverse() == k_EUniverseInvalid )
return;
int iLocalPlayerIndex = GetLocalPlayerIndex();
for( int iPlayerIndex = 1 ; iPlayerIndex <= MAX_PLAYERS; iPlayerIndex++ )
{
if( ( iPlayerIndex != iLocalPlayerIndex ) && ( g_PR->IsConnected( iPlayerIndex ) ) )
{
player_info_t pi;
if ( !engine->GetPlayerInfo( iPlayerIndex, &pi ) )
continue;
if ( !pi.friendsID )
continue;
if ( FStrEq( pi.name, args[1] ) == false )
continue;
CSteamID steamID( pi.friendsID, 1, GetUniverse(), k_EAccountTypeIndividual );
Trading_RequestTrade( steamID );
return;
}
}
}
CON_COMMAND( cl_trade_steamid, "Trade with a person by steam id" )
{
if ( args.ArgC() < 2 )
return;
if ( GetUniverse() == k_EUniverseInvalid )
return;
const char *pInput = args[1];
if ( pInput[0] >= '0' && pInput[0] <= '9' )
{
CSteamID steamID;
steamID.SetFromString( pInput, GetUniverse() );
if ( steamID.IsValid() )
Trading_RequestTrade( steamID );
}
}
#ifdef _DEBUG
CON_COMMAND( cl_trading_test_self_trade, "Test self-trading" )
{
Trading_RequestTrade( Trading_GetLocalPlayerSteamID() );
sbTestingSelfTrade = true;
}
#endif
+40
View File
@@ -0,0 +1,40 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Interface for the client to interact with the CTradingSession
//
// $NoKeywords: $
//=============================================================================
#ifndef TF_TRADING_H
#define TF_TRADING_H
#ifdef _WIN32
#pragma once
#endif
class CEconItemView;
/**
* @return CSteamID of the client
*/
CSteamID Trading_GetLocalPlayerSteamID();
/**
* Request a trade session with the player by player index (i.e. in the same game)
* @param iPlayerIdx
*/
void Trading_RequestTrade( int iPlayerIdx );
/**
* Request a trade session with the player by CSteamID
* @param steamID
*/
void Trading_RequestTrade( const CSteamID &steamID );
/**
* Sends a gift to the player with the given steamID
* @param steamID
* @param giftItem
*/
void Trading_SendGift( const CSteamID &steamID, const CEconItemView& giftItem );
#endif // TF_TRADING_H
+165
View File
@@ -0,0 +1,165 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef ECON_UI_H
#define ECON_UI_H
#ifdef _WIN32
#pragma once
#endif
enum EconBaseUIPanels_t
{
ECONUI_BASEUI = 0,
ECONUI_BACKPACK,
ECONUI_CRAFTING,
ECONUI_ARMORY,
ECONUI_TRADING,
ECONUI_LOADOUT,
ECONUI_FIRST_PANEL = ECONUI_BASEUI,
ECONUI_LAST_PANEL = ECONUI_LOADOUT
};
class CBackpackPanel;
class CCraftingPanel;
class CItemPickupPanel;
class CItemDiscardPanel;
class CStorePanel;
struct cart_item_t;
namespace vgui
{
class Panel;
};
// Interface used to connect to the game specific implementations of the Economy UI
abstract_class IEconRootUI
{
public:
// Open the EconUI, optionally to a specific page (Backpack/Crafting/etc)
// If bCheckForInventorySpaceOnExit is set, On closing the EconUI should make sure the user doesn't
// have to throw out any items to make room in their inventory.
virtual IEconRootUI *OpenEconUI( int iDirectToPage = 0, bool bCheckForInventorySpaceOnExit = false ) = 0;
// Close the EconUI, and any associated sub panels.
virtual void CloseEconUI( void ) = 0;
// Return true if the specified EconUI sub panel is currently visible.
virtual bool IsUIPanelVisible( EconBaseUIPanels_t iPanel ) = 0;
// Some part of the EconUI might be in a state where they want to prevent the user
// from being able to close the EconUI (in the middle of a trade, for instance)
virtual void SetPreventClosure( bool bPrevent ) = 0;
// Sub panel access.
// These are panels that are parented to the root EconUI.
virtual CBackpackPanel *GetBackpackPanel( void ) = 0;
virtual CCraftingPanel *GetCraftingPanel( void ) = 0;
// Gamestats access (We should replace these with an Econ Gamestats)
virtual void Gamestats_ItemTransaction( int eventID, CEconItemView *item, const char *pszReason = NULL, int iQuality = 0 ) = 0;
virtual void Gamestats_Store( int eventID, CEconItemView* item=NULL, const char* panelName=NULL,
int classId=0, const cart_item_t* in_cartItem=NULL, int in_checkoutAttempts=0, const char* storeError=NULL, int in_totalPrice=0, int in_currencyCode=0 ) = 0;
virtual void SetExperimentValue( uint64 experimentValue ) = 0;
// Open separate economy panels (they're not parented to the root EconUI)
// This is here so that games can customize the implementation of these panels.
virtual CItemPickupPanel *OpenItemPickupPanel( void ) = 0;
virtual CItemDiscardPanel *OpenItemDiscardPanel( void ) = 0;
// Store
virtual void CreateStorePanel( void ) = 0;
virtual CStorePanel *OpenStorePanel( int iItemDef, bool bAddToCart ) = 0;
virtual CStorePanel *GetStorePanel( void ) = 0;
// When the root UI is closed, send an "EconUIClosed" message to pListener.
virtual void AddPanelCloseListener( vgui::Panel *pListener ) = 0;
// The panel at which we want back to actually close the UI - defaults to the root panel - a negative value can be passed in for class loadout panels
virtual void SetClosePanel( int iPanel ) = 0;
// Call this to set which team the class loadout should display
virtual void SetDefaultTeam( int iTeam ) = 0;
};
extern IEconRootUI *EconUI( void );
// IDs for Item related events in Gamestats tracking
enum ITEMEVENTS
{
// STORE EVENTS
IE_STORE_ENTERED,
IE_STORE_EXITED,
IE_STORE_TAB_CHANGED,
IE_STORE_ITEM_SELECTED,
IE_STORE_ITEM_PREVIEWED,
IE_STORE_ITEM_ADDED_TO_CART,
IE_STORE_ITEM_REMOVED_FROM_CART,
IE_STORE_CHECKOUT_ATTEMPT,
IE_STORE_CHECKOUT_FAILURE,
IE_STORE_CHECKOUT_SUCCESS,
IE_STORE_CHECKOUT_ITEM,
// LOADOUT EVENTS
IE_LOADOUT_ENTERED,
IE_LOADOUT_EXITED,
// TRADING EVENTS
IE_TRADING_ENTERED,
IE_TRADING_EXITED,
IE_TRADING_WENT_TO_ARMORY,
IE_TRADING_RETURNED_FROM_ARMORY,
IE_TRADING_REQUEST_SENT,
IE_TRADING_REQUEST_RECEIVED,
IE_TRADING_REQUEST_REJECTED,
IE_TRADING_REQUEST_ACCEPTED,
IE_TRADING_TRADE_NEGOTIATED,
IE_TRADING_TRADE_SUCCESS,
IE_TRADING_TRADE_FAILURE,
IE_TRADING_ITEM_GIVEN,
IE_TRADING_ITEM_RECEIVED,
IE_TRADING_ITEM_GIFTED,
// CRAFTING EVENTS
IE_CRAFTING_ENTERED,
IE_CRAFTING_EXITED,
IE_CRAFTING_WENT_TO_ARMORY,
IE_CRAFTING_RETURNED_FROM_ARMORY,
IE_CRAFTING_VIEW_BLUEPRINTS,
IE_CRAFTING_TIMEOUT,
IE_CRAFTING_FAILURE,
IE_CRAFTING_SUCCESS,
IE_CRAFTING_NO_RECIPE_MATCH,
IE_CRAFTING_ATTEMPT,
IE_CRAFTING_RECIPE_FOUND,
// ARMORY EVENTS
IE_ARMORY_ENTERED,
IE_ARMORY_EXITED,
IE_ARMORY_SELECT_ITEM,
IE_ARMORY_BROWSE_WIKI,
IE_ARMORY_CHANGE_FILTER,
// TRANSACTION EVENTS
IE_ITEM_RECEIVED,
IE_ITEM_DISCARDED,
IE_ITEM_DELETED,
IE_ITEM_USED_TOOL,
IE_ITEM_USED_CONSUMABLE,
IE_ITEM_REMOVED_ATTRIB,
IE_ITEM_CHANGED_STYLE,
// NEW STORE EVENTS
IE_STORE2_ENTERED, // This gets written *in addition* to IE_STORE_ENTERED
// THESE STORED AS INTEGERS IN THE DATABASE SO THESE ARE NEW
IE_ITEM_RESET_STRANGE_COUNTERS,
IE_ITEM_PUT_INTO_COLLECTION,
IE_COUNT,
};
#endif // ECON_UI_H
+54
View File
@@ -0,0 +1,54 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Holds the result of an AsyncCreateTextureFromRenderTarget for VGUI. Don't reuse these.
//
//=============================================================================
#ifndef ICON_RENDER_RECEIVER_H
#define ICON_RENDER_RECEIVER_H
#ifdef _WIN32
#pragma once
#endif
#include "materialsystem/itexture.h"
class CIconRenderReceiver : public IAsyncTextureOperationReceiver
{
public:
CIconRenderReceiver() : m_pTex( NULL ) { }
protected:
virtual ~CIconRenderReceiver() { SafeRelease( &m_pTex ); }
public:
virtual int AddRef() OVERRIDE
{
return ++m_nReferenceCount;
}
virtual int Release() OVERRIDE
{
int retVal = --m_nReferenceCount;
if ( retVal == 0 )
delete this;
return retVal;
}
virtual void OnAsyncCreateComplete( ITexture* pTex, void *pRtSrc ) OVERRIDE
{
SafeAssign( &m_pTex, pTex );
}
virtual void OnAsyncFindComplete( ITexture* pTex, void * ) OVERRIDE { Assert( !"Should never be called." ); }
virtual void OnAsyncMapComplete( ITexture* pTex, void* pExtraArgs, void* pMemory, int pPitch ) OVERRIDE { Assert( !"Should never be called." ); }
virtual void OnAsyncReadbackBegin( ITexture* pDst, ITexture* pSrc, void* pExtraArgs ) OVERRIDE { Assert( !"Should never be called." ); }
virtual int GetRefCount() const OVERRIDE { return m_nReferenceCount; }
ITexture* GetTexture() const { return m_pTex; }
private:
CInterlockedInt m_nReferenceCount;
ITexture* m_pTex;
};
#endif // ICON_RENDER_RECEIVER_H
@@ -0,0 +1,29 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "item_confirm_delete_dialog.h"
#include <vgui/ILocalize.h>
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CConfirmDeleteItemDialog::CConfirmDeleteItemDialog( vgui::Panel *parent, bool bMultiItem ) : BaseClass(parent)
{
m_bMultiItem = bMultiItem;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
const wchar_t *CConfirmDeleteItemDialog::GetText()
{
return m_bMultiItem ? g_pVGuiLocalize->Find("MultiDeleteItemConfirmText") : g_pVGuiLocalize->Find("DeleteItemConfirmText");
}
@@ -0,0 +1,37 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef ITEM_CONFIRM_DELETE_DIALOG_H
#define ITEM_CONFIRM_DELETE_DIALOG_H
#ifdef _WIN32
#pragma once
#endif
#include "confirm_delete_dialog.h"
#include "vgui_controls/EditablePanel.h"
#include "econ_controls.h"
#include "item_pickup_panel.h"
#include "vgui_controls/ScrollableEditablePanel.h"
#include "GameEventListener.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CConfirmDeleteItemDialog : public CConfirmDeleteDialog
{
DECLARE_CLASS_SIMPLE( CConfirmDeleteItemDialog, CConfirmDeleteDialog );
public:
CConfirmDeleteItemDialog( vgui::Panel *parent, bool bMultiItem = false );
void SetMultiItem( bool bMultiItem ) { m_bMultiItem = bMultiItem; }
virtual const wchar_t *GetText();
private:
bool m_bMultiItem;
};
#endif // ITEM_CONFIRM_DELETE_DIALOG_H
File diff suppressed because it is too large Load Diff
+519
View File
@@ -0,0 +1,519 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef ITEM_MODEL_PANEL_H
#define ITEM_MODEL_PANEL_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Panel.h>
#include <vgui_controls/Frame.h>
#include <vgui_controls/Tooltip.h>
#include "basemodel_panel.h"
#include "basemodelpanel.h"
#include "econ_controls.h"
#define ITEM_MODEL_IMAGE_CACHE_SIZE 3
#define ATTRIB_LABEL_INDENT XRES(5)
class CEconItemView;
class CItemModelPanel;
class CItemMaterialCustomizationIconPanel;
class CIconRenderReceiver;
class CEmbeddedItemModelPanel;
enum itempanel_tooltippos_t
{
IPTTP_LEFT,
IPTTP_RIGHT,
IPTTP_LEFT_CENTERED,
IPTTP_RIGHT_CENTERED,
IPTTP_ABOVE,
IPTTP_BELOW,
NUM_POSITIONS_PER_STRATEGY
};
enum itempanel_tooltip_strategies_t
{
IPTTP_LEFT_SIDE,
IPTTP_RIGHT_SIDE,
IPTTP_TOP_SIDE,
IPTTP_BOTTOM_SIDE,
NUM_IPTTP_STRATEGIES,
};
extern itempanel_tooltippos_t g_iTooltipStrategies[NUM_IPTTP_STRATEGIES][NUM_POSITIONS_PER_STRATEGY];
struct item_model_cache_t
{
item_model_cache_t()
{
Clear();
}
void Clear()
{
iItemID = INVALID_ITEM_ID;
iItemDefinitionIndex = INVALID_ITEM_DEF_INDEX;
iWidth = 0;
iHeight = 0;
m_hModelPanelLock = NULL;
}
itemid_t iItemID;
item_definition_index_t iItemDefinitionIndex;
int iWidth;
int iHeight;
vgui::DHANDLE<CEmbeddedItemModelPanel> m_hModelPanelLock;
};
class CItemMaterialCustomizationIconPanel : public vgui::Panel
{
DECLARE_CLASS_SIMPLE( CItemMaterialCustomizationIconPanel, vgui::Panel );
public:
CItemMaterialCustomizationIconPanel( vgui::Panel *pParent, const char *pName );
virtual ~CItemMaterialCustomizationIconPanel();
// Custom painting
virtual void PaintBackground( void );
void DrawQuad( int iSubtileIndex, int iSubtileCount );
int m_iPaintSplat;
// UGC file of custom texture we are using. 0 in the more common case of none.
uint64 m_hUGCId;
// Paint color.
CUtlVector<Color> m_colPaintColors;
};
//-----------------------------------------------------------------------------
// Purpose: The model panel that's embedded inside the CItemModelPanel vgui panel
//-----------------------------------------------------------------------------
class CEmbeddedItemModelPanel : public CBaseModelPanel
{
DECLARE_CLASS_SIMPLE( CEmbeddedItemModelPanel, CBaseModelPanel );
public:
CEmbeddedItemModelPanel( vgui::Panel *pParent, const char *pName );
virtual ~CEmbeddedItemModelPanel();
virtual void PerformLayout( void ) OVERRIDE;
virtual void Paint( void );
virtual void RenderingRootModel( IMatRenderContext *pRenderContext, CStudioHdr *pStudioHdr, MDLHandle_t mdlHandle, matrix3x4_t *pWorldMatrix ) OVERRIDE;
virtual IMaterial *GetOverrideMaterial( MDLHandle_t mdlHandle ) OVERRIDE;
CEconItemView* GetItem() const { return m_pItem; }
void SetItem( CEconItemView *pItem );
bool IsForcingModelUsage( void ) { return m_bForceUseModel; }
void SetForceModelUsage( bool bUseModel ) { m_bForceUseModel = bUseModel; }
bool IsImageNotLoaded( void ) const;
bool IsLoadingWeaponSkin( void ) const;
enum InventoryImageType_t
{
IMAGETYPE_SMALL,
IMAGETYPE_LARGE,
IMAGETYPE_DETAILED, // show in detailed view if present -- defaults to "large" image if not
};
InventoryImageType_t GetInventoryImageType() const { return static_cast<InventoryImageType_t>( m_iInventoryImageType ); }
void SetInventoryImageType( InventoryImageType_t eNewImageType ) { m_iInventoryImageType = (int)eNewImageType; }
void LoadInventoryImage();
void SetGreyedOut( bool bGreyedOut ) { m_bGreyedOut = bGreyedOut; }
void SetModelHidden( bool bModelHidden ) { m_bModelIsHidden = bModelHidden; }
ITexture *GetCachedGeneratedIcon();
bool m_bOfflineIconGeneration;
private:
bool UseRenderTargetAsIcon() const { return m_bUseRenderTargetAsIcon || m_bUseItemRenderTarget; }
CEconItemView *m_pItem; // For directly specifying the item associated with this panel.
int m_iTextureID;
CUtlMap<int, int> m_iOverlayTextureIDs;
const char* m_pszToolTargetItemImage;
int m_iToolTargetItemTextureID;
Vector m_vecToolTargetItemImageOffset;
bool m_bImageNotLoaded;
bool m_bGreyedOut;
bool m_bModelIsHidden;
bool m_bUseRenderTargetAsIcon; // same as m_bUseItemRenderTarget but set by attribute instead of res file
void CleanUpCachedWeaponIcon();
bool m_bWeaponAllowInspect;
int m_iCachedTextureID;
CIconRenderReceiver *m_pCachedWeaponIcon;
IMaterial *m_pCachedWeaponMaterial;
MDLData_t m_ItemModel;
int m_iPedestalAttachment;
void UpdateCameraForIcon();
int m_iCameraAttachment;
bool RenderStatTrack( CStudioHdr *pStudioHdr, matrix3x4_t *pWorldMatrix );
MDLData_t m_StatTrackModel;
bool RenderAttachedModels( CStudioHdr *pStudioHdr, matrix3x4_t *pWorldMatrix );
void LoadAttachedModel( attachedmodel_t *pModel );
CUtlVector< MDLData_t > m_AttachedModels;
float m_flStatTrackScale;
CPanelAnimationVar( bool, m_bForceUseModel, "force_use_model", "0" );
CPanelAnimationVar( bool, m_bUseItemRenderTarget, "use_item_rendertarget", "0" );
CPanelAnimationVar( int, m_iInventoryImageType, "inventory_image_type", "0" );
CPanelAnimationVar( bool, m_bForceSquareImage, "force_square_image", "0" );
CPanelAnimationVar( float, m_flModelRotateYawSpeed, "model_rotate_yaw_speed", "0" );
CPanelAnimationVar( bool, m_bUsePedestal, "use_pedestal", "0" );
bool UpdateParticle(
IMatRenderContext *pRenderContext,
CStudioHdr *pStudioHdr,
MDLHandle_t mdlHandle,
matrix3x4_t *pWorldMatrix
);
particle_data_t *m_pItemParticle;
#ifdef STAGING_ONLY
double m_flStartUpdateTime;
#endif // STAGING_ONLY
};
IMaterial* GetMaterialForImage( CEmbeddedItemModelPanel::InventoryImageType_t eImageType, const char* pszBaseName );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CItemModelPanel : public vgui::EditablePanel
{
DECLARE_CLASS_SIMPLE( CItemModelPanel, vgui::EditablePanel );
public:
CItemModelPanel( vgui::Panel *parent, const char *name );
virtual ~CItemModelPanel( void );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme ) OVERRIDE;
virtual void ApplySettings( KeyValues *inResourceData ) OVERRIDE;
virtual void PerformLayout( void ) OVERRIDE;
virtual void PaintTraverse( bool forceRepaint, bool allowForce ) OVERRIDE;
virtual void OnSizeChanged( int newWide, int newTall );
void ResizeLabels( void );
virtual void SetItem( const CEconItemView *pItem );
void SetEconItem( CEconItem* pItem );
bool HasItem( void );
CEconItemView *GetItem( void ) { return ( m_ItemData.IsValid() ? &m_ItemData : NULL ); }
bool ModelIsHidden( void ) const { return m_bHideModel; }
void SetModelIsHidden( bool bHideModel );
virtual void OnTick() OVERRIDE;
void SetNeedsToLoad();
bool LoadData();
void LoadDataCompleted();
CExLabel *GetNameLabel( void ) { return m_pItemNameLabel; }
// Functionality to allow custom blobs of text to be displayed
void SetNoItemText( const char *pszText );
void SetNoItemText( const wchar_t *pwszTitleOverride, const wchar_t *pwszAttribs = NULL, int iNegAttribsBegin = 0 );
// Button functionality
void SetActAsButton( bool bClickable, bool bMouseOver );
virtual void NavigateTo();
virtual void NavigateFrom();
virtual void OnCursorEntered();
virtual void OnCursorExited();
virtual void OnMousePressed(vgui::MouseCode code);
virtual void OnMouseDoublePressed(vgui::MouseCode code);
virtual void OnMouseReleased(vgui::MouseCode code);
virtual void OnKeyCodePressed( vgui::KeyCode code );
MESSAGE_FUNC_INT_INT( OnCursorMoved, "OnCursorMoved", x, y );
void SetSelected( bool bSelected ) { m_bSelected = bSelected; }
bool IsSelected( void ) { return m_bSelected; }
void SetAttribOnly( bool bAttribs ) { m_bAttribOnly = bAttribs; }
void SetTextYPos( int iPos ) { m_iTextYPos = iPos; }
bool IsEquipped( void );
void SetShowEquipped( bool bShow ) { m_bShowEquipped = bShow; UpdateEquippedLabel(); }
void SetForceShowEquipped( bool bForce ) { m_bForceShowEquipped = bForce; UpdateEquippedLabel(); }
void SetGreyedOut( const char *pszGreyedOutReason ); // pass in NULL for "not greyed out"
void SetShowGreyedOutTooltip( bool bShow ) { m_bShowGreyedOutTooltip = bShow; }
bool IsGreyedOut( void ) const { return m_pszGreyedOutReason != NULL; }
const char *GetGreyedOutReason( void ) const { return m_pszGreyedOutReason; }
bool ShouldShowTooltip( void ) { return (!IsGreyedOut() || m_bShowGreyedOutTooltip); }
void SetShowQuantity( bool bShow ) { m_bShowQuantity = bShow; }
void UpdatePanels( void );
void SendPanelEnterExits( bool bSend ) { m_bShouldSendPanelEnterExits = bSend; }
void SetShouldShowOthersGiftWrappedItems( bool bShow ) { m_bShowOthersGiftWrappedItems = bShow; }
void Dragged( bool bDragging );
void HideContainedItemPanel();
void ShowContainedItemPanel( const CEconItemView *pItem );
bool IsContainedItem() { return m_bContainedItem; }
void SetContainedItem( bool bVal ) { m_bContainedItem = bVal; }
void SetSkin( int iSkin );
void SetItemStyle( style_index_t unStyle ) { m_ItemData.SetItemStyleOverride( unStyle ); }
void SetNameOnly( bool bNameOnly ) { m_bNameOnly = bNameOnly; }
void SetSpecialAttributesOnly( bool bSpecialOnly ) { m_bSpecialAttributesOnly = bSpecialOnly; }
CEmbeddedItemModelPanel::InventoryImageType_t GetInventoryImageType() /*const*/ { return m_pModelPanel->GetInventoryImageType(); }
void SetInventoryImageType( CEmbeddedItemModelPanel::InventoryImageType_t eNewImageType ) { m_pModelPanel->SetInventoryImageType( eNewImageType ); }
void UpdateDescription();
void DirtyDescription();
virtual void OnCommand( const char *command ) OVERRIDE;
void MakeFakeButton() { m_bFakeButton = true; }
private:
void UpdateEquippedLabel( void );
void CleanupNoItemWChars( void );
bool UpdateSeriesLabel();
bool UpdateMatchesLabel();
bool UpdateQuantityLabel();
bool CheckRecipeMatches();
int GetAttribWide( int iMaxWide ) { return (m_iTextWide ? m_iTextWide : (iMaxWide - (ATTRIB_LABEL_INDENT * 2))); }
void LoadResFileForCurrentItem( bool bForceLoad );
void HideAllModifierIcons();
enum eLoadingType_t
{
LOADING_ICONS = 0,
LOADING_DESCRIPTIONS,
LOADING_RECIPE_MATCHES,
NUM_LOADING_TYPES
};
enum eLoadedCollectionType_t
{
LOADED_COLLECTION_NONE,
LOADED_COLLECTION_WEAPON,
LOADED_COLLECTION_COSMETIC
};
vgui::DHANDLE<CEmbeddedItemModelPanel> m_pModelPanel;
CExLabel *m_pItemNameLabel;
vgui::Label *m_pItemAttribLabel;
CExLabel *m_pItemCollectionNameLabel;
vgui::Label *m_pItemCollectionListLabel;
vgui::EditablePanel *m_pItemCollectionHighlight;
eLoadedCollectionType_t m_nCollectionItemLoaded;
vgui::Label *m_pItemEquippedLabel;
vgui::Label *m_pItemQuantityLabel;
vgui::ImagePanel *m_pVisionRestrictionImage;
vgui::ImagePanel *m_pIsStrangeImage;
vgui::ImagePanel *m_pIsUnusualImage;
vgui::ImagePanel *m_pIsLoanerImage;
vgui::Label *m_pSeriesLabel;
vgui::Label *m_pMatchesLabel;
vgui::EditablePanel *m_pMainContentContainer;
vgui::ImagePanel *m_pLoadingSpinner;
CEconItemView m_ItemData;
vgui::HFont m_pFontNameSmallest;
vgui::HFont m_pFontNameSmall;
vgui::HFont m_pFontNameLarge;
vgui::HFont m_pFontNameLarger;
vgui::HFont m_pFontAttribSmallest;
vgui::HFont m_pFontAttribSmall;
vgui::HFont m_pFontAttribLarge;
vgui::HFont m_pFontAttribLarger;
const char *m_pszNoItemText;
const wchar_t *m_pwcNoItemText;
const wchar_t *m_pwcNoItemAttrib;
Color m_NoItemTextColor;
Color m_OrgItemTextColor;
bool m_bClickable;
bool m_bMouseOver;
bool m_bSelected;
bool m_bShowEquipped;
bool m_bForceShowEquipped;
const char *m_pszGreyedOutReason;
bool m_bShowGreyedOutTooltip;
bool m_bShouldSendPanelEnterExits;
bool m_bShowQuantity;
bool m_bContainedItem;
bool m_bShowOthersGiftWrappedItems;
bool m_bDescriptionDirty;
int m_nRecipeMatchingIndex;
static float sm_flLoadingTimeThisFrame;
static int sm_nCurrentDecriptionUpdateFrame;
static int sai_NumLoadingRequests[NUM_LOADING_TYPES];
static eLoadingType_t se_CurrentLoadingTask;
CUtlMap< attrib_definition_index_t, int > m_mapMatchingAttributes;
CItemMaterialCustomizationIconPanel *m_pPaintIcon;
vgui::ScalableImagePanel *m_pTF2Icon;
CItemModelPanel *m_pContainedItemPanel;
CPanelAnimationVar( bool, m_bSpecialAttributesOnly, "special_attributes_only", "0" );
CPanelAnimationVarAliasType( int, m_iModelXPos, "model_xpos", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iModelYPos, "model_ypos", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iModelWide, "model_wide", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iModelTall, "model_tall", "0", "proportional_int" );
CPanelAnimationVar( bool, m_bModelCenterX, "model_center_x", "0" );
CPanelAnimationVar( bool, m_bModelCenterY, "model_center_y", "0" );
CPanelAnimationVarAliasType( int, m_iTF2IconOffsetX, "tf2_icon_offset_x", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iTF2IconOffsetY, "tf2_icon_offset_y", "0", "proportional_int" );
CPanelAnimationVar( bool, m_bNoItemFullPanel, "noitem_use_fullpanel", "0" );
CPanelAnimationVar( bool, m_bTextCenter, "text_center", "0" );
CPanelAnimationVar( bool, m_bTextCenterX, "text_center_x", "0" );
CPanelAnimationVar( bool, m_bUseItemSounds, "use_item_sounds", "0" );
CPanelAnimationVar( bool, m_bNameOnly, "name_only", "0" );
CPanelAnimationVar( bool, m_bAttribOnly, "attrib_only", "0" );
CPanelAnimationVar( bool, m_bModelOnly, "model_only", "0" );
CPanelAnimationVar( bool, m_bHideModelDefault, "model_hide", "0" );
bool m_bHideModel;
CPanelAnimationVar( bool, m_bHidePaintIcon, "paint_icon_hide", "0" );
CPanelAnimationVar( bool, m_bResizeToText, "resize_to_text", "0" );
CPanelAnimationVar( int, m_iNameLabelAlignment, "name_label_alignment", "4" /*a_center*/ );
CPanelAnimationVarAliasType( int, m_iTextXPos, "text_xpos", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iTextYPos, "text_ypos", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iTextWide, "text_wide", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iTextYOffset, "text_yoffset", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iHPadding, "padding_height", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iMaxTextHeight, "max_text_height", "0", "proportional_int" );
CPanelAnimationVar( int, m_iForceTextSize, "text_forcesize", "0" );
CPanelAnimationVarAliasType( int, m_iEquippedInsetX, "inset_eq_x", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iEquippedInsetY, "inset_eq_y", "0", "proportional_int" );
CPanelAnimationVar( bool, m_bStandardTextColor, "standard_text_color", "0" );
CPanelAnimationVar( bool, m_bIsMouseOverPanel, "is_mouseover", "0" );
CPanelAnimationVarAliasType( int, m_iBaseWide, "wide", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iBaseTall, "tall", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iCollectionListXPos, "collection_list_xpos", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iTextXPosCollection, "text_xpos_collection", "0", "proportional_int" );
CPanelAnimationVar( bool, m_bHideCollectionPanel, "hide_collection_panel", "0" );
CPanelAnimationVar( bool, m_bHideModifierIcons, "hide_modifier_icons", "0" );
bool m_bFakeButton;
};
//-----------------------------------------------------------------------------
// Purpose: Item model panel tooltip. Calls setvisible on the controlled panel
// and positions it below/above the current panel.
//-----------------------------------------------------------------------------
class CItemModelPanelToolTip : public vgui::BaseTooltip
{
DECLARE_CLASS_SIMPLE( CItemModelPanelToolTip, vgui::BaseTooltip );
public:
CItemModelPanelToolTip(vgui::Panel *parent, const char *text = NULL);
void SetText(const char *text) { return; }
const char *GetText() { return NULL; }
virtual void PerformLayout();
virtual void ShowTooltip( vgui::Panel *currentPanel );
virtual void HideTooltip();
void SetupPanels( vgui::Panel *pParentPanel, CItemModelPanel *pMouseOverItemPanel ) { m_pParentPanel = pParentPanel; m_pMouseOverItemPanel = pMouseOverItemPanel; }
void SetPositioningStrategy( itempanel_tooltip_strategies_t iStrat ) { m_iPositioningStrategy = iStrat; }
private:
void GetPosition( itempanel_tooltippos_t iTooltipPosition, CItemModelPanel *pItemPanel, int iItemX, int iItemY, int *iXPos, int *iYPos );
bool ValidatePosition( CItemModelPanel *pItemPanel, int iItemX, int iItemY, int *iXPos, int *iYPos );
private:
CItemModelPanel *m_pMouseOverItemPanel; // This is the tooltip panel we make visible. Must be a CItemModelPanel.
vgui::Panel *m_pParentPanel; // This is the panel that we send item entered/exited messages to
vgui::DHANDLE<CItemModelPanel> m_hCurrentPanel;
itempanel_tooltip_strategies_t m_iPositioningStrategy;
bool m_bHorizontalPreferLeft;
};
//-----------------------------------------------------------------------------
// Purpose: Generate a list of items that can be equipped for a given set of
// restrictions (class/slot/region/etc.) and other data (count of dupes, etc.).
// Used for crafting, loadout selection, quickswitch, and elsewhere.
//-----------------------------------------------------------------------------
class CEquippableItemsForSlotGenerator
{
public:
// Flags that control how the data is generated.
enum
{
kSlotGenerator_None = 0x00,
kSlotGenerator_ShowDuplicates = 0x01,
kSlotGenerator_EquippedSpecialHandling = 0x02,
};
enum EItemDisplayType
{
kSlotDisplay_Normal,
kSlotDisplay_Disabled_EquipRegionConflict,
kSlotDisplay_Invalid, // just used to tag unitialized instances
};
struct CEquippableResult
{
CEquippableResult()
: m_pEconItemView( NULL )
, m_eDisplayType( kSlotDisplay_Invalid )
{
//
}
CEquippableResult( CEconItemView *pEconItemView, EItemDisplayType eDisplayType = kSlotDisplay_Normal )
: m_pEconItemView( pEconItemView )
, m_eDisplayType( eDisplayType )
{
//
}
// This only exists to support Find() and ignores display state.
bool operator==( const CEquippableResult& other ) const
{
return m_pEconItemView == other.m_pEconItemView;
}
CEconItemView *m_pEconItemView;
EItemDisplayType m_eDisplayType;
};
typedef CUtlMap<struct item_stack_type_t, int> DuplicateCountMap_t;
typedef CUtlVector<CEquippableResult> EquippableResultsVec_t;
CEquippableItemsForSlotGenerator( int iClass, int iSlot, equip_region_mask_t unUsedEquipRegionMask, unsigned int unFlags );
const EquippableResultsVec_t& GetDisplayItems() const { return m_vecDisplayItems; }
CEconItemView *GetEquippedItem() const { return m_pEquippedItemView; }
const DuplicateCountMap_t& GetDuplicateCountMap() const { return m_DuplicateCountsMap; }
private:
EquippableResultsVec_t m_vecDisplayItems;
DuplicateCountMap_t m_DuplicateCountsMap;
CEconItemView *m_pEquippedItemView; // if kSlotGenerator_EquippedSpecialHandling is passed in, this will store our equipped item; otherwise NULL
};
#endif // ITEM_MODEL_PANEL_H
+889
View File
@@ -0,0 +1,889 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "vgui/IInput.h"
#include <vgui/IVGui.h>
#include <vgui/IScheme.h>
#include <vgui/ILocalize.h>
#include "vgui_controls/TextImage.h"
#include "ienginevgui.h"
#include "iclientmode.h"
#include "baseviewport.h"
#include "item_pickup_panel.h"
#include "econ_ui.h"
#include "econ_item_inventory.h"
#include "econ_item_constants.h"
#include "item_confirm_delete_dialog.h"
#include "backpack_panel.h"
#ifdef TF_CLIENT_DLL
#include "c_tf_freeaccount.h"
#include "clientmode_tf.h"
#include "quest_log_panel.h"
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CItemPickupPanel::CItemPickupPanel( Panel *parent ) : Frame( parent, "item_pickup" )
{
vgui::VPANEL gameuiPanel = enginevgui->GetPanel( PANEL_GAMEUIDLL );
SetParent( gameuiPanel );
// We don't want the gameui to delete us, or things get messy
SetAutoDelete( false );
SetMoveable( false );
SetSizeable( false );
vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
SetScheme(scheme);
SetProportional( true );
m_pNextButton = new vgui::Button( this, "NextButton", "#Next" );
m_pPrevButton = new vgui::Button( this, "PrevButton", "#Prev" );
m_pDiscardButton = NULL;
m_pDiscardedLabel = NULL;
m_pOpenLoadoutButton = NULL;
m_pConfirmDeleteDialog = NULL;
m_pModelPanelsKV = NULL;
m_bRandomizePickupMethods = false;
m_pItemFoundMethod = NULL;
m_pCloseButton = NULL;
for ( int i = 0; i < ITEMPICKUP_NUM_MODELPANELS; i++ )
{
m_aModelPanels[i] = new CItemModelPanel( this, VarArgs("modelpanel%d", i) );
}
ListenForGameEvent( "gameui_hidden" );
vgui::EditablePanel *pToolTipPanel = new vgui::EditablePanel( this, "DiscardButtonTooltip" );
m_pToolTip = new CSimplePanelToolTip( this );
m_pToolTip->SetControlledPanel( pToolTipPanel );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CItemPickupPanel::~CItemPickupPanel()
{
if ( m_pModelPanelsKV )
{
m_pModelPanelsKV->deleteThis();
m_pModelPanelsKV = NULL;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemPickupPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
LoadControlSettings( "Resource/UI/econ/ItemPickupPanel.res" );
m_pItemsFoundLabel = dynamic_cast<vgui::Label*>(FindChildByName( "ItemsFoundLabel" ));
m_pDiscardedLabel = dynamic_cast<vgui::Label*>( FindChildByName("DiscardedLabel") );
m_pItemFoundMethod = dynamic_cast<vgui::Label*>(FindChildByName( "SelectedItemFoundMethodLabel" ));
for ( int i = 0; i < ITEMPICKUP_NUM_MODELPANELS; i++ )
{
m_aModelPanels[i]->SetPaintBackgroundType( 2 );
}
m_pDiscardButton = dynamic_cast<CExImageButton*>( FindChildByName("DiscardButton") );
if ( m_pDiscardButton )
{
m_pDiscardButton->SetTooltip( m_pToolTip, "" );
}
m_pOpenLoadoutButton = dynamic_cast<vgui::Button*>( FindChildByName("OpenLoadoutButton") );
m_pCloseButton = dynamic_cast<CExButton*>( FindChildByName("CloseButton") );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemPickupPanel::ApplySettings( KeyValues *inResourceData )
{
BaseClass::ApplySettings( inResourceData );
KeyValues *pModelKV = inResourceData->FindKey( "modelpanelskv" );
if ( pModelKV )
{
if ( m_pModelPanelsKV )
{
m_pModelPanelsKV->deleteThis();
}
m_pModelPanelsKV = new KeyValues("modelpanelkv");
pModelKV->CopySubkeys( m_pModelPanelsKV );
for ( int i = 0; i < ITEMPICKUP_NUM_MODELPANELS; i++ )
{
m_aModelPanels[i]->ApplySettings( m_pModelPanelsKV );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemPickupPanel::PerformLayout( void )
{
if ( GetVParent() )
{
int w,h;
vgui::ipanel()->GetSize( GetVParent(), w, h );
SetBounds(0,0,w,h);
}
BaseClass::PerformLayout();
// Now lay out our model panels
for ( int i = 0; i < ITEMPICKUP_NUM_MODELPANELS; i++ )
{
int iPos = (i - ITEMPICKUP_MODELPANEL_CENTER);
int iXPos = (GetWide() * 0.5) + (iPos * m_iModelPanelSpacing) + (iPos * m_iModelPanelW) - (m_iModelPanelW * 0.5);
m_aModelPanels[i]->SetBounds( iXPos, m_iModelPanelY, m_iModelPanelW, m_iModelPanelH );
m_aModelPanels[i]->SetVisible( m_aModelPanels[i]->HasItem() );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemPickupPanel::ShowPanel(bool bShow)
{
if ( bShow )
{
// Start with the first item centered, and the rest off to the right.
m_iSelectedItem = 0;
UpdateModelPanels();
MoveToFront(); // Any open dialogs from the main menu (options, servers, etc.) showing up sometimes - this should fix.
}
else
{
for ( int i = 0; i < m_aItems.Count(); i++ )
{
if ( !m_aItems[i].bDiscarded )
{
// if not a real item, ignore
if ( m_aItems[i].pItem.GetSOCData() == NULL )
{
continue;
}
// ignore items that are purchased or are store promotional items
CEconItem *pEconItem = m_aItems[i].pItem.GetSOCData();
switch ( pEconItem->GetOrigin() )
{
case kEconItemOrigin_PreviewItem:
case kEconItemOrigin_Purchased:
case kEconItemOrigin_StorePromotion:
continue;
}
}
}
if ( m_pConfirmDeleteDialog )
{
m_pConfirmDeleteDialog->MarkForDeletion();
m_pConfirmDeleteDialog = NULL;
}
m_aItems.Purge();
}
SetMouseInputEnabled( bShow );
SetVisible( bShow );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemPickupPanel::FireGameEvent( IGameEvent *event )
{
if ( !IsVisible() )
return;
const char * type = event->GetName();
if ( Q_strcmp(type, "gameui_hidden") == 0 )
{
ShowPanel( false );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemPickupPanel::OnCommand( const char *command )
{
if ( !Q_stricmp( command, "vguicancel" ) )
{
AcknowledgeItems();
ShowPanel( false );
}
else if ( !Q_stricmp( command, "changeloadout" ) )
{
AcknowledgeItems();
ShowPanel( false );
EconUI()->OpenEconUI( ECONUI_LOADOUT, true );
}
else if ( !Q_stricmp( command, "nextitem" ) )
{
m_iSelectedItem = clamp( m_iSelectedItem+1, 0, m_aItems.Count()-1 );
UpdateModelPanels();
}
else if ( !Q_stricmp( command, "previtem" ) )
{
m_iSelectedItem = clamp( m_iSelectedItem-1, 0, m_aItems.Count()-1 );
UpdateModelPanels();
}
else if ( !Q_stricmp( command, "discarditem" ) )
{
// Bring up confirm dialog
CConfirmDeleteItemDialog *pConfirm = vgui::SETUP_PANEL( new CConfirmDeleteItemDialog( this ) );
if ( pConfirm )
{
pConfirm->Show();
m_pConfirmDeleteDialog = pConfirm;
}
}
else
{
engine->ClientCmd( const_cast<char *>( command ) );
}
BaseClass::OnCommand( command );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemPickupPanel::UpdateModelPanels( void )
{
for ( int i = 0; i < ITEMPICKUP_NUM_MODELPANELS; i++ )
{
int iPos = (i - ITEMPICKUP_MODELPANEL_CENTER);
int iItem = m_iSelectedItem + iPos;
if ( iItem < 0 || iItem >= m_aItems.Count() )
{
m_aModelPanels[i]->SetItem( NULL );
m_aModelPanels[i]->SetVisible( false );
continue;
}
m_aModelPanels[i]->SetItem( &m_aItems[iItem].pItem );
m_aModelPanels[i]->SetVisible( true );
}
// Enable next & prev buttons if there are other items to the sides
bool bCanScrollRight = (m_iSelectedItem + 1) < m_aItems.Count();
m_pNextButton->SetVisible( bCanScrollRight );
m_pNextButton->SetEnabled( bCanScrollRight );
bool bCanScrollLeft = ((m_iSelectedItem - 1) >= 0) && m_aItems.Count();
m_pPrevButton->SetVisible( bCanScrollLeft );
m_pPrevButton->SetEnabled( bCanScrollLeft );
bool bDiscarded = false;
if ( m_iSelectedItem >= 0 && m_iSelectedItem < m_aItems.Count() )
{
bDiscarded = m_aItems[m_iSelectedItem].bDiscarded;
}
bool bAllowDiscard = true;
int iFoundMethod = 0;
if ( m_bRandomizePickupMethods )
{
iFoundMethod = RandomInt( 0, ARRAYSIZE(g_pszItemPickupMethodStrings)-1 );
}
else if ( m_iSelectedItem >= 0 && m_iSelectedItem < m_aItems.Count() )
{
iFoundMethod = GetUnacknowledgedReason( m_aItems[m_iSelectedItem].pItem.GetInventoryPosition() );
bAllowDiscard = ( iFoundMethod <= UNACK_ITEM_DROPPED );
iFoundMethod--;
if ( iFoundMethod < 0 || iFoundMethod >= ARRAYSIZE(g_pszItemPickupMethodStrings) )
{
iFoundMethod = 0;
}
}
// Hide the discard button if it's not a random find
m_pDiscardButton->SetVisible( !bDiscarded && bAllowDiscard );
m_pOpenLoadoutButton->SetVisible( !bDiscarded );
m_pDiscardedLabel->SetVisible( bDiscarded );
if ( m_pItemFoundMethod )
{
enum
{
COLOR_NORMAL = 1,
COLOR_HIGHLIGHTED = 2,
};
m_pItemFoundMethod->GetTextImage()->ClearColorChangeStream();
wchar_t wszTmp[1024];
wchar_t *pLocText = g_pVGuiLocalize->Find( g_pszItemPickupMethodStrings[iFoundMethod] );
if ( pLocText )
{
// Loop through and replace the color changes
Color baseColor = m_pItemFoundMethod->GetFgColor();
wchar_t *wpszChar = pLocText;
int iOutPos = 0;
while ( *wpszChar )
{
if ( *wpszChar == COLOR_NORMAL )
{
m_pItemFoundMethod->GetTextImage()->AddColorChange( baseColor, iOutPos );
}
else if ( *wpszChar == COLOR_HIGHLIGHTED )
{
m_pItemFoundMethod->GetTextImage()->AddColorChange( Color(200,80,60,255), iOutPos );
}
else
{
wszTmp[iOutPos] = *wpszChar;
iOutPos++;
}
wpszChar++;
if ( iOutPos >= (ARRAYSIZE(wszTmp) - 1) )
{
wszTmp[iOutPos] = L'\0';
break;
}
}
if ( iOutPos < (ARRAYSIZE(wszTmp) - 1) )
{
wszTmp[iOutPos] = L'\0';
}
m_pItemFoundMethod->SetText( wszTmp );
}
}
if ( m_pItemsFoundLabel )
{
if ( m_aItems.Count() > 1 )
{
m_pItemsFoundLabel->SetText( "#NewItemsAcquired" );
SetDialogVariable( "numitems", m_aItems.Count() );
}
else
{
m_pItemsFoundLabel->SetText( "#NewItemAcquired" );
}
}
SetDialogVariable( "selecteditem", m_iSelectedItem+1 );
// Update the loadout button as appropriate
if ( m_iSelectedItem >= 0 && m_iSelectedItem < m_aItems.Count() )
{
if ( m_aItems[m_iSelectedItem].pItem.IsValid() && !bDiscarded )
{
SetDialogVariable("loadouttext", g_pVGuiLocalize->Find( "#OpenGeneralLoadout" ) );
}
}
if ( m_pCloseButton )
{
const char *pszCloseString = (m_bReturnToGame && engine->IsInGame()) ? "#CloseItemPanel" : "#GameUI_OK";
m_pCloseButton->SetText( g_pVGuiLocalize->Find( pszCloseString ) );
}
m_pCloseButton->RequestFocus();
}
//-----------------------------------------------------------------------------
void CItemPickupPanel::AcknowledgeItems( void )
{
// On command, AckKnowledge all these items
for ( int i = 0; i < m_aItems.Count(); i++ )
{
InventoryManager()->AcknowledgeItem( &m_aItems[i].pItem, false );
}
InventoryManager()->SaveAckFile();
// If we were crafting, and the craft panel is up, we return to that instead.
if ( EconUI()->IsUIPanelVisible( ECONUI_CRAFTING ) )
return;
// Check to make sure the player has room for all his items. If not, bring up the discard panel. Otherwise, go away.
if ( !InventoryManager()->CheckForRoomAndForceDiscard( ) )
{
#ifdef TF_CLIENT_DLL
// If the quest log is up, we just go back to that
if ( GetQuestLog() && GetQuestLog()->IsVisible() )
return;
#endif
// If we're connected to a game server, we also close the game UI.
if ( m_bReturnToGame && engine->IsInGame() )
{
engine->ClientCmd_Unrestricted( "gameui_hide" );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Handles the escape key
//-----------------------------------------------------------------------------
void CItemPickupPanel::OnKeyCodeTyped( vgui::KeyCode code )
{
if( code == KEY_ESCAPE )
{
OnCommand( "vguicancel" );
}
else
{
BaseClass::OnKeyCodeTyped( code );
}
}
//-----------------------------------------------------------------------------
// Purpose: Handles button press code for controllers and enter
//-----------------------------------------------------------------------------
void CItemPickupPanel::OnKeyCodePressed( vgui::KeyCode code )
{
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
if( code == KEY_ENTER || nButtonCode == KEY_XBUTTON_A || nButtonCode == KEY_XBUTTON_B || nButtonCode == STEAMCONTROLLER_A || nButtonCode == STEAMCONTROLLER_B )
{
OnCommand( "vguicancel" );
}
else if( code == KEY_HOME || nButtonCode == KEY_XBUTTON_Y || nButtonCode == STEAMCONTROLLER_Y )
{
OnCommand( "changeloadout" );
}
else if ( nButtonCode == KEY_XBUTTON_RIGHT ||
nButtonCode == KEY_XSTICK1_RIGHT ||
nButtonCode == KEY_XSTICK2_RIGHT ||
nButtonCode == KEY_RIGHT )
{
OnCommand( "nextitem" );
}
else if ( nButtonCode == KEY_XBUTTON_LEFT ||
nButtonCode == KEY_XSTICK1_LEFT ||
nButtonCode == KEY_XSTICK2_LEFT ||
nButtonCode == KEY_LEFT )
{
OnCommand( "previtem" );
}
else
{
BaseClass::OnKeyCodePressed( code );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemPickupPanel::AddItem( CEconItemView *pItem )
{
// Guard against duplicates
FOR_EACH_VEC( m_aItems, i )
{
if ( m_aItems[i].pItem.GetItemID() == pItem->GetItemID() )
return;
}
int iIdx = m_aItems.AddToTail();
m_aItems[iIdx].pItem = *pItem;
m_aItems[iIdx].bDiscarded = false;
if ( IsVisible() )
{
UpdateModelPanels();
InvalidateLayout();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemPickupPanel::OnConfirmDelete( KeyValues *data )
{
m_pConfirmDeleteDialog = NULL;
m_pCloseButton->RequestFocus();
int iConfirmed = data->GetInt( "confirmed", 0 );
if ( !iConfirmed )
return;
if ( m_iSelectedItem >= 0 && m_iSelectedItem < m_aItems.Count() )
{
if ( m_aItems[m_iSelectedItem].pItem.IsValid() )
{
CPlayerInventory *pInventory = InventoryManager()->GetLocalInventory();
if ( pInventory )
{
EconUI()->Gamestats_ItemTransaction( IE_ITEM_DISCARDED, &m_aItems[m_iSelectedItem].pItem );
InventoryManager()->DropItem( m_aItems[m_iSelectedItem].pItem.GetItemID() );
InvalidateLayout();
m_aItems[m_iSelectedItem].bDiscarded = true;
m_pDiscardButton->SetVisible( false );
m_pOpenLoadoutButton->SetVisible( false );
m_pDiscardedLabel->SetVisible( true );
// If we've discarded all our items, we exit immediately
bool bFoundUndiscarded = false;
for ( int i = 0; i < m_aItems.Count(); i++ )
{
if ( !m_aItems[i].bDiscarded )
{
bFoundUndiscarded = true;
break;
}
}
if ( !bFoundUndiscarded )
{
OnCommand( "vguicancel" );
}
}
}
}
}
static vgui::DHANDLE<CItemPickupPanel> g_ItemPickupPanel;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CItemPickupPanel *OpenItemPickupPanel( void )
{
if (!g_ItemPickupPanel.Get())
{
g_ItemPickupPanel = vgui::SETUP_PANEL( new CItemPickupPanel( NULL ) );
g_ItemPickupPanel->InvalidateLayout( false, true );
}
engine->ClientCmd_Unrestricted( "gameui_activate" );
g_ItemPickupPanel->ShowPanel( true );
return g_ItemPickupPanel;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CItemPickupPanel *GetItemPickupPanel( void )
{
return g_ItemPickupPanel.Get();
}
//=======================================================================================================================================================
// ITEM DISCARD PANEL
//=======================================================================================================================================================
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CItemDiscardPanel::CItemDiscardPanel( Panel *parent ) : Frame( parent, "item_discard" )
{
vgui::VPANEL gameuiPanel = enginevgui->GetPanel( PANEL_GAMEUIDLL );
SetParent( gameuiPanel );
// We don't want the gameui to delete us, or things get messy
SetAutoDelete( false );
SetMoveable( false );
SetSizeable( false );
vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
SetScheme(scheme);
SetProportional( true );
m_pModelPanel = new CItemModelPanel( this, "modelpanel" );
m_pBackpackPanel = new CBackpackPanel( this, "backpack_panel" );
m_pConfirmDeleteDialog = NULL;
m_bDiscardedNewItem = false;
m_bMadeRoom = false;
m_pDiscardedLabelCarat = NULL;
m_pDiscardedLabel = NULL;
m_pDiscardButton = NULL;
m_pCloseButton = NULL;
m_pItemMouseOverPanel = new CItemModelPanel( this, "ItemMouseOverItemPanel" );
m_pItemToolTip = new CSimplePanelToolTip( this );
m_pItemToolTip->SetControlledPanel( m_pItemMouseOverPanel );
m_pModelPanel->SetTooltip( m_pItemToolTip, "" );
m_pModelPanel->SetActAsButton( false, true );
ListenForGameEvent( "gameui_hidden" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemDiscardPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
m_pItemMouseOverPanel->InvalidateLayout( true, true );
m_pModelPanel->InvalidateLayout( true, true );
LoadControlSettings( "Resource/UI/econ/ItemDiscardPanel.res" );
// Highlight the X on the discard button
m_pDiscardButton = dynamic_cast<CExButton*>( FindChildByName("DiscardButton") );
if ( m_pDiscardButton )
{
SetXToRed( m_pDiscardButton );
}
m_pCloseButton = dynamic_cast<CExButton*>( FindChildByName("CloseButton") );
m_pDiscardedLabel = dynamic_cast<vgui::Label*>( FindChildByName("DiscardedLabel") );
m_pDiscardedLabelCarat = dynamic_cast<vgui::Label*>( FindChildByName("DiscardedCaratLabel") );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemDiscardPanel::PerformLayout( void )
{
if ( GetVParent() )
{
int w,h;
vgui::ipanel()->GetSize( GetVParent(), w, h );
SetBounds(0,0,w,h);
}
BaseClass::PerformLayout();
m_pDiscardedLabelCarat->SetVisible( m_bDiscardedNewItem );
m_pDiscardedLabel->SetVisible( m_bDiscardedNewItem );
m_pDiscardButton->SetVisible( !m_bDiscardedNewItem && !m_bMadeRoom );
m_pCloseButton->SetVisible( m_bDiscardedNewItem || m_bMadeRoom );
if ( m_pItemMouseOverPanel->IsVisible() )
{
m_pItemMouseOverPanel->SetVisible( false );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemDiscardPanel::ShowPanel(bool bShow)
{
if ( bShow )
{
m_bDiscardedNewItem = false;
m_bMadeRoom = false;
m_pBackpackPanel->ShowPanel( 0, true );
InvalidateLayout();
}
else
{
if ( m_pConfirmDeleteDialog )
{
m_pConfirmDeleteDialog->MarkForDeletion();
m_pConfirmDeleteDialog = NULL;
}
}
SetMouseInputEnabled( bShow );
SetVisible( bShow );
#ifdef TF_CLIENT_DLL
// If the player made room and is a trial account, suggest that they upgrade to get more space.
if ( bShow && IsFreeTrialAccount() )
{
ShowUpgradeMessageBox( "#TF_TrialNeedSpace_Title", "#TF_TrialNeedSpace_Text" );
}
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemDiscardPanel::FireGameEvent( IGameEvent *event )
{
if ( !IsVisible() )
return;
const char * type = event->GetName();
if ( Q_strcmp(type, "gameui_hidden") == 0 )
{
// If they haven't discarded down to <MAX items, bring us right back up again
if ( InventoryManager()->CheckForRoomAndForceDiscard() )
{
engine->ClientCmd_Unrestricted( "gameui_activate" );
}
else
{
ShowPanel( false );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemDiscardPanel::OnCommand( const char *command )
{
if ( !Q_stricmp( command, "vguicancel" ) )
{
ShowPanel( false );
// Check to make sure the player has room for all his items. If not, bring up the discard panel. Otherwise, go away.
if ( !InventoryManager()->CheckForRoomAndForceDiscard() )
{
// If we're connected to a game server, we also close the game UI.
if ( engine->IsInGame() )
{
engine->ClientCmd_Unrestricted( "gameui_hide" );
}
}
}
else if ( !Q_stricmp( command, "discarditem" ) )
{
// Bring up confirm dialog
CConfirmDeleteItemDialog *pConfirm = vgui::SETUP_PANEL( new CConfirmDeleteItemDialog( this ) );
if ( pConfirm )
{
pConfirm->Show();
m_pConfirmDeleteDialog = pConfirm;
}
}
else
{
engine->ClientCmd( const_cast<char *>( command ) );
}
BaseClass::OnCommand( command );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemDiscardPanel::SetItem( CEconItemView *pItem )
{
if ( m_pModelPanel )
{
m_pModelPanel->SetItem( pItem );
}
if ( m_pItemMouseOverPanel )
{
m_pItemMouseOverPanel->SetItem( pItem );
IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
m_pItemMouseOverPanel->InvalidateLayout(true);
m_pItemMouseOverPanel->SetBorder( pScheme->GetBorder("MainMenuBGBorder") );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CItemDiscardPanel::OnConfirmDelete( KeyValues *data )
{
if ( !m_bDiscardedNewItem && !m_bMadeRoom && data && m_pModelPanel->HasItem() )
{
int iConfirmed = data->GetInt( "confirmed", 0 );
if ( iConfirmed == 2 )
{
// Player discarded an item from the backpack to make room
m_bMadeRoom = true;
InvalidateLayout();
}
else if ( iConfirmed )
{
CPlayerInventory *pInventory = InventoryManager()->GetLocalInventory();
if ( !pInventory )
return;
InventoryManager()->DropItem( m_pModelPanel->GetItem()->GetItemID() );
m_bDiscardedNewItem = true;
InvalidateLayout();
}
m_pBackpackPanel->RequestFocus();
}
m_pConfirmDeleteDialog = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Handles the escape key
//-----------------------------------------------------------------------------
void CItemDiscardPanel::OnKeyCodeTyped( vgui::KeyCode code )
{
if( code == KEY_ESCAPE )
{
OnCommand( "vguicancel" );
}
else
{
BaseClass::OnKeyCodeTyped( code );
}
}
//-----------------------------------------------------------------------------
// Purpose: Handles button press code for controllers and enter
//-----------------------------------------------------------------------------
void CItemDiscardPanel::OnKeyCodePressed( vgui::KeyCode code )
{
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
if( nButtonCode == KEY_XBUTTON_B )
{
OnCommand( "vguicancel" );
}
else
{
BaseClass::OnKeyCodePressed( code );
}
}
static vgui::DHANDLE<CItemDiscardPanel> g_ItemDiscardPanel;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CItemDiscardPanel *OpenItemDiscardPanel( void )
{
if (!g_ItemDiscardPanel.Get())
{
g_ItemDiscardPanel = vgui::SETUP_PANEL( new CItemDiscardPanel( NULL ) );
g_ItemDiscardPanel->InvalidateLayout( false, true );
}
engine->ClientCmd_Unrestricted( "gameui_activate" );
g_ItemDiscardPanel->ShowPanel( true );
return g_ItemDiscardPanel;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CItemDiscardPanel *GetItemDiscardPanel( void )
{
return g_ItemDiscardPanel.Get();
}
+128
View File
@@ -0,0 +1,128 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef ITEM_PICKUP_PANEL_H
#define ITEM_PICKUP_PANEL_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Panel.h>
#include <vgui_controls/Frame.h>
#include "GameEventListener.h"
#include "basemodel_panel.h"
#include "basemodelpanel.h"
#include "econ_item_inventory.h"
#include "econ_item_view.h"
#include "item_model_panel.h"
#include "vgui_controls/TextEntry.h"
#include "econ_controls.h"
class CEconItemView;
class CBackpackPanel;
#define ITEMPICKUP_NUM_MODELPANELS 5 // 1 in the center of the screen, 2 to each side to handle smooth sliding.
#define ITEMPICKUP_MODELPANEL_CENTER 2 // Panel that's in the center of the queue
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CItemPickupPanel : public vgui::Frame, public CGameEventListener
{
DECLARE_CLASS_SIMPLE( CItemPickupPanel, vgui::Frame );
public:
CItemPickupPanel( Panel *parent );
virtual ~CItemPickupPanel();
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void ApplySettings( KeyValues *inResourceData );
virtual void PerformLayout( void );
virtual void OnCommand( const char *command );
virtual void ShowPanel( bool bShow );
virtual void FireGameEvent( IGameEvent *event );
virtual void OnKeyCodeTyped( vgui::KeyCode code );
virtual void OnKeyCodePressed( vgui::KeyCode code );
void AddItem( CEconItemView *pItem );
void SetReturnToGame( bool bReturn ) { m_bReturnToGame = bReturn; }
#ifdef DEBUG
void DebugRandomizePickupMethods( void ) { m_bRandomizePickupMethods = true; }
#endif
MESSAGE_FUNC_PARAMS( OnConfirmDelete, "ConfirmDlgResult", data );
protected:
virtual void UpdateModelPanels( void );
virtual void AcknowledgeItems ( void );
protected:
int m_iSelectedItem;
struct founditem_t
{
CEconItemView pItem;
bool bDiscarded;
};
CUtlVector<founditem_t> m_aItems;
CItemModelPanel *m_aModelPanels[ITEMPICKUP_NUM_MODELPANELS];
vgui::Button *m_pNextButton;
vgui::Button *m_pPrevButton;
vgui::Button *m_pOpenLoadoutButton;
CExButton *m_pCloseButton;
CExImageButton *m_pDiscardButton;
vgui::Label *m_pItemsFoundLabel;
vgui::Label *m_pItemFoundMethod;
KeyValues *m_pModelPanelsKV;
vgui::EditablePanel *m_pConfirmDeleteDialog;
vgui::Label *m_pDiscardedLabel;
bool m_bRandomizePickupMethods;
CSimplePanelToolTip *m_pToolTip;
bool m_bReturnToGame;
CPanelAnimationVarAliasType( float, m_iModelPanelSpacing, "modelpanels_spacing", "40", "proportional_float" );
CPanelAnimationVarAliasType( float, m_iModelPanelW, "modelpanels_width", "128", "proportional_float" );
CPanelAnimationVarAliasType( float, m_iModelPanelH, "modelpanels_height", "80", "proportional_float" );
CPanelAnimationVarAliasType( float, m_iModelPanelY, "modelpanels_ypos", "120", "proportional_float" );
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CItemDiscardPanel : public vgui::Frame, public CGameEventListener
{
DECLARE_CLASS_SIMPLE( CItemDiscardPanel, vgui::Frame );
public:
CItemDiscardPanel( Panel *parent );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void PerformLayout( void );
virtual void OnCommand( const char *command );
virtual void ShowPanel( bool bShow );
virtual void FireGameEvent( IGameEvent *event );
virtual void OnKeyCodeTyped( vgui::KeyCode code );
virtual void OnKeyCodePressed( vgui::KeyCode code );
void SetItem( CEconItemView *pItem );
MESSAGE_FUNC_PARAMS( OnConfirmDelete, "ConfirmDlgResult", data );
protected:
CItemModelPanel *m_pModelPanel;
CBackpackPanel *m_pBackpackPanel;
vgui::EditablePanel *m_pConfirmDeleteDialog;
vgui::Label *m_pDiscardedLabel;
vgui::Label *m_pDiscardedLabelCarat;
bool m_bDiscardedNewItem;
bool m_bMadeRoom;
CExButton *m_pDiscardButton;
CExButton *m_pCloseButton;
CSimplePanelToolTip *m_pItemToolTip;
CItemModelPanel *m_pItemMouseOverPanel;
};
#endif // ITEM_PICKUP_PANEL_H
+274
View File
@@ -0,0 +1,274 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "rtime.h"
#include "vgui_controls/EditablePanel.h"
#include "vgui_controls/TextEntry.h"
#include "vgui/IInput.h"
#include "econ_item_system.h"
#include "econ_item_constants.h"
#include "econ_gcmessages.h"
#include "econ_item_inventory.h"
#include "item_rental_ui.h"
#ifdef TF_CLIENT_DLL
#include "c_tf_gamestats.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
//-----------------------------------------------------------------------------
// Purpose: Confirm item preview.
//-----------------------------------------------------------------------------
class CConfirmItemPreviewDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmItemPreviewDialog, CBaseToolUsageDialog );
public:
CConfirmItemPreviewDialog( vgui::Panel *pParent, CEconItemView *pPreviewItem );
~CConfirmItemPreviewDialog();
virtual void ApplySchemeSettings( vgui::IScheme *scheme );
virtual void Apply( void );
private:
CEconItemView* m_pPreviewItem;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CConfirmItemPreviewDialog::CConfirmItemPreviewDialog( vgui::Panel *parent, CEconItemView *pPreviewItem ) : CBaseToolUsageDialog( parent, "ConfirmItemPreviewDialog", pPreviewItem, pPreviewItem )
{
m_pPreviewItem = pPreviewItem;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CConfirmItemPreviewDialog::~CConfirmItemPreviewDialog()
{
delete m_pPreviewItem;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmItemPreviewDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmItemPreviewDialog.res" );
BaseClass::ApplySchemeSettings( pScheme );
m_pTitleLabel = dynamic_cast<vgui::Label*>( FindChildByName("TitleLabel") );
if ( m_pTitleLabel )
{
wchar_t *pszBaseString = g_pVGuiLocalize->Find( "ItemPreviewDialogTitle" );
if ( pszBaseString )
{
wchar_t wTemp[256];
g_pVGuiLocalize->ConstructString_safe( wTemp, pszBaseString, 1, m_pToolModelPanel->GetItem()->GetItemName() );
m_pTitleLabel->SetText( wTemp );
m_pTitleLabel->GetTextImage()->ClearColorChangeStream();
}
}
m_pSubjectModelPanel->SetVisible( false );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmItemPreviewDialog::Apply( void )
{
// Notify the GC that the player wants to preview this item.
GCSDK::CGCMsg< MsgGCItemPreviewRequest_t > msg( k_EMsgGCItemPreviewRequest );
msg.Body().m_unItemDefIndex = m_pToolModelPanel->GetItem()->GetItemDefIndex();
// OGS LOGGING HERE
GCClientSystem()->BSendMessage( msg );
EconUI()->SetPreventClosure( false );
}
//-----------------------------------------------------------------------------
// Purpose: GC Msg handler to receive the item preview query response.
//-----------------------------------------------------------------------------
class CGCItemPreviewStatusResponse : public GCSDK::CGCClientJob
{
public:
CGCItemPreviewStatusResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CGCMsg<MsgGCItemPreviewCheckStatusResponse_t> msg( pNetPacket );
CStorePanel *pStorePanel = EconUI()->GetStorePanel();
if ( !pStorePanel )
return true;
if ( msg.Body().m_eResponse == k_EGCMsgResponseOK )
{
// We can preview the item.
CEconItemView *pPreviewItem = new CEconItemView();
pPreviewItem->Init( msg.Body().m_unItemDefIndex, AE_UNIQUE, AE_USE_SCRIPT_VALUE, true );
CConfirmItemPreviewDialog *dialog = vgui::SETUP_PANEL( new CConfirmItemPreviewDialog( pStorePanel->GetPropertySheet()->GetActivePage(), pPreviewItem ) );
MakeModalAndBringToFront( dialog );
}
else
{
#ifdef TF_CLIENT_DLL
C_CTFGameStats::ImmediateWriteInterfaceEvent( "store_preview_item_denied", CFmtStr( "%i", msg.Body().m_unItemDefIndex ).Access() );
#endif
// We aren't allowed to preview an item right now.
CTFMessageBoxDialog* pDialog = ShowMessageBox( "#ItemPreview_PreviewStartFailedTitle", "#ItemPreview_PreviewStartFailedText", "#GameUI_OK" );
RTime32 nextTime = msg.Body().m_timePreviewTime + EconUI()->GetStorePanel()->GetPriceSheet()->GetPreviewPeriod();
locchar_t wzValue[64];
char time_buf[k_RTimeRenderBufferSize];
GLocalizationProvider()->ConvertUTF8ToLocchar( CRTime::Render( nextTime, time_buf ), wzValue, sizeof( wzValue ) );
pDialog->AddStringToken( "date_time", wzValue );
}
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCItemPreviewStatusResponse, "CGCItemPreviewStatusResponse", k_EMsgGCItemPreviewStatusResponse, GCSDK::k_EServerTypeGCClient );
//-----------------------------------------------------------------------------
// Purpose: The GC is telling us our request has been granted.
//-----------------------------------------------------------------------------
class CGCItemPreviewRequestResponse : public GCSDK::CGCClientJob
{
public:
CGCItemPreviewRequestResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
static void OnPreviewItemConfirm( bool bConfirmed, void *pContext )
{
InventoryManager()->ShowItemsPickedUp( true, false );
CStorePage* pStorePage = dynamic_cast<CStorePage*>( EconUI()->GetStorePanel()->GetActivePage() );
if ( pStorePage )
{
pStorePage->UpdateModelPanels();
}
}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CGCMsg<MsgGCItemPreviewRequestResponse_t> msg( pNetPacket );
CStorePanel *pStorePanel = EconUI()->GetStorePanel();
if ( !pStorePanel )
return true;
if ( msg.Body().m_eResponse == k_EGCMsgResponseOK )
{
// The preview has started.
ShowMessageBox( "#ItemPreview_PreviewStartedTitle", "#ItemPreview_PreviewStartedText", "#GameUI_OK", OnPreviewItemConfirm );
}
else
{
// The preview cannot start right now for some reason.
}
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCItemPreviewRequestResponse, "CGCItemPreviewRequestResponse", k_EMsgGCItemPreviewRequestResponse, GCSDK::k_EServerTypeGCClient );
void OpenStoreToItem( bool bConfirmed, void *pContext )
{
CEconPreviewExpiredNotification* pNotification = (CEconPreviewExpiredNotification*) pContext;
if ( pNotification )
{
pNotification->SetIsInUse( false );
pNotification->MarkForDeletion();
if ( bConfirmed )
{
EconUI()->OpenStorePanel( pNotification->GetItemDefIndex(), true );
}
}
}
CEconPreviewNotification::CEconPreviewNotification( uint64 ulSteamID, uint32 iItemDef )
: CEconNotification()
{
SetSteamID( ulSteamID );
SetLifetime( 20.0f );
m_pItemDef = GetItemSchema()->GetItemDefinition( iItemDef );
if ( !m_pItemDef )
return;
AddStringToken( "item_name", g_pVGuiLocalize->Find(m_pItemDef->GetItemBaseName()) );
}
void CEconPreviewExpiredNotification::Trigger()
{
CTFGenericConfirmDialog *pDialog = ShowConfirmDialog( "#TF_PreviewItem_Expired_Title", "#TF_PreviewItem_Expired_Text", "#TF_PreviewItem_BuyIt", "#TF_PreviewItem_NotNow", &OpenStoreToItem );
pDialog->SetContext( this );
pDialog->AddStringToken( "item_name", g_pVGuiLocalize->Find(m_pItemDef->GetItemBaseName()) );
SetIsInUse( true );
}
//-----------------------------------------------------------------------------
// Purpose: The GC is telling us our preview item has expired.
//-----------------------------------------------------------------------------
class CGCItemPreviewExpireNotification : public GCSDK::CGCClientJob
{
public:
CGCItemPreviewExpireNotification( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CGCMsg<MsgGCItemPreviewExpireNotification_t> msg( pNetPacket );
CEconPreviewExpiredNotification *pNotification = new CEconPreviewExpiredNotification( msg.Hdr().m_ulSteamID, msg.Body().m_unItemDefIndex );
pNotification->SetText( "#TF_PreviewItem_Expired" );
NotificationQueue_Add( pNotification );
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCItemPreviewExpireNotification, "CGCItemPreviewExpireNotification", k_EMsgGCItemPreviewExpireNotification, GCSDK::k_EServerTypeGCClient );
//-----------------------------------------------------------------------------
// Purpose: The GC is telling us we bought our preview item!
//-----------------------------------------------------------------------------
class CGCItemPreviewItemBoughtNotification : public GCSDK::CGCClientJob
{
public:
CGCItemPreviewItemBoughtNotification( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CProtoBufMsg<CMsgGCItemPreviewItemBoughtNotification> msg( pNetPacket );
CEconPreviewItemBoughtNotification *pNotification = new CEconPreviewItemBoughtNotification( msg.Hdr().client_steam_id(), msg.Body().item_def_index() );
pNotification->SetText( "#TF_PreviewItem_ItemBought" );
NotificationQueue_Add( pNotification );
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCItemPreviewItemBoughtNotification, "CGCItemPreviewItemBoughtNotification", k_EMsgGCItemPreviewItemBoughtNotification, GCSDK::k_EServerTypeGCClient );
+66
View File
@@ -0,0 +1,66 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef ITEM_RENTAL_UI_H
#define ITEM_RENTAL_UI_H
#ifdef _WIN32
#pragma once
#endif
#include "econ_ui.h"
#include "vgui/ISurface.h"
#include "econ_controls.h"
#include "gc_clientsystem.h"
#include "tool_items/tool_items.h"
#include "store/store_panel.h"
#include "vgui_controls/PropertySheet.h"
#include "confirm_dialog.h"
#include "econ_notifications.h"
class CEconPreviewNotification : public CEconNotification
{
public:
CEconPreviewNotification( uint64 ulSteamID, uint32 iItemDef );
virtual EType NotificationType() { return eType_Trigger; }
virtual void Trigger() {}
int GetItemDefIndex()
{
return m_pItemDef->GetDefinitionIndex();
}
public:
const CEconItemDefinition *m_pItemDef;
};
class CEconPreviewExpiredNotification : public CEconPreviewNotification
{
public:
CEconPreviewExpiredNotification( uint64 ulSteamID, uint32 iItemDef ) : CEconPreviewNotification( ulSteamID, iItemDef ) {}
virtual EType NotificationType() { return eType_Trigger; }
virtual void Trigger();
};
class CEconPreviewItemBoughtNotification : public CEconPreviewNotification
{
public:
CEconPreviewItemBoughtNotification( uint64 ulSteamID, uint32 iItemDef ) : CEconPreviewNotification( ulSteamID, iItemDef ) {}
virtual EType NotificationType() { return eType_Trigger; }
virtual void Trigger()
{
EconUI()->OpenEconUI( ECONUI_BACKPACK );
MarkForDeletion();
}
};
#endif // ITEM_RENTAL_UI_H
File diff suppressed because it is too large Load Diff
+215
View File
@@ -0,0 +1,215 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef ITEM_SELECTION_PANEL_H
#define ITEM_SELECTION_PANEL_H
#ifdef _WIN32
#pragma once
#endif
#include "vgui_controls/EditablePanel.h"
#include "econ_controls.h"
#include "vgui_controls/ScrollableEditablePanel.h"
#include "backpack_panel.h"
#include "base_loadout_panel.h"
class CItemModelPanel;
#define SELECTION_DISPLAY_SLOTS_PER_PAGE 18
#define SELECTION_DISPLAY_ROWS 3
#define SELECTION_DISPLAY_COLUMNS (SELECTION_DISPLAY_SLOTS_PER_PAGE / SELECTION_DISPLAY_ROWS)
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
struct item_stack_type_t
{
item_stack_type_t() : m_nDefIndex( INVALID_ITEM_DEF_INDEX ), m_nQuality( (uint8)-1 ) { }
item_stack_type_t( item_definition_index_t nDefIndex, uint8 nQuality ) : m_nDefIndex( nDefIndex ), m_nQuality( nQuality ) { }
bool operator<( const item_stack_type_t& other ) const { return m_nDefIndex < other.m_nDefIndex || m_nQuality < other.m_nQuality; }
bool operator==( const item_stack_type_t& other ) const { return m_nDefIndex == other.m_nDefIndex && m_nQuality == other.m_nQuality; }
item_definition_index_t m_nDefIndex;
uint8 m_nQuality;
};
class CItemSelectionPanel : public CBaseLoadoutPanel
{
DECLARE_CLASS_SIMPLE( CItemSelectionPanel, CBaseLoadoutPanel );
public:
CItemSelectionPanel(Panel *parent);
virtual ~CItemSelectionPanel();
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void ApplySettings( KeyValues *inResourceData );
virtual void PerformLayout( void );
virtual void OnThink( void );
virtual void OnCommand( const char *command );
virtual void OnClose( void );
virtual void SetVisible( bool bState );
virtual bool ShouldDeleteOnClose( void ) { return true; }
virtual void OnKeyCodePressed( vgui::KeyCode code ) OVERRIDE;
virtual void OnKeyCodeReleased( vgui::KeyCode code ) OVERRIDE;
virtual void OnKeyCodeTyped( vgui::KeyCode code) OVERRIDE;
MESSAGE_FUNC_PARAMS( OnButtonChecked, "CheckButtonChecked", pData );
virtual int GetNumItemPanels( void ) { return m_bShowingEntireBackpack ? BACKPACK_SLOTS_PER_PAGE : SELECTION_DISPLAY_SLOTS_PER_PAGE; };
virtual void PositionItemPanel( CItemModelPanel *pPanel, int iIndex );
virtual bool AllowSelection( void ) { return true; }
virtual bool AllowDragging( CItemModelPanel *panel ) { return false; }
virtual int GetNumSlotsPerPage( void ) OVERRIDE { return m_bShowingEntireBackpack ? BACKPACK_SLOTS_PER_PAGE : SELECTION_DISPLAY_SLOTS_PER_PAGE; }
virtual int GetNumColumns( void ) OVERRIDE { return m_bShowingEntireBackpack ? BACKPACK_COLUMNS : SELECTION_DISPLAY_COLUMNS; }
virtual int GetNumRows( void ) OVERRIDE { return m_bShowingEntireBackpack ? BACKPACK_ROWS : SELECTION_DISPLAY_ROWS; }
virtual int GetNumPages( void ) OVERRIDE;
virtual void SetCurrentPage( int nNewPage ) OVERRIDE;
void UpdateModelPanels( void );
virtual void ApplyKVsToItemPanels( void );
virtual void CreateItemPanels( void );
void ShowDuplicateCounts( bool bShow ) { m_bShowDuplicates = bShow; }
void UpdateDuplicateCounts( void );
MESSAGE_FUNC_PTR( OnItemPanelMousePressed, "ItemPanelMousePressed", panel );
MESSAGE_FUNC_PTR( OnItemPanelMouseReleased, "ItemPanelMouseReleased", panel );
MESSAGE_FUNC_PARAMS( OnTextChanged, "TextChanged", data );
// Derived panels need to override these with the custom selection behavior
virtual const char *GetSchemeFile( void ) = 0;
virtual bool ShouldItemPanelBeVisible( CItemModelPanel *pPanel, int iPanelIndex ) = 0;
virtual void UpdateModelPanelsForSelection( void ) = 0;
virtual const char *GetItemNotSelectableReason( const CEconItemView *pItem ) const = 0;
virtual bool DisableItemSelectionFromGrayedOutPanels( void ) const { return false; }
void NotifySelectionReturned( CItemModelPanel *pItemPanel );
void SetCaller( Panel* pCaller ) { m_pCaller = pCaller; }
virtual bool DisplayOnlyAllowUniqueQualityCheckbox() const { return false; }
protected:
void PostMessageSelectionReturned( itemid_t ulItemID );
bool m_bShowingEntireBackpack;
KeyValues *m_pSelectionItemModelPanelKVs;
KeyValues *m_pDuplicateLabelKVs;
vgui::CheckButton *m_pOnlyAllowUniqueQuality;
CExButton *m_pShowBackpack;
CExButton *m_pShowSelection;
bool m_bForceBackpack;
CExButton *m_pNextPageButton;
CExButton *m_pPrevPageButton;
vgui::Label *m_pCurPageLabel;
vgui::Label *m_pNoItemsInSelectionLabel;
int m_iItemsInSelection;
bool m_bShowDuplicates;
CUtlVector<CExLabel*> m_pDuplicateCountLabels;
typedef CUtlMap< item_stack_type_t, int > DuplicateCountsMap_t;
DuplicateCountsMap_t m_DuplicateCounts; // A map of item def indices to item counts. Derived classes should fill this out.
bool m_bGotMousePressed;
Panel *m_pCaller;
vgui::TextEntry *m_pNameFilterTextEntry;
CUtlVector<wchar_t> m_wNameFilter;
float m_flFilterItemTime;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CEquipSlotItemSelectionPanel : public CItemSelectionPanel
{
public:
DECLARE_CLASS_SIMPLE( CEquipSlotItemSelectionPanel, CItemSelectionPanel );
public:
CEquipSlotItemSelectionPanel(Panel *parent, int iClass, int iSlot);
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void PerformLayout( void );
virtual const char *GetSchemeFile( void ) { return "Resource/UI/ItemSelectionPanel.res"; }
virtual bool ShouldItemPanelBeVisible( CItemModelPanel *pPanel, int iPanelIndex );
virtual void UpdateModelPanelsForSelection( void );
virtual const char *GetItemNotSelectableReason( const CEconItemView *pItem ) const;
virtual bool DisableItemSelectionFromGrayedOutPanels( void ) const { return true; }
void OnBackPressed();
protected:
int m_iClass; // Class of the player we're selecting an item for
int m_iSlot; // Slot on the player that we're selecting an item for
itemid_t m_iCurrentItemID;
vgui::Label *m_pWeaponLabel;
};
//-----------------------------------------------------------------------------
// Purpose: Selection panel that uses an Item Criteria block to do selection
//-----------------------------------------------------------------------------
class CItemCriteriaSelectionPanel : public CItemSelectionPanel
{
DECLARE_CLASS_SIMPLE( CItemCriteriaSelectionPanel, CItemSelectionPanel );
public:
CItemCriteriaSelectionPanel(Panel *parent, const CItemSelectionCriteria *pCriteria, itemid_t pExceptions[] = NULL, int iNumExceptions = 0 );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
void UpdateExceptions( itemid_t pExceptions[], int iNumExceptions );
virtual const char *GetSchemeFile( void ) { return "Resource/UI/ItemSelectionPanel.res"; }
virtual bool ShouldItemPanelBeVisible( CItemModelPanel *pPanel, int iPanelIndex );
virtual void UpdateModelPanelsForSelection( void );
virtual const char *GetItemNotSelectableReason( const CEconItemView *pItem ) const;
protected:
const CItemSelectionCriteria *m_pCriteria;
CUtlVector<itemid_t> m_Exceptions;
};
//-----------------------------------------------------------------------------
// Purpose: Selection panel for crafting
//-----------------------------------------------------------------------------
class CCraftingItemSelectionPanel : public CItemCriteriaSelectionPanel
{
DECLARE_CLASS_SIMPLE( CCraftingItemSelectionPanel, CItemCriteriaSelectionPanel );
public:
CCraftingItemSelectionPanel(Panel *parent );
virtual const char *GetItemNotSelectableReason( const CEconItemView *pItem ) const;
virtual bool ShouldDeleteOnClose( void ) { return false; }
void UpdateOnShow( const CItemSelectionCriteria *pCriteria, bool bForceBackpack, itemid_t pExceptions[] = NULL, int iNumExceptions = 0 );
virtual bool DisplayOnlyAllowUniqueQualityCheckbox() const { return true; }
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CAccountSlotItemSelectionPanel : public CEquipSlotItemSelectionPanel
{
DECLARE_CLASS_SIMPLE( CAccountSlotItemSelectionPanel, CEquipSlotItemSelectionPanel );
public:
CAccountSlotItemSelectionPanel( Panel *pParent, int iSlot, const char *pszTitleToken );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme ) OVERRIDE;
virtual const char *GetItemNotSelectableReason( const CEconItemView *pItem ) const OVERRIDE;
protected:
const char * m_pszTitleToken;
};
#endif // ITEM_SELECTION_PANEL_H
@@ -0,0 +1,209 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "vgui_controls/EditablePanel.h"
#include "vgui_controls/ComboBox.h"
#include "econ_item_system.h"
#include "econ_item_constants.h"
#include "item_style_select_dialog.h"
#include "econ_gcmessages.h"
#include "backpack_panel.h"
#include "econ_ui.h"
#include "gc_clientsystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CComboBoxBackpackOverlayDialogBase::CComboBoxBackpackOverlayDialogBase( vgui::Panel *parent, CEconItemView *pItem )
: vgui::EditablePanel( parent, "ComboBoxBackpackOverlayDialogBase" )
, m_pPreviewModelPanel( NULL )
, m_pItem( pItem )
{
if ( m_pItem )
{
m_pPreviewModelPanel = new CItemModelPanel( this, "preview_model" );
m_pPreviewModelPanel->SetItem( m_pItem );
}
m_pComboBox = new vgui::ComboBox( this, "ComboBox", 5, false );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CComboBoxBackpackOverlayDialogBase::ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ComboBoxBackpackOverlayDialog.res" );
BaseClass::ApplySchemeSettings( pScheme );
if ( m_pPreviewModelPanel )
{
if ( m_pPreviewModelPanel && m_pItem )
{
m_pPreviewModelPanel->SetItem( m_pItem );
}
m_pPreviewModelPanel->SetActAsButton( true, false );
}
if ( m_pComboBox )
{
m_pComboBox->RemoveAll();
vgui::HFont hFont = pScheme->GetFont( "HudFontSmallestBold", true );
m_pComboBox->SetFont( hFont );
PopulateComboBoxOptions();
m_pComboBox->AddActionSignalTarget( this );
}
CExLabel *pTitleLabel = dynamic_cast<CExLabel *>( FindChildByName( "TitleLabel" ) );
if ( pTitleLabel )
{
pTitleLabel->SetText( GetTitleLabelLocalizationToken() );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CComboBoxBackpackOverlayDialogBase::OnCommand( const char *command )
{
if ( !Q_strnicmp( command, "cancel", 6 ) )
{
TFModalStack()->PopModal( this );
SetVisible( false );
MarkForDeletion();
}
else if ( !Q_strnicmp( command, "apply", 5 ) )
{
OnComboBoxApplication();
TFModalStack()->PopModal( this );
SetVisible( false );
MarkForDeletion();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CComboBoxBackpackOverlayDialogBase::Show()
{
SetVisible( true );
MakePopup();
MoveToFront();
SetKeyBoardInputEnabled( true );
SetMouseInputEnabled( true );
TFModalStack()->PushModal( this );
// Special-case the path where we only wind up with one option in the combo box. If
// this happens we just pretend the user selected it and move on to the next step. For
// restoration, this will bring up a confirmation dialog, and for setting styles... well,
// we'd expect it to never happen because the option to bring up the UI wouldn't be enabled
// if there was only a single style.
if ( m_pComboBox && m_pComboBox->GetItemCount() == 1 )
{
OnCommand( "apply" );
}
}
//-----------------------------------------------------------------------------
// Purpose: Called when text changes in combo box
//-----------------------------------------------------------------------------
void CComboBoxBackpackOverlayDialogBase::OnTextChanged( KeyValues *data )
{
if ( !m_pComboBox )
return;
Panel *pPanel = reinterpret_cast<vgui::Panel *>( data->GetPtr("panel") );
vgui::ComboBox *pComboBox = dynamic_cast<vgui::ComboBox *>( pPanel );
if ( pComboBox == m_pComboBox )
{
OnComboBoxChanged( m_pComboBox->GetActiveItem() );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStyleSelectDialog::PopulateComboBoxOptions()
{
CEconItemView* pItem = GetPreviewModelPanel()->GetItem();
Assert( pItem );
if ( pItem->GetStaticData()->GetNumStyles() )
{
KeyValues *pKeyValues = new KeyValues( "data" );
for ( style_index_t i=0; i<pItem->GetStaticData()->GetNumStyles(); i++ )
{
const CEconStyleInfo *pStyle = pItem->GetStaticData()->GetStyleInfo( i );
if ( pStyle && pStyle->IsSelectable() )
{
pKeyValues->SetInt( "style_index", i );
GetComboBox()->AddItem( pItem->GetStaticData()->GetStyleInfo( i )->GetName(), pKeyValues );
}
}
pKeyValues->deleteThis();
GetComboBox()->ActivateItemByRow( pItem->GetItemStyle() );
}
else
{
GetComboBox()->ActivateItemByRow( 0 );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStyleSelectDialog::OnComboBoxApplication()
{
KeyValues *pKV = GetComboBox()->GetActiveItemUserData();
int iNewStyle = pKV->GetInt( "style_index", 0 );
CEconItemView* pItem = GetPreviewModelPanel()->GetItem();
if ( pItem )
{
const char* pszStyleName = pItem->GetStaticData()->GetStyleInfo( iNewStyle )->GetName();
// Tell the GC to update the style.
GCSDK::CGCMsg< MsgGCSetItemStyle_t > msg( k_EMsgGCSetItemStyle );
msg.Body().m_unItemID = pItem->GetItemID();
msg.Body().m_iStyle = iNewStyle;
GCClientSystem()->BSendMessage( msg );
EconUI()->Gamestats_ItemTransaction( IE_ITEM_CHANGED_STYLE, pItem, pszStyleName /* stored unlocalized here intentionally */, iNewStyle );
// Tell our parent about the change
if ( pItem && pItem->IsValid() )
{
KeyValues *pKey = new KeyValues( "SelectionReturned" );
pKey->SetUint64( "itemindex", pItem->GetItemID() );
PostMessage( GetParent(), pKey );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStyleSelectDialog::OnComboBoxChanged( int iNewSelection )
{
GetPreviewModelPanel()->SetItemStyle( GetComboBox()->GetActiveItem() );
GetPreviewModelPanel()->UpdatePanels();
}
@@ -0,0 +1,71 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef ITEM_STYLE_SELECT_DIALOG_H
#define ITEM_STYLE_SELECT_DIALOG_H
#ifdef _WIN32
#pragma once
#endif
class CItemModelPanel;
#include "vgui_controls/EditablePanel.h"
#include "vgui_controls/ComboBox.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CComboBoxBackpackOverlayDialogBase : public vgui::EditablePanel
{
DECLARE_CLASS_SIMPLE( CComboBoxBackpackOverlayDialogBase, vgui::EditablePanel );
protected:
CComboBoxBackpackOverlayDialogBase( vgui::Panel *pParent, CEconItemView *pItem );
public:
virtual ~CComboBoxBackpackOverlayDialogBase() { }
virtual void ApplySchemeSettings( vgui::IScheme *scheme );
virtual void OnCommand( const char *command );
void Show();
protected:
CItemModelPanel *GetPreviewModelPanel() { return m_pPreviewModelPanel; }
vgui::ComboBox *GetComboBox() { return m_pComboBox; }
CEconItemView *m_pItem;
private:
virtual void PopulateComboBoxOptions() = 0;
virtual void OnComboBoxApplication() = 0;
virtual void OnComboBoxChanged( int iNewSelection ) { }
virtual const char *GetTitleLabelLocalizationToken() const = 0;
MESSAGE_FUNC_PARAMS( OnTextChanged, "TextChanged", data );
CItemModelPanel *m_pPreviewModelPanel;
vgui::ComboBox *m_pComboBox;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CStyleSelectDialog : public CComboBoxBackpackOverlayDialogBase
{
DECLARE_CLASS_SIMPLE( CStyleSelectDialog, CComboBoxBackpackOverlayDialogBase );
public:
CStyleSelectDialog( vgui::Panel *pParent, CEconItemView *pItem ) : CComboBoxBackpackOverlayDialogBase( pParent, pItem ) { }
protected:
virtual void PopulateComboBoxOptions();
virtual void OnComboBoxApplication();
virtual void OnComboBoxChanged( int iNewSelection );
virtual const char *GetTitleLabelLocalizationToken() const { return "#TF_Item_SelectStyle"; }
};
#endif // ITEM_STYLE_SELECT_DIALOG_H
@@ -0,0 +1,24 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "local_steam_shared_object_listener.h"
#include "tf_gc_client.h"
CLocalSteamSharedObjectListener::CLocalSteamSharedObjectListener()
{
// Delayed add in case something derives from us and isn't fully constructed yet
// so their SOCreated functions are setup in the VTable yet.
GTFGCClientSystem()->AddLocalPlayerSOListener( this, false );
}
CLocalSteamSharedObjectListener::~CLocalSteamSharedObjectListener()
{
GTFGCClientSystem()->RemoveLocalPlayerSOListener( this );
}
@@ -0,0 +1,31 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef LOCAL_STEAM_SHARED_OBJECT_LISTENER
#define LOCAL_STEAM_SHARED_OBJECT_LISTENER
#ifdef _WIN32
#pragma once
#endif
#include "gcsdk/gcclient_sharedobjectcache.h"
class CLocalSteamSharedObjectListener : public GCSDK::ISharedObjectListener
{
public:
CLocalSteamSharedObjectListener();
virtual ~CLocalSteamSharedObjectListener();
virtual void SOCreated( const CSteamID & steamIDOwner, const GCSDK::CSharedObject *pObject, GCSDK::ESOCacheEvent eEvent ) OVERRIDE {}
virtual void PreSOUpdate( const CSteamID & steamIDOwner, GCSDK::ESOCacheEvent eEvent ) OVERRIDE {}
virtual void SOUpdated( const CSteamID & steamIDOwner, const GCSDK::CSharedObject *pObject, GCSDK::ESOCacheEvent eEvent ) OVERRIDE {}
virtual void PostSOUpdate( const CSteamID & steamIDOwner, GCSDK::ESOCacheEvent eEvent ) OVERRIDE {}
virtual void SODestroyed( const CSteamID & steamIDOwner, const GCSDK::CSharedObject *pObject, GCSDK::ESOCacheEvent eEvent ) OVERRIDE {}
virtual void SOCacheSubscribed( const CSteamID & steamIDOwner, GCSDK::ESOCacheEvent eEvent ) OVERRIDE {}
virtual void SOCacheUnsubscribed( const CSteamID & steamIDOwner, GCSDK::ESOCacheEvent eEvent ) OVERRIDE {}
};
#endif // LOCAL_STEAM_SHARED_OBJECT_LISTENER
File diff suppressed because it is too large Load Diff
+424
View File
@@ -0,0 +1,424 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef STORE_PAGE_H
#define STORE_PAGE_H
#ifdef _WIN32
#pragma once
#endif
#include <game/client/iviewport.h>
#include "vgui_controls/PropertyPage.h"
#include <vgui_controls/Button.h>
#include <vgui_controls/ComboBox.h>
#include <vgui_controls/ImagePanel.h>
#include "econ_controls.h"
#include "econ_ui.h"
#include "econ_store.h"
#include "item_model_panel.h"
#include "econ_storecategory.h"
class CItemModelPanel;
class CItemModelPanelToolTip;
class CStorePreviewItemPanel;
class CStoreItemControlsPanel;
#define FILTER_ALL_ITEMS 0
//-----------------------------------------------------------------------------
// Purpose: Base class for the preview icons in the store's item preview panel
//-----------------------------------------------------------------------------
class CBaseStorePreviewIcon : public vgui::EditablePanel
{
DECLARE_CLASS_SIMPLE( CBaseStorePreviewIcon, vgui::EditablePanel );
public:
CBaseStorePreviewIcon( vgui::Panel *parent, const char *name ) : vgui::EditablePanel(parent,name)
{
REGISTER_COLOR_AS_OVERRIDABLE( m_colPanelBG, "panel_bgcolor" );
REGISTER_COLOR_AS_OVERRIDABLE( m_colPanelBGMouseover, "panel_bgcolor_mouseover" );
m_bHover = false;
m_bSelected = false;
}
void SetSelected( bool bSelected )
{
m_bSelected = bSelected;
UpdateBgColor();
}
void ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
SetBgColor( m_colPanelBG );
}
virtual void PerformLayout( void )
{
BaseClass::PerformLayout();
int iWide = GetWide() - (m_iImageIndent * 2);
int iTall = GetTall() - (m_iImageIndent * 2);
SetInternalImageBounds( m_iImageIndent, m_iImageIndent, iWide, iTall );
}
virtual void OnCursorEntered()
{
BaseClass::OnCursorEntered();
m_bHover = true;
UpdateBgColor();
}
virtual void OnCursorExited()
{
BaseClass::OnCursorExited();
m_bHover = false;
UpdateBgColor();
}
virtual void SetInternalImageBounds( int iX, int iY, int iWide, int iTall ) = 0;
private:
Color m_colPanelBG;
Color m_colPanelBGMouseover;
CPanelAnimationVarAliasType( int, m_iImageIndent, "image_indent", "0", "proportional_int" );
bool m_bHover;
bool m_bSelected;
void UpdateBgColor()
{
if ( m_bHover || m_bSelected )
{
SetBgColor( m_colPanelBGMouseover );
}
else
{
SetBgColor( m_colPanelBG );
}
}
};
//-----------------------------------------------------------------------------
// Purpose: An item preview icon in the store's item preview panel
//-----------------------------------------------------------------------------
class CStorePreviewItemIcon : public CBaseStorePreviewIcon
{
DECLARE_CLASS_SIMPLE( CStorePreviewItemIcon, CBaseStorePreviewIcon );
public:
CStorePreviewItemIcon( vgui::Panel *parent, const char *name ) : CBaseStorePreviewIcon(parent,name)
{
m_pItemPanel = new CItemModelPanel( this, "itempanel" );
m_pItemPanel->AddActionSignalTarget( this );
m_pItemPanel->SendPanelEnterExits( true );
m_pItemPanel->SetActAsButton( true, true );
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
vgui::EditablePanel *pTmp = dynamic_cast<vgui::EditablePanel*>( FindChildByName("bgblockout") );
if ( pTmp )
{
pTmp->SetMouseInputEnabled( false );
}
}
virtual void OnCursorEntered()
{
BaseClass::OnCursorEntered();
PostActionSignal(new KeyValues("ShowItemIconMouseover", "icon", m_iIconIndex));
}
virtual void OnCursorExited()
{
BaseClass::OnCursorExited();
PostActionSignal(new KeyValues("HideItemIconMouseover"));
}
virtual void OnMouseReleased(vgui::MouseCode code)
{
BaseClass::OnMouseReleased(code);
PostActionSignal(new KeyValues("ItemIconSelected", "icon", m_iIconIndex));
}
MESSAGE_FUNC_PTR( OnItemPanelMouseReleased, "ItemPanelMouseReleased", panel );
virtual void SetInternalImageBounds( int iX, int iY, int iWide, int iTall )
{
m_pItemPanel->SetBounds( iX, iY, iWide, iTall );
}
MESSAGE_FUNC_PTR( OnItemPanelEntered, "ItemPanelEntered", panel )
{
BaseClass::OnCursorEntered();
}
MESSAGE_FUNC_PTR( OnItemPanelExited, "ItemPanelExited", panel )
{
BaseClass::OnCursorExited();
}
void SetItem( int iIconIndex, int iItemDef )
{
m_iIconIndex = iIconIndex;
CEconItemView itemData;
itemData.Init( iItemDef, AE_UNIQUE, AE_USE_SCRIPT_VALUE, true );
m_pItemPanel->SetItem( &itemData );
}
void SetItem( int iIconIndex, CEconItemView *pItem )
{
m_iIconIndex = iIconIndex;
m_pItemPanel->SetItem( pItem );
}
CItemModelPanel *GetItemPanel( void ) { return m_pItemPanel; }
private:
CItemModelPanel *m_pItemPanel;
int m_iIconIndex;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CStoreItemControlsPanel;
class CStoreItemControlsPanel : public vgui::EditablePanel
{
public:
DECLARE_CLASS_SIMPLE( CStoreItemControlsPanel, vgui::EditablePanel );
CStoreItemControlsPanel( vgui::Panel *pParent, const char *pPanelName, CItemModelPanel *pItemModelPanel );
virtual ~CStoreItemControlsPanel() {}
void SetMouseHoverHandler( Panel *pHandler );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
const econ_store_entry_t *GetItem() const;
void SetItem( const econ_store_entry_t *pEntry );
void SetButtonsVisible( bool bVisible );
virtual void OnCursorEntered();
virtual void OnCursorExited();
void OnItemPanelEntered();
void OnItemPanelExited();
virtual void OnThink();
virtual void OnCommand( const char *command );
CItemModelPanel *GetItemModelPanel() { return m_pItemModelPanel; }
protected:
CItemModelPanel *m_pItemModelPanel;
const econ_store_entry_t *m_pEntry;
bool m_bButtonsVisible;
bool m_bItemPanelEntered;
vgui::DHANDLE< Panel > m_pMouseHoverHandler;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CStorePricePanel : public vgui::EditablePanel
{
public:
DECLARE_CLASS_SIMPLE( CStorePricePanel, vgui::EditablePanel );
CStorePricePanel( vgui::Panel *pParent, const char *pPanelName );
virtual ~CStorePricePanel();
virtual const char* GetPanelResFile();
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void PerformLayout();
void SetPriceText( int iPrice, const char *pVariable, const econ_store_entry_t *pEntry );
virtual void SetItem( const econ_store_entry_t *pEntry );
MESSAGE_FUNC_PARAMS( OnStoreItemControlsPanelHover, "StoreItemControlsPanelHover", data );
protected:
bool m_bOldDiscountVisibility;
CExLabel *m_pPrice;
CExLabel *m_pDiscount;
CExLabel *m_pNew;
CExLabel *m_pHighlighted;
CExLabel *m_pSale;
EditablePanel *m_pSaleBorder;
CExLabel *m_pOGPrice;
Panel *m_pCrossout;
Panel *m_pLimited;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CStorePage : public vgui::PropertyPage, public CGameEventListener
{
DECLARE_CLASS_SIMPLE( CStorePage, vgui::PropertyPage );
public:
CStorePage( Panel *parent, const CEconStoreCategoryManager::StoreCategory_t *pPageData, const char *pPreviewItemResFile = NULL );
virtual ~CStorePage();
virtual void OnPostCreate();
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void ApplySettings( KeyValues *inResourceData );
virtual void OnCommand( const char *command );
virtual void PerformLayout( void );
virtual void FireGameEvent( IGameEvent *event );
virtual void OnMouseWheeled( int delta );
virtual CStorePricePanel* CreatePricePanel( int iIndex );
void SetBorderForItem( CItemModelPanel *pItemPanel, bool bMouseOver );
void CalculateItemButtonPos( CItemModelPanel *pItemPanel, int x, int y, int *iXPos, int *iYPos );
int AssignItemToPanel( CItemModelPanel *pPanel, int iIndex );
void PositionItemPanel( CItemModelPanel *pPanel, int iIndex );
void UpdateModelPanels( void );
virtual void UpdateSelectionInfoPanel( void );
void UpdateCart( void );
void AddSelectionToCart( void );
void PreviewSelectionItem( void );
void DoPreviewItem( item_definition_index_t usItemDef );
const econ_store_entry_t *GetSelectedEntry( void );
int GetNumItemPanels( void ) { return m_iItemPanels; }
int GetNumColumns( void ) { return m_iItemColumns; }
int GetNumPages( void );
virtual void ShowPreview( int iClass, const econ_store_entry_t* pEntry );
void SetDetailsVisible( bool bVisible );
const char* GetPageName( void ) { return m_pPageData ? m_pPageData->m_pchName : NULL; }
virtual bool FindAndSelectEntry( const econ_store_entry_t *pEntry );
CItemModelPanelToolTip *GetItemTooltip( void ) { return m_pMouseOverTooltip; }
MESSAGE_FUNC( OnPageShow, "PageShow" );
MESSAGE_FUNC_PTR( OnItemPanelMouseReleased, "ItemPanelMouseReleased", panel ); // Comes from CStoreItemControlsPanel
MESSAGE_FUNC_PTR( OnItemPanelMouseDoublePressed, "ItemPanelMouseDoublePressed", panel );
MESSAGE_FUNC_PTR( OnItemPanelEntered, "ItemPanelEntered", panel );
MESSAGE_FUNC_PTR( OnItemPanelExited, "ItemPanelExited", panel );
MESSAGE_FUNC_PTR( OnItemAddToCart, "ItemAddToCart", panel );
MESSAGE_FUNC_PARAMS( OnTextChanged, "TextChanged", data );
MESSAGE_FUNC_PARAMS( OnPreviewItem, "PreviewItem", data );
virtual const char *GetPageResFile();
virtual CStorePreviewItemPanel *CreatePreviewPanel( void );
protected:
// Filtering
virtual bool DoesEntryFilterPassSecondaryFilter( const econ_store_entry_t *pEntry ) { return true; } // Allow derived classes to add an additional
virtual void UpdateFilteredItems( void );
virtual int GetNumPrimaryFilters( void ) { return 1; } // All Items
void SetFilter( int iFilter );
virtual void UpdateFilterComboBox( void );
virtual void GetFiltersForDef( GameItemDefinition_t *pDef, CUtlVector<int> *pVecFilters ) { pVecFilters->AddToTail( FILTER_ALL_ITEMS ); }
static int ItemDisplayOrderSort_UseSortOverride( const econ_store_entry_t *const *ppA, const econ_store_entry_t *const *ppB );
virtual void OrderItemsForDisplay( CUtlVector<const econ_store_entry_t *>& vecItems ) const;
protected:
void CreateItemPanels( void );
void DeSelectAllItemPanels( void );
void ToggleSelectItemPanel( CItemModelPanel *pPanel );
void SelectItemPanel( CItemModelPanel *pPanel );
void UpdateBackpackLabel( void );
bool IsHomePage( void ) { return m_pPageData && m_pPageData->m_bIsHome; }
protected:
const CEconStoreCategoryManager::StoreCategory_t *m_pPageData;
CStorePreviewItemPanel *m_pPreviewPanel;
const char *m_pPreviewItemResFile;
vgui::EditablePanel *m_pItemDetailsButtonPanel;
vgui::EditablePanel *m_pItemPreviewButtonPanel;
// Filtering
CUtlVector< const econ_store_entry_t* > m_FilteredEntries;
vgui::ComboBox *m_pFilterComboBox;
int m_iCurrentFilter;
// Selection info panel
int m_iSelectedItemDef;
int m_iOldSelectedItemDef;
int m_iSelectDefOnPageShow;
int m_iSelectPageOnPageShow;
CItemModelPanel *m_pSelectedPanel;
CItemModelPanel *m_pFeaturedItemPanel;
Color m_colBackpackOrg;
// Item model panels
struct item_panel
{
CItemModelPanel* m_pItemModelPanel;
CStorePricePanel* m_pStorePricePanel;
CStoreItemControlsPanel* m_pItemControlsPanel;
};
CUtlVector<item_panel> m_vecItemPanels;
CUtlVector<int> m_EntryIndices; // Easy lookup for which model panel is mapped to which entry index
CItemModelPanel *m_pMouseOverItemPanel;
CItemModelPanelToolTip *m_pMouseOverTooltip;
KeyValues *m_pItemModelPanelKVs;
KeyValues *m_pModelPanelLabelsKVs;
bool m_bReapplyItemKVs;
// Cart display
CExButton *m_pCartButton;
CUtlVector<CItemModelPanel*> m_pCartModelPanels;
KeyValues *m_pCartModelPanelKVs;
CUtlVector<CExLabel*> m_pCartQuantityLabels;
KeyValues *m_pCartQuantityLabelKVs;
vgui::ImagePanel *m_pCartFeaturedItemImage;
// Pages
int m_iCurrentPage;
vgui::Label *m_pCurPageLabel;
CExButton *m_pNextPageButton;
CExButton *m_pPrevPageButton;
CExButton *m_pCheckoutButton;
CExButton *m_pPreviewItemButton;
vgui::EditablePanel *m_pAddToCartButtonPanel;
vgui::Label *m_pBackpackLabel;
vgui::EditablePanel *m_pItemBackdropPanel;
bool m_bShouldDeletePreviewPanel; // Set to true by derived classes if the preview panel's panel should be deleted, which is necessary if its parent is NULL
CPanelAnimationVarAliasType( int, m_iItemOffcenterX, "item_offcenter_x", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iItemXDelta, "item_xdelta", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iItemYDelta, "item_ydelta", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iItemXPos, "item_xpos", "0", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iItemYPos, "item_ypos", "0", "proportional_int" );
CPanelAnimationVar( int, m_iItemPanels, "item_panels", "35" );
CPanelAnimationVar( int, m_iItemColumns, "item_columns", "7" );
CPanelAnimationVar( bool, m_bShowItemBgPanel, "show_item_backdrop", "0" );
CPanelAnimationVarAliasType( int, m_iItemBackdropLeftMargin, "item_backdrop_left_margin", "20", "proportional_xpos" );
CPanelAnimationVarAliasType( int, m_iItemBackdropRightMargin, "item_backdrop_right_margin", "20", "proportional_xpos" );
CPanelAnimationVarAliasType( int, m_iItemBackdropTopMargin, "item_backdrop_top_margin", "20", "proportional_ypos" );
CPanelAnimationVarAliasType( int, m_iItemBackdropBottomMargin, "item_backdrop_bottom_margin", "20", "proportional_ypos" );
CPanelAnimationVar( int, m_iItemBackdropPaintBackgroundType, "item_backdrop_paintbackgroundtype", "50" );
CPanelAnimationVar( int, m_iItemBackdropZPos, "item_backdrop_zpos", "0" );
CPanelAnimationVarAliasType( int, m_iItemControlsXOffset, "item_controls_xoffset", "5", "proportional_xpos" );
CPanelAnimationVarAliasType( int, m_iItemControlsYOffset, "item_controls_yoffset", "5", "proportional_xpos" );
CPanelAnimationVar( int, m_iMaxCartModelPanels, "max_cart_model_panels", "10" );
Color m_colItemPanelBG;
Color m_colItemPanelBGMouseover;
Color m_colItemPanelBGSelected;
Color m_colItemBackdropPanel;
// The number of items in each filter options
CUtlVector<int> m_vecFilterCounts;
bool m_bFilterDirty;
};
void AddItemToCartHelper( const char *pszContext, const econ_store_entry_t *pEntry, ECartItemType eSelectedCartItemType );
void AddItemToCartHelper( const char *pszContext, item_definition_index_t unItemDef, ECartItemType eSelectedCartItemType );
#endif // STORE_PAGE_H
@@ -0,0 +1,85 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "store/store_page_halloween.h"
#include "vgui/ISurface.h"
#include "vgui/IInput.h"
#include "vgui/ILocalize.h"
#include "c_tf_player.h"
#include "gamestringpool.h"
#include "tf_item_inventory.h"
#include "econ_item_system.h"
#include "item_model_panel.h"
#include "store/store_panel.h"
#include "store_preview_item.h"
#include "store_viewcart.h"
#include "c_tf_gamestats.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFStorePage_SpecialPromo::CTFStorePage_SpecialPromo( Panel *parent, const CEconStoreCategoryManager::StoreCategory_t *pPageData ) : BaseClass( parent, pPageData )
{
pszResFile = pPageData->m_pchPageRes;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
/*
void CTFStorePage_SpecialPromo::OrderItemsForDisplay( CUtlVector<const econ_store_entry_t *>& vecItems ) const
{
vecItems.Sort( &ItemDisplayOrderSort_UseSortOverride );
}
*/
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTFStorePage_Popular::CTFStorePage_Popular( Panel *parent, const CEconStoreCategoryManager::StoreCategory_t *pPageData ) : BaseClass( parent, pPageData )
{
}
//-----------------------------------------------------------------------------
// Purpose: The popular page draws its list of items from the overall popular items list.
//-----------------------------------------------------------------------------
void CTFStorePage_Popular::UpdateFilteredItems( void )
{
m_FilteredEntries.Purge();
m_vecFilterCounts.SetCount( GetNumPrimaryFilters() );
if ( !m_vecFilterCounts.Count() )
return;
FOR_EACH_VEC( m_vecFilterCounts, i )
{
m_vecFilterCounts[i] = 0;
}
CStorePanel *pStorePanel = EconUI()->GetStorePanel();
if ( !pStorePanel )
return;
// Add all popular items
const CUtlVector<uint32>& popularItems = pStorePanel->GetPopularItems();
for ( int i=0; i<popularItems.Count(); ++i )
{
const econ_store_entry_t *pEntry = pStorePanel->GetPriceSheet()->GetEntry( popularItems[i] );
m_FilteredEntries.AddToTail( pEntry );
}
FOR_EACH_VEC( m_vecItemPanels, idx )
{
m_vecItemPanels[idx].m_pItemModelPanel->SetShowQuantity( false );
}
m_pFilterComboBox->SetVisible( false );
}
@@ -0,0 +1,49 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef STORE_PAGE_SPECIALPROMO_H
#define STORE_PAGE_SPECIALPROMO_H
#ifdef _WIN32
#pragma once
#endif
#include "store/v1/tf_store_page.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CTFStorePage_SpecialPromo : public CTFStorePage1
{
DECLARE_CLASS_SIMPLE( CTFStorePage_SpecialPromo, CTFStorePage1 );
public:
CTFStorePage_SpecialPromo( Panel *parent, const CEconStoreCategoryManager::StoreCategory_t *pPageData );
virtual const char* GetPageResFile() { return pszResFile; }
protected:
// virtual void OrderItemsForDisplay( CUtlVector<const econ_store_entry_t *>& vecItems ) const;
private:
const char* pszResFile;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CTFStorePage_Popular : public CTFStorePage1
{
DECLARE_CLASS_SIMPLE( CTFStorePage_Popular, CTFStorePage1 );
public:
CTFStorePage_Popular( Panel *parent, const CEconStoreCategoryManager::StoreCategory_t *pPageData );
protected:
virtual void UpdateFilteredItems( void );
};
#endif // STORE_PAGE_SPECIALPROMO_H
+232
View File
@@ -0,0 +1,232 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "store_page_new.h"
#include "vgui/ISurface.h"
#include "vgui/IInput.h"
#include "vgui/ILocalize.h"
#include "gamestringpool.h"
#include "econ_item_inventory.h"
#include "econ_item_system.h"
#include "item_model_panel.h"
#include "store/store_panel.h"
#include "store_preview_item.h"
#include "store_viewcart.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStorePricePanel_New::CStorePricePanel_New( vgui::Panel *pParent, const char *pPanelName )
: CStorePricePanel( pParent, pPanelName )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePricePanel_New::SetItem( const econ_store_entry_t *pEntry )
{
BaseClass::SetItem( pEntry );
CExLabel *pNew = dynamic_cast< CExLabel* >( FindChildByName( "New" ) );
if ( pNew )
{
pNew->SetVisible( false );
}
pNew = dynamic_cast< CExLabel* >( FindChildByName( "NewLarge" ) );
if ( pNew )
{
int contentWidth, contentHeight;
pNew->GetContentSize( contentWidth, contentHeight );
int iTextInsetX, iTextInsetY;
pNew->GetTextInset( &iTextInsetX, &iTextInsetY );
pNew->SetWide( contentWidth + iTextInsetX );
int iPosX, iPosY;
pNew->GetPos( iPosX, iPosY );
pNew->SetPos( GetWide() - pNew->GetWide(), iPosY );
pNew->SetVisible( true );
}
vgui::Panel* pLimited = FindChildByName( "LimitedLarge" );
if ( pLimited )
{
int iPosX, iPosY;
pLimited->GetPos( iPosX, iPosY );
if ( pNew && pEntry->m_bLimited )
{
iPosY = pNew->GetTall() + YRES( 3 );
}
pLimited->SetPos( GetWide() - pLimited->GetWide() - XRES( 3 ), iPosY );
pLimited->SetVisible( pEntry->m_bLimited );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStorePricePanel_Bundles::CStorePricePanel_Bundles( vgui::Panel *pParent, const char *pPanelName )
: CStorePricePanel( pParent, pPanelName ),
m_pLimitedLarge( NULL )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePricePanel_Bundles::SetItem( const econ_store_entry_t *pEntry )
{
BaseClass::SetItem( pEntry );
if ( m_pLimitedLarge )
{
m_pLimitedLarge->SetVisible( pEntry->m_bLimited );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePricePanel_Bundles::ApplySchemeSettings( IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
m_pLimitedLarge = dynamic_cast<ImagePanel *>( FindChildByName( "LimitedLarge" ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePricePanel_Bundles::PerformLayout()
{
BaseClass::PerformLayout();
if ( m_pLimitedLarge )
{
int aPos[2];
m_pLimitedLarge->GetPos( aPos[0], aPos[1] );
if ( m_pNew && m_pNew->IsVisible() )
{
aPos[1] = m_pNew->GetTall() + YRES( 3 );
}
m_pLimitedLarge->SetPos( GetWide() - m_pLimitedLarge->GetWide(), aPos[1] );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStorePricePanel_Jumbo::CStorePricePanel_Jumbo( vgui::Panel *pParent, const char *pPanelName )
: CStorePricePanel( pParent, pPanelName )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStorePricePanel_Popular::CStorePricePanel_Popular( vgui::Panel *pParent, const char *pPanelName, int iPopularityRank )
: CStorePricePanel( pParent, pPanelName )
, m_iPopularityRank( iPopularityRank )
{
m_pNewLarge = NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePricePanel_Popular::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
m_pNewLarge = dynamic_cast< CExLabel* >( FindChildByName( "NewLarge" ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePricePanel_Popular::PerformLayout()
{
BaseClass::PerformLayout();
if ( m_pNewLarge )
{
int contentWidth, contentHeight;
m_pNewLarge->GetContentSize( contentWidth, contentHeight );
int iTextInsetX, iTextInsetY;
m_pNewLarge->GetTextInset( &iTextInsetX, &iTextInsetY );
m_pNewLarge->SetWide( contentWidth + iTextInsetX );
int iPosX, iPosY;
m_pNewLarge->GetPos( iPosX, iPosY );
m_pNewLarge->SetPos( GetWide() - m_pNewLarge->GetWide(), iPosY );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePricePanel_Popular::SetItem( const econ_store_entry_t *pEntry )
{
BaseClass::SetItem( pEntry );
CExLabel *pNew = dynamic_cast< CExLabel* >( FindChildByName( "New" ) );
if ( pNew )
{
pNew->SetVisible( false );
}
if ( m_pNewLarge )
{
if ( pEntry->m_bNew )
{
m_pNewLarge->SetVisible( true );
}
else
{
m_pNewLarge->SetVisible( false );
}
}
vgui::Panel* pLimited = FindChildByName( "LimitedLarge" );
if ( pLimited && m_pNewLarge )
{
int iPosX, iPosY;
pLimited->GetPos( iPosX, iPosY );
if ( pEntry->m_bLimited && pEntry->m_bNew )
{
iPosY = m_pNewLarge->GetTall() + YRES( 3 );
}
pLimited->SetPos( GetWide() - m_pNewLarge->GetWide() - 14, iPosY );
pLimited->SetVisible( pEntry->m_bLimited );
}
wchar_t wszRank[10];
_snwprintf( wszRank, ARRAYSIZE( wszRank ), L"%d", m_iPopularityRank );
wchar_t wszText[8];
g_pVGuiLocalize->ConstructString_safe( wszText, g_pVGuiLocalize->Find( "TF_Popularity_Rank" ), 1, wszRank );
SetDialogVariable( "rank1", wszText );
SetDialogVariable( "rank2", wszText );
// Show rank or rank2 based on old store/new store
CExLabel *pRank = dynamic_cast<CExLabel *>( FindChildByName( CFmtStr( "Rank%i", GetStoreVersion() ).Access() ) );
if ( pRank )
{
pRank->SetVisible( true );
}
}
+107
View File
@@ -0,0 +1,107 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef STORE_PAGE_NEW_H
#define STORE_PAGE_NEW_H
#ifdef _WIN32
#pragma once
#endif
#include <game/client/iviewport.h>
#include "vgui_controls/PropertyPage.h"
#include <vgui_controls/Button.h>
#include <vgui_controls/ComboBox.h>
#include <vgui_controls/ImagePanel.h>
#include "econ_controls.h"
#include "econ_store.h"
#include "item_model_panel.h"
#include "store_page.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CStorePricePanel_New : public CStorePricePanel
{
public:
DECLARE_CLASS_SIMPLE( CStorePricePanel_New, CStorePricePanel );
CStorePricePanel_New( vgui::Panel *pParent, const char *pPanelName );
virtual const char *GetPanelResFile()
{
return "Resource/UI/econ/store/v1/StorePrice_New.res";
}
virtual void SetItem( const econ_store_entry_t *pEntry );
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CStorePricePanel_Bundles : public CStorePricePanel
{
public:
DECLARE_CLASS_SIMPLE( CStorePricePanel_Bundles, CStorePricePanel );
CStorePricePanel_Bundles( vgui::Panel *pParent, const char *pPanelName );
virtual const char *GetPanelResFile()
{
return "Resource/UI/econ/store/v1/StorePrice_Bundles.res";
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void PerformLayout();
virtual void SetItem( const econ_store_entry_t *pEntry );
private:
vgui::ImagePanel *m_pLimitedLarge;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CStorePricePanel_Jumbo : public CStorePricePanel
{
public:
DECLARE_CLASS_SIMPLE( CStorePricePanel_Jumbo, CStorePricePanel );
CStorePricePanel_Jumbo( vgui::Panel *pParent, const char *pPanelName );
virtual const char *GetPanelResFile()
{
return "Resource/UI/econ/store/v1/StorePrice_Jumbo.res";
}
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CStorePricePanel_Popular : public CStorePricePanel
{
public:
DECLARE_CLASS_SIMPLE( CStorePricePanel_Popular, CStorePricePanel );
CStorePricePanel_Popular( vgui::Panel *pParent, const char *pPanelName, int iPopularityRank );
virtual const char *GetPanelResFile()
{
return "Resource/UI/econ/store/v1/StorePrice_Popular.res";
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void PerformLayout();
virtual void SetItem( const econ_store_entry_t *pEntry );
private:
int m_iPopularityRank;
CExLabel *m_pNewLarge;
};
#endif // STORE_PAGE_NEW_H
File diff suppressed because it is too large Load Diff
+236
View File
@@ -0,0 +1,236 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef STORE_PANEL_H
#define STORE_PANEL_H
#ifdef _WIN32
#pragma once
#endif
#include "vgui_controls/PropertyDialog.h"
#include "econ_ui.h"
#include "GameEventListener.h"
#include "store_page.h"
#include "econ_store.h"
#include "econ_gcmessages.h"
#include "steam/isteamuser.h"
#define MAX_CART_ITEMS 256
#define STOREPANEL_SHOW_UPGRADESTEPS -1
class CStorePage;
// An "item" in the cart.
struct cart_item_t
{
const econ_store_entry_t *pEntry;
int iQuantity;
ECartItemType eType;
item_price_t GetDisplayPrice() const;
};
//-----------------------------------------------------------------------------
// Purpose: The cart that contains items the player is purchasing
//-----------------------------------------------------------------------------
class CStoreCart
{
public:
CStoreCart( void );
void AddToCart( const econ_store_entry_t *pEntry, const char* pszPageName, ECartItemType eCartItemType );
void RemoveFromCart( int iEntryIndex );
void EmptyCart( void );
// Returns the total number of items in the cart
int GetTotalItems( void ) const;
int GetTotalConcreteItems( void ) const;
// Returns the number of different entries in the cart (ignoring quantities)
int GetNumEntries( void ) const { return m_Items.Count(); }
cart_item_t *GetItem( int iIndex ) { return ( ( GetNumEntries() > 0 ) ? &m_Items[iIndex] : NULL ); }
item_price_t GetTotalPrice( void ) const;
bool ContainsHolidayRestrictedItems() const;
bool ContainsItemDefinition( item_definition_index_t unItemDef ) const;
private:
int GetIndexForEntry( const econ_store_entry_t *pEntry, ECartItemType eCartItemType ) const;
private:
CUtlVector<cart_item_t> m_Items;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CStorePanel : public vgui::PropertyDialog, public CGameEventListener
{
DECLARE_CLASS_SIMPLE( CStorePanel, vgui::PropertyDialog );
public:
CStorePanel( Panel *parent );
virtual ~CStorePanel();
#ifdef _DEBUG
void ReAddPage( int iPage );
#endif
// UI Layout
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void PerformLayout( void );
virtual void OnCommand( const char *command );
virtual void ShowPanel( bool bShow );
virtual void OnKeyCodeTyped(vgui::KeyCode code);
virtual void FireGameEvent( IGameEvent *event );
void SetPreventClosure( bool bPrevent ) { m_bPreventClosure = bPrevent; }
void StartAtItemDef( int iItemDef, bool bAddToCart ) { m_iStartItemDef = iItemDef; m_bAddStartItemDefToCart = bAddToCart; };
virtual void OnTick();
// Steam Interaction
STEAM_CALLBACK( CStorePanel, OnMicroTransactionAuthResponse, MicroTxnAuthorizationResponse_t, m_CallbackMicroTransactionAuthResponse );
// GC Management
static bool CheckMessageResult( EPurchaseResult msgResult );
void FinalizeTransaction( void );
virtual void PostTransactionCompleted( void ) { return; }
// Cart Management
CStoreCart *GetCart( void ) { return &m_Cart; }
void ShowStorePanel( void );
bool ShouldUpsellStamps( void );
bool HasValidUpsellStamps( void );
void UpsellStamps( void );
static void ConfirmUpsellStamps( bool bConfirmed, CSchemaItemDefHandle hItemDef, int nSecondsVisible );
void InitiateCheckout( bool bSkipUpsell );
void CheckoutCancel( void );
virtual void OnAddToCart( void ) {}
void AddToCartAndCheckoutImmediately( item_definition_index_t nDefIndex );
// Pricesheet Management
static bool IsPricesheetLoaded( void ) { return CStorePanel::m_bPricesheetLoaded; }
static bool ShouldShowWarnings( void ) { return CStorePanel::m_bShowWarnings; }
static void SetShouldShowWarnings( bool bShow ) { CStorePanel::m_bShowWarnings = bShow; }
static void RequestPricesheet( void );
const CEconStorePriceSheet *GetPriceSheet( void ) { return &m_StoreSheet; }
CEconStorePriceSheet *GetPriceSheetForEdit( void ) { return &m_StoreSheet; }
bool LoadPricesheet( KeyValuesAD* pKVPricesheet );
void SetCurrency( ECurrency in_currency );
ECurrency GetCurrency( void ) { return m_eCurrency; }
void SetCountryCode( const char* in_country );
char* GetCountryCode( void ) { return m_rgchCountry; }
const econ_store_entry_t *GetFeaturedEntry( void );
void SetMostRecentSuccessfulTransactionID( uint64 inID ) { m_unMostRecentSuccessfulTransaction = inID; }
uint64 GetMostRecentSuccessfulTransactionID() const { return m_unMostRecentSuccessfulTransaction; }
virtual void SetTransactionID( uint64 inID ) { m_unTransactionID = inID; }
uint64 GetTransactionID( void ) { return m_unTransactionID; }
int GetCheckoutAttempts() { return m_iCheckoutAttempts; }
void SetLastPurchaseAttemptPrice( int totalPrice ) { m_iLastPurchaseAttemptPrice = totalPrice; }
int GetLastPurchaseAttemptPrice() { return m_iLastPurchaseAttemptPrice; }
void ClearPopularItems( void ) { m_vPopularItems.Purge(); }
void AddPopularItem( uint32 iItemDef ) { m_vPopularItems.AddToTail(iItemDef); }
const CUtlVector<uint32>& GetPopularItems( void ) const { return m_vPopularItems; }
MESSAGE_FUNC( OnStartShopping, "StartShopping" );
MESSAGE_FUNC( OnFindAndSelectFeaturedItem, "FindAndSelectFeaturedItem" );
MESSAGE_FUNC_PARAMS( OnItemLinkClicked, "URLClicked", pParams );
MESSAGE_FUNC_PARAMS( OnJumpToItem, "JumpToItem", pParams );
MESSAGE_FUNC( DoCheckout, "DoCheckout" );
protected:
void ParseStoreKV( void );
CStorePage *AddPageFromPriceSheet( int iPage );
void FindAndSelectEntry( const econ_store_entry_t *pEntry );
const econ_store_entry_t *FindEntryForItemDef( int iItemDef ) { return m_StoreSheet.GetEntry( iItemDef ); }
virtual CStorePage *CreateStorePage( const CEconStoreCategoryManager::StoreCategory_t *pPageData );
bool ShouldShowDx8PurchaseWarning( ) const;
protected:
static void ConfirmCheckout( bool bConfirmed, void *pContext );
static bool m_bPricesheetLoaded;
static bool m_bShowWarnings;
bool m_bPreventClosure;
int m_iStartItemDef;
bool m_bAddStartItemDefToCart;
CStoreCart m_Cart;
CEconStorePriceSheet m_StoreSheet;
ECurrency m_eCurrency;
char m_rgchCountry[3]; // This will change to an enum soon.
uint64 m_unTransactionID;
uint64 m_unMostRecentSuccessfulTransaction;
bool m_bShouldFinalize;
bool m_bOGSLogging;
int m_iCheckoutAttempts;
int m_iLastPurchaseAttemptPrice;
CUtlVector<uint32> m_vPopularItems;
};
void OpenStoreStatusDialog( vgui::Panel *pParent, const char *pszText, bool bAllowClose, bool bShowOnExit, bool bCancel=false );
void CloseStoreStatusDialog( void );
//-----------------------------------------------------------------------------
// Purpose: Asynchronous job for getting the price sheet from the GC
//-----------------------------------------------------------------------------
class CGCClientJobGetUserData : public GCSDK::CGCClientJob
{
public:
CGCClientJobGetUserData( GCSDK::CGCClient *pGCClient, RTime32 rTimeVersion ) : GCSDK::CGCClientJob( pGCClient ), m_RTimeVersion( rTimeVersion ) {}
virtual bool BYieldingRunJob( void *pvStartParam );
private:
RTime32 m_RTimeVersion;
};
//-----------------------------------------------------------------------------
// Purpose: Asynchronous job for initiating a checkout from the Steam store.
//-----------------------------------------------------------------------------
class CGCClientJobInitPurchase : public GCSDK::CGCClientJob
{
public:
CGCClientJobInitPurchase( GCSDK::CGCClient *pGCClient ) : GCSDK::CGCClientJob( pGCClient ) {}
virtual bool BYieldingRunJob( void *pvStartParam );
};
//-----------------------------------------------------------------------------
// Purpose: Asynchronous job for canceling a purchase in progress.
//-----------------------------------------------------------------------------
class CGCClientJobCancelPurchase : public GCSDK::CGCClientJob
{
public:
CGCClientJobCancelPurchase( GCSDK::CGCClient *pGCClient, uint64 ulTxnID ) : GCSDK::CGCClientJob( pGCClient ), m_ulTxnID( ulTxnID ) {}
virtual bool BYieldingRunJob( void *pvStartParam );
private:
uint64 m_ulTxnID;
};
//-----------------------------------------------------------------------------
// Purpose: Asynchronous job for finalizing a purchase with the GC.
//-----------------------------------------------------------------------------
class CGCClientJobFinalizePurchase : public GCSDK::CGCClientJob
{
public:
CGCClientJobFinalizePurchase( GCSDK::CGCClient *pGCClient, uint64 ulTxnID ) : GCSDK::CGCClientJob( pGCClient ), m_ulTxnID( ulTxnID ) {}
virtual bool BYieldingRunJob( void *pvStartParam );
private:
uint64 m_ulTxnID;
};
#endif // STORE_PANEL_H
@@ -0,0 +1,418 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "store_page.h"
#include "vgui/ISurface.h"
#include "vgui/IInput.h"
#include "vgui/ILocalize.h"
#include "gamestringpool.h"
#include "econ_item_inventory.h"
#include "econ_item_system.h"
#include "store_preview_item.h"
#include "item_model_panel.h"
#include "econ_ui.h"
#include "store/store_panel.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
DECLARE_BUILD_FACTORY_DEFAULT_TEXT( CPreviewRotButton, CPreviewRotButton );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStorePreviewItemPanel::CStorePreviewItemPanel( vgui::Panel *pParent, const char *pResFile, const char *pPanelName, CStorePage *pOwner )
: EditablePanel( pParent, "storepreviewitem" )
{
m_pOwner = pOwner;
m_pResFile = pResFile != NULL ? pResFile : ( ShouldUseNewStore() ? "Resource/UI/econ/store/v2/StorePreviewItemPanel.res" : "Resource/UI/econ/store/v1/StorePreviewItemPanel.res" );
m_pDataTextRichText = NULL;
m_iCurrentIconPosition = 0;
m_iState = PS_ITEM;
m_pIconsMoveLeftButton = NULL;
m_pIconsMoveRightButton = NULL;
m_pItemFullImage = new CItemModelPanel( this, "PreviewItemModelPanel" );
SetDialogVariable("selectiontitle", g_pVGuiLocalize->Find("#TF_NoSelection") );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStorePreviewItemPanel::~CStorePreviewItemPanel()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePreviewItemPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
LoadControlSettings( m_pResFile );
// Apply attribute changes to CItemModelPanel
m_pItemFullImage->UpdatePanels();
m_pIconsMoveLeftButton = dynamic_cast<CExButton*>( FindChildByName("IconsMoveLeftButton") );
if ( m_pIconsMoveLeftButton )
{
m_pIconsMoveLeftButton->AddActionSignalTarget( this );
}
m_pIconsMoveRightButton = dynamic_cast<CExButton*>( FindChildByName("IconsMoveRightButton") );
if ( m_pIconsMoveRightButton )
{
m_pIconsMoveRightButton->AddActionSignalTarget( this );
}
m_pDataTextRichText = dynamic_cast<CEconItemDetailsRichText*>( FindChildByName( "DetailsRichText" ) );
if ( m_pDataTextRichText )
{
m_pDataTextRichText->SetURLClickedHandler( EconUI()->GetStorePanel() );
m_pDataTextRichText->AllowItemSetLinks( true );
}
// Then find all our item icons
m_pItemIcons.Purge();
CStorePreviewItemIcon *pItemIcon = NULL;
int iIcon = 1;
do
{
pItemIcon = dynamic_cast<CStorePreviewItemIcon*>( FindChildByName( VarArgs("ItemIcon%d",iIcon)) );
if ( pItemIcon )
{
m_pItemIcons.AddToTail( pItemIcon );
if ( m_pOwner )
{
pItemIcon->GetItemPanel()->SetTooltip( m_pOwner->GetItemTooltip(), "" );
}
}
iIcon++;
} while ( pItemIcon );
// Update our item icons. Hide them all first. The code below will unhide ones used.
for ( int i = 0; i < m_pItemIcons.Count(); i++ )
{
m_pItemIcons[i]->SetVisible( false );
}
// Start with the item itself showing
SetState( PS_ITEM );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePreviewItemPanel::PerformLayout( void )
{
BaseClass::PerformLayout();
// center the icons
int iNumItemIcons = 0;
FOR_EACH_VEC( m_pItemIcons, i )
{
if ( m_pItemIcons[i]->IsVisible() )
{
++iNumItemIcons;
}
}
if ( iNumItemIcons )
{
int iCenterX = GetWide() / 2;
int interval = XRES(2);
int totalWidth = (iNumItemIcons * m_pItemIcons[0]->GetWide()) + (interval * (iNumItemIcons - 1));
int iX = iCenterX - ( totalWidth / 2 );
int posX, posY;
m_pItemIcons[0]->GetPos( posX, posY );
int iButton = 0;
for ( int i = 0; i < m_pItemIcons.Count(); i++ )
{
if ( m_pItemIcons[i]->IsVisible() )
{
m_pItemIcons[i]->SetPos( iX, posY );
iX += m_pItemIcons[i]->GetWide() + interval;
iButton++;
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePreviewItemPanel::OnCommand( const char *command )
{
if ( !Q_strnicmp( command, "close", 5 ) )
{
PostActionSignal(new KeyValues("HidePreview"));
SetVisible( false );
return;
}
else if ( !Q_stricmp( command, "icons_left" ) )
{
m_iCurrentIconPosition = MAX( m_iCurrentIconPosition - 1, 0 );
UpdateIcons();
}
else if ( !Q_stricmp( command, "icons_right" ) )
{
// It's only visible if we can still move right.
m_iCurrentIconPosition++;
UpdateIcons();
}
else
{
engine->ClientCmd( const_cast<char *>( command ) );
}
BaseClass::OnCommand( command );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePreviewItemPanel::OnRotButtonDown( KeyValues *data )
{
int iRotDelta = data->GetInt( "rot", 0 );
m_iCurrentRotation = iRotDelta;
vgui::ivgui()->AddTickSignal( GetVPanel(), 33 );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePreviewItemPanel::OnRotButtonUp( void )
{
m_iCurrentRotation = 0;
vgui::ivgui()->RemoveTickSignal( GetVPanel() );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePreviewItemPanel::PreviewItem( int iClass, CEconItemView *pItem, const econ_store_entry_t* pEntry /*= NULL*/ )
{
m_iCurrentIconPosition = 0;
m_item = *pItem;
if ( m_item.IsValid() )
{
m_pItemFullImage->SetItem( &m_item );
if ( m_pDataTextRichText )
{
m_pDataTextRichText->SetLimitedItem( pEntry && pEntry->m_bLimited );
m_pDataTextRichText->UpdateDetailsForItem( m_item.GetItemDefinition() );
}
SetDialogVariable("selectiontitle", m_item.GetItemName() );
CExButton *pButton = dynamic_cast<CExButton*>( FindChildByName( "AddToCartButton" ) );
if ( pButton )
{
const CEconStorePriceSheet *pPriceSheet = EconUI()->GetStorePanel()->GetPriceSheet();
if ( pPriceSheet )
{
const econ_store_entry_t *pStoreEntry = pPriceSheet->GetEntry( pItem->GetItemDefIndex() );
if ( pStoreEntry->m_bIsMarketItem )
{
SetDialogVariable( "storeaddtocart", g_pVGuiLocalize->Find( "#Store_ViewMarket" ) );
}
else
{
SetDialogVariable( "storeaddtocart", g_pVGuiLocalize->Find( "#Store_AddToCart" ) );
}
}
}
}
InvalidateLayout();
UpdateIcons();
if ( m_iState == PS_PLAYER )
{
SetState( PS_ITEM );
}
Panel *pAddToCart = FindChildByName( "AddToCartButton" );
if ( pAddToCart )
{
pAddToCart->RequestFocus();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePreviewItemPanel::SetState( preview_state_t iState )
{
// Only reset the position when moving from to items/details
if ( iState == PS_DETAILS || iState == PS_ITEM )
{
m_iCurrentIconPosition = 0;
}
m_iState = iState;
if ( m_pDataTextRichText )
{
m_pDataTextRichText->SetVisible( m_iState == PS_DETAILS );
}
m_pItemFullImage->SetVisible( m_iState == PS_ITEM );
UpdateIcons();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePreviewItemPanel::UpdateIcons( void )
{
bool bAdditionalIcons = false;
// Do the item icons first
if ( m_iState == PS_DETAILS )
{
// Show as many of the items in the bundle as possible
const CEconItemDefinition *pItemData = m_item.GetItemDefinition();
if ( pItemData )
{
const bundleinfo_t *pBundleInfo = pItemData->GetBundleInfo();
if ( pBundleInfo )
{
FOR_EACH_VEC( m_pItemIcons, i )
{
// If we haven't scrolled, the first item is the bundle itself
if ( m_iCurrentIconPosition == 0 && i == 0 )
{
m_pItemIcons[0]->SetItem( 0, &m_item );
continue;
}
int iItemPos = (i - 1 + m_iCurrentIconPosition);
if ( pBundleInfo->vecItemDefs.Count() > iItemPos && pBundleInfo->vecItemDefs[iItemPos] )
{
m_pItemIcons[i]->SetItem( i, pBundleInfo->vecItemDefs[iItemPos]->GetDefinitionIndex() );
m_pItemIcons[i]->SetVisible( true );
}
else
{
m_pItemIcons[i]->SetVisible( false );
}
}
bAdditionalIcons = (m_iCurrentIconPosition + m_pItemIcons.Count()) <= pBundleInfo->vecItemDefs.Count();
}
else if ( m_pItemIcons.Count() > 0 )
{
m_pItemIcons[0]->SetVisible( true );
m_pItemIcons[0]->SetItem( 0, &m_item );
FOR_EACH_VEC( m_pItemIcons, i )
{
if ( i != 0 )
{
m_pItemIcons[i]->SetVisible( false );
}
}
}
}
}
else
{
// Hide all item icons first (but not the first if we haven't scrolled)
FOR_EACH_VEC( m_pItemIcons, i )
{
m_pItemIcons[i]->SetVisible( m_iCurrentIconPosition == 0 && i == 0 );
}
// First icon is always the store entry (item/bundle), if we haven't scrolled right
if ( m_iCurrentIconPosition == 0 && m_pItemIcons.Count() )
{
m_pItemIcons[0]->SetItem( 0, &m_item );
}
}
if( m_pIconsMoveLeftButton )
m_pIconsMoveLeftButton->SetVisible( (m_iCurrentIconPosition > 0) );
if( m_pIconsMoveRightButton )
m_pIconsMoveRightButton->SetVisible( bAdditionalIcons );
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePreviewItemPanel::OnTick( void )
{
BaseClass::OnTick();
if ( !IsVisible() )
{
vgui::ivgui()->RemoveTickSignal( GetVPanel() );
return;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStorePreviewItemPanel::OnItemIconSelected( KeyValues *data )
{
if ( m_iState == PS_DETAILS )
{
int iIcon = data->GetInt( "icon", 0 );
CEconItemView *pItem = m_pItemIcons[iIcon]->GetItemPanel()->GetItem();
if ( pItem )
{
if ( m_pDataTextRichText )
{
m_pDataTextRichText->UpdateDetailsForItem( pItem->GetStaticData() );
}
SetDialogVariable("selectiontitle", pItem->GetItemName() );
}
}
else
{
SetState( PS_ITEM );
}
}
//================================================================================================================
// PREVIEW ROT BUTTON
//================================================================================================================
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPreviewRotButton::OnMousePressed(vgui::MouseCode code)
{
BaseClass::OnMousePressed( code );
if ( IsSelected() )
{
KeyValues *pCommand = GetCommand();
PostActionSignal(new KeyValues("RotButtonDown", "rot", pCommand->GetString("command", "0") ));
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPreviewRotButton::OnMouseReleased(vgui::MouseCode code)
{
if ( IsSelected() )
{
PostActionSignal(new KeyValues("RotButtonUp"));
}
BaseClass::OnMouseReleased( code );
}
+100
View File
@@ -0,0 +1,100 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef STORE_PREVIEW_ITEM_H
#define STORE_PREVIEW_ITEM_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Panel.h>
#include "econ_controls.h"
#include "store_page.h"
enum preview_state_t
{
PS_ITEM,
PS_PLAYER,
PS_DETAILS,
};
//-----------------------------------------------------------------------------
// Purpose: Button that handles the rotation of the preview model.
//-----------------------------------------------------------------------------
class CPreviewRotButton : public CExButton
{
DECLARE_CLASS_SIMPLE( CPreviewRotButton, CExButton );
public:
CPreviewRotButton( vgui::Panel *parent, const char *name, const char *text, vgui::Panel *pActionSignalTarget = NULL, const char *cmd = NULL ) :
CExButton( parent, name, text, pActionSignalTarget, cmd )
{
}
CPreviewRotButton( vgui::Panel *parent, const char *name, const wchar_t *wszText, vgui::Panel *pActionSignalTarget = NULL, const char *cmd = NULL ) :
CExButton( parent, name, wszText, pActionSignalTarget, cmd )
{
}
virtual void OnMousePressed(vgui::MouseCode code);
virtual void OnMouseReleased(vgui::MouseCode code);
// Our fire action signal does nothing, because it's all done in mouse pressed/released
virtual void FireActionSignal( void ) { return; }
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CStorePreviewItemPanel : public vgui::EditablePanel
{
DECLARE_CLASS_SIMPLE( CStorePreviewItemPanel, vgui::EditablePanel );
public:
CStorePreviewItemPanel( vgui::Panel *pParent, const char *pResFile, const char *pPanelName, CStorePage *pOwner );
virtual ~CStorePreviewItemPanel();
CStorePage *GetOwningStorePage() { return m_pOwner; }
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void OnCommand( const char *command );
virtual void PerformLayout( void );
virtual void OnTick( void );
virtual void PreviewItem( int iClass, CEconItemView *pItem, const econ_store_entry_t* pEntry=NULL );
virtual void SetState( preview_state_t iState );
// Subclass interface.
virtual int GetPreviewTeam() const { return 0; }
MESSAGE_FUNC_PARAMS( OnRotButtonDown, "RotButtonDown", data );
MESSAGE_FUNC( OnRotButtonUp, "RotButtonUp" );
MESSAGE_FUNC_PARAMS( OnItemIconSelected, "ItemIconSelected", data );
protected:
virtual void UpdateIcons( void );
protected:
const char *m_pResFile;
CUtlVector<CStorePreviewItemIcon*> m_pItemIcons;
int m_iCurrentIconPosition;
CEconItemDetailsRichText *m_pDataTextRichText;
CItemModelPanel *m_pItemFullImage;
CEconItemView m_item;
preview_state_t m_iState;
int m_iCurrentRotation;
CExButton *m_pIconsMoveLeftButton;
CExButton *m_pIconsMoveRightButton;
CStorePage *m_pOwner;
};
#endif // STORE_PREVIEW_ITEM_H
+387
View File
@@ -0,0 +1,387 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "store_viewcart.h"
#include "vgui/IInput.h"
#include "baseviewport.h"
#include "iclientmode.h"
#include "ienginevgui.h"
#include "econ_item_inventory.h"
#include <vgui/ILocalize.h>
#include "econ_item_system.h"
#include "item_model_panel.h"
#include "vgui_controls/ScrollBarSlider.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
DECLARE_BUILD_FACTORY( CCartViewItemEntry );
//-----------------------------------------------------------------------------
// Purpose: Basic help dialog
//-----------------------------------------------------------------------------
CStoreViewCartPanel::CStoreViewCartPanel( Panel *parent ) : Frame(parent, "store_viewcart_panel")
{
// Store is parented to the game UI panel
vgui::VPANEL gameuiPanel = enginevgui->GetPanel( PANEL_GAMEUIDLL );
SetParent( gameuiPanel );
// We don't want the gameui to delete us, or things get messy
SetAutoDelete( false );
SetMoveable( false );
SetSizeable( false );
vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
SetScheme(scheme);
SetProportional( true );
ListenForGameEvent( "gameui_hidden" );
ListenForGameEvent( "cart_updated" );
m_pItemEntryKVs = NULL;
m_pClientArea = new EditablePanel(this, "ClientArea");
m_pItemListContainer = new vgui::EditablePanel( this, "ItemListContainer" );
m_pItemListContainerScroller = new vgui::ScrollableEditablePanel( m_pClientArea, m_pItemListContainer, "ItemListContainerScroller" );
m_pPurchaseFooter = new EditablePanel(m_pItemListContainer, "PurchaseFooter");
m_pEmptyCartLabel = NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStoreViewCartPanel::~CStoreViewCartPanel()
{
if ( m_pItemEntryKVs )
{
m_pItemEntryKVs->deleteThis();
m_pItemEntryKVs = NULL;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStoreViewCartPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
LoadControlSettings( ShouldUseNewStore() ? "Resource/UI/econ/store/v2/StoreViewCartPanel.res" : "Resource/UI/econ/store/v1/StoreViewCartPanel.res" );
m_bReapplyItemKVs = true;
m_pItemListContainerScroller->GetScrollbar()->SetAutohideButtons( true );
m_pEmptyCartLabel = dynamic_cast<vgui::Label*>( m_pClientArea->FindChildByName("EmptyCartLabel") );
m_pFeaturedItemImage = dynamic_cast<vgui::ImagePanel*>( m_pItemListContainer->FindChildByName("FeaturedItemSymbol") );
if ( m_pFeaturedItemImage )
{
m_pFeaturedItemImage->SetMouseInputEnabled( false );
m_pFeaturedItemImage->SetKeyBoardInputEnabled( false );
}
CExButton *pCheckoutButton = dynamic_cast<CExButton*>( m_pClientArea->FindChildByName("CheckoutButton") );
if ( pCheckoutButton )
{
pCheckoutButton->AddActionSignalTarget( this );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStoreViewCartPanel::ApplySettings( KeyValues *inResourceData )
{
BaseClass::ApplySettings( inResourceData );
KeyValues *pItemKV = inResourceData->FindKey( "item_entry_kv" );
if ( pItemKV )
{
if ( m_pItemEntryKVs )
{
m_pItemEntryKVs->deleteThis();
}
m_pItemEntryKVs = new KeyValues("item_entry_kv");
pItemKV->CopySubkeys( m_pItemEntryKVs );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStoreViewCartPanel::PerformLayout( void )
{
if ( GetVParent() )
{
int w,h;
vgui::ipanel()->GetSize( GetVParent(), w, h );
SetBounds(0,0,w,h);
}
if ( m_bReapplyItemKVs )
{
m_bReapplyItemKVs = false;
if ( m_pItemEntryKVs )
{
FOR_EACH_VEC( m_pItemEntries, i )
{
m_pItemEntries[i]->ApplySettings( m_pItemEntryKVs );
m_pItemEntries[i]->InvalidateLayout();
}
}
}
BaseClass::PerformLayout();
if ( m_pItemEntries.Count() )
{
int iTall = m_pItemEntries[0]->GetTall();
m_pItemListContainer->SetSize( m_pItemListContainer->GetWide(), (iTall * m_pItemEntries.Count()) + m_pPurchaseFooter->GetTall() );
m_pItemListContainerScroller->InvalidateLayout( true );
m_pItemListContainerScroller->GetScrollbar()->InvalidateLayout( true );
int iX,iY;
m_pItemEntries[0]->GetPos( iX, iY );
FOR_EACH_VEC( m_pItemEntries, i )
{
iY = (iTall * i);
m_pItemEntries[i]->SetPos( iX, iY );
}
m_pPurchaseFooter->SetVisible( true );
m_pPurchaseFooter->SetPos( 0, iTall * m_pItemEntries.Count() );
}
else
{
m_pItemListContainer->SetSize( m_pItemListContainer->GetWide(), 100 );
m_pItemListContainer->InvalidateLayout( true );
m_pItemListContainerScroller->InvalidateLayout( true );
m_pPurchaseFooter->SetVisible( false );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStoreViewCartPanel::ShowPanel(bool bShow)
{
if ( bShow )
{
InvalidateLayout( false, true );
Activate();
CExButton *pCloseButton = dynamic_cast<CExButton*>( FindChildByName("CloseButton") );
if ( pCloseButton )
{
pCloseButton->RequestFocus();
}
// don't display the WA sales tax outside of the US
vgui::Panel *pPanel = FindChildByName( "WashingtonStateSalesTaxLabel", true );
if ( pPanel )
{
pPanel->SetVisible( FStrEq( EconUI()->GetStorePanel()->GetCountryCode(), "US" ) == true );
}
}
SetVisible( bShow );
if ( bShow )
{
UpdateCartItemList();
m_pItemListContainerScroller->GetScrollbar()->SetValue( 0 );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStoreViewCartPanel::FireGameEvent( IGameEvent *event )
{
const char * type = event->GetName();
if ( Q_strcmp(type, "gameui_hidden") == 0 )
{
ShowPanel( false );
}
else if ( Q_strcmp(type, "cart_updated") == 0 )
{
UpdateCartItemList();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStoreViewCartPanel::UpdateCartItemList( void )
{
CStoreCart *pCart = EconUI()->GetStorePanel()->GetCart();
int iNumEntriesInCart = pCart->GetNumEntries();
// Update the item count
wchar_t wszCount[16];
_snwprintf( wszCount, ARRAYSIZE( wszCount ), L"%d", pCart->GetTotalItems() );
wchar_t wzLocalized[32];
g_pVGuiLocalize->ConstructString_safe( wzLocalized, g_pVGuiLocalize->Find( "#Store_CartItems" ), 1, wszCount );
m_pClientArea->SetDialogVariable("storecart", wzLocalized );
// Create / Update all the item entries
if ( m_pItemEntries.Count() < iNumEntriesInCart )
{
for ( int i = m_pItemEntries.Count(); i < iNumEntriesInCart; i++ )
{
CCartViewItemEntry *pPanel = vgui::SETUP_PANEL( new CCartViewItemEntry( m_pItemListContainer, VarArgs("itementry%d", i) ) );
pPanel->ApplySettings( m_pItemEntryKVs );
m_pItemEntries.AddToTail( pPanel );
}
}
else
{
for ( int i = m_pItemEntries.Count()-1; i >= iNumEntriesInCart; i-- )
{
m_pItemEntries[i]->MarkForDeletion();
m_pItemEntries.Remove( i );
}
}
if ( m_pEmptyCartLabel )
{
m_pEmptyCartLabel->SetVisible( iNumEntriesInCart == 0 );
}
InvalidateLayout( true );
if ( !iNumEntriesInCart )
return;
bool bFeaturedImagePanelVisible = false;
// Set all the entries up
FOR_EACH_VEC( m_pItemEntries, i )
{
if ( i >= iNumEntriesInCart )
{
m_pItemEntries[i]->SetVisible( false );
continue;
}
cart_item_t *pCartItem = pCart->GetItem(i);
m_pItemEntries[i]->SetEntry( pCartItem, i );
m_pItemEntries[i]->SetVisible( true );
// If we're the featured item, show it
if ( pCartItem && pCartItem->pEntry == EconUI()->GetStorePanel()->GetFeaturedEntry() )
{
bFeaturedImagePanelVisible = true;
int iX, iY;
m_pItemEntries[i]->GetPos( iX, iY );
m_pFeaturedItemImage->SetPos( iX, iY + m_pItemEntries[i]->GetTall() - m_pFeaturedItemImage->GetTall() );
}
}
if ( m_pFeaturedItemImage->IsVisible() != bFeaturedImagePanelVisible )
{
m_pFeaturedItemImage->SetVisible( bFeaturedImagePanelVisible );
}
// Update total price
item_price_t unTotalPrice = pCart->GetTotalPrice();
wchar_t wzLocalizedPrice[ kLocalizedPriceSizeInChararacters ];
MakeMoneyString( wzLocalizedPrice, ARRAYSIZE( wzLocalizedPrice ), unTotalPrice, EconUI()->GetStorePanel()->GetCurrency() );
m_pPurchaseFooter->SetDialogVariable( "totalprice", wzLocalizedPrice );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CStoreViewCartPanel::OnCommand( const char *command )
{
if ( !Q_stricmp( command, "close" ) )
{
ShowPanel( false );
}
else if ( !Q_strnicmp( command, "remove", 6 ) )
{
int iIndex = atoi(command+6);
if ( iIndex >= 0 && iIndex < m_pItemEntries.Count() )
{
CStoreCart *pCart = EconUI()->GetStorePanel()->GetCart();
pCart->RemoveFromCart( iIndex );
}
return;
}
else if ( !Q_stricmp( command, "checkout" ) )
{
EconUI()->GetStorePanel()->InitiateCheckout( false );
}
else
{
engine->ClientCmd( const_cast<char *>( command ) );
}
BaseClass::OnCommand( command );
}
static vgui::DHANDLE<CStoreViewCartPanel> g_StoreViewCartPanel;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStoreViewCartPanel *OpenStoreViewCartPanel( void )
{
if (!g_StoreViewCartPanel.Get())
{
g_StoreViewCartPanel = vgui::SETUP_PANEL( new CStoreViewCartPanel( NULL ) );
g_StoreViewCartPanel->InvalidateLayout( false, true );
}
engine->ClientCmd_Unrestricted( "gameui_activate" );
g_StoreViewCartPanel->ShowPanel( true );
return g_StoreViewCartPanel;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CStoreViewCartPanel *GetStoreViewCartPanel( void )
{
return g_StoreViewCartPanel.Get();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCartViewItemEntry::SetEntry( cart_item_t *pEntry, int iEntryIndex )
{
m_pEntry = pEntry;
SetDialogVariable( "quantity", pEntry->iQuantity );
int iSubTotal = pEntry->GetDisplayPrice();
wchar_t wzLocalizedPrice[ kLocalizedPriceSizeInChararacters ];
MakeMoneyString( wzLocalizedPrice, ARRAYSIZE( wzLocalizedPrice ), iSubTotal, EconUI()->GetStorePanel()->GetCurrency() );
SetDialogVariable("price", wzLocalizedPrice );
CItemModelPanel *pItemPanel = dynamic_cast<CItemModelPanel*>( FindChildByName("itempanel") );
if ( pItemPanel )
{
CEconItemView ItemData;
ItemData.Init( pEntry->pEntry->GetItemDefinitionIndex(), AE_UNIQUE, AE_USE_SCRIPT_VALUE, true );
pItemPanel->SetItem( &ItemData );
}
CExButton *pRemoveButton = dynamic_cast<CExButton*>( FindChildByName("RemoveButton") );
if ( pRemoveButton )
{
pRemoveButton->SetCommand( VarArgs("remove%d",iEntryIndex) );
pRemoveButton->AddActionSignalTarget( GetStoreViewCartPanel() );
}
}
+75
View File
@@ -0,0 +1,75 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef STORE_VIEWCART_H
#define STORE_VIEWCART_H
#ifdef _WIN32
#pragma once
#endif
#include "vgui_controls/Frame.h"
#include "vgui_controls/ScrollableEditablePanel.h"
#include "GameEventListener.h"
#include "store/store_panel.h"
//-----------------------------------------------------------------------------
// Purpose: Shows a single item in the cart
//-----------------------------------------------------------------------------
class CCartViewItemEntry : public vgui::EditablePanel
{
DECLARE_CLASS_SIMPLE( CCartViewItemEntry, vgui::EditablePanel );
public:
CCartViewItemEntry( vgui::Panel *parent, const char *name ) : vgui::EditablePanel(parent,name)
{
m_pEntry = NULL;
}
void SetEntry( cart_item_t *pEntry, int iEntryIndex );
cart_item_t *GetEntry( void ) { return m_pEntry; }
private:
cart_item_t *m_pEntry;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CStoreViewCartPanel : public vgui::Frame, public CGameEventListener
{
DECLARE_CLASS_SIMPLE( CStoreViewCartPanel, vgui::Frame );
public:
CStoreViewCartPanel( Panel *parent );
virtual ~CStoreViewCartPanel();
virtual void ApplySettings( KeyValues *inResourceData );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void PerformLayout( void );
virtual void OnCommand( const char *command );
virtual void ShowPanel( bool bShow );
virtual void FireGameEvent( IGameEvent *event );
void UpdateCartItemList( void );
private:
vgui::EditablePanel *m_pClientArea;
vgui::EditablePanel *m_pPurchaseFooter;
KeyValues *m_pItemEntryKVs;
bool m_bReapplyItemKVs;
vgui::Label *m_pEmptyCartLabel;
vgui::ImagePanel *m_pFeaturedItemImage;
vgui::EditablePanel *m_pItemListContainer;
vgui::ScrollableEditablePanel *m_pItemListContainerScroller;
CUtlVector<CCartViewItemEntry*> m_pItemEntries;
CPanelAnimationVar( int, m_iSheetInsetBottom, "sheetinset_bottom", "32" );
};
CStoreViewCartPanel *OpenStoreViewCartPanel( void );
CStoreViewCartPanel *GetStoreViewCartPanel( void );
#endif // STORE_VIEWCART_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,83 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef CUSTOM_TEXTURE_CACHE_H
#define CUSTOM_TEXTURE_CACHE_H
#ifdef _WIN32
#pragma once
#endif
#ifndef GC_CLIENTSYSTEM_H
#include "gc_clientsystem.h"
#endif
class IGameSystem;
class ITexture;
class CEconItemView;
/// Given a UGC cloud ID of a custom image, return a VGUI texture handle
/// that can be used for drawing. Returns 0 on failure
int GetCustomTextureGuiHandle( uint64 hCloudId );
//-----------------------------------------------------------------------------
// Purpose: Job to do the async work of uploading the file to the CDN (if
// necessary) and sending the tool request message
//-----------------------------------------------------------------------------
class CApplyCustomTextureJob : public GCSDK::CGCClientJob
{
public:
CApplyCustomTextureJob( itemid_t nToolItemID, itemid_t nSubjectItemID, const void *pPNGData, int nPNGDataBytes );
protected:
char m_chRemoteStorageName[ MAX_PATH ];
virtual bool BYieldingRunGCJob();
virtual EResult YieldingRunJob();
virtual EResult YieldingFindFileIncacheOrUploadFileToCDN();
virtual EResult YieldingApplyTool();
/// The file data, in PNG format
CUtlBuffer m_bufPNGData;
/// Item that we are applying the texture onto
itemid_t m_nSubjectItemID;
/// Tool that is being applied and will be consumed
itemid_t m_nToolItemID;
/// Cloud file ID
uint64 m_hCloudID;
private:
void CleanUp();
};
/// get interface to the game system responsible for managing the custom texture cache
IGameSystem *CustomTextureToolCacheGameSystem();
/// A few internal things that really shouldn't be public
namespace CustomTextureSystem
{
/// If we're auditioning (while selecting a file to apply on a model),
/// what texture should we display?
extern ITexture *g_pPreviewCustomTexture;
/// What is the econ item that is being auditioned and so should
/// use the preview texture
extern CEconItemView *g_pPreviewEconItem;
/// Do we need to update the bits in the rendering system?
extern bool g_pPreviewCustomTextureDirty;
extern const char k_rchCustomTextureFilterPreviewImageName[];
extern const char k_rchCustomTextureFilterPreviewTextureName[];
}
#endif // CUSTOM_TEXTURE_CACHE_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,213 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "vgui_controls/EditablePanel.h"
#include "vgui_controls/TextEntry.h"
#include "vgui/IInput.h"
#include "econ_item_system.h"
#include "econ_item_constants.h"
#include "econ_gcmessages.h"
#include "econ_item_inventory.h"
#include "econ_item_tools.h"
#include "tool_items.h"
#include "decoder_ring_tool.h"
#include "vgui/ISurface.h"
#include "econ_controls.h"
#include "econ_ui.h"
#include "gc_clientsystem.h"
#include "collection_crafting_panel.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
enum
{
CRATETYPE_NORMAL = 0,
CRATETYPE_ROBO = 1,
};
#define ROBOCRATE_UNLOCKING_SND "/mvm/mvm_tank_deploy.wav"
#define ROBOCRATE_OPENED_SND "/mvm/mvm_tank_explode.wav"
static int s_iCrateType = CRATETYPE_NORMAL;
//-----------------------------------------------------------------------------
// Purpose: Confirm / abort tool application
//-----------------------------------------------------------------------------
class CConfirmDecodeDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmDecodeDialog, CBaseToolUsageDialog );
public:
CConfirmDecodeDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject );
virtual void ApplySchemeSettings( vgui::IScheme *scheme );
virtual void Apply( void );
virtual void OnCommand( const char *command );
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CConfirmDecodeDialog::CConfirmDecodeDialog( vgui::Panel *parent, CEconItemView *pTool, CEconItemView *pToolSubject ) : CBaseToolUsageDialog( parent, "ConfirmApplyDecodeDialog", pTool, pToolSubject )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmDecodeDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmApplyDecodeDialog.res" );
const CEconItemView* pCrate = m_pSubjectModelPanel->GetItem();
s_iCrateType = CRATETYPE_NORMAL;
// Check Crate Type
if ( pCrate )
{
if ( pCrate->GetItemDefIndex() == 5635 ) // Robo Crate items_tools_crafting
{
s_iCrateType = CRATETYPE_ROBO;
}
}
if ( V_strstr( pCrate->GetItemDefinition()->GetDefinitionName(), "Case" ) )
{
SetDialogVariable( "confirm_text", GLocalizationProvider()->Find("#ToolDecodeConfirmCase") );
}
else
{
SetDialogVariable( "confirm_text", GLocalizationProvider()->Find("#ToolDecodeConfirm") );
}
const locchar_t *loc_Append = NULL;
if ( pCrate && pCrate->GetItemDefinition() && pCrate->GetItemDefinition()->GetHolidayRestriction() )
{
loc_Append = GLocalizationProvider()->Find( "#ToolDecodeConfirm_OptionalAppend_RestrictedContents" );
}
if ( !loc_Append )
{
loc_Append = LOCCHAR( "" );
}
SetDialogVariable( "optional_append", loc_Append );
BaseClass::ApplySchemeSettings( pScheme );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmDecodeDialog::OnCommand( const char *command )
{
if ( FStrEq( "cancel", command ) )
{
InventoryManager()->ShowItemsPickedUp( true );
}
BaseClass::OnCommand( command );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmDecodeDialog::Apply( void )
{
static CSchemaAttributeDefHandle pAttrDef_SupplyCrateSeries( "set supply crate series" );
// Tell the GC to unlock the subject item.
GCSDK::CGCMsg< MsgGCUnlockCrate_t > msg( k_EMsgGCUnlockCrate );
msg.Body().m_unToolItemID = m_pToolModelPanel->GetItem()->GetItemID();
msg.Body().m_unSubjectItemID = m_pSubjectModelPanel->GetItem()->GetItemID();
int iSeries = 0;
CEconItemView* pCrate = m_pSubjectModelPanel->GetItem();
if ( pCrate )
{
float fSeries;
if ( FindAttribute_UnsafeBitwiseCast<attrib_value_t>( pCrate, pAttrDef_SupplyCrateSeries, &fSeries ) )
{
iSeries = fSeries;
}
}
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "unlocked_supply_crate", iSeries );
GCClientSystem()->BSendMessage( msg );
CCollectionCraftingPanel *pPanel = EconUI()->GetBackpackPanel()->GetCollectionCraftPanel();
if ( pPanel )
{
pPanel->SetWaitingForItem( kEconItemOrigin_FoundInCrate );
}
}
void CEconTool_CrateKey::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmDecodeDialog *dialog = vgui::SETUP_PANEL( new CConfirmDecodeDialog( pParent, pTool, pSubject ) );
MakeModalAndBringToFront( dialog );
}
class CWaitForCrateDialog : public CGenericWaitingDialog
{
public:
CWaitForCrateDialog( vgui::Panel *pParent ) : CGenericWaitingDialog( pParent )
{
}
protected:
virtual void OnTimeout()
{
// Play an exciting sound!
if ( s_iCrateType == CRATETYPE_ROBO )
{
vgui::surface()->PlaySound( ROBOCRATE_OPENED_SND );
}
else
{
vgui::surface()->PlaySound( "misc/achievement_earned.wav" );
}
// Show them their loot!
InventoryManager()->ShowItemsPickedUp( true );
}
};
//-----------------------------------------------------------------------------
// Purpose: GC Msg handler to receive the decoder ring response
//-----------------------------------------------------------------------------
class CGCUnlockCrateResponse : public GCSDK::CGCClientJob
{
public:
CGCUnlockCrateResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CGCMsg<MsgGCStandardResponse_t> msg( pNetPacket );
if ( s_iCrateType == CRATETYPE_ROBO )
{
vgui::surface()->PlaySound( ROBOCRATE_UNLOCKING_SND );
}
else
{
vgui::surface()->PlaySound( "ui/item_open_crate_short.wav" );
}
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCUnlockCrateResponse, "CGCUnlockCrateResponse", k_EMsgGCUnlockCrateResponse, GCSDK::k_EServerTypeGCClient );
@@ -0,0 +1,14 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef DECODER_RING_TOOL_H
#define DECODER_RING_TOOL_H
#ifdef _WIN32
#pragma once
#endif
#endif // DECODER_RING_TOOL_H
@@ -0,0 +1,241 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "vgui_controls/EditablePanel.h"
#include "vgui_controls/TextEntry.h"
#include "vgui/IInput.h"
#include "econ_item_system.h"
#include "econ_item_constants.h"
#include "econ_item_tools.h"
#include "econ_gcmessages.h"
#include "econ_item_inventory.h"
#include "tool_items.h"
#include "gift_wrap_tool.h"
#include "econ_ui.h"
#include "vgui/ISurface.h"
#include "econ_controls.h"
#include "confirm_dialog.h"
#include "gc_clientsystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
//-----------------------------------------------------------------------------
// Purpose: Confirm / abort tool application
//-----------------------------------------------------------------------------
class CConfirmGiftWrapDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmGiftWrapDialog, CBaseToolUsageDialog );
public:
CConfirmGiftWrapDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject );
virtual void ApplySchemeSettings( vgui::IScheme *scheme );
virtual void Apply( void );
};
//-----------------------------------------------------------------------------
// Purpose: Completed wrapping dialog
//-----------------------------------------------------------------------------
class CWaitForGiftWrapDialog : public CGenericWaitingDialog
{
public:
CWaitForGiftWrapDialog( vgui::Panel *pParent ) : CGenericWaitingDialog( pParent )
{
}
protected:
virtual void OnTimeout()
{
// Play an exciting sound!
vgui::surface()->PlaySound( "misc/achievement_earned.wav" );
// Show them the result item.
InventoryManager()->ShowItemsPickedUp( true );
}
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CConfirmGiftWrapDialog::CConfirmGiftWrapDialog( vgui::Panel *parent, CEconItemView *pTool, CEconItemView *pToolSubject ) : CBaseToolUsageDialog( parent, "ConfirmApplyGiftWrapDialog", pTool, pToolSubject )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmGiftWrapDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmApplyGiftWrapDialog.res" );
// We might want to change our label text to explicitly call out that we'll reset strange scores
// on gift wrap, but only if we're trying to use this gift wrap on a strange item that has scores
// that would be affected by it.
CEconItemView *pSubjectItemView = GetSubjectItem();
CExLabel *pTextLabel = dynamic_cast<CExLabel *>( FindChildByName( "ConfirmLabel" ) );
CExLabel *pTextLabelStrange = dynamic_cast<CExLabel *>( FindChildByName( "ConfirmLabelStrange" ) );
if ( pSubjectItemView && pTextLabel && pTextLabelStrange )
{
bool bHasNonZeroScore = false;
for ( int i = 0; i < GetKillEaterAttrCount(); i++ )
{
uint32 unScore;
if ( pSubjectItemView->FindAttribute( GetKillEaterAttr_Score( i ), &unScore ) && unScore > 0 )
{
bHasNonZeroScore = true;
break;
}
}
if ( bHasNonZeroScore )
{
pTextLabel->SetVisible( false );
pTextLabelStrange->SetVisible( true );
}
}
BaseClass::ApplySchemeSettings( pScheme );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmGiftWrapDialog::Apply( void )
{
// Tell the GC to wrap the subject item.
GCSDK::CGCMsg< MsgGCGiftWrapItem_t > msg( k_EMsgGCGiftWrapItem );
msg.Body().m_unToolItemID = m_pToolModelPanel->GetItem()->GetItemID();
msg.Body().m_unSubjectItemID = m_pSubjectModelPanel->GetItem()->GetItemID();
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pSubjectModelPanel->GetItem(), "gift_wrap_item" );
GCClientSystem()->BSendMessage( msg );
vgui::surface()->PlaySound( "ui/item_gift_wrap_use.wav" );
ShowWaitingDialog( new CWaitForGiftWrapDialog( NULL ), "#ToolGiftWrapInProgress", true, false, 5.0f );
}
// Entry point from the UI.
void CEconTool_GiftWrap::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmGiftWrapDialog *dialog = vgui::SETUP_PANEL( new CConfirmGiftWrapDialog( pParent, pTool, pSubject ) );
MakeModalAndBringToFront( dialog );
}
//-----------------------------------------------------------------------------
// Purpose: GC Msg handler to receive the server response that we've given an item.
//-----------------------------------------------------------------------------
class CGCGiftGivenResponse : public GCSDK::CGCClientJob
{
public:
CGCGiftGivenResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CProtoBufMsg<CMsgDeliverGiftResponseGiver> msg( pNetPacket );
// Pop up a notification to confirm that the gift has been sent.
switch ( msg.Body().response_code() )
{
case k_EGCMsgResponseOK:
if ( msg.Body().has_receiver_account_name() )
{
KeyValues *pkv = new KeyValues( "GiftReceiverParams" );
KeyValuesAD kvad( pkv );
pkv->SetString( "receiver_account_name", msg.Body().receiver_account_name().c_str() );
ShowMessageBox( "#TF_DeliverGiftResultDialog_Title", "#TF_DeliverGiftResultDialog_Success_WithAccount", pkv, "#GameUI_OK" );
}
else
{
ShowMessageBox( "#TF_DeliverGiftResultDialog_Title", "#TF_DeliverGiftResultDialog_Success", "#GameUI_OK" );
}
break;
case k_EGCMsgResponseDenied:
ShowMessageBox( "#TF_DeliverGiftResultDialog_Title", "#TF_DeliverGiftResultDialog_VAC", "#GameUI_OK" );
break;
default:
ShowMessageBox( "#TF_DeliverGiftResultDialog_Title", "#TF_DeliverGiftResultDialog_Fail", "#GameUI_OK" );
break;
} // switch
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCGiftGivenResponse, "CGCGiftGivenResponse", k_EMsgGCDeliverGiftResponseGiver, GCSDK::k_EServerTypeGCClient );
//-----------------------------------------------------------------------------
// Purpose: GC Msg handler to receive the server response that we've received an item.
//-----------------------------------------------------------------------------
class CGCGiftReceivedResponse : public GCSDK::CGCClientJob
{
public:
CGCGiftReceivedResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CGCMsg<MsgGCStandardResponse_t> msg( pNetPacket );
// If the receiver is online when the gift is sent, they will get this response.
InventoryManager()->GetLocalInventory()->NotifyHasNewItems();
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCGiftReceivedResponse, "CGCGiftReceivedResponse", k_EMsgGCDeliverGiftResponseReceiver, GCSDK::k_EServerTypeGCClient );
//-----------------------------------------------------------------------------
// Purpose: Completed unwrapping...
//-----------------------------------------------------------------------------
class CWaitForGiftUnwrapDialog : public CGenericWaitingDialog
{
public:
CWaitForGiftUnwrapDialog( vgui::Panel *pParent ) : CGenericWaitingDialog( pParent )
{
}
protected:
virtual void OnTimeout()
{
// Play an exciting sound!
vgui::surface()->PlaySound( "misc/achievement_earned.wav" );
// Show them the result item.
InventoryManager()->ShowItemsPickedUp( true );
}
};
static void UnwrapGiftConfirm( bool bConfirmed, void *pContext )
{
if ( bConfirmed )
{
vgui::surface()->PlaySound( "ui/item_gift_wrap_unwrap.wav" );
ShowWaitingDialog( new CWaitForGiftWrapDialog( NULL ), "#ToolGiftUnwrapInProgress", true, false, 5.0f );
CEconItemView *pItem = (CEconItemView*) pContext;
GCSDK::CGCMsg< MsgGCUnwrapGiftRequest_t > msg( k_EMsgGCUnwrapGiftRequest );
msg.Body().m_unItemID = pItem->GetItemID();
GCClientSystem()->BSendMessage( msg );
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, pItem, "unwrapped_gift" );
}
}
void PerformToolAction_UnwrapGift( vgui::Panel* pParent, CEconItemView *pGiftItem )
{
CTFGenericConfirmDialog *pDialog = ShowConfirmDialog( "#TF_UnwrapGift_Title", "#TF_UnwrapGift_Text",
"#GameUI_OK", "#Cancel",
&UnwrapGiftConfirm );
pDialog->AddStringToken( "item_name", pGiftItem->GetItemName() );
pDialog->SetContext( pGiftItem );
}
@@ -0,0 +1,14 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef GIFT_WRAP_TOOL_H
#define GIFT_WRAP_TOOL_H
#ifdef _WIN32
#pragma once
#endif
#endif // GIFT_WRAP_TOOL_H
@@ -0,0 +1,205 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "vgui_controls/EditablePanel.h"
#include "vgui_controls/TextEntry.h"
#include "vgui/IInput.h"
#include "econ_item_system.h"
#include "econ_item_constants.h"
#include "econ_gcmessages.h"
#include "econ_item_inventory.h"
#include "econ_item_tools.h"
#include "tool_items.h"
#include "paint_can_tool.h"
#include "econ_ui.h"
#include "gc_clientsystem.h"
#ifdef TF_CLIENT_DLL
#include "tf_shareddefs.h"
#endif // TF_CLIENT_DLL
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
enum
{
#ifdef TF_CLIENT_DLL
kTeamID0 = TF_TEAM_RED,
kTeamID1 = TF_TEAM_BLUE,
#else // !defined( TF_CLIENT_DLL )
kTeamID0 = -1,
kTeamID1 = -1,
#endif // TF_CLIENT_DLL
};
//-----------------------------------------------------------------------------
// Purpose: Confirm / abort paint application
//-----------------------------------------------------------------------------
class CConfirmApplyPaintCanBaseDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmApplyPaintCanBaseDialog, CBaseToolUsageDialog );
protected:
CConfirmApplyPaintCanBaseDialog( vgui::Panel *pParent, const char *szType, CEconItemView *pTool, CEconItemView *pToolSubject )
: CBaseToolUsageDialog( pParent, szType, pTool, pToolSubject )
{
//
}
public:
virtual void Apply( void )
{
// Send the apply request to the GC
GCSDK::CGCMsg< MsgGCPaintItem_t > msg( k_EMsgGCPaintItem );
msg.Body().m_unToolItemID = m_pToolModelPanel->GetItem()->GetItemID();
msg.Body().m_unSubjectItemID = m_pSubjectModelPanel->GetItem()->GetItemID();
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "painted_item" );
GCClientSystem()->BSendMessage( msg );
}
protected:
// Set up a particular panel for a certain item with a certain preview color.
static void SetupPaintModelPanel( CItemModelPanel *pPaintModelPanel, CEconItemView *pToolSubjectView, int iTeam, int iPaintRGB )
{
static CSchemaAttributeDefHandle pAttrDef_ItemTintRGB( "set item tint RGB" );
if ( !pAttrDef_ItemTintRGB )
return;
// Fake-paint the demonstration items.
pPaintModelPanel->SetItem( pToolSubjectView );
pPaintModelPanel->GetItem()->GetAttributeList()->SetRuntimeAttributeValue( pAttrDef_ItemTintRGB, iPaintRGB );
// Set the appropriate skins for each item given the team and the style selected.
int iStyleSkin = pToolSubjectView->GetSkin( iTeam );
if ( iStyleSkin == -1 )
{
// Fallback case: rely on default skins.
pPaintModelPanel->SetSkin( iTeam == kTeamID0 ? 0 : 1 );
}
else
{
pPaintModelPanel->SetSkin( iStyleSkin );
}
pPaintModelPanel->SetActAsButton( true, false );
pPaintModelPanel->GetItem()->InvalidateColor();
pPaintModelPanel->GetItem()->InvalidateOverrideColor();
}
CItemModelPanel *m_pPaintModelPanel;
};
//-----------------------------------------------------------------------------
// Purpose: Preview a single-color paint
//-----------------------------------------------------------------------------
class CConfirmApplyPaintCanDialog : public CConfirmApplyPaintCanBaseDialog
{
DECLARE_CLASS_SIMPLE( CConfirmApplyPaintCanDialog, CConfirmApplyPaintCanBaseDialog );
public:
CConfirmApplyPaintCanDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
: CConfirmApplyPaintCanBaseDialog( pParent, "ConfirmApplyPaintCanDialog", pTool, pToolSubject )
{
m_pPaintModelPanel = new CItemModelPanel( this, "paint_model" );
m_pPaintModelPanel->SetItem( pToolSubject );
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmApplyPaintCanDialog.res" );
BaseClass::ApplySchemeSettings( pScheme );
SetupPaintModelPanel( m_pPaintModelPanel, m_pSubjectModelPanel->GetItem(), kTeamID0, m_pToolModelPanel->GetItem()->GetModifiedRGBValue( false ) );
}
private:
CItemModelPanel *m_pPaintModelPanel;
};
//-----------------------------------------------------------------------------
// Purpose: Preview team-colored paint
//-----------------------------------------------------------------------------
class CConfirmApplyTeamColorPaintCanDialog : public CConfirmApplyPaintCanBaseDialog
{
DECLARE_CLASS_SIMPLE( CConfirmApplyTeamColorPaintCanDialog, CConfirmApplyPaintCanBaseDialog );
public:
CConfirmApplyTeamColorPaintCanDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
: CConfirmApplyPaintCanBaseDialog( pParent, "ConfirmApplyTeamColorPaintCanDialog", pTool, pToolSubject )
{
m_pPaintModelPanel_Red = new CItemModelPanel( this, "paint_model_red" );
m_pPaintModelPanel_Red->SetItem( pToolSubject );
m_pPaintModelPanel_Blue = new CItemModelPanel( this, "paint_model_blue" );
m_pPaintModelPanel_Blue->SetItem( pToolSubject );
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmApplyTeamColorPaintCanDialog.res" );
BaseClass::ApplySchemeSettings( pScheme );
SetupPaintModelPanel( m_pPaintModelPanel_Red, m_pSubjectModelPanel->GetItem(), kTeamID0, m_pToolModelPanel->GetItem()->GetModifiedRGBValue( false ) );
SetupPaintModelPanel( m_pPaintModelPanel_Blue, m_pSubjectModelPanel->GetItem(), kTeamID1, m_pToolModelPanel->GetItem()->GetModifiedRGBValue( true ) );
// @note Tom Bui: we need to change the global index so that the material does not get
// re-used for each item. Should be ok to change the high bit.
Assert( m_pPaintModelPanel_Red->GetItem() );
m_pPaintModelPanel_Red->GetItem()->SetItemID( m_pPaintModelPanel_Red->GetItem()->GetItemID() | ( 1LL << 63 ) );
}
private:
CItemModelPanel *m_pPaintModelPanel_Red;
CItemModelPanel *m_pPaintModelPanel_Blue;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_PaintCan::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
// Bizarro logic: we have no way of finding out whether an item has two different
// colors of paint applied so instead we ask whether both colors are
// the same.
CBaseToolUsageDialog *dialog = NULL;
if ( pTool->GetModifiedRGBValue( true ) != pTool->GetModifiedRGBValue( false ) )
{
dialog = new CConfirmApplyTeamColorPaintCanDialog( pParent, pTool, pSubject );
}
else
{
dialog = new CConfirmApplyPaintCanDialog( pParent, pTool, pSubject );
}
vgui::SETUP_PANEL( dialog );
MakeModalAndBringToFront( dialog );
}
//-----------------------------------------------------------------------------
// Purpose: GC Msg handler to receive the paint can response
//-----------------------------------------------------------------------------
class CGCPaintItemResponse : public GCSDK::CGCClientJob
{
public:
CGCPaintItemResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CGCMsg<MsgGCStandardResponse_t> msg( pNetPacket );
InventoryManager()->ShowItemsPickedUp( true );
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCPaintItemResponse, "CGCPaintItemResponse", k_EMsgGCPaintItemResponse, GCSDK::k_EServerTypeGCClient );
@@ -0,0 +1,15 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef PAINT_CAN_TOOL_H
#define PAINT_CAN_TOOL_H
#ifdef _WIN32
#pragma once
#endif
#endif // PAINT_CAN_TOOL_H
@@ -0,0 +1,306 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "vgui_controls/EditablePanel.h"
#include "vgui_controls/TextEntry.h"
#include "vgui/IInput.h"
#include "vgui//ILocalize.h"
#include "econ_item_system.h"
#include "econ_item_constants.h"
#include "econ_gcmessages.h"
#include "econ_item_inventory.h"
#include "econ_item_tools.h"
#include "tool_items.h"
#include "rename_tool_ui.h"
#include "econ_ui.h"
#include "gc_clientsystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
CNameToolUsageDialog::CNameToolUsageDialog( vgui::Panel *pParent, const char* pszName, CEconItemView *pTool, CEconItemView *pToolSubject, bool bDescription )
: CBaseToolUsageDialog( pParent, pszName, pTool, pToolSubject )
{
m_bDescription = bDescription;
}
int CNameToolUsageDialog::GetMaxLength()
{
if ( m_bDescription )
return MAX_ITEM_CUSTOM_DESC_LENGTH;
else
return MAX_ITEM_CUSTOM_NAME_LENGTH;
}
int CNameToolUsageDialog::GetMaxDBSize()
{
if ( m_bDescription )
return MAX_ITEM_CUSTOM_DESC_DATABASE_SIZE;
else
return MAX_ITEM_CUSTOM_NAME_DATABASE_SIZE;
}
void CEconTool_NameTag::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CRequestNameDialog *dialog = vgui::SETUP_PANEL( new CRequestNameDialog( pParent, "ItemRenameDialog", pTool, pSubject, false ) );
MakeModalAndBringToFront( dialog );
}
//-----------------------------------------------------------------------------
CRequestNameDialog::CRequestNameDialog( vgui::Panel *parent, const char* pszName, CEconItemView *pTool, CEconItemView *pToolSubject, bool bDescription ) :
CNameToolUsageDialog( parent, pszName, pTool, pToolSubject, bDescription )
{
m_pCustomNameEntry = new vgui::TextEntry( this, "CustomNameEntry" );
m_bDescription = bDescription;
}
//-----------------------------------------------------------------------------
void CRequestNameDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "resource/UI/ItemRenameDialog.res" );
BaseClass::ApplySchemeSettings( pScheme );
m_pOldNameLabel = dynamic_cast<vgui::Label *>( FindChildByName( "OldItemNameDescLabel" ) );
if ( m_pOldNameLabel )
{
if ( m_bDescription )
m_pOldNameLabel->SetText( g_pVGuiLocalize->Find( "#ToolItemRenameOldItemDesc" ) );
else
m_pOldNameLabel->SetText( g_pVGuiLocalize->Find( "#ToolItemRenameOldItemName" ) );
}
m_pNewNameLabel = dynamic_cast<vgui::Label *>( FindChildByName( "NewItemNameDescLabel" ) );
if ( m_pNewNameLabel )
{
if ( m_bDescription )
m_pNewNameLabel->SetText( g_pVGuiLocalize->Find( "#ToolItemRenameNewItemDesc" ) );
else
m_pNewNameLabel->SetText( g_pVGuiLocalize->Find( "#ToolItemRenameNewItemName" ) );
}
m_pOldName = dynamic_cast<vgui::Label *>( FindChildByName( "OldItemNameLabel" ) );
if ( m_pOldName )
{
if ( m_bDescription )
{
CEconItem *pSOCData = m_pSubjectModelPanel->GetItem()->GetSOCData();
if ( pSOCData && pSOCData->GetCustomDesc() )
m_pOldName->SetText( pSOCData->GetCustomDesc() );
else
m_pOldName->SetText( m_pSubjectModelPanel->GetItem()->GetStaticData()->GetItemDesc() );
}
else
{
CEconItem *pSOCData = m_pSubjectModelPanel->GetItem()->GetSOCData();
if ( pSOCData && pSOCData->GetCustomName() )
m_pOldName->SetText( pSOCData->GetCustomName() );
else
m_pOldName->SetText( m_pSubjectModelPanel->GetItem()->GetStaticData()->GetItemBaseName() );
}
}
CExButton *pOKButton = dynamic_cast< CExButton* >( FindChildByName( "OkButton" ) );
if ( pOKButton )
{
if ( m_bDescription )
pOKButton->SetText( "#CraftDescribeOk" );
}
m_pCustomNameEntry->SetMaximumCharCount( GetMaxLength() );
m_pCustomNameEntry->SetAllowNonAsciiCharacters( true );
}
//-----------------------------------------------------------------------------
void CRequestNameDialog::MoveToFront()
{
BaseClass::MoveToFront();
// do this after MoveToFront so we can force the text box to have focus instead
// of the dialog itself
m_pCustomNameEntry->RequestFocus();
}
//-----------------------------------------------------------------------------
void CRequestNameDialog::Apply( void )
{
const int maxNameLength = MAX_ITEM_CUSTOM_DESC_LENGTH + 1;
wchar_t inputName[ maxNameLength ];
m_pCustomNameEntry->GetText( inputName, sizeof(inputName) );
// pop up modal confirmation dialog
CConfirmNameDialog *dialog = vgui::SETUP_PANEL( new CConfirmNameDialog( GetParent(), "ItemRenameConfirmationDialog", m_pToolModelPanel->GetItem(), m_pSubjectModelPanel->GetItem(), inputName, m_bDescription ) );
MakeModalAndBringToFront( dialog );
}
//-----------------------------------------------------------------------------
// Purpose: Gives focus back to the name entry field after the mouse enters a
// item model panel
//-----------------------------------------------------------------------------
void CRequestNameDialog::OnItemPanelEntered( vgui::Panel *panel )
{
CItemModelPanel *pItemPanel = dynamic_cast < CItemModelPanel * > ( panel );
if ( pItemPanel && IsVisible() )
{
// The item panel is going to try and steal our focus. Steal it back!
m_pCustomNameEntry->RequestFocus();
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CConfirmNameDialog::CConfirmNameDialog( vgui::Panel *parent, const char* pszName, CEconItemView *pTool, CEconItemView *pToolSubject, const wchar_t *name, bool bDescription ) :
CNameToolUsageDialog( parent, pszName, pTool, pToolSubject, bDescription )
{
Q_wcsncpy( m_name, name, sizeof(m_name) );
m_bDescription = bDescription;
}
//-----------------------------------------------------------------------------
//
// We're going to want to flesh this out to trim off leading/training spaces, etc
//
bool CConfirmNameDialog::IsNameValid( void ) const
{
// legal names are 1 or more alphanumeric values (only)
const wchar_t *c = m_name;
int length = 0;
while( *c )
{
// no leading spaces
if ( length == 0 && *c == ' ' )
return false;
++c;
++length;
}
// no trailing spaces
if ( length > 0 && m_name[length-1] == ' ' )
return false;
return (length > 0);
}
//-----------------------------------------------------------------------------
void CConfirmNameDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
if ( !IsNameValid() )
{
// pop up bad name dialog
LoadControlSettings( "resource/UI/ItemRenameInvalidDialog.res" );
}
else
{
// pop up "are you sure" dialog
LoadControlSettings( "resource/UI/ItemRenameConfirmationDialog.res" );
}
// Set our dialog name, but pre & post pend it with quotes
wchar_t tmpname[ MAX_ITEM_CUSTOM_DESC_LENGTH+3 ];
V_wcscpy_safe( tmpname, L"\"" );
V_wcscat_safe( tmpname, m_name );
V_wcscat_safe( tmpname, L"\"" );
SetDialogVariable( "name", tmpname );
BaseClass::ApplySchemeSettings( pScheme );
}
//-----------------------------------------------------------------------------
void CConfirmNameDialog::Apply( void )
{
// the GC stores 8-bit chars, so convert Unicode name to UTF8
char* utf8Name = new char[ GetMaxDBSize() ];
int count = V_UnicodeToUTF8( m_name, utf8Name, GetMaxDBSize() );
if ( count > GetMaxDBSize() )
{
// the encoded name exceeds the GC's storage limit
return;
}
if ( m_pSubjectModelPanel->GetItem()->GetItemID() != INVALID_ITEM_ID )
{
// Name has been confirmed - send message to GC to apply name to item
GCSDK::CGCMsg< MsgGCNameItem_t > msg( k_EMsgGCNameItem );
msg.Body().m_unToolItemID = m_pToolModelPanel->GetItem()->GetItemID();
msg.Body().m_unSubjectItemID = m_pSubjectModelPanel->GetItem()->GetItemID();
msg.AddStrData( utf8Name );
GCClientSystem()->BSendMessage( msg );
}
else
{
// Name has been confirmed - send message to GC to apply name to item
GCSDK::CGCMsg< MsgGCNameBaseItem_t > msg( k_EMsgGCNameBaseItem );
msg.Body().m_unToolItemID = m_pToolModelPanel->GetItem()->GetItemID();
msg.Body().m_unBaseItemDefinitionID = m_pSubjectModelPanel->GetItem()->GetStaticData()->GetDefinitionIndex();
msg.AddStrData( utf8Name );
GCClientSystem()->BSendMessage( msg );
}
if ( m_bDescription )
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "redescription_item" );
else
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "renamed_item" );
delete []utf8Name;
}
//-----------------------------------------------------------------------------
void CConfirmNameDialog::OnCommand( const char *command )
{
BaseClass::OnCommand( command );
if ( !Q_stricmp( command, "backfrominvalid" ) )
{
// Re-open the name dialog
CRequestNameDialog *dialog = vgui::SETUP_PANEL( new CRequestNameDialog( GetParent(), "ItemRenameDialog", m_pToolModelPanel->GetItem(), m_pSubjectModelPanel->GetItem(), m_bDescription ) );
MakeModalAndBringToFront( dialog );
}
}
//-----------------------------------------------------------------------------
// Purpose: GC Msg handler to receive the name base item response
//-----------------------------------------------------------------------------
class CGCNameBaseItemResponse : public GCSDK::CGCClientJob
{
public:
CGCNameBaseItemResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CGCMsg<MsgGCStandardResponse_t> msg( pNetPacket );
InventoryManager()->ShowItemsPickedUp( true );
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCNameBaseItemResponse, "CGCNameBaseItemResponse", k_EMsgGCNameBaseItemResponse, GCSDK::k_EServerTypeGCClient );
//-----------------------------------------------------------------------------
// Purpose: UI Hook for applying a new description to items.
//-----------------------------------------------------------------------------
void CEconTool_DescTag::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CRequestNameDialog *dialog = vgui::SETUP_PANEL( new CRequestNameDialog( pParent, "ItemRenameDialog", pTool, pSubject, true ) );
MakeModalAndBringToFront( dialog );
}
@@ -0,0 +1,74 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef RENAME_TOOL_UI_H
#define RENAME_TOOL_UI_H
#ifdef _WIN32
#pragma once
#endif
#include "tool_items.h"
class CNameToolUsageDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CNameToolUsageDialog, CBaseToolUsageDialog );
public:
CNameToolUsageDialog( vgui::Panel *pParent, const char* pszName, CEconItemView *pTool, CEconItemView *pToolSubject, bool bDescription );
virtual int GetMaxLength();
virtual int GetMaxDBSize();
protected:
bool m_bDescription;
};
//-----------------------------------------------------------------------------
// Purpose: A dialog used to input a Tool's name payload
//-----------------------------------------------------------------------------
class CRequestNameDialog : public CNameToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CRequestNameDialog, CNameToolUsageDialog );
public:
CRequestNameDialog( vgui::Panel *pParent, const char* pszName, CEconItemView *pTool, CEconItemView *pToolSubject, bool bDescription );
virtual void MoveToFront();
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void Apply( void );
MESSAGE_FUNC_PTR( OnItemPanelEntered, "ItemPanelEntered", panel );
private:
vgui::TextEntry *m_pCustomNameEntry;
vgui::Label *m_pOldNameLabel;
vgui::Label *m_pOldName;
vgui::Label *m_pNewNameLabel;
};
//-----------------------------------------------------------------------------
// Purpose: Confirm name and commit or reject
//-----------------------------------------------------------------------------
class CConfirmNameDialog : public CNameToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmNameDialog, CNameToolUsageDialog );
public:
CConfirmNameDialog( vgui::Panel *pParent, const char* pszName, CEconItemView *pTool, CEconItemView *pToolSubject, const wchar_t *name, bool bDescription );
virtual void ApplySchemeSettings( vgui::IScheme *scheme );
virtual void Apply( void );
virtual void OnCommand( const char *command );
private:
wchar_t m_name[ MAX_ITEM_CUSTOM_DESC_LENGTH+1 ];
bool IsNameValid( void ) const;
};
#endif // RENAME_TOOL_UI_H
+968
View File
@@ -0,0 +1,968 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "vgui_controls/EditablePanel.h"
#include "vgui_controls/TextEntry.h"
#include "vgui_controls/TextImage.h"
#include "vgui/IInput.h"
#include "econ_item_system.h"
#include "econ_item_constants.h"
#include "econ_gcmessages.h"
#include "econ_ui.h"
#include "tool_items.h"
#ifdef TF_CLIENT_DLL
#include "tf_item_tools.h"
#else
#include "econ_item_tools.h"
#endif
#include <vgui/ILocalize.h>
#include "gc_clientsystem.h"
#include "item_style_select_dialog.h" // for CComboBoxBackpackOverlayDialogBase
#include "backpack_panel.h"
#include "vgui_controls/Controls.h"
#include "vgui/ISurface.h"
#ifdef TF_CLIENT_DLL
#include "character_info_panel.h"
#include "c_tf_gamestats.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CBaseToolUsageDialog::CBaseToolUsageDialog( vgui::Panel *parent, const char *panelName, CEconItemView *pTool, CEconItemView *pToolSubject ) : vgui::EditablePanel( parent, panelName )
{
m_pToolModelPanel = new CItemModelPanel( this, "tool_modelpanel" );
m_pToolModelPanel->SetActAsButton( true, true );
m_pSubjectModelPanel = new CItemModelPanel( this, "subject_modelpanel" );
m_pSubjectModelPanel->SetActAsButton( true, true );
m_pMouseOverItemPanel = vgui::SETUP_PANEL( new CItemModelPanel( this, "mouseoveritempanel" ) );
m_pMouseOverTooltip = new CItemModelPanelToolTip( this );
m_pMouseOverTooltip->SetupPanels( this, m_pMouseOverItemPanel );
m_pToolModelPanel->SetTooltip( m_pMouseOverTooltip, "" );
m_pSubjectModelPanel->SetTooltip( m_pMouseOverTooltip, "" );
m_pToolModelPanel->SetItem( pTool );
m_pToolModelPanel->SetShowEquipped( true );
m_pSubjectModelPanel->SetItem( pToolSubject );
m_pSubjectModelPanel->SetShowEquipped( true );
m_pTitleLabel = NULL;
m_pszInternalPanelName = panelName ? panelName : "unknown";
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseToolUsageDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
SetDialogVariable( "oldname", m_pSubjectModelPanel->GetItem()->GetItemName() );
m_pTitleLabel = dynamic_cast<vgui::Label*>( FindChildByName("TitleLabel") );
if ( m_pTitleLabel )
{
wchar_t *pszBaseString = g_pVGuiLocalize->Find( "ToolDialogTitle" );
if ( pszBaseString )
{
wchar_t wTemp[256];
g_pVGuiLocalize->ConstructString_safe( wTemp, pszBaseString, 2, m_pToolModelPanel->GetItem()->GetItemName(), m_pSubjectModelPanel->GetItem()->GetItemName() );
m_pTitleLabel->SetText( wTemp );
// Now go through the string and find the escape characters telling us where the color changes are
m_pTitleLabel->GetTextImage()->ClearColorChangeStream();
// We change the title's text color to match the colors of the matching model panel backgrounds
wchar_t *txt = wTemp;
int iWChars = 0;
Color colCustom;
while ( txt && *txt )
{
switch ( *txt )
{
case 0x01: // Normal color
m_pTitleLabel->GetTextImage()->AddColorChange( Color(235,226,202,255), iWChars );
break;
case 0x02: // Item 1 color
m_pTitleLabel->GetTextImage()->AddColorChange( Color(112,176,74,255), iWChars );
break;
case 0x03: // Item 2 color
m_pTitleLabel->GetTextImage()->AddColorChange( Color(71,98,145,255), iWChars );
break;
default:
break;
}
txt++;
iWChars++;
}
}
}
vgui::Panel *pToolIcon = FindChildByName( "tool_icon" );
if ( pToolIcon )
{
pToolIcon->SetMouseInputEnabled( false );
pToolIcon->SetKeyBoardInputEnabled( false );
}
vgui::Panel *pSubjectIcon = FindChildByName( "subject_icon" );
if ( pSubjectIcon )
{
pSubjectIcon->SetMouseInputEnabled( false );
pSubjectIcon->SetKeyBoardInputEnabled( false );
}
// @note Tom Bui: because the children have already applied their scheme settings and/or performed their layout before
// this dialog has had a chance to load its res file, we need to manually invalidate the layout of these children
// to make sure that the settings are valid with respect to what the parent wants
m_pToolModelPanel->UpdatePanels();
m_pSubjectModelPanel->UpdatePanels();
m_pMouseOverItemPanel->SetBorder( pScheme->GetBorder("LoadoutItemPopupBorder") );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseToolUsageDialog::PerformLayout()
{
BaseClass::PerformLayout();
// if ( m_pMouseOverItemPanel->IsVisible() )
// {
// // The mouseover panel was visible. Fake a panel entry into the original panel to get it to show up again properly.
// if ( m_pItemPanelBeingMousedOver )
// {
// OnItemPanelEntered( m_pItemPanelBeingMousedOver );
// }
// else
// {
// HideMouseOverPanel();
// }
// }
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseToolUsageDialog::OnCommand( const char *command )
{
// in any case, our dialog is going away
TFModalStack()->PopModal( this );
SetVisible( false );
MarkForDeletion();
#ifdef TF_CLIENT_DLL
const char *pSubjectBaseName = m_pSubjectModelPanel && m_pSubjectModelPanel->GetItem() && m_pSubjectModelPanel->GetItem()->GetItemDefinition()
? m_pSubjectModelPanel->GetItem()->GetItemDefinition()->GetItemBaseName()
: "n/a";
#endif
if ( !Q_stricmp( command, "apply" ) )
{
#ifdef TF_CLIENT_DLL
C_CTFGameStats::ImmediateWriteInterfaceEvent( CFmtStr( "tool_usage_proceed(%s)", m_pszInternalPanelName ).Access(),
pSubjectBaseName );
#endif
// Call before Apply() in case it creates new dialogs that wants to handle prevention
EconUI()->SetPreventClosure( false );
Apply();
}
else // "cancel"
{
#ifdef TF_CLIENT_DLL
C_CTFGameStats::ImmediateWriteInterfaceEvent( CFmtStr( "tool_usage_cancel(%s)", m_pszInternalPanelName ).Access(),
pSubjectBaseName );
#endif
EconUI()->SetPreventClosure( false );
IGameEvent *event = gameeventmanager->CreateEvent( "inventory_updated" );
if ( event )
{
gameeventmanager->FireEventClientSide( event );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Utility function
//-----------------------------------------------------------------------------
void CBaseToolUsageDialog::OnKeyCodeTyped( vgui::KeyCode code )
{
if( code == KEY_ESCAPE )
{
OnCommand( "cancel" );
}
else
{
BaseClass::OnKeyCodeTyped( code );
}
}
//-----------------------------------------------------------------------------
// Purpose: Utility function
//-----------------------------------------------------------------------------
void CBaseToolUsageDialog::OnKeyCodePressed( vgui::KeyCode code )
{
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
if (nButtonCode == KEY_XBUTTON_LEFT ||
nButtonCode == KEY_XSTICK1_LEFT ||
nButtonCode == KEY_XSTICK2_LEFT ||
nButtonCode == STEAMCONTROLLER_DPAD_LEFT ||
code == KEY_LEFT ||
nButtonCode == KEY_XBUTTON_RIGHT ||
nButtonCode == KEY_XSTICK1_RIGHT ||
nButtonCode == KEY_XSTICK2_RIGHT ||
nButtonCode == STEAMCONTROLLER_DPAD_RIGHT ||
code == KEY_RIGHT ||
nButtonCode == KEY_XBUTTON_UP ||
nButtonCode == KEY_XSTICK1_UP ||
nButtonCode == KEY_XSTICK2_UP ||
nButtonCode == STEAMCONTROLLER_DPAD_UP ||
code == KEY_UP ||
nButtonCode == KEY_XBUTTON_DOWN ||
nButtonCode == KEY_XSTICK1_DOWN ||
nButtonCode == KEY_XSTICK2_DOWN ||
nButtonCode == STEAMCONTROLLER_DPAD_DOWN ||
code == KEY_DOWN )
{
// eat all the movement keys so the selection doesn't update behind the dialog
}
else if( nButtonCode == KEY_XBUTTON_A || code == KEY_ENTER || nButtonCode == STEAMCONTROLLER_A )
{
OnCommand( "apply" );
}
else if( nButtonCode == KEY_XBUTTON_B || nButtonCode == STEAMCONTROLLER_B )
{
OnCommand( "cancel" );
}
else
{
BaseClass::OnKeyCodePressed( code );
}
}
//-----------------------------------------------------------------------------
// Purpose: Utility function
//-----------------------------------------------------------------------------
void MakeModalAndBringToFront( vgui::EditablePanel *dialog )
{
dialog->SetVisible( true );
if ( dialog->GetParent() == NULL )
{
dialog->MakePopup();
}
dialog->SetZPos( 10000 );
dialog->MoveToFront();
dialog->SetKeyBoardInputEnabled( true );
dialog->SetMouseInputEnabled( true );
TFModalStack()->PushModal( dialog );
EconUI()->SetPreventClosure( true );
}
//-----------------------------------------------------------------------------
//
// Given a tool and an item to apply the tool's effects upon,
// gather required information from the user and
// send a change request to the GC.
//
bool ApplyTool( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
{
if ( !pTool || !pToolSubject )
return false;
if ( !CEconSharedToolSupport::ToolCanApplyTo( pTool, pToolSubject ) )
return false;
// this tool can be applied to this subject item
const IEconTool *pEconTool = pTool->GetStaticData()->GetEconTool();
if ( !pEconTool )
return false;
pEconTool->OnClientApplyTool( pTool, pToolSubject, pParent );
return true;
}
//-----------------------------------------------------------------------------
// Purpose: STRANGE COUNT TRANSFER
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
class CConfirmStrangeCountTransferApplicationDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmStrangeCountTransferApplicationDialog, CBaseToolUsageDialog );
public:
CConfirmStrangeCountTransferApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
: CBaseToolUsageDialog( pParent, "ConfirmApplyStrangeCountTransferDialog", pTool, pToolSubject )
{
m_pItemSrc = NULL;
m_pItemDest = NULL;
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmApplyDuckTokenDialog.res" ); // fix me
BaseClass::ApplySchemeSettings( pScheme );
}
virtual void Apply( void )
{
GCSDK::CProtoBufMsg<CMsgApplyStrangeCountTransfer> msg( k_EMsgGCApplyStrangeCountTransfer );
if ( !m_pItemSrc || !m_pItemDest )
return;
msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
msg.Body().set_item_src_item_id( m_pItemSrc->GetItemID() );
msg.Body().set_item_dest_item_id( m_pItemDest->GetItemID() );
GCClientSystem()->BSendMessage( msg );
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_strangecounttransfer", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
GCClientSystem()->BSendMessage( msg );
}
bool SetItems( CEconItemView *pItemSrc, CEconItemView *pItemDest )
{
if ( !pItemSrc || !pItemDest )
return false;
if ( CEconTool_StrangeCountTransfer::AreItemsEligibleForStrangeCountTransfer( pItemSrc, pItemDest ) )
{
m_pItemSrc = pItemSrc;
m_pItemDest = pItemDest;
return true;
}
return false;
}
private:
CEconItemView *m_pItemSrc;
CEconItemView *m_pItemDest;
};
/*static */bool CEconTool_StrangeCountTransfer::SetItems( CEconItemView *pItemSrc, CEconItemView *pItemDest )
{
if ( !pItemSrc || !pItemDest )
return false;
if ( CEconTool_StrangeCountTransfer::AreItemsEligibleForStrangeCountTransfer( pItemSrc, pItemDest ) )
{
CEconTool_StrangeCountTransfer::m_pItemSrc = pItemSrc;
CEconTool_StrangeCountTransfer::m_pItemDest = pItemDest;
return true;
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_StrangeCountTransfer::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmStrangeCountTransferApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmStrangeCountTransferApplicationDialog( pParent, pTool, pSubject ) );
MakeModalAndBringToFront( pDialog );
}
// ****************************************************************************
// STRANGE PARTS
//-----------------------------------------------------------------------------
// Purpose: Confirm / abort strange part application
//-----------------------------------------------------------------------------
class CConfirmStrangePartApplicationDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmStrangePartApplicationDialog, CBaseToolUsageDialog );
public:
CConfirmStrangePartApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void Apply( void );
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CConfirmStrangePartApplicationDialog::CConfirmStrangePartApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
: CBaseToolUsageDialog( pParent, "ConfirmApplyStrangePartApplicationDialog", pTool, pToolSubject )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmStrangePartApplicationDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmApplyStrangePartApplicationDialog.res" );
int iRemainingStrangePartSlots = 0;
for ( int i = 0; i < GetKillEaterAttrCount(); i++ )
{
if ( !GetKillEaterAttr_IsUserCustomizable( i ) )
continue;
if ( !m_pSubjectModelPanel->GetItem()->FindAttribute( GetKillEaterAttr_Score( i ) ) )
++iRemainingStrangePartSlots;
}
SetDialogVariable( "remaining_strange_part_slots", iRemainingStrangePartSlots );
SetDialogVariable( "maximum_strange_part_slots", GetKillEaterAttrCount_UserCustomizable() );
SetDialogVariable( "subject_item_def_name", GLocalizationProvider()->Find( m_pSubjectModelPanel->GetItem()->GetItemDefinition()->GetItemBaseName() ) );
SetDialogVariable( "slot_singular_plural", GLocalizationProvider()->Find( iRemainingStrangePartSlots == 1 ? "#Econ_FreeSlot_Singular" : "#Econ_FreeSlot_Plural" ) );
BaseClass::ApplySchemeSettings( pScheme );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmStrangePartApplicationDialog::Apply()
{
GCSDK::CProtoBufMsg<CMsgApplyStrangePart> msg( k_EMsgGCApplyStrangePart );
msg.Body().set_strange_part_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
msg.Body().set_item_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_strange_part", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
GCClientSystem()->BSendMessage( msg );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_StrangePart::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmStrangePartApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmStrangePartApplicationDialog( pParent, pTool, pSubject ) );
MakeModalAndBringToFront( pDialog );
}
//-----------------------------------------------------------------------------
// Purpose: Confirm / abort strange restriction application
//-----------------------------------------------------------------------------
class CConfirmStrangeRestrictionApplicationDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmStrangeRestrictionApplicationDialog, CBaseToolUsageDialog );
public:
CConfirmStrangeRestrictionApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject, int iStrangeSlot, const char *pszStatLocalizationToken );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void Apply( void );
private:
int m_iStrangeSlot;
const char *m_pszStatLocalizationToken;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CConfirmStrangeRestrictionApplicationDialog::CConfirmStrangeRestrictionApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject, int iStrangeSlot, const char *pszStatLocalizationToken )
: CBaseToolUsageDialog( pParent, "ConfirmApplyStrangeRestrictionApplicationDialog", pTool, pToolSubject )
, m_iStrangeSlot( iStrangeSlot )
, m_pszStatLocalizationToken( pszStatLocalizationToken )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmStrangeRestrictionApplicationDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmApplyStrangeRestrictionApplicationDialog.res" );
SetDialogVariable( "stat_name", GLocalizationProvider()->Find( m_pszStatLocalizationToken ) );
BaseClass::ApplySchemeSettings( pScheme );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CConfirmStrangeRestrictionApplicationDialog::Apply()
{
GCSDK::CProtoBufMsg<CMsgApplyStrangeRestriction> msg( k_EMsgGCApplyStrangeRestriction );
msg.Body().set_strange_part_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
msg.Body().set_item_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
msg.Body().set_strange_attr_index( m_iStrangeSlot );
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_strange_restriction", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
GCClientSystem()->BSendMessage( msg );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CSelectStrangePartToRestrictDialog : public CComboBoxBackpackOverlayDialogBase
{
public:
DECLARE_CLASS_SIMPLE( CSelectStrangePartToRestrictDialog, CComboBoxBackpackOverlayDialogBase );
public:
CSelectStrangePartToRestrictDialog( vgui::Panel *pParent, CEconItemView *pToolItem, CEconItemView *pSubjectItem )
: CComboBoxBackpackOverlayDialogBase( pParent, pSubjectItem )
, m_ToolItem( *pToolItem )
, m_SubjectItem( *pSubjectItem )
{
//
}
private:
virtual void PopulateComboBoxOptions()
{
const wchar_t *pLocBase = GLocalizationProvider()->Find( "#ApplyStrangeRestrictionCombo" );
const CEconTool_StrangePartRestriction *pToolRestriction = m_ToolItem.GetItemDefinition()->GetTypedEconTool<CEconTool_StrangePartRestriction>();
Assert( pToolRestriction );
KeyValues *pKeyValues = new KeyValues( "data" );
for ( int i = 0; i < GetKillEaterAttrCount(); i++ )
{
uint32 unScoreType;
if ( !GetItemSchema()->BCanStrangeFilterApplyToStrangeSlotInItem( pToolRestriction->GetRestrictionType(), pToolRestriction->GetRestrictionValue(), &m_SubjectItem, i, &unScoreType ) )
continue;
const char *pszTypeLocKey = GetItemSchema()->GetKillEaterScoreTypeLocString( unScoreType );
if ( !pszTypeLocKey )
continue;
pKeyValues->SetInt( "data", i );
pKeyValues->SetString( "token", pszTypeLocKey );
GetComboBox()->AddItem( CConstructLocalizedString( pLocBase, GLocalizationProvider()->Find( pszTypeLocKey ) ), pKeyValues );
}
pKeyValues->deleteThis();
Assert( GetComboBox()->GetItemCount() > 0 );
GetComboBox()->ActivateItemByRow( 0 );
}
virtual void OnComboBoxApplication()
{
KeyValues *pKVActiveUserData = GetComboBox()->GetActiveItemUserData();
int iIndex = pKVActiveUserData ? pKVActiveUserData->GetInt( "data", -1 ) : -1;
if ( iIndex < 0 )
return;
// FIXME: CConfirmStrangePartApplicationDialog is wrong class
CConfirmStrangeRestrictionApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmStrangeRestrictionApplicationDialog( GetParent(), &m_ToolItem, &m_SubjectItem, iIndex, pKVActiveUserData ? pKVActiveUserData->GetString( "token", NULL ) : NULL ) );
MakeModalAndBringToFront( pDialog );
}
virtual const char *GetTitleLabelLocalizationToken() const { return "#ApplyStrangeRestrictionPartTitle"; }
private:
CEconItemView m_ToolItem;
CEconItemView m_SubjectItem;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_StrangePartRestriction::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
if ( EconUI()->GetBackpackPanel() )
{
EconUI()->GetBackpackPanel()->SetComboBoxOverlaySelectionItem( pSubject );
}
CSelectStrangePartToRestrictDialog *pDialog = vgui::SETUP_PANEL( new CSelectStrangePartToRestrictDialog( pParent, pTool, pSubject ) );
MakeModalAndBringToFront( pDialog );
}
//-----------------------------------------------------------------------------
class CWaitingDialog : public CGenericWaitingDialog
{
public:
CWaitingDialog( vgui::Panel *pParent ) : CGenericWaitingDialog( pParent )
{
}
protected:
virtual void OnTimeout()
{
// Play an exciting sound!
vgui::surface()->PlaySound( "misc/achievement_earned.wav" );
// Show them the result item.
InventoryManager()->ShowItemsPickedUp( true );
}
};
//-----------------------------------------------------------------------------
// Purpose: Confirm / abort card upgrade tool application
//-----------------------------------------------------------------------------
class CConfirmApplyStrangifierDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmApplyStrangifierDialog, CBaseToolUsageDialog );
public:
CConfirmApplyStrangifierDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject, const char *pszPromptLocToken, const char *pszTransactionReason, const char *pszUpdatingText = "" )
: CBaseToolUsageDialog( pParent, "ConfirmApplyStrangifierDialog", pTool, pToolSubject )
, m_sPromptLocToken( pszPromptLocToken )
, m_sTransactionReason( pszTransactionReason )
, m_sUpdatingText( pszUpdatingText )
{
//
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmApplyStrangifierDialog.res" );
BaseClass::ApplySchemeSettings( pScheme );
CExLabel* pTextLabel = dynamic_cast<CExLabel*>( FindChildByName( "ConfirmLabel" ) );
if( pTextLabel && m_pToolModelPanel )
{
wchar_t *pszBaseString = g_pVGuiLocalize->Find( m_sPromptLocToken );
wchar_t wTempFinalString[1024] = { 0 };
if ( pszBaseString )
{
V_wcscpy_safe( wTempFinalString, pszBaseString );
}
// If the strangifier is untradable, add an extra warning in the prompt to let the user know
if( m_pToolModelPanel->GetItem() && !m_pToolModelPanel->GetItem()->IsTradable() &&
m_pSubjectModelPanel && m_pSubjectModelPanel->GetItem() )
{
wchar_t *pszUntradableString = g_pVGuiLocalize->Find( "ToolStrangifierUntradableWarning" );
// Stick the names of the items into the string
wchar_t wTempUntradable[1024] = { 0 };
g_pVGuiLocalize->ConstructString_safe( wTempUntradable, pszUntradableString, 2, m_pToolModelPanel->GetItem()->GetItemName(), m_pSubjectModelPanel->GetItem()->GetItemName() );
// Concat onto the the original string
V_wcscat_safe( wTempFinalString, wTempUntradable, sizeof( wTempUntradable ) );
}
pTextLabel->SetText( wTempFinalString );
}
}
virtual void Apply( void )
{
if ( m_pSubjectModelPanel->GetItem()->GetItemID() != INVALID_ITEM_ID )
{
GCSDK::CProtoBufMsg<CMsgApplyToolToItem> msg( k_EMsgGCApplyXifier );
msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
msg.Body().set_subject_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
GCClientSystem()->BSendMessage( msg );
}
else
{
GCSDK::CProtoBufMsg<CMsgApplyToolToBaseItem> msg( k_EMsgGCApplyBaseItemXifier );
msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
msg.Body().set_baseitem_def_index( m_pSubjectModelPanel->GetItem()->GetStaticData()->GetDefinitionIndex() );
GCClientSystem()->BSendMessage( msg );
}
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), m_sTransactionReason.String() );
if ( *m_sUpdatingText.String() )
{
vgui::surface()->PlaySound( "ui/item_gift_wrap_use.wav" );
ShowWaitingDialog( new CWaitingDialog( NULL ), m_sUpdatingText.String(), true, false, 5.0f );
}
}
private:
CUtlString m_sPromptLocToken;
CUtlString m_sTransactionReason;
CUtlString m_sUpdatingText;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_Strangifier::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmApplyStrangifierDialog *pDialog = vgui::SETUP_PANEL( new CConfirmApplyStrangifierDialog( pParent, pTool, pSubject, "ToolStrangifierConfirm", "strangified_item" ) );
MakeModalAndBringToFront( pDialog );
}
//-----------------------------------------------------------------------------
void CEconTool_KillStreakifier::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmApplyStrangifierDialog *pDialog = vgui::SETUP_PANEL( new CConfirmApplyStrangifierDialog( pParent, pTool, pSubject, "ToolKillStreakifierConfirm", "killstreakified_item" ) );
MakeModalAndBringToFront( pDialog );
}
//-----------------------------------------------------------------------------
void CEconTool_Festivizer::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmApplyStrangifierDialog *pDialog = vgui::SETUP_PANEL( new CConfirmApplyStrangifierDialog( pParent, pTool, pSubject, "ToolFestivizerConfirm", "festivized_item", "#ToolFestivizerInProgress" ) );
MakeModalAndBringToFront( pDialog );
}
//-----------------------------------------------------------------------------
void CEconTool_Unusualifier::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmApplyStrangifierDialog *pDialog = vgui::SETUP_PANEL( new CConfirmApplyStrangifierDialog( pParent, pTool, pSubject, "ToolUnusualifierConfirm", "unusualified_item", "#ToolUnusualifierInProgress" ) );
MakeModalAndBringToFront( pDialog );
}
//-----------------------------------------------------------------------------
class CConfirmUseItemEaterRechargerDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmUseItemEaterRechargerDialog, CBaseToolUsageDialog );
public:
CConfirmUseItemEaterRechargerDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
: CBaseToolUsageDialog( pParent, "ConfirmUseItemEaterRechargerDialog", pTool, pToolSubject )
{
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmUseItemEaterRechargerDialog.res" );
// Find the number of charges to add by looking at item tool rescritions.
const CEconTool_ItemEaterRecharger *pTool = m_pToolModelPanel->GetItem()->GetItemDefinition()->GetTypedEconTool<CEconTool_ItemEaterRecharger>();
if ( pTool )
{
int iCharges = pTool->GetChargesForItemDefId( m_pSubjectModelPanel->GetItem()->GetItemDefIndex() );
SetDialogVariable( "charges_added", iCharges );
}
BaseClass::ApplySchemeSettings( pScheme );
}
virtual void Apply( void )
{
GCSDK::CProtoBufMsg<CMsgApplyToolToItem> msg( k_EMsgGCItemEaterRecharger );
msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
msg.Body().set_subject_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "recharging_item" );
GCClientSystem()->BSendMessage( msg );
}
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_ItemEaterRecharger::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmUseItemEaterRechargerDialog *pDialog = vgui::SETUP_PANEL( new CConfirmUseItemEaterRechargerDialog( pParent, pTool, pSubject ) );
MakeModalAndBringToFront( pDialog );
}
//-----------------------------------------------------------------------------
// Purpose: Confirm / abort card upgrade tool application
//-----------------------------------------------------------------------------
class CConfirmCardUpgradeApplicationDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmCardUpgradeApplicationDialog, CBaseToolUsageDialog );
public:
CConfirmCardUpgradeApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
: CBaseToolUsageDialog( pParent, "ConfirmApplyCardUpgradeApplicationDialog", pTool, pToolSubject )
{
//
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmApplyCardUpgradeApplicationDialog.res" );
// See how many card upgrades have already been applied
CCountUserGeneratedAttributeIterator countIterator;
m_pSubjectModelPanel->GetItem()->IterateAttributes( &countIterator );
int iRemainingStrangePartSlots = GetMaxCardUpgradesPerItem() - countIterator.GetCount();
SetDialogVariable( "remaining_upgrade_card_slots", iRemainingStrangePartSlots );
SetDialogVariable( "subject_item_def_name", GLocalizationProvider()->Find( m_pSubjectModelPanel->GetItem()->GetItemDefinition()->GetItemBaseName() ) );
SetDialogVariable( "slot_singular_plural", GLocalizationProvider()->Find( iRemainingStrangePartSlots == 1 ? "#Econ_FreeSlot_Singular" : "#Econ_FreeSlot_Plural" ) );
BaseClass::ApplySchemeSettings( pScheme );
}
virtual void Apply( void )
{
GCSDK::CProtoBufMsg<CMsgApplyUpgradeCard> msg( k_EMsgGCApplyUpgradeCard );
msg.Body().set_upgrade_card_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
msg.Body().set_subject_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_upgrade_card", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
GCClientSystem()->BSendMessage( msg );
}
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_UpgradeCard::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmCardUpgradeApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmCardUpgradeApplicationDialog( pParent, pTool, pSubject ) );
MakeModalAndBringToFront( pDialog );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CConfirmTransmogrifyApplicationDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmTransmogrifyApplicationDialog, CBaseToolUsageDialog );
public:
CConfirmTransmogrifyApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
: CBaseToolUsageDialog( pParent, "ConfirmTransmogrifyApplicationDialog", pTool, pToolSubject )
{
//
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmTransmogrifyApplicationDialog.res" );
const CEconTool_ClassTransmogrifier *pTool = m_pToolModelPanel->GetItem()->GetItemDefinition()->GetTypedEconTool<CEconTool_ClassTransmogrifier>();
Assert( pTool );
if ( pTool )
{
int iOutputClass = pTool->GetOutputClass();
if ( iOutputClass > 0 && iOutputClass < LOADOUT_COUNT )
{
SetDialogVariable( "output_class", GLocalizationProvider()->Find( g_aPlayerClassNames[ iOutputClass ] ) );
}
}
BaseClass::ApplySchemeSettings( pScheme );
}
virtual void Apply( void )
{
GCSDK::CProtoBufMsg<CMsgApplyToolToItem> msg( k_EMsgGCApplyClassTransmogrifier );
msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
msg.Body().set_subject_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_transmogrifier", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
GCClientSystem()->BSendMessage( msg );
}
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_ClassTransmogrifier::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmTransmogrifyApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmTransmogrifyApplicationDialog( pParent, pTool, pSubject ) );
MakeModalAndBringToFront( pDialog );
}
#ifdef TF_CLIENT_DLL
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CConfirmSpellbookPageApplicationDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmSpellbookPageApplicationDialog, CBaseToolUsageDialog );
public:
CConfirmSpellbookPageApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
: CBaseToolUsageDialog( pParent, "ConfirmSpellbookPageApplicationDialog", pTool, pToolSubject )
{
//
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmSpellbookPageApplicationDialog.res" );
BaseClass::ApplySchemeSettings( pScheme );
}
virtual void Apply( void )
{
GCSDK::CProtoBufMsg<CMsgApplyToolToItem> msg( k_EMsgGCApplyHalloweenSpellbookPage );
msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
msg.Body().set_subject_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_spellbook_page", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
GCClientSystem()->BSendMessage( msg );
}
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_TFSpellbookPage::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmSpellbookPageApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmSpellbookPageApplicationDialog( pParent, pTool, pSubject ) );
MakeModalAndBringToFront( pDialog );
}
//-----------------------------------------------------------------------------
class CConfirmDuckTokenApplicationDialog : public CBaseToolUsageDialog
{
DECLARE_CLASS_SIMPLE( CConfirmDuckTokenApplicationDialog, CBaseToolUsageDialog );
public:
CConfirmDuckTokenApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
: CBaseToolUsageDialog( pParent, "ConfirmApplyDuckTokenDialog", pTool, pToolSubject )
{
//
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
{
LoadControlSettings( "Resource/UI/econ/ConfirmApplyDuckTokenDialog.res" );
BaseClass::ApplySchemeSettings( pScheme );
}
virtual void Apply( void )
{
GCSDK::CProtoBufMsg<CMsgApplyToolToItem> msg( k_EMsgGCApplyDuckToken );
msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
msg.Body().set_subject_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_ducktoken", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
GCClientSystem()->BSendMessage( msg );
}
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEconTool_DuckToken::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
{
CConfirmDuckTokenApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmDuckTokenApplicationDialog( pParent, pTool, pSubject ) );
MakeModalAndBringToFront( pDialog );
}
#endif // TF_CLIENT_DLL
+58
View File
@@ -0,0 +1,58 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef TOOL_ITEMS_H
#define TOOL_ITEMS_H
#ifdef _WIN32
#pragma once
#endif
#include "item_model_panel.h"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CBaseToolUsageDialog : public vgui::EditablePanel
{
DECLARE_CLASS_SIMPLE( CBaseToolUsageDialog, vgui::EditablePanel );
public:
CBaseToolUsageDialog( vgui::Panel *pParent, const char *panelName, CEconItemView *pTool, CEconItemView *pToolSubject );
virtual void ApplySchemeSettings( vgui::IScheme *scheme );
virtual void PerformLayout();
virtual void OnCommand( const char *command );
virtual void OnKeyCodeTyped( vgui::KeyCode code ) OVERRIDE;
virtual void OnKeyCodePressed( vgui::KeyCode code ) OVERRIDE;
virtual void Apply( void ) { return; }
inline CEconItemView *GetToolItem() { return m_pToolModelPanel->GetItem(); };
inline CEconItemView *GetSubjectItem() { return m_pSubjectModelPanel->GetItem(); };
protected:
CItemModelPanel *m_pToolModelPanel;
CItemModelPanel *m_pSubjectModelPanel;
CItemModelPanel *m_pMouseOverItemPanel;
CItemModelPanelToolTip *m_pMouseOverTooltip;
vgui::Label *m_pTitleLabel;
const char *m_pszInternalPanelName;
};
// Utility function for tool dialogs.
void MakeModalAndBringToFront( vgui::EditablePanel *dialog );
bool ToolCanApplyTo( CEconItemView *pTool, CEconItemView *pToolSubject );
// Given a tool and an item to apply the tool's effects upon,
// gather required information from the user and
// send a change request to the GC.
bool ApplyTool( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject );
#endif // TOOL_ITEMS_H
+713
View File
@@ -0,0 +1,713 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include <vgui/ILocalize.h>
#include "vgui_controls/TextEntry.h"
#include "trading_start_dialog.h"
#include "econ_controls.h"
#include "econ_trading.h"
#include "c_playerresource.h"
#include "gcsdk/gcmsg.h"
#include "econ_item_inventory.h"
#include "econ_gcmessages.h"
#include "gc_clientsystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTradingStartDialog::CTradingStartDialog( vgui::Panel *parent ) : vgui::EditablePanel( parent, "TradingStartDialog" )
{
m_pSelectFromServerButton = NULL;
m_pCancelButton = NULL;
m_pButtonKV = NULL;
m_bReapplyButtonKVs = false;
m_pURLFailLabel = NULL;
m_pURLSearchingLabel = NULL;
for ( int i = 0; i < TDS_NUM_STATES; i++ )
{
m_pStatePanels[i] = new vgui::EditablePanel( this, VarArgs("StatePanel%d",i) );
}
m_pPlayerList = new vgui::EditablePanel( this, "PlayerList" );
m_pPlayerListScroller = new vgui::ScrollableEditablePanel( this, m_pPlayerList, "PlayerListScroller" );
ListenForGameEvent( "gameui_hidden" );
Reset();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTradingStartDialog::~CTradingStartDialog( void )
{
if ( m_pButtonKV )
{
m_pButtonKV->deleteThis();
m_pButtonKV = NULL;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::Reset( void )
{
m_iCurrentState = TDS_SELECTING_PLAYER;
m_bGiftMode = false;
m_giftItem = CEconItemView();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::ApplySettings( KeyValues *inResourceData )
{
BaseClass::ApplySettings( inResourceData );
KeyValues *pItemKV = inResourceData->FindKey( "button_kv" );
if ( pItemKV )
{
if ( m_pButtonKV )
{
m_pButtonKV->deleteThis();
}
m_pButtonKV = new KeyValues("button_kv");
pItemKV->CopySubkeys( m_pButtonKV );
m_bReapplyButtonKVs = true;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
LoadControlSettings( "resource/ui/econ/TradingStartDialog.res" );
m_pCancelButton = dynamic_cast<CExButton*>( FindChildByName( "CancelButton" ) );
// Find all the sub buttons, and set their action signals to point to this panel
for ( int i = 0; i < TDS_NUM_STATES; i++ )
{
int iButton = 0;
CExButton *pButton = NULL;
do
{
pButton = dynamic_cast<CExButton*>( m_pStatePanels[i]->FindChildByName( VarArgs("subbutton%d",iButton)) );
if ( pButton )
{
pButton->AddActionSignalTarget( this );
// The second button on the first state is the server button
if ( iButton == 1 )
{
m_pSelectFromServerButton = pButton;
}
iButton++;
}
} while (pButton);
}
m_pURLFailLabel = dynamic_cast<vgui::Label*>( m_pStatePanels[TDS_SELECTING_FROM_PROFILE]->FindChildByName( "URLFailLabel" ) );
m_pURLSearchingLabel = dynamic_cast<vgui::Label*>( m_pStatePanels[TDS_SELECTING_FROM_PROFILE]->FindChildByName( "URLSearchingLabel" ) );
UpdateState();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::PerformLayout( void )
{
BaseClass::PerformLayout();
// Layout the player list buttons
if ( m_pPlayerPanels.Count() )
{
int iButtonH = m_pPlayerPanels[0]->GetTall() + YRES(2);
m_pPlayerList->SetSize( m_pPlayerList->GetWide(), YRES(2) + (iButtonH * m_pPlayerPanels.Count()) );
// These need to all be layout-complete before we can position the player panels,
// because the scrollbar will cause the playerlist entries to move when it lays out.
m_pPlayerList->InvalidateLayout( true );
m_pPlayerListScroller->InvalidateLayout( true );
m_pPlayerListScroller->GetScrollbar()->InvalidateLayout( true );
for ( int i = 0; i < m_pPlayerPanels.Count(); i++ )
{
m_pPlayerPanels[i]->SetPos( 0, YRES(2) + (iButtonH * i) );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::FireGameEvent( IGameEvent *event )
{
const char *type = event->GetName();
if ( Q_strcmp(type, "gameui_hidden") == 0 )
{
Close();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::Close( void )
{
TFModalStack()->PopModal( this );
SetVisible( false );
MarkForDeletion();
PostMessage( GetParent(), new KeyValues("CancelSelection") );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::OnCommand( const char *command )
{
if ( !Q_stricmp( command, "cancel" ) )
{
if ( m_iCurrentState != TDS_SELECTING_PLAYER )
{
m_iCurrentState = TDS_SELECTING_PLAYER;
UpdateState();
return;
}
Close();
return;
}
else if ( !Q_stricmp( command, "friends" ) )
{
m_iCurrentState = TDS_SELECTING_FROM_FRIENDS;
UpdateState();
return;
}
else if ( !Q_stricmp( command, "server" ) )
{
m_iCurrentState = TDS_SELECTING_FROM_SERVER;
UpdateState();
return;
}
else if ( !Q_stricmp( command, "profile" ) )
{
m_iCurrentState = TDS_SELECTING_FROM_PROFILE;
UpdateState();
return;
}
else if ( !Q_strnicmp( command, "select_player", 13 ) )
{
int iPlayer = atoi( command + 13 ) - 1;
if ( iPlayer >= 0 && iPlayer < m_PlayerInfoList.Count() )
{
StartTradeWith( m_PlayerInfoList[iPlayer].m_steamID );
}
return;
}
else if ( !Q_stricmp( command, "url_ok" ) )
{
vgui::TextEntry *pEntry = dynamic_cast<vgui::TextEntry*>( m_pStatePanels[m_iCurrentState]->FindChildByName("URLEntry") );
if ( pEntry )
{
const int maxURLLength = 512;
char inputURL[ maxURLLength ];
pEntry->GetText( inputURL, maxURLLength );
if ( m_pURLSearchingLabel )
{
m_pURLSearchingLabel->SetVisible( false );
}
bool bSuccess = ExtractSteamIDFromURL( inputURL );
if ( m_pURLFailLabel )
{
m_pURLFailLabel->SetVisible( !bSuccess );
}
}
return;
}
BaseClass::OnCommand( command );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::SendGiftTo( CSteamID steamID )
{
Trading_SendGift( steamID, m_giftItem );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::StartTradeWith( CSteamID steamID )
{
m_iCurrentState = TDS_SELECTING_PLAYER;
OnCommand( "cancel" );
if ( !m_bGiftMode )
{
Trading_RequestTrade( steamID );
return;
}
Trading_SendGift( steamID, m_giftItem );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CTradingStartDialog::ExtractSteamIDFromURL( char *inputURL )
{
if ( !inputURL || !inputURL[0] )
return false;
EUniverse localUniverse = GetUniverse();
if ( localUniverse == k_EUniverseInvalid )
return false;
CSteamID steamID;
int iLen = Q_strlen(inputURL);
// First, see if it's a profile link. If it is, clip the SteamID from it.
const char *pszProfilePrepend = ( localUniverse == k_EUniversePublic ) ? "http://steamcommunity.com/profiles/" : "http://beta.steamcommunity.com/profiles/";
int iProfilePrependLen = Q_strlen(pszProfilePrepend);
if ( Q_strnicmp( pszProfilePrepend, inputURL, iProfilePrependLen ) == 0 )
{
if ( iLen > iProfilePrependLen )
{
steamID.SetFromString( &inputURL[iProfilePrependLen], localUniverse );
if ( steamID.IsValid() )
{
StartTradeWith( steamID );
return true;
}
}
}
else
{
// If it's an id link, we download it and extract the steam ID from it.
const char *pszIDPrepend = ( localUniverse == k_EUniversePublic ) ? "http://steamcommunity.com/id/" : "http://beta.steamcommunity.com/id/";
int iIDPrependLen = Q_strlen(pszIDPrepend);
if ( Q_strnicmp( pszIDPrepend, inputURL, iIDPrependLen ) == 0 )
{
if ( iLen > iIDPrependLen )
{
// Trim off a trailing slash
if ( inputURL[iLen-1] == '/' || inputURL[iLen-1] == '\\' )
{
inputURL[iLen-1] = '\0';
}
GCSDK::CGCMsg<MsgGCLookupAccount_t> msg( k_EMsgGCLookupAccount );
msg.Body().m_uiFindType = GCSDK::k_EFindAccountTypeURL;
msg.AddStrData( &inputURL[iIDPrependLen] );
GCClientSystem()->BSendMessage( msg );
// For now, return true and wait.
if ( m_pURLSearchingLabel )
{
m_pURLSearchingLabel->SetVisible( true );
}
return true;
}
}
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::OnLookupAccountResponse( uint64 iAccountID )
{
if ( m_pURLSearchingLabel )
{
m_pURLSearchingLabel->SetVisible( false );
}
CSteamID steamID( iAccountID );
if ( steamID.IsValid() )
{
if ( m_pURLFailLabel )
{
m_pURLFailLabel->SetVisible( false );
}
StartTradeWith( steamID );
}
else
{
if ( m_pURLFailLabel )
{
m_pURLFailLabel->SetVisible( true );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Sets a gift for the dialog to hand out. If pGiftItem is NULL, which is
// fine, make sure to clear our our own existing gift.
//-----------------------------------------------------------------------------
void CTradingStartDialog::SetGift( CEconItemView* pGiftItem )
{
if ( pGiftItem )
{
m_giftItem = *pGiftItem;
m_bGiftMode = true;
}
else
{
// Reset to default
m_giftItem = CEconItemView();
m_bGiftMode = false;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::OnTextChanged( KeyValues *data )
{
vgui::TextEntry *pEntry = dynamic_cast<vgui::TextEntry*>( m_pStatePanels[m_iCurrentState]->FindChildByName("URLEntry") );
if ( !pEntry )
return;
Panel *pPanel = reinterpret_cast<vgui::Panel *>( data->GetPtr("panel") );
if ( pEntry == pPanel )
{
CExButton *pButton = dynamic_cast<CExButton*>( m_pStatePanels[m_iCurrentState]->FindChildByName( "subbutton0" ) );
if ( pButton )
{
pButton->SetEnabled( pEntry->GetTextLength() > 0 );
}
if ( m_pURLFailLabel )
{
m_pURLFailLabel->SetVisible( false );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::UpdateState( void )
{
for ( int i = 0; i < TDS_NUM_STATES; i++ )
{
if ( !m_pStatePanels[i] )
continue;
m_pStatePanels[i]->SetVisible( m_iCurrentState == i );
}
if ( m_pSelectFromServerButton )
{
m_pSelectFromServerButton->SetEnabled( engine->IsInGame() );
}
if ( m_iCurrentState == TDS_SELECTING_PLAYER )
{
m_pCancelButton->SetText( g_pVGuiLocalize->Find( "#Cancel" ) );
}
else
{
m_pCancelButton->SetText( g_pVGuiLocalize->Find( "#TF_Back" ) );
}
switch ( m_iCurrentState )
{
case TDS_SELECTING_FROM_FRIENDS:
SetupSelectFriends();
break;
case TDS_SELECTING_FROM_SERVER:
SetupSelectServer();
break;
case TDS_SELECTING_FROM_PROFILE:
SetupSelectProfile();
break;
case TDS_SELECTING_PLAYER:
default:
m_pPlayerListScroller->SetVisible( false );
break;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::SetupSelectFriends( void )
{
m_PlayerInfoList.Purge();
if ( steamapicontext && steamapicontext->SteamFriends() )
{
// Get our game info so we can use that to test if our friends are connected to the same game as us
FriendGameInfo_t myGameInfo;
CSteamID mySteamID = steamapicontext->SteamUser()->GetSteamID();
steamapicontext->SteamFriends()->GetFriendGamePlayed( mySteamID, &myGameInfo );
int iFriends = steamapicontext->SteamFriends()->GetFriendCount( k_EFriendFlagImmediate );
for ( int i = 0; i < iFriends; i++ )
{
CSteamID friendSteamID = steamapicontext->SteamFriends()->GetFriendByIndex( i, k_EFriendFlagImmediate );
FriendGameInfo_t gameInfo;
if ( !steamapicontext->SteamFriends()->GetFriendGamePlayed( friendSteamID, &gameInfo ) )
continue;
// Friends is in-game. Make sure it's TF2.
if ( gameInfo.m_gameID.IsValid() && gameInfo.m_gameID == myGameInfo.m_gameID )
{
const char *pszName = steamapicontext->SteamFriends()->GetFriendPersonaName( friendSteamID );
int idx = m_PlayerInfoList.AddToTail();
trade_partner_info_t &info = m_PlayerInfoList[idx];
info.m_steamID = friendSteamID;
info.m_name = pszName;
}
}
}
UpdatePlayerList();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::SetupSelectServer( void )
{
m_PlayerInfoList.Purge();
if ( steamapicontext && steamapicontext->SteamUtils() )
{
for( int iPlayerIndex = 1 ; iPlayerIndex <= MAX_PLAYERS; iPlayerIndex++ )
{
// find all players who are on the local player's team
int iLocalPlayerIndex = GetLocalPlayerIndex();
if( ( iPlayerIndex != iLocalPlayerIndex ) && ( g_PR->IsConnected( iPlayerIndex ) ) )
{
player_info_t pi;
if ( !engine->GetPlayerInfo( iPlayerIndex, &pi ) )
continue;
if ( !pi.friendsID )
continue;
CSteamID steamID( pi.friendsID, 1, GetUniverse(), k_EAccountTypeIndividual );
int idx = m_PlayerInfoList.AddToTail();
trade_partner_info_t &info = m_PlayerInfoList[idx];
info.m_steamID = steamID;
info.m_name = pi.name;
}
}
}
UpdatePlayerList();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::SetupSelectProfile( void )
{
vgui::TextEntry *pEntry = dynamic_cast<vgui::TextEntry*>( m_pStatePanels[m_iCurrentState]->FindChildByName("URLEntry") );
if ( pEntry )
{
pEntry->SetText( "" );
pEntry->RequestFocus();
pEntry->AddActionSignalTarget( this );
}
if ( m_pURLFailLabel )
{
m_pURLFailLabel->SetVisible( false );
}
if ( m_pURLSearchingLabel )
{
m_pURLSearchingLabel->SetVisible( false );
}
CExButton *pButton = dynamic_cast<CExButton*>( m_pStatePanels[m_iCurrentState]->FindChildByName( "subbutton0" ) );
if ( pButton )
{
pButton->SetEnabled( false );
}
m_pPlayerListScroller->SetVisible( false );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradingStartDialog::UpdatePlayerList( void )
{
vgui::Label *pLabelEmpty = dynamic_cast<vgui::Label*>( m_pStatePanels[m_iCurrentState]->FindChildByName("EmptyPlayerListLabel") );
vgui::Label *pLabelQuery = dynamic_cast<vgui::Label*>( m_pStatePanels[m_iCurrentState]->FindChildByName("QueryLabel") );
// If we have no players in our list, show the no-player label.
if ( m_PlayerInfoList.Count() == 0 )
{
if ( pLabelEmpty )
{
pLabelEmpty->SetVisible( true );
}
if ( pLabelQuery )
{
pLabelQuery->SetVisible( false );
}
return;
}
// First, reapply any KVs we have to reapply
if ( m_bReapplyButtonKVs )
{
m_bReapplyButtonKVs = false;
if ( m_pButtonKV )
{
FOR_EACH_VEC( m_pPlayerPanels, i )
{
m_pPlayerPanels[i]->ApplySettings( m_pButtonKV );
}
}
}
// Otherwise, build the player panels from the list of steam IDs
for ( int i = 0; i < m_PlayerInfoList.Count(); i++ )
{
if ( m_pPlayerPanels.Count() <= i )
{
m_pPlayerPanels.AddToTail();
m_pPlayerPanels[i] = new CTradeTargetPanel( m_pPlayerList, VarArgs("player%d",i) );
m_pPlayerPanels[i]->GetButton()->SetCommand( VarArgs("select_player%d",i+1) );
m_pPlayerPanels[i]->GetButton()->AddActionSignalTarget( this );
m_pPlayerPanels[i]->GetAvatar()->SetShouldDrawFriendIcon( false );
m_pPlayerPanels[i]->GetAvatar()->SetMouseInputEnabled( false );
if ( m_pButtonKV )
{
m_pPlayerPanels[i]->ApplySettings( m_pButtonKV );
m_pPlayerPanels[i]->InvalidateLayout( true );
}
}
m_pPlayerPanels[i]->SetInfo( m_PlayerInfoList[i].m_steamID, m_PlayerInfoList[i].m_name.Get() );
}
m_pPlayerListScroller->GetScrollbar()->SetAutohideButtons( true );
m_pPlayerListScroller->GetScrollbar()->SetValue( 0 );
// Remove any extra player panels
for ( int i = m_pPlayerPanels.Count()-1; i >= m_PlayerInfoList.Count(); i-- )
{
m_pPlayerPanels[i]->MarkForDeletion();
m_pPlayerPanels.Remove(i);
}
if ( pLabelEmpty )
{
pLabelEmpty->SetVisible( false );
}
if ( pLabelQuery )
{
pLabelQuery->SetVisible( true );
}
m_pPlayerListScroller->SetVisible( true );
InvalidateLayout();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTradeTargetPanel::SetInfo( const CSteamID &steamID, const char *pszName )
{
if ( !steamapicontext || !steamapicontext->SteamFriends() )
return;
m_pAvatar->SetPlayer( steamID, k_EAvatarSize64x64 );
m_pButton->SetText( pszName );
}
static vgui::DHANDLE<CTradingStartDialog> g_hTradingStartDialog;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTradingStartDialog *OpenTradingStartDialog( vgui::Panel *pParent, CEconItemView* pOptGiftItem )
{
if (!g_hTradingStartDialog.Get())
{
g_hTradingStartDialog = vgui::SETUP_PANEL( new CTradingStartDialog( pParent ) );
}
g_hTradingStartDialog->InvalidateLayout( false, true );
g_hTradingStartDialog->Reset();
g_hTradingStartDialog->SetVisible( true );
g_hTradingStartDialog->MakePopup();
g_hTradingStartDialog->MoveToFront();
g_hTradingStartDialog->SetKeyBoardInputEnabled(true);
g_hTradingStartDialog->SetMouseInputEnabled(true);
g_hTradingStartDialog->SetGift( pOptGiftItem );
TFModalStack()->PushModal( g_hTradingStartDialog );
return g_hTradingStartDialog;
}
//-----------------------------------------------------------------------------
// Purpose: GC Msg handler to receive the Lookup Account response
//-----------------------------------------------------------------------------
class CGCLookupAccountResponse : public GCSDK::CGCClientJob
{
public:
CGCLookupAccountResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
{
GCSDK::CGCMsg<MsgGCStandardResponse_t> msg( pNetPacket );
uint8 iAccounts = 0;
uint64 iAccountID = 0;
if ( msg.BReadUint8Data( &iAccounts ) )
{
// We only care about the first account we find in this panel.
if ( iAccounts > 0 )
{
msg.BReadUint64Data( &iAccountID );
}
}
if ( g_hTradingStartDialog.Get() )
{
g_hTradingStartDialog->OnLookupAccountResponse( iAccountID );
}
return true;
}
};
GC_REG_JOB( GCSDK::CGCClient, CGCLookupAccountResponse, "CGCLookupAccountResponse", k_EMsgGCLookupAccountResponse, GCSDK::k_EServerTypeGCClient );
+115
View File
@@ -0,0 +1,115 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef TRADING_START_DIALOG_H
#define TRADING_START_DIALOG_H
#ifdef _WIN32
#pragma once
#endif
#include "vgui_controls/EditablePanel.h"
#include "vgui_controls/ScrollableEditablePanel.h"
#include "econ_controls.h"
#include "vgui_avatarimage.h"
// Trading Dialog states
enum
{
TDS_SELECTING_PLAYER,
TDS_SELECTING_FROM_FRIENDS,
TDS_SELECTING_FROM_SERVER,
TDS_SELECTING_FROM_PROFILE,
TDS_NUM_STATES,
};
// Button that displays the name & avatar image of a potential trade target
class CTradeTargetPanel : public vgui::EditablePanel
{
DECLARE_CLASS_SIMPLE( CTradeTargetPanel, vgui::EditablePanel );
public:
CTradeTargetPanel( vgui::Panel *parent, const char *name ) : vgui::EditablePanel( parent, name )
{
m_pAvatar = new CAvatarImagePanel( this, "avatar" );
m_pButton = new CExButton( this, "button", "", parent );
}
~CTradeTargetPanel( void )
{
m_pAvatar->MarkForDeletion();
m_pButton->MarkForDeletion();
}
void SetInfo( const CSteamID &steamID, const char *pszName );
CAvatarImagePanel *GetAvatar( void ) { return m_pAvatar; }
CExButton *GetButton( void ) { return m_pButton; }
private:
// Embedded panels
CAvatarImagePanel *m_pAvatar;
CExButton *m_pButton;
};
//-----------------------------------------------------------------------------
// A dialog that allows users to select who they want to trade with.
//-----------------------------------------------------------------------------
class CTradingStartDialog : public vgui::EditablePanel, public CGameEventListener
{
DECLARE_CLASS_SIMPLE( CTradingStartDialog, vgui::EditablePanel );
public:
CTradingStartDialog( vgui::Panel *parent );
~CTradingStartDialog( void );
virtual void ApplySettings( KeyValues *inResourceData );
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void PerformLayout( void );
virtual void OnCommand( const char *command );
virtual void FireGameEvent( IGameEvent *event );
void Close( void );
void Reset( void );
void UpdateState( void );
void SetupSelectFriends( void );
void SetupSelectServer( void );
void SetupSelectProfile( void );
void UpdatePlayerList( void );
void SendGiftTo( CSteamID steamID );
void StartTradeWith( CSteamID steamID );
bool ExtractSteamIDFromURL( char *inputURL );
void OnLookupAccountResponse( uint64 iAccountID );
bool IsInGiftMode( ) const { return m_bGiftMode; }
void SetGift( CEconItemView* pGiftItem );
MESSAGE_FUNC_PARAMS( OnTextChanged, "TextChanged", data );
private:
struct trade_partner_info_t
{
CSteamID m_steamID;
CUtlString m_name;
};
vgui::EditablePanel *m_pStatePanels[TDS_NUM_STATES];
int m_iCurrentState;
CExButton *m_pSelectFromServerButton;
CExButton *m_pCancelButton;
vgui::EditablePanel *m_pPlayerList;
vgui::ScrollableEditablePanel *m_pPlayerListScroller;
CUtlVector<trade_partner_info_t> m_PlayerInfoList;
CUtlVector<CTradeTargetPanel*> m_pPlayerPanels;
KeyValues *m_pButtonKV;
bool m_bReapplyButtonKVs;
vgui::Label *m_pURLFailLabel;
vgui::Label *m_pURLSearchingLabel;
CEconItemView m_giftItem;
bool m_bGiftMode;
};
CTradingStartDialog *OpenTradingStartDialog( vgui::Panel *pParent, CEconItemView* pOptGiftItem = NULL );
#endif // TRADING_START_DIALOG_H