2023-09-06 02:25:25 +02:00
//=========== (C) Copyright 1996-2001 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose: Client DLL VGUI Viewport
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================
# include<VGUI_Cursor.h>
# include<VGUI_Frame.h>
# include<VGUI_Label.h>
# include<VGUI_Surface.h>
# include<VGUI_BorderLayout.h>
# include<VGUI_Panel.h>
# include<VGUI_ImagePanel.h>
# include<VGUI_Button.h>
# include<VGUI_ActionSignal.h>
# include<VGUI_InputSignal.h>
# include<VGUI_MenuSeparator.h>
# include<VGUI_TextPanel.h>
# include<VGUI_LoweredBorder.h>
# include<VGUI_LineBorder.h>
# include<VGUI_BitmapTGA.h>
# include<VGUI_Scheme.h>
# include<VGUI_Font.h>
# include<VGUI_App.h>
# include<VGUI_BuildGroup.h>
# include "hud.h"
# include "cl_util.h"
# include "camera.h"
# include "kbutton.h"
# include "cvardef.h"
# include "usercmd.h"
# include "const.h"
# include "camera.h"
# include "in_defs.h"
# include "parsemsg.h"
# include "pm_shared.h"
# include "../engine/keydefs.h"
# include "demo.h"
# include "demo_api.h"
# include "tw_vgui.h"
# include "vgui_int.h"
# include "vgui_TheWastesViewport.h"
# include "vgui_ServerBrowser.h"
# include "vgui_ScorePanel.h"
# include "tw_common.h"
extern int g_iVisibleMouse ;
class CCommandMenu ;
int g_iPlayerClass ;
int g_iTeamNumber ;
int g_iUser1 ;
int g_iUser2 ;
int g_iUser3 ;
// Scoreboard positions
# define SBOARD_INDENT_X XRES(104)
# define SBOARD_INDENT_Y YRES(40)
// low-res scoreboard indents
# define SBOARD_INDENT_X_512 30
# define SBOARD_INDENT_Y_512 30
# define SBOARD_INDENT_X_400 0
# define SBOARD_INDENT_Y_400 20
void IN_ResetMouse ( void ) ;
extern CMenuPanel * CMessageWindowPanel_Create ( const char * szMOTD , const char * szTitle , int iShadeFullscreen , int iRemoveMe , int iTextType , int x , int y , int wide , int tall ) ;
extern CMenuPanel * CItemSelectionPanel_Create ( int x , int y , int wide , int tall ) ;
using namespace vgui ;
// Team Colors
int iNumberOfTeamColors = 6 ;
int iTeamColors [ 5 ] [ 3 ] =
{
{ 255 , 255 , 255 } , // (default)
{ 125 , 165 , 210 } , // Blue
{ 200 , 90 , 70 } , // Red
{ 225 , 205 , 45 } , // Yellow
{ 145 , 215 , 140 } , // Green
} ;
// This maps class numbers to the Invalid Class bit.
// This is needed for backwards compatability in maps that were finished before
// all the classes were in TF. Hence the wacky sequence.
int sTFValidClassInts [ ] =
{
0 ,
TF_ILL_SCOUT ,
TF_ILL_SNIPER ,
TF_ILL_SOLDIER ,
TF_ILL_DEMOMAN ,
TF_ILL_MEDIC ,
TF_ILL_HVYWEP ,
TF_ILL_PYRO ,
TF_ILL_SPY ,
TF_ILL_ENGINEER ,
TF_ILL_RANDOMPC ,
} ;
// Get the name of TGA file, based on GameDir
char * GetVGUITGAName ( const char * pszName )
{
int i ;
char sz [ 256 ] ;
static char gd [ 256 ] ;
const char * gamedir ;
if ( ScreenWidth < 640 )
i = 320 ;
else
i = 640 ;
sprintf ( sz , pszName , i ) ;
gamedir = gEngfuncs . pfnGetGameDirectory ( ) ;
sprintf ( gd , " %s/gfx/vgui/%s.tga " , gamedir , sz ) ;
return gd ;
}
//================================================================
// COMMAND MENU
//================================================================
void CCommandMenu : : AddButton ( CommandButton * pButton )
{
if ( m_iButtons > = MAX_BUTTONS )
return ;
m_aButtons [ m_iButtons ] = pButton ;
m_iButtons + + ;
pButton - > setParent ( this ) ;
pButton - > setFont ( Scheme : : sf_primary3 ) ;
// give the button a default key binding
if ( m_iButtons < 10 )
{
pButton - > setBoundKey ( m_iButtons + ' 0 ' ) ;
}
else if ( m_iButtons = = 10 )
{
pButton - > setBoundKey ( ' 0 ' ) ;
}
}
//-----------------------------------------------------------------------------
// Purpose: Tries to find a button that has a key bound to the input, and
// presses the button if found
// Input : keyNum - the character number of the input key
// Output : Returns true if the command menu should close, false otherwise
//-----------------------------------------------------------------------------
bool CCommandMenu : : KeyInput ( int keyNum )
{
// loop through all our buttons looking for one bound to keyNum
for ( int i = 0 ; i < m_iButtons ; i + + )
{
if ( ! m_aButtons [ i ] - > IsNotValid ( ) )
{
if ( m_aButtons [ i ] - > getBoundKey ( ) = = keyNum )
{
// hit the button
if ( m_aButtons [ i ] - > GetSubMenu ( ) )
{
// open the sub menu
gViewPort - > SetCurrentCommandMenu ( m_aButtons [ i ] - > GetSubMenu ( ) ) ;
return false ;
}
else
{
// run the bound command
m_aButtons [ i ] - > fireActionSignal ( ) ;
return true ;
}
}
}
}
return false ;
}
//-----------------------------------------------------------------------------
// Purpose: clears the current menus buttons of any armed (highlighted)
// state, and all their sub buttons
//-----------------------------------------------------------------------------
void CCommandMenu : : ClearButtonsOfArmedState ( void )
{
for ( int i = 0 ; i < GetNumButtons ( ) ; i + + )
{
m_aButtons [ i ] - > setArmed ( false ) ;
if ( m_aButtons [ i ] - > GetSubMenu ( ) )
{
m_aButtons [ i ] - > GetSubMenu ( ) - > ClearButtonsOfArmedState ( ) ;
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pSubMenu -
// Output : CommandButton
//-----------------------------------------------------------------------------
CommandButton * CCommandMenu : : FindButtonWithSubmenu ( CCommandMenu * pSubMenu )
{
for ( int i = 0 ; i < GetNumButtons ( ) ; i + + )
{
if ( m_aButtons [ i ] - > GetSubMenu ( ) = = pSubMenu )
return m_aButtons [ i ] ;
}
return NULL ;
}
// Recalculate the visible buttons
bool CCommandMenu : : RecalculateVisibles ( int iNewYPos , bool bHideAll )
{
int iCurrentY = 0 ;
int iXPos , iYPos ;
bool bHasButton = false ;
if ( iNewYPos )
setPos ( _pos [ 0 ] , iNewYPos ) ;
// Cycle through all the buttons in this menu, and see which will be visible
for ( int i = 0 ; i < m_iButtons ; i + + )
{
int iClass = m_aButtons [ i ] - > GetPlayerClass ( ) ;
if ( ( iClass & & iClass ! = g_iPlayerClass ) | | ( m_aButtons [ i ] - > IsNotValid ( ) ) | | bHideAll )
{
m_aButtons [ i ] - > setVisible ( false ) ;
if ( m_aButtons [ i ] - > GetSubMenu ( ) ! = NULL )
{
( m_aButtons [ i ] - > GetSubMenu ( ) ) - > RecalculateVisibles ( _pos [ 1 ] + iCurrentY , true ) ;
}
}
else
{
// If it's got a submenu, force it to check visibilities
if ( m_aButtons [ i ] - > GetSubMenu ( ) ! = NULL )
{
if ( ! ( m_aButtons [ i ] - > GetSubMenu ( ) ) - > RecalculateVisibles ( _pos [ 1 ] + iCurrentY , false ) )
{
// The submenu had no visible buttons, so don't display this button
m_aButtons [ i ] - > setVisible ( false ) ;
continue ;
}
}
m_aButtons [ i ] - > setVisible ( true ) ;
// Make sure it's at the right Y position
m_aButtons [ i ] - > getPos ( iXPos , iYPos ) ;
m_aButtons [ i ] - > setPos ( iXPos , iCurrentY ) ;
iCurrentY + = BUTTON_SIZE_Y - 1 ;
bHasButton = true ;
}
}
// Set Size
setSize ( _size [ 0 ] , iCurrentY + 1 ) ;
return bHasButton ;
}
// Make sure all submenus can fit on the screen
void CCommandMenu : : RecalculatePositions ( int iYOffset )
{
int iNewYPos = _pos [ 1 ] + iYOffset ;
int iAdjust = 0 ;
// Calculate if this is going to fit onscreen, and shuffle it up if it won't
int iBottom = iNewYPos + _size [ 1 ] ;
if ( iBottom > ScreenHeight )
{
// Move in increments of button sizes
while ( iAdjust < ( iBottom - ScreenHeight ) )
{
iAdjust + = BUTTON_SIZE_Y - 1 ;
}
iNewYPos - = iAdjust ;
// Make sure it doesn't move off the top of the screen (the menu's too big to fit it all)
if ( iNewYPos < 0 )
{
iAdjust - = ( 0 - iNewYPos ) ;
iNewYPos = 0 ;
}
}
// We need to force all menus below this one to update their positions now, because they
// might have submenus riding off buttons in this menu that have just shifted.
for ( int i = 0 ; i < m_iButtons ; i + + )
m_aButtons [ i ] - > UpdateSubMenus ( iAdjust ) ;
setPos ( _pos [ 0 ] , iNewYPos ) ;
}
// Make this menu and all menus above it in the chain visible
void CCommandMenu : : MakeVisible ( CCommandMenu * pChildMenu )
{
/*
// Push down the button leading to the child menu
for ( int i = 0 ; i < m_iButtons ; i + + )
{
if ( ( pChildMenu ! = NULL ) & & ( m_aButtons [ i ] - > GetSubMenu ( ) = = pChildMenu ) )
{
m_aButtons [ i ] - > setArmed ( true ) ;
}
else
{
m_aButtons [ i ] - > setArmed ( false ) ;
}
}
*/
setVisible ( true ) ;
if ( m_pParentMenu )
m_pParentMenu - > MakeVisible ( this ) ;
}
//================================================================
// CreateSubMenu
CCommandMenu * TheWastesViewport : : CreateSubMenu ( CommandButton * pButton , CCommandMenu * pParentMenu )
{
int iXPos = 0 ;
int iYPos = 0 ;
int iWide = CMENU_SIZE_X ;
int iTall = 0 ;
if ( pParentMenu )
{
iXPos = pParentMenu - > GetXOffset ( ) + CMENU_SIZE_X - 1 ;
iYPos = pParentMenu - > GetYOffset ( ) + BUTTON_SIZE_Y * ( m_pCurrentCommandMenu - > GetNumButtons ( ) - 1 ) ;
}
CCommandMenu * pMenu = new CCommandMenu ( pParentMenu , iXPos , iYPos , iWide , iTall ) ;
pMenu - > setParent ( this ) ;
pButton - > AddSubMenu ( pMenu ) ;
pButton - > setFont ( Scheme : : sf_primary3 ) ;
// Create the Submenu-open signal
InputSignal * pISignal = new CMenuHandler_PopupSubMenuInput ( pButton , pMenu ) ;
pButton - > addInputSignal ( pISignal ) ;
// Put a > to show it's a submenu
CImageLabel * pLabel = new CImageLabel ( " arrow " , CMENU_SIZE_X - SUBMENU_SIZE_X , SUBMENU_SIZE_Y ) ;
pLabel - > setParent ( pButton ) ;
pLabel - > addInputSignal ( pISignal ) ;
// Reposition
pLabel - > getPos ( iXPos , iYPos ) ;
pLabel - > setPos ( CMENU_SIZE_X - pLabel - > getImageWide ( ) , ( BUTTON_SIZE_Y - pLabel - > getImageTall ( ) ) / 2 ) ;
// Create the mouse off signal for the Label too
if ( ! pButton - > m_bNoHighlight )
pLabel - > addInputSignal ( new CHandler_CommandButtonHighlight ( pButton ) ) ;
return pMenu ;
}
//-----------------------------------------------------------------------------
// Purpose: Makes sure the memory allocated for TheWastesViewport is nulled out
// Input : stAllocateBlock -
// Output : void *
//-----------------------------------------------------------------------------
void * TheWastesViewport : : operator new ( size_t stAllocateBlock )
{
// void *mem = Panel::operator new( stAllocateBlock );
void * mem = : : operator new ( stAllocateBlock ) ;
memset ( mem , 0 , stAllocateBlock ) ;
return mem ;
}
//-----------------------------------------------------------------------------
// Purpose: InputSignal handler for the main viewport
//-----------------------------------------------------------------------------
class CViewPortInputHandler : public InputSignal
{
public :
bool bPressed ;
CViewPortInputHandler ( )
{
}
virtual void cursorMoved ( int x , int y , Panel * panel ) { }
virtual void cursorEntered ( Panel * panel ) { }
virtual void cursorExited ( Panel * panel ) { }
virtual void mousePressed ( MouseCode code , Panel * panel )
{
if ( code ! = MOUSE_LEFT )
{
// send a message to close the command menu
// this needs to be a message, since a direct call screws the timing
gEngfuncs . pfnClientCmd ( " ForceCloseCommandMenu \n " ) ;
}
}
virtual void mouseReleased ( MouseCode code , Panel * panel )
{
}
virtual void mouseDoublePressed ( MouseCode code , Panel * panel ) { }
virtual void mouseWheeled ( int delta , Panel * panel ) { }
virtual void keyPressed ( KeyCode code , Panel * panel ) { }
virtual void keyTyped ( KeyCode code , Panel * panel ) { }
virtual void keyReleased ( KeyCode code , Panel * panel ) { }
virtual void keyFocusTicked ( Panel * panel ) { }
} ;
//================================================================
TheWastesViewport : : TheWastesViewport ( int x , int y , int wide , int tall ) : Panel ( x , y , wide , tall ) , m_SchemeManager ( wide , tall )
{
gViewPort = this ;
m_iInitialized = false ;
m_flGameTimeDelay = 0.0f ;
m_pTeamMenu = NULL ;
m_pScoreBoard = NULL ;
m_pSpectatorMenu = NULL ;
m_pCurrentMenu = NULL ;
m_pCurrentCommandMenu = NULL ;
m_pGameInfoMenu = NULL ;
Initialize ( ) ;
addInputSignal ( new CViewPortInputHandler ) ;
int r , g , b , a ;
Scheme * pScheme = App : : getInstance ( ) - > getScheme ( ) ;
// primary text color
// Get the colors
//!! two different types of scheme here, need to integrate
SchemeHandle_t hPrimaryScheme = m_SchemeManager . getSchemeHandle ( " Primary Button Text " ) ;
{
// font
pScheme - > setFont ( Scheme : : sf_primary1 , m_SchemeManager . getFont ( hPrimaryScheme ) ) ;
// text color
m_SchemeManager . getFgColor ( hPrimaryScheme , r , g , b , a ) ;
pScheme - > setColor ( Scheme : : sc_primary1 , r , g , b , a ) ; // sc_primary1 is non-transparent orange
// background color (transparent black)
m_SchemeManager . getBgColor ( hPrimaryScheme , r , g , b , a ) ;
pScheme - > setColor ( Scheme : : sc_primary3 , r , g , b , a ) ;
// armed foreground color
m_SchemeManager . getFgArmedColor ( hPrimaryScheme , r , g , b , a ) ;
pScheme - > setColor ( Scheme : : sc_secondary2 , r , g , b , a ) ;
// armed background color
m_SchemeManager . getBgArmedColor ( hPrimaryScheme , r , g , b , a ) ;
pScheme - > setColor ( Scheme : : sc_primary2 , r , g , b , a ) ;
//!! need to get this color from scheme file
// used for orange borders around buttons
m_SchemeManager . getBorderColor ( hPrimaryScheme , r , g , b , a ) ;
// pScheme->setColor(Scheme::sc_secondary1, r, g, b, a );
pScheme - > setColor ( Scheme : : sc_secondary1 , 255 * 0.7 , 170 * 0.7 , 0 , 0 ) ;
}
// Change the second primary font (used in the scoreboard)
SchemeHandle_t hScoreboardScheme = m_SchemeManager . getSchemeHandle ( " Scoreboard Text " ) ;
{
pScheme - > setFont ( Scheme : : sf_primary2 , m_SchemeManager . getFont ( hScoreboardScheme ) ) ;
}
// Change the third primary font (used in command menu)
SchemeHandle_t hCommandMenuScheme = m_SchemeManager . getSchemeHandle ( " CommandMenu Text " ) ;
{
pScheme - > setFont ( Scheme : : sf_primary3 , m_SchemeManager . getFont ( hCommandMenuScheme ) ) ;
}
App : : getInstance ( ) - > setScheme ( pScheme ) ;
// VGUI MENUS
CreateTeamMenu ( ) ;
CreateScoreBoard ( ) ;
CreateCommandMenu ( ) ;
CreateServerBrowser ( ) ;
CreateSpectatorMenu ( ) ;
CreateGameInfoMenu ( ) ;
}
//-----------------------------------------------------------------------------
// Purpose: Called everytime a new level is started. Viewport clears out it's data.
//-----------------------------------------------------------------------------
void TheWastesViewport : : Initialize ( void )
{
// Force each menu to Initialize
if ( m_pTeamMenu )
{
m_pTeamMenu - > Initialize ( ) ;
}
if ( m_pScoreBoard )
{
m_pScoreBoard - > Initialize ( ) ;
HideScoreBoard ( ) ;
}
if ( m_pSpectatorMenu )
{
// Spectator menu doesn't need initializing
m_pSpectatorMenu - > setVisible ( false ) ;
}
if ( m_pGameInfoMenu )
{
m_pGameInfoMenu - > setVisible ( false ) ;
}
// Make sure all menus are hidden
HideVGUIMenu ( ) ;
HideCommandMenu ( ) ;
// Clear out some data
m_iGotAllMOTD = true ;
m_iRandomPC = false ;
m_flScoreBoardLastUpdated = 0 ;
// reset player info
g_iPlayerClass = 0 ;
g_iTeamNumber = 0 ;
strcpy ( m_sMapName , " " ) ;
strcpy ( m_szServerName , " " ) ;
for ( int i = 0 ; i < 5 ; i + + )
{
m_iValidClasses [ i ] = 0 ;
strcpy ( m_sTeamNames [ i ] , " " ) ;
}
App : : getInstance ( ) - > setCursorOveride ( App : : getInstance ( ) - > getScheme ( ) - > getCursor ( Scheme : : SchemeCursor : : scu_none ) ) ;
}
class CException ;
//-----------------------------------------------------------------------------
// Purpose: Read the Command Menu structure from the txt file and create the menu.
//-----------------------------------------------------------------------------
void TheWastesViewport : : CreateCommandMenu ( void )
{
// COMMAND MENU
// Create the root of the Command Menu
m_pCommandMenus [ 0 ] = new CCommandMenu ( NULL , 0 , CMENU_TOP , CMENU_SIZE_X , 300 ) ; // This will be resized once we know how many items are in it
m_pCommandMenus [ 0 ] - > setParent ( this ) ;
m_pCommandMenus [ 0 ] - > setVisible ( false ) ;
m_iNumMenus = 1 ;
m_iCurrentTeamNumber = m_iUser1 = m_iUser2 = m_iUser3 = 0 ;
// Read Command Menu from the txt file
char token [ 1024 ] ;
char * pfile = ( char * ) gEngfuncs . COM_LoadFile ( " commandmenu.txt " , 5 , NULL ) ;
if ( ! pfile )
{
gEngfuncs . Con_DPrintf ( " Unable to open commandmenu.txt \n " ) ;
SetCurrentCommandMenu ( NULL ) ;
return ;
}
try
{
// First, read in the localisation strings
// Now start parsing the menu structure
m_pCurrentCommandMenu = m_pCommandMenus [ 0 ] ;
char szLastButtonText [ 32 ] = " file start " ;
pfile = gEngfuncs . COM_ParseFile ( pfile , token ) ;
while ( ( strlen ( token ) > 0 ) & & ( m_iNumMenus < MAX_MENUS ) )
{
// Keep looping until we hit the end of this menu
while ( token [ 0 ] ! = ' } ' & & ( strlen ( token ) > 0 ) )
{
char cText [ 32 ] = " " ;
char cBoundKey [ 32 ] = " " ;
char cCustom [ 32 ] = " " ;
static const int cCommandLength = 128 ;
char cCommand [ cCommandLength ] = " " ;
char szMap [ MAX_MAPNAME ] = " " ;
int iPlayerClass = 0 ;
int iCustom = false ;
int iTeamOnly = 0 ;
bool bGetExtraToken = true ;
CommandButton * pButton = NULL ;
// We should never be here without a Command Menu
if ( ! m_pCurrentCommandMenu )
{
gEngfuncs . Con_Printf ( " Error in Commandmenu.txt file after '%s'. \n " , szLastButtonText ) ;
m_iInitialized = false ;
return ;
}
// token should already be the bound key, or the custom name
strncpy ( cCustom , token , 32 ) ;
cCustom [ 31 ] = ' \0 ' ;
// See if it's a custom button
if ( ! strcmp ( cCustom , " CUSTOM " ) )
{
iCustom = true ;
// Get the next token
pfile = gEngfuncs . COM_ParseFile ( pfile , token ) ;
}
// See if it's a map
else if ( ! strcmp ( cCustom , " MAP " ) )
{
// Get the mapname
pfile = gEngfuncs . COM_ParseFile ( pfile , token ) ;
strncpy ( szMap , token , MAX_MAPNAME ) ;
szMap [ MAX_MAPNAME - 1 ] = ' \0 ' ;
// Get the next token
pfile = gEngfuncs . COM_ParseFile ( pfile , token ) ;
}
else if ( ! strncmp ( cCustom , " TEAM " , 4 ) ) // TEAM1, TEAM2, TEAM3, TEAM4
{
// make it a team only button
iTeamOnly = atoi ( cCustom + 4 ) ;
// Get the next token
pfile = gEngfuncs . COM_ParseFile ( pfile , token ) ;
}
/* else
{
// See if it's a Class
for ( int i = 1 ; i < = PC_ENGINEER ; i + + )
{
if ( ! strcmp ( token , sTFClasses [ i ] ) )
{
// Save it off
iPlayerClass = i ;
// Get the button text
pfile = gEngfuncs . COM_ParseFile ( pfile , token ) ;
break ;
}
}
}
*/
// Get the button bound key
strncpy ( cBoundKey , token , 32 ) ;
cText [ 31 ] = ' \0 ' ;
// Get the button text
pfile = gEngfuncs . COM_ParseFile ( pfile , token ) ;
strncpy ( cText , token , 32 ) ;
cText [ 31 ] = ' \0 ' ;
// save off the last button text we've come across (for error reporting)
strcpy ( szLastButtonText , cText ) ;
// Get the button command
pfile = gEngfuncs . COM_ParseFile ( pfile , token ) ;
strncpy ( cCommand , token , cCommandLength ) ;
cCommand [ cCommandLength - 1 ] = ' \0 ' ;
// Custom button handling
if ( iCustom )
{
pButton = CreateCustomButton ( cText , cCommand ) ;
// Get the next token to see if we're a menu
pfile = gEngfuncs . COM_ParseFile ( pfile , token ) ;
if ( token [ 0 ] = = ' { ' )
{
strcpy ( cCommand , token ) ;
}
else
{
bGetExtraToken = false ;
}
}
else if ( szMap [ 0 ] ! = ' \0 ' )
{
// create a map button
pButton = new MapButton ( szMap , cText , 0 , BUTTON_SIZE_Y * m_pCurrentCommandMenu - > GetNumButtons ( ) , CMENU_SIZE_X , BUTTON_SIZE_Y ) ;
}
else if ( iTeamOnly )
{
// button that only shows up if the player is on team iTeamOnly
pButton = new TeamOnlyCommandButton ( iTeamOnly , cText , 0 , BUTTON_SIZE_Y * m_pCurrentCommandMenu - > GetNumButtons ( ) , CMENU_SIZE_X , BUTTON_SIZE_Y ) ;
}
else
{
// normal button
pButton = new CommandButton ( iPlayerClass , cText , 0 , BUTTON_SIZE_Y * m_pCurrentCommandMenu - > GetNumButtons ( ) , CMENU_SIZE_X , BUTTON_SIZE_Y ) ;
}
// add the button into the command menu
if ( pButton )
{
m_pCurrentCommandMenu - > AddButton ( pButton ) ;
pButton - > setBoundKey ( cBoundKey [ 0 ] ) ;
pButton - > setParentMenu ( m_pCurrentCommandMenu ) ;
// Override font in CommandMenu
pButton - > setFont ( Scheme : : sf_primary3 ) ;
}
// Find out if it's a submenu or a button we're dealing with
if ( cCommand [ 0 ] = = ' { ' )
{
if ( m_iNumMenus > = MAX_MENUS )
{
gEngfuncs . Con_Printf ( " Too many menus in commandmenu.txt past '%s' \n " , szLastButtonText ) ;
}
else
{
// Create the menu
m_pCommandMenus [ m_iNumMenus ] = CreateSubMenu ( pButton , m_pCurrentCommandMenu ) ;
m_pCurrentCommandMenu = m_pCommandMenus [ m_iNumMenus ] ;
m_iNumMenus + + ;
}
}
else if ( ! iCustom )
{
// Create the button and attach it to the current menu
pButton - > addActionSignal ( new CMenuHandler_StringCommand ( cCommand ) ) ;
// Create an input signal that'll popup the current menu
pButton - > addInputSignal ( new CMenuHandler_PopupSubMenuInput ( pButton , m_pCurrentCommandMenu ) ) ;
}
// Get the next token
if ( bGetExtraToken )
{
pfile = gEngfuncs . COM_ParseFile ( pfile , token ) ;
}
}
// Move back up a menu
m_pCurrentCommandMenu = m_pCurrentCommandMenu - > GetParentMenu ( ) ;
pfile = gEngfuncs . COM_ParseFile ( pfile , token ) ;
}
}
catch ( CException * e )
{
e ;
//e->Delete();
e = NULL ;
m_iInitialized = false ;
return ;
}
SetCurrentMenu ( NULL ) ;
SetCurrentCommandMenu ( NULL ) ;
gEngfuncs . COM_FreeFile ( pfile ) ;
m_iInitialized = true ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pButtonText -
// *pButtonName -
// Output : CommandButton
//-----------------------------------------------------------------------------
CommandButton * TheWastesViewport : : CreateCustomButton ( char * pButtonText , char * pButtonName )
{
CommandButton * pButton = NULL ;
CCommandMenu * pMenu = NULL ;
// ChangeTeam
if ( ! strcmp ( pButtonName , " !CHANGETEAM " ) )
{
// ChangeTeam Submenu
pButton = new CommandButton ( pButtonText , 0 , BUTTON_SIZE_Y * 2 , CMENU_SIZE_X , BUTTON_SIZE_Y ) ;
// Create the submenu
pMenu = CreateSubMenu ( pButton , m_pCurrentCommandMenu ) ;
m_pCommandMenus [ m_iNumMenus ] = pMenu ;
m_iNumMenus + + ;
// ChangeTeam buttons
for ( int i = 0 ; i < 4 ; i + + )
{
char sz [ 256 ] ;
sprintf ( sz , " jointeam %d " , i + 1 ) ;
m_pTeamButtons [ i ] = new TeamButton ( i + 1 , " teamname " , 0 , BUTTON_SIZE_Y , CMENU_SIZE_X , BUTTON_SIZE_Y ) ;
m_pTeamButtons [ i ] - > addActionSignal ( new CMenuHandler_StringCommandWatch ( sz ) ) ;
pMenu - > AddButton ( m_pTeamButtons [ i ] ) ;
}
// Auto Assign button
m_pTeamButtons [ 4 ] = new TeamButton ( 5 , gHUD . m_TextMessage . BufferedLocaliseTextString ( " #Team_AutoAssign " ) , 0 , BUTTON_SIZE_Y , CMENU_SIZE_X , BUTTON_SIZE_Y ) ;
m_pTeamButtons [ 4 ] - > addActionSignal ( new CMenuHandler_StringCommand ( " jointeam 5 " ) ) ;
pMenu - > AddButton ( m_pTeamButtons [ 4 ] ) ;
// Spectate button
m_pTeamButtons [ 5 ] = new SpectateButton ( CHudTextMessage : : BufferedLocaliseTextString ( " #Menu_Spectate " ) , 0 , BUTTON_SIZE_Y , CMENU_SIZE_X , BUTTON_SIZE_Y , false ) ;
m_pTeamButtons [ 5 ] - > addActionSignal ( new CMenuHandler_StringCommand ( " spectate " ) ) ;
pMenu - > AddButton ( m_pTeamButtons [ 5 ] ) ;
}
// Map Briefing
else if ( ! strcmp ( pButtonName , " !MAPBRIEFING " ) )
{
pButton = new CommandButton ( pButtonText , 0 , BUTTON_SIZE_Y * m_pCurrentCommandMenu - > GetNumButtons ( ) , CMENU_SIZE_X , BUTTON_SIZE_Y ) ;
pButton - > addActionSignal ( new CMenuHandler_TextWindow ( MENU_MAPBRIEFING ) ) ;
// Create an input signal that'll popup the current menu
pButton - > addInputSignal ( new CMenuHandler_PopupSubMenuInput ( pButton , m_pCurrentCommandMenu ) ) ;
}
else if ( ! strcmp ( pButtonName , " !SERVERINFO " ) )
{
pButton = new ClassButton ( 0 , pButtonText , 0 , BUTTON_SIZE_Y * m_pCurrentCommandMenu - > GetNumButtons ( ) , CMENU_SIZE_X , BUTTON_SIZE_Y , false ) ;
pButton - > addActionSignal ( new CMenuHandler_TextWindow ( MENU_INTRO ) ) ;
// Create an input signal that'll popup the current menu
pButton - > addInputSignal ( new CMenuHandler_PopupSubMenuInput ( pButton , m_pCurrentCommandMenu ) ) ;
}
return pButton ;
}
void TheWastesViewport : : ToggleServerBrowser ( )
{
if ( ! m_iInitialized )
return ;
if ( ! m_pServerBrowser )
return ;
if ( m_pServerBrowser - > isVisible ( ) )
{
m_pServerBrowser - > setVisible ( false ) ;
}
else
{
m_pServerBrowser - > setVisible ( true ) ;
}
UpdateCursorState ( ) ;
}
//=======================================================================
void TheWastesViewport : : ShowCommandMenu ( )
{
if ( ! m_iInitialized )
return ;
// Not visible while undefined
if ( g_iPlayerClass = = 0 )
return ;
// is the command menu open?
if ( m_pCurrentCommandMenu )
{
HideCommandMenu ( ) ;
return ;
}
// Not visible while in intermission
if ( gHUD . m_iIntermission )
return ;
// Recalculate visible menus
UpdateCommandMenu ( ) ;
HideVGUIMenu ( ) ;
SetCurrentCommandMenu ( m_pCommandMenus [ 0 ] ) ;
m_flMenuOpenTime = gHUD . m_flTime ;
UpdateCursorState ( ) ;
// get command menu parameters
for ( int i = 2 ; i < gEngfuncs . Cmd_Argc ( ) ; i + + )
{
const char * param = gEngfuncs . Cmd_Argv ( i - 1 ) ;
if ( param )
{
if ( m_pCurrentCommandMenu - > KeyInput ( param [ 0 ] ) )
{
// kill the menu open time, since the key input is final
HideCommandMenu ( ) ;
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Handles the key input of "-commandmenu"
// Input :
//-----------------------------------------------------------------------------
void TheWastesViewport : : InputSignalHideCommandMenu ( )
{
if ( ! m_iInitialized )
return ;
// if they've just tapped the command menu key, leave it open
if ( ( m_flMenuOpenTime + 0.3 ) > gHUD . m_flTime )
return ;
HideCommandMenu ( ) ;
}
//-----------------------------------------------------------------------------
// Purpose: Hides the command menu
//-----------------------------------------------------------------------------
void TheWastesViewport : : HideCommandMenu ( void )
{
if ( ! m_iInitialized )
return ;
if ( m_pCommandMenus [ 0 ] )
{
m_pCommandMenus [ 0 ] - > ClearButtonsOfArmedState ( ) ;
}
m_flMenuOpenTime = 0.0f ;
SetCurrentCommandMenu ( NULL ) ;
UpdateCursorState ( ) ;
}
//-----------------------------------------------------------------------------
// Purpose: Bring up the scoreboard
//-----------------------------------------------------------------------------
void TheWastesViewport : : ShowScoreBoard ( void )
{
if ( m_pScoreBoard )
{
// No Scoreboard in single-player
if ( gEngfuncs . GetMaxClients ( ) > 1 )
{
m_pScoreBoard - > Open ( ) ;
UpdateCursorState ( ) ;
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Returns true if the scoreboard is up
//-----------------------------------------------------------------------------
bool TheWastesViewport : : IsScoreBoardVisible ( void )
{
if ( m_pScoreBoard )
return m_pScoreBoard - > isVisible ( ) ;
return false ;
}
//-----------------------------------------------------------------------------
// Purpose: Hide the scoreboard
//-----------------------------------------------------------------------------
void TheWastesViewport : : HideScoreBoard ( void )
{
// Prevent removal of scoreboard during intermission
if ( gHUD . m_iIntermission )
return ;
if ( m_pScoreBoard )
{
m_pScoreBoard - > setVisible ( false ) ;
GetClientVoiceMgr ( ) - > StopSquelchMode ( ) ;
UpdateCursorState ( ) ;
}
}
// Set the submenu of the Command Menu
void TheWastesViewport : : SetCurrentCommandMenu ( CCommandMenu * pNewMenu )
{
for ( int i = 0 ; i < m_iNumMenus ; i + + )
m_pCommandMenus [ i ] - > setVisible ( false ) ;
m_pCurrentCommandMenu = pNewMenu ;
if ( m_pCurrentCommandMenu )
m_pCurrentCommandMenu - > MakeVisible ( NULL ) ;
}
void TheWastesViewport : : UpdateCommandMenu ( )
{
m_pCommandMenus [ 0 ] - > RecalculateVisibles ( 0 , false ) ;
m_pCommandMenus [ 0 ] - > RecalculatePositions ( 0 ) ;
}
void TheWastesViewport : : UpdateSpectatorMenu ( )
{
char helpString1 [ 128 ] ;
char helpString2 [ 128 ] ;
int mode ;
m_iUser1 = g_iUser1 ;
m_iUser2 = g_iUser2 ;
m_iUser3 = g_iUser3 ;
if ( ! m_pSpectatorMenu )
return ;
if ( gEngfuncs . IsSpectateOnly ( ) )
{
mode = gHUD . m_Spectator . m_iMainMode ; // spec mode is set client side
sprintf ( helpString2 , " #Spec_Only_Help " ) ;
}
else
{
// spec mode is given by server
mode = m_iUser1 ;
// set normal help text
sprintf ( helpString2 , " #Spec_Help " ) ;
}
if ( mode & & ( gEngfuncs . IsSpectateOnly ( ) ! = 2 ) ) // don't draw in dev_overview mode
{
m_pSpectatorMenu - > setVisible ( true ) ;
// check if we're locked onto a target, show the player's name
if ( ( m_iUser2 > 0 ) & & ( m_iUser2 < = gEngfuncs . GetMaxClients ( ) ) )
{
// Locked onto a target, show the player's name
if ( g_PlayerInfoList [ m_iUser2 ] . name ! = NULL )
sprintf ( helpString1 , " #Spec_Mode%d : %s " , mode , g_PlayerInfoList [ m_iUser2 ] . name ) ;
else
sprintf ( helpString1 , " #Spec_Mode%d " , mode ) ;
}
else
{
sprintf ( helpString1 , " #Spec_Mode%d " , mode ) ;
}
if ( m_iUser1 = = OBS_DIRECTED )
{
char tempString [ 128 ] ;
sprintf ( tempString , " #Directed %s " , helpString1 ) ;
strcpy ( helpString1 , tempString ) ;
}
m_pSpectatorLabel - > setText ( CHudTextMessage : : BufferedLocaliseTextString ( helpString1 ) ) ;
m_pSpectatorHelpLabel - > setText ( CHudTextMessage : : BufferedLocaliseTextString ( helpString2 ) ) ;
}
else
{
m_pSpectatorMenu - > setVisible ( false ) ;
}
}
void TheWastesViewport : : UpdateGameInfoMenu ( )
{
if ( ! m_pGameInfoMenu )
return ;
if ( gHUD . m_flTime > m_flGameTimeDelay )
{
m_pGameInfoMenu - > setVisible ( false ) ;
return ;
}
m_pGameInfoMenu - > setVisible ( true ) ;
// Update time
m_pGameTimeLabel - > setText ( " %s %1.0f " , CHudTextMessage : : BufferedLocaliseTextString ( " #GameInfo_LMS_RoundDelay " ) ,
m_flGameTimeDelay - gHUD . m_flTime ) ;
}
//======================================================================
void TheWastesViewport : : CreateScoreBoard ( void )
{
int xdent = SBOARD_INDENT_X , ydent = SBOARD_INDENT_Y ;
if ( ScreenWidth = = 512 )
{
xdent = SBOARD_INDENT_X_512 ;
ydent = SBOARD_INDENT_Y_512 ;
}
else if ( ScreenWidth = = 400 )
{
xdent = SBOARD_INDENT_X_400 ;
ydent = SBOARD_INDENT_Y_400 ;
}
m_pScoreBoard = new ScorePanel ( xdent , ydent , ScreenWidth - ( xdent * 2 ) , ScreenHeight - ( ydent * 2 ) ) ;
m_pScoreBoard - > setParent ( this ) ;
m_pScoreBoard - > setVisible ( false ) ;
}
void TheWastesViewport : : CreateServerBrowser ( void )
{
m_pServerBrowser = new ServerBrowser ( 0 , 0 , ScreenWidth , ScreenHeight ) ;
m_pServerBrowser - > setParent ( this ) ;
m_pServerBrowser - > setVisible ( false ) ;
}
//======================================================================
// Set the VGUI Menu
void TheWastesViewport : : SetCurrentMenu ( CMenuPanel * pMenu )
{
m_pCurrentMenu = pMenu ;
if ( m_pCurrentMenu )
{
// Don't open menus in demo playback
if ( gEngfuncs . pDemoAPI - > IsPlayingback ( ) )
return ;
m_pCurrentMenu - > Open ( ) ;
}
}
//================================================================
// Text Window
CMenuPanel * TheWastesViewport : : CreateTextWindow ( int iTextToShow )
{
char sz [ 256 ] ;
char * cText ;
char * pfile = NULL ;
static const int MAX_TITLE_LENGTH = 32 ;
char cTitle [ MAX_TITLE_LENGTH ] ;
if ( iTextToShow = = SHOW_MOTD )
{
if ( ! m_szServerName | | ! m_szServerName [ 0 ] )
strcpy ( cTitle , " The Wastes " ) ;
else
strncpy ( cTitle , m_szServerName , MAX_TITLE_LENGTH ) ;
cTitle [ MAX_TITLE_LENGTH - 1 ] = 0 ;
cText = m_szMOTD ;
}
else if ( iTextToShow = = SHOW_MAPBRIEFING )
{
// Get the current mapname, and open it's map briefing text
if ( m_sMapName & & m_sMapName [ 0 ] )
{
strcpy ( sz , " maps/ " ) ;
strcat ( sz , m_sMapName ) ;
strcat ( sz , " .txt " ) ;
}
else
{
const char * level = gEngfuncs . pfnGetLevelName ( ) ;
if ( ! level )
return NULL ;
strcpy ( sz , level ) ;
char * ch = strchr ( sz , ' . ' ) ;
* ch = ' \0 ' ;
strcat ( sz , " .txt " ) ;
// pull out the map name
strcpy ( m_sMapName , level ) ;
ch = strchr ( m_sMapName , ' . ' ) ;
if ( ch )
{
* ch = 0 ;
}
ch = strchr ( m_sMapName , ' / ' ) ;
if ( ch )
{
// move the string back over the '/'
memmove ( m_sMapName , ch + 1 , strlen ( ch ) + 1 ) ;
}
}
pfile = ( char * ) gEngfuncs . COM_LoadFile ( sz , 5 , NULL ) ;
// Return dummy stuff
if ( ! pfile )
{
CMenuPanel * pMOTDPanel = CMessageWindowPanel_Create ( " Just another area decimated by fallout \n and radiation. Happy hunting! " , gEngfuncs . pfnGetLevelName ( ) , 1 , false , iTextToShow , 0 , 0 , ScreenWidth , ScreenHeight ) ;
pMOTDPanel - > setParent ( this ) ;
return pMOTDPanel ;
}
cText = pfile ;
strncpy ( cTitle , m_sMapName , MAX_TITLE_LENGTH ) ;
cTitle [ MAX_TITLE_LENGTH - 1 ] = 0 ;
}
else if ( iTextToShow = = SHOW_ITEMSELECTION )
{
CMenuPanel * pRetPanel = CItemSelectionPanel_Create ( 0 , 0 , ScreenWidth , ScreenHeight ) ;
pRetPanel - > setParent ( this ) ;
return pRetPanel ;
}
// if we're in the game (ie. have selected a class), flag the menu to be only grayed in the dialog box, instead of full screen
CMenuPanel * pMOTDPanel = CMessageWindowPanel_Create ( cText , cTitle , 1 , false , iTextToShow , 0 , 0 , ScreenWidth , ScreenHeight ) ;
pMOTDPanel - > setParent ( this ) ;
if ( pfile )
gEngfuncs . COM_FreeFile ( pfile ) ;
return pMOTDPanel ;
}
//================================================================
// VGUI Menus
void TheWastesViewport : : ShowVGUIMenu ( int iMenu )
{
CMenuPanel * pNewMenu = NULL ;
// Don't open menus in demo playback
if ( gEngfuncs . pDemoAPI - > IsPlayingback ( ) )
return ;
// Don't open any menus except the MOTD during intermission
// MOTD needs to be accepted because it's sent down to the client
// after map change, before intermission's turned off
if ( gHUD . m_iIntermission & & iMenu ! = MENU_INTRO )
return ;
// Don't create one if it's already in the list
if ( m_pCurrentMenu )
{
CMenuPanel * pMenu = m_pCurrentMenu ;
while ( pMenu ! = NULL )
{
if ( pMenu - > GetMenuID ( ) = = iMenu )
return ;
pMenu = pMenu - > GetNextMenu ( ) ;
}
}
switch ( iMenu )
{
case MENU_TEAM :
pNewMenu = ShowTeamMenu ( ) ;
break ;
// Map Briefing removed now that it appears in the team menu
case MENU_MAPBRIEFING :
pNewMenu = CreateTextWindow ( SHOW_MAPBRIEFING ) ;
break ;
case MENU_INTRO :
pNewMenu = CreateTextWindow ( SHOW_MOTD ) ;
break ;
case MENU_ITEMSELECTION :
pNewMenu = CreateTextWindow ( SHOW_ITEMSELECTION ) ;
break ;
default :
break ;
}
if ( ! pNewMenu )
return ;
// Close the Command Menu if it's open
HideCommandMenu ( ) ;
pNewMenu - > SetMenuID ( iMenu ) ;
pNewMenu - > SetActive ( true ) ;
pNewMenu - > setParent ( this ) ;
// See if another menu is visible, and if so, cache this one for display once the other one's finished
if ( m_pCurrentMenu )
{
m_pCurrentMenu - > SetNextMenu ( pNewMenu ) ;
}
else
{
m_pCurrentMenu = pNewMenu ;
m_pCurrentMenu - > Open ( ) ;
UpdateCursorState ( ) ;
}
}
// Removes all VGUI Menu's onscreen
void TheWastesViewport : : HideVGUIMenu ( )
{
while ( m_pCurrentMenu )
{
HideTopMenu ( ) ;
}
}
// Remove the top VGUI menu, and bring up the next one
void TheWastesViewport : : HideTopMenu ( )
{
if ( m_pCurrentMenu )
{
// Close the top one
m_pCurrentMenu - > Close ( ) ;
// Bring up the next one
gViewPort - > SetCurrentMenu ( m_pCurrentMenu - > GetNextMenu ( ) ) ;
}
UpdateCursorState ( ) ;
}
// Return TRUE if the HUD's allowed to print text messages
bool TheWastesViewport : : AllowedToPrintText ( void )
{
// Prevent text messages when fullscreen menus are up
if ( m_pCurrentMenu & & g_iPlayerClass = = 0 )
{
int iId = m_pCurrentMenu - > GetMenuID ( ) ;
if ( iId = = MENU_TEAM | | iId = = MENU_INTRO )
return FALSE ;
}
return TRUE ;
}
//======================================================================================
// TEAM MENU
//======================================================================================
// Bring up the Team selection Menu
CMenuPanel * TheWastesViewport : : ShowTeamMenu ( )
{
// Don't open menus in demo playback
if ( gEngfuncs . pDemoAPI - > IsPlayingback ( ) )
return NULL ;
m_pTeamMenu - > Reset ( ) ;
return m_pTeamMenu ;
}
void TheWastesViewport : : CreateTeamMenu ( )
{
// Create the panel
m_pTeamMenu = new CTeamMenuPanel ( 100 , false , 0 , 0 , ScreenWidth , ScreenHeight ) ;
m_pTeamMenu - > setParent ( this ) ;
m_pTeamMenu - > setVisible ( false ) ;
}
void TheWastesViewport : : CreateGameInfoMenu ( )
{
m_pGameInfoMenu = new CTransparentPanel ( 100 , 0 , 0 , ScreenWidth , YRES ( 60 ) ) ;
m_pGameInfoMenu - > setParent ( this ) ;
m_pGameInfoMenu - > setVisible ( false ) ;
CSchemeManager * pSchemes = gViewPort - > GetSchemeManager ( ) ;
// schemes
SchemeHandle_t hTitleScheme = pSchemes - > getSchemeHandle ( " Title Font " ) ;
SchemeHandle_t hHelpText = pSchemes - > getSchemeHandle ( " Primary Button Text " ) ;
// color schemes
int r , g , b , a ;
// Create the title
m_pGameInfoLabel = new Label ( CHudTextMessage : : BufferedLocaliseTextString ( " #GameInfo_LMS_Title " ) , 0 , 0 , ScreenWidth , YRES ( 30 ) ) ;
m_pGameInfoLabel - > setParent ( m_pGameInfoMenu ) ;
m_pGameInfoLabel - > setFont ( pSchemes - > getFont ( hTitleScheme ) ) ;
pSchemes - > getFgColor ( hTitleScheme , r , g , b , a ) ;
m_pGameInfoLabel - > setFgColor ( r , g , b , a ) ;
pSchemes - > getBgColor ( hTitleScheme , r , g , b , a ) ;
m_pGameInfoLabel - > setBgColor ( r , g , b , 255 ) ;
m_pGameInfoLabel - > setContentAlignment ( vgui : : Label : : a_north ) ;
// Create the Help
m_pGameTimeLabel = new Label ( CHudTextMessage : : BufferedLocaliseTextString ( " #GameInfo_LMS_RoundDelay " ) , 0 , YRES ( 35 ) , ScreenWidth , YRES ( 15 ) ) ;
m_pGameTimeLabel - > setParent ( m_pGameInfoMenu ) ;
m_pGameTimeLabel - > setFont ( pSchemes - > getFont ( hHelpText ) ) ;
pSchemes - > getFgColor ( hHelpText , r , g , b , a ) ;
m_pGameTimeLabel - > setFgColor ( r , g , b , a ) ;
pSchemes - > getBgColor ( hHelpText , r , g , b , a ) ;
m_pGameTimeLabel - > setBgColor ( r , g , b , 255 ) ;
m_pGameTimeLabel - > setContentAlignment ( vgui : : Label : : a_north ) ;
}
//======================================================================================
// SPECTATOR MENU
//======================================================================================
// Spectator "Menu" explaining the Spectator buttons
void TheWastesViewport : : CreateSpectatorMenu ( )
{
// Create the Panel
m_pSpectatorMenu = new CTransparentPanel ( 100 , 0 , ScreenHeight - YRES ( 60 ) , ScreenWidth , YRES ( 60 ) ) ;
m_pSpectatorMenu - > setParent ( this ) ;
m_pSpectatorMenu - > setVisible ( false ) ;
// Get the scheme used for the Titles
CSchemeManager * pSchemes = gViewPort - > GetSchemeManager ( ) ;
// schemes
SchemeHandle_t hTitleScheme = pSchemes - > getSchemeHandle ( " Title Font " ) ;
SchemeHandle_t hHelpText = pSchemes - > getSchemeHandle ( " Primary Button Text " ) ;
// color schemes
int r , g , b , a ;
// Create the title
m_pSpectatorLabel = new Label ( CHudTextMessage : : BufferedLocaliseTextString ( " #Spec_Help_Title " ) , 0 , 0 , ScreenWidth , YRES ( 25 ) ) ;
m_pSpectatorLabel - > setParent ( m_pSpectatorMenu ) ;
m_pSpectatorLabel - > setFont ( pSchemes - > getFont ( hTitleScheme ) ) ;
pSchemes - > getFgColor ( hTitleScheme , r , g , b , a ) ;
m_pSpectatorLabel - > setFgColor ( r , g , b , a ) ;
pSchemes - > getBgColor ( hTitleScheme , r , g , b , a ) ;
m_pSpectatorLabel - > setBgColor ( r , g , b , 255 ) ;
m_pSpectatorLabel - > setContentAlignment ( vgui : : Label : : a_north ) ;
// Create the Help
m_pSpectatorHelpLabel = new Label ( CHudTextMessage : : BufferedLocaliseTextString ( " #Spec_Help " ) , 0 , YRES ( 25 ) , ScreenWidth , YRES ( 15 ) ) ;
m_pSpectatorHelpLabel - > setParent ( m_pSpectatorMenu ) ;
m_pSpectatorHelpLabel - > setFont ( pSchemes - > getFont ( hHelpText ) ) ;
pSchemes - > getFgColor ( hHelpText , r , g , b , a ) ;
m_pSpectatorHelpLabel - > setFgColor ( r , g , b , a ) ;
pSchemes - > getBgColor ( hHelpText , r , g , b , a ) ;
m_pSpectatorHelpLabel - > setBgColor ( r , g , b , 255 ) ;
m_pSpectatorHelpLabel - > setContentAlignment ( vgui : : Label : : a_north ) ;
/* Label *pLabel = new Label( CHudTextMessage::BufferedLocaliseTextString( "#Spec_Help2" ), 0, YRES(40), ScreenWidth, YRES(20) );
pLabel - > setParent ( m_pSpectatorMenu ) ;
pLabel - > setFont ( pSchemes - > getFont ( hHelpText ) ) ;
pSchemes - > getFgColor ( hHelpText , r , g , b , a ) ;
pLabel - > setFgColor ( r , g , b , a ) ;
pSchemes - > getBgColor ( hHelpText , r , g , b , a ) ;
pLabel - > setBgColor ( r , g , b , 255 ) ;
pLabel - > setContentAlignment ( vgui : : Label : : a_center ) ;
*/
}
//======================================================================================
// UPDATE HUD SECTIONS
//======================================================================================
// We've got an update on player info
// Recalculate any menus that use it.
void TheWastesViewport : : UpdateOnPlayerInfo ( )
{
if ( m_pTeamMenu )
m_pTeamMenu - > Update ( ) ;
if ( m_pScoreBoard )
m_pScoreBoard - > Update ( ) ;
}
void TheWastesViewport : : UpdateCursorState ( )
{
// Need cursor if any VGUI window is up
if ( m_pCurrentMenu | | m_pTeamMenu - > isVisible ( ) | | m_pServerBrowser - > isVisible ( ) | | GetClientVoiceMgr ( ) - > IsInSquelchMode ( ) )
{
g_iVisibleMouse = true ;
App : : getInstance ( ) - > setCursorOveride ( App : : getInstance ( ) - > getScheme ( ) - > getCursor ( Scheme : : SchemeCursor : : scu_arrow ) ) ;
return ;
}
else if ( m_pCurrentCommandMenu )
{
// commandmenu doesn't have cursor if hud_capturemouse is turned off
if ( gHUD . m_pCvarStealMouse - > value ! = 0.0f )
{
g_iVisibleMouse = true ;
App : : getInstance ( ) - > setCursorOveride ( App : : getInstance ( ) - > getScheme ( ) - > getCursor ( Scheme : : SchemeCursor : : scu_arrow ) ) ;
return ;
}
}
IN_ResetMouse ( ) ;
g_iVisibleMouse = false ;
App : : getInstance ( ) - > setCursorOveride ( App : : getInstance ( ) - > getScheme ( ) - > getCursor ( Scheme : : SchemeCursor : : scu_none ) ) ;
}
void TheWastesViewport : : UpdateHighlights ( )
{
if ( m_pCurrentCommandMenu )
m_pCurrentCommandMenu - > MakeVisible ( NULL ) ;
}
void TheWastesViewport : : GetAllPlayersInfo ( void )
{
for ( int i = 1 ; i < MAX_PLAYERS ; i + + )
{
GetPlayerInfo ( i , & g_PlayerInfoList [ i ] ) ;
if ( g_PlayerInfoList [ i ] . thisplayer )
m_pScoreBoard - > m_iPlayerNum = i ; // !!!HACK: this should be initialized elsewhere... maybe gotten from the engine
}
}
void TheWastesViewport : : paintBackground ( )
{
if ( m_pScoreBoard )
{
int x , y ;
getApp ( ) - > getCursorPos ( x , y ) ;
m_pScoreBoard - > cursorMoved ( x , y , m_pScoreBoard ) ;
}
// See if the command menu is visible and needs recalculating due to some external change
if ( g_iTeamNumber ! = m_iCurrentTeamNumber )
{
UpdateCommandMenu ( ) ;
m_iCurrentTeamNumber = g_iTeamNumber ;
}
if ( g_iPlayerClass ! = m_iCurrentPlayerClass )
{
UpdateCommandMenu ( ) ;
m_iCurrentPlayerClass = g_iPlayerClass ;
}
// See if the Spectator Menu needs to be update
// no update if only second target (m_iUser3) changes
if ( g_iUser1 ! = m_iUser1 | | g_iUser2 ! = m_iUser2 )
{
UpdateSpectatorMenu ( ) ;
}
UpdateGameInfoMenu ( ) ;
// Update the Scoreboard, if it's visible
if ( m_pScoreBoard - > isVisible ( ) & & ( m_flScoreBoardLastUpdated < gHUD . m_flTime ) )
{
m_pScoreBoard - > Update ( ) ;
m_flScoreBoardLastUpdated = gHUD . m_flTime + 0.5 ;
}
int extents [ 4 ] ;
getAbsExtents ( extents [ 0 ] , extents [ 1 ] , extents [ 2 ] , extents [ 3 ] ) ;
VGui_ViewportPaintBackground ( extents ) ;
}
//================================================================
// Input Handler for Drag N Drop panels
void CDragNDropHandler : : cursorMoved ( int x , int y , Panel * panel )
{
if ( m_bDragging )
{
App : : getInstance ( ) - > getCursorPos ( x , y ) ;
m_pPanel - > setPos ( m_iaDragOrgPos [ 0 ] + ( x - m_iaDragStart [ 0 ] ) , m_iaDragOrgPos [ 1 ] + ( y - m_iaDragStart [ 1 ] ) ) ;
if ( m_pPanel - > getParent ( ) ! = null )
{
m_pPanel - > getParent ( ) - > repaint ( ) ;
}
}
}
void CDragNDropHandler : : mousePressed ( MouseCode code , Panel * panel )
{
int x , y ;
App : : getInstance ( ) - > getCursorPos ( x , y ) ;
m_bDragging = true ;
m_iaDragStart [ 0 ] = x ;
m_iaDragStart [ 1 ] = y ;
m_pPanel - > getPos ( m_iaDragOrgPos [ 0 ] , m_iaDragOrgPos [ 1 ] ) ;
App : : getInstance ( ) - > setMouseCapture ( panel ) ;
m_pPanel - > setDragged ( m_bDragging ) ;
m_pPanel - > requestFocus ( ) ;
}
void CDragNDropHandler : : mouseReleased ( MouseCode code , Panel * panel )
{
m_bDragging = false ;
m_pPanel - > setDragged ( m_bDragging ) ;
App : : getInstance ( ) - > setMouseCapture ( null ) ;
}
//================================================================
// Number Key Input
bool TheWastesViewport : : SlotInput ( int iSlot )
{
// If there's a menu up, give it the input
if ( m_pCurrentMenu )
return m_pCurrentMenu - > SlotInput ( iSlot ) ;
return FALSE ;
}
// Direct Key Input
int TheWastesViewport : : KeyInput ( int down , int keynum , const char * pszCurrentBinding )
{
// Enter gets out of Spectator Mode by bringing up the Team Menu
if ( m_iUser1 & & gEngfuncs . Con_IsVisible ( ) = = false )
{
if ( down & & ( keynum = = K_ENTER | | keynum = = K_KP_ENTER ) )
ShowVGUIMenu ( MENU_TEAM ) ;
}
// Open Text Window?
if ( m_pCurrentMenu & & gEngfuncs . Con_IsVisible ( ) = = false )
{
int iMenuID = m_pCurrentMenu - > GetMenuID ( ) ;
// Get number keys as Input for Team/Class menus
if ( iMenuID = = MENU_TEAM )
{
// Escape gets you out of Team/Class menus if the Cancel button is visible
if ( keynum = = K_ESCAPE )
{
if ( ( iMenuID = = MENU_TEAM & & g_iTeamNumber ) )
{
HideTopMenu ( ) ;
return 0 ;
}
}
for ( int i = ' 0 ' ; i < = ' 9 ' ; i + + )
{
if ( down & & ( keynum = = i ) )
{
SlotInput ( i - ' 0 ' ) ;
return 0 ;
}
}
}
// Grab enter keys to close TextWindows
if ( down & & ( keynum = = K_ENTER | | keynum = = K_KP_ENTER | | keynum = = K_SPACE | | keynum = = K_ESCAPE ) )
{
if ( iMenuID = = MENU_MAPBRIEFING | | iMenuID = = MENU_INTRO )
{
HideTopMenu ( ) ;
if ( iMenuID = = MENU_INTRO )
ShowVGUIMenu ( MENU_MAPBRIEFING ) ;
else if ( iMenuID = = MENU_MAPBRIEFING )
ShowVGUIMenu ( MENU_ITEMSELECTION ) ;
return 0 ;
}
}
// Grab jump key on Team Menu as autoassign
if ( pszCurrentBinding & & down & & ! strcmp ( pszCurrentBinding , " +jump " ) )
{
if ( iMenuID = = MENU_TEAM )
{
m_pTeamMenu - > SlotInput ( 5 ) ;
return 0 ;
}
}
}
// if we're in a command menu, try hit one of it's buttons
if ( down & & m_pCurrentCommandMenu )
{
// Escape hides the command menu
if ( keynum = = K_ESCAPE )
{
HideCommandMenu ( ) ;
return 0 ;
}
// only trap the number keys
if ( keynum > = ' 0 ' & & keynum < = ' 9 ' )
{
if ( m_pCurrentCommandMenu - > KeyInput ( keynum ) )
{
// a final command has been issued, so close the command menu
HideCommandMenu ( ) ;
}
return 0 ;
}
}
return 1 ;
}
//================================================================
// Message Handlers
int TheWastesViewport : : MsgFunc_ValClass ( const char * pszName , int iSize , void * pbuf )
{
BEGIN_READ ( pbuf , iSize ) ;
for ( int i = 0 ; i < 5 ; i + + )
m_iValidClasses [ i ] = READ_SHORT ( ) ;
// Force the menu to update
UpdateCommandMenu ( ) ;
return 1 ;
}
int TheWastesViewport : : MsgFunc_TeamNames ( const char * pszName , int iSize , void * pbuf )
{
BEGIN_READ ( pbuf , iSize ) ;
m_iNumberOfTeams = READ_BYTE ( ) ;
for ( int i = 0 ; i < m_iNumberOfTeams ; i + + )
{
int teamNum = i + 1 ;
gHUD . m_TextMessage . LocaliseTextString ( READ_STRING ( ) , m_sTeamNames [ teamNum ] , MAX_TEAMNAME_SIZE ) ;
// Set the team name buttons
if ( m_pTeamButtons [ i ] )
m_pTeamButtons [ i ] - > setText ( m_sTeamNames [ teamNum ] ) ;
// range check this value...m_pDisguiseButtons[5];
if ( teamNum < 5 )
{
// Set the disguise buttons
if ( m_pDisguiseButtons [ teamNum ] )
m_pDisguiseButtons [ teamNum ] - > setText ( m_sTeamNames [ teamNum ] ) ;
}
}
// Update the Team Menu
if ( m_pTeamMenu )
m_pTeamMenu - > Update ( ) ;
return 1 ;
}
int TheWastesViewport : : MsgFunc_VGUIMenu ( const char * pszName , int iSize , void * pbuf )
{
BEGIN_READ ( pbuf , iSize ) ;
int iMenu = READ_BYTE ( ) ;
// Map briefing includes the name of the map (because it's sent down before the client knows what map it is)
if ( iMenu = = MENU_MAPBRIEFING )
{
strncpy ( m_sMapName , READ_STRING ( ) , sizeof ( m_sMapName ) ) ;
m_sMapName [ sizeof ( m_sMapName ) - 1 ] = ' \0 ' ;
}
// Bring up the menu6
ShowVGUIMenu ( iMenu ) ;
return 1 ;
}
int TheWastesViewport : : MsgFunc_MOTD ( const char * pszName , int iSize , void * pbuf )
{
if ( m_iGotAllMOTD )
m_szMOTD [ 0 ] = 0 ;
BEGIN_READ ( pbuf , iSize ) ;
m_iGotAllMOTD = READ_BYTE ( ) ;
int roomInArray = sizeof ( m_szMOTD ) - strlen ( m_szMOTD ) - 1 ;
strncat ( m_szMOTD , READ_STRING ( ) , roomInArray > = 0 ? roomInArray : 0 ) ;
m_szMOTD [ sizeof ( m_szMOTD ) - 1 ] = ' \0 ' ;
if ( m_iGotAllMOTD )
ShowVGUIMenu ( MENU_INTRO ) ;
return 1 ;
}
int TheWastesViewport : : MsgFunc_Briefing ( const char * pszName , int iSize , void * pbuf )
{
BEGIN_READ ( pbuf , iSize ) ;
if ( READ_BYTE ( ) )
{
ShowVGUIMenu ( MENU_MAPBRIEFING ) ;
}
return 1 ;
}
int TheWastesViewport : : MsgFunc_BuildSt ( const char * pszName , int iSize , void * pbuf )
{
BEGIN_READ ( pbuf , iSize ) ;
m_iBuildState = READ_BYTE ( ) ;
// Force the menu to update
UpdateCommandMenu ( ) ;
return 1 ;
}
int TheWastesViewport : : MsgFunc_RandomPC ( const char * pszName , int iSize , void * pbuf )
{
BEGIN_READ ( pbuf , iSize ) ;
m_iRandomPC = READ_BYTE ( ) ;
return 1 ;
}
int TheWastesViewport : : MsgFunc_ServerName ( const char * pszName , int iSize , void * pbuf )
{
BEGIN_READ ( pbuf , iSize ) ;
strncpy ( m_szServerName , READ_STRING ( ) , MAX_SERVERNAME_LENGTH ) ;
return 1 ;
}
int TheWastesViewport : : MsgFunc_ScoreInfo ( const char * pszName , int iSize , void * pbuf )
{
BEGIN_READ ( pbuf , iSize ) ;
short cl = READ_BYTE ( ) ;
short frags = READ_SHORT ( ) ;
short deaths = READ_SHORT ( ) ;
short alive = READ_SHORT ( ) ;
short teamnumber = READ_SHORT ( ) ;
if ( cl > 0 & & cl < = MAX_PLAYERS )
{
g_PlayerExtraInfo [ cl ] . frags = frags ;
g_PlayerExtraInfo [ cl ] . deaths = deaths ;
g_PlayerExtraInfo [ cl ] . alive = alive ;
g_PlayerExtraInfo [ cl ] . teamnumber = teamnumber ;
//Dont go below 0!
if ( g_PlayerExtraInfo [ cl ] . teamnumber < 0 )
g_PlayerExtraInfo [ cl ] . teamnumber = 0 ;
UpdateOnPlayerInfo ( ) ;
}
return 1 ;
}
// Message handler for TeamScore message
// accepts three values:
// string: team name
// short: teams kills
// short: teams deaths
// if this message is never received, then scores will simply be the combined totals of the players.
int TheWastesViewport : : MsgFunc_TeamScore ( const char * pszName , int iSize , void * pbuf )
{
BEGIN_READ ( pbuf , iSize ) ;
char * TeamName = READ_STRING ( ) ;
// find the team matching the name
for ( int i = 1 ; i < = m_pScoreBoard - > m_iNumTeams ; i + + )
{
if ( ! stricmp ( TeamName , g_TeamInfo [ i ] . name ) )
break ;
}
if ( i > m_pScoreBoard - > m_iNumTeams )
return 1 ;
// use this new score data instead of combined player scoresw
g_TeamInfo [ i ] . scores_overriden = TRUE ;
g_TeamInfo [ i ] . frags = READ_SHORT ( ) ;
g_TeamInfo [ i ] . deaths = READ_SHORT ( ) ;
return 1 ;
}
// Message handler for TeamInfo message
// accepts two values:
// byte: client number
// string: client team name
int TheWastesViewport : : MsgFunc_TeamInfo ( const char * pszName , int iSize , void * pbuf )
{
if ( ! m_pScoreBoard )
return 1 ;
BEGIN_READ ( pbuf , iSize ) ;
short cl = READ_BYTE ( ) ;
if ( cl > 0 & & cl < = MAX_PLAYERS )
{
// set the players team
strncpy ( g_PlayerExtraInfo [ cl ] . teamname , READ_STRING ( ) , MAX_TEAM_NAME ) ;
}
// rebuild the list of teams
m_pScoreBoard - > RebuildTeams ( ) ;
return 1 ;
}
void TheWastesViewport : : DeathMsg ( int killer , int victim )
{
m_pScoreBoard - > DeathMsg ( killer , victim ) ;
}
int TheWastesViewport : : MsgFunc_Spectator ( const char * pszName , int iSize , void * pbuf )
{
BEGIN_READ ( pbuf , iSize ) ;
short cl = READ_BYTE ( ) ;
if ( cl > 0 & & cl < = MAX_PLAYERS )
{
g_IsSpectator [ cl ] = READ_BYTE ( ) ;
}
return 1 ;
}
int TheWastesViewport : : MsgFunc_AllowSpec ( const char * pszName , int iSize , void * pbuf )
{
BEGIN_READ ( pbuf , iSize ) ;
m_iAllowSpectators = READ_BYTE ( ) ;
// Force the menu to update
UpdateCommandMenu ( ) ;
// If the team menu is up, update it too
if ( m_pTeamMenu )
m_pTeamMenu - > Update ( ) ;
return 1 ;
}
int TheWastesViewport : : MsgFunc_LmsStart ( const char * pszName , int iSize , void * pbuf )
{
BEGIN_READ ( pbuf , iSize ) ;
m_flGameTimeDelay = READ_COORD ( ) + gHUD . m_flTime ;
return 1 ;
}