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.

447 lines
12 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "vgui/IInput.h"
  8. #include <vgui/IVGui.h>
  9. #include <vgui/IScheme.h>
  10. #include "tf_giveawayitempanel.h"
  11. #include "iclientmode.h"
  12. #include "baseviewport.h"
  13. #include "econ_entity.h"
  14. #include "c_tf_player.h"
  15. #include "gamestringpool.h"
  16. #include "vgui_controls/TextImage.h"
  17. #include "vgui_controls/Label.h"
  18. #include "vgui_controls/Button.h"
  19. #include "econ_item_system.h"
  20. #include "ienginevgui.h"
  21. #include "achievementmgr.h"
  22. #include "fmtstr.h"
  23. #include "c_tf_playerresource.h"
  24. #include "tf_gamerules.h"
  25. //-----------------------------------------------------------------------------
  26. // Purpose:
  27. //-----------------------------------------------------------------------------
  28. CGiveawayPlayerPanel::CGiveawayPlayerPanel( vgui::Panel *parent, const char *name ) : BaseClass(parent,name)
  29. {
  30. m_pNameLabel = new vgui::Label( this, "name_label", "" );
  31. m_pScoreLabel = new vgui::Label( this, "score_label", "" );
  32. REGISTER_COLOR_AS_OVERRIDABLE( m_PlayerColorLocal, "fgcolor_local" );
  33. REGISTER_COLOR_AS_OVERRIDABLE( m_PlayerColorOther, "fgcolor_other" );
  34. }
  35. //-----------------------------------------------------------------------------
  36. // Purpose:
  37. //-----------------------------------------------------------------------------
  38. void CGiveawayPlayerPanel::PerformLayout( void )
  39. {
  40. BaseClass::PerformLayout();
  41. }
  42. //-----------------------------------------------------------------------------
  43. // Purpose:
  44. //-----------------------------------------------------------------------------
  45. void CGiveawayPlayerPanel::SetPlayer( CTFPlayer *pPlayer )
  46. {
  47. m_iBonus = 0;
  48. if ( pPlayer )
  49. {
  50. SetVisible( true );
  51. if ( g_TF_PR )
  52. {
  53. int playerIndex = pPlayer->entindex();
  54. const char *pszName = g_TF_PR->GetPlayerName( playerIndex );
  55. m_iBonus = pPlayer->m_Shared.GetItemFindBonus();
  56. SetDialogVariable( "playername", pszName );
  57. SetDialogVariable( "playerscore", m_iBonus );
  58. }
  59. m_iPlayerIndex = pPlayer->entindex();
  60. if ( pPlayer->IsLocalPlayer() )
  61. {
  62. m_pNameLabel->SetFgColor( m_PlayerColorLocal );
  63. m_pScoreLabel->SetFgColor( m_PlayerColorLocal );
  64. }
  65. else
  66. {
  67. m_pNameLabel->SetFgColor( m_PlayerColorOther );
  68. m_pScoreLabel->SetFgColor( m_PlayerColorOther );
  69. }
  70. }
  71. else
  72. {
  73. SetVisible( false );
  74. m_iPlayerIndex = 0;
  75. }
  76. }
  77. //-----------------------------------------------------------------------------
  78. // Purpose:
  79. //-----------------------------------------------------------------------------
  80. void CGiveawayPlayerPanel::SpinBonus( void )
  81. {
  82. SetDialogVariable( "playerscore", RandomInt( PLAYER_ROLL_MIN, PLAYER_ROLL_MAX ) );
  83. }
  84. //-----------------------------------------------------------------------------
  85. // Purpose:
  86. //-----------------------------------------------------------------------------
  87. void CGiveawayPlayerPanel::LockBonus( int iRoll )
  88. {
  89. m_iRoll = iRoll;
  90. SetDialogVariable( "playerscore", m_iBonus + m_iRoll );
  91. }
  92. //===========================================================================================================================
  93. //-----------------------------------------------------------------------------
  94. // Purpose:
  95. //-----------------------------------------------------------------------------
  96. CTFGiveawayItemPanel::CTFGiveawayItemPanel( IViewPort *pViewPort ) : Frame( NULL, PANEL_GIVEAWAY_ITEM )
  97. {
  98. m_pViewPort = pViewPort;
  99. // load the new scheme early!!
  100. SetScheme( "ClientScheme" );
  101. SetTitleBarVisible( false );
  102. SetMinimizeButtonVisible( false );
  103. SetMaximizeButtonVisible( false );
  104. SetCloseButtonVisible( false );
  105. SetSizeable( false );
  106. SetMoveable( false );
  107. SetProportional( true );
  108. SetVisible( false );
  109. SetKeyBoardInputEnabled( true );
  110. SetMouseInputEnabled( true );
  111. m_pModelPanel = new CItemModelPanel( this, "item_panel" );
  112. m_pPlayerListPanelKVs = NULL;
  113. m_iNumActivePlayers = 0;
  114. }
  115. //-----------------------------------------------------------------------------
  116. // Purpose:
  117. //-----------------------------------------------------------------------------
  118. CTFGiveawayItemPanel::~CTFGiveawayItemPanel( void )
  119. {
  120. if ( m_pPlayerListPanelKVs )
  121. {
  122. m_pPlayerListPanelKVs->deleteThis();
  123. m_pPlayerListPanelKVs = NULL;
  124. }
  125. }
  126. //-----------------------------------------------------------------------------
  127. // Purpose:
  128. //-----------------------------------------------------------------------------
  129. void CTFGiveawayItemPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
  130. {
  131. BaseClass::ApplySchemeSettings( pScheme );
  132. LoadControlSettings( "Resource/UI/GiveawayItemPanel.res" );
  133. for ( int i = 0; i < m_aPlayerList.Count(); i++ )
  134. {
  135. m_aPlayerList[i]->ApplySettings( m_pPlayerListPanelKVs );
  136. m_aPlayerList[i]->SetBorder( pScheme->GetBorder("EconItemBorder") );
  137. m_aPlayerList[i]->InvalidateLayout();
  138. }
  139. m_pModelPanel->SetNoItemText( "#Item_Giveaway_NoItem" );
  140. }
  141. //-----------------------------------------------------------------------------
  142. // Purpose:
  143. //-----------------------------------------------------------------------------
  144. void CTFGiveawayItemPanel::ApplySettings( KeyValues *inResourceData )
  145. {
  146. BaseClass::ApplySettings( inResourceData );
  147. KeyValues *pItemKV = inResourceData->FindKey( "playerlist_panel_kvs" );
  148. if ( pItemKV )
  149. {
  150. if ( m_pPlayerListPanelKVs )
  151. {
  152. m_pPlayerListPanelKVs->deleteThis();
  153. }
  154. m_pPlayerListPanelKVs = new KeyValues("playerlist_panel_kvs");
  155. pItemKV->CopySubkeys( m_pPlayerListPanelKVs );
  156. }
  157. }
  158. //-----------------------------------------------------------------------------
  159. // Purpose:
  160. //-----------------------------------------------------------------------------
  161. void CTFGiveawayItemPanel::PerformLayout( void )
  162. {
  163. BaseClass::PerformLayout();
  164. int iPosition = 0;
  165. for ( int i = 0; i < m_aPlayerList.Count(); i++ )
  166. {
  167. if ( !m_aPlayerList[i]->IsVisible() )
  168. continue;
  169. int iCenter = GetWide() * 0.5;
  170. int iXPos = iCenter;
  171. int iYPos = 0;
  172. if ( iPosition < (m_iNumActivePlayers * 0.5) )
  173. {
  174. iXPos -= m_aPlayerList[i]->GetWide() + m_iPlayerXOffset;
  175. iYPos = m_iPlayerYPos + iPosition * m_aPlayerList[i]->GetTall();
  176. }
  177. else
  178. {
  179. iXPos += m_iPlayerXOffset;
  180. iYPos = m_iPlayerYPos + (iPosition - ceil(m_iNumActivePlayers * 0.5)) * m_aPlayerList[i]->GetTall();
  181. }
  182. m_aPlayerList[i]->SetPos( iXPos, iYPos );
  183. iPosition++;
  184. }
  185. }
  186. //-----------------------------------------------------------------------------
  187. // Purpose:
  188. //-----------------------------------------------------------------------------
  189. void CTFGiveawayItemPanel::ShowPanel(bool bShow)
  190. {
  191. if ( bShow )
  192. {
  193. SetItem( NULL );
  194. m_bBuiltPlayerList = false;
  195. m_flNextRollStart = 0;
  196. m_iRollingForPlayer = 0;
  197. m_iNumActivePlayers = 0;
  198. }
  199. SetMouseInputEnabled( bShow );
  200. SetVisible( bShow );
  201. }
  202. //-----------------------------------------------------------------------------
  203. // Purpose:
  204. //-----------------------------------------------------------------------------
  205. void CTFGiveawayItemPanel::FireGameEvent( IGameEvent *event )
  206. {
  207. const char * type = event->GetName();
  208. if ( Q_strcmp(type, "gameui_hidden") == 0 )
  209. {
  210. ShowPanel( false );
  211. }
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Purpose:
  215. //-----------------------------------------------------------------------------
  216. void CTFGiveawayItemPanel::OnCommand( const char *command )
  217. {
  218. if ( !Q_stricmp( command, "vguicancel" ) )
  219. {
  220. ShowPanel( false );
  221. // If we're connected to a game server, we also close the game UI.
  222. if ( engine->IsInGame() )
  223. {
  224. engine->ClientCmd_Unrestricted( "gameui_hide" );
  225. }
  226. }
  227. else
  228. {
  229. engine->ClientCmd( const_cast<char *>( command ) );
  230. }
  231. BaseClass::OnCommand( command );
  232. }
  233. //-----------------------------------------------------------------------------
  234. // Purpose:
  235. //-----------------------------------------------------------------------------
  236. void CTFGiveawayItemPanel::Update( void )
  237. {
  238. // First, wait for the player list to get built
  239. if ( !m_bBuiltPlayerList )
  240. {
  241. BuildPlayerList();
  242. if ( !m_bBuiltPlayerList )
  243. return;
  244. }
  245. // Then wait for the server to send us the item details
  246. if ( !m_pModelPanel->HasItem() )
  247. {
  248. if ( TFGameRules() )
  249. {
  250. CBonusRoundLogic *pLogic = TFGameRules()->GetBonusLogic();
  251. if ( pLogic )
  252. {
  253. m_pModelPanel->SetItem( pLogic->GetBonusItem() );
  254. }
  255. }
  256. if ( !m_pModelPanel->HasItem() )
  257. return;
  258. }
  259. // Then start rolling through the players and locking in their bonuses
  260. if ( m_iRollingForPlayer < m_iNumActivePlayers )
  261. {
  262. // Spin all the numbers & lock them in one by one
  263. for ( int i = 0; i < m_aPlayerList.Count(); i++ )
  264. {
  265. if ( m_iRollingForPlayer < i )
  266. {
  267. // Haven't got to this player yet, so spin their bonus.
  268. m_aPlayerList[i]->SpinBonus();
  269. continue;
  270. }
  271. if ( i == m_iRollingForPlayer )
  272. {
  273. if ( gpGlobals->curtime > m_flNextRollStart )
  274. {
  275. // Lock in this player's bonus and move on to the next one
  276. CBonusRoundLogic *pLogic = TFGameRules()->GetBonusLogic();
  277. if ( pLogic )
  278. {
  279. m_aPlayerList[i]->LockBonus( pLogic->GetPlayerBonusRoll( m_aPlayerList[i]->GetPlayerIndex() ) );
  280. }
  281. m_iRollingForPlayer++;
  282. m_flNextRollStart = gpGlobals->curtime + 0.4;
  283. }
  284. else
  285. {
  286. m_aPlayerList[i]->SpinBonus();
  287. }
  288. }
  289. }
  290. }
  291. }
  292. //-----------------------------------------------------------------------------
  293. // Purpose:
  294. //-----------------------------------------------------------------------------
  295. void CTFGiveawayItemPanel::BuildPlayerList( void )
  296. {
  297. CBonusRoundLogic *pLogic = TFGameRules()->GetBonusLogic();
  298. if ( !pLogic )
  299. return;
  300. m_bBuiltPlayerList = true;
  301. pLogic->BuildBonusPlayerList();
  302. for ( int i = 0; i < m_aPlayerList.Count(); i++ )
  303. {
  304. m_aPlayerList[i]->SetPlayer(NULL);
  305. }
  306. m_iNumActivePlayers = 0;
  307. for( int playerIndex = 0; playerIndex < pLogic->GetNumBonusPlayers(); playerIndex++ )
  308. {
  309. C_TFPlayer *pPlayer = pLogic->GetBonusPlayer(playerIndex);
  310. if ( !pPlayer )
  311. continue;
  312. CGiveawayPlayerPanel *pPlayerPanel;
  313. if ( m_iNumActivePlayers < m_aPlayerList.Count() )
  314. {
  315. pPlayerPanel = m_aPlayerList[m_iNumActivePlayers];
  316. }
  317. else
  318. {
  319. const char *pszCommand = VarArgs("playerpanel%d",m_iNumActivePlayers);
  320. pPlayerPanel = new CGiveawayPlayerPanel( this, pszCommand );
  321. if ( m_pPlayerListPanelKVs )
  322. {
  323. pPlayerPanel->ApplySettings( m_pPlayerListPanelKVs );
  324. }
  325. pPlayerPanel->MakeReadyForUse();
  326. vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
  327. pPlayerPanel->SetBorder( pScheme->GetBorder("EconItemBorder") );
  328. m_aPlayerList.AddToTail( pPlayerPanel );
  329. }
  330. pPlayerPanel->SetPlayer( pPlayer );
  331. m_iNumActivePlayers++;
  332. }
  333. // Start the animation
  334. m_flNextRollStart = gpGlobals->curtime + 1.0;
  335. m_iRollingForPlayer = 0;
  336. InvalidateLayout();
  337. }
  338. //-----------------------------------------------------------------------------
  339. // Purpose:
  340. //-----------------------------------------------------------------------------
  341. void CTFGiveawayItemPanel::SetItem( CEconItemView *pItem )
  342. {
  343. m_pModelPanel->SetItem( pItem );
  344. }
  345. static vgui::DHANDLE<CTFGiveawayItemPanel> g_GiveawayItemPanel;
  346. //-----------------------------------------------------------------------------
  347. // Purpose:
  348. //-----------------------------------------------------------------------------
  349. CTFGiveawayItemPanel *OpenGiveawayItemPanel( CEconItemView *pItem )
  350. {
  351. CTFGiveawayItemPanel *pPanel = (CTFGiveawayItemPanel*)gViewPortInterface->FindPanelByName( PANEL_GIVEAWAY_ITEM );
  352. if ( pPanel )
  353. {
  354. pPanel->InvalidateLayout( false, true );
  355. pPanel->SetItem( pItem );
  356. gViewPortInterface->ShowPanel( pPanel, true );
  357. }
  358. return pPanel;
  359. }
  360. //-----------------------------------------------------------------------------
  361. // Purpose:
  362. //-----------------------------------------------------------------------------
  363. void Test_GiveawayItemPanel( const CCommand &args )
  364. {
  365. C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  366. if ( !pLocalPlayer )
  367. return;
  368. CEconItemView *pScriptCreatedItem = NULL;
  369. bool bAllItems = (args.ArgC() <= 1);
  370. for ( int i = bAllItems ? 0 : clamp( atoi(args[1]), 0, 2 ); i <= 2; i++ )
  371. {
  372. CEconEntity *pItem = dynamic_cast<CEconEntity *>( pLocalPlayer->Weapon_GetWeaponByType( i ) );
  373. if ( !pItem )
  374. continue;
  375. pScriptCreatedItem = pItem->GetAttributeContainer()->GetItem();
  376. break;
  377. }
  378. if ( pScriptCreatedItem )
  379. {
  380. OpenGiveawayItemPanel( pScriptCreatedItem );
  381. }
  382. }
  383. ConCommand test_giveawayitem( "test_giveawayitem", Test_GiveawayItemPanel, "Debugging tool to test the item giveaway panel. Usage: test_giveawayitem <weapon name>\n <weapon id>: 0 = primary, 1 = secondary, 2 = melee.", FCVAR_CHEAT );