Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

967 lines
36 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "vgui_controls/EditablePanel.h"
  8. #include "vgui_controls/TextEntry.h"
  9. #include "vgui_controls/TextImage.h"
  10. #include "vgui/IInput.h"
  11. #include "econ_item_system.h"
  12. #include "econ_item_constants.h"
  13. #include "econ_gcmessages.h"
  14. #include "econ_ui.h"
  15. #include "tool_items.h"
  16. #ifdef TF_CLIENT_DLL
  17. #include "tf_item_tools.h"
  18. #else
  19. #include "econ_item_tools.h"
  20. #endif
  21. #include <vgui/ILocalize.h>
  22. #include "gc_clientsystem.h"
  23. #include "item_style_select_dialog.h" // for CComboBoxBackpackOverlayDialogBase
  24. #include "backpack_panel.h"
  25. #include "vgui_controls/Controls.h"
  26. #include "vgui/ISurface.h"
  27. #ifdef TF_CLIENT_DLL
  28. #include "character_info_panel.h"
  29. #include "c_tf_gamestats.h"
  30. #endif
  31. // memdbgon must be the last include file in a .cpp file!!!
  32. #include <tier0/memdbgon.h>
  33. //-----------------------------------------------------------------------------
  34. // Purpose:
  35. //-----------------------------------------------------------------------------
  36. CBaseToolUsageDialog::CBaseToolUsageDialog( vgui::Panel *parent, const char *panelName, CEconItemView *pTool, CEconItemView *pToolSubject ) : vgui::EditablePanel( parent, panelName )
  37. {
  38. m_pToolModelPanel = new CItemModelPanel( this, "tool_modelpanel" );
  39. m_pToolModelPanel->SetActAsButton( true, true );
  40. m_pSubjectModelPanel = new CItemModelPanel( this, "subject_modelpanel" );
  41. m_pSubjectModelPanel->SetActAsButton( true, true );
  42. m_pMouseOverItemPanel = vgui::SETUP_PANEL( new CItemModelPanel( this, "mouseoveritempanel" ) );
  43. m_pMouseOverTooltip = new CItemModelPanelToolTip( this );
  44. m_pMouseOverTooltip->SetupPanels( this, m_pMouseOverItemPanel );
  45. m_pToolModelPanel->SetTooltip( m_pMouseOverTooltip, "" );
  46. m_pSubjectModelPanel->SetTooltip( m_pMouseOverTooltip, "" );
  47. m_pToolModelPanel->SetItem( pTool );
  48. m_pToolModelPanel->SetShowEquipped( true );
  49. m_pSubjectModelPanel->SetItem( pToolSubject );
  50. m_pSubjectModelPanel->SetShowEquipped( true );
  51. m_pTitleLabel = NULL;
  52. m_pszInternalPanelName = panelName ? panelName : "unknown";
  53. }
  54. //-----------------------------------------------------------------------------
  55. // Purpose:
  56. //-----------------------------------------------------------------------------
  57. void CBaseToolUsageDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
  58. {
  59. BaseClass::ApplySchemeSettings( pScheme );
  60. SetDialogVariable( "oldname", m_pSubjectModelPanel->GetItem()->GetItemName() );
  61. m_pTitleLabel = dynamic_cast<vgui::Label*>( FindChildByName("TitleLabel") );
  62. if ( m_pTitleLabel )
  63. {
  64. wchar_t *pszBaseString = g_pVGuiLocalize->Find( "ToolDialogTitle" );
  65. if ( pszBaseString )
  66. {
  67. wchar_t wTemp[256];
  68. g_pVGuiLocalize->ConstructString_safe( wTemp, pszBaseString, 2, m_pToolModelPanel->GetItem()->GetItemName(), m_pSubjectModelPanel->GetItem()->GetItemName() );
  69. m_pTitleLabel->SetText( wTemp );
  70. // Now go through the string and find the escape characters telling us where the color changes are
  71. m_pTitleLabel->GetTextImage()->ClearColorChangeStream();
  72. // We change the title's text color to match the colors of the matching model panel backgrounds
  73. wchar_t *txt = wTemp;
  74. int iWChars = 0;
  75. Color colCustom;
  76. while ( txt && *txt )
  77. {
  78. switch ( *txt )
  79. {
  80. case 0x01: // Normal color
  81. m_pTitleLabel->GetTextImage()->AddColorChange( Color(235,226,202,255), iWChars );
  82. break;
  83. case 0x02: // Item 1 color
  84. m_pTitleLabel->GetTextImage()->AddColorChange( Color(112,176,74,255), iWChars );
  85. break;
  86. case 0x03: // Item 2 color
  87. m_pTitleLabel->GetTextImage()->AddColorChange( Color(71,98,145,255), iWChars );
  88. break;
  89. default:
  90. break;
  91. }
  92. txt++;
  93. iWChars++;
  94. }
  95. }
  96. }
  97. vgui::Panel *pToolIcon = FindChildByName( "tool_icon" );
  98. if ( pToolIcon )
  99. {
  100. pToolIcon->SetMouseInputEnabled( false );
  101. pToolIcon->SetKeyBoardInputEnabled( false );
  102. }
  103. vgui::Panel *pSubjectIcon = FindChildByName( "subject_icon" );
  104. if ( pSubjectIcon )
  105. {
  106. pSubjectIcon->SetMouseInputEnabled( false );
  107. pSubjectIcon->SetKeyBoardInputEnabled( false );
  108. }
  109. // @note Tom Bui: because the children have already applied their scheme settings and/or performed their layout before
  110. // this dialog has had a chance to load its res file, we need to manually invalidate the layout of these children
  111. // to make sure that the settings are valid with respect to what the parent wants
  112. m_pToolModelPanel->UpdatePanels();
  113. m_pSubjectModelPanel->UpdatePanels();
  114. m_pMouseOverItemPanel->SetBorder( pScheme->GetBorder("LoadoutItemPopupBorder") );
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Purpose:
  118. //-----------------------------------------------------------------------------
  119. void CBaseToolUsageDialog::PerformLayout()
  120. {
  121. BaseClass::PerformLayout();
  122. // if ( m_pMouseOverItemPanel->IsVisible() )
  123. // {
  124. // // The mouseover panel was visible. Fake a panel entry into the original panel to get it to show up again properly.
  125. // if ( m_pItemPanelBeingMousedOver )
  126. // {
  127. // OnItemPanelEntered( m_pItemPanelBeingMousedOver );
  128. // }
  129. // else
  130. // {
  131. // HideMouseOverPanel();
  132. // }
  133. // }
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Purpose:
  137. //-----------------------------------------------------------------------------
  138. void CBaseToolUsageDialog::OnCommand( const char *command )
  139. {
  140. // in any case, our dialog is going away
  141. TFModalStack()->PopModal( this );
  142. SetVisible( false );
  143. MarkForDeletion();
  144. #ifdef TF_CLIENT_DLL
  145. const char *pSubjectBaseName = m_pSubjectModelPanel && m_pSubjectModelPanel->GetItem() && m_pSubjectModelPanel->GetItem()->GetItemDefinition()
  146. ? m_pSubjectModelPanel->GetItem()->GetItemDefinition()->GetItemBaseName()
  147. : "n/a";
  148. #endif
  149. if ( !Q_stricmp( command, "apply" ) )
  150. {
  151. #ifdef TF_CLIENT_DLL
  152. C_CTFGameStats::ImmediateWriteInterfaceEvent( CFmtStr( "tool_usage_proceed(%s)", m_pszInternalPanelName ).Access(),
  153. pSubjectBaseName );
  154. #endif
  155. // Call before Apply() in case it creates new dialogs that wants to handle prevention
  156. EconUI()->SetPreventClosure( false );
  157. Apply();
  158. }
  159. else // "cancel"
  160. {
  161. #ifdef TF_CLIENT_DLL
  162. C_CTFGameStats::ImmediateWriteInterfaceEvent( CFmtStr( "tool_usage_cancel(%s)", m_pszInternalPanelName ).Access(),
  163. pSubjectBaseName );
  164. #endif
  165. EconUI()->SetPreventClosure( false );
  166. IGameEvent *event = gameeventmanager->CreateEvent( "inventory_updated" );
  167. if ( event )
  168. {
  169. gameeventmanager->FireEventClientSide( event );
  170. }
  171. }
  172. }
  173. //-----------------------------------------------------------------------------
  174. // Purpose: Utility function
  175. //-----------------------------------------------------------------------------
  176. void CBaseToolUsageDialog::OnKeyCodeTyped( vgui::KeyCode code )
  177. {
  178. if( code == KEY_ESCAPE )
  179. {
  180. OnCommand( "cancel" );
  181. }
  182. else
  183. {
  184. BaseClass::OnKeyCodeTyped( code );
  185. }
  186. }
  187. //-----------------------------------------------------------------------------
  188. // Purpose: Utility function
  189. //-----------------------------------------------------------------------------
  190. void CBaseToolUsageDialog::OnKeyCodePressed( vgui::KeyCode code )
  191. {
  192. ButtonCode_t nButtonCode = GetBaseButtonCode( code );
  193. if (nButtonCode == KEY_XBUTTON_LEFT ||
  194. nButtonCode == KEY_XSTICK1_LEFT ||
  195. nButtonCode == KEY_XSTICK2_LEFT ||
  196. nButtonCode == STEAMCONTROLLER_DPAD_LEFT ||
  197. code == KEY_LEFT ||
  198. nButtonCode == KEY_XBUTTON_RIGHT ||
  199. nButtonCode == KEY_XSTICK1_RIGHT ||
  200. nButtonCode == KEY_XSTICK2_RIGHT ||
  201. nButtonCode == STEAMCONTROLLER_DPAD_RIGHT ||
  202. code == KEY_RIGHT ||
  203. nButtonCode == KEY_XBUTTON_UP ||
  204. nButtonCode == KEY_XSTICK1_UP ||
  205. nButtonCode == KEY_XSTICK2_UP ||
  206. nButtonCode == STEAMCONTROLLER_DPAD_UP ||
  207. code == KEY_UP ||
  208. nButtonCode == KEY_XBUTTON_DOWN ||
  209. nButtonCode == KEY_XSTICK1_DOWN ||
  210. nButtonCode == KEY_XSTICK2_DOWN ||
  211. nButtonCode == STEAMCONTROLLER_DPAD_DOWN ||
  212. code == KEY_DOWN )
  213. {
  214. // eat all the movement keys so the selection doesn't update behind the dialog
  215. }
  216. else if( nButtonCode == KEY_XBUTTON_A || code == KEY_ENTER || nButtonCode == STEAMCONTROLLER_A )
  217. {
  218. OnCommand( "apply" );
  219. }
  220. else if( nButtonCode == KEY_XBUTTON_B || nButtonCode == STEAMCONTROLLER_B )
  221. {
  222. OnCommand( "cancel" );
  223. }
  224. else
  225. {
  226. BaseClass::OnKeyCodePressed( code );
  227. }
  228. }
  229. //-----------------------------------------------------------------------------
  230. // Purpose: Utility function
  231. //-----------------------------------------------------------------------------
  232. void MakeModalAndBringToFront( vgui::EditablePanel *dialog )
  233. {
  234. dialog->SetVisible( true );
  235. if ( dialog->GetParent() == NULL )
  236. {
  237. dialog->MakePopup();
  238. }
  239. dialog->SetZPos( 10000 );
  240. dialog->MoveToFront();
  241. dialog->SetKeyBoardInputEnabled( true );
  242. dialog->SetMouseInputEnabled( true );
  243. TFModalStack()->PushModal( dialog );
  244. EconUI()->SetPreventClosure( true );
  245. }
  246. //-----------------------------------------------------------------------------
  247. //
  248. // Given a tool and an item to apply the tool's effects upon,
  249. // gather required information from the user and
  250. // send a change request to the GC.
  251. //
  252. bool ApplyTool( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
  253. {
  254. if ( !pTool || !pToolSubject )
  255. return false;
  256. if ( !CEconSharedToolSupport::ToolCanApplyTo( pTool, pToolSubject ) )
  257. return false;
  258. // this tool can be applied to this subject item
  259. const IEconTool *pEconTool = pTool->GetStaticData()->GetEconTool();
  260. if ( !pEconTool )
  261. return false;
  262. pEconTool->OnClientApplyTool( pTool, pToolSubject, pParent );
  263. return true;
  264. }
  265. //-----------------------------------------------------------------------------
  266. // Purpose: STRANGE COUNT TRANSFER
  267. //-----------------------------------------------------------------------------
  268. //-----------------------------------------------------------------------------
  269. class CConfirmStrangeCountTransferApplicationDialog : public CBaseToolUsageDialog
  270. {
  271. DECLARE_CLASS_SIMPLE( CConfirmStrangeCountTransferApplicationDialog, CBaseToolUsageDialog );
  272. public:
  273. CConfirmStrangeCountTransferApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
  274. : CBaseToolUsageDialog( pParent, "ConfirmApplyStrangeCountTransferDialog", pTool, pToolSubject )
  275. {
  276. m_pItemSrc = NULL;
  277. m_pItemDest = NULL;
  278. }
  279. virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
  280. {
  281. LoadControlSettings( "Resource/UI/econ/ConfirmApplyDuckTokenDialog.res" ); // fix me
  282. BaseClass::ApplySchemeSettings( pScheme );
  283. }
  284. virtual void Apply( void )
  285. {
  286. GCSDK::CProtoBufMsg<CMsgApplyStrangeCountTransfer> msg( k_EMsgGCApplyStrangeCountTransfer );
  287. if ( !m_pItemSrc || !m_pItemDest )
  288. return;
  289. msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
  290. msg.Body().set_item_src_item_id( m_pItemSrc->GetItemID() );
  291. msg.Body().set_item_dest_item_id( m_pItemDest->GetItemID() );
  292. GCClientSystem()->BSendMessage( msg );
  293. EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_strangecounttransfer", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
  294. GCClientSystem()->BSendMessage( msg );
  295. }
  296. bool SetItems( CEconItemView *pItemSrc, CEconItemView *pItemDest )
  297. {
  298. if ( !pItemSrc || !pItemDest )
  299. return false;
  300. if ( CEconTool_StrangeCountTransfer::AreItemsEligibleForStrangeCountTransfer( pItemSrc, pItemDest ) )
  301. {
  302. m_pItemSrc = pItemSrc;
  303. m_pItemDest = pItemDest;
  304. return true;
  305. }
  306. return false;
  307. }
  308. private:
  309. CEconItemView *m_pItemSrc;
  310. CEconItemView *m_pItemDest;
  311. };
  312. /*static */bool CEconTool_StrangeCountTransfer::SetItems( CEconItemView *pItemSrc, CEconItemView *pItemDest )
  313. {
  314. if ( !pItemSrc || !pItemDest )
  315. return false;
  316. if ( CEconTool_StrangeCountTransfer::AreItemsEligibleForStrangeCountTransfer( pItemSrc, pItemDest ) )
  317. {
  318. CEconTool_StrangeCountTransfer::m_pItemSrc = pItemSrc;
  319. CEconTool_StrangeCountTransfer::m_pItemDest = pItemDest;
  320. return true;
  321. }
  322. return false;
  323. }
  324. //-----------------------------------------------------------------------------
  325. // Purpose:
  326. //-----------------------------------------------------------------------------
  327. void CEconTool_StrangeCountTransfer::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
  328. {
  329. CConfirmStrangeCountTransferApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmStrangeCountTransferApplicationDialog( pParent, pTool, pSubject ) );
  330. MakeModalAndBringToFront( pDialog );
  331. }
  332. // ****************************************************************************
  333. // STRANGE PARTS
  334. //-----------------------------------------------------------------------------
  335. // Purpose: Confirm / abort strange part application
  336. //-----------------------------------------------------------------------------
  337. class CConfirmStrangePartApplicationDialog : public CBaseToolUsageDialog
  338. {
  339. DECLARE_CLASS_SIMPLE( CConfirmStrangePartApplicationDialog, CBaseToolUsageDialog );
  340. public:
  341. CConfirmStrangePartApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject );
  342. virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
  343. virtual void Apply( void );
  344. };
  345. //-----------------------------------------------------------------------------
  346. // Purpose:
  347. //-----------------------------------------------------------------------------
  348. CConfirmStrangePartApplicationDialog::CConfirmStrangePartApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
  349. : CBaseToolUsageDialog( pParent, "ConfirmApplyStrangePartApplicationDialog", pTool, pToolSubject )
  350. {
  351. }
  352. //-----------------------------------------------------------------------------
  353. // Purpose:
  354. //-----------------------------------------------------------------------------
  355. void CConfirmStrangePartApplicationDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
  356. {
  357. LoadControlSettings( "Resource/UI/econ/ConfirmApplyStrangePartApplicationDialog.res" );
  358. int iRemainingStrangePartSlots = 0;
  359. for ( int i = 0; i < GetKillEaterAttrCount(); i++ )
  360. {
  361. if ( !GetKillEaterAttr_IsUserCustomizable( i ) )
  362. continue;
  363. if ( !m_pSubjectModelPanel->GetItem()->FindAttribute( GetKillEaterAttr_Score( i ) ) )
  364. ++iRemainingStrangePartSlots;
  365. }
  366. SetDialogVariable( "remaining_strange_part_slots", iRemainingStrangePartSlots );
  367. SetDialogVariable( "maximum_strange_part_slots", GetKillEaterAttrCount_UserCustomizable() );
  368. SetDialogVariable( "subject_item_def_name", GLocalizationProvider()->Find( m_pSubjectModelPanel->GetItem()->GetItemDefinition()->GetItemBaseName() ) );
  369. SetDialogVariable( "slot_singular_plural", GLocalizationProvider()->Find( iRemainingStrangePartSlots == 1 ? "#Econ_FreeSlot_Singular" : "#Econ_FreeSlot_Plural" ) );
  370. BaseClass::ApplySchemeSettings( pScheme );
  371. }
  372. //-----------------------------------------------------------------------------
  373. // Purpose:
  374. //-----------------------------------------------------------------------------
  375. void CConfirmStrangePartApplicationDialog::Apply()
  376. {
  377. GCSDK::CProtoBufMsg<CMsgApplyStrangePart> msg( k_EMsgGCApplyStrangePart );
  378. msg.Body().set_strange_part_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
  379. msg.Body().set_item_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
  380. EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_strange_part", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
  381. GCClientSystem()->BSendMessage( msg );
  382. }
  383. //-----------------------------------------------------------------------------
  384. // Purpose:
  385. //-----------------------------------------------------------------------------
  386. void CEconTool_StrangePart::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
  387. {
  388. CConfirmStrangePartApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmStrangePartApplicationDialog( pParent, pTool, pSubject ) );
  389. MakeModalAndBringToFront( pDialog );
  390. }
  391. //-----------------------------------------------------------------------------
  392. // Purpose: Confirm / abort strange restriction application
  393. //-----------------------------------------------------------------------------
  394. class CConfirmStrangeRestrictionApplicationDialog : public CBaseToolUsageDialog
  395. {
  396. DECLARE_CLASS_SIMPLE( CConfirmStrangeRestrictionApplicationDialog, CBaseToolUsageDialog );
  397. public:
  398. CConfirmStrangeRestrictionApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject, int iStrangeSlot, const char *pszStatLocalizationToken );
  399. virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
  400. virtual void Apply( void );
  401. private:
  402. int m_iStrangeSlot;
  403. const char *m_pszStatLocalizationToken;
  404. };
  405. //-----------------------------------------------------------------------------
  406. // Purpose:
  407. //-----------------------------------------------------------------------------
  408. CConfirmStrangeRestrictionApplicationDialog::CConfirmStrangeRestrictionApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject, int iStrangeSlot, const char *pszStatLocalizationToken )
  409. : CBaseToolUsageDialog( pParent, "ConfirmApplyStrangeRestrictionApplicationDialog", pTool, pToolSubject )
  410. , m_iStrangeSlot( iStrangeSlot )
  411. , m_pszStatLocalizationToken( pszStatLocalizationToken )
  412. {
  413. }
  414. //-----------------------------------------------------------------------------
  415. // Purpose:
  416. //-----------------------------------------------------------------------------
  417. void CConfirmStrangeRestrictionApplicationDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
  418. {
  419. LoadControlSettings( "Resource/UI/econ/ConfirmApplyStrangeRestrictionApplicationDialog.res" );
  420. SetDialogVariable( "stat_name", GLocalizationProvider()->Find( m_pszStatLocalizationToken ) );
  421. BaseClass::ApplySchemeSettings( pScheme );
  422. }
  423. //-----------------------------------------------------------------------------
  424. // Purpose:
  425. //-----------------------------------------------------------------------------
  426. void CConfirmStrangeRestrictionApplicationDialog::Apply()
  427. {
  428. GCSDK::CProtoBufMsg<CMsgApplyStrangeRestriction> msg( k_EMsgGCApplyStrangeRestriction );
  429. msg.Body().set_strange_part_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
  430. msg.Body().set_item_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
  431. msg.Body().set_strange_attr_index( m_iStrangeSlot );
  432. EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_strange_restriction", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
  433. GCClientSystem()->BSendMessage( msg );
  434. }
  435. //-----------------------------------------------------------------------------
  436. // Purpose:
  437. //-----------------------------------------------------------------------------
  438. class CSelectStrangePartToRestrictDialog : public CComboBoxBackpackOverlayDialogBase
  439. {
  440. public:
  441. DECLARE_CLASS_SIMPLE( CSelectStrangePartToRestrictDialog, CComboBoxBackpackOverlayDialogBase );
  442. public:
  443. CSelectStrangePartToRestrictDialog( vgui::Panel *pParent, CEconItemView *pToolItem, CEconItemView *pSubjectItem )
  444. : CComboBoxBackpackOverlayDialogBase( pParent, pSubjectItem )
  445. , m_ToolItem( *pToolItem )
  446. , m_SubjectItem( *pSubjectItem )
  447. {
  448. //
  449. }
  450. private:
  451. virtual void PopulateComboBoxOptions()
  452. {
  453. const wchar_t *pLocBase = GLocalizationProvider()->Find( "#ApplyStrangeRestrictionCombo" );
  454. const CEconTool_StrangePartRestriction *pToolRestriction = m_ToolItem.GetItemDefinition()->GetTypedEconTool<CEconTool_StrangePartRestriction>();
  455. Assert( pToolRestriction );
  456. KeyValues *pKeyValues = new KeyValues( "data" );
  457. for ( int i = 0; i < GetKillEaterAttrCount(); i++ )
  458. {
  459. uint32 unScoreType;
  460. if ( !GetItemSchema()->BCanStrangeFilterApplyToStrangeSlotInItem( pToolRestriction->GetRestrictionType(), pToolRestriction->GetRestrictionValue(), &m_SubjectItem, i, &unScoreType ) )
  461. continue;
  462. const char *pszTypeLocKey = GetItemSchema()->GetKillEaterScoreTypeLocString( unScoreType );
  463. if ( !pszTypeLocKey )
  464. continue;
  465. pKeyValues->SetInt( "data", i );
  466. pKeyValues->SetString( "token", pszTypeLocKey );
  467. GetComboBox()->AddItem( CConstructLocalizedString( pLocBase, GLocalizationProvider()->Find( pszTypeLocKey ) ), pKeyValues );
  468. }
  469. pKeyValues->deleteThis();
  470. Assert( GetComboBox()->GetItemCount() > 0 );
  471. GetComboBox()->ActivateItemByRow( 0 );
  472. }
  473. virtual void OnComboBoxApplication()
  474. {
  475. KeyValues *pKVActiveUserData = GetComboBox()->GetActiveItemUserData();
  476. int iIndex = pKVActiveUserData ? pKVActiveUserData->GetInt( "data", -1 ) : -1;
  477. if ( iIndex < 0 )
  478. return;
  479. // FIXME: CConfirmStrangePartApplicationDialog is wrong class
  480. CConfirmStrangeRestrictionApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmStrangeRestrictionApplicationDialog( GetParent(), &m_ToolItem, &m_SubjectItem, iIndex, pKVActiveUserData ? pKVActiveUserData->GetString( "token", NULL ) : NULL ) );
  481. MakeModalAndBringToFront( pDialog );
  482. }
  483. virtual const char *GetTitleLabelLocalizationToken() const { return "#ApplyStrangeRestrictionPartTitle"; }
  484. private:
  485. CEconItemView m_ToolItem;
  486. CEconItemView m_SubjectItem;
  487. };
  488. //-----------------------------------------------------------------------------
  489. // Purpose:
  490. //-----------------------------------------------------------------------------
  491. void CEconTool_StrangePartRestriction::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
  492. {
  493. if ( EconUI()->GetBackpackPanel() )
  494. {
  495. EconUI()->GetBackpackPanel()->SetComboBoxOverlaySelectionItem( pSubject );
  496. }
  497. CSelectStrangePartToRestrictDialog *pDialog = vgui::SETUP_PANEL( new CSelectStrangePartToRestrictDialog( pParent, pTool, pSubject ) );
  498. MakeModalAndBringToFront( pDialog );
  499. }
  500. //-----------------------------------------------------------------------------
  501. class CWaitingDialog : public CGenericWaitingDialog
  502. {
  503. public:
  504. CWaitingDialog( vgui::Panel *pParent ) : CGenericWaitingDialog( pParent )
  505. {
  506. }
  507. protected:
  508. virtual void OnTimeout()
  509. {
  510. // Play an exciting sound!
  511. vgui::surface()->PlaySound( "misc/achievement_earned.wav" );
  512. // Show them the result item.
  513. InventoryManager()->ShowItemsPickedUp( true );
  514. }
  515. };
  516. //-----------------------------------------------------------------------------
  517. // Purpose: Confirm / abort card upgrade tool application
  518. //-----------------------------------------------------------------------------
  519. class CConfirmApplyStrangifierDialog : public CBaseToolUsageDialog
  520. {
  521. DECLARE_CLASS_SIMPLE( CConfirmApplyStrangifierDialog, CBaseToolUsageDialog );
  522. public:
  523. CConfirmApplyStrangifierDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject, const char *pszPromptLocToken, const char *pszTransactionReason, const char *pszUpdatingText = "" )
  524. : CBaseToolUsageDialog( pParent, "ConfirmApplyStrangifierDialog", pTool, pToolSubject )
  525. , m_sPromptLocToken( pszPromptLocToken )
  526. , m_sTransactionReason( pszTransactionReason )
  527. , m_sUpdatingText( pszUpdatingText )
  528. {
  529. //
  530. }
  531. virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
  532. {
  533. LoadControlSettings( "Resource/UI/econ/ConfirmApplyStrangifierDialog.res" );
  534. BaseClass::ApplySchemeSettings( pScheme );
  535. CExLabel* pTextLabel = dynamic_cast<CExLabel*>( FindChildByName( "ConfirmLabel" ) );
  536. if( pTextLabel && m_pToolModelPanel )
  537. {
  538. wchar_t *pszBaseString = g_pVGuiLocalize->Find( m_sPromptLocToken );
  539. wchar_t wTempFinalString[1024] = { 0 };
  540. if ( pszBaseString )
  541. {
  542. V_wcscpy_safe( wTempFinalString, pszBaseString );
  543. }
  544. // If the strangifier is untradable, add an extra warning in the prompt to let the user know
  545. if( m_pToolModelPanel->GetItem() && !m_pToolModelPanel->GetItem()->IsTradable() &&
  546. m_pSubjectModelPanel && m_pSubjectModelPanel->GetItem() )
  547. {
  548. wchar_t *pszUntradableString = g_pVGuiLocalize->Find( "ToolStrangifierUntradableWarning" );
  549. // Stick the names of the items into the string
  550. wchar_t wTempUntradable[1024] = { 0 };
  551. g_pVGuiLocalize->ConstructString_safe( wTempUntradable, pszUntradableString, 2, m_pToolModelPanel->GetItem()->GetItemName(), m_pSubjectModelPanel->GetItem()->GetItemName() );
  552. // Concat onto the the original string
  553. V_wcscat_safe( wTempFinalString, wTempUntradable, sizeof( wTempUntradable ) );
  554. }
  555. pTextLabel->SetText( wTempFinalString );
  556. }
  557. }
  558. virtual void Apply( void )
  559. {
  560. if ( m_pSubjectModelPanel->GetItem()->GetItemID() != INVALID_ITEM_ID )
  561. {
  562. GCSDK::CProtoBufMsg<CMsgApplyToolToItem> msg( k_EMsgGCApplyXifier );
  563. msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
  564. msg.Body().set_subject_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
  565. GCClientSystem()->BSendMessage( msg );
  566. }
  567. else
  568. {
  569. GCSDK::CProtoBufMsg<CMsgApplyToolToBaseItem> msg( k_EMsgGCApplyBaseItemXifier );
  570. msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
  571. msg.Body().set_baseitem_def_index( m_pSubjectModelPanel->GetItem()->GetStaticData()->GetDefinitionIndex() );
  572. GCClientSystem()->BSendMessage( msg );
  573. }
  574. EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), m_sTransactionReason.String() );
  575. if ( *m_sUpdatingText.String() )
  576. {
  577. vgui::surface()->PlaySound( "ui/item_gift_wrap_use.wav" );
  578. ShowWaitingDialog( new CWaitingDialog( NULL ), m_sUpdatingText.String(), true, false, 5.0f );
  579. }
  580. }
  581. private:
  582. CUtlString m_sPromptLocToken;
  583. CUtlString m_sTransactionReason;
  584. CUtlString m_sUpdatingText;
  585. };
  586. //-----------------------------------------------------------------------------
  587. // Purpose:
  588. //-----------------------------------------------------------------------------
  589. void CEconTool_Strangifier::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
  590. {
  591. CConfirmApplyStrangifierDialog *pDialog = vgui::SETUP_PANEL( new CConfirmApplyStrangifierDialog( pParent, pTool, pSubject, "ToolStrangifierConfirm", "strangified_item" ) );
  592. MakeModalAndBringToFront( pDialog );
  593. }
  594. //-----------------------------------------------------------------------------
  595. void CEconTool_KillStreakifier::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
  596. {
  597. CConfirmApplyStrangifierDialog *pDialog = vgui::SETUP_PANEL( new CConfirmApplyStrangifierDialog( pParent, pTool, pSubject, "ToolKillStreakifierConfirm", "killstreakified_item" ) );
  598. MakeModalAndBringToFront( pDialog );
  599. }
  600. //-----------------------------------------------------------------------------
  601. void CEconTool_Festivizer::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
  602. {
  603. CConfirmApplyStrangifierDialog *pDialog = vgui::SETUP_PANEL( new CConfirmApplyStrangifierDialog( pParent, pTool, pSubject, "ToolFestivizerConfirm", "festivized_item", "#ToolFestivizerInProgress" ) );
  604. MakeModalAndBringToFront( pDialog );
  605. }
  606. //-----------------------------------------------------------------------------
  607. void CEconTool_Unusualifier::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
  608. {
  609. CConfirmApplyStrangifierDialog *pDialog = vgui::SETUP_PANEL( new CConfirmApplyStrangifierDialog( pParent, pTool, pSubject, "ToolUnusualifierConfirm", "unusualified_item", "#ToolUnusualifierInProgress" ) );
  610. MakeModalAndBringToFront( pDialog );
  611. }
  612. //-----------------------------------------------------------------------------
  613. class CConfirmUseItemEaterRechargerDialog : public CBaseToolUsageDialog
  614. {
  615. DECLARE_CLASS_SIMPLE( CConfirmUseItemEaterRechargerDialog, CBaseToolUsageDialog );
  616. public:
  617. CConfirmUseItemEaterRechargerDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
  618. : CBaseToolUsageDialog( pParent, "ConfirmUseItemEaterRechargerDialog", pTool, pToolSubject )
  619. {
  620. }
  621. virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
  622. {
  623. LoadControlSettings( "Resource/UI/econ/ConfirmUseItemEaterRechargerDialog.res" );
  624. // Find the number of charges to add by looking at item tool rescritions.
  625. const CEconTool_ItemEaterRecharger *pTool = m_pToolModelPanel->GetItem()->GetItemDefinition()->GetTypedEconTool<CEconTool_ItemEaterRecharger>();
  626. if ( pTool )
  627. {
  628. int iCharges = pTool->GetChargesForItemDefId( m_pSubjectModelPanel->GetItem()->GetItemDefIndex() );
  629. SetDialogVariable( "charges_added", iCharges );
  630. }
  631. BaseClass::ApplySchemeSettings( pScheme );
  632. }
  633. virtual void Apply( void )
  634. {
  635. GCSDK::CProtoBufMsg<CMsgApplyToolToItem> msg( k_EMsgGCItemEaterRecharger );
  636. msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
  637. msg.Body().set_subject_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
  638. EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "recharging_item" );
  639. GCClientSystem()->BSendMessage( msg );
  640. }
  641. };
  642. //-----------------------------------------------------------------------------
  643. // Purpose:
  644. //-----------------------------------------------------------------------------
  645. void CEconTool_ItemEaterRecharger::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
  646. {
  647. CConfirmUseItemEaterRechargerDialog *pDialog = vgui::SETUP_PANEL( new CConfirmUseItemEaterRechargerDialog( pParent, pTool, pSubject ) );
  648. MakeModalAndBringToFront( pDialog );
  649. }
  650. //-----------------------------------------------------------------------------
  651. // Purpose: Confirm / abort card upgrade tool application
  652. //-----------------------------------------------------------------------------
  653. class CConfirmCardUpgradeApplicationDialog : public CBaseToolUsageDialog
  654. {
  655. DECLARE_CLASS_SIMPLE( CConfirmCardUpgradeApplicationDialog, CBaseToolUsageDialog );
  656. public:
  657. CConfirmCardUpgradeApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
  658. : CBaseToolUsageDialog( pParent, "ConfirmApplyCardUpgradeApplicationDialog", pTool, pToolSubject )
  659. {
  660. //
  661. }
  662. virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
  663. {
  664. LoadControlSettings( "Resource/UI/econ/ConfirmApplyCardUpgradeApplicationDialog.res" );
  665. // See how many card upgrades have already been applied
  666. CCountUserGeneratedAttributeIterator countIterator;
  667. m_pSubjectModelPanel->GetItem()->IterateAttributes( &countIterator );
  668. int iRemainingStrangePartSlots = GetMaxCardUpgradesPerItem() - countIterator.GetCount();
  669. SetDialogVariable( "remaining_upgrade_card_slots", iRemainingStrangePartSlots );
  670. SetDialogVariable( "subject_item_def_name", GLocalizationProvider()->Find( m_pSubjectModelPanel->GetItem()->GetItemDefinition()->GetItemBaseName() ) );
  671. SetDialogVariable( "slot_singular_plural", GLocalizationProvider()->Find( iRemainingStrangePartSlots == 1 ? "#Econ_FreeSlot_Singular" : "#Econ_FreeSlot_Plural" ) );
  672. BaseClass::ApplySchemeSettings( pScheme );
  673. }
  674. virtual void Apply( void )
  675. {
  676. GCSDK::CProtoBufMsg<CMsgApplyUpgradeCard> msg( k_EMsgGCApplyUpgradeCard );
  677. msg.Body().set_upgrade_card_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
  678. msg.Body().set_subject_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
  679. EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_upgrade_card", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
  680. GCClientSystem()->BSendMessage( msg );
  681. }
  682. };
  683. //-----------------------------------------------------------------------------
  684. // Purpose:
  685. //-----------------------------------------------------------------------------
  686. void CEconTool_UpgradeCard::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
  687. {
  688. CConfirmCardUpgradeApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmCardUpgradeApplicationDialog( pParent, pTool, pSubject ) );
  689. MakeModalAndBringToFront( pDialog );
  690. }
  691. //-----------------------------------------------------------------------------
  692. // Purpose:
  693. //-----------------------------------------------------------------------------
  694. class CConfirmTransmogrifyApplicationDialog : public CBaseToolUsageDialog
  695. {
  696. DECLARE_CLASS_SIMPLE( CConfirmTransmogrifyApplicationDialog, CBaseToolUsageDialog );
  697. public:
  698. CConfirmTransmogrifyApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
  699. : CBaseToolUsageDialog( pParent, "ConfirmTransmogrifyApplicationDialog", pTool, pToolSubject )
  700. {
  701. //
  702. }
  703. virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
  704. {
  705. LoadControlSettings( "Resource/UI/econ/ConfirmTransmogrifyApplicationDialog.res" );
  706. const CEconTool_ClassTransmogrifier *pTool = m_pToolModelPanel->GetItem()->GetItemDefinition()->GetTypedEconTool<CEconTool_ClassTransmogrifier>();
  707. Assert( pTool );
  708. if ( pTool )
  709. {
  710. int iOutputClass = pTool->GetOutputClass();
  711. if ( iOutputClass > 0 && iOutputClass < LOADOUT_COUNT )
  712. {
  713. SetDialogVariable( "output_class", GLocalizationProvider()->Find( g_aPlayerClassNames[ iOutputClass ] ) );
  714. }
  715. }
  716. BaseClass::ApplySchemeSettings( pScheme );
  717. }
  718. virtual void Apply( void )
  719. {
  720. GCSDK::CProtoBufMsg<CMsgApplyToolToItem> msg( k_EMsgGCApplyClassTransmogrifier );
  721. msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
  722. msg.Body().set_subject_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
  723. EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_transmogrifier", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
  724. GCClientSystem()->BSendMessage( msg );
  725. }
  726. };
  727. //-----------------------------------------------------------------------------
  728. // Purpose:
  729. //-----------------------------------------------------------------------------
  730. void CEconTool_ClassTransmogrifier::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
  731. {
  732. CConfirmTransmogrifyApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmTransmogrifyApplicationDialog( pParent, pTool, pSubject ) );
  733. MakeModalAndBringToFront( pDialog );
  734. }
  735. #ifdef TF_CLIENT_DLL
  736. //-----------------------------------------------------------------------------
  737. // Purpose:
  738. //-----------------------------------------------------------------------------
  739. class CConfirmSpellbookPageApplicationDialog : public CBaseToolUsageDialog
  740. {
  741. DECLARE_CLASS_SIMPLE( CConfirmSpellbookPageApplicationDialog, CBaseToolUsageDialog );
  742. public:
  743. CConfirmSpellbookPageApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
  744. : CBaseToolUsageDialog( pParent, "ConfirmSpellbookPageApplicationDialog", pTool, pToolSubject )
  745. {
  746. //
  747. }
  748. virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
  749. {
  750. LoadControlSettings( "Resource/UI/econ/ConfirmSpellbookPageApplicationDialog.res" );
  751. BaseClass::ApplySchemeSettings( pScheme );
  752. }
  753. virtual void Apply( void )
  754. {
  755. GCSDK::CProtoBufMsg<CMsgApplyToolToItem> msg( k_EMsgGCApplyHalloweenSpellbookPage );
  756. msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
  757. msg.Body().set_subject_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
  758. EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_spellbook_page", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
  759. GCClientSystem()->BSendMessage( msg );
  760. }
  761. };
  762. //-----------------------------------------------------------------------------
  763. // Purpose:
  764. //-----------------------------------------------------------------------------
  765. void CEconTool_TFSpellbookPage::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
  766. {
  767. CConfirmSpellbookPageApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmSpellbookPageApplicationDialog( pParent, pTool, pSubject ) );
  768. MakeModalAndBringToFront( pDialog );
  769. }
  770. //-----------------------------------------------------------------------------
  771. class CConfirmDuckTokenApplicationDialog : public CBaseToolUsageDialog
  772. {
  773. DECLARE_CLASS_SIMPLE( CConfirmDuckTokenApplicationDialog, CBaseToolUsageDialog );
  774. public:
  775. CConfirmDuckTokenApplicationDialog( vgui::Panel *pParent, CEconItemView *pTool, CEconItemView *pToolSubject )
  776. : CBaseToolUsageDialog( pParent, "ConfirmApplyDuckTokenDialog", pTool, pToolSubject )
  777. {
  778. //
  779. }
  780. virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
  781. {
  782. LoadControlSettings( "Resource/UI/econ/ConfirmApplyDuckTokenDialog.res" );
  783. BaseClass::ApplySchemeSettings( pScheme );
  784. }
  785. virtual void Apply( void )
  786. {
  787. GCSDK::CProtoBufMsg<CMsgApplyToolToItem> msg( k_EMsgGCApplyDuckToken );
  788. msg.Body().set_tool_item_id( m_pToolModelPanel->GetItem()->GetItemID() );
  789. msg.Body().set_subject_item_id( m_pSubjectModelPanel->GetItem()->GetItemID() );
  790. EconUI()->Gamestats_ItemTransaction( IE_ITEM_USED_TOOL, m_pToolModelPanel->GetItem(), "applied_ducktoken", m_pToolModelPanel->GetItem()->GetItemDefIndex() );
  791. GCClientSystem()->BSendMessage( msg );
  792. }
  793. };
  794. //-----------------------------------------------------------------------------
  795. // Purpose:
  796. //-----------------------------------------------------------------------------
  797. void CEconTool_DuckToken::OnClientApplyTool( CEconItemView *pTool, CEconItemView *pSubject, vgui::Panel *pParent ) const
  798. {
  799. CConfirmDuckTokenApplicationDialog *pDialog = vgui::SETUP_PANEL( new CConfirmDuckTokenApplicationDialog( pParent, pTool, pSubject ) );
  800. MakeModalAndBringToFront( pDialog );
  801. }
  802. #endif // TF_CLIENT_DLL