FF Diff Viewer

Comparing 2006 Base SDK to Fortress Forever 2.46

cl_dll/game_controls/teammenu.cpp

1234567891011121314151617181920212223242526272829303132333435363738
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #include "cbase.h" #include #include "teammenu.h" #include #include #include #include #include #include #include #include #include #include #include "IGameUIFuncs.h" // for key bindings #include #ifndef _XBOX extern IGameUIFuncs *gameuifuncs; // for key binding details #endif #include #include // MAX_PATH define #include // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h"
123456789101112131415161718192021222324252627282930313233343536373839404142434445
/// =============== 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"
39404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
using namespace vgui; void UpdateCursorState(); // void DuckMessage(const char *str); // helper function const 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 ); } }
464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
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-y CON_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); }