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.

323 lines
8.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Present a list of sessions from which the player can choose a game to join.
  4. //
  5. //=============================================================================//
  6. #include "sessionbrowserdialog.h"
  7. #include "engine/imatchmaking.h"
  8. #include "EngineInterface.h"
  9. #include "vgui_controls/ImagePanel.h"
  10. #include "vgui_controls/Label.h"
  11. #include "KeyValues.h"
  12. #include "vgui/ISurface.h"
  13. // memdbgon must be the last include file in a .cpp file!!!
  14. #include "tier0/memdbgon.h"
  15. CSessionBrowserDialog *g_pBrowserDialog;
  16. //--------------------------------
  17. // CSessionBrowserDialog
  18. //--------------------------------
  19. CSessionBrowserDialog::CSessionBrowserDialog( vgui::Panel *pParent, KeyValues *pDialogKeys ) : BaseClass( pParent, "" )
  20. {
  21. g_pBrowserDialog = this;
  22. m_pDialogKeys = pDialogKeys;
  23. SetDeleteSelfOnClose( true );
  24. }
  25. CSessionBrowserDialog::~CSessionBrowserDialog()
  26. {
  27. m_pScenarioInfos.PurgeAndDeleteElements();
  28. }
  29. //---------------------------------------------------------------------
  30. // Purpose: Center the dialog on the screen
  31. //---------------------------------------------------------------------
  32. void CSessionBrowserDialog::PerformLayout()
  33. {
  34. BaseClass::PerformLayout();
  35. MoveToCenterOfScreen();
  36. UpdateScenarioDisplay();
  37. }
  38. //---------------------------------------------------------------------
  39. // Purpose: Parse session properties and contexts from the resource file
  40. //---------------------------------------------------------------------
  41. void CSessionBrowserDialog::ApplySettings( KeyValues *pResourceData )
  42. {
  43. BaseClass::ApplySettings( pResourceData );
  44. KeyValues *pScenarios = pResourceData->FindKey( "ScenarioInfoPanels" );
  45. if ( pScenarios )
  46. {
  47. for ( KeyValues *pScenario = pScenarios->GetFirstSubKey(); pScenario != NULL; pScenario = pScenario->GetNextKey() )
  48. {
  49. CScenarioInfoPanel *pScenarioInfo = new CScenarioInfoPanel( this, "ScenarioInfoPanel" );
  50. SETUP_PANEL( pScenarioInfo );
  51. pScenarioInfo->m_pTitle->SetText( pScenario->GetString( "title" ) );
  52. pScenarioInfo->m_pSubtitle->SetText( pScenario->GetString( "subtitle" ) );
  53. pScenarioInfo->m_pMapImage->SetImage( pScenario->GetString( "image" ) );
  54. int nTall = pScenario->GetInt( "tall", -1 );
  55. if ( nTall > 0 )
  56. {
  57. pScenarioInfo->SetTall( nTall );
  58. }
  59. int nXPos = pScenario->GetInt( "xpos", -1 );
  60. if ( nXPos >= 0 )
  61. {
  62. int x, y;
  63. pScenarioInfo->GetPos( x, y );
  64. pScenarioInfo->SetPos( nXPos, y );
  65. }
  66. int nDescOneYpos = pScenario->GetInt( "descOneY", -1 );
  67. if ( nDescOneYpos > 0 )
  68. {
  69. int x, y;
  70. pScenarioInfo->m_pDescOne->GetPos( x, y );
  71. pScenarioInfo->m_pDescOne->SetPos( x, nDescOneYpos );
  72. }
  73. int nDescTwoYpos = pScenario->GetInt( "descTwoY", -1 );
  74. if ( nDescTwoYpos > 0 )
  75. {
  76. int x, y;
  77. pScenarioInfo->m_pDescTwo->GetPos( x, y );
  78. pScenarioInfo->m_pDescTwo->SetPos( x, nDescTwoYpos );
  79. }
  80. m_pScenarioInfos.AddToTail( pScenarioInfo );
  81. }
  82. }
  83. }
  84. //---------------------------------------------------------------------
  85. // Purpose: Set up colors and other such stuff
  86. //---------------------------------------------------------------------
  87. void CSessionBrowserDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
  88. {
  89. BaseClass::ApplySchemeSettings( pScheme );
  90. for ( int i = 0; i < m_pScenarioInfos.Count(); ++i )
  91. {
  92. m_pScenarioInfos[i]->SetBgColor( pScheme->GetColor( "TanDark", Color( 0, 0, 0, 255 ) ) );
  93. }
  94. }
  95. //---------------------------------------------------------------------
  96. // Purpose: Info about a session, sent from matchmaking
  97. //---------------------------------------------------------------------
  98. void CSessionBrowserDialog::SessionSearchResult( int searchIdx, void *pHostData, XSESSION_SEARCHRESULT *pResult, int ping )
  99. {
  100. char *pPing;
  101. switch ( ping )
  102. {
  103. case 0:
  104. pPing = "#TF_Icon_Ping_Green";
  105. break;
  106. case 1:
  107. pPing = "#TF_Icon_Ping_Yellow";
  108. break;
  109. case 2:
  110. default:
  111. pPing = "#TF_Icon_Ping_Red";
  112. break;
  113. }
  114. int nScenarioId = 0;
  115. uint nContextId = m_pDialogKeys->GetInt( "scenario", -1 );
  116. for ( uint i = 0; i < pResult->cContexts; ++i )
  117. {
  118. if ( pResult->pContexts[i].dwContextId == nContextId )
  119. {
  120. nScenarioId = pResult->pContexts[i].dwValue;
  121. break;
  122. }
  123. }
  124. hostData_s *pData = (hostData_s*)pHostData;
  125. int filledSlots = pResult->dwFilledPublicSlots + pResult->dwFilledPrivateSlots;
  126. int totalSlots = filledSlots + pResult->dwOpenPublicSlots + pResult->dwOpenPrivateSlots;
  127. m_GameStates.AddToTail( pData->gameState );
  128. m_GameTimes.AddToTail( pData->gameTime );
  129. m_XUIDs.AddToTail( pData->xuid );
  130. char szSlots[16] = {0};
  131. Q_snprintf( szSlots, sizeof( szSlots ), "%d/%d", filledSlots, totalSlots );
  132. int ct = 0;
  133. const char *ppStrings[4];
  134. ppStrings[ct++] = pData->hostName;
  135. ppStrings[ct++] = szSlots;
  136. ppStrings[ct++] = pData->scenario;
  137. if ( ping != -1 )
  138. {
  139. ppStrings[ct++] = pPing;
  140. }
  141. m_Menu.AddSectionedItem( ppStrings, ct );
  142. m_ScenarioIndices.AddToTail( nScenarioId );
  143. m_SearchIndices.AddToTail( searchIdx );
  144. if ( m_Menu.GetItemCount() == 1 )
  145. {
  146. m_Menu.SetFocus( 0 );
  147. }
  148. UpdateScenarioDisplay();
  149. }
  150. //-----------------------------------------------------------------
  151. // Purpose: Show the correct scenario image and text
  152. //-----------------------------------------------------------------
  153. void CSessionBrowserDialog::UpdateScenarioDisplay( void )
  154. {
  155. if ( !m_ScenarioIndices.Count() )
  156. return;
  157. // Check if the selected map has changed (first menu item)
  158. int idx = m_Menu.GetActiveItemIndex();
  159. for ( int i = 0; i < m_pScenarioInfos.Count(); ++i )
  160. {
  161. m_pScenarioInfos[i]->SetVisible( i == m_ScenarioIndices[idx] );
  162. }
  163. // Get the screen size
  164. int wide, tall;
  165. vgui::surface()->GetScreenSize(wide, tall);
  166. bool bLodef = ( tall <= 480 );
  167. const char *pState = "";
  168. switch( m_GameStates[idx] )
  169. {
  170. case 0:
  171. if ( bLodef )
  172. {
  173. pState = "#TF_GameState_InLobby_lodef";
  174. }
  175. else
  176. {
  177. pState = "#TF_GameState_InLobby";
  178. }
  179. break;
  180. case 1:
  181. if ( bLodef )
  182. {
  183. pState = "#TF_GameState_GameInProgress_lodef";
  184. }
  185. else
  186. {
  187. pState = "#TF_GameState_GameInProgress";
  188. }
  189. break;
  190. }
  191. char szTime[32] = {0};
  192. if ( m_GameTimes[idx] >= NO_TIME_LIMIT )
  193. {
  194. Q_strncpy( szTime, "#TF_NoTimeLimit", sizeof( szTime) );
  195. }
  196. else
  197. {
  198. Q_snprintf( szTime, sizeof( szTime), "%d:00", m_GameTimes[idx] );
  199. }
  200. if ( !m_pScenarioInfos.IsValidIndex( m_ScenarioIndices[idx] ) )
  201. return;
  202. CScenarioInfoPanel *pPanel = m_pScenarioInfos[ m_ScenarioIndices[idx] ];
  203. pPanel->m_pDescOne->SetText( pState );
  204. pPanel->m_pDescTwo->SetText( szTime );
  205. }
  206. //-----------------------------------------------------------------
  207. // helper to swap two ints in a utlvector
  208. //-----------------------------------------------------------------
  209. static void Swap( CUtlVector< int > &vec, int iOne, int iTwo )
  210. {
  211. int temp = vec[iOne];
  212. vec[iOne] = vec[iTwo];
  213. vec[iTwo] = temp;
  214. }
  215. //-----------------------------------------------------------------
  216. // Purpose: Swap the order of two menu items
  217. //-----------------------------------------------------------------
  218. void CSessionBrowserDialog::SwapMenuItems( int iOne, int iTwo )
  219. {
  220. Swap( m_ScenarioIndices, iOne, iTwo );
  221. Swap( m_SearchIndices, iOne, iTwo );
  222. Swap( m_GameStates, iOne, iTwo );
  223. Swap( m_GameTimes, iOne, iTwo );
  224. // swap the XUIDs, too
  225. XUID temp = m_XUIDs[iOne];
  226. m_XUIDs[iOne] = m_XUIDs[iTwo];
  227. m_XUIDs[iTwo] = temp;
  228. }
  229. //-----------------------------------------------------------------
  230. // Purpose: Handle commands from the dialog menu
  231. //-----------------------------------------------------------------
  232. void CSessionBrowserDialog::OnCommand( const char *pCommand )
  233. {
  234. if ( !Q_stricmp( pCommand, "SelectSession" ) )
  235. {
  236. int idx = m_SearchIndices[ m_Menu.GetActiveItemIndex() ];
  237. matchmaking->SelectSession( idx );
  238. }
  239. m_pParent->OnCommand( pCommand );
  240. }
  241. //-----------------------------------------------------------------
  242. // Purpose: Send key presses to the dialog's menu
  243. //-----------------------------------------------------------------
  244. void CSessionBrowserDialog::OnKeyCodePressed( vgui::KeyCode code )
  245. {
  246. switch( code )
  247. {
  248. case KEY_XBUTTON_B:
  249. matchmaking->KickPlayerFromSession( 0 );
  250. break;
  251. case KEY_XBUTTON_X:
  252. #ifdef _X360
  253. int idx = m_Menu.GetActiveItemIndex();
  254. if ( m_XUIDs.IsValidIndex( idx ) )
  255. {
  256. XShowGamerCardUI( XBX_GetPrimaryUserId(), m_XUIDs[idx] );
  257. }
  258. #endif
  259. break;
  260. }
  261. BaseClass::OnKeyCodePressed( code );
  262. // Selected session may have been updated
  263. UpdateScenarioDisplay();
  264. }
  265. //-----------------------------------------------------------------------------
  266. // Purpose:
  267. //-----------------------------------------------------------------------------
  268. void CSessionBrowserDialog::OnThink()
  269. {
  270. vgui::KeyCode code = m_KeyRepeat.KeyRepeated();
  271. if ( code )
  272. {
  273. m_Menu.HandleKeyCode( code );
  274. UpdateScenarioDisplay();
  275. }
  276. BaseClass::OnThink();
  277. }