summaryrefslogtreecommitdiff
path: root/game/client/tf/vgui/crate_detail_panels.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/client/tf/vgui/crate_detail_panels.cpp')
-rw-r--r--game/client/tf/vgui/crate_detail_panels.cpp388
1 files changed, 388 insertions, 0 deletions
diff --git a/game/client/tf/vgui/crate_detail_panels.cpp b/game/client/tf/vgui/crate_detail_panels.cpp
new file mode 100644
index 0000000..dcde85d
--- /dev/null
+++ b/game/client/tf/vgui/crate_detail_panels.cpp
@@ -0,0 +1,388 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+
+#include "cbase.h"
+#include "crate_detail_panels.h"
+#include "vgui_controls/TextImage.h"
+#include "econ_gcmessages.h"
+#include "gc_clientsystem.h"
+#include "econ_ui.h"
+#include <vgui/ISurface.h>
+#include "econ_item_inventory.h"
+#include "econ/tool_items/tool_items.h"
+
+#define SHUFFLE_TIME 5.f
+
+float CInputStringForItemBackpackOverlayDialog::m_sflNextShuffleTime = 0.f;
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CInputStringForItemBackpackOverlayDialog::CInputStringForItemBackpackOverlayDialog( vgui::Panel *pParent, CEconItemView *pItem, CEconItemView *pChosenKey )
+ : vgui::EditablePanel( pParent, "InputStringForItemBackpackOverlayDialog" )
+ , m_Item( *pItem )
+ , m_pPreviewModelPanel( NULL )
+ , m_pTextEntry( NULL )
+ , m_pItemModelPanelKVs( NULL )
+ , m_bUpdateRecieved( false )
+{
+ if ( pChosenKey )
+ {
+ m_UseableKey = *pChosenKey;
+ }
+ m_pPreviewModelPanel = new CItemModelPanel( this, "preview_model" );
+ m_pTextEntry = new vgui::TextEntry( this, "TextEntryControl" );
+ m_pShuffleButton = new CExButton( this, "ShuffleButton", "Shuffle" );
+ m_pRareLootLabel = new CExLabel( this, "RareLootLabel", "#Econ_Revolving_Loot_List_Rare_Item" );
+ m_pProgressBar = new vgui::ProgressBar( this, "ShuffleProgress" );
+ m_pGetKeyButton = new CExButton( this, "GetKeyButton", "getkey" );
+ m_pUseKeyButton = new CExButton( this, "UseKeyButton", "usekey" );
+
+ m_pMouseOverItemPanel = vgui::SETUP_PANEL( new CItemModelPanel( this, "mouseoveritempanel" ) );
+ m_pMouseOverTooltip = new CItemModelPanelToolTip( this );
+ m_pMouseOverTooltip->SetupPanels( this, m_pMouseOverItemPanel );
+
+ ListenForGameEvent( "inventory_updated" );
+}
+
+CInputStringForItemBackpackOverlayDialog::~CInputStringForItemBackpackOverlayDialog()
+{
+ if ( m_pItemModelPanelKVs )
+ {
+ m_pItemModelPanelKVs->deleteThis();
+ m_pItemModelPanelKVs = NULL;
+ }
+
+ m_vecContentsPanels.PurgeAndDeleteElements();
+}
+
+void CInputStringForItemBackpackOverlayDialog::FireGameEvent( IGameEvent *event )
+{
+ // If we're not visible, ignore all events
+ if ( !IsVisible() )
+ return;
+
+ // Something caused our inventory to update. Assuming it was from our shuffle
+ // then we need to update ourselves.
+ const char *type = event->GetName();
+ if ( Q_strcmp( "inventory_updated", type ) == 0 )
+ {
+ m_bUpdateRecieved = true;
+ }
+}
+
+void CInputStringForItemBackpackOverlayDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ LoadControlSettings( "Resource/UI/econ/InputStringForItemBackpackOverlayDialog.res" );
+
+ CCrateLootListWrapper itemWrapper( &m_Item );
+ const IEconLootList *pLootList = itemWrapper.GetEconLootList();
+ // Set the crate footer text. The crate itself specifies what to use.
+ if ( pLootList->GetLootListFooterLocalizationKey() )
+ {
+ m_pRareLootLabel->SetText( pLootList->GetLootListFooterLocalizationKey() );
+ }
+ else
+ {
+ const char *pszRareLootListFooterLocalizationKey = m_Item.GetItemDefinition()->GetDefinitionString( "loot_list_rare_item_footer", "#Econ_Revolving_Loot_List_Rare_Item" );
+ m_pRareLootLabel->SetText( pszRareLootListFooterLocalizationKey );
+ }
+
+ // Use the gradient border for the tooltip
+ m_pMouseOverItemPanel->SetBorder( pScheme->GetBorder("LoadoutItemPopupBorder") );
+
+ m_pPreviewModelPanel->SetItem( &m_Item );
+ m_pPreviewModelPanel->SetActAsButton( false, false ); // Dont mess around with the mouse
+
+ m_pTextEntry->RequestFocus();
+}
+
+void CInputStringForItemBackpackOverlayDialog::ApplySettings( KeyValues *inResourceData )
+{
+ BaseClass::ApplySettings( inResourceData );
+
+ // Pull out the model panel KVs for this panel
+ KeyValues *pItemKV = inResourceData->FindKey( "modelpanels_kv" );
+ if ( pItemKV )
+ {
+ if ( m_pItemModelPanelKVs )
+ {
+ m_pItemModelPanelKVs->deleteThis();
+ }
+ m_pItemModelPanelKVs = new KeyValues( "modelpanels_kv" );
+ pItemKV->CopySubkeys( m_pItemModelPanelKVs );
+ }
+
+ CreateItemPanels();
+}
+
+void CInputStringForItemBackpackOverlayDialog::CreateItemPanels()
+{
+ CCrateLootListWrapper itemWrapper( &m_Item );
+ const IEconLootList *pLootList = itemWrapper.GetEconLootList();
+
+ class CItemDefLootListIterator : public IEconLootList::IEconLootListIterator
+ {
+ public:
+ CItemDefLootListIterator( CUtlVector< item_definition_index_t > *pVecItemDefs )
+ : m_pVecItemDefs( pVecItemDefs )
+ {}
+
+ virtual void OnIterate( item_definition_index_t unItemDefIndex ) OVERRIDE
+ {
+ const CEconItemDefinition *pItemDef = GetItemSchema()->GetItemDefinition( unItemDefIndex );
+ if ( pItemDef && pItemDef->BValidForShuffle() )
+ {
+ m_pVecItemDefs->AddToTail( unItemDefIndex );
+ }
+ }
+
+ private:
+ CUtlVector< item_definition_index_t > * const m_pVecItemDefs;
+ };
+
+ // Get the drops from the item
+ CUtlVector< item_definition_index_t > vecItemDefs;
+ CItemDefLootListIterator it( &vecItemDefs );
+ pLootList->EnumerateUserFacingPotentialDrops( &it );
+
+ if ( !m_pItemModelPanelKVs )
+ return;
+
+ if ( m_vecContentsPanels.Count() != vecItemDefs.Count() )
+ {
+ m_vecContentsPanels.PurgeAndDeleteElements();
+
+ FOR_EACH_VEC( vecItemDefs, i )
+ {
+ // Create new panel
+ CItemModelPanel* pItemPanel = m_vecContentsPanels[ m_vecContentsPanels.AddToTail( new CItemModelPanel( this, CFmtStr( "item_preview_%d", i ) ) ) ];
+ pItemPanel->ApplySettings( m_pItemModelPanelKVs );
+ pItemPanel->InvalidateLayout( true );
+ pItemPanel->SetActAsButton( false, true ); // Lets us get mouse enter/exit evens for tooltips
+ pItemPanel->SetTooltip( m_pMouseOverTooltip, "" ); // Tooltip panel to use
+ }
+ }
+
+ // Create the panels and set the items into them
+ FOR_EACH_VEC( vecItemDefs, i )
+ {
+ const item_definition_index_t &itemDef = vecItemDefs[i];
+
+ CItemModelPanel* pItemPanel = m_vecContentsPanels[i];
+
+ CEconItemView item;
+ item.SetItemDefIndex( itemDef );
+ item.SetItemQuality( AE_UNIQUE ); // Unique by default
+ item.SetItemLevel( 0 ); // Hide this?
+ item.SetInitialized( true );
+ item.SetItemOriginOverride( kEconItemOrigin_Invalid );
+
+ pItemPanel->SetItem( &item );
+ }
+}
+
+void CInputStringForItemBackpackOverlayDialog::PerformLayout( void )
+{
+ BaseClass::PerformLayout();
+
+ // Find out how wide these panels will be side by side
+ const int nBuffer = 5;
+ int nTotalWide = 0;
+ const int nCount = m_vecContentsPanels.Count();
+ if ( nCount )
+ {
+ const int nWide = m_vecContentsPanels.Head()->GetWide();
+ nTotalWide = (nCount * nWide) + ( (nCount - 1) * nBuffer );
+ }
+
+ // Find out how much space the panels take up within the parent
+ int nParentWide = GetWide();
+ int nDiff = nParentWide - nTotalWide;
+ // How far we need to offset from the left edge
+ int nStartOffset = nDiff / 2;
+
+ // Place all the panels side by side
+ FOR_EACH_VEC( m_vecContentsPanels, i )
+ {
+ CItemModelPanel* pItemPanel = m_vecContentsPanels[ i ];
+
+ const int nWide = pItemPanel->GetWide();
+
+ pItemPanel->SetPos( nStartOffset + i * (nWide + nBuffer), YRES(150) );
+ pItemPanel->SetVisible( true );
+ }
+
+ // Which button to show
+ m_pUseKeyButton->SetVisible( m_UseableKey.IsValid() );
+ m_pGetKeyButton->SetVisible( !m_UseableKey.IsValid() );
+}
+
+void CInputStringForItemBackpackOverlayDialog::OnCommand( const char *command )
+{
+ if ( !Q_strnicmp( command, "cancel", 6 ) )
+ {
+ TFModalStack()->PopModal( this );
+
+ SetVisible( false );
+ MarkForDeletion();
+ }
+ else if ( !Q_strnicmp( command, "shuffle", 7 ) )
+ {
+ // let the GC know
+ if ( m_pTextEntry && Plat_FloatTime() >= m_sflNextShuffleTime )
+ {
+ // Set the next time they can send a request to shuffle
+ m_sflNextShuffleTime = Plat_FloatTime() + SHUFFLE_TIME;
+
+ enum { kMaxCodeStringSize = 32 };
+ char szText[ kMaxCodeStringSize ] = { 0 };
+ m_pTextEntry->GetText( &szText[0], sizeof( szText ) );
+
+ GCSDK::CProtoBufMsg<CMsgGCShuffleCrateContents> msg( k_EMsgGCShuffleCrateContents );
+
+ msg.Body().set_crate_item_id( m_Item.GetID() );
+ msg.Body().set_user_code_string( szText );
+
+ GCClientSystem()->BSendMessage( msg );
+
+ m_pProgressBar->SetProgress( 0.f );
+ m_pProgressBar->SetVisible( true );
+ m_pTextEntry->SetVisible( false );
+
+ vgui::surface()->PlaySound( "ui/itemcrate_shuffle.wav" );
+ }
+ }
+ else if ( !Q_strnicmp( command, "getkey", 6 ) )
+ {
+ static CSchemaAttributeDefHandle pAttrDef_DecodedBy( "decoded by itemdefindex" );
+
+ uint32 iDecodableItemDef = 0;
+ if ( m_Item.FindAttribute( pAttrDef_DecodedBy, &iDecodableItemDef ) )
+ {
+ // casting to the proper type since our econ system is dumb
+ const float& value_as_float = (float&)iDecodableItemDef;
+ EconUI()->CloseEconUI();
+ EconUI()->OpenStorePanel( (int)value_as_float, false );
+
+ // close ourselves
+ TFModalStack()->PopModal( this );
+ SetVisible( false );
+ MarkForDeletion();
+ }
+ }
+ else if ( !Q_strnicmp( command, "usekey", 6 ) )
+ {
+ if ( m_UseableKey.IsValid() )
+ {
+ // Use the key
+ ApplyTool( GetParent(), &m_UseableKey, &m_Item );
+ // close ourselves
+ TFModalStack()->PopModal( this );
+ SetVisible( false );
+ MarkForDeletion();
+ }
+ }
+}
+
+void CInputStringForItemBackpackOverlayDialog::FindUsableKey()
+{
+ static CSchemaAttributeDefHandle pAttrDef_DecodedBy( "decoded by itemdefindex" );
+
+ uint32 iDecodableItemDef = 0;
+ if ( m_Item.FindAttribute( pAttrDef_DecodedBy, &iDecodableItemDef ) )
+ {
+ const float& value_as_float = (float&)iDecodableItemDef;
+ iDecodableItemDef = (float)value_as_float;
+ CPlayerInventory *pInventory = InventoryManager()->GetLocalInventory();
+ if ( !pInventory )
+ return;
+
+ for ( int i = 0; i < pInventory->GetItemCount(); i++ )
+ {
+ CEconItemView *pItem = pInventory->GetItem(i);
+ if ( pItem->GetItemDefIndex() == iDecodableItemDef )
+ {
+ m_UseableKey = *pItem;
+ }
+ }
+ }
+}
+
+void CInputStringForItemBackpackOverlayDialog::OnThink()
+{
+ float flDelta = m_sflNextShuffleTime - Plat_FloatTime();
+
+ // If we're ready, show "Shuffle"
+ if ( flDelta < 0 )
+ {
+ // Show the text entry, show the progress bar
+ m_pProgressBar->SetVisible( false );
+ m_pTextEntry->SetVisible( true );
+
+ // Re-enable the shuffle/use buttons
+ m_pShuffleButton->SetEnabled( m_pTextEntry->GetTextLength() != 0 );
+ m_pUseKeyButton->SetEnabled( true );
+ // Say "Shuffle"
+ m_pShuffleButton->SetText( "#ShuffleContents" );
+
+ // We got a inventory update message, update
+ if ( m_bUpdateRecieved )
+ {
+ CreateItemPanels();
+ m_bUpdateRecieved = false;
+ }
+ }
+ else
+ {
+ // Show the progress bar, hide the text field
+ m_pProgressBar->SetVisible( true );
+ m_pTextEntry->SetVisible( false );
+
+ // Dont allow clicking the shuffle or use key button
+ m_pShuffleButton->SetEnabled( false );
+ m_pUseKeyButton->SetEnabled( false );
+ // Say "Shuffling..."
+ m_pShuffleButton->SetText( "#ShufflingContents" );
+
+ // Set progress
+ float flProgress = ( SHUFFLE_TIME - flDelta ) / SHUFFLE_TIME;
+ m_pProgressBar->SetProgress( flProgress );
+ }
+}
+
+void CInputStringForItemBackpackOverlayDialog::Show()
+{
+ SetVisible( true );
+ MakePopup();
+ MoveToFront();
+ SetKeyBoardInputEnabled( true );
+ SetMouseInputEnabled( true );
+ TFModalStack()->PushModal( this );
+
+ // If a key wasnt passed in, find the first one in the
+ // player's inventory
+ if ( !m_UseableKey.IsValid() )
+ {
+ FindUsableKey();
+ }
+
+ // Which button to show
+ m_pUseKeyButton->SetVisible( m_UseableKey.IsValid() );
+ m_pGetKeyButton->SetVisible( !m_UseableKey.IsValid() );
+
+ // Put the current gen code of the crate into the text field
+ static CSchemaAttributeDefHandle pAttrDef_DecodedBy( "crate generation code" );
+ const char *pszAttrGenCode;
+ if ( FindAttribute_UnsafeBitwiseCast<CAttribute_String>( &m_Item, pAttrDef_DecodedBy, &pszAttrGenCode ) )
+ {
+ m_pTextEntry->SetText( pszAttrGenCode );
+ }
+}
+
+