2010-11-20 10:37:14 +00:00
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
2010-05-29 07:25:38 +00:00
# include <base/math.h>
2022-05-18 16:00:05 +00:00
# include <base/system.h>
2008-09-29 11:34:49 +00:00
2010-08-09 12:14:15 +00:00
# include <engine/demo.h>
2022-05-23 18:16:18 +00:00
# include <engine/favorites.h>
2011-03-23 12:06:35 +00:00
# include <engine/friends.h>
2017-09-09 15:04:19 +00:00
# include <engine/ghost.h>
2011-04-06 18:18:31 +00:00
# include <engine/graphics.h>
2010-05-29 07:25:38 +00:00
# include <engine/serverbrowser.h>
# include <engine/shared/config.h>
2020-09-26 19:41:58 +00:00
# include <engine/textrender.h>
2008-09-29 11:34:49 +00:00
2010-05-29 07:25:38 +00:00
# include <game/generated/client_data.h>
2020-09-26 19:41:58 +00:00
# include <game/generated/protocol.h>
2008-09-29 11:34:49 +00:00
2011-03-22 21:41:27 +00:00
# include <game/client/animstate.h>
2020-09-26 19:41:58 +00:00
# include <game/client/components/countryflags.h>
2011-03-22 21:41:27 +00:00
# include <game/client/gameclient.h>
# include <game/client/render.h>
# include <game/client/ui.h>
2022-08-15 21:19:56 +00:00
# include <game/client/ui_scrollregion.h>
2020-09-26 19:41:58 +00:00
# include <game/localization.h>
2008-09-29 11:34:49 +00:00
2010-05-29 07:25:38 +00:00
# include "menus.h"
# include "motd.h"
# include "voting.h"
2008-09-29 11:34:49 +00:00
2020-09-26 19:41:58 +00:00
# include "ghost.h"
2011-02-04 17:25:04 +00:00
# include <engine/keys.h>
# include <engine/storage.h>
2008-09-29 11:34:49 +00:00
2022-05-18 16:00:05 +00:00
# include <chrono>
using namespace std : : chrono_literals ;
2010-05-29 07:25:38 +00:00
void CMenus : : RenderGame ( CUIRect MainView )
2008-09-29 11:34:49 +00:00
{
2020-09-03 10:08:00 +00:00
CUIRect Button , ButtonBar , ButtonBar2 ;
2011-04-06 18:18:31 +00:00
MainView . HSplitTop ( 45.0f , & ButtonBar , & MainView ) ;
2022-08-07 16:12:07 +00:00
ButtonBar . Draw ( ms_ColorTabbarActive , IGraphics : : CORNER_B , 10.0f ) ;
2011-04-13 18:37:12 +00:00
2011-03-22 21:41:27 +00:00
// button bar
ButtonBar . HSplitTop ( 10.0f , 0 , & ButtonBar ) ;
ButtonBar . HSplitTop ( 25.0f , & ButtonBar , 0 ) ;
ButtonBar . VMargin ( 10.0f , & ButtonBar ) ;
2011-04-13 18:37:12 +00:00
2020-09-03 10:08:00 +00:00
ButtonBar . HSplitTop ( 30.0f , 0 , & ButtonBar2 ) ;
ButtonBar2 . HSplitTop ( 25.0f , & ButtonBar2 , 0 ) ;
2011-03-22 21:41:27 +00:00
ButtonBar . VSplitRight ( 120.0f , & ButtonBar , & Button ) ;
2020-09-03 10:08:00 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_DisconnectButton ;
2010-05-29 07:25:38 +00:00
if ( DoButton_Menu ( & s_DisconnectButton , Localize ( " Disconnect " ) , 0 , & Button ) )
2014-07-08 18:21:19 +00:00
{
2019-03-29 13:56:02 +00:00
if ( Client ( ) - > GetCurrentRaceTime ( ) / 60 > = g_Config . m_ClConfirmDisconnectTime & & g_Config . m_ClConfirmDisconnectTime > = 0 )
2019-03-25 19:02:50 +00:00
{
2022-11-30 22:06:44 +00:00
PopupConfirm ( Localize ( " Disconnect " ) , Localize ( " Are you sure that you want to disconnect? " ) , Localize ( " Yes " ) , Localize ( " No " ) , & CMenus : : PopupConfirmDisconnect ) ;
2019-03-25 19:02:50 +00:00
}
2014-07-10 14:50:59 +00:00
else
2019-03-25 19:02:50 +00:00
{
2014-07-10 14:50:59 +00:00
Client ( ) - > Disconnect ( ) ;
2022-09-23 17:59:18 +00:00
RefreshBrowserTab ( g_Config . m_UiPage ) ;
2019-03-25 19:02:50 +00:00
}
2014-07-08 18:21:19 +00:00
}
2008-09-29 11:34:49 +00:00
2020-09-03 10:08:00 +00:00
ButtonBar . VSplitRight ( 5.0f , & ButtonBar , 0 ) ;
ButtonBar . VSplitRight ( 170.0f , & ButtonBar , & Button ) ;
bool DummyConnecting = Client ( ) - > DummyConnecting ( ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_DummyButton ;
2021-11-17 19:35:39 +00:00
if ( ! Client ( ) - > DummyAllowed ( ) )
{
2022-07-26 19:17:29 +00:00
DoButton_Menu ( & s_DummyButton , Localize ( " Connect Dummy " ) , 1 , & Button , nullptr , IGraphics : : CORNER_ALL , 5.0f , 0.0f , vec4 ( 1.0f , 0.5f , 0.5f , 0.75f ) , vec4 ( 1 , 0.5f , 0.5f , 0.5f ) ) ;
2021-11-17 19:35:39 +00:00
}
else if ( DummyConnecting )
2020-09-03 10:08:00 +00:00
{
DoButton_Menu ( & s_DummyButton , Localize ( " Connecting dummy " ) , 1 , & Button ) ;
}
else if ( DoButton_Menu ( & s_DummyButton , Client ( ) - > DummyConnected ( ) ? Localize ( " Disconnect Dummy " ) : Localize ( " Connect Dummy " ) , 0 , & Button ) )
{
if ( ! Client ( ) - > DummyConnected ( ) )
{
Client ( ) - > DummyConnect ( ) ;
}
else
{
if ( Client ( ) - > GetCurrentRaceTime ( ) / 60 > = g_Config . m_ClConfirmDisconnectTime & & g_Config . m_ClConfirmDisconnectTime > = 0 )
{
2022-11-30 22:06:44 +00:00
PopupConfirm ( Localize ( " Disconnect Dummy " ) , Localize ( " Are you sure that you want to disconnect your dummy? " ) , Localize ( " Yes " ) , Localize ( " No " ) , & CMenus : : PopupConfirmDisconnectDummy ) ;
2020-09-03 10:08:00 +00:00
}
else
{
Client ( ) - > DummyDisconnect ( 0 ) ;
2020-09-05 15:13:32 +00:00
SetActive ( false ) ;
2020-09-03 10:08:00 +00:00
}
}
}
ButtonBar . VSplitRight ( 5.0f , & ButtonBar , 0 ) ;
ButtonBar . VSplitRight ( 140.0f , & ButtonBar , & Button ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_DemoButton ;
2020-09-03 10:08:00 +00:00
bool Recording = DemoRecorder ( RECORDER_MANUAL ) - > IsRecording ( ) ;
if ( DoButton_Menu ( & s_DemoButton , Recording ? Localize ( " Stop record " ) : Localize ( " Record demo " ) , 0 , & Button ) )
{
if ( ! Recording )
Client ( ) - > DemoRecorder_Start ( Client ( ) - > GetCurrentMap ( ) , true , RECORDER_MANUAL ) ;
else
Client ( ) - > DemoRecorder_Stop ( RECORDER_MANUAL ) ;
}
2022-07-16 13:32:06 +00:00
static CButtonContainer s_SpectateButton ;
static CButtonContainer s_JoinRedButton ;
static CButtonContainer s_JoinBlueButton ;
2015-04-19 12:24:20 +00:00
2020-10-10 10:43:05 +00:00
bool Paused = false ;
bool Spec = false ;
if ( m_pClient - > m_Snap . m_LocalClientID > = 0 )
{
Paused = m_pClient - > m_aClients [ m_pClient - > m_Snap . m_LocalClientID ] . m_Paused ;
Spec = m_pClient - > m_aClients [ m_pClient - > m_Snap . m_LocalClientID ] . m_Spec ;
}
2020-09-03 10:08:00 +00:00
if ( m_pClient - > m_Snap . m_pLocalInfo & & m_pClient - > m_Snap . m_pGameInfoObj & & ! Paused & & ! Spec )
2008-09-29 11:34:49 +00:00
{
2011-01-03 11:50:38 +00:00
if ( m_pClient - > m_Snap . m_pLocalInfo - > m_Team ! = TEAM_SPECTATORS )
2008-09-29 11:34:49 +00:00
{
2014-05-03 22:11:11 +00:00
ButtonBar . VSplitLeft ( 5.0f , 0 , & ButtonBar ) ;
2011-03-22 21:41:27 +00:00
ButtonBar . VSplitLeft ( 120.0f , & Button , & ButtonBar ) ;
2015-04-19 12:40:05 +00:00
if ( ! DummyConnecting & & DoButton_Menu ( & s_SpectateButton , Localize ( " Spectate " ) , 0 , & Button ) )
2008-09-29 11:34:49 +00:00
{
2020-09-03 10:08:00 +00:00
if ( g_Config . m_ClDummy = = 0 | | Client ( ) - > DummyConnected ( ) )
2014-07-08 00:00:13 +00:00
{
m_pClient - > SendSwitchTeam ( TEAM_SPECTATORS ) ;
SetActive ( false ) ;
}
2008-09-29 11:34:49 +00:00
}
}
2011-04-13 18:37:12 +00:00
2011-03-04 16:08:10 +00:00
if ( m_pClient - > m_Snap . m_pGameInfoObj - > m_GameFlags & GAMEFLAG_TEAMS )
2008-09-29 11:34:49 +00:00
{
2011-01-03 11:50:38 +00:00
if ( m_pClient - > m_Snap . m_pLocalInfo - > m_Team ! = TEAM_RED )
2008-09-29 11:34:49 +00:00
{
2014-05-03 22:11:11 +00:00
ButtonBar . VSplitLeft ( 5.0f , 0 , & ButtonBar ) ;
2011-03-22 21:41:27 +00:00
ButtonBar . VSplitLeft ( 120.0f , & Button , & ButtonBar ) ;
2015-05-28 21:11:01 +00:00
if ( ! DummyConnecting & & DoButton_Menu ( & s_JoinRedButton , Localize ( " Join red " ) , 0 , & Button ) )
2008-09-29 11:34:49 +00:00
{
2011-01-03 11:50:38 +00:00
m_pClient - > SendSwitchTeam ( TEAM_RED ) ;
2010-05-29 07:25:38 +00:00
SetActive ( false ) ;
2008-09-29 11:34:49 +00:00
}
}
2011-01-03 11:50:38 +00:00
if ( m_pClient - > m_Snap . m_pLocalInfo - > m_Team ! = TEAM_BLUE )
2008-09-29 11:34:49 +00:00
{
2014-05-03 22:11:11 +00:00
ButtonBar . VSplitLeft ( 5.0f , 0 , & ButtonBar ) ;
2011-03-22 21:41:27 +00:00
ButtonBar . VSplitLeft ( 120.0f , & Button , & ButtonBar ) ;
2015-05-28 21:11:01 +00:00
if ( ! DummyConnecting & & DoButton_Menu ( & s_JoinBlueButton , Localize ( " Join blue " ) , 0 , & Button ) )
2008-09-29 11:34:49 +00:00
{
2011-01-03 11:50:38 +00:00
m_pClient - > SendSwitchTeam ( TEAM_BLUE ) ;
2010-05-29 07:25:38 +00:00
SetActive ( false ) ;
2008-09-29 11:34:49 +00:00
}
}
}
else
{
2010-05-29 07:25:38 +00:00
if ( m_pClient - > m_Snap . m_pLocalInfo - > m_Team ! = 0 )
2008-09-29 11:34:49 +00:00
{
2014-05-03 22:11:11 +00:00
ButtonBar . VSplitLeft ( 5.0f , 0 , & ButtonBar ) ;
2011-03-22 21:41:27 +00:00
ButtonBar . VSplitLeft ( 120.0f , & Button , & ButtonBar ) ;
2015-04-19 12:40:05 +00:00
if ( ! DummyConnecting & & DoButton_Menu ( & s_SpectateButton , Localize ( " Join game " ) , 0 , & Button ) )
2008-09-29 11:34:49 +00:00
{
2010-05-29 07:25:38 +00:00
m_pClient - > SendSwitchTeam ( 0 ) ;
SetActive ( false ) ;
2008-09-29 11:34:49 +00:00
}
}
}
2010-08-09 12:14:15 +00:00
2020-09-03 10:08:00 +00:00
if ( m_pClient - > m_Snap . m_pLocalInfo - > m_Team ! = TEAM_SPECTATORS )
{
ButtonBar . VSplitLeft ( 5.0f , 0 , & ButtonBar ) ;
ButtonBar . VSplitLeft ( 65.0f , & Button , & ButtonBar ) ;
2014-04-26 18:29:42 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_KillButton ;
2020-09-03 10:08:00 +00:00
if ( DoButton_Menu ( & s_KillButton , Localize ( " Kill " ) , 0 , & Button ) )
{
m_pClient - > SendKill ( - 1 ) ;
SetActive ( false ) ;
}
}
2015-04-19 12:40:05 +00:00
}
2020-09-03 10:08:00 +00:00
2020-09-05 08:44:50 +00:00
if ( m_pClient - > m_ReceivedDDNetPlayer & & m_pClient - > m_Snap . m_pLocalInfo & & m_pClient - > m_Snap . m_pGameInfoObj )
2014-04-26 18:29:42 +00:00
{
2020-09-03 10:08:00 +00:00
if ( m_pClient - > m_Snap . m_pLocalInfo - > m_Team ! = TEAM_SPECTATORS | | Paused | | Spec )
2014-04-26 18:29:42 +00:00
{
2020-09-03 10:08:00 +00:00
ButtonBar . VSplitLeft ( 5.0f , 0 , & ButtonBar ) ;
ButtonBar . VSplitLeft ( ( ! Paused & & ! Spec ) ? 65.0f : 120.0f , & Button , & ButtonBar ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_PauseButton ;
2020-09-03 10:08:00 +00:00
if ( DoButton_Menu ( & s_PauseButton , ( ! Paused & & ! Spec ) ? Localize ( " Pause " ) : Localize ( " Join game " ) , 0 , & Button ) )
2019-03-25 19:02:50 +00:00
{
2020-09-03 10:08:00 +00:00
m_pClient - > Console ( ) - > ExecuteLine ( " say /pause " ) ;
SetActive ( false ) ;
2019-03-25 19:02:50 +00:00
}
2014-04-26 18:29:42 +00:00
}
}
2011-04-06 18:18:31 +00:00
}
2022-11-30 22:06:44 +00:00
void CMenus : : PopupConfirmDisconnect ( )
{
Client ( ) - > Disconnect ( ) ;
}
void CMenus : : PopupConfirmDisconnectDummy ( )
{
Client ( ) - > DummyDisconnect ( 0 ) ;
SetActive ( false ) ;
}
2011-04-06 18:18:31 +00:00
void CMenus : : RenderPlayers ( CUIRect MainView )
{
2014-02-19 13:49:08 +00:00
CUIRect Button , Button2 , ButtonBar , Options , Player ;
2022-08-07 16:12:07 +00:00
MainView . Draw ( ms_ColorTabbarActive , IGraphics : : CORNER_B , 10.0f ) ;
2011-03-22 21:41:27 +00:00
// player options
MainView . Margin ( 10.0f , & Options ) ;
2022-08-07 16:12:07 +00:00
Options . Draw ( ColorRGBA ( 1.0f , 1.0f , 1.0f , 0.25f ) , IGraphics : : CORNER_ALL , 10.0f ) ;
2011-03-22 21:41:27 +00:00
Options . Margin ( 10.0f , & Options ) ;
Options . HSplitTop ( 50.0f , & Button , & Options ) ;
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Button , Localize ( " Player options " ) , 34.0f , TEXTALIGN_LEFT ) ;
2011-03-22 21:41:27 +00:00
2011-04-06 18:18:31 +00:00
// headline
Options . HSplitTop ( 34.0f , & ButtonBar , & Options ) ;
2020-06-27 20:58:28 +00:00
ButtonBar . VSplitRight ( 231.0f , & Player , & ButtonBar ) ;
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Player , Localize ( " Player " ) , 24.0f , TEXTALIGN_LEFT ) ;
2011-04-06 18:18:31 +00:00
ButtonBar . HMargin ( 1.0f , & ButtonBar ) ;
2020-09-26 19:41:58 +00:00
float Width = ButtonBar . h * 2.0f ;
2011-04-06 18:18:31 +00:00
ButtonBar . VSplitLeft ( Width , & Button , & ButtonBar ) ;
2022-06-25 15:15:37 +00:00
RenderTools ( ) - > RenderIcon ( IMAGE_GUIICONS , SPRITE_GUIICON_MUTE , & Button ) ;
2011-04-06 18:18:31 +00:00
2020-06-27 20:39:54 +00:00
ButtonBar . VSplitLeft ( 20.0f , 0 , & ButtonBar ) ;
2020-06-26 22:06:07 +00:00
ButtonBar . VSplitLeft ( Width , & Button , & ButtonBar ) ;
2022-06-25 15:15:37 +00:00
RenderTools ( ) - > RenderIcon ( IMAGE_GUIICONS , SPRITE_GUIICON_EMOTICON_MUTE , & Button ) ;
2020-06-26 22:06:07 +00:00
2011-04-06 18:18:31 +00:00
ButtonBar . VSplitLeft ( 20.0f , 0 , & ButtonBar ) ;
ButtonBar . VSplitLeft ( Width , & Button , & ButtonBar ) ;
2022-06-25 15:15:37 +00:00
RenderTools ( ) - > RenderIcon ( IMAGE_GUIICONS , SPRITE_GUIICON_FRIEND , & Button ) ;
2011-04-06 18:18:31 +00:00
2013-12-31 21:14:59 +00:00
int TotalPlayers = 0 ;
2022-06-30 22:36:32 +00:00
for ( auto & pInfoByName : m_pClient - > m_Snap . m_apInfoByName )
2013-12-31 21:14:59 +00:00
{
2020-10-26 14:14:07 +00:00
if ( ! pInfoByName )
2013-12-31 21:14:59 +00:00
continue ;
2020-10-26 14:14:07 +00:00
int Index = pInfoByName - > m_ClientID ;
2013-12-31 21:14:59 +00:00
if ( Index = = m_pClient - > m_Snap . m_LocalClientID )
continue ;
TotalPlayers + + ;
}
static int s_VoteList = 0 ;
static float s_ScrollValue = 0 ;
CUIRect List = Options ;
2022-03-30 18:40:46 +00:00
// List.HSplitTop(28.0f, 0, &List);
2013-12-31 21:14:59 +00:00
UiDoListboxStart ( & s_VoteList , & List , 24.0f , " " , " " , TotalPlayers , 1 , - 1 , s_ScrollValue ) ;
2011-04-06 18:18:31 +00:00
// options
2020-06-26 22:06:07 +00:00
static int s_aPlayerIDs [ MAX_CLIENTS ] [ 3 ] = { { 0 } } ;
2013-12-31 21:14:59 +00:00
2011-04-06 18:18:31 +00:00
for ( int i = 0 , Count = 0 ; i < MAX_CLIENTS ; + + i )
2011-03-22 21:41:27 +00:00
{
2022-06-30 22:36:32 +00:00
if ( ! m_pClient - > m_Snap . m_apInfoByName [ i ] )
2011-08-04 21:43:39 +00:00
continue ;
2022-06-30 22:36:32 +00:00
int Index = m_pClient - > m_Snap . m_apInfoByName [ i ] - > m_ClientID ;
2013-12-31 21:14:59 +00:00
2011-08-04 21:43:39 +00:00
if ( Index = = m_pClient - > m_Snap . m_LocalClientID )
2011-03-22 21:41:27 +00:00
continue ;
2014-02-02 20:06:05 +00:00
CListboxItem Item = UiDoListboxNextItem ( & m_pClient - > m_aClients [ Index ] ) ;
2013-12-31 21:14:59 +00:00
Count + + ;
if ( ! Item . m_Visible )
continue ;
2020-09-26 19:41:58 +00:00
if ( Count % 2 = = 1 )
2022-08-07 16:12:07 +00:00
Item . m_Rect . Draw ( ColorRGBA ( 1.0f , 1.0f , 1.0f , 0.25f ) , IGraphics : : CORNER_ALL , 10.0f ) ;
2014-02-19 13:49:08 +00:00
Item . m_Rect . VSplitRight ( 300.0f , & Player , & Item . m_Rect ) ;
2011-03-22 21:41:27 +00:00
// player info
2011-03-28 19:10:37 +00:00
Player . VSplitLeft ( 28.0f , & Button , & Player ) ;
2021-04-09 18:11:53 +00:00
CTeeRenderInfo TeeInfo = m_pClient - > m_aClients [ Index ] . m_RenderInfo ;
TeeInfo . m_Size = Button . h ;
CAnimState * pIdleState = CAnimState : : GetIdle ( ) ;
vec2 OffsetToMid ;
RenderTools ( ) - > GetRenderTeeOffsetToRenderedTee ( pIdleState , & TeeInfo , OffsetToMid ) ;
vec2 TeeRenderPos ( Button . x + Button . h / 2 , Button . y + Button . h / 2 + OffsetToMid . y ) ;
RenderTools ( ) - > RenderTee ( pIdleState , & TeeInfo , EMOTE_NORMAL , vec2 ( 1.0f , 0.0f ) , TeeRenderPos ) ;
2011-03-22 21:41:27 +00:00
Player . HSplitTop ( 1.5f , 0 , & Player ) ;
Player . VSplitMid ( & Player , & Button ) ;
2014-02-19 13:49:08 +00:00
Item . m_Rect . VSplitRight ( 200.0f , & Button2 , & Item . m_Rect ) ;
2011-03-22 21:41:27 +00:00
CTextCursor Cursor ;
2020-09-26 19:41:58 +00:00
TextRender ( ) - > SetCursor ( & Cursor , Player . x , Player . y + ( Player . h - 14.f ) / 2.f , 14.0f , TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END ) ;
2011-03-22 21:41:27 +00:00
Cursor . m_LineWidth = Player . w ;
2011-08-04 21:43:39 +00:00
TextRender ( ) - > TextEx ( & Cursor , m_pClient - > m_aClients [ Index ] . m_aName , - 1 ) ;
2011-03-22 21:41:27 +00:00
2020-09-26 19:41:58 +00:00
TextRender ( ) - > SetCursor ( & Cursor , Button . x , Button . y + ( Button . h - 14.f ) / 2.f , 14.0f , TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END ) ;
2011-03-22 21:41:27 +00:00
Cursor . m_LineWidth = Button . w ;
2011-08-04 21:43:39 +00:00
TextRender ( ) - > TextEx ( & Cursor , m_pClient - > m_aClients [ Index ] . m_aClan , - 1 ) ;
2011-03-22 21:41:27 +00:00
2022-03-30 18:40:46 +00:00
// TextRender()->SetCursor(&Cursor, Button2.x,Button2.y, 14.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
// Cursor.m_LineWidth = Button.w;
2019-04-26 21:47:34 +00:00
ColorRGBA Color ( 1.0f , 1.0f , 1.0f , 0.5f ) ;
2021-07-12 09:43:56 +00:00
m_pClient - > m_CountryFlags . Render ( m_pClient - > m_aClients [ Index ] . m_Country , & Color ,
2022-03-21 06:10:44 +00:00
Button2 . x , Button2 . y + Button2 . h / 2.0f - 0.75f * Button2 . h / 2.0f , 1.5f * Button2 . h , 0.75f * Button2 . h ) ;
2014-02-19 13:49:08 +00:00
2020-06-26 22:06:07 +00:00
// ignore chat button
2014-02-02 20:06:05 +00:00
Item . m_Rect . HMargin ( 2.0f , & Item . m_Rect ) ;
Item . m_Rect . VSplitLeft ( Width , & Button , & Item . m_Rect ) ;
2020-09-26 19:41:58 +00:00
Button . VSplitLeft ( ( Width - Button . h ) / 4.0f , 0 , & Button ) ;
2011-04-06 18:18:31 +00:00
Button . VSplitLeft ( Button . h , & Button , 0 ) ;
2013-11-14 15:23:15 +00:00
if ( g_Config . m_ClShowChatFriends & & ! m_pClient - > m_aClients [ Index ] . m_Friend )
2012-01-10 22:03:23 +00:00
DoButton_Toggle ( & s_aPlayerIDs [ Index ] [ 0 ] , 1 , & Button , false ) ;
2020-09-26 19:41:58 +00:00
else if ( DoButton_Toggle ( & s_aPlayerIDs [ Index ] [ 0 ] , m_pClient - > m_aClients [ Index ] . m_ChatIgnore , & Button , true ) )
m_pClient - > m_aClients [ Index ] . m_ChatIgnore ^ = 1 ;
2011-03-23 12:06:35 +00:00
2020-06-26 22:06:07 +00:00
// ignore emoticon button
Item . m_Rect . VSplitLeft ( 20.0f , & Button , & Item . m_Rect ) ;
Item . m_Rect . VSplitLeft ( Width , & Button , & Item . m_Rect ) ;
2020-09-26 19:41:58 +00:00
Button . VSplitLeft ( ( Width - Button . h ) / 4.0f , 0 , & Button ) ;
2020-06-26 22:06:07 +00:00
Button . VSplitLeft ( Button . h , & Button , 0 ) ;
if ( g_Config . m_ClShowChatFriends & & ! m_pClient - > m_aClients [ Index ] . m_Friend )
DoButton_Toggle ( & s_aPlayerIDs [ Index ] [ 1 ] , 1 , & Button , false ) ;
2020-09-26 19:41:58 +00:00
else if ( DoButton_Toggle ( & s_aPlayerIDs [ Index ] [ 1 ] , m_pClient - > m_aClients [ Index ] . m_EmoticonIgnore , & Button , true ) )
m_pClient - > m_aClients [ Index ] . m_EmoticonIgnore ^ = 1 ;
2020-06-26 22:06:07 +00:00
2011-03-23 12:06:35 +00:00
// friend button
2014-02-02 20:06:05 +00:00
Item . m_Rect . VSplitLeft ( 20.0f , & Button , & Item . m_Rect ) ;
Item . m_Rect . VSplitLeft ( Width , & Button , & Item . m_Rect ) ;
2020-09-26 19:41:58 +00:00
Button . VSplitLeft ( ( Width - Button . h ) / 4.0f , 0 , & Button ) ;
2011-04-06 18:18:31 +00:00
Button . VSplitLeft ( Button . h , & Button , 0 ) ;
2020-06-26 22:06:07 +00:00
if ( DoButton_Toggle ( & s_aPlayerIDs [ Index ] [ 2 ] , m_pClient - > m_aClients [ Index ] . m_Friend , & Button , true ) )
2011-05-04 23:43:27 +00:00
{
2011-08-04 21:43:39 +00:00
if ( m_pClient - > m_aClients [ Index ] . m_Friend )
m_pClient - > Friends ( ) - > RemoveFriend ( m_pClient - > m_aClients [ Index ] . m_aName , m_pClient - > m_aClients [ Index ] . m_aClan ) ;
2011-04-06 18:18:31 +00:00
else
2011-08-04 21:43:39 +00:00
m_pClient - > Friends ( ) - > AddFriend ( m_pClient - > m_aClients [ Index ] . m_aName , m_pClient - > m_aClients [ Index ] . m_aClan ) ;
2011-05-04 23:43:27 +00:00
}
2011-03-22 21:41:27 +00:00
}
2011-04-13 18:37:12 +00:00
2014-01-10 12:55:31 +00:00
UiDoListboxEnd ( & s_ScrollValue , 0 ) ;
2008-09-29 11:34:49 +00:00
}
2010-05-29 07:25:38 +00:00
void CMenus : : RenderServerInfo ( CUIRect MainView )
2008-09-29 11:34:49 +00:00
{
2011-03-13 10:14:35 +00:00
if ( ! m_pClient - > m_Snap . m_pLocalInfo )
return ;
2008-10-17 21:16:23 +00:00
// fetch server info
2010-05-29 07:25:38 +00:00
CServerInfo CurrentServerInfo ;
Client ( ) - > GetServerInfo ( & CurrentServerInfo ) ;
2011-04-13 18:37:12 +00:00
2008-09-29 11:34:49 +00:00
// render background
2022-08-07 16:12:07 +00:00
MainView . Draw ( ms_ColorTabbarActive , IGraphics : : CORNER_B , 10.0f ) ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
CUIRect View , ServerInfo , GameInfo , Motd ;
2011-04-13 18:37:12 +00:00
2008-09-29 11:34:49 +00:00
float x = 0.0f ;
float y = 0.0f ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
char aBuf [ 1024 ] ;
2011-04-13 18:37:12 +00:00
2008-09-29 11:34:49 +00:00
// set view to use for all sub-modules
2010-05-29 07:25:38 +00:00
MainView . Margin ( 10.0f , & View ) ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
// serverinfo
2022-06-12 08:34:09 +00:00
View . HSplitTop ( View . h / 2 - 5.0f , & ServerInfo , & Motd ) ;
ServerInfo . VSplitLeft ( View . w / 2 - 5.0f , & ServerInfo , & GameInfo ) ;
2022-08-07 16:12:07 +00:00
ServerInfo . Draw ( ColorRGBA ( 1 , 1 , 1 , 0.25f ) , IGraphics : : CORNER_ALL , 10.0f ) ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
ServerInfo . Margin ( 5.0f , & ServerInfo ) ;
2011-04-13 18:37:12 +00:00
2008-09-29 11:34:49 +00:00
x = 5.0f ;
y = 0.0f ;
2011-04-13 18:37:12 +00:00
2020-09-26 19:41:58 +00:00
TextRender ( ) - > Text ( 0 , ServerInfo . x + x , ServerInfo . y + y , 32 , Localize ( " Server info " ) , 250.0f ) ;
y + = 32.0f + 5.0f ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
mem_zero ( aBuf , sizeof ( aBuf ) ) ;
2008-09-29 11:34:49 +00:00
str_format (
2010-05-29 07:25:38 +00:00
aBuf ,
sizeof ( aBuf ) ,
2008-09-29 11:34:49 +00:00
" %s \n \n "
2009-06-15 07:34:25 +00:00
" %s: %s \n "
" %s: %d \n "
" %s: %s \n "
" %s: %s \n " ,
2010-05-29 07:25:38 +00:00
CurrentServerInfo . m_aName ,
2013-12-18 03:11:26 +00:00
Localize ( " Address " ) , CurrentServerInfo . m_aAddress ,
2010-05-29 07:25:38 +00:00
Localize ( " Ping " ) , m_pClient - > m_Snap . m_pLocalInfo - > m_Latency ,
Localize ( " Version " ) , CurrentServerInfo . m_aVersion ,
2020-09-26 19:41:58 +00:00
Localize ( " Password " ) , CurrentServerInfo . m_Flags & 1 ? Localize ( " Yes " ) : Localize ( " No " ) ) ;
2011-04-13 18:37:12 +00:00
2020-09-26 19:41:58 +00:00
TextRender ( ) - > Text ( 0 , ServerInfo . x + x , ServerInfo . y + y , 20 , aBuf , 250.0f ) ;
2011-04-13 18:37:12 +00:00
2008-09-29 11:34:49 +00:00
{
2010-05-29 07:25:38 +00:00
CUIRect Button ;
2022-05-23 18:16:18 +00:00
NETADDR ServerAddr = Client ( ) - > ServerAddress ( ) ;
TRISTATE IsFavorite = Favorites ( ) - > IsFavorite ( & ServerAddr , 1 ) ;
2010-05-29 07:25:38 +00:00
ServerInfo . HSplitBottom ( 20.0f , & ServerInfo , & Button ) ;
static int s_AddFavButton = 0 ;
2022-05-23 18:16:18 +00:00
if ( DoButton_CheckBox ( & s_AddFavButton , Localize ( " Favorite " ) , IsFavorite ! = TRISTATE : : NONE , & Button ) )
2008-09-29 11:34:49 +00:00
{
2022-05-23 18:16:18 +00:00
if ( IsFavorite ! = TRISTATE : : NONE )
Favorites ( ) - > Remove ( & ServerAddr , 1 ) ;
2008-09-29 11:34:49 +00:00
else
2022-05-23 18:16:18 +00:00
Favorites ( ) - > Add ( & ServerAddr , 1 ) ;
2008-09-29 11:34:49 +00:00
}
}
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
// gameinfo
GameInfo . VSplitLeft ( 10.0f , 0x0 , & GameInfo ) ;
2022-08-07 16:12:07 +00:00
GameInfo . Draw ( ColorRGBA ( 1 , 1 , 1 , 0.25f ) , IGraphics : : CORNER_ALL , 10.0f ) ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
GameInfo . Margin ( 5.0f , & GameInfo ) ;
2011-04-13 18:37:12 +00:00
2008-09-29 11:34:49 +00:00
x = 5.0f ;
y = 0.0f ;
2011-04-13 18:37:12 +00:00
2020-09-26 19:41:58 +00:00
TextRender ( ) - > Text ( 0 , GameInfo . x + x , GameInfo . y + y , 32 , Localize ( " Game info " ) , 250.0f ) ;
y + = 32.0f + 5.0f ;
2011-04-13 18:37:12 +00:00
2011-03-04 16:08:10 +00:00
if ( m_pClient - > m_Snap . m_pGameInfoObj )
{
mem_zero ( aBuf , sizeof ( aBuf ) ) ;
str_format (
aBuf ,
sizeof ( aBuf ) ,
" \n \n "
" %s: %s \n "
" %s: %s \n "
" %s: %d \n "
" %s: %d \n "
" \n "
" %s: %d/%d \n " ,
Localize ( " Game type " ) , CurrentServerInfo . m_aGameType ,
Localize ( " Map " ) , CurrentServerInfo . m_aMap ,
Localize ( " Score limit " ) , m_pClient - > m_Snap . m_pGameInfoObj - > m_ScoreLimit ,
Localize ( " Time limit " ) , m_pClient - > m_Snap . m_pGameInfoObj - > m_TimeLimit ,
2020-09-26 19:41:58 +00:00
Localize ( " Players " ) , m_pClient - > m_Snap . m_NumPlayers , CurrentServerInfo . m_MaxClients ) ;
TextRender ( ) - > Text ( 0 , GameInfo . x + x , GameInfo . y + y , 20 , aBuf , 250.0f ) ;
2011-03-04 16:08:10 +00:00
}
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
// motd
2022-08-15 21:19:56 +00:00
const float MotdFontSize = 16.0f ;
Motd . HSplitTop ( 10.0f , nullptr , & Motd ) ;
2022-08-07 16:12:07 +00:00
Motd . Draw ( ColorRGBA ( 1 , 1 , 1 , 0.25f ) , IGraphics : : CORNER_ALL , 10.0f ) ;
2022-08-15 21:19:56 +00:00
Motd . HMargin ( 5.0f , & Motd ) ;
Motd . VMargin ( 10.0f , & Motd ) ;
CUIRect MotdHeader ;
Motd . HSplitTop ( 2.0f * MotdFontSize , & MotdHeader , & Motd ) ;
Motd . HSplitTop ( 5.0f , nullptr , & Motd ) ;
TextRender ( ) - > Text ( nullptr , MotdHeader . x , MotdHeader . y , 2.0f * MotdFontSize , Localize ( " MOTD " ) , - 1.0f ) ;
static CScrollRegion s_ScrollRegion ;
vec2 ScrollOffset ( 0.0f , 0.0f ) ;
CScrollRegionParams ScrollParams ;
ScrollParams . m_ScrollUnit = 5 * MotdFontSize ;
s_ScrollRegion . Begin ( & Motd , & ScrollOffset , & ScrollParams ) ;
Motd . y + = ScrollOffset . y ;
CUIRect MotdTextArea ;
Motd . HSplitTop ( ( str_countchr ( m_pClient - > m_Motd . m_aServerMotd , ' \n ' ) + 1 ) * MotdFontSize , & MotdTextArea , & Motd ) ;
s_ScrollRegion . AddRect ( MotdTextArea ) ;
TextRender ( ) - > Text ( nullptr , MotdTextArea . x , MotdTextArea . y , MotdFontSize , m_pClient - > m_Motd . m_aServerMotd , MotdTextArea . w ) ;
s_ScrollRegion . End ( ) ;
2008-09-29 11:34:49 +00:00
}
2016-04-27 18:04:31 +00:00
bool CMenus : : RenderServerControlServer ( CUIRect MainView )
2008-09-29 11:34:49 +00:00
{
2010-05-29 07:25:38 +00:00
static int s_VoteList = 0 ;
static float s_ScrollValue = 0 ;
CUIRect List = MainView ;
2021-07-12 09:43:56 +00:00
int Total = m_pClient - > m_Voting . m_NumVoteOptions ;
2015-04-18 22:31:45 +00:00
int NumVoteOptions = 0 ;
2015-04-02 23:27:07 +00:00
int aIndices [ MAX_VOTE_OPTIONS ] ;
2015-03-14 14:32:04 +00:00
static int s_CurVoteOption = 0 ;
2015-07-25 16:43:54 +00:00
int TotalShown = 0 ;
2021-07-12 09:43:56 +00:00
for ( CVoteOptionClient * pOption = m_pClient - > m_Voting . m_pFirst ; pOption ; pOption = pOption - > m_pNext )
2015-07-25 16:43:54 +00:00
{
2021-06-28 20:51:14 +00:00
if ( m_aFilterString [ 0 ] ! = ' \0 ' & & ! str_utf8_find_nocase ( pOption - > m_aDescription , m_aFilterString ) )
2015-07-25 16:43:54 +00:00
continue ;
TotalShown + + ;
}
2015-03-14 10:05:08 +00:00
2020-10-27 17:31:27 +00:00
UiDoListboxStart ( & s_VoteList , & List , 19.0f , " " , " " , TotalShown , 1 , s_CurVoteOption , s_ScrollValue ) ;
2011-04-13 18:37:12 +00:00
2015-03-14 14:32:04 +00:00
int i = - 1 ;
2021-07-12 09:43:56 +00:00
for ( CVoteOptionClient * pOption = m_pClient - > m_Voting . m_pFirst ; pOption ; pOption = pOption - > m_pNext )
2008-09-29 11:34:49 +00:00
{
2015-03-14 14:32:04 +00:00
i + + ;
2021-06-28 20:51:14 +00:00
if ( m_aFilterString [ 0 ] ! = ' \0 ' & & ! str_utf8_find_nocase ( pOption - > m_aDescription , m_aFilterString ) )
2015-03-13 15:44:05 +00:00
continue ;
2010-05-29 07:25:38 +00:00
CListboxItem Item = UiDoListboxNextItem ( pOption ) ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
if ( Item . m_Visible )
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Item . m_Rect , pOption - > m_aDescription , 13.0f , TEXTALIGN_LEFT ) ;
2015-03-14 10:05:08 +00:00
2015-03-14 14:32:04 +00:00
if ( NumVoteOptions < Total )
aIndices [ NumVoteOptions ] = i ;
NumVoteOptions + + ;
2008-10-06 18:05:01 +00:00
}
2011-04-13 18:37:12 +00:00
2016-04-27 18:04:31 +00:00
bool Call ;
s_CurVoteOption = UiDoListboxEnd ( & s_ScrollValue , & Call ) ;
2015-03-14 14:32:04 +00:00
if ( s_CurVoteOption < Total )
m_CallvoteSelectedOption = aIndices [ s_CurVoteOption ] ;
2016-04-27 18:04:31 +00:00
return Call ;
2008-09-29 11:34:49 +00:00
}
2016-04-27 18:04:31 +00:00
bool CMenus : : RenderServerControlKick ( CUIRect MainView , bool FilterSpectators )
2008-09-29 11:34:49 +00:00
{
2010-05-31 15:36:20 +00:00
int NumOptions = 0 ;
2020-11-12 13:20:38 +00:00
int Selected = 0 ;
2010-05-31 20:05:45 +00:00
static int aPlayerIDs [ MAX_CLIENTS ] ;
2022-06-30 22:36:32 +00:00
for ( auto & pInfoByName : m_pClient - > m_Snap . m_apInfoByName )
2010-05-31 15:36:20 +00:00
{
2020-10-26 14:14:07 +00:00
if ( ! pInfoByName )
2010-05-31 15:36:20 +00:00
continue ;
2011-08-11 08:59:14 +00:00
2020-10-26 14:14:07 +00:00
int Index = pInfoByName - > m_ClientID ;
if ( Index = = m_pClient - > m_Snap . m_LocalClientID | | ( FilterSpectators & & pInfoByName - > m_Team = = TEAM_SPECTATORS ) )
2010-05-31 15:36:20 +00:00
continue ;
2015-03-14 10:05:08 +00:00
2021-06-28 20:51:14 +00:00
if ( ! str_utf8_find_nocase ( m_pClient - > m_aClients [ Index ] . m_aName , m_aFilterString ) )
2015-03-14 10:05:08 +00:00
continue ;
2011-08-04 21:43:39 +00:00
if ( m_CallvoteSelectedPlayer = = Index )
2010-05-31 20:05:45 +00:00
Selected = NumOptions ;
2011-08-04 21:43:39 +00:00
aPlayerIDs [ NumOptions + + ] = Index ;
2010-05-31 15:36:20 +00:00
}
2008-09-29 11:34:49 +00:00
2010-05-31 15:36:20 +00:00
static int s_VoteList = 0 ;
static float s_ScrollValue = 0 ;
2010-05-29 07:25:38 +00:00
CUIRect List = MainView ;
2011-04-08 22:03:56 +00:00
UiDoListboxStart ( & s_VoteList , & List , 24.0f , " " , " " , NumOptions , 1 , Selected , s_ScrollValue ) ;
2011-04-13 18:37:12 +00:00
2010-05-31 20:05:45 +00:00
for ( int i = 0 ; i < NumOptions ; i + + )
2008-09-29 11:34:49 +00:00
{
2010-05-31 20:05:45 +00:00
CListboxItem Item = UiDoListboxNextItem ( & aPlayerIDs [ i ] ) ;
2011-04-13 18:37:12 +00:00
2010-05-31 15:36:20 +00:00
if ( Item . m_Visible )
{
2021-04-09 18:11:53 +00:00
CTeeRenderInfo TeeInfo = m_pClient - > m_aClients [ aPlayerIDs [ i ] ] . m_RenderInfo ;
TeeInfo . m_Size = Item . m_Rect . h ;
CAnimState * pIdleState = CAnimState : : GetIdle ( ) ;
vec2 OffsetToMid ;
RenderTools ( ) - > GetRenderTeeOffsetToRenderedTee ( pIdleState , & TeeInfo , OffsetToMid ) ;
vec2 TeeRenderPos ( Item . m_Rect . x + Item . m_Rect . h / 2 , Item . m_Rect . y + Item . m_Rect . h / 2 + OffsetToMid . y ) ;
RenderTools ( ) - > RenderTee ( pIdleState , & TeeInfo , EMOTE_NORMAL , vec2 ( 1.0f , 0.0f ) , TeeRenderPos ) ;
Item . m_Rect . x + = TeeInfo . m_Size ;
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Item . m_Rect , m_pClient - > m_aClients [ aPlayerIDs [ i ] ] . m_aName , 16.0f , TEXTALIGN_LEFT ) ;
2010-05-31 15:36:20 +00:00
}
2008-09-29 11:34:49 +00:00
}
2011-04-13 18:37:12 +00:00
2016-04-27 18:04:31 +00:00
bool Call ;
Selected = UiDoListboxEnd ( & s_ScrollValue , & Call ) ;
2010-05-31 20:05:45 +00:00
m_CallvoteSelectedPlayer = Selected ! = - 1 ? aPlayerIDs [ Selected ] : - 1 ;
2016-04-27 18:04:31 +00:00
return Call ;
2008-09-29 11:34:49 +00:00
}
2010-05-29 07:25:38 +00:00
void CMenus : : RenderServerControl ( CUIRect MainView )
2008-09-29 11:34:49 +00:00
{
2010-05-29 07:25:38 +00:00
static int s_ControlPage = 0 ;
2011-04-13 18:37:12 +00:00
2008-09-29 11:34:49 +00:00
// render background
2020-10-27 17:23:20 +00:00
CUIRect Bottom , RconExtension , TabBar , Button ;
2011-04-08 22:03:56 +00:00
MainView . HSplitTop ( 20.0f , & Bottom , & MainView ) ;
2022-08-07 16:12:07 +00:00
Bottom . Draw ( ms_ColorTabbarActive , 0 , 10.0f ) ;
2011-04-08 22:03:56 +00:00
MainView . HSplitTop ( 20.0f , & TabBar , & MainView ) ;
2022-08-07 16:12:07 +00:00
MainView . Draw ( ms_ColorTabbarActive , IGraphics : : CORNER_B , 10.0f ) ;
2011-04-06 09:41:40 +00:00
MainView . Margin ( 10.0f , & MainView ) ;
2020-10-27 17:23:20 +00:00
if ( Client ( ) - > RconAuthed ( ) )
MainView . HSplitBottom ( 90.0f , & MainView , & RconExtension ) ;
2011-04-06 09:41:40 +00:00
// tab bar
2008-09-29 11:34:49 +00:00
{
2020-09-26 19:41:58 +00:00
TabBar . VSplitLeft ( TabBar . w / 3 , & Button , & TabBar ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_Button0 ;
2011-04-08 22:03:56 +00:00
if ( DoButton_MenuTab ( & s_Button0 , Localize ( " Change settings " ) , s_ControlPage = = 0 , & Button , 0 ) )
2011-04-06 09:41:40 +00:00
s_ControlPage = 0 ;
TabBar . VSplitMid ( & Button , & TabBar ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_Button1 ;
2011-04-06 09:41:40 +00:00
if ( DoButton_MenuTab ( & s_Button1 , Localize ( " Kick player " ) , s_ControlPage = = 1 , & Button , 0 ) )
s_ControlPage = 1 ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_Button2 ;
2011-04-08 22:03:56 +00:00
if ( DoButton_MenuTab ( & s_Button2 , Localize ( " Move player to spectators " ) , s_ControlPage = = 2 , & TabBar , 0 ) )
2011-04-06 09:41:40 +00:00
s_ControlPage = 2 ;
2008-09-29 11:34:49 +00:00
}
2011-03-31 13:43:12 +00:00
// render page
2020-09-26 19:41:58 +00:00
MainView . HSplitBottom ( ms_ButtonHeight + 5 * 2 , & MainView , & Bottom ) ;
2010-05-29 07:25:38 +00:00
Bottom . HMargin ( 5.0f , & Bottom ) ;
2011-03-31 13:43:12 +00:00
2016-04-27 18:04:31 +00:00
bool Call = false ;
2010-05-29 07:25:38 +00:00
if ( s_ControlPage = = 0 )
2016-04-27 18:04:31 +00:00
Call = RenderServerControlServer ( MainView ) ;
2010-05-29 07:25:38 +00:00
else if ( s_ControlPage = = 1 )
2016-04-27 18:04:31 +00:00
Call = RenderServerControlKick ( MainView , false ) ;
2011-03-26 15:56:59 +00:00
else if ( s_ControlPage = = 2 )
2016-04-27 18:04:31 +00:00
Call = RenderServerControlKick ( MainView , true ) ;
2008-09-29 11:34:49 +00:00
2011-03-31 13:43:12 +00:00
// vote menu
2008-09-29 11:34:49 +00:00
{
2022-03-20 11:57:50 +00:00
CUIRect QuickSearch ;
2015-03-13 15:15:05 +00:00
// render quick search
{
Bottom . VSplitLeft ( 240.0f , & QuickSearch , & Bottom ) ;
QuickSearch . HSplitTop ( 5.0f , 0 , & QuickSearch ) ;
2022-03-19 17:50:33 +00:00
const char * pSearchLabel = " \xEF \x80 \x82 " ;
2018-03-13 20:59:07 +00:00
TextRender ( ) - > SetCurFont ( TextRender ( ) - > GetFont ( TEXT_FONT_ICON_FONT ) ) ;
2020-10-06 10:25:10 +00:00
TextRender ( ) - > SetRenderFlags ( ETextRenderFlags : : TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_OVERSIZE ) ;
2022-03-11 16:34:48 +00:00
SLabelProperties Props ;
Props . m_AlignVertically = 0 ;
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & QuickSearch , pSearchLabel , 14.0f , TEXTALIGN_LEFT , Props ) ;
2020-07-15 19:10:13 +00:00
float wSearch = TextRender ( ) - > TextWidth ( 0 , 14.0f , pSearchLabel , - 1 , - 1.0f ) ;
2018-03-13 20:59:07 +00:00
TextRender ( ) - > SetRenderFlags ( 0 ) ;
TextRender ( ) - > SetCurFont ( NULL ) ;
2015-03-13 15:15:05 +00:00
QuickSearch . VSplitLeft ( wSearch , 0 , & QuickSearch ) ;
QuickSearch . VSplitLeft ( 5.0f , 0 , & QuickSearch ) ;
2018-09-20 05:43:05 +00:00
static int s_ClearButton = 0 ;
2021-12-03 19:15:44 +00:00
static float s_Offset = 0.0f ;
2022-03-13 18:09:33 +00:00
SUIExEditBoxProperties EditProps ;
2021-12-18 11:23:20 +00:00
if ( m_ControlPageOpening | | ( Input ( ) - > KeyPress ( KEY_F ) & & Input ( ) - > ModifierIsPressed ( ) ) )
2021-03-14 18:57:21 +00:00
{
2017-07-24 16:05:19 +00:00
UI ( ) - > SetActiveItem ( & m_aFilterString ) ;
2021-03-14 18:57:21 +00:00
m_ControlPageOpening = false ;
2022-03-13 18:09:33 +00:00
EditProps . m_SelectText = true ;
2021-03-14 18:57:21 +00:00
}
2022-03-13 18:09:33 +00:00
EditProps . m_pEmptyText = Localize ( " Search " ) ;
2022-08-07 20:03:34 +00:00
UI ( ) - > DoClearableEditBox ( & m_aFilterString , & s_ClearButton , & QuickSearch , m_aFilterString , sizeof ( m_aFilterString ) , 14.0f , & s_Offset , false , IGraphics : : CORNER_ALL , EditProps ) ;
2015-03-13 15:15:05 +00:00
}
2010-05-29 07:25:38 +00:00
Bottom . VSplitRight ( 120.0f , & Bottom , & Button ) ;
2011-04-13 18:37:12 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_CallVoteButton ;
2016-04-27 18:04:31 +00:00
if ( DoButton_Menu ( & s_CallVoteButton , Localize ( " Call vote " ) , 0 , & Button ) | | Call )
2008-09-29 11:34:49 +00:00
{
2010-05-29 07:25:38 +00:00
if ( s_ControlPage = = 0 )
2016-04-27 18:04:31 +00:00
{
2021-07-12 09:43:56 +00:00
m_pClient - > m_Voting . CallvoteOption ( m_CallvoteSelectedOption , m_aCallvoteReason ) ;
2017-07-25 17:08:16 +00:00
if ( g_Config . m_UiCloseWindowAfterChangingSetting )
SetActive ( false ) ;
2016-04-27 18:04:31 +00:00
}
2010-05-29 07:25:38 +00:00
else if ( s_ControlPage = = 1 )
{
if ( m_CallvoteSelectedPlayer > = 0 & & m_CallvoteSelectedPlayer < MAX_CLIENTS & &
2022-06-30 22:36:32 +00:00
m_pClient - > m_Snap . m_apPlayerInfos [ m_CallvoteSelectedPlayer ] )
2010-05-29 07:25:38 +00:00
{
2021-07-12 09:43:56 +00:00
m_pClient - > m_Voting . CallvoteKick ( m_CallvoteSelectedPlayer , m_aCallvoteReason ) ;
2010-05-29 07:25:38 +00:00
SetActive ( false ) ;
}
}
2011-03-26 15:56:59 +00:00
else if ( s_ControlPage = = 2 )
{
if ( m_CallvoteSelectedPlayer > = 0 & & m_CallvoteSelectedPlayer < MAX_CLIENTS & &
2022-06-30 22:36:32 +00:00
m_pClient - > m_Snap . m_apPlayerInfos [ m_CallvoteSelectedPlayer ] )
2011-03-26 15:56:59 +00:00
{
2021-07-12 09:43:56 +00:00
m_pClient - > m_Voting . CallvoteSpectate ( m_CallvoteSelectedPlayer , m_aCallvoteReason ) ;
2011-03-26 15:56:59 +00:00
SetActive ( false ) ;
}
}
2011-03-25 11:06:45 +00:00
m_aCallvoteReason [ 0 ] = 0 ;
2010-05-29 07:25:38 +00:00
}
2011-04-13 18:37:12 +00:00
2010-10-09 18:34:17 +00:00
// render kick reason
2011-03-25 09:26:59 +00:00
CUIRect Reason ;
Bottom . VSplitRight ( 40.0f , & Bottom , 0 ) ;
Bottom . VSplitRight ( 160.0f , & Bottom , & Reason ) ;
Reason . HSplitTop ( 5.0f , 0 , & Reason ) ;
const char * pLabel = Localize ( " Reason: " ) ;
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Reason , pLabel , 14.0f , TEXTALIGN_LEFT ) ;
2020-07-15 19:10:13 +00:00
float w = TextRender ( ) - > TextWidth ( 0 , 14.0f , pLabel , - 1 , - 1.0f ) ;
2020-09-26 19:41:58 +00:00
Reason . VSplitLeft ( w + 10.0f , 0 , & Reason ) ;
2011-03-25 09:26:59 +00:00
static float s_Offset = 0.0f ;
2021-12-18 11:23:20 +00:00
if ( Input ( ) - > KeyPress ( KEY_R ) & & Input ( ) - > ModifierIsPressed ( ) )
2017-07-24 16:05:19 +00:00
UI ( ) - > SetActiveItem ( & m_aCallvoteReason ) ;
2022-08-07 20:03:34 +00:00
UI ( ) - > DoEditBox ( & m_aCallvoteReason , & Reason , m_aCallvoteReason , sizeof ( m_aCallvoteReason ) , 14.0f , & s_Offset , false , IGraphics : : CORNER_ALL ) ;
2011-04-13 18:37:12 +00:00
2011-03-26 17:43:43 +00:00
// extended features (only available when authed in rcon)
2010-05-29 07:25:38 +00:00
if ( Client ( ) - > RconAuthed ( ) )
{
2020-10-30 03:40:15 +00:00
// background
RconExtension . Margin ( 10.0f , & RconExtension ) ;
RconExtension . HSplitTop ( 20.0f , & Bottom , & RconExtension ) ;
RconExtension . HSplitTop ( 5.0f , 0 , & RconExtension ) ;
2011-03-26 17:43:43 +00:00
// force vote
Bottom . VSplitLeft ( 5.0f , 0 , & Bottom ) ;
2010-05-29 07:25:38 +00:00
Bottom . VSplitLeft ( 120.0f , & Button , & Bottom ) ;
2020-10-27 17:23:20 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ForceVoteButton ;
2010-05-29 07:25:38 +00:00
if ( DoButton_Menu ( & s_ForceVoteButton , Localize ( " Force vote " ) , 0 , & Button ) )
2008-09-29 11:34:49 +00:00
{
2010-05-29 07:25:38 +00:00
if ( s_ControlPage = = 0 )
2021-07-12 09:43:56 +00:00
m_pClient - > m_Voting . CallvoteOption ( m_CallvoteSelectedOption , m_aCallvoteReason , true ) ;
2010-05-29 07:25:38 +00:00
else if ( s_ControlPage = = 1 )
{
if ( m_CallvoteSelectedPlayer > = 0 & & m_CallvoteSelectedPlayer < MAX_CLIENTS & &
2022-06-30 22:36:32 +00:00
m_pClient - > m_Snap . m_apPlayerInfos [ m_CallvoteSelectedPlayer ] )
2010-05-29 07:25:38 +00:00
{
2021-07-12 09:43:56 +00:00
m_pClient - > m_Voting . CallvoteKick ( m_CallvoteSelectedPlayer , m_aCallvoteReason , true ) ;
2010-05-29 07:25:38 +00:00
SetActive ( false ) ;
}
}
2011-03-26 15:56:59 +00:00
else if ( s_ControlPage = = 2 )
2008-09-29 11:34:49 +00:00
{
2010-05-29 07:25:38 +00:00
if ( m_CallvoteSelectedPlayer > = 0 & & m_CallvoteSelectedPlayer < MAX_CLIENTS & &
2022-06-30 22:36:32 +00:00
m_pClient - > m_Snap . m_apPlayerInfos [ m_CallvoteSelectedPlayer ] )
2010-05-29 07:25:38 +00:00
{
2021-07-12 09:43:56 +00:00
m_pClient - > m_Voting . CallvoteSpectate ( m_CallvoteSelectedPlayer , m_aCallvoteReason , true ) ;
2010-05-29 07:25:38 +00:00
SetActive ( false ) ;
}
2008-09-29 11:34:49 +00:00
}
2011-03-25 11:06:45 +00:00
m_aCallvoteReason [ 0 ] = 0 ;
2008-09-29 11:34:49 +00:00
}
2011-03-26 17:43:43 +00:00
if ( s_ControlPage = = 0 )
{
// remove vote
Bottom . VSplitRight ( 10.0f , & Bottom , 0 ) ;
Bottom . VSplitRight ( 120.0f , 0 , & Button ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_RemoveVoteButton ;
2011-03-26 17:43:43 +00:00
if ( DoButton_Menu ( & s_RemoveVoteButton , Localize ( " Remove " ) , 0 , & Button ) )
2021-07-12 09:43:56 +00:00
m_pClient - > m_Voting . RemovevoteOption ( m_CallvoteSelectedOption ) ;
2011-04-13 18:37:12 +00:00
2011-03-26 17:43:43 +00:00
// add vote
2020-10-27 17:23:20 +00:00
RconExtension . HSplitTop ( 20.0f , & Bottom , & RconExtension ) ;
2011-03-26 17:43:43 +00:00
Bottom . VSplitLeft ( 5.0f , 0 , & Bottom ) ;
Bottom . VSplitLeft ( 250.0f , & Button , & Bottom ) ;
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Button , Localize ( " Vote description: " ) , 14.0f , TEXTALIGN_LEFT ) ;
2011-03-26 17:43:43 +00:00
Bottom . VSplitLeft ( 20.0f , 0 , & Button ) ;
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Button , Localize ( " Vote command: " ) , 14.0f , TEXTALIGN_LEFT ) ;
2011-03-26 17:43:43 +00:00
static char s_aVoteDescription [ 64 ] = { 0 } ;
static char s_aVoteCommand [ 512 ] = { 0 } ;
2020-10-27 17:23:20 +00:00
RconExtension . HSplitTop ( 20.0f , & Bottom , & RconExtension ) ;
2011-03-26 17:43:43 +00:00
Bottom . VSplitRight ( 10.0f , & Bottom , 0 ) ;
Bottom . VSplitRight ( 120.0f , & Bottom , & Button ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_AddVoteButton ;
2011-03-26 17:43:43 +00:00
if ( DoButton_Menu ( & s_AddVoteButton , Localize ( " Add " ) , 0 , & Button ) )
2011-04-05 18:06:41 +00:00
if ( s_aVoteDescription [ 0 ] ! = 0 & & s_aVoteCommand [ 0 ] ! = 0 )
2021-07-12 09:43:56 +00:00
m_pClient - > m_Voting . AddvoteOption ( s_aVoteDescription , s_aVoteCommand ) ;
2011-03-26 17:43:43 +00:00
Bottom . VSplitLeft ( 5.0f , 0 , & Bottom ) ;
Bottom . VSplitLeft ( 250.0f , & Button , & Bottom ) ;
static float s_OffsetDesc = 0.0f ;
2022-08-07 20:03:34 +00:00
UI ( ) - > DoEditBox ( & s_aVoteDescription , & Button , s_aVoteDescription , sizeof ( s_aVoteDescription ) , 14.0f , & s_OffsetDesc , false , IGraphics : : CORNER_ALL ) ;
2011-03-26 17:43:43 +00:00
2011-04-13 18:37:12 +00:00
Bottom . VMargin ( 20.0f , & Button ) ;
2011-03-26 17:43:43 +00:00
static float s_OffsetCmd = 0.0f ;
2022-08-07 20:03:34 +00:00
UI ( ) - > DoEditBox ( & s_aVoteCommand , & Button , s_aVoteCommand , sizeof ( s_aVoteCommand ) , 14.0f , & s_OffsetCmd , false , IGraphics : : CORNER_ALL ) ;
2008-09-29 11:34:49 +00:00
}
}
2011-03-31 13:43:12 +00:00
}
2011-02-23 07:33:21 +00:00
}
2016-04-27 18:14:03 +00:00
void CMenus : : RenderInGameNetwork ( CUIRect MainView )
2010-10-29 22:44:52 +00:00
{
CUIRect Box = MainView ;
CUIRect Button ;
2015-10-04 16:54:13 +00:00
int Page = g_Config . m_UiPage ;
2010-10-29 22:44:52 +00:00
int NewPage = - 1 ;
2022-08-07 16:12:07 +00:00
MainView . Draw ( ms_ColorTabbarActive , IGraphics : : CORNER_B , 10.0f ) ;
2010-10-29 22:44:52 +00:00
Box . HSplitTop ( 5.0f , & MainView , & MainView ) ;
Box . HSplitTop ( 24.0f , & Box , & MainView ) ;
Box . VSplitLeft ( 100.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_InternetButton ;
2020-09-26 19:41:58 +00:00
if ( DoButton_MenuTab ( & s_InternetButton , Localize ( " Internet " ) , Page = = PAGE_INTERNET , & Button , 0 ) )
2010-10-29 22:44:52 +00:00
{
2018-03-13 20:59:07 +00:00
if ( Page ! = PAGE_INTERNET )
2015-10-04 16:54:13 +00:00
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_INTERNET ) ;
2010-10-29 22:44:52 +00:00
NewPage = PAGE_INTERNET ;
}
Box . VSplitLeft ( 80.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_LanButton ;
2020-09-26 19:41:58 +00:00
if ( DoButton_MenuTab ( & s_LanButton , Localize ( " LAN " ) , Page = = PAGE_LAN , & Button , 0 ) )
2010-10-29 22:44:52 +00:00
{
2018-03-13 20:59:07 +00:00
if ( Page ! = PAGE_LAN )
2015-10-04 16:54:13 +00:00
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_LAN ) ;
2010-10-29 22:44:52 +00:00
NewPage = PAGE_LAN ;
}
Box . VSplitLeft ( 110.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_FavoritesButton ;
2020-09-26 19:41:58 +00:00
if ( DoButton_MenuTab ( & s_FavoritesButton , Localize ( " Favorites " ) , Page = = PAGE_FAVORITES , & Button , 0 ) )
2010-10-29 22:44:52 +00:00
{
2018-03-13 20:59:07 +00:00
if ( Page ! = PAGE_FAVORITES )
2015-10-04 16:54:13 +00:00
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_FAVORITES ) ;
2019-03-24 22:15:38 +00:00
NewPage = PAGE_FAVORITES ;
2010-10-29 22:44:52 +00:00
}
2014-09-20 11:41:20 +00:00
Box . VSplitLeft ( 110.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_DDNetButton ;
2020-09-26 19:41:58 +00:00
if ( DoButton_MenuTab ( & s_DDNetButton , " DDNet " , Page = = PAGE_DDNET , & Button , 0 ) | | Page < PAGE_INTERNET | | Page > PAGE_KOG )
2014-09-20 11:41:20 +00:00
{
2018-03-13 20:59:07 +00:00
if ( Page ! = PAGE_DDNET )
2017-09-03 16:17:21 +00:00
{
Client ( ) - > RequestDDNetInfo ( ) ;
2015-10-04 16:54:13 +00:00
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_DDNET ) ;
2017-09-03 16:17:21 +00:00
}
2019-03-24 22:15:38 +00:00
NewPage = PAGE_DDNET ;
}
Box . VSplitLeft ( 110.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_KoGButton ;
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_KoGButton , " KoG " , Page = = PAGE_KOG , & Button , IGraphics : : CORNER_BR ) )
2019-03-24 22:15:38 +00:00
{
if ( Page ! = PAGE_KOG )
{
Client ( ) - > RequestDDNetInfo ( ) ;
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_KOG ) ;
}
NewPage = PAGE_KOG ;
2014-09-20 11:41:20 +00:00
}
2010-10-29 22:44:52 +00:00
if ( NewPage ! = - 1 )
{
if ( Client ( ) - > State ( ) ! = IClient : : STATE_OFFLINE )
2020-09-16 05:36:47 +00:00
SetMenuPage ( NewPage ) ;
2010-10-29 22:44:52 +00:00
}
RenderServerbrowser ( MainView ) ;
}
2011-02-04 17:25:04 +00:00
// ghost stuff
2011-04-09 06:41:31 +00:00
int CMenus : : GhostlistFetchCallback ( const char * pName , int IsDir , int StorageType , void * pUser )
2011-02-04 17:25:04 +00:00
{
CMenus * pSelf = ( CMenus * ) pUser ;
2017-09-28 17:13:20 +00:00
const char * pMap = pSelf - > Client ( ) - > GetCurrentMap ( ) ;
2018-07-25 08:29:05 +00:00
if ( IsDir | | ! str_endswith ( pName , " .gho " ) | | ! str_startswith ( pName , pMap ) )
2011-04-09 06:41:31 +00:00
return 0 ;
2021-09-13 08:06:34 +00:00
char aFilename [ IO_MAX_PATH_LENGTH ] ;
2021-07-12 09:43:56 +00:00
str_format ( aFilename , sizeof ( aFilename ) , " %s/%s " , pSelf - > m_pClient - > m_Ghost . GetGhostDir ( ) , pName ) ;
2017-09-09 15:04:19 +00:00
2020-10-10 20:58:33 +00:00
CGhostInfo Info ;
2021-07-12 09:43:56 +00:00
if ( ! pSelf - > m_pClient - > m_Ghost . GhostLoader ( ) - > GetGhostInfo ( aFilename , & Info , pMap , pSelf - > Client ( ) - > GetCurrentMapSha256 ( ) , pSelf - > Client ( ) - > GetCurrentMapCrc ( ) ) )
2011-04-09 06:41:31 +00:00
return 0 ;
2011-02-04 17:25:04 +00:00
CGhostItem Item ;
2022-07-09 16:14:56 +00:00
str_copy ( Item . m_aFilename , aFilename ) ;
str_copy ( Item . m_aPlayer , Info . m_aOwner ) ;
2020-10-10 20:58:33 +00:00
Item . m_Time = Info . m_Time ;
2017-09-09 15:04:19 +00:00
if ( Item . m_Time > 0 )
2022-06-11 19:38:18 +00:00
pSelf - > m_vGhosts . push_back ( Item ) ;
2022-04-02 11:37:59 +00:00
2022-06-13 16:07:29 +00:00
if ( time_get_nanoseconds ( ) - pSelf - > m_GhostPopulateStartTime > 500 ms )
2022-04-02 11:37:59 +00:00
{
2022-06-23 17:59:38 +00:00
pSelf - > GameClient ( ) - > m_Menus . RenderLoading ( Localize ( " Loading ghost files " ) , " " , 0 , false ) ;
2022-04-02 11:37:59 +00:00
}
2011-04-09 06:41:31 +00:00
return 0 ;
2011-02-04 17:25:04 +00:00
}
void CMenus : : GhostlistPopulate ( )
{
2022-06-11 19:38:18 +00:00
m_vGhosts . clear ( ) ;
2022-06-13 16:07:29 +00:00
m_GhostPopulateStartTime = time_get_nanoseconds ( ) ;
2021-07-12 09:43:56 +00:00
Storage ( ) - > ListDirectory ( IStorage : : TYPE_ALL , m_pClient - > m_Ghost . GetGhostDir ( ) , GhostlistFetchCallback , this ) ;
2022-06-11 19:38:18 +00:00
std : : sort ( m_vGhosts . begin ( ) , m_vGhosts . end ( ) ) ;
2011-04-09 06:41:31 +00:00
2022-05-23 19:36:04 +00:00
CGhostItem * pOwnGhost = 0 ;
2022-06-11 19:38:18 +00:00
for ( auto & Ghost : m_vGhosts )
2022-05-23 19:36:04 +00:00
if ( str_comp ( Ghost . m_aPlayer , Client ( ) - > PlayerName ( ) ) = = 0 & & ( ! pOwnGhost | | Ghost < * pOwnGhost ) )
pOwnGhost = & Ghost ;
2011-04-09 06:41:31 +00:00
2017-09-09 16:25:32 +00:00
if ( pOwnGhost )
2011-02-04 17:25:04 +00:00
{
2017-09-09 16:25:32 +00:00
pOwnGhost - > m_Own = true ;
2021-07-12 09:43:56 +00:00
pOwnGhost - > m_Slot = m_pClient - > m_Ghost . Load ( pOwnGhost - > m_aFilename ) ;
2011-02-04 17:25:04 +00:00
}
}
2017-09-09 16:25:32 +00:00
CMenus : : CGhostItem * CMenus : : GetOwnGhost ( )
{
2022-06-11 19:38:18 +00:00
for ( auto & Ghost : m_vGhosts )
2022-05-23 19:36:04 +00:00
if ( Ghost . m_Own )
return & Ghost ;
return nullptr ;
2017-09-09 16:25:32 +00:00
}
2017-09-10 01:48:22 +00:00
void CMenus : : UpdateOwnGhost ( CGhostItem Item )
{
int Own = - 1 ;
2022-06-11 19:38:18 +00:00
for ( size_t i = 0 ; i < m_vGhosts . size ( ) ; i + + )
if ( m_vGhosts [ i ] . m_Own )
2017-09-10 01:48:22 +00:00
Own = i ;
if ( Own ! = - 1 )
{
2022-06-11 19:38:18 +00:00
m_vGhosts [ Own ] . m_Slot = - 1 ;
m_vGhosts [ Own ] . m_Own = false ;
if ( Item . HasFile ( ) | | ! m_vGhosts [ Own ] . HasFile ( ) )
2017-09-10 01:48:22 +00:00
DeleteGhostItem ( Own ) ;
}
Item . m_Own = true ;
2022-06-11 19:38:18 +00:00
m_vGhosts . insert ( std : : lower_bound ( m_vGhosts . begin ( ) , m_vGhosts . end ( ) , Item ) , Item ) ;
2017-09-10 01:48:22 +00:00
}
void CMenus : : DeleteGhostItem ( int Index )
{
2022-06-11 19:38:18 +00:00
if ( m_vGhosts [ Index ] . HasFile ( ) )
Storage ( ) - > RemoveFile ( m_vGhosts [ Index ] . m_aFilename , IStorage : : TYPE_SAVE ) ;
m_vGhosts . erase ( m_vGhosts . begin ( ) + Index ) ;
2017-09-10 01:48:22 +00:00
}
2011-02-04 17:25:04 +00:00
void CMenus : : RenderGhost ( CUIRect MainView )
{
// render background
2022-08-07 16:12:07 +00:00
MainView . Draw ( ms_ColorTabbarActive , IGraphics : : CORNER_B , 10.0f ) ;
2011-04-09 06:41:31 +00:00
2011-02-04 17:25:04 +00:00
MainView . HSplitTop ( 10.0f , 0 , & MainView ) ;
MainView . HSplitBottom ( 5.0f , & MainView , 0 ) ;
MainView . VSplitLeft ( 5.0f , 0 , & MainView ) ;
MainView . VSplitRight ( 5.0f , & MainView , 0 ) ;
2011-04-09 06:41:31 +00:00
2011-02-04 17:25:04 +00:00
CUIRect Headers , Status ;
CUIRect View = MainView ;
View . HSplitTop ( 17.0f , & Headers , & View ) ;
View . HSplitBottom ( 28.0f , & View , & Status ) ;
// split of the scrollbar
2022-08-07 16:12:07 +00:00
Headers . Draw ( ColorRGBA ( 1 , 1 , 1 , 0.25f ) , IGraphics : : CORNER_T , 5.0f ) ;
2011-02-04 17:25:04 +00:00
Headers . VSplitRight ( 20.0f , & Headers , 0 ) ;
2011-04-09 06:41:31 +00:00
2011-02-04 17:25:04 +00:00
struct CColumn
{
CLocConstString m_Caption ;
2022-07-09 15:07:30 +00:00
int m_Id ;
2011-02-04 17:25:04 +00:00
float m_Width ;
CUIRect m_Rect ;
CUIRect m_Spacer ;
} ;
2011-04-09 06:41:31 +00:00
2011-02-04 17:25:04 +00:00
enum
{
2020-09-26 19:41:58 +00:00
COL_ACTIVE = 0 ,
2011-02-04 17:25:04 +00:00
COL_NAME ,
COL_TIME ,
} ;
2011-04-09 06:41:31 +00:00
2011-02-04 17:25:04 +00:00
static CColumn s_aCols [ ] = {
2022-07-09 15:07:30 +00:00
{ " " , - 1 , 2.0f , { 0 } , { 0 } } ,
{ " " , COL_ACTIVE , 30.0f , { 0 } , { 0 } } ,
{ " Name " , COL_NAME , 300.0f , { 0 } , { 0 } } , // Localize("Name")
{ " Time " , COL_TIME , 200.0f , { 0 } , { 0 } } , // Localize("Time")
2011-02-04 17:25:04 +00:00
} ;
2011-04-09 06:41:31 +00:00
2022-03-30 13:16:19 +00:00
int NumCols = std : : size ( s_aCols ) ;
2011-04-09 06:41:31 +00:00
2011-02-04 17:25:04 +00:00
// do layout
for ( int i = 0 ; i < NumCols ; i + + )
{
Headers . VSplitLeft ( s_aCols [ i ] . m_Width , & s_aCols [ i ] . m_Rect , & Headers ) ;
2020-09-26 19:41:58 +00:00
if ( i + 1 < NumCols )
2011-02-04 17:25:04 +00:00
Headers . VSplitLeft ( 2 , & s_aCols [ i ] . m_Spacer , & Headers ) ;
}
2011-04-09 06:41:31 +00:00
2011-02-04 17:25:04 +00:00
// do headers
for ( int i = 0 ; i < NumCols ; i + + )
2021-06-11 05:31:30 +00:00
DoButton_GridHeader ( s_aCols [ i ] . m_Caption , Localize ( s_aCols [ i ] . m_Caption ) , 0 , & s_aCols [ i ] . m_Rect ) ;
2011-04-09 06:41:31 +00:00
2022-08-07 16:12:07 +00:00
View . Draw ( ColorRGBA ( 0 , 0 , 0 , 0.15f ) , 0 , 0 ) ;
2011-02-04 17:25:04 +00:00
CUIRect Scroll ;
2021-11-26 20:55:31 +00:00
View . VSplitRight ( 20.0f , & View , & Scroll ) ;
2011-04-09 06:41:31 +00:00
2011-02-04 17:25:04 +00:00
static float s_ScrollValue = 0 ;
2022-08-07 20:03:34 +00:00
s_ScrollValue = UI ( ) - > DoScrollbarV ( & s_ScrollValue , & Scroll , s_ScrollValue ) ;
2011-02-04 17:25:04 +00:00
2022-06-11 19:38:18 +00:00
int NumGhosts = m_vGhosts . size ( ) ;
2021-12-03 18:54:22 +00:00
static int s_SelectedIndex = 0 ;
2020-11-12 13:20:38 +00:00
HandleListInputs ( View , s_ScrollValue , 1.0f , nullptr , s_aCols [ 0 ] . m_Rect . h , s_SelectedIndex , NumGhosts ) ;
2011-02-04 17:25:04 +00:00
// set clipping
UI ( ) - > ClipEnable ( & View ) ;
2011-04-09 06:41:31 +00:00
2011-02-04 17:25:04 +00:00
CUIRect OriginalView = View ;
2020-11-12 13:20:38 +00:00
int Num = ( int ) ( View . h / s_aCols [ 0 ] . m_Rect . h ) + 1 ;
2020-11-21 17:30:24 +00:00
int ScrollNum = maximum ( NumGhosts - Num + 1 , 0 ) ;
2020-09-26 19:41:58 +00:00
View . y - = s_ScrollValue * ScrollNum * s_aCols [ 0 ] . m_Rect . h ;
2011-02-04 17:25:04 +00:00
2011-02-11 06:00:12 +00:00
int NewSelected = - 1 ;
2022-02-10 16:40:03 +00:00
bool DoubleClicked = false ;
2011-02-11 06:00:12 +00:00
2018-03-13 20:59:07 +00:00
for ( int i = 0 ; i < NumGhosts ; i + + )
2011-02-04 17:25:04 +00:00
{
2022-06-11 19:38:18 +00:00
const CGhostItem * pItem = & m_vGhosts [ i ] ;
2011-02-04 17:25:04 +00:00
CUIRect Row ;
View . HSplitTop ( 17.0f , & Row , & View ) ;
// make sure that only those in view can be selected
2020-09-26 19:41:58 +00:00
if ( Row . y + Row . h > OriginalView . y & & Row . y < OriginalView . y + OriginalView . h )
2011-02-04 17:25:04 +00:00
{
if ( i = = s_SelectedIndex )
{
CUIRect r = Row ;
r . Margin ( 1.5f , & r ) ;
2022-08-07 16:12:07 +00:00
r . Draw ( ColorRGBA ( 1 , 1 , 1 , 0.5f ) , IGraphics : : CORNER_ALL , 4.0f ) ;
2011-02-04 17:25:04 +00:00
}
2022-05-13 22:26:15 +00:00
if ( UI ( ) - > DoButtonLogic ( pItem , 0 , & Row ) )
2011-02-04 17:25:04 +00:00
{
2011-02-11 06:00:12 +00:00
NewSelected = i ;
2022-02-10 16:40:03 +00:00
DoubleClicked | = NewSelected = = m_DoubleClickIndex ;
m_DoubleClickIndex = NewSelected ;
2011-02-04 17:25:04 +00:00
}
}
2019-04-26 12:06:32 +00:00
ColorRGBA rgb = ColorRGBA ( 1.0f , 1.0f , 1.0f ) ;
2017-09-09 18:19:44 +00:00
if ( pItem - > m_Own )
2019-04-26 12:06:32 +00:00
rgb = color_cast < ColorRGBA > ( ColorHSLA ( 0.33f , 1.0f , 0.75f ) ) ;
2017-09-10 01:48:22 +00:00
2019-12-02 09:18:50 +00:00
TextRender ( ) - > TextColor ( rgb . WithAlpha ( pItem - > HasFile ( ) ? 1.0f : 0.5f ) ) ;
2017-09-09 18:19:44 +00:00
2011-02-04 17:25:04 +00:00
for ( int c = 0 ; c < NumCols ; c + + )
{
CUIRect Button ;
Button . x = s_aCols [ c ] . m_Rect . x ;
Button . y = Row . y ;
Button . h = Row . h ;
Button . w = s_aCols [ c ] . m_Rect . w ;
int Id = s_aCols [ c ] . m_Id ;
if ( Id = = COL_ACTIVE )
{
2017-09-09 16:25:32 +00:00
if ( pItem - > Active ( ) )
2011-02-04 17:25:04 +00:00
{
2020-10-09 07:07:05 +00:00
Graphics ( ) - > WrapClamp ( ) ;
2022-06-25 08:39:39 +00:00
Graphics ( ) - > TextureSet ( GameClient ( ) - > m_EmoticonsSkin . m_aSpriteEmoticons [ ( SPRITE_OOP + 7 ) - SPRITE_OOP ] ) ;
2011-02-04 17:25:04 +00:00
Graphics ( ) - > QuadsBegin ( ) ;
2020-09-26 19:41:58 +00:00
IGraphics : : CQuadItem QuadItem ( Button . x + Button . w / 2 , Button . y + Button . h / 2 , 20.0f , 20.0f ) ;
2011-02-04 17:25:04 +00:00
Graphics ( ) - > QuadsDraw ( & QuadItem , 1 ) ;
Graphics ( ) - > QuadsEnd ( ) ;
2020-10-09 07:07:05 +00:00
Graphics ( ) - > WrapNormal ( ) ;
2011-02-04 17:25:04 +00:00
}
}
else if ( Id = = COL_NAME )
{
CTextCursor Cursor ;
2022-06-12 08:34:09 +00:00
TextRender ( ) - > SetCursor ( & Cursor , Button . x , Button . y + ( Button . h - 12.0f ) / 2.f , 12.0f , TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END ) ;
2011-02-04 17:25:04 +00:00
Cursor . m_LineWidth = Button . w ;
2017-09-09 18:19:44 +00:00
TextRender ( ) - > TextEx ( & Cursor , pItem - > m_aPlayer , - 1 ) ;
2011-02-04 17:25:04 +00:00
}
else if ( Id = = COL_TIME )
{
CTextCursor Cursor ;
2022-06-12 08:34:09 +00:00
TextRender ( ) - > SetCursor ( & Cursor , Button . x , Button . y + ( Button . h - 12.0f ) / 2.f , 12.0f , TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END ) ;
2011-02-04 17:25:04 +00:00
Cursor . m_LineWidth = Button . w ;
char aBuf [ 64 ] ;
2020-10-18 21:33:45 +00:00
str_time ( pItem - > m_Time / 10 , TIME_HOURS_CENTISECS , aBuf , sizeof ( aBuf ) ) ;
2011-02-04 17:25:04 +00:00
TextRender ( ) - > TextEx ( & Cursor , aBuf , - 1 ) ;
}
}
2017-09-09 18:19:44 +00:00
TextRender ( ) - > TextColor ( 1.0f , 1.0f , 1.0f , 1.0f ) ;
2011-02-04 17:25:04 +00:00
}
2011-04-09 06:41:31 +00:00
2017-09-09 16:25:32 +00:00
UI ( ) - > ClipDisable ( ) ;
2011-02-11 06:00:12 +00:00
if ( NewSelected ! = - 1 )
s_SelectedIndex = NewSelected ;
2011-04-09 06:41:31 +00:00
2022-08-07 16:12:07 +00:00
Status . Draw ( ColorRGBA ( 1 , 1 , 1 , 0.25f ) , IGraphics : : CORNER_B , 5.0f ) ;
2011-02-04 17:25:04 +00:00
Status . Margin ( 5.0f , & Status ) ;
2011-04-09 06:41:31 +00:00
2011-02-04 17:25:04 +00:00
CUIRect Button ;
2017-09-17 22:57:21 +00:00
Status . VSplitLeft ( 120.0f , & Button , & Status ) ;
2011-04-09 06:41:31 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ReloadButton ;
2020-11-12 13:20:38 +00:00
if ( DoButton_Menu ( & s_ReloadButton , Localize ( " Reload " ) , 0 , & Button ) | | Input ( ) - > KeyPress ( KEY_F5 ) )
2017-09-17 22:57:21 +00:00
{
2021-07-12 09:43:56 +00:00
m_pClient - > m_Ghost . UnloadAll ( ) ;
2017-09-17 22:57:21 +00:00
GhostlistPopulate ( ) ;
}
2022-06-11 19:38:18 +00:00
if ( s_SelectedIndex = = - 1 | | s_SelectedIndex > = ( int ) m_vGhosts . size ( ) )
2017-09-17 22:57:21 +00:00
return ;
2022-06-11 19:38:18 +00:00
CGhostItem * pGhost = & m_vGhosts [ s_SelectedIndex ] ;
2011-04-09 06:41:31 +00:00
2017-09-10 02:57:03 +00:00
CGhostItem * pOwnGhost = GetOwnGhost ( ) ;
int ReservedSlots = ! pGhost - > m_Own & & ! ( pOwnGhost & & pOwnGhost - > Active ( ) ) ;
2021-07-12 09:43:56 +00:00
if ( pGhost - > HasFile ( ) & & ( pGhost - > Active ( ) | | m_pClient - > m_Ghost . FreeSlots ( ) > ReservedSlots ) )
2011-02-04 17:25:04 +00:00
{
2017-09-10 01:48:22 +00:00
Status . VSplitRight ( 120.0f , & Status , & Button ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_GhostButton ;
2017-09-10 01:48:22 +00:00
const char * pText = pGhost - > Active ( ) ? Localize ( " Deactivate " ) : Localize ( " Activate " ) ;
2022-02-10 16:40:03 +00:00
if ( DoButton_Menu ( & s_GhostButton , pText , 0 , & Button ) | | ( DoubleClicked & & Input ( ) - > MouseDoubleClick ( ) ) )
2017-09-09 16:25:32 +00:00
{
2017-09-10 01:48:22 +00:00
if ( pGhost - > Active ( ) )
{
2021-07-12 09:43:56 +00:00
m_pClient - > m_Ghost . Unload ( pGhost - > m_Slot ) ;
2017-09-10 01:48:22 +00:00
pGhost - > m_Slot = - 1 ;
}
else
2021-07-12 09:43:56 +00:00
pGhost - > m_Slot = m_pClient - > m_Ghost . Load ( pGhost - > m_aFilename ) ;
2017-09-09 16:25:32 +00:00
}
2017-09-10 01:48:22 +00:00
Status . VSplitRight ( 5.0f , & Status , 0 ) ;
}
Status . VSplitRight ( 120.0f , & Status , & Button ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_DeleteButton ;
2017-09-10 01:48:22 +00:00
if ( DoButton_Menu ( & s_DeleteButton , Localize ( " Delete " ) , 0 , & Button ) )
{
if ( pGhost - > Active ( ) )
2021-07-12 09:43:56 +00:00
m_pClient - > m_Ghost . Unload ( pGhost - > m_Slot ) ;
2017-09-10 01:48:22 +00:00
DeleteGhostItem ( s_SelectedIndex ) ;
}
Status . VSplitRight ( 5.0f , & Status , 0 ) ;
2021-07-12 09:43:56 +00:00
bool Recording = m_pClient - > m_Ghost . GhostRecorder ( ) - > IsRecording ( ) ;
2017-09-10 01:48:22 +00:00
if ( ! pGhost - > HasFile ( ) & & ! Recording & & pGhost - > Active ( ) )
{
2022-07-16 13:32:06 +00:00
static CButtonContainer s_SaveButton ;
2017-09-10 01:48:22 +00:00
Status . VSplitRight ( 120.0f , & Status , & Button ) ;
if ( DoButton_Menu ( & s_SaveButton , Localize ( " Save " ) , 0 , & Button ) )
2021-07-12 09:43:56 +00:00
m_pClient - > m_Ghost . SaveGhost ( pGhost ) ;
2011-02-04 17:25:04 +00:00
}
}
2022-10-02 22:11:01 +00:00
void CMenus : : RenderIngameHint ( )
{
float Width = 300 * Graphics ( ) - > ScreenAspect ( ) ;
Graphics ( ) - > MapScreen ( 0 , 0 , Width , 300 ) ;
TextRender ( ) - > TextColor ( 1 , 1 , 1 , 1 ) ;
2022-10-07 17:03:20 +00:00
TextRender ( ) - > Text ( 0x0 , 5 , 280 , 5 , Localize ( " Menu opened. Press Esc key again to close menu. " ) , - 1.0f ) ;
2022-10-02 22:11:01 +00:00
UI ( ) - > MapScreen ( ) ;
}