2548 lines
73 KiB
C++
2548 lines
73 KiB
C++
//=========== (C) Copyright 1996-2002 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_Scheme.h>
|
||
#include<VGUI_Font.h>
|
||
#include<VGUI_App.h>
|
||
#include<VGUI_BuildGroup.h>
|
||
|
||
#include "vgui_paranoiatext.h"// buz
|
||
|
||
#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 "vgui_int.h"
|
||
#include "vgui_TeamFortressViewport.h"
|
||
#include "vgui_ServerBrowser.h"
|
||
#include "vgui_ScorePanel.h"
|
||
#include "vgui_SpectatorPanel.h"
|
||
|
||
#include "vgui_subtitles.h"// buz
|
||
#include "vgui_radio.h"// buz
|
||
#include "vgui_hud.h" // buz
|
||
#include "vgui_tabpanel.h" // buz
|
||
#include "vgui_tips.h" // buz
|
||
#include "vgui_gamma.h" // buz
|
||
#include "vgui_screenmsg.h" // buz
|
||
|
||
|
||
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 x, int y, int wide, int tall );
|
||
extern float * GetClientColor( int clientIndex );
|
||
|
||
using namespace vgui;
|
||
/*
|
||
typedef struct tga_s {
|
||
unsigned char IDLength, ColorMapType, ImageType;
|
||
unsigned short ColorMapStart; //
|
||
unsigned short ColorMapLength; // unused
|
||
unsigned char ColorMapDepth; //
|
||
unsigned short XOrigin, YOrigin, Width, Height;
|
||
unsigned char ColorBits, ImageDescriptor;
|
||
} tga_t;
|
||
|
||
|
||
//buz test
|
||
class CTestPanel : public Panel
|
||
{
|
||
public:
|
||
CTestPanel() : Panel(0, 0, ScreenWidth, ScreenHeight)
|
||
{
|
||
setPaintBackgroundEnabled(false);
|
||
setPaintEnabled(true);
|
||
|
||
int fontFileLength;
|
||
void* pFontData = gEngfuncs.COM_LoadFile( "gfx/vgui/fonts/640_Default Text.tga", 5, &fontFileLength );
|
||
if(!pFontData)
|
||
gEngfuncs.Con_Printf("Missing bitmap font\n");
|
||
|
||
fffffffff tga_t* tgaDesc = (tga_t*)pFontData;
|
||
gEngfuncs.Con_Printf("Description length: %d\n", tgaDesc->IDLength);
|
||
gEngfuncs.Con_Printf("Color map: %d\n", tgaDesc->ColorMapType);
|
||
gEngfuncs.Con_Printf("Image type: %d\n", tgaDesc->ImageType);
|
||
gEngfuncs.Con_Printf("color map start: %d\n", tgaDesc->ColorMapStart);
|
||
gEngfuncs.Con_Printf("color map length: %d\n", tgaDesc->ColorMapLength);
|
||
gEngfuncs.Con_Printf("color map depth: %d\n", tgaDesc->ColorMapDepth);
|
||
gEngfuncs.Con_Printf("X origin: %d\n", tgaDesc->XOrigin);
|
||
gEngfuncs.Con_Printf("Y origin: %d\n", tgaDesc->YOrigin);
|
||
gEngfuncs.Con_Printf("Width: %d\n", tgaDesc->Width);
|
||
gEngfuncs.Con_Printf("Height: %d\n", tgaDesc->Width);
|
||
gEngfuncs.Con_Printf("Colorbits: %d\n", tgaDesc->ColorBits);
|
||
|
||
tgaDesc++;
|
||
char* pFileData = (char*)tgaDesc;
|
||
for (int i=0; i < 20; i++, pFileData++)
|
||
{
|
||
char byte = *pFileData;
|
||
gEngfuncs.Con_Printf("byte n%d: %d\n", i, byte);
|
||
} fffffffff
|
||
|
||
m_pFont = new Font("Arial",pFontData,fontFileLength,17,0,0,0,false,false,false,false);
|
||
//m_pFont = new Font("Arial",17,0,0,0,false,false,false,false);
|
||
}
|
||
|
||
~CTestPanel()
|
||
{
|
||
if (m_pFont) delete m_pFont;
|
||
}
|
||
|
||
void paint()
|
||
{
|
||
if (!m_pFont)
|
||
{
|
||
return;
|
||
}
|
||
|
||
drawSetColor(0, 0, 0, 0);
|
||
drawFilledRect(0, 0, getWide(), getTall()/3);
|
||
|
||
drawSetTextFont(m_pFont);
|
||
drawSetTextColor(0, 250, 0, 0);
|
||
|
||
fff char* pos = "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
||
int xpos = 0;
|
||
|
||
while(*pos != 0)
|
||
{
|
||
drawPrintChar(xpos, 0, *pos);
|
||
pos++;
|
||
xpos += 16;
|
||
}
|
||
|
||
pos = "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
||
xpos = 0;
|
||
|
||
while(*pos != 0)
|
||
{
|
||
drawPrintChar(xpos, 17, *pos);
|
||
pos++;
|
||
xpos += 16;
|
||
} fffffffffff
|
||
drawSetTextPos(0,17);
|
||
char* textstring = "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...";
|
||
drawPrintText(textstring, strlen(textstring) - 1);
|
||
|
||
int xpos = 0;
|
||
while(*textstring != 0)
|
||
{
|
||
int a, b, c;
|
||
drawPrintChar(xpos, 0, *textstring);
|
||
textstring++;
|
||
m_pFont->getCharABCwide(*textstring, a, b, c);
|
||
xpos += (b + a + c);
|
||
}
|
||
|
||
int wide, tall;
|
||
m_pFont->getTextSize("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...", wide, tall);
|
||
drawSetColor(100, 0, 0, 0);
|
||
drawFilledRect(0, 34, wide, 34+tall);
|
||
//gEngfuncs.Con_Printf("wide %d, tall %d\n", wide, tall);
|
||
}
|
||
|
||
private:
|
||
Font* m_pFont;
|
||
};
|
||
*/
|
||
|
||
// Team Colors
|
||
int iNumberOfTeamColors = 5;
|
||
int iTeamColors[5][3] =
|
||
{
|
||
{ 255, 170, 0 }, // HL orange (default)
|
||
{ 125, 165, 210 }, // Blue
|
||
{ 200, 90, 70 }, // Red
|
||
{ 225, 205, 45 }, // Yellow
|
||
{ 145, 215, 140 }, // Green
|
||
};
|
||
|
||
|
||
// Used for Class specific buttons
|
||
char *sTFClasses[] =
|
||
{
|
||
"",
|
||
"SCOUT",
|
||
"SNIPER",
|
||
"SOLDIER",
|
||
"DEMOMAN",
|
||
"MEDIC",
|
||
"HWGUY",
|
||
"PYRO",
|
||
"SPY",
|
||
"ENGINEER",
|
||
"CIVILIAN",
|
||
};
|
||
|
||
char *sLocalisedClasses[] =
|
||
{
|
||
"#Civilian",
|
||
"#Scout",
|
||
"#Sniper",
|
||
"#Soldier",
|
||
"#Demoman",
|
||
"#Medic",
|
||
"#HWGuy",
|
||
"#Pyro",
|
||
"#Spy",
|
||
"#Engineer",
|
||
"#Random",
|
||
"#Civilian",
|
||
};
|
||
|
||
char *sTFClassSelection[] =
|
||
{
|
||
"civilian",
|
||
"scout",
|
||
"sniper",
|
||
"soldier",
|
||
"demoman",
|
||
"medic",
|
||
"hwguy",
|
||
"pyro",
|
||
"spy",
|
||
"engineer",
|
||
"randompc",
|
||
"civilian",
|
||
};
|
||
|
||
int iBuildingCosts[] =
|
||
{
|
||
BUILD_COST_DISPENSER,
|
||
BUILD_COST_SENTRYGUN
|
||
};
|
||
|
||
// 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 iYOffset, bool bHideAll )
|
||
{
|
||
int i, iCurrentY = 0;
|
||
int iVisibleButtons = 0;
|
||
|
||
// Cycle through all the buttons in this menu, and see which will be visible
|
||
for (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( 0, 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( 0 , false ) )
|
||
{
|
||
// The submenu had no visible buttons, so don't display this button
|
||
m_aButtons[i]->setVisible( false );
|
||
continue;
|
||
}
|
||
}
|
||
|
||
m_aButtons[i]->setVisible( true );
|
||
iVisibleButtons++;
|
||
}
|
||
}
|
||
|
||
// Set Size
|
||
setSize( _size[0], (iVisibleButtons * (m_flButtonSizeY-1)) + 1 );
|
||
|
||
if ( iYOffset )
|
||
{
|
||
m_iYOffset = iYOffset;
|
||
}
|
||
|
||
for (i = 0; i < m_iButtons; i++)
|
||
{
|
||
if ( m_aButtons[i]->isVisible() )
|
||
{
|
||
if ( m_aButtons[i]->GetSubMenu() != NULL )
|
||
(m_aButtons[i]->GetSubMenu())->RecalculateVisibles( iCurrentY + m_iYOffset, false );
|
||
|
||
|
||
// Make sure it's at the right Y position
|
||
// m_aButtons[i]->getPos( iXPos, iYPos );
|
||
|
||
if ( m_iDirection )
|
||
{
|
||
m_aButtons[i]->setPos( 0, (iVisibleButtons-1) * (m_flButtonSizeY-1) - iCurrentY );
|
||
}
|
||
else
|
||
{
|
||
m_aButtons[i]->setPos( 0, iCurrentY );
|
||
}
|
||
|
||
iCurrentY += (m_flButtonSizeY-1);
|
||
}
|
||
}
|
||
|
||
return iVisibleButtons?true:false;
|
||
}
|
||
|
||
// Make sure all submenus can fit on the screen
|
||
void CCommandMenu::RecalculatePositions( int iYOffset )
|
||
{
|
||
int iTop;
|
||
int iAdjust = 0;
|
||
|
||
m_iYOffset+= iYOffset;
|
||
|
||
if ( m_iDirection )
|
||
iTop = ScreenHeight - (m_iYOffset + _size[1] );
|
||
else
|
||
iTop = m_iYOffset;
|
||
|
||
if ( iTop < 0 )
|
||
iTop = 0;
|
||
|
||
// Calculate if this is going to fit onscreen, and shuffle it up if it won't
|
||
int iBottom = iTop + _size[1];
|
||
|
||
if ( iBottom > ScreenHeight )
|
||
{
|
||
// Move in increments of button sizes
|
||
while (iAdjust < (iBottom - ScreenHeight))
|
||
{
|
||
iAdjust += m_flButtonSizeY - 1;
|
||
}
|
||
|
||
iTop -= iAdjust;
|
||
|
||
// Make sure it doesn't move off the top of the screen (the menu's too big to fit it all)
|
||
if ( iTop < 0 )
|
||
{
|
||
iAdjust -= (0 - iTop);
|
||
iTop = 0;
|
||
}
|
||
}
|
||
|
||
setPos( _pos[0], iTop );
|
||
|
||
// 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 );
|
||
}
|
||
|
||
|
||
// 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 *TeamFortressViewport::CreateSubMenu( CommandButton *pButton, CCommandMenu *pParentMenu, int iYOffset, int iXOffset )
|
||
{
|
||
int iXPos = 0;
|
||
int iYPos = 0;
|
||
int iWide = CMENU_SIZE_X;
|
||
int iTall = 0;
|
||
int iDirection = 0;
|
||
|
||
if (pParentMenu)
|
||
{
|
||
iXPos = m_pCurrentCommandMenu->GetXOffset() + (CMENU_SIZE_X - 1) + iXOffset;
|
||
iYPos = m_pCurrentCommandMenu->GetYOffset() + iYOffset;
|
||
iDirection = pParentMenu->GetDirection();
|
||
}
|
||
|
||
CCommandMenu *pMenu = new CCommandMenu(pParentMenu, iDirection, iXPos, iYPos, iWide, iTall );
|
||
pMenu->setParent(this);
|
||
pButton->AddSubMenu( pMenu );
|
||
pButton->setFont( Scheme::sf_primary3 );
|
||
pMenu->m_flButtonSizeY = m_pCurrentCommandMenu->m_flButtonSizeY;
|
||
|
||
// 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 TeamFortressViewport is nulled out
|
||
// Input : stAllocateBlock -
|
||
// Output : void *
|
||
//-----------------------------------------------------------------------------
|
||
void *TeamFortressViewport::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) {}
|
||
};
|
||
|
||
|
||
//================================================================
|
||
TeamFortressViewport::TeamFortressViewport(int x,int y,int wide,int tall) : Panel(x,y,wide,tall), m_SchemeManager(wide,tall)
|
||
{
|
||
gViewPort = this;
|
||
m_iInitialized = false;
|
||
// m_pTeamMenu = NULL;
|
||
// m_pClassMenu = NULL;
|
||
m_pScoreBoard = NULL;
|
||
// m_pSpectatorPanel = NULL;
|
||
m_pCurrentMenu = NULL;
|
||
m_pCurrentCommandMenu = NULL;
|
||
m_pSubtitle = NULL; // buz
|
||
m_pTips = NULL; // buz
|
||
m_pScreenMsg = NULL;
|
||
m_pRadio = NULL; // buz
|
||
m_pGamma = NULL; // buz
|
||
|
||
// Wargon: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>.
|
||
m_pScrollingMsg = NULL;
|
||
|
||
CreatePickupMessagePanels(); // buz
|
||
|
||
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();
|
||
// CreateClassMenu();
|
||
// CreateSpectatorMenu();
|
||
CreateScoreBoard();
|
||
// Init command menus
|
||
m_iNumMenus = 0;
|
||
m_iCurrentTeamNumber = m_iUser1 = m_iUser2 = m_iUser3 = 0;
|
||
|
||
m_StandardMenu = CreateCommandMenu("commandmenu.txt", 0, CMENU_TOP, false, CMENU_SIZE_X, BUTTON_SIZE_Y, 0 );
|
||
m_SpectatorOptionsMenu = CreateCommandMenu("spectatormenu.txt", 1, YRES(32), true, CMENU_SIZE_X, BUTTON_SIZE_Y / 2, 0 ); // above bottom bar, flat design
|
||
m_SpectatorCameraMenu = CreateCommandMenu("spectcammenu.txt", 1, YRES(32), true, XRES( 200 ), BUTTON_SIZE_Y / 2, ScreenWidth - ( XRES ( 200 ) + 15 ) ); // above bottom bar, flat design
|
||
CreateServerBrowser();
|
||
|
||
// CTestPanel* pan = new CTestPanel;
|
||
// pan->setParent(this);
|
||
// pan->setVisible(true);
|
||
|
||
m_pHud2 = new CHud2();
|
||
m_pHud2->setParent(this);
|
||
m_pHud2->setVisible(true);
|
||
|
||
// buz
|
||
m_pSubtitle = new CSubtitle();
|
||
m_pSubtitle->setParent(this);
|
||
m_pSubtitle->setVisible(false);
|
||
|
||
// buz
|
||
m_pRadio = new CRadioIcon();
|
||
m_pRadio->setParent(this);
|
||
|
||
// buz
|
||
m_pTabPanel = new CTabPanel();
|
||
m_pTabPanel->setParent(this);
|
||
|
||
// buz
|
||
m_pTips = new CTips();
|
||
m_pTips->setParent(this);
|
||
|
||
// buz
|
||
m_pGamma = new CGammaView();
|
||
m_pGamma->setParent(this);
|
||
|
||
// buz
|
||
m_pScreenMsg = new CScreenMessage();
|
||
m_pScreenMsg->setParent(this);
|
||
|
||
// Wargon: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>.
|
||
m_pScrollingMsg = new CScrollingMessage();
|
||
m_pScrollingMsg->setParent(this);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Purpose: Called everytime a new level is started. Viewport clears out it's data.
|
||
//-----------------------------------------------------------------------------
|
||
void TeamFortressViewport::Initialize( void )
|
||
{
|
||
// Force each menu to Initialize
|
||
// if (m_pTeamMenu)
|
||
// {
|
||
// m_pTeamMenu->Initialize();
|
||
// }
|
||
// if (m_pClassMenu)
|
||
// {
|
||
// m_pClassMenu->Initialize();
|
||
// }
|
||
if (m_pScoreBoard)
|
||
{
|
||
m_pScoreBoard->Initialize();
|
||
HideScoreBoard();
|
||
}
|
||
// if (m_pSpectatorPanel)
|
||
// {
|
||
// // Spectator menu doesn't need initializing
|
||
// m_pSpectatorPanel->setVisible( false );
|
||
// }
|
||
|
||
// buz
|
||
if (m_pParanoiaText)
|
||
{
|
||
m_pParanoiaText->setVisible(false);
|
||
UpdateCursorState();
|
||
}
|
||
if (m_pRadio)
|
||
m_pRadio->Initialize(); // buz
|
||
if (m_pSubtitle)
|
||
m_pSubtitle->Initialize(); // buz
|
||
if (m_pHud2)
|
||
m_pHud2->Initialize(); // buz
|
||
if (m_pTabPanel)
|
||
m_pTabPanel->Initialize(); // buz
|
||
if (m_pTips)
|
||
m_pTips->Initialize(); // buz
|
||
if (m_pScreenMsg)
|
||
m_pScreenMsg->Initialize(); // buz
|
||
// Wargon: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>.
|
||
if (m_pScrollingMsg)
|
||
m_pScrollingMsg->Initialize();
|
||
|
||
InitializePickupMessagePanels(); // buz
|
||
|
||
// Make sure all menus are hidden
|
||
HideVGUIMenu();
|
||
HideCommandMenu();
|
||
|
||
// Clear out some data
|
||
m_iGotAllMOTD = true;
|
||
m_iRandomPC = false;
|
||
m_flScoreBoardLastUpdated = 0;
|
||
m_flSpectatorPanelLastUpdated = 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.
|
||
// Returns Index of menu in m_pCommandMenus
|
||
//-----------------------------------------------------------------------------
|
||
int TeamFortressViewport::CreateCommandMenu( char * menuFile, int direction, int yOffset, bool flatDesign, float flButtonSizeX, float flButtonSizeY, int xOffset )
|
||
{
|
||
// COMMAND MENU
|
||
// Create the root of this new Command Menu
|
||
|
||
int newIndex = m_iNumMenus;
|
||
|
||
m_pCommandMenus[newIndex] = new CCommandMenu(NULL, direction, xOffset, yOffset, flButtonSizeX, 300); // This will be resized once we know how many items are in it
|
||
m_pCommandMenus[newIndex]->setParent(this);
|
||
m_pCommandMenus[newIndex]->setVisible(false);
|
||
m_pCommandMenus[newIndex]->m_flButtonSizeY = flButtonSizeY;
|
||
m_pCommandMenus[newIndex]->m_iSpectCmdMenu = direction;
|
||
|
||
m_iNumMenus++;
|
||
|
||
// Read Command Menu from the txt file
|
||
char token[1024];
|
||
char *pfile = (char*)gEngfuncs.COM_LoadFile( menuFile, 5, NULL);
|
||
if (!pfile)
|
||
{
|
||
ALERT( at_aiconsole, "Unable to open %s\n", menuFile);
|
||
SetCurrentCommandMenu( NULL );
|
||
return newIndex;
|
||
}
|
||
|
||
try
|
||
{
|
||
// First, read in the localisation strings
|
||
|
||
// Detpack strings
|
||
gHUD.m_TextMessage.LocaliseTextString( "#DetpackSet_For5Seconds", m_sDetpackStrings[0], MAX_BUTTON_SIZE );
|
||
gHUD.m_TextMessage.LocaliseTextString( "#DetpackSet_For20Seconds", m_sDetpackStrings[1], MAX_BUTTON_SIZE );
|
||
gHUD.m_TextMessage.LocaliseTextString( "#DetpackSet_For50Seconds", m_sDetpackStrings[2], MAX_BUTTON_SIZE );
|
||
|
||
// Now start parsing the menu structure
|
||
m_pCurrentCommandMenu = m_pCommandMenus[newIndex];
|
||
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 = -1;
|
||
int iToggle = 0;
|
||
int iButtonY;
|
||
bool bGetExtraToken = true;
|
||
CommandButton *pButton = NULL;
|
||
|
||
// We should never be here without a Command Menu
|
||
if (!m_pCurrentCommandMenu)
|
||
{
|
||
gEngfuncs.Con_Printf("Error in %s file after '%s'.\n",menuFile, szLastButtonText );
|
||
m_iInitialized = false;
|
||
return newIndex;
|
||
}
|
||
|
||
// 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 if ( !strncmp(cCustom, "TOGGLE", 6) )
|
||
{
|
||
iToggle = true;
|
||
// 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';
|
||
|
||
iButtonY = (BUTTON_SIZE_Y-1) * m_pCurrentCommandMenu->GetNumButtons();
|
||
|
||
// Custom button handling
|
||
if ( iCustom )
|
||
{
|
||
pButton = CreateCustomButton( cText, cCommand, iButtonY );
|
||
|
||
// 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, xOffset, iButtonY, flButtonSizeX, flButtonSizeY );
|
||
}
|
||
else if ( iTeamOnly != -1)
|
||
{
|
||
// button that only shows up if the player is on team iTeamOnly
|
||
pButton = new TeamOnlyCommandButton( iTeamOnly, cText, xOffset, iButtonY, flButtonSizeX, flButtonSizeY, flatDesign );
|
||
}
|
||
else if ( iToggle && direction == 0 )
|
||
{
|
||
pButton = new ToggleCommandButton( cCommand, cText, xOffset, iButtonY, flButtonSizeX, flButtonSizeY, flatDesign );
|
||
}
|
||
else if ( direction == 1 )
|
||
{
|
||
if ( iToggle )
|
||
pButton = new SpectToggleButton( cCommand, cText, xOffset, iButtonY, flButtonSizeX, flButtonSizeY, flatDesign );
|
||
else
|
||
pButton = new SpectButton( iPlayerClass, cText, xOffset, iButtonY, flButtonSizeX, flButtonSizeY );
|
||
}
|
||
else
|
||
{
|
||
// normal button
|
||
pButton = new CommandButton( iPlayerClass, cText, xOffset, iButtonY, flButtonSizeX, flButtonSizeY, flatDesign );
|
||
}
|
||
|
||
// 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 %s past '%s'\n",menuFile, szLastButtonText );
|
||
}
|
||
else
|
||
{
|
||
// Create the menu
|
||
m_pCommandMenus[m_iNumMenus] = CreateSubMenu(pButton, m_pCurrentCommandMenu, iButtonY );
|
||
m_pCurrentCommandMenu = m_pCommandMenus[m_iNumMenus];
|
||
m_iNumMenus++;
|
||
}
|
||
}
|
||
else if ( !iCustom )
|
||
{
|
||
// Create the button and attach it to the current menu
|
||
if ( iToggle )
|
||
pButton->addActionSignal(new CMenuHandler_ToggleCvar(cCommand));
|
||
else
|
||
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 newIndex;
|
||
}
|
||
|
||
SetCurrentMenu( NULL );
|
||
SetCurrentCommandMenu( NULL );
|
||
gEngfuncs.COM_FreeFile( pfile );
|
||
|
||
m_iInitialized = true;
|
||
return newIndex;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Purpose: Creates all the class choices under a spy's disguise menus, and
|
||
// maps a command to them
|
||
// Output : CCommandMenu
|
||
//-----------------------------------------------------------------------------
|
||
CCommandMenu *TeamFortressViewport::CreateDisguiseSubmenu( CommandButton *pButton, CCommandMenu *pParentMenu, const char *commandText, int iYOffset, int iXOffset )
|
||
{
|
||
// create the submenu, under which the class choices will be listed
|
||
CCommandMenu *pMenu = CreateSubMenu( pButton, pParentMenu, iYOffset, iXOffset );
|
||
m_pCommandMenus[m_iNumMenus] = pMenu;
|
||
m_iNumMenus++;
|
||
|
||
// create the class choice buttons
|
||
for ( int i = PC_SCOUT; i <= PC_ENGINEER; i++ )
|
||
{
|
||
CommandButton *pDisguiseButton = new CommandButton( CHudTextMessage::BufferedLocaliseTextString( sLocalisedClasses[i] ), 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y );
|
||
|
||
char sz[256];
|
||
sprintf(sz, "%s %d", commandText, i );
|
||
pDisguiseButton->addActionSignal(new CMenuHandler_StringCommand(sz));
|
||
|
||
pMenu->AddButton( pDisguiseButton );
|
||
}
|
||
|
||
return pMenu;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Purpose:
|
||
// Input : *pButtonText -
|
||
// *pButtonName -
|
||
// Output : CommandButton
|
||
//-----------------------------------------------------------------------------
|
||
CommandButton *TeamFortressViewport::CreateCustomButton( char *pButtonText, char *pButtonName, int iYOffset )
|
||
{
|
||
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, iYOffset );
|
||
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] );
|
||
}
|
||
// ChangeClass
|
||
else if ( !strcmp( pButtonName, "!CHANGECLASS" ) )
|
||
{
|
||
// Create the Change class menu
|
||
pButton = new ClassButton(-1, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y, false);
|
||
|
||
// ChangeClass Submenu
|
||
pMenu = CreateSubMenu(pButton, m_pCurrentCommandMenu, iYOffset );
|
||
m_pCommandMenus[m_iNumMenus] = pMenu;
|
||
m_iNumMenus++;
|
||
|
||
for (int i = PC_SCOUT; i <= PC_RANDOM; i++ )
|
||
{
|
||
char sz[256];
|
||
|
||
// ChangeClass buttons
|
||
CHudTextMessage::LocaliseTextString( sLocalisedClasses[i], sz, 256 );
|
||
ClassButton *pClassButton = new ClassButton( i, sz, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y, false);
|
||
|
||
sprintf(sz, "%s", sTFClassSelection[i]);
|
||
pClassButton->addActionSignal(new CMenuHandler_StringCommandClassSelect(sz));
|
||
pMenu->AddButton( pClassButton );
|
||
}
|
||
}
|
||
// 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) );
|
||
}
|
||
// Class Descriptions
|
||
else if ( !strcmp( pButtonName, "!CLASSDESC" ) )
|
||
{
|
||
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_CLASSHELP));
|
||
// 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) );
|
||
}
|
||
// Spy abilities
|
||
else if ( !strcmp( pButtonName, "!SPY" ) )
|
||
{
|
||
pButton = new DisguiseButton( 0, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y );
|
||
}
|
||
// Feign
|
||
else if ( !strcmp( pButtonName, "!FEIGN" ) )
|
||
{
|
||
pButton = new FeignButton(FALSE, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand( "feign" ));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
// Feign Silently
|
||
else if ( !strcmp( pButtonName, "!FEIGNSILENT" ) )
|
||
{
|
||
pButton = new FeignButton(FALSE, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand( "sfeign" ));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
// Stop Feigning
|
||
else if ( !strcmp( pButtonName, "!FEIGNSTOP" ) )
|
||
{
|
||
pButton = new FeignButton(TRUE, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand( "feign" ));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
// Disguise
|
||
else if ( !strcmp( pButtonName, "!DISGUISEENEMY" ) )
|
||
{
|
||
// Create the disguise enemy button, which active only if there are 2 teams
|
||
pButton = new DisguiseButton(DISGUISE_TEAM2, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
CreateDisguiseSubmenu( pButton, m_pCurrentCommandMenu, "disguise_enemy", iYOffset);
|
||
}
|
||
else if ( !strcmp( pButtonName, "!DISGUISEFRIENDLY" ) )
|
||
{
|
||
// Create the disguise friendly button, which active only if there are 1 or 2 teams
|
||
pButton = new DisguiseButton(DISGUISE_TEAM1 | DISGUISE_TEAM2, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
CreateDisguiseSubmenu( pButton, m_pCurrentCommandMenu, "disguise_friendly", iYOffset );
|
||
}
|
||
else if ( !strcmp( pButtonName, "!DISGUISE" ) )
|
||
{
|
||
// Create the Disguise button
|
||
pButton = new DisguiseButton( DISGUISE_TEAM3 | DISGUISE_TEAM4, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
CCommandMenu *pDisguiseMenu = CreateSubMenu( pButton, m_pCurrentCommandMenu, iYOffset );
|
||
m_pCommandMenus[m_iNumMenus] = pDisguiseMenu;
|
||
m_iNumMenus++;
|
||
|
||
// Disguise Enemy submenu buttons
|
||
for ( int i = 1; i <= 4; i++ )
|
||
{
|
||
// only show the 4th disguise button if we have 4 teams
|
||
m_pDisguiseButtons[i] = new DisguiseButton( ((i < 4) ? DISGUISE_TEAM3 : 0) | DISGUISE_TEAM4, "Disguise", 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
|
||
pDisguiseMenu->AddButton( m_pDisguiseButtons[i] );
|
||
m_pDisguiseButtons[i]->setParentMenu( pDisguiseMenu );
|
||
|
||
char sz[256];
|
||
sprintf( sz, "disguise %d", i );
|
||
CreateDisguiseSubmenu( m_pDisguiseButtons[i], pDisguiseMenu, sz, iYOffset, CMENU_SIZE_X - 1 );
|
||
}
|
||
}
|
||
// Start setting a Detpack
|
||
else if ( !strcmp( pButtonName, "!DETPACKSTART" ) )
|
||
{
|
||
// Detpack Submenu
|
||
pButton = new DetpackButton(2, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
|
||
// Create the submenu
|
||
pMenu = CreateSubMenu(pButton, m_pCurrentCommandMenu, iYOffset );
|
||
m_pCommandMenus[m_iNumMenus] = pMenu;
|
||
m_iNumMenus++;
|
||
|
||
// Set detpack buttons
|
||
CommandButton *pDetButton;
|
||
pDetButton = new CommandButton(m_sDetpackStrings[0], 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pDetButton->addActionSignal(new CMenuHandler_StringCommand("detstart 5"));
|
||
pMenu->AddButton( pDetButton );
|
||
pDetButton = new CommandButton(m_sDetpackStrings[1], 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pDetButton->addActionSignal(new CMenuHandler_StringCommand("detstart 20"));
|
||
pMenu->AddButton( pDetButton );
|
||
pDetButton = new CommandButton(m_sDetpackStrings[2], 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pDetButton->addActionSignal(new CMenuHandler_StringCommand("detstart 50"));
|
||
pMenu->AddButton( pDetButton );
|
||
}
|
||
// Stop setting a Detpack
|
||
else if ( !strcmp( pButtonName, "!DETPACKSTOP" ) )
|
||
{
|
||
pButton = new DetpackButton(1, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand( "detstop" ));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
// Engineer building
|
||
else if ( !strcmp( pButtonName, "!BUILD" ) )
|
||
{
|
||
// only appears if the player is an engineer, and either they have built something or have enough metal to build
|
||
pButton = new BuildButton( BUILDSTATE_BASE, 0, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
}
|
||
else if ( !strcmp( pButtonName, "!BUILDSENTRY" ) )
|
||
{
|
||
pButton = new BuildButton( BUILDSTATE_CANBUILD, BuildButton::SENTRYGUN, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand("build 2"));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
else if ( !strcmp( pButtonName, "!BUILDDISPENSER" ) )
|
||
{
|
||
pButton = new BuildButton( BUILDSTATE_CANBUILD, BuildButton::DISPENSER, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand("build 1"));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
else if ( !strcmp( pButtonName, "!ROTATESENTRY180" ) )
|
||
{
|
||
pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::SENTRYGUN, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand("rotatesentry180"));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
else if ( !strcmp( pButtonName, "!ROTATESENTRY" ) )
|
||
{
|
||
pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::SENTRYGUN, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand("rotatesentry"));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
else if ( !strcmp( pButtonName, "!DISMANTLEDISPENSER" ) )
|
||
{
|
||
pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::DISPENSER, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand("dismantle 1"));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
else if ( !strcmp( pButtonName, "!DISMANTLESENTRY" ) )
|
||
{
|
||
pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::SENTRYGUN, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand("dismantle 2"));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
else if ( !strcmp( pButtonName, "!DETONATEDISPENSER" ) )
|
||
{
|
||
pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::DISPENSER, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand("detdispenser"));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
else if ( !strcmp( pButtonName, "!DETONATESENTRY" ) )
|
||
{
|
||
pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::SENTRYGUN, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand("detsentry"));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
// Stop building
|
||
else if ( !strcmp( pButtonName, "!BUILDSTOP" ) )
|
||
{
|
||
pButton = new BuildButton( BUILDSTATE_BUILDING, 0, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y);
|
||
pButton->addActionSignal(new CMenuHandler_StringCommand("build"));
|
||
// Create an input signal that'll popup the current menu
|
||
pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) );
|
||
}
|
||
|
||
return pButton;
|
||
}
|
||
|
||
void TeamFortressViewport::ToggleServerBrowser()
|
||
{
|
||
if (!m_iInitialized)
|
||
return;
|
||
|
||
if ( !m_pServerBrowser )
|
||
return;
|
||
|
||
if ( m_pServerBrowser->isVisible() )
|
||
{
|
||
m_pServerBrowser->setVisible( false );
|
||
}
|
||
else
|
||
{
|
||
m_pServerBrowser->setVisible( true );
|
||
}
|
||
|
||
UpdateCursorState();
|
||
}
|
||
|
||
//=======================================================================
|
||
void TeamFortressViewport::ShowCommandMenu(int menuIndex)
|
||
{
|
||
if (!m_iInitialized)
|
||
return;
|
||
|
||
//Already have a menu open.
|
||
if ( m_pCurrentMenu )
|
||
return;
|
||
|
||
// is the command menu open?
|
||
if ( m_pCurrentCommandMenu == m_pCommandMenus[menuIndex] )
|
||
{
|
||
HideCommandMenu();
|
||
return;
|
||
}
|
||
|
||
// Not visible while in intermission
|
||
if ( gHUD.m_iIntermission )
|
||
return;
|
||
|
||
// Recalculate visible menus
|
||
UpdateCommandMenu( menuIndex );
|
||
HideVGUIMenu();
|
||
|
||
SetCurrentCommandMenu( m_pCommandMenus[menuIndex] );
|
||
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 TeamFortressViewport::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 TeamFortressViewport::HideCommandMenu()
|
||
{
|
||
if (!m_iInitialized)
|
||
return;
|
||
|
||
if ( m_pCommandMenus[m_StandardMenu] )
|
||
{
|
||
m_pCommandMenus[m_StandardMenu]->ClearButtonsOfArmedState();
|
||
}
|
||
|
||
if ( m_pCommandMenus[m_SpectatorOptionsMenu] )
|
||
{
|
||
m_pCommandMenus[m_SpectatorOptionsMenu]->ClearButtonsOfArmedState();
|
||
}
|
||
|
||
if ( m_pCommandMenus[m_SpectatorCameraMenu] )
|
||
{
|
||
m_pCommandMenus[m_SpectatorCameraMenu]->ClearButtonsOfArmedState();
|
||
}
|
||
|
||
m_flMenuOpenTime = 0.0f;
|
||
SetCurrentCommandMenu( NULL );
|
||
UpdateCursorState();
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Purpose: Bring up the scoreboard
|
||
//-----------------------------------------------------------------------------
|
||
void TeamFortressViewport::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 TeamFortressViewport::IsScoreBoardVisible( void )
|
||
{
|
||
if (m_pScoreBoard)
|
||
return m_pScoreBoard->isVisible();
|
||
|
||
return false;
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Purpose: Hide the scoreboard
|
||
//-----------------------------------------------------------------------------
|
||
void TeamFortressViewport::HideScoreBoard( void )
|
||
{
|
||
// Prevent removal of scoreboard during intermission
|
||
if ( gHUD.m_iIntermission )
|
||
return;
|
||
|
||
if (m_pScoreBoard)
|
||
{
|
||
m_pScoreBoard->setVisible(false);
|
||
|
||
GetClientVoiceMgr()->StopSquelchMode();
|
||
|
||
UpdateCursorState();
|
||
}
|
||
}
|
||
|
||
//-----------------------------------------------------------------------------
|
||
// Purpose: Activate's the player special ability
|
||
// called when the player hits their "special" key
|
||
//-----------------------------------------------------------------------------
|
||
void TeamFortressViewport::InputPlayerSpecial( void )
|
||
{
|
||
if (!m_iInitialized)
|
||
return;
|
||
|
||
if ( g_iPlayerClass == PC_ENGINEER || g_iPlayerClass == PC_SPY )
|
||
{
|
||
ShowCommandMenu( gViewPort->m_StandardMenu );
|
||
|
||
if ( m_pCurrentCommandMenu )
|
||
{
|
||
m_pCurrentCommandMenu->KeyInput( '7' );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// if it's any other class, just send the command down to the server
|
||
ClientCmd( "_special" );
|
||
}
|
||
}
|
||
|
||
// Set the submenu of the Command Menu
|
||
void TeamFortressViewport::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 TeamFortressViewport::UpdateCommandMenu(int menuIndex)
|
||
{
|
||
m_pCommandMenus[menuIndex]->RecalculateVisibles( 0, false );
|
||
m_pCommandMenus[menuIndex]->RecalculatePositions( 0 );
|
||
}
|
||
|
||
void COM_FileBase ( const char *in, char *out);
|
||
|
||
//======================================================================
|
||
void TeamFortressViewport::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 TeamFortressViewport::CreateServerBrowser( void )
|
||
{
|
||
m_pServerBrowser = new ServerBrowser( 0, 0, ScreenWidth, ScreenHeight );
|
||
m_pServerBrowser->setParent(this);
|
||
m_pServerBrowser->setVisible(false);
|
||
}
|
||
|
||
|
||
//======================================================================
|
||
// Set the VGUI Menu
|
||
void TeamFortressViewport::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* TeamFortressViewport::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, "Half-Life" );
|
||
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 );
|
||
|
||
if (!pfile)
|
||
return NULL;
|
||
|
||
cText = pfile;
|
||
|
||
strncpy( cTitle, m_sMapName, MAX_TITLE_LENGTH );
|
||
cTitle[MAX_TITLE_LENGTH-1] = 0;
|
||
}
|
||
else if ( iTextToShow == SHOW_CLASSDESC )
|
||
{
|
||
switch ( g_iPlayerClass )
|
||
{
|
||
case PC_SCOUT: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_scout" );
|
||
CHudTextMessage::LocaliseTextString( "#Title_scout", cTitle, MAX_TITLE_LENGTH ); break;
|
||
case PC_SNIPER: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_sniper" );
|
||
CHudTextMessage::LocaliseTextString( "#Title_sniper", cTitle, MAX_TITLE_LENGTH ); break;
|
||
case PC_SOLDIER: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_soldier" );
|
||
CHudTextMessage::LocaliseTextString( "#Title_soldier", cTitle, MAX_TITLE_LENGTH ); break;
|
||
case PC_DEMOMAN: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_demoman" );
|
||
CHudTextMessage::LocaliseTextString( "#Title_demoman", cTitle, MAX_TITLE_LENGTH ); break;
|
||
case PC_MEDIC: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_medic" );
|
||
CHudTextMessage::LocaliseTextString( "#Title_medic", cTitle, MAX_TITLE_LENGTH ); break;
|
||
case PC_HVYWEAP: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_hwguy" );
|
||
CHudTextMessage::LocaliseTextString( "#Title_hwguy", cTitle, MAX_TITLE_LENGTH ); break;
|
||
case PC_PYRO: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_pyro" );
|
||
CHudTextMessage::LocaliseTextString( "#Title_pyro", cTitle, MAX_TITLE_LENGTH ); break;
|
||
case PC_SPY: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_spy" );
|
||
CHudTextMessage::LocaliseTextString( "#Title_spy", cTitle, MAX_TITLE_LENGTH ); break;
|
||
case PC_ENGINEER: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_engineer" );
|
||
CHudTextMessage::LocaliseTextString( "#Title_engineer", cTitle, MAX_TITLE_LENGTH ); break;
|
||
case PC_CIVILIAN: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_civilian" );
|
||
CHudTextMessage::LocaliseTextString( "#Title_civilian", cTitle, MAX_TITLE_LENGTH ); break;
|
||
default:
|
||
return NULL;
|
||
}
|
||
|
||
if ( g_iPlayerClass == PC_CIVILIAN )
|
||
{
|
||
sprintf(sz, "classes/long_civilian.txt");
|
||
}
|
||
else
|
||
{
|
||
sprintf(sz, "classes/long_%s.txt", sTFClassSelection[ g_iPlayerClass ]);
|
||
}
|
||
char *pfile = (char*)gEngfuncs.COM_LoadFile( sz, 5, NULL );
|
||
if (pfile)
|
||
{
|
||
cText = pfile;
|
||
}
|
||
}
|
||
else if ( iTextToShow == SHOW_SPECHELP )
|
||
{
|
||
CHudTextMessage::LocaliseTextString( "#Spec_Help_Title", cTitle, MAX_TITLE_LENGTH );
|
||
cTitle[MAX_TITLE_LENGTH-1] = 0;
|
||
|
||
char *pfile = CHudTextMessage::BufferedLocaliseTextString( "#Spec_Help_Text" );
|
||
if ( pfile )
|
||
{
|
||
cText = pfile;
|
||
}
|
||
}
|
||
|
||
// 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, g_iPlayerClass == PC_UNDEFINED, false, 0, 0, ScreenWidth, ScreenHeight );
|
||
pMOTDPanel->setParent( this );
|
||
|
||
if ( pfile )
|
||
gEngfuncs.COM_FreeFile( pfile );
|
||
|
||
return pMOTDPanel;
|
||
}
|
||
|
||
//================================================================
|
||
// VGUI Menus
|
||
void TeamFortressViewport::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_CLASSHELP:
|
||
pNewMenu = CreateTextWindow( SHOW_CLASSDESC );
|
||
break;
|
||
|
||
case MENU_SPECHELP:
|
||
pNewMenu = CreateTextWindow( SHOW_SPECHELP );
|
||
break;
|
||
// case MENU_CLASS:
|
||
// pNewMenu = ShowClassMenu();
|
||
// 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)
|
||
{
|
||
if ( m_pCurrentMenu->GetMenuID() == MENU_CLASS && iMenu == MENU_TEAM )
|
||
{
|
||
CMenuPanel *temp = m_pCurrentMenu;
|
||
m_pCurrentMenu->Close();
|
||
m_pCurrentMenu = pNewMenu;
|
||
m_pCurrentMenu->SetNextMenu( temp );
|
||
m_pCurrentMenu->Open();
|
||
UpdateCursorState();
|
||
}
|
||
else
|
||
{
|
||
m_pCurrentMenu->SetNextMenu( pNewMenu );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
m_pCurrentMenu = pNewMenu;
|
||
m_pCurrentMenu->Open();
|
||
UpdateCursorState();
|
||
}
|
||
}
|
||
|
||
// Removes all VGUI Menu's onscreen
|
||
void TeamFortressViewport::HideVGUIMenu()
|
||
{
|
||
while (m_pCurrentMenu)
|
||
{
|
||
HideTopMenu();
|
||
}
|
||
}
|
||
|
||
// Remove the top VGUI menu, and bring up the next one
|
||
void TeamFortressViewport::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 TeamFortressViewport::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_CLASS || iId == MENU_INTRO || iId == MENU_CLASSHELP )
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
//======================================================================================
|
||
// TEAM MENU
|
||
//======================================================================================
|
||
// Bring up the Team selection Menu
|
||
/*CMenuPanel* TeamFortressViewport::ShowTeamMenu()
|
||
{
|
||
// Don't open menus in demo playback
|
||
if ( gEngfuncs.pDemoAPI->IsPlayingback() )
|
||
return NULL;
|
||
|
||
m_pTeamMenu->Reset();
|
||
return m_pTeamMenu;
|
||
}
|
||
|
||
void TeamFortressViewport::CreateTeamMenu()
|
||
{
|
||
// Create the panel
|
||
m_pTeamMenu = new CTeamMenuPanel(100, false, 0, 0, ScreenWidth, ScreenHeight);
|
||
m_pTeamMenu->setParent( this );
|
||
m_pTeamMenu->setVisible( false );
|
||
}*/
|
||
|
||
//======================================================================================
|
||
// CLASS MENU
|
||
//======================================================================================
|
||
// Bring up the Class selection Menu
|
||
/*CMenuPanel* TeamFortressViewport::ShowClassMenu()
|
||
{
|
||
// Don't open menus in demo playback
|
||
if ( gEngfuncs.pDemoAPI->IsPlayingback() )
|
||
return NULL;
|
||
|
||
m_pClassMenu->Reset();
|
||
return m_pClassMenu;
|
||
}
|
||
|
||
void TeamFortressViewport::CreateClassMenu()
|
||
{
|
||
// Create the panel
|
||
m_pClassMenu = new CClassMenuPanel(100, false, 0, 0, ScreenWidth, ScreenHeight);
|
||
m_pClassMenu->setParent(this);
|
||
m_pClassMenu->setVisible( false );
|
||
}*/
|
||
|
||
//======================================================================================
|
||
//======================================================================================
|
||
// SPECTATOR MENU
|
||
//======================================================================================
|
||
// Spectator "Menu" explaining the Spectator buttons
|
||
/*void TeamFortressViewport::CreateSpectatorMenu()
|
||
{
|
||
// Create the Panel
|
||
m_pSpectatorPanel = new SpectatorPanel(0, 0, ScreenWidth, ScreenHeight);
|
||
m_pSpectatorPanel->setParent(this);
|
||
m_pSpectatorPanel->setVisible(false);
|
||
m_pSpectatorPanel->Initialize();
|
||
}*/
|
||
|
||
//======================================================================================
|
||
// UPDATE HUD SECTIONS
|
||
//======================================================================================
|
||
// We've got an update on player info
|
||
// Recalculate any menus that use it.
|
||
void TeamFortressViewport::UpdateOnPlayerInfo()
|
||
{
|
||
// if (m_pTeamMenu)
|
||
// m_pTeamMenu->Update();
|
||
// if (m_pClassMenu)
|
||
// m_pClassMenu->Update();
|
||
if (m_pScoreBoard)
|
||
m_pScoreBoard->Update();
|
||
}
|
||
|
||
void TeamFortressViewport::UpdateCursorState()
|
||
{
|
||
// Need cursor if any VGUI window is up
|
||
// if ( /*m_pSpectatorPanel->m_menuVisible ||*/ m_pCurrentMenu || /*m_pTeamMenu->isVisible() ||*/ m_pServerBrowser->isVisible() || GetClientVoiceMgr()->IsInSquelchMode() )
|
||
if (m_pParanoiaText && m_pParanoiaText->isVisible())
|
||
{
|
||
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;
|
||
}
|
||
}
|
||
|
||
// Don't reset mouse in demo playback
|
||
if ( !gEngfuncs.pDemoAPI->IsPlayingback() )
|
||
{
|
||
IN_ResetMouse();
|
||
}
|
||
|
||
g_iVisibleMouse = false;
|
||
App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::SchemeCursor::scu_none) );
|
||
}
|
||
|
||
void TeamFortressViewport::UpdateHighlights()
|
||
{
|
||
if (m_pCurrentCommandMenu)
|
||
m_pCurrentCommandMenu->MakeVisible( NULL );
|
||
}
|
||
|
||
void TeamFortressViewport::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 TeamFortressViewport::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_StandardMenu );
|
||
|
||
// if ( m_pClassMenu )
|
||
// {
|
||
// m_pClassMenu->Update();
|
||
// }
|
||
|
||
m_iCurrentTeamNumber = g_iTeamNumber;
|
||
}
|
||
|
||
if ( g_iPlayerClass != m_iCurrentPlayerClass )
|
||
{
|
||
UpdateCommandMenu( m_StandardMenu );
|
||
|
||
m_iCurrentPlayerClass = g_iPlayerClass;
|
||
}
|
||
|
||
// See if the Spectator Menu needs to be update
|
||
// if ( ( g_iUser1 != m_iUser1 || g_iUser2 != m_iUser2 ) ||
|
||
// ( m_flSpectatorPanelLastUpdated < gHUD.m_flTime ) )
|
||
// {
|
||
// UpdateSpectatorPanel();
|
||
// }
|
||
|
||
// 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 TeamFortressViewport::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 TeamFortressViewport::KeyInput( int down, int keynum, const char *pszCurrentBinding )
|
||
{
|
||
// buz
|
||
if (m_pParanoiaText && m_pParanoiaText->isVisible())
|
||
return m_pParanoiaText->KeyInput(down, keynum, pszCurrentBinding);
|
||
|
||
// buz
|
||
if ( down && m_pTabPanel && ( keynum == K_TAB ) && gEngfuncs.GetMaxClients() == 1 )
|
||
return m_pTabPanel->Toggle();
|
||
|
||
// 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 || iMenuID == MENU_CLASS)
|
||
{
|
||
// Escape gets you out of Team/Class menus if the Cancel button is visible
|
||
if ( keynum == K_ESCAPE )
|
||
{
|
||
if ( (iMenuID == MENU_TEAM && g_iTeamNumber) || (iMenuID == MENU_CLASS && g_iPlayerClass) )
|
||
{
|
||
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 || iMenuID == MENU_CLASSHELP )
|
||
{
|
||
HideTopMenu();
|
||
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 TeamFortressViewport::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( m_StandardMenu );
|
||
|
||
return 1;
|
||
}
|
||
|
||
int TeamFortressViewport::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 TeamFortressViewport::MsgFunc_Feign(const char *pszName, int iSize, void *pbuf )
|
||
{
|
||
BEGIN_READ( pbuf, iSize );
|
||
|
||
m_iIsFeigning = READ_BYTE();
|
||
|
||
// Force the menu to update
|
||
UpdateCommandMenu( m_StandardMenu );
|
||
|
||
return 1;
|
||
}
|
||
|
||
int TeamFortressViewport::MsgFunc_Detpack(const char *pszName, int iSize, void *pbuf )
|
||
{
|
||
BEGIN_READ( pbuf, iSize );
|
||
|
||
m_iIsSettingDetpack = READ_BYTE();
|
||
|
||
// Force the menu to update
|
||
UpdateCommandMenu( m_StandardMenu );
|
||
|
||
return 1;
|
||
}
|
||
|
||
int TeamFortressViewport::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 TeamFortressViewport::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';
|
||
|
||
// don't show MOTD for HLTV spectators
|
||
if ( m_iGotAllMOTD && !gEngfuncs.IsSpectateOnly() )
|
||
{
|
||
ShowVGUIMenu( MENU_INTRO );
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
|
||
int TeamFortressViewport::MsgFunc_BuildSt( const char *pszName, int iSize, void *pbuf )
|
||
{
|
||
BEGIN_READ( pbuf, iSize );
|
||
|
||
m_iBuildState = READ_BYTE();
|
||
|
||
// Force the menu to update
|
||
UpdateCommandMenu( m_StandardMenu );
|
||
|
||
return 1;
|
||
}
|
||
|
||
int TeamFortressViewport::MsgFunc_RandomPC( const char *pszName, int iSize, void *pbuf )
|
||
{
|
||
BEGIN_READ( pbuf, iSize );
|
||
|
||
m_iRandomPC = READ_BYTE();
|
||
|
||
return 1;
|
||
}
|
||
|
||
int TeamFortressViewport::MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf )
|
||
{
|
||
BEGIN_READ( pbuf, iSize );
|
||
|
||
strncpy( m_szServerName, READ_STRING(), MAX_SERVERNAME_LENGTH );
|
||
|
||
return 1;
|
||
}
|
||
|
||
int TeamFortressViewport::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 playerclass = 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].playerclass = playerclass;
|
||
g_PlayerExtraInfo[cl].teamnumber = teamnumber;
|
||
|
||
//Dont go bellow 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 TeamFortressViewport::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 TeamFortressViewport::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 TeamFortressViewport::DeathMsg( int killer, int victim )
|
||
{
|
||
m_pScoreBoard->DeathMsg(killer,victim);
|
||
}
|
||
|
||
int TeamFortressViewport::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 TeamFortressViewport::MsgFunc_AllowSpec( const char *pszName, int iSize, void *pbuf )
|
||
{
|
||
BEGIN_READ( pbuf, iSize );
|
||
|
||
m_iAllowSpectators = READ_BYTE();
|
||
|
||
// Force the menu to update
|
||
UpdateCommandMenu( m_StandardMenu );
|
||
|
||
// If the team menu is up, update it too
|
||
// if (m_pTeamMenu)
|
||
// m_pTeamMenu->Update();
|
||
|
||
return 1;
|
||
}
|
||
|
||
|
||
// buz: text windows
|
||
int TeamFortressViewport::MsgFunc_ShowTextWindow(const char *pszName, int iSize, void *pbuf )
|
||
{
|
||
BEGIN_READ( pbuf, iSize );
|
||
|
||
// only one parameter - text file name
|
||
char* str = READ_STRING();
|
||
|
||
if (m_pParanoiaText)
|
||
{
|
||
if (strcmp(m_pParanoiaText->m_loadedFileName, str))
|
||
{
|
||
removeChild(m_pParanoiaText);
|
||
m_pParanoiaText = new CParanoiaTextPanel(str);
|
||
m_pParanoiaText->setParent(this);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
m_pParanoiaText = new CParanoiaTextPanel(str);
|
||
m_pParanoiaText->setParent(this);
|
||
}
|
||
|
||
m_pParanoiaText->setVisible(true);
|
||
m_pParanoiaText->ResetBackground();
|
||
UpdateCursorState();
|
||
return 1;
|
||
}
|
||
|
||
//===========================================
|
||
// buz: pickup messages system
|
||
//
|
||
// works similar to half-life's ammohistory, but uses text instead of images
|
||
//===========================================
|
||
|
||
void TeamFortressViewport::CreatePickupMessagePanels()
|
||
{
|
||
m_iCurrentPickupMessage = 0;
|
||
int h = PICKUP_MESSAGES_MINHEIGHT;
|
||
for (int i = 0; i < MAX_PICKUP_MESSAGES; i++)
|
||
{
|
||
m_pPickupMessages[i] = new CPickupMessage( h );
|
||
m_pPickupMessages[i]->setParent(this);
|
||
h -= PICKUP_MESSAGES_DISTANCE;
|
||
}
|
||
}
|
||
|
||
|
||
// hide all messages when another map starts
|
||
void TeamFortressViewport::InitializePickupMessagePanels()
|
||
{
|
||
m_iCurrentPickupMessage = 0;
|
||
for (int i = 0; i < MAX_PICKUP_MESSAGES; i++)
|
||
{
|
||
if (m_pPickupMessages[i])
|
||
m_pPickupMessages[i]->Initialize();
|
||
}
|
||
}
|
||
|
||
|
||
// reset m_iCurrentPickupMessage to zero when no active messages
|
||
void TeamFortressViewport::CheckCurrentPickupMessagePanel()
|
||
{
|
||
for (int i = 0; i < MAX_PICKUP_MESSAGES; i++)
|
||
{
|
||
if (m_pPickupMessages[i])
|
||
{
|
||
if (m_pPickupMessages[i]->isVisible())
|
||
return;
|
||
}
|
||
}
|
||
|
||
m_iCurrentPickupMessage = 0;
|
||
}
|
||
|
||
void CheckPanel()
|
||
{
|
||
gViewPort->CheckCurrentPickupMessagePanel();
|
||
}
|
||
|
||
|
||
void TeamFortressViewport::AddPickupMessage( client_textmessage_t *msg )
|
||
{
|
||
CPickupMessage *msgpanel = m_pPickupMessages[m_iCurrentPickupMessage];
|
||
if (msgpanel)
|
||
{
|
||
msgpanel->SetMessage(msg);
|
||
m_iCurrentPickupMessage++;
|
||
if (m_iCurrentPickupMessage >= MAX_PICKUP_MESSAGES)
|
||
m_iCurrentPickupMessage = 0;
|
||
}
|
||
else
|
||
CONPRINT("ACHTUNG! pickup msgpanel is not created!\n");
|
||
}
|
||
|
||
|
||
// link to world
|
||
void VGuiAddPickupMessage( client_textmessage_t *msg )
|
||
{
|
||
if (gViewPort)
|
||
gViewPort->AddPickupMessage( msg );
|
||
else
|
||
gEngfuncs.Con_Printf("Pickup message error: Viewport is not constructed!\n");
|
||
} |