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.

481 lines
14 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Client DLL VGUI2 Viewport
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. //
  8. //-----------------------------------------------------------------------------
  9. // $Log: $
  10. //
  11. // $NoKeywords: $
  12. //=============================================================================//
  13. #include "cbase.h"
  14. #pragma warning( disable : 4800 ) // disable forcing int to bool performance warning
  15. // VGUI panel includes
  16. #include <vgui_controls/Panel.h>
  17. #include <vgui/ISurface.h>
  18. #include <KeyValues.h>
  19. #include <vgui/Cursor.h>
  20. #include <vgui/IScheme.h>
  21. #include <vgui/IVGui.h>
  22. #include <vgui/ILocalize.h>
  23. #include <vgui/VGUI.h>
  24. #include "tier0/icommandline.h"
  25. // client dll/engine defines
  26. #include "hud.h"
  27. #include <voice_status.h>
  28. // viewport definitions
  29. #include <baseviewport.h>
  30. #include "tf_viewport.h"
  31. #include "tf_teammenu.h"
  32. #include "vguicenterprint.h"
  33. #include "text_message.h"
  34. #include "tf_classmenu.h"
  35. #include "tf_textwindow.h"
  36. #include "tf_clientscoreboard.h"
  37. #include "tf_spectatorgui.h"
  38. #include "intromenu.h"
  39. #include "tf_intromenu.h"
  40. #include "tf_controls.h"
  41. #include "tf_mapinfomenu.h"
  42. #include "tf_roundinfo.h"
  43. #include "item_pickup_panel.h"
  44. #include "character_info_panel.h"
  45. #include "tf_hud_arena_winpanel.h"
  46. #include "tf_arenateammenu.h"
  47. #include "tf_hud_pve_winpanel.h"
  48. #include "hud_chat.h"
  49. #include "tf_giveawayitempanel.h"
  50. #if defined( REPLAY_ENABLED )
  51. #include "replay/vgui/replaybrowsermainpanel.h"
  52. #endif
  53. #include "clientmode_tf.h"
  54. #include "ienginevgui.h"
  55. #include "tf_hud_mainmenuoverride.h"
  56. #include "c_tf_objective_resource.h"
  57. #include "quest_log_panel.h"
  58. //#include "tf_overview.h"
  59. /*
  60. CON_COMMAND( spec_help, "Show spectator help screen")
  61. {
  62. if ( gViewPortInterface )
  63. gViewPortInterface->ShowPanel( PANEL_INFO, true );
  64. }
  65. CON_COMMAND( spec_menu, "Activates spectator menu")
  66. {
  67. bool bShowIt = true;
  68. C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer();
  69. if ( pPlayer && !pPlayer->IsObserver() )
  70. return;
  71. if ( args.ArgC() == 2 )
  72. {
  73. bShowIt = atoi( args[ 1 ] ) == 1;
  74. }
  75. if ( gViewPortInterface )
  76. gViewPortInterface->ShowPanel( PANEL_SPECMENU, bShowIt );
  77. }
  78. */
  79. CON_COMMAND( showmapinfo, "Show map info panel" )
  80. {
  81. if ( !gViewPortInterface )
  82. return;
  83. C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer();
  84. // don't let the player open the team menu themselves until they're a spectator or they're on a regular team and have picked a class
  85. if ( pPlayer )
  86. {
  87. if ( ( pPlayer->GetTeamNumber() == TEAM_SPECTATOR ) ||
  88. ( ( pPlayer->GetTeamNumber() != TEAM_UNASSIGNED ) && ( pPlayer->GetPlayerClass()->GetClassIndex() != TF_CLASS_UNDEFINED ) ) )
  89. {
  90. // close all the other panels that could be open
  91. gViewPortInterface->ShowPanel( PANEL_TEAM, false );
  92. gViewPortInterface->ShowPanel( PANEL_ARENA_TEAM, false );
  93. gViewPortInterface->ShowPanel( PANEL_ARENA_WIN, false );
  94. gViewPortInterface->ShowPanel( PANEL_PVE_WIN, false );
  95. gViewPortInterface->ShowPanel( PANEL_CLASS_RED, false );
  96. gViewPortInterface->ShowPanel( PANEL_CLASS_BLUE, false );
  97. gViewPortInterface->ShowPanel( PANEL_INTRO, false );
  98. gViewPortInterface->ShowPanel( PANEL_ROUNDINFO, false );
  99. gViewPortInterface->ShowPanel( PANEL_MAPINFO, true );
  100. gViewPortInterface->ShowPanel( PANEL_GIVEAWAY_ITEM, false );
  101. }
  102. }
  103. }
  104. CON_COMMAND( changeteam, "Choose a new team" )
  105. {
  106. if ( !gViewPortInterface )
  107. return;
  108. C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer();
  109. // don't let the player open the team menu themselves until they're on a team
  110. if ( pPlayer && pPlayer->CanShowTeamMenu() )
  111. {
  112. if ( TFGameRules()->IsInArenaMode() == true && tf_arena_use_queue.GetBool() == true )
  113. {
  114. gViewPortInterface->ShowPanel( PANEL_ARENA_TEAM, true );
  115. }
  116. else
  117. {
  118. gViewPortInterface->ShowPanel( PANEL_TEAM, true );
  119. }
  120. }
  121. }
  122. CON_COMMAND( changeclass, "Choose a new class" )
  123. {
  124. if ( !gViewPortInterface )
  125. return;
  126. C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer();
  127. if ( pPlayer && pPlayer->CanShowClassMenu() )
  128. {
  129. if ( TFGameRules() && TFGameRules()->IsInArenaMode() && pPlayer->IsAlive() == true )
  130. {
  131. if ( pPlayer->GetTeamNumber() > LAST_SHARED_TEAM && ( tf_arena_force_class.GetBool() == true || TFGameRules()->InStalemate() == true ) )
  132. {
  133. CBaseHudChat *pHUDChat = (CBaseHudChat *)GET_HUDELEMENT( CHudChat );
  134. if ( pHUDChat )
  135. {
  136. char szLocalized[100];
  137. g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( "#TF_Arena_NoClassChange" ), szLocalized, sizeof(szLocalized) );
  138. pHUDChat->ChatPrintf( pPlayer->entindex(), CHAT_FILTER_NONE, "%s ", szLocalized );
  139. }
  140. return;
  141. }
  142. }
  143. if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
  144. {
  145. if ( !TFGameRules()->InSetup() )
  146. {
  147. CBaseHudChat *pHUDChat = (CBaseHudChat *)GET_HUDELEMENT( CHudChat );
  148. if ( pHUDChat )
  149. {
  150. char szLocalized[100];
  151. g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( "#TF_MVM_NoClassChangeAfterSetup" ), szLocalized, sizeof(szLocalized) );
  152. pHUDChat->ChatPrintf( pPlayer->entindex(), CHAT_FILTER_NONE, "%s ", szLocalized );
  153. }
  154. return;
  155. }
  156. }
  157. switch( pPlayer->GetTeamNumber() )
  158. {
  159. case TF_TEAM_RED:
  160. gViewPortInterface->ShowPanel( PANEL_CLASS_RED, true );
  161. break;
  162. case TF_TEAM_BLUE:
  163. gViewPortInterface->ShowPanel( PANEL_CLASS_BLUE, true );
  164. break;
  165. case TEAM_SPECTATOR:
  166. {
  167. if( TFGameRules() && TFGameRules()->IsInArenaMode() == true && tf_arena_use_queue.GetBool() == true )
  168. {
  169. gViewPortInterface->ShowPanel( PANEL_CLASS_BLUE, true );
  170. }
  171. }
  172. break;
  173. default:
  174. break;
  175. }
  176. }
  177. }
  178. CON_COMMAND( togglescores, "Toggles score panel")
  179. {
  180. if ( !gViewPortInterface )
  181. return;
  182. IViewPortPanel *scoreboard = gViewPortInterface->FindPanelByName( PANEL_SCOREBOARD );
  183. if ( !scoreboard )
  184. return;
  185. if ( scoreboard->IsVisible() )
  186. {
  187. gViewPortInterface->ShowPanel( scoreboard, false );
  188. GetClientVoiceMgr()->StopSquelchMode();
  189. }
  190. else
  191. {
  192. gViewPortInterface->ShowPanel( scoreboard, true );
  193. }
  194. }
  195. CON_COMMAND( show_quest_log, "Show the quest log panel" )
  196. {
  197. if ( !gViewPortInterface )
  198. return;
  199. IViewPortPanel *pQuestLog = gViewPortInterface->FindPanelByName( PANEL_QUEST_LOG );
  200. if ( !pQuestLog )
  201. return;
  202. if ( pQuestLog->IsVisible() )
  203. {
  204. gViewPortInterface->ShowPanel( pQuestLog, false );
  205. }
  206. else
  207. {
  208. gViewPortInterface->ShowPanel( pQuestLog, true );
  209. }
  210. }
  211. TFViewport::TFViewport()
  212. {
  213. ivgui()->AddTickSignal( GetVPanel(), 0 );
  214. }
  215. //-----------------------------------------------------------------------------
  216. // Purpose:
  217. //-----------------------------------------------------------------------------
  218. TFViewport::~TFViewport()
  219. {
  220. }
  221. //-----------------------------------------------------------------------------
  222. // Purpose: called when the VGUI subsystem starts up
  223. // Creates the sub panels and initialises them
  224. //-----------------------------------------------------------------------------
  225. void TFViewport::Start( IGameUIFuncs *pGameUIFuncs, IGameEventManager2 * pGameEventManager )
  226. {
  227. BaseClass::Start( pGameUIFuncs, pGameEventManager );
  228. }
  229. void TFViewport::ApplySchemeSettings( vgui::IScheme *pScheme )
  230. {
  231. BaseClass::ApplySchemeSettings( pScheme );
  232. gHUD.InitColors( pScheme );
  233. SetPaintBackgroundEnabled( false );
  234. // Precache some font characters for the 360
  235. if ( IsX360() || CommandLine()->CheckParm( "-precachefontchars" ) || CommandLine()->CheckParm( "-precachefontintlchars" ) )
  236. {
  237. const wchar_t *pAllChars = L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.!:";
  238. const wchar_t *pNumbers = L"0123456789";
  239. // Try some tricky characters and some international characters with accents, etc.
  240. static const wchar_t IntlChars[] = { 'a', 'b', 'c', 'i', 'o', 'y', 'A', 'B', 'C', 0xbf, 0xc1, 0xd1, 0xd3, 0x00 };
  241. if ( CommandLine()->CheckParm( "-precachefontintlchars" ) )
  242. pAllChars = IntlChars;
  243. vgui::surface()->PrecacheFontCharacters( pScheme->GetFont( "ScoreboardTeamName" ), pAllChars );
  244. vgui::surface()->PrecacheFontCharacters( pScheme->GetFont( "ScoreboardMedium" ), pAllChars );
  245. vgui::surface()->PrecacheFontCharacters( pScheme->GetFont( "ScoreboardSmall" ), pAllChars );
  246. vgui::surface()->PrecacheFontCharacters( pScheme->GetFont( "ScoreboardVerySmall" ), pAllChars );
  247. vgui::surface()->PrecacheFontCharacters( pScheme->GetFont( "TFFontMedium" ), pAllChars );
  248. vgui::surface()->PrecacheFontCharacters( pScheme->GetFont( "TFFontSmall" ), pAllChars );
  249. vgui::surface()->PrecacheFontCharacters( pScheme->GetFont( "HudFontMedium" ), pAllChars );
  250. vgui::surface()->PrecacheFontCharacters( pScheme->GetFont( "HudFontMediumSmallSecondary" ), pAllChars );
  251. vgui::surface()->PrecacheFontCharacters( pScheme->GetFont( "HudFontSmall" ), pAllChars );
  252. vgui::surface()->PrecacheFontCharacters( pScheme->GetFont( "DefaultSmall" ), pAllChars );
  253. vgui::surface()->PrecacheFontCharacters( pScheme->GetFont( "ScoreboardTeamScore" ), pNumbers );
  254. }
  255. }
  256. //
  257. // This is the main function of the viewport. Right here is where we create our class menu,
  258. // team menu, and anything else that we want to turn on and off in the UI.
  259. //
  260. IViewPortPanel* TFViewport::CreatePanelByName(const char *szPanelName)
  261. {
  262. IViewPortPanel* newpanel = NULL;
  263. // overwrite MOD specific panel creation
  264. if ( Q_strcmp( PANEL_SCOREBOARD, szPanelName ) == 0 )
  265. {
  266. newpanel = new CTFClientScoreBoardDialog( this );
  267. }
  268. else if ( Q_strcmp( PANEL_SPECGUI, szPanelName ) == 0 )
  269. {
  270. newpanel = new CTFSpectatorGUI( this );
  271. }
  272. else if ( Q_strcmp( PANEL_SPECMENU, szPanelName ) == 0 )
  273. {
  274. // newpanel = new CTFSpectatorGUI( this );
  275. }
  276. else if ( Q_strcmp( PANEL_OVERVIEW, szPanelName ) == 0 )
  277. {
  278. // newpanel = new CTFMapOverview( this );
  279. }
  280. else if ( Q_strcmp( PANEL_INFO, szPanelName ) == 0 )
  281. {
  282. newpanel = new CTFTextWindow( this );
  283. }
  284. else if ( Q_strcmp( PANEL_MAPINFO, szPanelName ) == 0 )
  285. {
  286. newpanel = new CTFMapInfoMenu( this );
  287. }
  288. else if ( Q_strcmp( PANEL_ROUNDINFO, szPanelName ) == 0 )
  289. {
  290. newpanel = new CTFRoundInfo( this );
  291. }
  292. else if ( Q_strcmp( PANEL_TEAM, szPanelName ) == 0 )
  293. {
  294. newpanel = new CTFTeamMenu( this );
  295. }
  296. else if ( Q_strcmp( PANEL_CLASS_RED, szPanelName ) == 0 )
  297. {
  298. newpanel = new CTFClassMenu_Red( this );
  299. }
  300. else if ( Q_strcmp( PANEL_CLASS_BLUE, szPanelName ) == 0 )
  301. {
  302. newpanel = new CTFClassMenu_Blue( this );
  303. }
  304. else if ( Q_strcmp( PANEL_INTRO, szPanelName ) == 0 )
  305. {
  306. newpanel = new CTFIntroMenu( this );
  307. }
  308. else if ( Q_strcmp( PANEL_ARENA_TEAM, szPanelName ) == 0 )
  309. {
  310. newpanel = new CTFArenaTeamMenu( this );
  311. }
  312. else if ( Q_strcmp( PANEL_ARENA_WIN, szPanelName ) == 0 )
  313. {
  314. newpanel = new CTFArenaWinPanel( this );
  315. }
  316. else if ( Q_strcmp( PANEL_PVE_WIN, szPanelName ) == 0 )
  317. {
  318. newpanel = new CTFPVEWinPanel( this );
  319. }
  320. else if ( Q_strcmp( PANEL_GIVEAWAY_ITEM, szPanelName ) == 0 )
  321. {
  322. newpanel = new CTFGiveawayItemPanel( this );
  323. }
  324. else if ( Q_strcmp( PANEL_MAINMENUOVERRIDE, szPanelName ) == 0 )
  325. {
  326. newpanel = new CHudMainMenuOverride( this );
  327. }
  328. else if ( V_strcmp( PANEL_QUEST_LOG, szPanelName ) == 0 )
  329. {
  330. newpanel = new CQuestLogPanel( this );
  331. }
  332. else
  333. {
  334. // create a generic base panel, don't add twice
  335. newpanel = BaseClass::CreatePanelByName( szPanelName );
  336. }
  337. return newpanel;
  338. }
  339. void TFViewport::CreateDefaultPanels( void )
  340. {
  341. AddNewPanel( CreatePanelByName( PANEL_MAPINFO ), "PANEL_MAPINFO" );
  342. AddNewPanel( CreatePanelByName( PANEL_TEAM ), "PANEL_TEAM" );
  343. AddNewPanel( CreatePanelByName( PANEL_CLASS_RED ), "PANEL_CLASS_RED" );
  344. AddNewPanel( CreatePanelByName( PANEL_CLASS_BLUE ), "PANEL_CLASS_BLUE" );
  345. AddNewPanel( CreatePanelByName( PANEL_INTRO ), "PANEL_INTRO" );
  346. AddNewPanel( CreatePanelByName( PANEL_ROUNDINFO ), "PANEL_ROUNDINFO" );
  347. AddNewPanel( CreatePanelByName( PANEL_ARENA_WIN ), "PANEL_ARENA_WIN" );
  348. AddNewPanel( CreatePanelByName( PANEL_ARENA_TEAM ), "PANEL_ARENA_TEAM" );
  349. AddNewPanel( CreatePanelByName( PANEL_PVE_WIN ), "PANEL_PVE_WIN" );
  350. AddNewPanel( CreatePanelByName( PANEL_GIVEAWAY_ITEM ), "PANEL_GIVEAWAY_ITEM" );
  351. AddNewPanel( CreatePanelByName( PANEL_QUEST_LOG ), "PANEL_QUEST_LOG" );
  352. CHudMainMenuOverride *pMMOverride = (CHudMainMenuOverride*)CreatePanelByName( PANEL_MAINMENUOVERRIDE );
  353. if ( pMMOverride )
  354. {
  355. AddNewPanel( pMMOverride, "PANEL_MAINMENUOVERRIDE" );
  356. pMMOverride->AttachToGameUI();
  357. }
  358. BaseClass::CreateDefaultPanels();
  359. }
  360. int TFViewport::GetDeathMessageStartHeight( void )
  361. {
  362. int y = YRES(2);
  363. if ( IsX360() )
  364. {
  365. y = YRES(36);
  366. }
  367. if ( g_pSpectatorGUI && g_pSpectatorGUI->IsVisible() )
  368. {
  369. y = YRES(2) + g_pSpectatorGUI->GetTopBarHeight();
  370. }
  371. return y;
  372. }
  373. //-----------------------------------------------------------------------------
  374. // Purpose:
  375. //-----------------------------------------------------------------------------
  376. void TFViewport::OnScreenSizeChanged( int iOldWide, int iOldTall )
  377. {
  378. BaseClass::OnScreenSizeChanged( iOldWide, iOldTall );
  379. // we've changed resolution, let's try to figure out if we need to show any of our menus
  380. if ( !gViewPortInterface )
  381. return;
  382. C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer();
  383. if ( pPlayer )
  384. {
  385. // are we on a team yet?
  386. if ( pPlayer->GetTeamNumber() == TEAM_UNASSIGNED )
  387. {
  388. engine->ClientCmd( "show_motd" );
  389. }
  390. else if ( ( pPlayer->GetTeamNumber() != TEAM_SPECTATOR ) && ( pPlayer->m_Shared.GetDesiredPlayerClassIndex() == TF_CLASS_UNDEFINED ) )
  391. {
  392. if ( tf_arena_force_class.GetBool() == false )
  393. {
  394. switch( pPlayer->GetTeamNumber() )
  395. {
  396. case TF_TEAM_RED:
  397. gViewPortInterface->ShowPanel( PANEL_CLASS_RED, true );
  398. break;
  399. case TF_TEAM_BLUE:
  400. gViewPortInterface->ShowPanel( PANEL_CLASS_BLUE, true );
  401. break;
  402. }
  403. }
  404. }
  405. }
  406. }
  407. //-----------------------------------------------------------------------------
  408. // Purpose:
  409. //-----------------------------------------------------------------------------
  410. void TFViewport::OnTick()
  411. {
  412. m_pAnimController->UpdateAnimations( gpGlobals->curtime );
  413. }