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.

425 lines
12 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "cbase.h"
  8. #include <vgui_controls/Label.h>
  9. #include <vgui_controls/Button.h>
  10. #include <vgui_controls/ImagePanel.h>
  11. #include <vgui_controls/RichText.h>
  12. #include <vgui_controls/Frame.h>
  13. #include <vgui/IScheme.h>
  14. #include <game/client/iviewport.h>
  15. #include <vgui/IVGui.h>
  16. #include <KeyValues.h>
  17. #include <filesystem.h>
  18. #include "vguicenterprint.h"
  19. #include "tf_controls.h"
  20. #include "basemodelpanel.h"
  21. #include "tf_arenateammenu.h"
  22. #include <convar.h>
  23. #include "IGameUIFuncs.h" // for key bindings
  24. #include "hud.h" // for gEngfuncs
  25. #include "c_tf_player.h"
  26. #include "tf_gamerules.h"
  27. #include "c_team.h"
  28. #include "tf_hud_notification_panel.h"
  29. #include "inputsystem/iinputsystem.h"
  30. using namespace vgui;
  31. //-----------------------------------------------------------------------------
  32. // Purpose: Constructor
  33. //-----------------------------------------------------------------------------
  34. CTFArenaTeamMenu::CTFArenaTeamMenu( IViewPort *pViewPort ) : CTeamMenu( pViewPort )
  35. {
  36. SetMinimizeButtonVisible( false );
  37. SetMaximizeButtonVisible( false );
  38. SetCloseButtonVisible( false );
  39. SetVisible( false );
  40. SetKeyBoardInputEnabled( true );
  41. m_iTeamMenuKey = BUTTON_CODE_INVALID;
  42. m_pAutoTeamButton = new CTFTeamButton( this, "teambutton2" );
  43. m_pSpecTeamButton = new CTFTeamButton( this, "teambutton3" );
  44. m_pSpecLabel = new CExLabel( this, "TeamMenuSpectate", "" );
  45. #ifdef _X360
  46. m_pFooter = new CTFFooter( this, "Footer" );
  47. #else
  48. m_pCancelButton = new CExButton( this, "CancelButton", "#TF_Cancel" );
  49. m_pJoinAutoHintIcon = m_pJoinSpectatorsHintIcon = m_pCancelHintIcon = nullptr;
  50. #endif
  51. vgui::ivgui()->AddTickSignal( GetVPanel() );
  52. m_bRedDisabled = false;
  53. m_bBlueDisabled = false;
  54. if ( ::input->IsSteamControllerActive() )
  55. {
  56. LoadControlSettings( "Resource/UI/HudArenaTeamMenu_SC.res" );
  57. }
  58. else
  59. {
  60. LoadControlSettings( "Resource/UI/HudArenaTeamMenu.res" );
  61. }
  62. }
  63. //-----------------------------------------------------------------------------
  64. // Purpose: Destructor
  65. //-----------------------------------------------------------------------------
  66. CTFArenaTeamMenu::~CTFArenaTeamMenu()
  67. {
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Purpose: Destructor
  71. //-----------------------------------------------------------------------------
  72. void CTFArenaTeamMenu::ApplySchemeSettings( IScheme *pScheme )
  73. {
  74. BaseClass::ApplySchemeSettings( pScheme );
  75. if ( ::input->IsSteamControllerActive() )
  76. {
  77. LoadControlSettings( "Resource/UI/HudArenaTeamMenu_SC.res" );
  78. m_pCancelHintIcon = dynamic_cast< CSCHintIcon* >( FindChildByName( "CancelHintIcon" ) );
  79. m_pJoinAutoHintIcon = dynamic_cast< CSCHintIcon* >( FindChildByName( "JoinAutoHintIcon" ) );
  80. m_pJoinSpectatorsHintIcon = dynamic_cast< CSCHintIcon* >( FindChildByName( "JoinSpectatorsHintIcon" ) );
  81. SetMouseInputEnabled( false );
  82. }
  83. else
  84. {
  85. LoadControlSettings( "Resource/UI/HudArenaTeamMenu.res" );
  86. SetMouseInputEnabled( true );
  87. m_pCancelHintIcon = m_pJoinAutoHintIcon = m_pJoinSpectatorsHintIcon = nullptr;
  88. }
  89. Update();
  90. }
  91. //-----------------------------------------------------------------------------
  92. // Purpose:
  93. //-----------------------------------------------------------------------------
  94. void CTFArenaTeamMenu::ShowPanel( bool bShow )
  95. {
  96. if ( BaseClass::IsVisible() == bShow )
  97. return;
  98. if ( !gameuifuncs || !gViewPortInterface || !engine )
  99. return;
  100. if ( bShow )
  101. {
  102. if ( !C_TFPlayer::GetLocalTFPlayer() )
  103. return;
  104. if ( TFGameRules()->State_Get() == GR_STATE_TEAM_WIN &&
  105. C_TFPlayer::GetLocalTFPlayer() &&
  106. C_TFPlayer::GetLocalTFPlayer()->GetTeamNumber() != TFGameRules()->GetWinningTeam()
  107. && C_TFPlayer::GetLocalTFPlayer()->GetTeamNumber() != TEAM_SPECTATOR
  108. && C_TFPlayer::GetLocalTFPlayer()->GetTeamNumber() != TEAM_UNASSIGNED )
  109. {
  110. SetVisible( false );
  111. CHudNotificationPanel *pNotifyPanel = GET_HUDELEMENT( CHudNotificationPanel );
  112. if ( pNotifyPanel )
  113. {
  114. pNotifyPanel->SetupNotifyCustom( "#TF_CantChangeTeamNow", "ico_notify_flag_moving", C_TFPlayer::GetLocalTFPlayer()->GetTeamNumber() );
  115. }
  116. return;
  117. }
  118. gViewPortInterface->ShowPanel( PANEL_CLASS_RED, false );
  119. gViewPortInterface->ShowPanel( PANEL_CLASS_BLUE, false );
  120. engine->CheckPoint( "TeamMenu" );
  121. InvalidateLayout( true, true );
  122. Activate();
  123. // get key bindings if shown
  124. m_iTeamMenuKey = gameuifuncs->GetButtonCodeForBind( "changeteam" );
  125. m_iScoreBoardKey = gameuifuncs->GetButtonCodeForBind( "showscores" );
  126. GetFocusNavGroup().SetCurrentFocus( m_pAutoTeamButton->GetVPanel(), m_pAutoTeamButton->GetVPanel() );
  127. ActivateSelectIconHint( GetFocusNavGroup().GetCurrentFocus() ? GetFocusNavGroup().GetCurrentFocus()->GetTabPosition() : -1 );
  128. }
  129. else
  130. {
  131. SetVisible( false );
  132. if ( IsConsole() )
  133. {
  134. // Close the door behind us
  135. CTFArenaTeamMenu *pButton = dynamic_cast< CTFArenaTeamMenu *> ( GetFocusNavGroup().GetCurrentFocus() );
  136. if ( pButton )
  137. {
  138. pButton->OnCursorExited();
  139. }
  140. }
  141. }
  142. }
  143. //-----------------------------------------------------------------------------
  144. // Purpose: Activate the right selection hint icon, depending on the focus group number selected
  145. //-----------------------------------------------------------------------------
  146. void CTFArenaTeamMenu::ActivateSelectIconHint( int focus_group_number )
  147. {
  148. if ( m_pJoinAutoHintIcon ) m_pJoinAutoHintIcon->SetVisible( false );
  149. if ( m_pJoinSpectatorsHintIcon ) m_pJoinSpectatorsHintIcon->SetVisible( false );
  150. CSCHintIcon* icon = nullptr;
  151. switch ( focus_group_number )
  152. {
  153. case 1: icon = m_pJoinAutoHintIcon; break;
  154. case 2: icon = m_pJoinSpectatorsHintIcon; break;
  155. }
  156. if ( icon )
  157. {
  158. icon->SetVisible( true );
  159. }
  160. }
  161. //-----------------------------------------------------------------------------
  162. // Purpose: called to update the menu with new information
  163. //-----------------------------------------------------------------------------
  164. void CTFArenaTeamMenu::Update( void )
  165. {
  166. BaseClass::Update();
  167. C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  168. if ( pLocalPlayer && ( pLocalPlayer->GetTeamNumber() != TEAM_UNASSIGNED ) )
  169. {
  170. #ifdef _X360
  171. if ( m_pFooter )
  172. {
  173. m_pFooter->ShowButtonLabel( "cancel", true );
  174. }
  175. #else
  176. if ( m_pCancelButton )
  177. {
  178. m_pCancelButton->SetVisible( true );
  179. if ( m_pCancelHintIcon )
  180. {
  181. m_pCancelHintIcon->SetVisible( true );
  182. }
  183. }
  184. #endif
  185. }
  186. else
  187. {
  188. #ifdef _X360
  189. if ( m_pFooter )
  190. {
  191. m_pFooter->ShowButtonLabel( "cancel", false );
  192. }
  193. #else
  194. if ( m_pCancelButton && m_pCancelButton->IsVisible() )
  195. {
  196. m_pCancelButton->SetVisible( false );
  197. if ( m_pCancelHintIcon )
  198. {
  199. m_pCancelHintIcon->SetVisible( false );
  200. }
  201. }
  202. #endif
  203. }
  204. }
  205. #ifdef _X360
  206. //-----------------------------------------------------------------------------
  207. // Purpose:
  208. //-----------------------------------------------------------------------------
  209. void CTFArenaTeamMenu::Join_Team( const CCommand &args )
  210. {
  211. if ( args.ArgC() > 1 )
  212. {
  213. char cmd[256];
  214. Q_snprintf( cmd, sizeof( cmd ), "jointeam_nomenus %s", args.Arg( 1 ) );
  215. OnCommand( cmd );
  216. }
  217. }
  218. #endif
  219. //-----------------------------------------------------------------------------
  220. // Purpose: chooses and loads the text page to display that describes mapName map
  221. //-----------------------------------------------------------------------------
  222. void CTFArenaTeamMenu::LoadMapPage( const char *mapName )
  223. {
  224. }
  225. //-----------------------------------------------------------------------------
  226. // Purpose:
  227. //-----------------------------------------------------------------------------
  228. void CTFArenaTeamMenu::OnKeyCodePressed( KeyCode code )
  229. {
  230. if ( ( m_iTeamMenuKey != BUTTON_CODE_INVALID && m_iTeamMenuKey == code ) ||
  231. code == KEY_XBUTTON_BACK ||
  232. code == KEY_XBUTTON_B ||
  233. code == STEAMCONTROLLER_B )
  234. {
  235. C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  236. if ( pLocalPlayer && ( pLocalPlayer->GetTeamNumber() != TEAM_UNASSIGNED ) )
  237. {
  238. ShowPanel( false );
  239. }
  240. }
  241. else if( code == KEY_SPACE || code == STEAMCONTROLLER_Y )
  242. {
  243. engine->ClientCmd( "jointeam auto" );
  244. ShowPanel( false );
  245. OnClose();
  246. }
  247. else if( code == KEY_XBUTTON_A || code == KEY_XBUTTON_RTRIGGER || code == STEAMCONTROLLER_A )
  248. {
  249. // select the active focus
  250. if ( GetFocusNavGroup().GetCurrentFocus() )
  251. {
  252. ipanel()->SendMessage( GetFocusNavGroup().GetCurrentFocus()->GetVPanel(), new KeyValues( "PressButton" ), GetVPanel() );
  253. }
  254. }
  255. else if( code == KEY_XBUTTON_RIGHT || code == KEY_XSTICK1_RIGHT || code == STEAMCONTROLLER_DPAD_RIGHT )
  256. {
  257. CTFTeamButton *pButton;
  258. pButton = dynamic_cast< CTFTeamButton *> ( GetFocusNavGroup().GetCurrentFocus() );
  259. if ( pButton )
  260. {
  261. pButton->OnCursorExited();
  262. GetFocusNavGroup().RequestFocusNext( pButton->GetVPanel() );
  263. }
  264. else
  265. {
  266. GetFocusNavGroup().RequestFocusNext( NULL );
  267. }
  268. pButton = dynamic_cast< CTFTeamButton * > ( GetFocusNavGroup().GetCurrentFocus() );
  269. if ( pButton )
  270. {
  271. pButton->OnCursorEntered();
  272. }
  273. ActivateSelectIconHint( GetFocusNavGroup().GetCurrentFocus() ? GetFocusNavGroup().GetCurrentFocus()->GetTabPosition() : -1 );
  274. }
  275. else if( code == KEY_XBUTTON_LEFT || code == KEY_XSTICK1_LEFT || code == STEAMCONTROLLER_DPAD_LEFT )
  276. {
  277. CTFTeamButton *pButton;
  278. pButton = dynamic_cast< CTFTeamButton *> ( GetFocusNavGroup().GetCurrentFocus() );
  279. if ( pButton )
  280. {
  281. pButton->OnCursorExited();
  282. GetFocusNavGroup().RequestFocusPrev( pButton->GetVPanel() );
  283. }
  284. else
  285. {
  286. GetFocusNavGroup().RequestFocusPrev( NULL );
  287. }
  288. pButton = dynamic_cast< CTFTeamButton * > ( GetFocusNavGroup().GetCurrentFocus() );
  289. if ( pButton )
  290. {
  291. pButton->OnCursorEntered();
  292. }
  293. ActivateSelectIconHint( GetFocusNavGroup().GetCurrentFocus() ? GetFocusNavGroup().GetCurrentFocus()->GetTabPosition() : -1 );
  294. }
  295. else if ( m_iScoreBoardKey != BUTTON_CODE_INVALID && m_iScoreBoardKey == code )
  296. {
  297. gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, true );
  298. gViewPortInterface->PostMessageToPanel( PANEL_SCOREBOARD, new KeyValues( "PollHideCode", "code", code ) );
  299. }
  300. else
  301. {
  302. BaseClass::OnKeyCodePressed( code );
  303. }
  304. }
  305. //-----------------------------------------------------------------------------
  306. // Purpose: Called when the user picks a team
  307. //-----------------------------------------------------------------------------
  308. void CTFArenaTeamMenu::OnCommand( const char *command )
  309. {
  310. C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  311. if ( Q_stricmp( command, "vguicancel" ) )
  312. {
  313. // we're selecting a team, so make sure it's not the team we're already on before sending to the server
  314. if ( pLocalPlayer && ( Q_strstr( command, "jointeam " ) ) )
  315. {
  316. engine->ClientCmd( command );
  317. }
  318. else if ( pLocalPlayer && ( Q_strstr( command, "jointeam_nomenus " ) ) )
  319. {
  320. engine->ClientCmd( command );
  321. }
  322. }
  323. BaseClass::OnCommand( command );
  324. ShowPanel( false );
  325. OnClose();
  326. }
  327. //-----------------------------------------------------------------------------
  328. // Frame-based update
  329. //-----------------------------------------------------------------------------
  330. void CTFArenaTeamMenu::OnTick()
  331. {
  332. // update the number of players on each team
  333. // enable or disable buttons based on team limit
  334. C_Team *pRed = GetGlobalTeam( TF_TEAM_RED );
  335. C_Team *pBlue = GetGlobalTeam( TF_TEAM_BLUE );
  336. if ( !pRed || !pBlue )
  337. return;
  338. C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
  339. if ( !pLocalPlayer )
  340. return;
  341. CTFGameRules *pRules = TFGameRules();
  342. if ( !pRules )
  343. return;
  344. if ( m_pSpecTeamButton && m_pSpecLabel )
  345. {
  346. {
  347. if ( mp_allowspectators.GetBool() )
  348. {
  349. if ( !m_pSpecTeamButton->IsVisible() )
  350. {
  351. m_pSpecTeamButton->SetVisible( true );
  352. m_pSpecLabel->SetVisible( true );
  353. }
  354. }
  355. else
  356. {
  357. if ( m_pSpecTeamButton->IsVisible() )
  358. {
  359. m_pSpecTeamButton->SetVisible( false );
  360. m_pSpecLabel->SetVisible( false );
  361. }
  362. }
  363. }
  364. }
  365. }