Counter Strike : Global Offensive Source Code
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.

458 lines
13 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include <cdll_client_int.h>
  9. #include "teammenu.h"
  10. #include <vgui/IScheme.h>
  11. #include <vgui/ILocalize.h>
  12. #include <vgui/ISurface.h>
  13. #include <KeyValues.h>
  14. #include <vgui_controls/ImageList.h>
  15. #include <FileSystem.h>
  16. #include <vgui_controls/RichText.h>
  17. #include <vgui_controls/Label.h>
  18. #include <vgui_controls/Button.h>
  19. #include <vgui_controls/HTML.h>
  20. #include "IGameUIFuncs.h" // for key bindings
  21. #include <igameresources.h>
  22. #include <game/client/iviewport.h>
  23. #include <stdlib.h> // MAX_PATH define
  24. #include <stdio.h>
  25. #include "byteswap.h"
  26. // memdbgon must be the last include file in a .cpp file!!!
  27. #include "tier0/memdbgon.h"
  28. extern IGameUIFuncs *gameuifuncs; // for key binding details
  29. using namespace vgui;
  30. void UpdateCursorState();
  31. // void DuckMessage(const char *str);
  32. // helper function
  33. const char *GetStringTeamColor( int i )
  34. {
  35. switch( i )
  36. {
  37. case 0:
  38. return "team0";
  39. case 1:
  40. return "team1";
  41. case 2:
  42. return "team2";
  43. case 3:
  44. return "team3";
  45. case 4:
  46. default:
  47. return "team4";
  48. }
  49. }
  50. //-----------------------------------------------------------------------------
  51. // Purpose: Constructor
  52. //-----------------------------------------------------------------------------
  53. CTeamMenu::CTeamMenu(IViewPort *pViewPort) : Frame(NULL, PANEL_TEAM )
  54. {
  55. m_pViewPort = pViewPort;
  56. m_iJumpKey = BUTTON_CODE_INVALID; // this is looked up in Activate()
  57. m_iScoreBoardKey = BUTTON_CODE_INVALID; // this is looked up in Activate()
  58. // initialize dialog
  59. SetTitle("", true);
  60. // load the new scheme early!!
  61. SetScheme("ClientScheme");
  62. SetMoveable(false);
  63. SetSizeable(false);
  64. // hide the system buttons
  65. SetTitleBarVisible( false );
  66. SetProportional(true);
  67. #if !defined(CSTRIKE15)
  68. // info window about this map
  69. m_pMapInfo = new RichText( this, "MapInfo" );
  70. #if defined( ENABLE_HTML_WINDOW )
  71. m_pMapInfoHTML = new HTML( this, "MapInfoHTML");
  72. #endif
  73. #endif
  74. LoadControlSettings("Resource/UI/TeamMenu.res");
  75. InvalidateLayout();
  76. m_szMapName[0] = 0;
  77. //=============================================================================
  78. // HPE_BEGIN:
  79. // [Forrest]
  80. //=============================================================================
  81. ListenForGameEvent( "cs_match_end_restart" );
  82. //=============================================================================
  83. // HPE_END
  84. //=============================================================================
  85. }
  86. //-----------------------------------------------------------------------------
  87. // Purpose: Destructor
  88. //-----------------------------------------------------------------------------
  89. CTeamMenu::~CTeamMenu()
  90. {
  91. }
  92. //-----------------------------------------------------------------------------
  93. // Purpose: sets the text color of the map description field
  94. //-----------------------------------------------------------------------------
  95. void CTeamMenu::ApplySchemeSettings(IScheme *pScheme)
  96. {
  97. BaseClass::ApplySchemeSettings(pScheme);
  98. #if !defined(CSTRIKE15)
  99. m_pMapInfo->SetFgColor( pScheme->GetColor("MapDescriptionText", Color(255, 255, 255, 0)) );
  100. if ( *m_szMapName )
  101. {
  102. LoadMapPage( m_szMapName ); // reload the map description to pick up the color
  103. }
  104. #endif
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Purpose: makes the user choose the auto assign option
  108. //-----------------------------------------------------------------------------
  109. void CTeamMenu::AutoAssign()
  110. {
  111. engine->ClientCmd("jointeam 0");
  112. OnClose();
  113. }
  114. //-----------------------------------------------------------------------------
  115. // Purpose: shows the team menu
  116. //-----------------------------------------------------------------------------
  117. void CTeamMenu::ShowPanel(bool bShow)
  118. {
  119. if ( BaseClass::IsVisible() == bShow )
  120. return;
  121. if ( bShow )
  122. {
  123. Activate();
  124. SetMouseInputEnabled( true );
  125. // get key bindings if shown
  126. if( m_iJumpKey == BUTTON_CODE_INVALID ) // you need to lookup the jump key AFTER the engine has loaded
  127. {
  128. m_iJumpKey = gameuifuncs->GetButtonCodeForBind( "jump" );
  129. }
  130. if ( m_iScoreBoardKey == BUTTON_CODE_INVALID )
  131. {
  132. m_iScoreBoardKey = gameuifuncs->GetButtonCodeForBind( "showscores" );
  133. }
  134. }
  135. else
  136. {
  137. SetVisible( false );
  138. SetMouseInputEnabled( false );
  139. }
  140. m_pViewPort->ShowBackGround( bShow );
  141. }
  142. //=============================================================================
  143. // HPE_BEGIN:
  144. // [Forrest]
  145. //=============================================================================
  146. //-----------------------------------------------------------------------------
  147. // Purpose: respond to game events
  148. //-----------------------------------------------------------------------------
  149. void CTeamMenu::FireGameEvent( IGameEvent *event )
  150. {
  151. const char *type = event->GetName();
  152. if( 0 == Q_strcmp( type, "cs_match_end_restart" ) )
  153. {
  154. // Reselect teams when restarting a new match.
  155. ShowPanel( true );
  156. }
  157. }
  158. //=============================================================================
  159. // HPE_END
  160. //=============================================================================
  161. //-----------------------------------------------------------------------------
  162. // Purpose: updates the UI with a new map name and map html page, and sets up the team buttons
  163. //-----------------------------------------------------------------------------
  164. void CTeamMenu::Update()
  165. {
  166. #if !defined(CSTRIKE15)
  167. char mapname[MAX_MAP_NAME];
  168. Q_FileBase( engine->GetLevelName(), mapname, sizeof(mapname) );
  169. SetLabelText( "mapname", mapname );
  170. // DWenger - Pulled out for now - LoadMapPage( mapname );
  171. #endif
  172. }
  173. //-----------------------------------------------------------------------------
  174. // Purpose: chooses and loads the text page to display that describes mapName map
  175. //-----------------------------------------------------------------------------
  176. void CTeamMenu::LoadMapPage( const char *mapName )
  177. {
  178. #if !defined(CSTRIKE15)
  179. // Save off the map name so we can re-load the page in ApplySchemeSettings().
  180. Q_strncpy( m_szMapName, mapName, strlen( mapName ) + 1 );
  181. char mapRES[ MAX_PATH ];
  182. char uilanguage[ 64 ];
  183. engine->GetUILanguage( uilanguage, sizeof( uilanguage ) );
  184. Q_snprintf( mapRES, sizeof( mapRES ), "resource/maphtml/%s_%s.html", mapName, uilanguage );
  185. bool bFoundHTML = false;
  186. if ( !g_pFullFileSystem->FileExists( mapRES ) )
  187. {
  188. // try english
  189. Q_snprintf( mapRES, sizeof( mapRES ), "resource/maphtml/%s_english.html", mapName );
  190. }
  191. else
  192. {
  193. bFoundHTML = true;
  194. }
  195. if( bFoundHTML || g_pFullFileSystem->FileExists( mapRES ) )
  196. {
  197. // it's a local HTML file
  198. char localURL[ _MAX_PATH + 7 ];
  199. Q_strncpy( localURL, "file://", sizeof( localURL ) );
  200. char pPathData[ _MAX_PATH ];
  201. g_pFullFileSystem->GetLocalPath( mapRES, pPathData, sizeof(pPathData) );
  202. Q_strncat( localURL, pPathData, sizeof( localURL ), COPY_ALL_CHARACTERS );
  203. // force steam to dump a local copy
  204. g_pFullFileSystem->GetLocalCopy( pPathData );
  205. m_pMapInfo->SetVisible( false );
  206. #if defined( ENABLE_HTML_WINDOW )
  207. m_pMapInfoHTML->SetVisible( true );
  208. m_pMapInfoHTML->OpenURL( localURL );
  209. #endif
  210. InvalidateLayout();
  211. Repaint();
  212. return;
  213. }
  214. else
  215. {
  216. m_pMapInfo->SetVisible( true );
  217. #if defined( ENABLE_HTML_WINDOW )
  218. m_pMapInfoHTML->SetVisible( false );
  219. #endif
  220. }
  221. Q_snprintf( mapRES, sizeof( mapRES ), "maps/%s.txt", mapName);
  222. // if no map specific description exists, load default text
  223. if( !g_pFullFileSystem->FileExists( mapRES ) )
  224. {
  225. if ( g_pFullFileSystem->FileExists( "maps/default.txt" ) )
  226. {
  227. Q_snprintf ( mapRES, sizeof( mapRES ), "maps/default.txt");
  228. }
  229. else
  230. {
  231. m_pMapInfo->SetText( "" );
  232. return;
  233. }
  234. }
  235. FileHandle_t f = g_pFullFileSystem->Open( mapRES, "r" );
  236. // read into a memory block
  237. int fileSize = g_pFullFileSystem->Size(f);
  238. int dataSize = fileSize + sizeof( wchar_t );
  239. if ( dataSize % 2 )
  240. ++dataSize;
  241. wchar_t *memBlock = (wchar_t *)malloc(dataSize);
  242. memset( memBlock, 0x0, dataSize);
  243. int bytesRead = g_pFullFileSystem->Read(memBlock, fileSize, f);
  244. if ( bytesRead < fileSize )
  245. {
  246. // NULL-terminate based on the length read in, since Read() can transform \r\n to \n and
  247. // return fewer bytes than we were expecting.
  248. char *data = reinterpret_cast<char *>( memBlock );
  249. data[ bytesRead ] = 0;
  250. data[ bytesRead+1 ] = 0;
  251. }
  252. // null-terminate the stream (redundant, since we memset & then trimmed the transformed buffer already)
  253. memBlock[dataSize / sizeof(wchar_t) - 1] = 0x0000;
  254. // ensure little-endian unicode reads correctly on all platforms
  255. CByteswap byteSwap;
  256. byteSwap.SetTargetBigEndian( false );
  257. byteSwap.SwapBufferToTargetEndian( memBlock, memBlock, dataSize/sizeof(wchar_t) );
  258. // check the first character, make sure this a little-endian unicode file
  259. if ( memBlock[0] != 0xFEFF )
  260. {
  261. // its a ascii char file
  262. m_pMapInfo->SetText( reinterpret_cast<char *>( memBlock ) );
  263. }
  264. else
  265. {
  266. m_pMapInfo->SetText( memBlock+1 );
  267. }
  268. // go back to the top of the text buffer
  269. m_pMapInfo->GotoTextStart();
  270. g_pFullFileSystem->Close( f );
  271. free(memBlock);
  272. InvalidateLayout();
  273. Repaint();
  274. #endif
  275. }
  276. /*
  277. //-----------------------------------------------------------------------------
  278. // Purpose: sets the text on and displays the team buttons
  279. //-----------------------------------------------------------------------------
  280. void CTeamMenu::MakeTeamButtons(void)
  281. {
  282. int i = 0;
  283. for( i = 0; i< m_pTeamButtons.Count(); i++ )
  284. {
  285. m_pTeamButtons[i]->SetVisible(false);
  286. }
  287. i = 0;
  288. while( true )
  289. {
  290. const char *teamname = GameResources()->GetTeamName( i );
  291. if ( !teamname || !teamname[0] )
  292. return; // no more teams
  293. char buttonText[32];
  294. Q_snprintf( buttonText, sizeof(buttonText), "&%i %s", i +1, teamname );
  295. m_pTeamButtons[i]->SetText( buttonText );
  296. m_pTeamButtons[i]->SetCommand( new KeyValues("TeamButton", "team", i ) );
  297. IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
  298. m_pTeamButtons[i]->SetArmedColor(pScheme->GetColor(GetStringTeamColor(i), Color(255, 255, 255, 255)) , pScheme->GetColor("SelectionBG", Color(255, 255, 255, 0)) );
  299. m_pTeamButtons[i]->SetDepressedColor( pScheme->GetColor(GetStringTeamColor(i), Color(255, 255, 255, 255)), pScheme->GetColor("ButtonArmedBgColor", Color(255, 255, 255, 0)) );
  300. m_pTeamButtons[i]->SetDefaultColor( pScheme->GetColor(GetStringTeamColor(i), Color(255, 255, 255, 255)), pScheme->GetColor("ButtonDepressedBgColor", Color(255, 255, 255, 0)) );
  301. m_pTeamButtons[i]->SetVisible(true);
  302. i++;
  303. }
  304. }
  305. //-----------------------------------------------------------------------------
  306. // Purpose: When a team button is pressed it triggers this function to cause the player to join a team
  307. //-----------------------------------------------------------------------------
  308. void CTeamMenu::OnTeamButton( int team )
  309. {
  310. char cmd[64];
  311. if( team >= m_iNumTeams ) // its a special button
  312. {
  313. if( team == m_iNumTeams ) // first extra team is auto assign
  314. {
  315. Q_snprintf( cmd, sizeof( cmd ), "jointeam 5" );
  316. }
  317. else // next is spectate
  318. {
  319. // DuckMessage( "#Spec_Duck" );
  320. gViewPortInterface->ShowBackGround( false );
  321. }
  322. }
  323. else
  324. {
  325. Q_snprintf( cmd, sizeof( cmd ), "jointeam %i", team + 1 );
  326. //g_iTeamNumber = team + 1;
  327. }
  328. engine->ClientCmd(cmd);
  329. SetVisible( false );
  330. OnClose();
  331. } */
  332. //-----------------------------------------------------------------------------
  333. // Purpose: Sets the text of a control by name
  334. //-----------------------------------------------------------------------------
  335. void CTeamMenu::SetLabelText(const char *textEntryName, const char *text)
  336. {
  337. Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
  338. if (entry)
  339. {
  340. entry->SetText(text);
  341. }
  342. }
  343. void CTeamMenu::OnKeyCodePressed(KeyCode code)
  344. {
  345. if ( m_iScoreBoardKey != BUTTON_CODE_INVALID && m_iScoreBoardKey == code )
  346. {
  347. GetViewPortInterface()->ShowPanel( PANEL_SCOREBOARD, true );
  348. GetViewPortInterface()->PostMessageToPanel( PANEL_SCOREBOARD, new KeyValues( "PollHideCode", "code", code ) );
  349. }
  350. //=============================================================================
  351. // HPE_BEGIN
  352. // mjohnson
  353. // Remove the jump auto-assign code on the xbox. The jump code is the gamepad's
  354. // A button which is generally expected to select the currently focused item.
  355. // Add in the code for processing the stick movement up/down to modify selection.
  356. //=============================================================================
  357. #if !defined(CSTRIKE15)
  358. else if( m_iJumpKey != BUTTON_CODE_INVALID && m_iJumpKey == code )
  359. {
  360. AutoAssign();
  361. }
  362. #else
  363. else if (KEY_XSTICK1_UP == code || KEY_XBUTTON_UP == code)
  364. {
  365. RequestFocusPrev(GetFocusNavGroup().GetCurrentFocus()->GetVPanel());
  366. }
  367. else if (KEY_XSTICK1_DOWN == code || KEY_XBUTTON_DOWN == code)
  368. {
  369. RequestFocusNext(GetFocusNavGroup().GetCurrentFocus()->GetVPanel());
  370. }
  371. #endif
  372. //=============================================================================
  373. // HPE_END
  374. //=============================================================================
  375. else
  376. {
  377. BaseClass::OnKeyCodePressed( code );
  378. }
  379. }