/// =============== Fortress Forever ==============/// ======== A modification for Half-Life 2 =======////// @file teammenu.cpp/// @author Gavin "Mirvin_Monkey" Bramhill/// @date August 15, 2005/// @brief New team selection menu////// REVISIONS/// ---------/// Aug 15, 2005 Mirv: First creation#include "cbase.h"#include "teammenu.h"#include #include #include #include #include #include #include #include #include #include #include #include #include #include "ff_menu_panel.h"#include #include #include "IGameUIFuncs.h"#include "ienginevgui.h"#include "c_team.h"#include "ff_utils.h"#include "ff_button.h"// memdbgon must be the last include file in a .cpp file!!!#include "tier0/memdbgon.h"
using namespace vgui;void UpdateCursorState();// void DuckMessage(const char *str);// helper functionconst char *GetStringTeamColor( int i ){ switch( i ) { case 0: return "team0"; case 1: return "team1"; case 2: return "team2"; case 3: return "team3"; case 4: default: return "team4"; }}//-----------------------------------------------------------------------------// Purpose: Constructor//-----------------------------------------------------------------------------CTeamMenu::CTeamMenu(IViewPort *pViewPort) : Frame(NULL, PANEL_TEAM ){ m_pViewPort = pViewPort; m_iJumpKey = -1; // this is looked up in Activate() m_iScoreBoardKey = -1; // this is looked up in Activate() // initialize dialog SetTitle("", true); // load the new scheme early!! SetScheme("ClientScheme"); SetMoveable(false); SetSizeable(false); // hide the system buttons SetTitleBarVisible( false ); SetProportional(true); // info window about this map m_pMapInfo = new RichText( this, "MapInfo" ); m_pMapInfoHTML = new HTML( this, "MapInfoHTML"); LoadControlSettings("Resource/UI/TeamMenu.res"); InvalidateLayout(); m_szMapName[0] = 0;}//-----------------------------------------------------------------------------// Purpose: Destructor//-----------------------------------------------------------------------------CTeamMenu::~CTeamMenu(){}//-----------------------------------------------------------------------------// Purpose: sets the text color of the map description field//-----------------------------------------------------------------------------void CTeamMenu::ApplySchemeSettings(IScheme *pScheme){ BaseClass::ApplySchemeSettings(pScheme); m_pMapInfo->SetFgColor( pScheme->GetColor("MapDescriptionText", Color(255, 255, 255, 0)) ); if ( *m_szMapName ) { LoadMapPage( m_szMapName ); // reload the map description to pick up the color }}//-----------------------------------------------------------------------------// Purpose: makes the user choose the auto assign option//-----------------------------------------------------------------------------void CTeamMenu::AutoAssign(){ engine->ClientCmd("jointeam 0");}//-----------------------------------------------------------------------------// Purpose: shows the team menu//-----------------------------------------------------------------------------void CTeamMenu::ShowPanel(bool bShow){ if ( BaseClass::IsVisible() == bShow ) return; if ( bShow ) { Activate(); SetMouseInputEnabled( true ); // get key bindings if shown if( m_iJumpKey < 0 ) // you need to lookup the jump key AFTER the engine has loaded { m_iJumpKey = gameuifuncs->GetEngineKeyCodeForBind( "jump" ); } if ( m_iScoreBoardKey < 0 ) { m_iScoreBoardKey = gameuifuncs->GetEngineKeyCodeForBind( "showscores" ); } } else { SetVisible( false ); SetMouseInputEnabled( false ); } m_pViewPort->ShowBackGround( bShow );}//-----------------------------------------------------------------------------// Purpose: updates the UI with a new map name and map html page, and sets up the team buttons//-----------------------------------------------------------------------------void CTeamMenu::Update(){ char mapname[MAX_MAP_NAME]; Q_FileBase( engine->GetLevelName(), mapname, sizeof(mapname) ); SetLabelText( "mapname", mapname ); LoadMapPage( mapname );}//-----------------------------------------------------------------------------// Purpose: chooses and loads the text page to display that describes mapName map//-----------------------------------------------------------------------------void CTeamMenu::LoadMapPage( const char *mapName ){ // Save off the map name so we can re-load the page in ApplySchemeSettings(). Q_strncpy( m_szMapName, mapName, strlen( mapName ) + 1 ); char mapRES[ MAX_PATH ]; char uilanguage[ 64 ]; engine->GetUILanguage( uilanguage, sizeof( uilanguage ) ); Q_snprintf( mapRES, sizeof( mapRES ), "resource/maphtml/%s_%s.html", mapName, uilanguage ); bool bFoundHTML = false; if ( !vgui::filesystem()->FileExists( mapRES ) ) { // try english Q_snprintf( mapRES, sizeof( mapRES ), "resource/maphtml/%s_english.html", mapName ); } else { bFoundHTML = true; } if( bFoundHTML || vgui::filesystem()->FileExists( mapRES ) ) { // it's a local HTML file char localURL[ _MAX_PATH + 7 ]; Q_strncpy( localURL, "file://", sizeof( localURL ) ); char pPathData[ _MAX_PATH ]; vgui::filesystem()->GetLocalPath( mapRES, pPathData, sizeof(pPathData) ); Q_strncat( localURL, pPathData, sizeof( localURL ), COPY_ALL_CHARACTERS ); // force steam to dump a local copy vgui::filesystem()->GetLocalCopy( pPathData ); m_pMapInfo->SetVisible( false ); m_pMapInfoHTML->SetVisible( true ); m_pMapInfoHTML->OpenURL( localURL ); InvalidateLayout(); Repaint(); return; } else { m_pMapInfo->SetVisible( true ); m_pMapInfoHTML->SetVisible( false ); } Q_snprintf( mapRES, sizeof( mapRES ), "maps/%s.txt", mapName); // if no map specific description exists, load default text if( !vgui::filesystem()->FileExists( mapRES ) ) { if ( vgui::filesystem()->FileExists( "maps/default.txt" ) ) { Q_snprintf ( mapRES, sizeof( mapRES ), "maps/default.txt"); } else { m_pMapInfo->SetText( "" ); return; } } FileHandle_t f = vgui::filesystem()->Open( mapRES, "r" ); // read into a memory block int fileSize = vgui::filesystem()->Size(f); int dataSize = fileSize + sizeof( wchar_t ); if ( dataSize % 2 ) ++dataSize; wchar_t *memBlock = (wchar_t *)malloc(dataSize); memset( memBlock, 0x0, dataSize); int bytesRead = vgui::filesystem()->Read(memBlock, fileSize, f); if ( bytesRead < fileSize ) { // NULL-terminate based on the length read in, since Read() can transform \r\n to \n and // return fewer bytes than we were expecting. char *data = reinterpret_cast( memBlock ); data[ bytesRead ] = 0; data[ bytesRead+1 ] = 0; } // null-terminate the stream (redundant, since we memset & then trimmed the transformed buffer already) memBlock[dataSize / sizeof(wchar_t) - 1] = 0x0000; // check the first character, make sure this a little-endian unicode file if (memBlock[0] != 0xFEFF) { // its a ascii char file m_pMapInfo->SetText( reinterpret_cast( memBlock ) ); } else { m_pMapInfo->SetText( memBlock+1 ); } // go back to the top of the text buffer m_pMapInfo->GotoTextStart(); vgui::filesystem()->Close( f ); free(memBlock); InvalidateLayout(); Repaint();}/*//-----------------------------------------------------------------------------// Purpose: sets the text on and displays the team buttons//-----------------------------------------------------------------------------void CTeamMenu::MakeTeamButtons(void){ int i = 0; for( i = 0; i< m_pTeamButtons.Count(); i++ ) { m_pTeamButtons[i]->SetVisible(false); } i = 0; while( true ) { const char *teamname = GameResources()->GetTeamName( i ); if ( !teamname || !teamname[0] ) return; // no more teams char buttonText[32]; Q_snprintf( buttonText, sizeof(buttonText), "&%i %s", i +1, teamname ); m_pTeamButtons[i]->SetText( buttonText ); m_pTeamButtons[i]->SetCommand( new KeyValues("TeamButton", "team", i ) ); IScheme *pScheme = scheme()->GetIScheme( GetScheme() ); m_pTeamButtons[i]->SetArmedColor(pScheme->GetColor(GetStringTeamColor(i), Color(255, 255, 255, 255)) , pScheme->GetColor("SelectionBG", Color(255, 255, 255, 0)) ); m_pTeamButtons[i]->SetDepressedColor( pScheme->GetColor(GetStringTeamColor(i), Color(255, 255, 255, 255)), pScheme->GetColor("ButtonArmedBgColor", Color(255, 255, 255, 0)) ); m_pTeamButtons[i]->SetDefaultColor( pScheme->GetColor(GetStringTeamColor(i), Color(255, 255, 255, 255)), pScheme->GetColor("ButtonDepressedBgColor", Color(255, 255, 255, 0)) ); m_pTeamButtons[i]->SetVisible(true); i++; }} //-----------------------------------------------------------------------------// Purpose: When a team button is pressed it triggers this function to cause the player to join a team//-----------------------------------------------------------------------------void CTeamMenu::OnTeamButton( int team ){ char cmd[64]; if( team >= m_iNumTeams ) // its a special button { if( team == m_iNumTeams ) // first extra team is auto assign { Q_snprintf( cmd, sizeof( cmd ), "jointeam 5" ); } else // next is spectate { // DuckMessage( "#Spec_Duck" ); gViewPortInterface->ShowBackGround( false ); } } else { Q_snprintf( cmd, sizeof( cmd ), "jointeam %i", team + 1 ); //g_iTeamNumber = team + 1; } engine->ClientCmd(cmd); SetVisible( false ); OnClose();} *///-----------------------------------------------------------------------------// Purpose: Sets the text of a control by name//-----------------------------------------------------------------------------void CTeamMenu::SetLabelText(const char *textEntryName, const char *text){ Label *entry = dynamic_cast if (entry) { entry->SetText(text); }}void CTeamMenu::OnKeyCodePressed(KeyCode code){ int lastPressedEngineKey = engine->GetLastPressedEngineKey(); if( m_iJumpKey >= 0 && m_iJumpKey == lastPressedEngineKey ) { AutoAssign(); } else if ( m_iScoreBoardKey >= 0 && m_iScoreBoardKey == lastPressedEngineKey ) { gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, true ); } else { BaseClass::OnKeyCodePressed( code ); }}
using namespace vgui;extern INetworkStringTable *g_pStringTableInfoPanel;extern IGameUIFuncs *gameuifuncs;const char *szTeamButtons[] = { "bluebutton", "redbutton", "yellowbutton", "greenbutton" };#define TEAM_BUTTON_GAP 20//-----------------------------------------------------------------------------// Purpose: Lets us make a test menu//-----------------------------------------------------------------------------//CON_COMMAND(teammenu, "Shows the team menu") //{// if (!gViewPortInterface) // return;// // IViewPortPanel *panel = gViewPortInterface->FindPanelByName(PANEL_TEAM);//// if (panel) // gViewPortInterface->ShowPanel(panel, true);// else// Msg("Couldn't find panel.\n");//}//=============================================================================// A team button has the following components:// A number (this is the button text itself so that hotkeys work automatically)// The team insignia image// Score// Player count// Avg ping//=============================================================================class TeamButton : public FFButton{public: DECLARE_CLASS_SIMPLE(TeamButton, FFButton); TeamButton(Panel *parent, const char *panelName, const char *text, Panel *pActionSignalTarget = NULL, const char *pCmd = NULL) : BaseClass(parent, panelName, text, pActionSignalTarget, pCmd) { m_pTeamInsignia = new ImagePanel(this, "TeamImage"); m_pInfoDescriptions = new Label(this, "TeamDescription", (const char *) NULL); m_pInfoValues = new Label(this, "TeamValues", (const char *) NULL); m_iTeamID = -1; } void ApplySchemeSettings(IScheme *pScheme) { BaseClass::ApplySchemeSettings(pScheme); SetTextInset(10, 7); SetContentAlignment(a_northwest); // Line up image int iInsigniaSize = GetTall() * 0.4f; m_pTeamInsignia->SetBounds(GetWide() / 2 - iInsigniaSize / 2, GetTall() / 2.5f - iInsigniaSize / 2, iInsigniaSize, iInsigniaSize); m_pTeamInsignia->SetShouldScaleImage(true); m_pTeamInsignia->SetMouseInputEnabled(false); // Line up info descriptions m_pInfoDescriptions->SetContentAlignment(a_northwest); m_pInfoDescriptions->SetBounds(GetWide() * 0.1f, GetTall() * 0.6f, GetWide() * 0.4f, GetTall() * 0.4f); m_pInfoDescriptions->SetMouseInputEnabled(false); // Line up info values m_pInfoValues->SetContentAlignment(a_northeast); m_pInfoValues->SetBounds(GetWide() * 0.5f, GetTall() * 0.6f, GetWide() * 0.4f, GetTall() * 0.4f); m_pInfoValues->SetMouseInputEnabled(false); m_pInfoDescriptions->SetText("#TEAM_STATS"); m_pInfoValues->SetText("0\n0\n0"); } //----------------------------------------------------------------------------- // Purpose: Set the team id used by this button for updating itself // Also load the team insignia image. //----------------------------------------------------------------------------- void SetTeamID(int iTeamID) { Assert(iTeamID >= TEAM_BLUE && iTeamID <= TEAM_GREEN); m_iTeamID = iTeamID; const char *pszInsignias[] = { "hud_team_blue", "hud_team_red", "hud_team_yellow", "hud_team_green" }; m_pTeamInsignia->SetShouldScaleImage(true); m_pTeamInsignia->SetImage(pszInsignias[m_iTeamID - TEAM_BLUE]); } //----------------------------------------------------------------------------- // Purpose: Update the various sections of the team button //----------------------------------------------------------------------------- void OnThink() { IGameResources *pGR = GameResources(); if (pGR == NULL) return; int iScore = pGR->GetTeamScore(m_iTeamID); int nPlayers = 0; int iLag = 0; for (int iClient = 1; iClient <= gpGlobals->maxClients; iClient++) { if (!pGR->IsConnected(iClient) || pGR->GetTeam(iClient) != m_iTeamID) continue; nPlayers++; iLag += pGR->GetPing(iClient); } if (nPlayers > 0) iLag /= nPlayers; m_pInfoValues->SetText(VarArgs("%d\n%d\n%d", iScore, nPlayers, iLag)); BaseClass::OnThink(); }private: ImagePanel *m_pTeamInsignia; Label *m_pInfoDescriptions; Label *m_pInfoValues; int m_iTeamID;};// Mulch: TODO: make this work for pheeeeeeeesh-yCON_COMMAND( hud_reloadteammenu, "hud_reloadteammenu" ){ IViewPortPanel *pPanel = gViewPortInterface->FindPanelByName( PANEL_TEAM ); if( !pPanel ) return; CTeamMenu *pTeamMenu = dynamic_cast< CTeamMenu * >( pPanel ); if( !pTeamMenu ) return; vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "HudScheme" ); pTeamMenu->SetScheme( scheme ); pTeamMenu->SetProportional( true ); pTeamMenu->LoadControlSettings( "Resource/UI/TeamMenu.res" );}//-----------------------------------------------------------------------------// Purpose: Constructor//-----------------------------------------------------------------------------CTeamMenu::CTeamMenu(IViewPort *pViewPort) : BaseClass(NULL, PANEL_TEAM) { // initialize dialog m_pViewPort = pViewPort; // load the new scheme early!! SetScheme("ClientScheme"); SetProportional(true); // Various Frame things SetTitleBarVisible(false); SetMoveable(false); SetSizeable(false); // ServerInfo elements m_pServerInfoHost = new HTML(this, "ServerInfoHost"); m_pServerInfoHost->SetScrollbarsEnabled(false); m_pServerInfoButton = new FFButton(this, "ServerInfoButton", (const char *) NULL, this, "serverinfo"); // MapDescription elements m_pMapDescriptionHead = new Label(this, "MapDescriptionHead", ""); m_pMapDescriptionText = new RichText(this, "MapDescriptionText"); m_pMapDescriptionText->SetDrawOffsets( 10, 0 ); char *pszButtons[] = { "BlueTeamButton", "RedTeamButton", "YellowTeamButton", "GreenTeamButton" }; for (int iTeamIndex = 0; iTeamIndex < ARRAYSIZE(pszButtons); iTeamIndex++) { m_pTeamButtons[iTeamIndex] = new TeamButton(this, pszButtons[iTeamIndex], (const char *) NULL, this, pszButtons[iTeamIndex]); m_pTeamButtons[iTeamIndex]->SetTeamID(iTeamIndex + TEAM_BLUE); } m_pAutoAssignButton = new FFButton(this, "AutoAssignButton", (const char *) NULL, this, "AutoAssign"); m_pSpectateButton = new FFButton(this, "SpectateButton", (const char *) NULL, this, "Spectate"); m_pFlythroughButton = new FFButton(this, "FlythroughButton", (const char *) NULL, this, "mapguide overview"); m_pMapScreenshotButton = new FFButton(this, "MapScreenshotButton", (const char *) NULL, this, "MapShot"); // Mulch: Removed this //new Button(this, "screenshot", "screenshot", this, "jpeg"); // to get server name gameeventmanager->AddListener(this, "server_spawn", false ); LoadControlSettings("Resource/UI/TeamMenu.res"); Reset();}//-----------------------------------------------------------------------------// Purpose: Destructor//-----------------------------------------------------------------------------CTeamMenu::~CTeamMenu() {}void CTeamMenu::ApplySchemeSettings(IScheme *pScheme){ BaseClass::ApplySchemeSettings(pScheme); m_pMapDescriptionText->SetBorder(NULL); //m_pServerInfoHost->SetBorder(NULL);}//-----------------------------------------------------------------------------// Purpose: Run the client command if needed//-----------------------------------------------------------------------------void CTeamMenu::OnCommand(const char *command) { //DevMsg("[Teammenu] Command: %s\n", command); if (Q_strcmp(command, "cancel") == 0) { m_pViewPort->ShowPanel(this, false); return; } // Create a new frame to display the Map Screenshot if (Q_strcmp(command, "map shot") == 0) { gViewPortInterface->ShowPanel(PANEL_MAP, true); return; } // Run the command engine->ClientCmd(command); if (Q_strcmp(command, "serverinfo") == 0) return; if (Q_strcmp(command, "jpeg") == 0) { return; } // Hide this panel m_pViewPort->ShowPanel(this, false); if (Q_strcmp(command, "team spec") == 0) return; if (Q_strcmp(command, "mapguide") == 0) return; // Display the class panel now gViewPortInterface->ShowPanel(PANEL_CLASS, true); BaseClass::OnCommand(command);}//-----------------------------------------------------------------------------// Purpose: Nothings//-----------------------------------------------------------------------------void CTeamMenu::SetData(KeyValues *data) {}//-----------------------------------------------------------------------------// Purpose: Get the server name//-----------------------------------------------------------------------------void CTeamMenu::FireGameEvent( IGameEvent *event ){ const char * type = event->GetName(); if ( Q_strcmp(type, "server_spawn") == 0 ) { Q_strncpy( m_szServerName, event->GetString("hostname"), 255 ); } if( IsVisible() ) Update();}//-----------------------------------------------------------------------------// Purpose: Give them some key control too//-----------------------------------------------------------------------------void CTeamMenu::OnKeyCodePressed(KeyCode code) { // Show the scoreboard over this if needed if (engine->GetLastPressedEngineKey() == gameuifuncs->GetEngineKeyCodeForBind("showscores")) gViewPortInterface->ShowPanel(PANEL_SCOREBOARD, true); // Support hiding the team menu by hitting your changeteam button again like TFC // 0001232: Or if the user presses escape, kill the menu if ((engine->GetLastPressedEngineKey() == gameuifuncs->GetEngineKeyCodeForBind("changeteam")) || (engine->GetLastPressedEngineKey() == gameuifuncs->GetEngineKeyCodeForBind("cancelselect"))) gViewPortInterface->ShowPanel(this, false); // Bug #0000540: Can't changeclass while changeteam menu is up // Support bring the class menu back up if the team menu is showing if( ( engine->GetLastPressedEngineKey() == gameuifuncs->GetEngineKeyCodeForBind( "changeclass" ) ) && ( C_BasePlayer::GetLocalPlayer()->GetTeamNumber() >= TEAM_BLUE ) ) { m_pViewPort->ShowPanel( this, false ); engine->ClientCmd( "changeclass" ); } if (engine->GetLastPressedEngineKey() == gameuifuncs->GetEngineKeyCodeForBind("serverinfo")) engine->ClientCmd( "serverinfo" ); BaseClass::OnKeyCodePressed(code);}void CTeamMenu::OnKeyCodeReleased(KeyCode code){ // Bug #0000524: Scoreboard gets stuck with the class menu up when you first join // Hide the scoreboard now if (engine->GetLastPressedEngineKey() == gameuifuncs->GetEngineKeyCodeForBind("showscores")) gViewPortInterface->ShowPanel(PANEL_SCOREBOARD, false); BaseClass::OnKeyCodeReleased(code);}//-----------------------------------------------------------------------------// Purpose: Show the panel or whatever//-----------------------------------------------------------------------------void CTeamMenu::ShowPanel(bool bShow) { if (BaseClass::IsVisible() == bShow) return; m_pViewPort->ShowBackGround(false); if (bShow) { Activate(); SetMouseInputEnabled(true); SetKeyBoardInputEnabled(true); SetEnabled(true); Update(); MoveToFront(); } else { SetVisible(false); SetMouseInputEnabled(false); SetKeyBoardInputEnabled(false); }}//-----------------------------------------------------------------------------// Purpose: Don't need anything yet//-----------------------------------------------------------------------------void CTeamMenu::Reset() { Q_strcpy( m_szServerName, "Fortress Forever" );}//-----------------------------------------------------------------------------// Purpose: Update the menu with everything//-----------------------------------------------------------------------------void CTeamMenu::Update() { // TODO: Some of these should only happen once per map UpdateMapDescriptionText(); UpdateServerInfo(); UpdateTeamButtons(); // When a map 1st loads, the image proxy is in front of the button (so you can't click it) -- this seems to fix that m_pMapScreenshotButton->SetZPos( 10 );}void CTeamMenu::UpdateTeamButtons(){ IGameResources *pGR = GameResources(); if (pGR == NULL) return; char nTeamSpaces[4]; UTIL_GetTeamSpaces(nTeamSpaces); int nActiveButtons = 0; for (int iTeamID = TEAM_BLUE; iTeamID <= TEAM_GREEN; iTeamID++) { int iTeamIndex = iTeamID - TEAM_BLUE; TeamButton *pTeamButton = m_pTeamButtons[iTeamIndex]; // This team doesn't exist at all if (nTeamSpaces[iTeamIndex] == -1) { pTeamButton->SetVisible(false); continue; } // Make sure team button is visible pTeamButton->SetVisible(true); // Need this for later nActiveButtons++; // The team is full, so disable pTeamButton->SetEnabled((nTeamSpaces[iTeamIndex] != 0)); // set the team number wchar_t wchTeamNumber = iTeamIndex + '1'; // Set the team name wchar_t *szTeamName = localize()->Find( pGR->GetTeamName( iTeamID ) ); wchar_t szName[ 256 ]; if (szTeamName) { swprintf( szName, L"%c. %s", wchTeamNumber, szTeamName ); szTeamName = szName; } else { // No localized text or team name not a resource string char szString[ 256 ]; Q_snprintf( szString, 256, "%c. %s", wchTeamNumber, pGR->GetTeamName( iTeamID ) ); localize()->ConvertANSIToUnicode( szString, szName, sizeof( szName ) ); szTeamName = szName; } // one last check if ( szTeamName ) { pTeamButton->SetText(szTeamName); } else { // no name, just use the number swprintf( szTeamName, L"%c.", wchTeamNumber ); pTeamButton->SetText(szTeamName); } pTeamButton->SetHotkey(wchTeamNumber); } int iTeamButtonGap = scheme()->GetProportionalScaledValue(TEAM_BUTTON_GAP); // Now that we know how many active buttons there are we can // move them into the correct location int iStartX = m_pTeamButtons[0]->GetWide() * nActiveButtons * 0.5f; iStartX += (nActiveButtons - 1) * (iTeamButtonGap * 0.5f); iStartX = (GetWide() * 0.5f) - iStartX; // Move active buttons in correct place for (int iTeamIndex = 0; iTeamIndex < 4; iTeamIndex++) { TeamButton *pTeamButton = m_pTeamButtons[iTeamIndex]; if (pTeamButton->IsVisible()) { int iXPos, iYPos; pTeamButton->GetPos(iXPos, iYPos); pTeamButton->SetPos(iStartX, iYPos); iStartX += pTeamButton->GetWide() + iTeamButtonGap; } } // Done here for now int iXPos, iYPos; m_pSpectateButton->GetPos(iXPos, iYPos); m_pSpectateButton->SetPos(GetWide() / 2 - (m_pAutoAssignButton->GetWide() + iTeamButtonGap / 2), iYPos); m_pAutoAssignButton->GetPos(iXPos, iYPos); m_pAutoAssignButton->SetPos(GetWide() / 2 + iTeamButtonGap / 2, iYPos);}void CTeamMenu::UpdateServerInfo(){ //m_pServerInfoText->SetText(pszTitle); if (g_pStringTableInfoPanel == NULL) return; int x,y; m_pServerInfoButton->GetPos(x,y); m_pServerInfoButton->SetPos( x, scheme()->GetProportionalScaledValue(34) ); int iIndex = g_pStringTableInfoPanel->FindStringIndex("host"); if (iIndex == ::INVALID_STRING_INDEX) { m_pServerInfoHost->OpenURL( VarArgs("http://www.fortress-forever.com/defaulthost/index.php?name=%s", m_szServerName) ); return; } int nLength = 0; const char *pszMotd = (const char *) g_pStringTableInfoPanel->GetStringUserData(iIndex, &nLength); m_pServerInfoHost->OpenURL(pszMotd);}void CTeamMenu::UpdateMapDescriptionText(){ char szMapName[MAX_MAP_NAME]; Q_FileBase(engine->GetLevelName(), szMapName, sizeof(szMapName)); const char *pszMapPath = VarArgs("maps/%s.txt", szMapName); // If no map specific description exists then escape for now if (!vgui::filesystem()->FileExists(pszMapPath)) { m_pMapDescriptionHead->SetText(""); m_pMapDescriptionText->SetText(""); return; } // Read from local text from file FileHandle_t f = vgui::filesystem()->Open(pszMapPath, "rb", "GAME"); if (!f) return; char szBuffer[2048]; int size = min(vgui::filesystem()->Size(f), sizeof(szBuffer) - 1); vgui::filesystem()->Read(szBuffer, size, f); vgui::filesystem()->Close(f); szBuffer[size] = 0; const char *pszEndOfHead = strstr(szBuffer, "\n"); // Could not find a title for this, just stick everything in the normal spot // Or there was nothing after the title if (!pszEndOfHead || (pszEndOfHead + 1) == '\0') { m_pMapDescriptionHead->SetText("Unknown map style"); m_pMapDescriptionText->SetText(szBuffer); return; } int iEndOfHead = pszEndOfHead - szBuffer; // Put the rest of the text into the description richtext first. // We're then just going to stick in a null terminator and then add the start // to the head label. m_pMapDescriptionText->SetText(pszEndOfHead + 1); szBuffer[iEndOfHead] = 0; m_pMapDescriptionHead->SetText(szBuffer);}