halflife-sdk/cl_dll/vgui_teammenu.cpp
2000-06-05 00:00:00 +00:00

389 lines
12 KiB
C++

//=========== (C) Copyright 1999 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: TFC Team Menu
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================
#include "vgui_int.h"
#include "VGUI_Font.h"
#include "VGUI_ScrollPanel.h"
#include "VGUI_TextImage.h"
#include "hud.h"
#include "cl_util.h"
#include "vgui_TeamFortressViewport.h"
// Team Menu Dimensions
#define TEAMMENU_TITLE_X XRES(40)
#define TEAMMENU_TITLE_Y YRES(32)
#define TEAMMENU_TOPLEFT_BUTTON_X XRES(40)
#define TEAMMENU_TOPLEFT_BUTTON_Y YRES(80)
#define TEAMMENU_BUTTON_SIZE_X XRES(124)
#define TEAMMENU_BUTTON_SIZE_Y YRES(24)
#define TEAMMENU_BUTTON_SPACER_Y YRES(8)
#define TEAMMENU_WINDOW_X XRES(176)
#define TEAMMENU_WINDOW_Y YRES(80)
#define TEAMMENU_WINDOW_SIZE_X XRES(424)
#define TEAMMENU_WINDOW_SIZE_Y YRES(312)
#define TEAMMENU_WINDOW_TITLE_X XRES(16)
#define TEAMMENU_WINDOW_TITLE_Y YRES(16)
#define TEAMMENU_WINDOW_TEXT_X XRES(16)
#define TEAMMENU_WINDOW_TEXT_Y YRES(48)
#define TEAMMENU_WINDOW_TEXT_SIZE_Y YRES(178)
#define TEAMMENU_WINDOW_INFO_X XRES(16)
#define TEAMMENU_WINDOW_INFO_Y YRES(234)
// Creation
CTeamMenuPanel::CTeamMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide,int tall) : CMenuPanel(iTrans, iRemoveMe, x,y,wide,tall)
{
// Get the scheme used for the Titles
CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
// schemes
SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" );
SchemeHandle_t hTeamWindowText = pSchemes->getSchemeHandle( "Briefing Text" );
SchemeHandle_t hTeamInfoText = pSchemes->getSchemeHandle( "Team Info Text" );
// get the Font used for the Titles
Font *pTitleFont = pSchemes->getFont( hTitleScheme );
int r, g, b, a;
// Create the title
Label *pLabel = new Label( "", TEAMMENU_TITLE_X, TEAMMENU_TITLE_Y );
pLabel->setParent( this );
pLabel->setFont( pTitleFont );
pSchemes->getFgColor( hTitleScheme, r, g, b, a );
pLabel->setFgColor( r, g, b, a );
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
pLabel->setBgColor( r, g, b, a );
pLabel->setContentAlignment( vgui::Label::a_west );
pLabel->setText(gHUD.m_TextMessage.BufferedLocaliseTextString("#Title_SelectYourTeam"));
// Create the Info Window
m_pTeamWindow = new CTransparentPanel( 255, TEAMMENU_WINDOW_X, TEAMMENU_WINDOW_Y, TEAMMENU_WINDOW_SIZE_X, TEAMMENU_WINDOW_SIZE_Y );
m_pTeamWindow->setParent( this );
m_pTeamWindow->setBorder( new LineBorder( Color(255*0.7,170*0.7,0,0 )) );
// Create the Map Name Label
m_pMapTitle = new Label( "", TEAMMENU_WINDOW_TITLE_X, TEAMMENU_WINDOW_TITLE_Y );
m_pMapTitle->setFont( pTitleFont );
m_pMapTitle->setParent( m_pTeamWindow );
pSchemes->getFgColor( hTitleScheme, r, g, b, a );
m_pMapTitle->setFgColor( r, g, b, a );
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
m_pMapTitle->setBgColor( r, g, b, a );
m_pMapTitle->setContentAlignment( vgui::Label::a_west );
// Create the Scroll panel
m_pScrollPanel = new CTFScrollPanel( TEAMMENU_WINDOW_TEXT_X, TEAMMENU_WINDOW_TEXT_Y, TEAMMENU_WINDOW_SIZE_X - (TEAMMENU_WINDOW_TEXT_X * 2), TEAMMENU_WINDOW_TEXT_SIZE_Y );
m_pScrollPanel->setParent(m_pTeamWindow);
m_pScrollPanel->setScrollBarVisible(false, false);
// Create the Map Briefing panel
m_pBriefing = new TextPanel("", 0,0, TEAMMENU_WINDOW_SIZE_X - TEAMMENU_WINDOW_TEXT_X, TEAMMENU_WINDOW_TEXT_SIZE_Y );
m_pBriefing->setParent( m_pScrollPanel->getClient() );
m_pBriefing->setFont( pSchemes->getFont(hTeamWindowText) );
pSchemes->getFgColor( hTeamWindowText, r, g, b, a );
m_pBriefing->setFgColor( r, g, b, a );
pSchemes->getBgColor( hTeamWindowText, r, g, b, a );
m_pBriefing->setBgColor( r, g, b, a );
m_pBriefing->setText("Map Description not available.");
// Team Menu buttons
for (int i = 1; i <= 5; i++)
{
char sz[256];
int iYPos = TEAMMENU_TOPLEFT_BUTTON_Y + ( (TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y) * i );
// Team button
m_pButtons[i] = new CommandButton( "", TEAMMENU_TOPLEFT_BUTTON_X, iYPos, TEAMMENU_BUTTON_SIZE_X, TEAMMENU_BUTTON_SIZE_Y, true);
m_pButtons[i]->setParent( this );
m_pButtons[i]->setContentAlignment( vgui::Label::a_west );
m_pButtons[i]->setVisible( false );
// AutoAssign button uses special case
if (i == 5)
{
m_pButtons[5]->setBoundKey( '5' );
m_pButtons[5]->setText( gHUD.m_TextMessage.BufferedLocaliseTextString("#Team_AutoAssign") );
m_pButtons[5]->setVisible( true );
}
// Create the Signals
sprintf(sz, "jointeam %d", i);
m_pButtons[i]->addActionSignal( new CMenuHandler_StringCommandWatch( sz, true ) );
m_pButtons[i]->addInputSignal( new CHandler_MenuButtonOver(this, i) );
// Create the Team Info panel
m_pTeamInfoPanel[i] = new TextPanel("", TEAMMENU_WINDOW_INFO_X, TEAMMENU_WINDOW_INFO_Y, TEAMMENU_WINDOW_SIZE_X - TEAMMENU_WINDOW_INFO_X, TEAMMENU_WINDOW_SIZE_X - TEAMMENU_WINDOW_INFO_Y );
m_pTeamInfoPanel[i]->setParent( m_pTeamWindow );
m_pTeamInfoPanel[i]->setFont( pSchemes->getFont(hTeamInfoText) );
m_pTeamInfoPanel[i]->setFgColor( iTeamColors[i][0], iTeamColors[i][1], iTeamColors[i][2], 0 );
m_pTeamInfoPanel[i]->setBgColor( 0,0,0, 255 );
}
// Create the Cancel button
m_pCancelButton = new CommandButton( CHudTextMessage::BufferedLocaliseTextString( "#Menu_Cancel" ), TEAMMENU_TOPLEFT_BUTTON_X, 0, TEAMMENU_BUTTON_SIZE_X, TEAMMENU_BUTTON_SIZE_Y);
m_pCancelButton->setParent( this );
m_pCancelButton->addActionSignal( new CMenuHandler_TextWindow(HIDE_TEXTWINDOW) );
// Create the Spectate button
m_pSpectateButton = new SpectateButton( CHudTextMessage::BufferedLocaliseTextString( "#Menu_Spectate" ), TEAMMENU_TOPLEFT_BUTTON_X, 0, TEAMMENU_BUTTON_SIZE_X, TEAMMENU_BUTTON_SIZE_Y, true);
m_pSpectateButton->setParent( this );
m_pSpectateButton->addActionSignal( new CMenuHandler_StringCommand( "spectate", true ) );
m_pSpectateButton->setBoundKey( '6' );
m_pSpectateButton->addInputSignal( new CHandler_MenuButtonOver(this, 6) );
Initialize();
}
//-----------------------------------------------------------------------------
// Purpose: Called each time a new level is started.
//-----------------------------------------------------------------------------
void CTeamMenuPanel::Initialize( void )
{
m_bUpdatedMapName = false;
m_iCurrentInfo = 0;
m_pScrollPanel->setScrollValue( 0, 0 );
}
//-----------------------------------------------------------------------------
// Purpose: Called everytime the Team Menu is displayed
//-----------------------------------------------------------------------------
void CTeamMenuPanel::Update( void )
{
int iYPos = TEAMMENU_TOPLEFT_BUTTON_Y;
// Set the team buttons
for (int i = 1; i <= 4; i++)
{
if (m_pButtons[i])
{
if ( i <= gViewPort->GetNumberOfTeams() )
{
m_pButtons[i]->setText( gViewPort->GetTeamName(i) );
// bound key replacement
char sz[32];
sprintf( sz, "%d", i );
m_pButtons[i]->setBoundKey( sz[0] );
m_pButtons[i]->setVisible( true );
m_pButtons[i]->setPos( TEAMMENU_TOPLEFT_BUTTON_X, iYPos );
iYPos += TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y;
// Start with the first option up
if (!m_iCurrentInfo)
SetActiveInfo( i );
char szPlayerList[ (MAX_PLAYER_NAME_LENGTH + 3) * 31 ]; // name + ", "
strcpy(szPlayerList, "\n");
// Update the Team Info
// Now count the number of teammembers of this class
int iTotal = 0;
for ( int j = 1; j < MAX_PLAYERS; j++ )
{
if ( g_PlayerInfoList[j].name == NULL )
continue; // empty player slot, skip
if ( g_PlayerInfoList[j].thisplayer )
continue; // skip this player
if ( g_PlayerExtraInfo[j].teamnumber != i )
continue; // skip over players in other teams
iTotal++;
if (iTotal > 1)
strncat( szPlayerList, ", ", sizeof(szPlayerList) - strlen(szPlayerList) );
strncat( szPlayerList, g_PlayerInfoList[j].name, sizeof(szPlayerList) - strlen(szPlayerList) );
szPlayerList[ sizeof(szPlayerList) - 1 ] = '\0';
}
if (iTotal > 0)
{
// Set the text of the info Panel
char szText[ ((MAX_PLAYER_NAME_LENGTH + 3) * 31) + 256 ];
if (iTotal == 1)
sprintf(szText, "%s: %d Player (%d points)", gViewPort->GetTeamName(i), iTotal, g_TeamInfo[i].frags );
else
sprintf(szText, "%s: %d Players (%d points)", gViewPort->GetTeamName(i), iTotal, g_TeamInfo[i].frags );
strncat( szText, szPlayerList, sizeof(szText) - strlen(szText) );
szText[ sizeof(szText) - 1 ] = '\0';
m_pTeamInfoPanel[i]->setText( szText );
}
else
{
m_pTeamInfoPanel[i]->setText( "" );
}
}
else
{
// Hide the button (may be visible from previous maps)
m_pButtons[i]->setVisible( false );
}
}
}
// Move the AutoAssign button into place
m_pButtons[5]->setPos( TEAMMENU_TOPLEFT_BUTTON_X, iYPos );
iYPos += TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y;
// Spectate button
if (m_pSpectateButton->IsNotValid())
{
m_pSpectateButton->setVisible( false );
}
else
{
m_pSpectateButton->setPos( TEAMMENU_TOPLEFT_BUTTON_X, iYPos );
m_pSpectateButton->setVisible( true );
iYPos += TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y;
}
// If the player is already in a team, make the cancel button visible
if ( g_iTeamNumber )
{
m_pCancelButton->setPos( TEAMMENU_TOPLEFT_BUTTON_X, iYPos );
iYPos += TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y;
m_pCancelButton->setVisible( true );
}
else
{
m_pCancelButton->setVisible( false );
}
// Set the Map Title
if (!m_bUpdatedMapName)
{
const char *level = gEngfuncs.pfnGetLevelName();
if (level && level[0])
{
char sz[256];
char szTitle[256];
char *ch;
// Update the level name
strcpy( sz, level );
ch = strchr( sz, '/' );
if (!ch)
ch = strchr( sz, '\\' );
strcpy( szTitle, ch+1 );
ch = strchr( szTitle, '.' );
*ch = '\0';
m_pMapTitle->setText( szTitle );
*ch = '.';
// Update the map briefing
strcpy( sz, level );
ch = strchr( sz, '.' );
*ch = '\0';
strcat( sz, ".txt" );
char *pfile = (char*)gEngfuncs.COM_LoadFile( sz, 5, NULL );
if (pfile)
{
m_pBriefing->setText( pfile );
// Get the total size of the Briefing text and resize the text panel
int iXSize, iYSize;
m_pBriefing->getTextImage()->getTextSize( iXSize, iYSize );
m_pBriefing->setSize( iXSize, iYSize );
}
m_bUpdatedMapName = true;
}
}
m_pScrollPanel->validate();
}
//=====================================
// Key inputs
bool CTeamMenuPanel::SlotInput( int iSlot )
{
// Check for AutoAssign
if ( iSlot == 5)
{
m_pButtons[5]->fireActionSignal();
return true;
}
// Spectate
if ( iSlot == 6)
{
m_pSpectateButton->fireActionSignal();
return true;
}
// Otherwise, see if a particular team is selectable
if ( (iSlot < 1) || (iSlot > gViewPort->GetNumberOfTeams()) )
return false;
if ( !m_pButtons[ iSlot ] )
return false;
// Is the button pushable?
if ( m_pButtons[ iSlot ]->isVisible() )
{
m_pButtons[ iSlot ]->fireActionSignal();
return true;
}
return false;
}
//======================================
// Update the Team menu before opening it
void CTeamMenuPanel::Open( void )
{
Update();
CMenuPanel::Open();
}
void CTeamMenuPanel::paintBackground()
{
// make sure we get the map briefing up
if ( !m_bUpdatedMapName )
Update();
CMenuPanel::paintBackground();
}
//======================================
// Mouse is over a team button, bring up the class info
void CTeamMenuPanel::SetActiveInfo( int iInput )
{
// Remove all the Info panels and bring up the specified one
m_pSpectateButton->setArmed( false );
for (int i = 1; i <= 5; i++)
{
m_pButtons[i]->setArmed( false );
m_pTeamInfoPanel[i]->setVisible( false );
}
// 6 is Spectate
if (iInput == 6)
{
m_pSpectateButton->setArmed( true );
}
else
{
m_pButtons[iInput]->setArmed( true );
m_pTeamInfoPanel[iInput]->setVisible( true );
}
m_iCurrentInfo = iInput;
m_pScrollPanel->validate();
}