aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/game_controls
diff options
context:
space:
mode:
authorNarendra Umate <[email protected]>2013-12-02 23:36:05 -0800
committerNarendra Umate <[email protected]>2013-12-02 23:36:05 -0800
commit8737f191f3b59f001a77bf6c08091109211c1c9f (patch)
treedbbf05c004d9b026f2c1f23f06600fe0add82c36 /mp/src/game/client/game_controls
parentUpdate .gitignore. (diff)
parentMake .xcconfigs text files too. (diff)
downloadsource-sdk-2013-8737f191f3b59f001a77bf6c08091109211c1c9f.tar.xz
source-sdk-2013-8737f191f3b59f001a77bf6c08091109211c1c9f.zip
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'mp/src/game/client/game_controls')
-rw-r--r--mp/src/game/client/game_controls/ClientScoreBoardDialog.cpp1160
-rw-r--r--mp/src/game/client/game_controls/IconPanel.cpp136
-rw-r--r--mp/src/game/client/game_controls/IconPanel.h82
-rw-r--r--mp/src/game/client/game_controls/MapOverview.cpp2678
-rw-r--r--mp/src/game/client/game_controls/NavProgress.cpp274
-rw-r--r--mp/src/game/client/game_controls/NavProgress.h118
-rw-r--r--mp/src/game/client/game_controls/SpectatorGUI.cpp1700
-rw-r--r--mp/src/game/client/game_controls/basemodel_panel.cpp1306
-rw-r--r--mp/src/game/client/game_controls/basemodel_panel.h448
-rw-r--r--mp/src/game/client/game_controls/basemodelpanel.cpp1796
-rw-r--r--mp/src/game/client/game_controls/basemodelpanel.h466
-rw-r--r--mp/src/game/client/game_controls/baseviewport.cpp1442
-rw-r--r--mp/src/game/client/game_controls/baseviewport.h296
-rw-r--r--mp/src/game/client/game_controls/buymenu.cpp300
-rw-r--r--mp/src/game/client/game_controls/buymenu.h132
-rw-r--r--mp/src/game/client/game_controls/buysubmenu.cpp342
-rw-r--r--mp/src/game/client/game_controls/buysubmenu.h118
-rw-r--r--mp/src/game/client/game_controls/classmenu.cpp632
-rw-r--r--mp/src/game/client/game_controls/classmenu.h158
-rw-r--r--mp/src/game/client/game_controls/clientscoreboarddialog.h254
-rw-r--r--mp/src/game/client/game_controls/commandmenu.cpp720
-rw-r--r--mp/src/game/client/game_controls/commandmenu.h152
-rw-r--r--mp/src/game/client/game_controls/imagemouseoverbutton.h510
-rw-r--r--mp/src/game/client/game_controls/intromenu.cpp244
-rw-r--r--mp/src/game/client/game_controls/intromenu.h114
-rw-r--r--mp/src/game/client/game_controls/mapoverview.h550
-rw-r--r--mp/src/game/client/game_controls/mouseoverhtmlbutton.h238
-rw-r--r--mp/src/game/client/game_controls/mouseoverpanelbutton.h372
-rw-r--r--mp/src/game/client/game_controls/spectatorgui.h308
-rw-r--r--mp/src/game/client/game_controls/teammenu.cpp888
-rw-r--r--mp/src/game/client/game_controls/teammenu.h172
-rw-r--r--mp/src/game/client/game_controls/vguitextwindow.cpp860
-rw-r--r--mp/src/game/client/game_controls/vguitextwindow.h208
33 files changed, 9587 insertions, 9587 deletions
diff --git a/mp/src/game/client/game_controls/ClientScoreBoardDialog.cpp b/mp/src/game/client/game_controls/ClientScoreBoardDialog.cpp
index 5d8d27cc..72776206 100644
--- a/mp/src/game/client/game_controls/ClientScoreBoardDialog.cpp
+++ b/mp/src/game/client/game_controls/ClientScoreBoardDialog.cpp
@@ -1,580 +1,580 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//===========================================================================//
-
-#include "cbase.h"
-#include <stdio.h>
-
-#include <cdll_client_int.h>
-#include <cdll_util.h>
-#include <globalvars_base.h>
-#include <igameresources.h>
-#include "IGameUIFuncs.h" // for key bindings
-#include "inputsystem/iinputsystem.h"
-#include "clientscoreboarddialog.h"
-#include <voice_status.h>
-
-#include <vgui/IScheme.h>
-#include <vgui/ILocalize.h>
-#include <vgui/ISurface.h>
-#include <vgui/IVGui.h>
-#include <vstdlib/IKeyValuesSystem.h>
-
-#include <KeyValues.h>
-#include <vgui_controls/ImageList.h>
-#include <vgui_controls/Label.h>
-#include <vgui_controls/SectionedListPanel.h>
-
-#include <game/client/iviewport.h>
-#include <igameresources.h>
-
-#include "vgui_avatarimage.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-using namespace vgui;
-
-bool AvatarIndexLessFunc( const int &lhs, const int &rhs )
-{
- return lhs < rhs;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CClientScoreBoardDialog::CClientScoreBoardDialog(IViewPort *pViewPort) : EditablePanel( NULL, PANEL_SCOREBOARD )
-{
- m_iPlayerIndexSymbol = KeyValuesSystem()->GetSymbolForString("playerIndex");
- m_nCloseKey = BUTTON_CODE_INVALID;
-
- //memset(s_VoiceImage, 0x0, sizeof( s_VoiceImage ));
- TrackerImage = 0;
- m_pViewPort = pViewPort;
-
- // initialize dialog
- SetProportional(true);
- SetKeyBoardInputEnabled(false);
- SetMouseInputEnabled(false);
-
- // set the scheme before any child control is created
- SetScheme("ClientScheme");
-
- m_pPlayerList = new SectionedListPanel(this, "PlayerList");
- m_pPlayerList->SetVerticalScrollbar(false);
-
- LoadControlSettings("Resource/UI/ScoreBoard.res");
- m_iDesiredHeight = GetTall();
- m_pPlayerList->SetVisible( false ); // hide this until we load the images in applyschemesettings
-
- m_HLTVSpectators = 0;
- m_ReplaySpectators = 0;
-
- // update scoreboard instantly if on of these events occure
- ListenForGameEvent( "hltv_status" );
- ListenForGameEvent( "server_spawn" );
-
- m_pImageList = NULL;
-
- m_mapAvatarsToImageList.SetLessFunc( DefLessFunc( CSteamID ) );
- m_mapAvatarsToImageList.RemoveAll();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CClientScoreBoardDialog::~CClientScoreBoardDialog()
-{
- if ( NULL != m_pImageList )
- {
- delete m_pImageList;
- m_pImageList = NULL;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Call every frame
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::OnThink()
-{
- BaseClass::OnThink();
-
- // NOTE: this is necessary because of the way input works.
- // If a key down message is sent to vgui, then it will get the key up message
- // Sometimes the scoreboard is activated by other vgui menus,
- // sometimes by console commands. In the case where it's activated by
- // other vgui menus, we lose the key up message because this panel
- // doesn't accept keyboard input. It *can't* accept keyboard input
- // because another feature of the dialog is that if it's triggered
- // from within the game, you should be able to still run around while
- // the scoreboard is up. That feature is impossible if this panel accepts input.
- // because if a vgui panel is up that accepts input, it prevents the engine from
- // receiving that input. So, I'm stuck with a polling solution.
- //
- // Close key is set to non-invalid when something other than a keybind
- // brings the scoreboard up, and it's set to invalid as soon as the
- // dialog becomes hidden.
- if ( m_nCloseKey != BUTTON_CODE_INVALID )
- {
- if ( !g_pInputSystem->IsButtonDown( m_nCloseKey ) )
- {
- m_nCloseKey = BUTTON_CODE_INVALID;
- gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, false );
- GetClientVoiceMgr()->StopSquelchMode();
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Called by vgui panels that activate the client scoreboard
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::OnPollHideCode( int code )
-{
- m_nCloseKey = (ButtonCode_t)code;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: clears everything in the scoreboard and all it's state
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::Reset()
-{
- // clear
- m_pPlayerList->DeleteAllItems();
- m_pPlayerList->RemoveAllSections();
-
- m_iSectionId = 0;
- m_fNextUpdateTime = 0;
- // add all the sections
- InitScoreboardSections();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: adds all the team sections to the scoreboard
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::InitScoreboardSections()
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets up screen
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::ApplySchemeSettings( IScheme *pScheme )
-{
- BaseClass::ApplySchemeSettings( pScheme );
-
- if ( m_pImageList )
- delete m_pImageList;
- m_pImageList = new ImageList( false );
-
- m_mapAvatarsToImageList.RemoveAll();
-
- PostApplySchemeSettings( pScheme );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Does dialog-specific customization after applying scheme settings.
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::PostApplySchemeSettings( vgui::IScheme *pScheme )
-{
- // resize the images to our resolution
- for (int i = 0; i < m_pImageList->GetImageCount(); i++ )
- {
- int wide, tall;
- m_pImageList->GetImage(i)->GetSize(wide, tall);
- m_pImageList->GetImage(i)->SetSize(scheme()->GetProportionalScaledValueEx( GetScheme(),wide), scheme()->GetProportionalScaledValueEx( GetScheme(),tall));
- }
-
- m_pPlayerList->SetImageList( m_pImageList, false );
- m_pPlayerList->SetVisible( true );
-
- // light up scoreboard a bit
- SetBgColor( Color( 0,0,0,0) );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::ShowPanel(bool bShow)
-{
- // Catch the case where we call ShowPanel before ApplySchemeSettings, eg when
- // going from windowed <-> fullscreen
- if ( m_pImageList == NULL )
- {
- InvalidateLayout( true, true );
- }
-
- if ( !bShow )
- {
- m_nCloseKey = BUTTON_CODE_INVALID;
- }
-
- if ( BaseClass::IsVisible() == bShow )
- return;
-
- if ( bShow )
- {
- Reset();
- Update();
- SetVisible( true );
- MoveToFront();
- }
- else
- {
- BaseClass::SetVisible( false );
- SetMouseInputEnabled( false );
- SetKeyBoardInputEnabled( false );
- }
-}
-
-void CClientScoreBoardDialog::FireGameEvent( IGameEvent *event )
-{
- const char * type = event->GetName();
-
- if ( Q_strcmp(type, "hltv_status") == 0 )
- {
- // spectators = clients - proxies
- m_HLTVSpectators = event->GetInt( "clients" );
- m_HLTVSpectators -= event->GetInt( "proxies" );
- }
- else if ( Q_strcmp(type, "server_spawn") == 0 )
- {
- // We'll post the message ourselves instead of using SetControlString()
- // so we don't try to translate the hostname.
- const char *hostname = event->GetString( "hostname" );
- Panel *control = FindChildByName( "ServerName" );
- if ( control )
- {
- PostMessage( control, new KeyValues( "SetText", "text", hostname ) );
- control->MoveToFront();
- }
- }
-
- if( IsVisible() )
- Update();
-
-}
-
-bool CClientScoreBoardDialog::NeedsUpdate( void )
-{
- return (m_fNextUpdateTime < gpGlobals->curtime);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Recalculate the internal scoreboard data
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::Update( void )
-{
- // Set the title
-
- // Reset();
- m_pPlayerList->DeleteAllItems();
-
- FillScoreBoard();
-
- // grow the scoreboard to fit all the players
- int wide, tall;
- m_pPlayerList->GetContentSize(wide, tall);
- tall += GetAdditionalHeight();
- wide = GetWide();
- if (m_iDesiredHeight < tall)
- {
- SetSize(wide, tall);
- m_pPlayerList->SetSize(wide, tall);
- }
- else
- {
- SetSize(wide, m_iDesiredHeight);
- m_pPlayerList->SetSize(wide, m_iDesiredHeight);
- }
-
- MoveToCenterOfScreen();
-
- // update every second
- m_fNextUpdateTime = gpGlobals->curtime + 1.0f;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sort all the teams
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::UpdateTeamInfo()
-{
-// TODO: work out a sorting algorithm for team display for TF2
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::UpdatePlayerInfo()
-{
- m_iSectionId = 0; // 0'th row is a header
- int selectedRow = -1;
-
- // walk all the players and make sure they're in the scoreboard
- for ( int i = 1; i <= gpGlobals->maxClients; ++i )
- {
- IGameResources *gr = GameResources();
-
- if ( gr && gr->IsConnected( i ) )
- {
- // add the player to the list
- KeyValues *playerData = new KeyValues("data");
- GetPlayerScoreInfo( i, playerData );
- UpdatePlayerAvatar( i, playerData );
-
- const char *oldName = playerData->GetString("name","");
- char newName[MAX_PLAYER_NAME_LENGTH];
-
- UTIL_MakeSafeName( oldName, newName, MAX_PLAYER_NAME_LENGTH );
-
- playerData->SetString("name", newName);
-
- int itemID = FindItemIDForPlayerIndex( i );
- int sectionID = gr->GetTeam( i );
-
- if ( gr->IsLocalPlayer( i ) )
- {
- selectedRow = itemID;
- }
- if (itemID == -1)
- {
- // add a new row
- itemID = m_pPlayerList->AddItem( sectionID, playerData );
- }
- else
- {
- // modify the current row
- m_pPlayerList->ModifyItem( itemID, sectionID, playerData );
- }
-
- // set the row color based on the players team
- m_pPlayerList->SetItemFgColor( itemID, gr->GetTeamColor( sectionID ) );
-
- playerData->deleteThis();
- }
- else
- {
- // remove the player
- int itemID = FindItemIDForPlayerIndex( i );
- if (itemID != -1)
- {
- m_pPlayerList->RemoveItem(itemID);
- }
- }
- }
-
- if ( selectedRow != -1 )
- {
- m_pPlayerList->SetSelectedItem(selectedRow);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: adds the top header of the scoreboars
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::AddHeader()
-{
- // add the top header
- m_pPlayerList->AddSection(m_iSectionId, "");
- m_pPlayerList->SetSectionAlwaysVisible(m_iSectionId);
- m_pPlayerList->AddColumnToSection(m_iSectionId, "name", "#PlayerName", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),NAME_WIDTH) );
- m_pPlayerList->AddColumnToSection(m_iSectionId, "frags", "#PlayerScore", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),SCORE_WIDTH) );
- m_pPlayerList->AddColumnToSection(m_iSectionId, "deaths", "#PlayerDeath", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),DEATH_WIDTH) );
- m_pPlayerList->AddColumnToSection(m_iSectionId, "ping", "#PlayerPing", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),PING_WIDTH) );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Adds a new section to the scoreboard (i.e the team header)
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::AddSection(int teamType, int teamNumber)
-{
- if ( teamType == TYPE_TEAM )
- {
- IGameResources *gr = GameResources();
-
- if ( !gr )
- return;
-
- // setup the team name
- wchar_t *teamName = g_pVGuiLocalize->Find( gr->GetTeamName(teamNumber) );
- wchar_t name[64];
- wchar_t string1[1024];
-
- if (!teamName)
- {
- g_pVGuiLocalize->ConvertANSIToUnicode(gr->GetTeamName(teamNumber), name, sizeof(name));
- teamName = name;
- }
-
- g_pVGuiLocalize->ConstructString( string1, sizeof( string1 ), g_pVGuiLocalize->Find("#Player"), 2, teamName );
-
- m_pPlayerList->AddSection(m_iSectionId, "", StaticPlayerSortFunc);
-
- // Avatars are always displayed at 32x32 regardless of resolution
- if ( ShowAvatars() )
- {
- m_pPlayerList->AddColumnToSection( m_iSectionId, "avatar", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, m_iAvatarWidth );
- }
-
- m_pPlayerList->AddColumnToSection(m_iSectionId, "name", string1, 0, scheme()->GetProportionalScaledValueEx( GetScheme(),NAME_WIDTH) - m_iAvatarWidth );
- m_pPlayerList->AddColumnToSection(m_iSectionId, "frags", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),SCORE_WIDTH) );
- m_pPlayerList->AddColumnToSection(m_iSectionId, "deaths", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),DEATH_WIDTH) );
- m_pPlayerList->AddColumnToSection(m_iSectionId, "ping", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),PING_WIDTH) );
- }
- else if ( teamType == TYPE_SPECTATORS )
- {
- m_pPlayerList->AddSection(m_iSectionId, "");
-
- // Avatars are always displayed at 32x32 regardless of resolution
- if ( ShowAvatars() )
- {
- m_pPlayerList->AddColumnToSection( m_iSectionId, "avatar", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, m_iAvatarWidth );
- }
- m_pPlayerList->AddColumnToSection(m_iSectionId, "name", "#Spectators", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),NAME_WIDTH) - m_iAvatarWidth );
- m_pPlayerList->AddColumnToSection(m_iSectionId, "frags", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),SCORE_WIDTH) );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Used for sorting players
-//-----------------------------------------------------------------------------
-bool CClientScoreBoardDialog::StaticPlayerSortFunc(vgui::SectionedListPanel *list, int itemID1, int itemID2)
-{
- KeyValues *it1 = list->GetItemData(itemID1);
- KeyValues *it2 = list->GetItemData(itemID2);
- Assert(it1 && it2);
-
- // first compare frags
- int v1 = it1->GetInt("frags");
- int v2 = it2->GetInt("frags");
- if (v1 > v2)
- return true;
- else if (v1 < v2)
- return false;
-
- // next compare deaths
- v1 = it1->GetInt("deaths");
- v2 = it2->GetInt("deaths");
- if (v1 > v2)
- return false;
- else if (v1 < v2)
- return true;
-
- // the same, so compare itemID's (as a sentinel value to get deterministic sorts)
- return itemID1 < itemID2;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Adds a new row to the scoreboard, from the playerinfo structure
-//-----------------------------------------------------------------------------
-bool CClientScoreBoardDialog::GetPlayerScoreInfo(int playerIndex, KeyValues *kv)
-{
- IGameResources *gr = GameResources();
-
- if (!gr )
- return false;
-
- kv->SetInt("deaths", gr->GetDeaths( playerIndex ) );
- kv->SetInt("frags", gr->GetFrags( playerIndex ) );
- kv->SetInt("ping", gr->GetPing( playerIndex ) ) ;
- kv->SetString("name", gr->GetPlayerName( playerIndex ) );
- kv->SetInt("playerIndex", playerIndex);
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::UpdatePlayerAvatar( int playerIndex, KeyValues *kv )
-{
- // Update their avatar
- if ( kv && ShowAvatars() && steamapicontext->SteamFriends() && steamapicontext->SteamUtils() )
- {
- player_info_t pi;
- if ( engine->GetPlayerInfo( playerIndex, &pi ) )
- {
- if ( pi.friendsID )
- {
- CSteamID steamIDForPlayer( pi.friendsID, 1, steamapicontext->SteamUtils()->GetConnectedUniverse(), k_EAccountTypeIndividual );
-
- // See if we already have that avatar in our list
- int iMapIndex = m_mapAvatarsToImageList.Find( steamIDForPlayer );
- int iImageIndex;
- if ( iMapIndex == m_mapAvatarsToImageList.InvalidIndex() )
- {
- CAvatarImage *pImage = new CAvatarImage();
- pImage->SetAvatarSteamID( steamIDForPlayer );
- pImage->SetAvatarSize( 32, 32 ); // Deliberately non scaling
- iImageIndex = m_pImageList->AddImage( pImage );
-
- m_mapAvatarsToImageList.Insert( steamIDForPlayer, iImageIndex );
- }
- else
- {
- iImageIndex = m_mapAvatarsToImageList[ iMapIndex ];
- }
-
- kv->SetInt( "avatar", iImageIndex );
-
- CAvatarImage *pAvIm = (CAvatarImage *)m_pImageList->GetImage( iImageIndex );
- pAvIm->UpdateFriendStatus();
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: reload the player list on the scoreboard
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::FillScoreBoard()
-{
- // update totals information
- UpdateTeamInfo();
-
- // update player info
- UpdatePlayerInfo();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: searches for the player in the scoreboard
-//-----------------------------------------------------------------------------
-int CClientScoreBoardDialog::FindItemIDForPlayerIndex(int playerIndex)
-{
- for (int i = 0; i <= m_pPlayerList->GetHighestItemID(); i++)
- {
- if (m_pPlayerList->IsItemIDValid(i))
- {
- KeyValues *kv = m_pPlayerList->GetItemData(i);
- kv = kv->FindKey(m_iPlayerIndexSymbol);
- if (kv && kv->GetInt() == playerIndex)
- return i;
- }
- }
- return -1;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the text of a control by name
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::MoveLabelToFront(const char *textEntryName)
-{
- Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
- if (entry)
- {
- entry->MoveToFront();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Center the dialog on the screen. (vgui has this method on
-// Frame, but we're an EditablePanel, need to roll our own.)
-//-----------------------------------------------------------------------------
-void CClientScoreBoardDialog::MoveToCenterOfScreen()
-{
- int wx, wy, ww, wt;
- surface()->GetWorkspaceBounds(wx, wy, ww, wt);
- SetPos((ww - GetWide()) / 2, (wt - GetTall()) / 2);
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//===========================================================================//
+
+#include "cbase.h"
+#include <stdio.h>
+
+#include <cdll_client_int.h>
+#include <cdll_util.h>
+#include <globalvars_base.h>
+#include <igameresources.h>
+#include "IGameUIFuncs.h" // for key bindings
+#include "inputsystem/iinputsystem.h"
+#include "clientscoreboarddialog.h"
+#include <voice_status.h>
+
+#include <vgui/IScheme.h>
+#include <vgui/ILocalize.h>
+#include <vgui/ISurface.h>
+#include <vgui/IVGui.h>
+#include <vstdlib/IKeyValuesSystem.h>
+
+#include <KeyValues.h>
+#include <vgui_controls/ImageList.h>
+#include <vgui_controls/Label.h>
+#include <vgui_controls/SectionedListPanel.h>
+
+#include <game/client/iviewport.h>
+#include <igameresources.h>
+
+#include "vgui_avatarimage.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+bool AvatarIndexLessFunc( const int &lhs, const int &rhs )
+{
+ return lhs < rhs;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CClientScoreBoardDialog::CClientScoreBoardDialog(IViewPort *pViewPort) : EditablePanel( NULL, PANEL_SCOREBOARD )
+{
+ m_iPlayerIndexSymbol = KeyValuesSystem()->GetSymbolForString("playerIndex");
+ m_nCloseKey = BUTTON_CODE_INVALID;
+
+ //memset(s_VoiceImage, 0x0, sizeof( s_VoiceImage ));
+ TrackerImage = 0;
+ m_pViewPort = pViewPort;
+
+ // initialize dialog
+ SetProportional(true);
+ SetKeyBoardInputEnabled(false);
+ SetMouseInputEnabled(false);
+
+ // set the scheme before any child control is created
+ SetScheme("ClientScheme");
+
+ m_pPlayerList = new SectionedListPanel(this, "PlayerList");
+ m_pPlayerList->SetVerticalScrollbar(false);
+
+ LoadControlSettings("Resource/UI/ScoreBoard.res");
+ m_iDesiredHeight = GetTall();
+ m_pPlayerList->SetVisible( false ); // hide this until we load the images in applyschemesettings
+
+ m_HLTVSpectators = 0;
+ m_ReplaySpectators = 0;
+
+ // update scoreboard instantly if on of these events occure
+ ListenForGameEvent( "hltv_status" );
+ ListenForGameEvent( "server_spawn" );
+
+ m_pImageList = NULL;
+
+ m_mapAvatarsToImageList.SetLessFunc( DefLessFunc( CSteamID ) );
+ m_mapAvatarsToImageList.RemoveAll();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CClientScoreBoardDialog::~CClientScoreBoardDialog()
+{
+ if ( NULL != m_pImageList )
+ {
+ delete m_pImageList;
+ m_pImageList = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Call every frame
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::OnThink()
+{
+ BaseClass::OnThink();
+
+ // NOTE: this is necessary because of the way input works.
+ // If a key down message is sent to vgui, then it will get the key up message
+ // Sometimes the scoreboard is activated by other vgui menus,
+ // sometimes by console commands. In the case where it's activated by
+ // other vgui menus, we lose the key up message because this panel
+ // doesn't accept keyboard input. It *can't* accept keyboard input
+ // because another feature of the dialog is that if it's triggered
+ // from within the game, you should be able to still run around while
+ // the scoreboard is up. That feature is impossible if this panel accepts input.
+ // because if a vgui panel is up that accepts input, it prevents the engine from
+ // receiving that input. So, I'm stuck with a polling solution.
+ //
+ // Close key is set to non-invalid when something other than a keybind
+ // brings the scoreboard up, and it's set to invalid as soon as the
+ // dialog becomes hidden.
+ if ( m_nCloseKey != BUTTON_CODE_INVALID )
+ {
+ if ( !g_pInputSystem->IsButtonDown( m_nCloseKey ) )
+ {
+ m_nCloseKey = BUTTON_CODE_INVALID;
+ gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, false );
+ GetClientVoiceMgr()->StopSquelchMode();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Called by vgui panels that activate the client scoreboard
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::OnPollHideCode( int code )
+{
+ m_nCloseKey = (ButtonCode_t)code;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: clears everything in the scoreboard and all it's state
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::Reset()
+{
+ // clear
+ m_pPlayerList->DeleteAllItems();
+ m_pPlayerList->RemoveAllSections();
+
+ m_iSectionId = 0;
+ m_fNextUpdateTime = 0;
+ // add all the sections
+ InitScoreboardSections();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: adds all the team sections to the scoreboard
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::InitScoreboardSections()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets up screen
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::ApplySchemeSettings( IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ if ( m_pImageList )
+ delete m_pImageList;
+ m_pImageList = new ImageList( false );
+
+ m_mapAvatarsToImageList.RemoveAll();
+
+ PostApplySchemeSettings( pScheme );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Does dialog-specific customization after applying scheme settings.
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::PostApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ // resize the images to our resolution
+ for (int i = 0; i < m_pImageList->GetImageCount(); i++ )
+ {
+ int wide, tall;
+ m_pImageList->GetImage(i)->GetSize(wide, tall);
+ m_pImageList->GetImage(i)->SetSize(scheme()->GetProportionalScaledValueEx( GetScheme(),wide), scheme()->GetProportionalScaledValueEx( GetScheme(),tall));
+ }
+
+ m_pPlayerList->SetImageList( m_pImageList, false );
+ m_pPlayerList->SetVisible( true );
+
+ // light up scoreboard a bit
+ SetBgColor( Color( 0,0,0,0) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::ShowPanel(bool bShow)
+{
+ // Catch the case where we call ShowPanel before ApplySchemeSettings, eg when
+ // going from windowed <-> fullscreen
+ if ( m_pImageList == NULL )
+ {
+ InvalidateLayout( true, true );
+ }
+
+ if ( !bShow )
+ {
+ m_nCloseKey = BUTTON_CODE_INVALID;
+ }
+
+ if ( BaseClass::IsVisible() == bShow )
+ return;
+
+ if ( bShow )
+ {
+ Reset();
+ Update();
+ SetVisible( true );
+ MoveToFront();
+ }
+ else
+ {
+ BaseClass::SetVisible( false );
+ SetMouseInputEnabled( false );
+ SetKeyBoardInputEnabled( false );
+ }
+}
+
+void CClientScoreBoardDialog::FireGameEvent( IGameEvent *event )
+{
+ const char * type = event->GetName();
+
+ if ( Q_strcmp(type, "hltv_status") == 0 )
+ {
+ // spectators = clients - proxies
+ m_HLTVSpectators = event->GetInt( "clients" );
+ m_HLTVSpectators -= event->GetInt( "proxies" );
+ }
+ else if ( Q_strcmp(type, "server_spawn") == 0 )
+ {
+ // We'll post the message ourselves instead of using SetControlString()
+ // so we don't try to translate the hostname.
+ const char *hostname = event->GetString( "hostname" );
+ Panel *control = FindChildByName( "ServerName" );
+ if ( control )
+ {
+ PostMessage( control, new KeyValues( "SetText", "text", hostname ) );
+ control->MoveToFront();
+ }
+ }
+
+ if( IsVisible() )
+ Update();
+
+}
+
+bool CClientScoreBoardDialog::NeedsUpdate( void )
+{
+ return (m_fNextUpdateTime < gpGlobals->curtime);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Recalculate the internal scoreboard data
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::Update( void )
+{
+ // Set the title
+
+ // Reset();
+ m_pPlayerList->DeleteAllItems();
+
+ FillScoreBoard();
+
+ // grow the scoreboard to fit all the players
+ int wide, tall;
+ m_pPlayerList->GetContentSize(wide, tall);
+ tall += GetAdditionalHeight();
+ wide = GetWide();
+ if (m_iDesiredHeight < tall)
+ {
+ SetSize(wide, tall);
+ m_pPlayerList->SetSize(wide, tall);
+ }
+ else
+ {
+ SetSize(wide, m_iDesiredHeight);
+ m_pPlayerList->SetSize(wide, m_iDesiredHeight);
+ }
+
+ MoveToCenterOfScreen();
+
+ // update every second
+ m_fNextUpdateTime = gpGlobals->curtime + 1.0f;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sort all the teams
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::UpdateTeamInfo()
+{
+// TODO: work out a sorting algorithm for team display for TF2
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::UpdatePlayerInfo()
+{
+ m_iSectionId = 0; // 0'th row is a header
+ int selectedRow = -1;
+
+ // walk all the players and make sure they're in the scoreboard
+ for ( int i = 1; i <= gpGlobals->maxClients; ++i )
+ {
+ IGameResources *gr = GameResources();
+
+ if ( gr && gr->IsConnected( i ) )
+ {
+ // add the player to the list
+ KeyValues *playerData = new KeyValues("data");
+ GetPlayerScoreInfo( i, playerData );
+ UpdatePlayerAvatar( i, playerData );
+
+ const char *oldName = playerData->GetString("name","");
+ char newName[MAX_PLAYER_NAME_LENGTH];
+
+ UTIL_MakeSafeName( oldName, newName, MAX_PLAYER_NAME_LENGTH );
+
+ playerData->SetString("name", newName);
+
+ int itemID = FindItemIDForPlayerIndex( i );
+ int sectionID = gr->GetTeam( i );
+
+ if ( gr->IsLocalPlayer( i ) )
+ {
+ selectedRow = itemID;
+ }
+ if (itemID == -1)
+ {
+ // add a new row
+ itemID = m_pPlayerList->AddItem( sectionID, playerData );
+ }
+ else
+ {
+ // modify the current row
+ m_pPlayerList->ModifyItem( itemID, sectionID, playerData );
+ }
+
+ // set the row color based on the players team
+ m_pPlayerList->SetItemFgColor( itemID, gr->GetTeamColor( sectionID ) );
+
+ playerData->deleteThis();
+ }
+ else
+ {
+ // remove the player
+ int itemID = FindItemIDForPlayerIndex( i );
+ if (itemID != -1)
+ {
+ m_pPlayerList->RemoveItem(itemID);
+ }
+ }
+ }
+
+ if ( selectedRow != -1 )
+ {
+ m_pPlayerList->SetSelectedItem(selectedRow);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: adds the top header of the scoreboars
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::AddHeader()
+{
+ // add the top header
+ m_pPlayerList->AddSection(m_iSectionId, "");
+ m_pPlayerList->SetSectionAlwaysVisible(m_iSectionId);
+ m_pPlayerList->AddColumnToSection(m_iSectionId, "name", "#PlayerName", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),NAME_WIDTH) );
+ m_pPlayerList->AddColumnToSection(m_iSectionId, "frags", "#PlayerScore", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),SCORE_WIDTH) );
+ m_pPlayerList->AddColumnToSection(m_iSectionId, "deaths", "#PlayerDeath", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),DEATH_WIDTH) );
+ m_pPlayerList->AddColumnToSection(m_iSectionId, "ping", "#PlayerPing", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),PING_WIDTH) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Adds a new section to the scoreboard (i.e the team header)
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::AddSection(int teamType, int teamNumber)
+{
+ if ( teamType == TYPE_TEAM )
+ {
+ IGameResources *gr = GameResources();
+
+ if ( !gr )
+ return;
+
+ // setup the team name
+ wchar_t *teamName = g_pVGuiLocalize->Find( gr->GetTeamName(teamNumber) );
+ wchar_t name[64];
+ wchar_t string1[1024];
+
+ if (!teamName)
+ {
+ g_pVGuiLocalize->ConvertANSIToUnicode(gr->GetTeamName(teamNumber), name, sizeof(name));
+ teamName = name;
+ }
+
+ g_pVGuiLocalize->ConstructString( string1, sizeof( string1 ), g_pVGuiLocalize->Find("#Player"), 2, teamName );
+
+ m_pPlayerList->AddSection(m_iSectionId, "", StaticPlayerSortFunc);
+
+ // Avatars are always displayed at 32x32 regardless of resolution
+ if ( ShowAvatars() )
+ {
+ m_pPlayerList->AddColumnToSection( m_iSectionId, "avatar", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, m_iAvatarWidth );
+ }
+
+ m_pPlayerList->AddColumnToSection(m_iSectionId, "name", string1, 0, scheme()->GetProportionalScaledValueEx( GetScheme(),NAME_WIDTH) - m_iAvatarWidth );
+ m_pPlayerList->AddColumnToSection(m_iSectionId, "frags", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),SCORE_WIDTH) );
+ m_pPlayerList->AddColumnToSection(m_iSectionId, "deaths", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),DEATH_WIDTH) );
+ m_pPlayerList->AddColumnToSection(m_iSectionId, "ping", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),PING_WIDTH) );
+ }
+ else if ( teamType == TYPE_SPECTATORS )
+ {
+ m_pPlayerList->AddSection(m_iSectionId, "");
+
+ // Avatars are always displayed at 32x32 regardless of resolution
+ if ( ShowAvatars() )
+ {
+ m_pPlayerList->AddColumnToSection( m_iSectionId, "avatar", "", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::COLUMN_RIGHT, m_iAvatarWidth );
+ }
+ m_pPlayerList->AddColumnToSection(m_iSectionId, "name", "#Spectators", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),NAME_WIDTH) - m_iAvatarWidth );
+ m_pPlayerList->AddColumnToSection(m_iSectionId, "frags", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(),SCORE_WIDTH) );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Used for sorting players
+//-----------------------------------------------------------------------------
+bool CClientScoreBoardDialog::StaticPlayerSortFunc(vgui::SectionedListPanel *list, int itemID1, int itemID2)
+{
+ KeyValues *it1 = list->GetItemData(itemID1);
+ KeyValues *it2 = list->GetItemData(itemID2);
+ Assert(it1 && it2);
+
+ // first compare frags
+ int v1 = it1->GetInt("frags");
+ int v2 = it2->GetInt("frags");
+ if (v1 > v2)
+ return true;
+ else if (v1 < v2)
+ return false;
+
+ // next compare deaths
+ v1 = it1->GetInt("deaths");
+ v2 = it2->GetInt("deaths");
+ if (v1 > v2)
+ return false;
+ else if (v1 < v2)
+ return true;
+
+ // the same, so compare itemID's (as a sentinel value to get deterministic sorts)
+ return itemID1 < itemID2;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Adds a new row to the scoreboard, from the playerinfo structure
+//-----------------------------------------------------------------------------
+bool CClientScoreBoardDialog::GetPlayerScoreInfo(int playerIndex, KeyValues *kv)
+{
+ IGameResources *gr = GameResources();
+
+ if (!gr )
+ return false;
+
+ kv->SetInt("deaths", gr->GetDeaths( playerIndex ) );
+ kv->SetInt("frags", gr->GetFrags( playerIndex ) );
+ kv->SetInt("ping", gr->GetPing( playerIndex ) ) ;
+ kv->SetString("name", gr->GetPlayerName( playerIndex ) );
+ kv->SetInt("playerIndex", playerIndex);
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::UpdatePlayerAvatar( int playerIndex, KeyValues *kv )
+{
+ // Update their avatar
+ if ( kv && ShowAvatars() && steamapicontext->SteamFriends() && steamapicontext->SteamUtils() )
+ {
+ player_info_t pi;
+ if ( engine->GetPlayerInfo( playerIndex, &pi ) )
+ {
+ if ( pi.friendsID )
+ {
+ CSteamID steamIDForPlayer( pi.friendsID, 1, steamapicontext->SteamUtils()->GetConnectedUniverse(), k_EAccountTypeIndividual );
+
+ // See if we already have that avatar in our list
+ int iMapIndex = m_mapAvatarsToImageList.Find( steamIDForPlayer );
+ int iImageIndex;
+ if ( iMapIndex == m_mapAvatarsToImageList.InvalidIndex() )
+ {
+ CAvatarImage *pImage = new CAvatarImage();
+ pImage->SetAvatarSteamID( steamIDForPlayer );
+ pImage->SetAvatarSize( 32, 32 ); // Deliberately non scaling
+ iImageIndex = m_pImageList->AddImage( pImage );
+
+ m_mapAvatarsToImageList.Insert( steamIDForPlayer, iImageIndex );
+ }
+ else
+ {
+ iImageIndex = m_mapAvatarsToImageList[ iMapIndex ];
+ }
+
+ kv->SetInt( "avatar", iImageIndex );
+
+ CAvatarImage *pAvIm = (CAvatarImage *)m_pImageList->GetImage( iImageIndex );
+ pAvIm->UpdateFriendStatus();
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: reload the player list on the scoreboard
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::FillScoreBoard()
+{
+ // update totals information
+ UpdateTeamInfo();
+
+ // update player info
+ UpdatePlayerInfo();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: searches for the player in the scoreboard
+//-----------------------------------------------------------------------------
+int CClientScoreBoardDialog::FindItemIDForPlayerIndex(int playerIndex)
+{
+ for (int i = 0; i <= m_pPlayerList->GetHighestItemID(); i++)
+ {
+ if (m_pPlayerList->IsItemIDValid(i))
+ {
+ KeyValues *kv = m_pPlayerList->GetItemData(i);
+ kv = kv->FindKey(m_iPlayerIndexSymbol);
+ if (kv && kv->GetInt() == playerIndex)
+ return i;
+ }
+ }
+ return -1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the text of a control by name
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::MoveLabelToFront(const char *textEntryName)
+{
+ Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
+ if (entry)
+ {
+ entry->MoveToFront();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Center the dialog on the screen. (vgui has this method on
+// Frame, but we're an EditablePanel, need to roll our own.)
+//-----------------------------------------------------------------------------
+void CClientScoreBoardDialog::MoveToCenterOfScreen()
+{
+ int wx, wy, ww, wt;
+ surface()->GetWorkspaceBounds(wx, wy, ww, wt);
+ SetPos((ww - GetWide()) / 2, (wt - GetTall()) / 2);
+}
diff --git a/mp/src/game/client/game_controls/IconPanel.cpp b/mp/src/game/client/game_controls/IconPanel.cpp
index 88fb8071..3688daed 100644
--- a/mp/src/game/client/game_controls/IconPanel.cpp
+++ b/mp/src/game/client/game_controls/IconPanel.cpp
@@ -1,68 +1,68 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "IconPanel.h"
-#include "KeyValues.h"
-
-DECLARE_BUILD_FACTORY( CIconPanel );
-
-CIconPanel::CIconPanel( vgui::Panel *parent, const char *name ) : vgui::Panel( parent, name )
-{
- m_szIcon[0] = '\0';
- m_icon = NULL;
- m_bScaleImage = false;
-}
-
-void CIconPanel::ApplySettings( KeyValues *inResourceData )
-{
- Q_strncpy( m_szIcon, inResourceData->GetString( "icon", "" ), sizeof( m_szIcon ) );
-
- m_icon = gHUD.GetIcon( m_szIcon );
-
- m_bScaleImage = inResourceData->GetInt("scaleImage", 0);
-
- BaseClass::ApplySettings( inResourceData );
-}
-
-void CIconPanel::SetIcon( const char *szIcon )
-{
- Q_strncpy( m_szIcon, szIcon, sizeof(m_szIcon) );
-
- m_icon = gHUD.GetIcon( m_szIcon );
-}
-
-void CIconPanel::Paint()
-{
- BaseClass::Paint();
-
- if ( m_icon )
- {
- int x, y, w, h;
- GetBounds( x, y, w, h );
-
- if ( m_bScaleImage )
- {
- m_icon->DrawSelf( 0, 0, w, h, m_IconColor );
- }
- else
- {
- m_icon->DrawSelf( 0, 0, m_IconColor );
- }
- }
-}
-
-void CIconPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
-{
- BaseClass::ApplySchemeSettings( pScheme );
-
- if ( m_szIcon[0] != '\0' )
- {
- m_icon = gHUD.GetIcon( m_szIcon );
- }
-
- SetFgColor( pScheme->GetColor( "FgColor", Color( 255, 255, 255, 255 ) ) );
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "IconPanel.h"
+#include "KeyValues.h"
+
+DECLARE_BUILD_FACTORY( CIconPanel );
+
+CIconPanel::CIconPanel( vgui::Panel *parent, const char *name ) : vgui::Panel( parent, name )
+{
+ m_szIcon[0] = '\0';
+ m_icon = NULL;
+ m_bScaleImage = false;
+}
+
+void CIconPanel::ApplySettings( KeyValues *inResourceData )
+{
+ Q_strncpy( m_szIcon, inResourceData->GetString( "icon", "" ), sizeof( m_szIcon ) );
+
+ m_icon = gHUD.GetIcon( m_szIcon );
+
+ m_bScaleImage = inResourceData->GetInt("scaleImage", 0);
+
+ BaseClass::ApplySettings( inResourceData );
+}
+
+void CIconPanel::SetIcon( const char *szIcon )
+{
+ Q_strncpy( m_szIcon, szIcon, sizeof(m_szIcon) );
+
+ m_icon = gHUD.GetIcon( m_szIcon );
+}
+
+void CIconPanel::Paint()
+{
+ BaseClass::Paint();
+
+ if ( m_icon )
+ {
+ int x, y, w, h;
+ GetBounds( x, y, w, h );
+
+ if ( m_bScaleImage )
+ {
+ m_icon->DrawSelf( 0, 0, w, h, m_IconColor );
+ }
+ else
+ {
+ m_icon->DrawSelf( 0, 0, m_IconColor );
+ }
+ }
+}
+
+void CIconPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ if ( m_szIcon[0] != '\0' )
+ {
+ m_icon = gHUD.GetIcon( m_szIcon );
+ }
+
+ SetFgColor( pScheme->GetColor( "FgColor", Color( 255, 255, 255, 255 ) ) );
+}
diff --git a/mp/src/game/client/game_controls/IconPanel.h b/mp/src/game/client/game_controls/IconPanel.h
index c9936284..f9dcb243 100644
--- a/mp/src/game/client/game_controls/IconPanel.h
+++ b/mp/src/game/client/game_controls/IconPanel.h
@@ -1,42 +1,42 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef ICONPANEL_H
-#define ICONPANEL_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui_controls/Panel.h>
-
-using namespace vgui;
-
-class CIconPanel : public vgui::Panel
-{
- DECLARE_CLASS_SIMPLE( CIconPanel, vgui::Panel );
-
-public:
- CIconPanel( vgui::Panel *parent, const char *name );
-
- void Init( void );
- virtual void Paint();
- virtual void ApplySettings( KeyValues *inResourceData );
- virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
-
- void SetIcon( const char *szIcon );
- void SetIconColor( Color cColor ) { m_IconColor = cColor; }
-
-private:
- CHudTexture *m_icon;
- char m_szIcon[128];
-
- bool m_bScaleImage;
-
- CPanelAnimationVar( Color, m_IconColor, "iconColor", "255 255 255 255" );
-};
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef ICONPANEL_H
+#define ICONPANEL_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui_controls/Panel.h>
+
+using namespace vgui;
+
+class CIconPanel : public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CIconPanel, vgui::Panel );
+
+public:
+ CIconPanel( vgui::Panel *parent, const char *name );
+
+ void Init( void );
+ virtual void Paint();
+ virtual void ApplySettings( KeyValues *inResourceData );
+ virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
+
+ void SetIcon( const char *szIcon );
+ void SetIconColor( Color cColor ) { m_IconColor = cColor; }
+
+private:
+ CHudTexture *m_icon;
+ char m_szIcon[128];
+
+ bool m_bScaleImage;
+
+ CPanelAnimationVar( Color, m_IconColor, "iconColor", "255 255 255 255" );
+};
+
#endif //ICONPANEL_H \ No newline at end of file
diff --git a/mp/src/game/client/game_controls/MapOverview.cpp b/mp/src/game/client/game_controls/MapOverview.cpp
index 9f335b26..b4262fbb 100644
--- a/mp/src/game/client/game_controls/MapOverview.cpp
+++ b/mp/src/game/client/game_controls/MapOverview.cpp
@@ -1,1340 +1,1340 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: MapOverview.cpp: implementation of the CMapOverview class.
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include "mapoverview.h"
-#include <vgui/ISurface.h>
-#include <vgui/ILocalize.h>
-#include <filesystem.h>
-#include <KeyValues.h>
-#include <convar.h>
-#include "mathlib/mathlib.h"
-#include <game/client/iviewport.h>
-#include <igameresources.h>
-#include "gamevars_shared.h"
-#include "spectatorgui.h"
-#include "c_playerresource.h"
-#include "view.h"
-
-#include "clientmode.h"
-#include <vgui_controls/AnimationController.h>
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-ConVar overview_health( "overview_health", "1", FCVAR_ARCHIVE | FCVAR_CLIENTCMD_CAN_EXECUTE, "Show player's health in map overview.\n" );
-ConVar overview_names ( "overview_names", "1", FCVAR_ARCHIVE | FCVAR_CLIENTCMD_CAN_EXECUTE, "Show player's names in map overview.\n" );
-ConVar overview_tracks( "overview_tracks", "1", FCVAR_ARCHIVE | FCVAR_CLIENTCMD_CAN_EXECUTE, "Show player's tracks in map overview.\n" );
-ConVar overview_locked( "overview_locked", "1", FCVAR_ARCHIVE | FCVAR_CLIENTCMD_CAN_EXECUTE, "Locks map angle, doesn't follow view angle.\n" );
-ConVar overview_alpha( "overview_alpha", "1.0", FCVAR_ARCHIVE | FCVAR_CLIENTCMD_CAN_EXECUTE, "Overview map translucency.\n" );
-
-IMapOverviewPanel *g_pMapOverview = NULL; // we assume only one overview is created
-
-static int AdjustValue( int curValue, int targetValue, int amount )
-{
- if ( curValue > targetValue )
- {
- curValue -= amount;
-
- if ( curValue < targetValue )
- curValue = targetValue;
- }
- else if ( curValue < targetValue )
- {
- curValue += amount;
-
- if ( curValue > targetValue )
- curValue = targetValue;
- }
-
- return curValue;
-}
-
-CON_COMMAND( overview_zoom, "Sets overview map zoom: <zoom> [<time>] [rel]" )
-{
- if ( !g_pMapOverview || args.ArgC() < 2 )
- return;
-
- float zoom = Q_atof( args[ 1 ] );
-
- float time = 0;
-
- if ( args.ArgC() >= 3 )
- time = Q_atof( args[ 2 ] );
-
- if ( args.ArgC() == 4 )
- zoom *= g_pMapOverview->GetZoom();
-
- // We are going to store their zoom pick as the resultant overview size that it sees. This way, the value will remain
- // correct even on a different map that has a different intrinsic zoom.
- float desiredViewSize = 0.0f;
- desiredViewSize = (zoom * OVERVIEW_MAP_SIZE * g_pMapOverview->GetFullZoom()) / g_pMapOverview->GetMapScale();
- g_pMapOverview->SetPlayerPreferredViewSize( desiredViewSize );
-
- if( !g_pMapOverview->AllowConCommandsWhileAlive() )
- {
- C_BasePlayer *localPlayer = CBasePlayer::GetLocalPlayer();
- if( localPlayer && CBasePlayer::GetLocalPlayer()->IsAlive() )
- return;// Not allowed to execute commands while alive
- else if( localPlayer && localPlayer->GetObserverMode() == OBS_MODE_DEATHCAM )
- return;// In the death cam spiral counts as alive
- }
-
- g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( g_pMapOverview->GetAsPanel(), "zoom", zoom, 0.0, time, vgui::AnimationController::INTERPOLATOR_LINEAR );
-}
-
-CON_COMMAND( overview_mode, "Sets overview map mode off,small,large: <0|1|2>" )
-{
- if ( !g_pMapOverview )
- return;
-
- int mode;
-
- if ( args.ArgC() < 2 )
- {
- // toggle modes
- mode = g_pMapOverview->GetMode() + 1;
-
- if ( mode > CMapOverview::MAP_MODE_FULL )
- mode = CMapOverview::MAP_MODE_OFF;
- }
- else
- {
- // set specific mode
- mode = Q_atoi( args[ 1 ] );
- }
-
- if( mode != CMapOverview::MAP_MODE_RADAR )
- g_pMapOverview->SetPlayerPreferredMode( mode );
-
- if( !g_pMapOverview->AllowConCommandsWhileAlive() )
- {
- C_BasePlayer *localPlayer = CBasePlayer::GetLocalPlayer();
- if( localPlayer && CBasePlayer::GetLocalPlayer()->IsAlive() )
- return;// Not allowed to execute commands while alive
- else if( localPlayer && localPlayer->GetObserverMode() == OBS_MODE_DEATHCAM )
- return;// In the death cam spiral counts as alive
- }
-
- g_pMapOverview->SetMode( mode );
-}
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-
-using namespace vgui;
-
-CMapOverview::CMapOverview( const char *pElementName ) : BaseClass( NULL, pElementName ), CHudElement( pElementName )
-{
- SetParent( g_pClientMode->GetViewport()->GetVPanel() );
-
- SetBounds( 0,0, 256, 256 );
- SetBgColor( Color( 0,0,0,100 ) );
- SetPaintBackgroundEnabled( true );
- ShowPanel( false );
-
- // Make sure we actually have the font...
- vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
-
- m_hIconFont = pScheme->GetFont( "DefaultSmall" );
-
- m_nMapTextureID = -1;
- m_MapKeyValues = NULL;
-
- m_MapOrigin = Vector( 0, 0, 0 );
- m_fMapScale = 1.0f;
- m_bFollowAngle = false;
- SetMode( MAP_MODE_OFF );
-
- m_fZoom = 3.0f;
- m_MapCenter = Vector2D( 512, 512 );
- m_ViewOrigin = Vector2D( 512, 512 );
- m_fViewAngle = 0;
- m_fTrailUpdateInterval = 1.0f;
-
- m_bShowNames = true;
- m_bShowHealth = true;
- m_bShowTrails = true;
-
- m_flChangeSpeed = 1000;
- m_flIconSize = 64.0f;
-
- m_ObjectCounterID = 1;
-
- Reset();
-
- Q_memset( m_Players, 0, sizeof(m_Players) );
-
- InitTeamColorsAndIcons();
-
- g_pMapOverview = this; // for cvars access etc
-}
-
-void CMapOverview::Init( void )
-{
- // register for events as client listener
- ListenForGameEvent( "game_newmap" );
- ListenForGameEvent( "round_start" );
- ListenForGameEvent( "player_connect" );
- ListenForGameEvent( "player_info" );
- ListenForGameEvent( "player_team" );
- ListenForGameEvent( "player_spawn" );
- ListenForGameEvent( "player_death" );
- ListenForGameEvent( "player_disconnect" );
-}
-
-void CMapOverview::InitTeamColorsAndIcons()
-{
- Q_memset( m_TeamIcons, 0, sizeof(m_TeamIcons) );
- Q_memset( m_TeamColors, 0, sizeof(m_TeamColors) );
- Q_memset( m_ObjectIcons, 0, sizeof(m_ObjectIcons) );
-
- m_TextureIDs.RemoveAll();
-}
-
-int CMapOverview::AddIconTexture(const char *filename)
-{
- int index = m_TextureIDs.Find( filename );
-
- if ( m_TextureIDs.IsValidIndex( index ) )
- {
- // already known, return texture ID
- return m_TextureIDs.Element(index);
- }
-
- index = surface()->CreateNewTextureID();
- surface()->DrawSetTextureFile( index , filename, true, false);
-
- m_TextureIDs.Insert( filename, index );
-
- return index;
-}
-
-void CMapOverview::ApplySchemeSettings(vgui::IScheme *scheme)
-{
- BaseClass::ApplySchemeSettings( scheme );
-
- SetBgColor( Color( 0,0,0,100 ) );
- SetPaintBackgroundEnabled( true );
-}
-
-CMapOverview::~CMapOverview()
-{
- if ( m_MapKeyValues )
- m_MapKeyValues->deleteThis();
-
- g_pMapOverview = NULL;
-
- //TODO release Textures ? clear lists
-}
-
-void CMapOverview::UpdatePlayers()
-{
- if ( !g_PR )
- return;
-
- // first disable all players health
- for ( int i=0; i<MAX_PLAYERS; i++ )
- {
- m_Players[i].health = 0;
- m_Players[i].team = TEAM_SPECTATOR;
- }
-
- for ( int i = 1; i<= gpGlobals->maxClients; i++)
- {
- // update from global player resources
- if ( g_PR && g_PR->IsConnected(i) )
- {
- MapPlayer_t *player = &m_Players[i-1];
-
- player->health = g_PR->GetHealth( i );
-
- if ( !g_PR->IsAlive( i ) )
- {
- player->health = 0;
- }
-
- if ( player->team != g_PR->GetTeam( i ) )
- {
- player->team = g_PR->GetTeam( i );
- player->icon = m_TeamIcons[ GetIconNumberFromTeamNumber(player->team) ];
- player->color = m_TeamColors[ GetIconNumberFromTeamNumber(player->team) ];
- }
- }
-
- C_BasePlayer *pPlayer = UTIL_PlayerByIndex( i );
-
- if ( !pPlayer )
- continue;
-
- // don't update if player is dormant
- if ( pPlayer->IsDormant() )
- continue;
-
- // update position of active players in our PVS
- Vector position = pPlayer->EyePosition();
- QAngle angles = pPlayer->EyeAngles();
-
- SetPlayerPositions( i-1, position, angles );
- }
-}
-
-void CMapOverview::UpdatePlayerTrails()
-{
- if ( m_fNextTrailUpdate > m_fWorldTime )
- return;
-
- m_fNextTrailUpdate = m_fWorldTime + 1.0f; // update once a second
-
- for (int i=0; i<MAX_PLAYERS; i++)
- {
- MapPlayer_t *p = &m_Players[i];
-
- // no trails for spectators or dead players
- if ( (p->team <= TEAM_SPECTATOR) || (p->health <= 0) )
- {
- continue;
- }
-
- // move old trail points
- for ( int j=MAX_TRAIL_LENGTH-1; j>0; j--)
- {
- p->trail[j]=p->trail[j-1];
- }
-
- p->trail[0] = WorldToMap ( p->position );
- }
-}
-
-void CMapOverview::UpdateFollowEntity()
-{
- if ( m_nFollowEntity != 0 )
- {
- C_BaseEntity *ent = ClientEntityList().GetEnt( m_nFollowEntity );
-
- if ( ent )
- {
- Vector position = MainViewOrigin(); // Use MainViewOrigin so SourceTV works in 3rd person
- QAngle angle = ent->EyeAngles();
-
- if ( m_nFollowEntity <= MAX_PLAYERS )
- {
- SetPlayerPositions( m_nFollowEntity-1, position, angle );
- }
-
- SetCenter( WorldToMap(position) );
- SetAngle( angle[YAW] );
- }
- }
- else
- {
- SetCenter( Vector2D(OVERVIEW_MAP_SIZE/2,OVERVIEW_MAP_SIZE/2) );
- SetAngle( 0 );
- }
-}
-
-void CMapOverview::Paint()
-{
- UpdateSizeAndPosition();
-
- UpdateFollowEntity();
-
- UpdateObjects();
-
- UpdatePlayers();
-
- UpdatePlayerTrails();
-
- DrawMapTexture();
-
- DrawMapPlayerTrails();
-
- DrawObjects();
-
- DrawMapPlayers();
-
- DrawCamera();
-
- BaseClass::Paint();
-}
-
-bool CMapOverview::CanPlayerBeSeen(MapPlayer_t *player)
-{
- C_BasePlayer *localPlayer = C_BasePlayer::GetLocalPlayer();
-
- if ( !localPlayer || !player )
- return false;
-
- // don't draw ourself
- if ( localPlayer->GetUserID() == (player->userid) )
- return false;
-
- // Invalid guy.
- if( player->position == Vector(0,0,0) )
- return false;
-
- // if local player is on spectator team, he can see everyone
- if ( localPlayer->GetTeamNumber() <= TEAM_SPECTATOR )
- return true;
-
- // we never track unassigned or real spectators
- if ( player->team <= TEAM_SPECTATOR )
- return false;
-
- // if observer is an active player, check mp_forcecamera:
-
- if ( mp_forcecamera.GetInt() == OBS_ALLOW_NONE )
- return false;
-
- if ( mp_forcecamera.GetInt() == OBS_ALLOW_TEAM )
- {
- // true if both players are on the same team
- return (localPlayer->GetTeamNumber() == player->team );
- }
-
- // by default we can see all players
- return true;
-}
-
-/// allows mods to restrict health
-/// Note: index is 0-based
-bool CMapOverview::CanPlayerHealthBeSeen(MapPlayer_t *player)
-{
- C_BasePlayer *localPlayer = C_BasePlayer::GetLocalPlayer();
-
- if ( !localPlayer )
- return false;
-
- // real spectators can see everything
- if ( localPlayer->GetTeamNumber() <= TEAM_SPECTATOR )
- return true;
-
- if ( mp_forcecamera.GetInt() != OBS_ALLOW_ALL )
- {
- // if forcecamera is on, only show health for teammates
- return ( localPlayer->GetTeamNumber() == player->team );
- }
-
- return true;
-}
-
-// usually name rule is same as health rule
-bool CMapOverview::CanPlayerNameBeSeen(MapPlayer_t *player)
-{
- return CanPlayerHealthBeSeen( player );
-}
-
-void CMapOverview::SetPlayerPositions(int index, const Vector &position, const QAngle &angle)
-{
- MapPlayer_t *p = &m_Players[index];
-
- p->angle = angle;
- p->position = position;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: shows/hides the buy menu
-//-----------------------------------------------------------------------------
-void CMapOverview::ShowPanel(bool bShow)
-{
- SetVisible( bShow );
-}
-
-void CMapOverview::OnThink( void )
-{
- if ( NeedsUpdate() )
- {
- Update();
- m_fNextUpdateTime = gpGlobals->curtime + 0.2f; // update 5 times a second
- }
-}
-
-bool CMapOverview::NeedsUpdate( void )
-{
- return m_fNextUpdateTime < gpGlobals->curtime;
-}
-
-void CMapOverview::Update( void )
-{
- // update settings
- m_bShowNames = overview_names.GetBool() && ( GetMode() != MAP_MODE_RADAR );
- m_bShowHealth = overview_health.GetBool() && ( GetMode() != MAP_MODE_RADAR );
- m_bFollowAngle = ( GetMode() != MAP_MODE_RADAR && !overview_locked.GetBool() ) || ( GetMode() == MAP_MODE_RADAR && !IsRadarLocked() );
- m_fTrailUpdateInterval = overview_tracks.GetInt() && ( GetMode() != MAP_MODE_RADAR );
-
- m_fWorldTime = gpGlobals->curtime;
-
- C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
-
- if ( !pPlayer )
- return;
-
- int specmode = GetSpectatorMode();
-
- if ( specmode == OBS_MODE_IN_EYE || specmode == OBS_MODE_CHASE )
- {
- // follow target
- SetFollowEntity( GetSpectatorTarget() );
- }
- else
- {
- // follow ourself otherwise
- SetFollowEntity( pPlayer->entindex() );
- }
-}
-
-void CMapOverview::Reset( void )
-{
- m_fNextUpdateTime = 0;
-}
-
-void CMapOverview::SetData(KeyValues *data)
-{
- m_fZoom = data->GetFloat( "zoom", m_fZoom );
- m_nFollowEntity = data->GetInt( "entity", m_nFollowEntity );
-}
-
-
-CMapOverview::MapPlayer_t* CMapOverview::GetPlayerByUserID( int userID )
-{
- for (int i=0; i<MAX_PLAYERS; i++)
- {
- MapPlayer_t *player = &m_Players[i];
-
- if ( player->userid == userID )
- return player;
- }
-
- return NULL;
-}
-
-bool CMapOverview::IsInPanel(Vector2D &pos)
-{
- int x,y,w,t;
-
- GetBounds( x,y,w,t );
-
- return ( pos.x >= 0 && pos.x < w && pos.y >= 0 && pos.y < t );
-}
-
-void CMapOverview::DrawMapTexture()
-{
- // now draw a box around the outside of this panel
- int x0, y0, x1, y1;
- int wide, tall;
-
- GetSize(wide, tall);
- x0 = 0; y0 = 0; x1 = wide - 2; y1 = tall - 2 ;
-
- if ( m_nMapTextureID < 0 )
- return;
-
- Vertex_t points[4] =
- {
- Vertex_t( MapToPanel ( Vector2D(0,0) ), Vector2D(0,0) ),
- Vertex_t( MapToPanel ( Vector2D(OVERVIEW_MAP_SIZE-1,0) ), Vector2D(1,0) ),
- Vertex_t( MapToPanel ( Vector2D(OVERVIEW_MAP_SIZE-1,OVERVIEW_MAP_SIZE-1) ), Vector2D(1,1) ),
- Vertex_t( MapToPanel ( Vector2D(0,OVERVIEW_MAP_SIZE-1) ), Vector2D(0,1) )
- };
-
- int alpha = 255.0f * overview_alpha.GetFloat(); clamp( alpha, 1, 255 );
-
- surface()->DrawSetColor( 255,255,255, alpha );
- surface()->DrawSetTexture( m_nMapTextureID );
- surface()->DrawTexturedPolygon( 4, points );
-}
-
-void CMapOverview::DrawMapPlayerTrails()
-{
- if ( m_fTrailUpdateInterval <= 0 )
- return; // turned off
-
- for (int i=0; i<MAX_PLAYERS; i++)
- {
- MapPlayer_t *player = &m_Players[i];
-
- if ( !CanPlayerBeSeen(player) )
- continue;
-
- player->trail[0] = WorldToMap ( player->position );
-
- for ( int i=0; i<(MAX_TRAIL_LENGTH-1); i++)
- {
- if ( player->trail[i+1].x == 0 && player->trail[i+1].y == 0 )
- break;
-
- Vector2D pos1 = MapToPanel( player->trail[i] );
- Vector2D pos2 = MapToPanel( player->trail[i+1] );
-
- int intensity = 255 - float(255.0f * i) / MAX_TRAIL_LENGTH;
-
- Vector2D dist = pos1 - pos2;
-
- // don't draw too long lines, player probably teleported
- if ( dist.LengthSqr() < (128*128) )
- {
- surface()->DrawSetColor( player->color[0], player->color[1], player->color[2], intensity );
- surface()->DrawLine( pos1.x, pos1.y, pos2.x, pos2.y );
- }
- }
- }
-}
-
-void CMapOverview::DrawObjects( )
-{
- surface()->DrawSetTextFont( m_hIconFont );
-
- for (int i=0; i<m_Objects.Count(); i++)
- {
- MapObject_t *obj = &m_Objects[i];
-
- const char *text = NULL;
-
- if ( Q_strlen(obj->name) > 0 )
- text = obj->name;
-
- float flAngle = obj->angle[YAW];
-
- if ( obj->flags & MAP_OBJECT_ALIGN_TO_MAP && m_bRotateMap )
- {
- if ( m_bRotateMap )
- flAngle = 90;
- else
- flAngle = 0;
- }
-
- MapObject_t tempObj = *obj;
- tempObj.angle[YAW] = flAngle;
- tempObj.text = text;
- tempObj.statusColor = obj->color;
-
- // draw icon
- if ( !DrawIcon( &tempObj ) )
- continue;
- }
-}
-
-bool CMapOverview::DrawIcon( MapObject_t *obj )
-{
- int textureID = obj->icon;
- Vector pos = obj->position;
- float scale = obj->size;
- float angle = obj->angle[YAW];
- const char *text = obj->text;
- Color *textColor = &obj->color;
- float status = obj->status;
- Color *statusColor = &obj->statusColor;
-
- Vector offset; offset.z = 0;
-
- Vector2D pospanel = WorldToMap( pos );
- pospanel = MapToPanel( pospanel );
-
- if ( !IsInPanel( pospanel ) )
- return false; // player is not within overview panel
-
- offset.x = -scale; offset.y = scale;
- VectorYawRotate( offset, angle, offset );
- Vector2D pos1 = WorldToMap( pos + offset );
-
- offset.x = scale; offset.y = scale;
- VectorYawRotate( offset, angle, offset );
- Vector2D pos2 = WorldToMap( pos + offset );
-
- offset.x = scale; offset.y = -scale;
- VectorYawRotate( offset, angle, offset );
- Vector2D pos3 = WorldToMap( pos + offset );
-
- offset.x = -scale; offset.y = -scale;
- VectorYawRotate( offset, angle, offset );
- Vector2D pos4 = WorldToMap( pos + offset );
-
- Vertex_t points[4] =
- {
- Vertex_t( MapToPanel ( pos1 ), Vector2D(0,0) ),
- Vertex_t( MapToPanel ( pos2 ), Vector2D(1,0) ),
- Vertex_t( MapToPanel ( pos3 ), Vector2D(1,1) ),
- Vertex_t( MapToPanel ( pos4 ), Vector2D(0,1) )
- };
-
- surface()->DrawSetColor( 255, 255, 255, 255 );
- surface()->DrawSetTexture( textureID );
- surface()->DrawTexturedPolygon( 4, points );
-
- int d = GetPixelOffset( scale);
-
- pospanel.y += d + 4;
-
- if ( status >=0.0f && status <= 1.0f && statusColor )
- {
- // health bar is 50x3 pixels
- surface()->DrawSetColor( 0,0,0,255 );
- surface()->DrawFilledRect( pospanel.x-d, pospanel.y-1, pospanel.x+d, pospanel.y+1 );
-
- int length = (float)(d*2)*status;
- surface()->DrawSetColor( statusColor->r(), statusColor->g(), statusColor->b(), 255 );
- surface()->DrawFilledRect( pospanel.x-d, pospanel.y-1, pospanel.x-d+length, pospanel.y+1 );
-
- pospanel.y += 3;
- }
-
- if ( text && textColor )
- {
- wchar_t iconText[ MAX_PLAYER_NAME_LENGTH*2 ];
-
- g_pVGuiLocalize->ConvertANSIToUnicode( text, iconText, sizeof( iconText ) );
-
- int wide, tall;
- surface()->GetTextSize( m_hIconFont, iconText, wide, tall );
-
- int x = pospanel.x-(wide/2);
- int y = pospanel.y;
-
- // draw black shadow text
- surface()->DrawSetTextColor( 0, 0, 0, 255 );
- surface()->DrawSetTextPos( x+1, y );
- surface()->DrawPrintText( iconText, wcslen(iconText) );
-
- // draw name in color
- surface()->DrawSetTextColor( textColor->r(), textColor->g(), textColor->b(), 255 );
- surface()->DrawSetTextPos( x, y );
- surface()->DrawPrintText( iconText, wcslen(iconText) );
- }
-
- return true;
-}
-
-int CMapOverview::GetPixelOffset( float height )
-{
- Vector2D pos2 = WorldToMap( Vector( height,0,0) );
- pos2 = MapToPanel( pos2 );
-
- Vector2D pos3 = WorldToMap( Vector(0,0,0) );
- pos3 = MapToPanel( pos3 );
-
- int a = pos2.y-pos3.y;
- int b = pos2.x-pos3.x;
-
- return (int)sqrt((float)(a*a+b*b)); // number of panel pixels for "scale" units in world
-}
-
-void CMapOverview::DrawMapPlayers()
-{
- surface()->DrawSetTextFont( m_hIconFont );
-
- Color colorGreen( 0, 255, 0, 255 ); // health bar color
-
- for (int i=0; i<MAX_PLAYERS; i++)
- {
- MapPlayer_t *player = &m_Players[i];
-
- if ( !CanPlayerBeSeen( player ) )
- continue;
-
- // don't draw dead players / spectators
- if ( player->health <= 0 )
- continue;
-
- float status = -1;
- const char *name = NULL;
-
- if ( m_bShowNames && CanPlayerNameBeSeen( player ) )
- name = player->name;
-
- if ( m_bShowHealth && CanPlayerHealthBeSeen( player ) )
- status = player->health/100.0f;
-
- // convert from PlayerObject_t
- MapObject_t tempObj;
- memset( &tempObj, 0, sizeof(MapObject_t) );
- tempObj.icon = player->icon;
- tempObj.position = player->position;
- tempObj.size = m_flIconSize;
- tempObj.angle = player->angle;
- tempObj.text = name;
- tempObj.color = player->color;
- tempObj.status = status;
- tempObj.statusColor = colorGreen;
-
- DrawIcon( &tempObj );
- }
-}
-
-Vector2D CMapOverview::WorldToMap( const Vector &worldpos )
-{
- Vector2D offset( worldpos.x - m_MapOrigin.x, worldpos.y - m_MapOrigin.y);
-
- offset.x /= m_fMapScale;
- offset.y /= -m_fMapScale;
-
- return offset;
-}
-
-float CMapOverview::GetViewAngle( void )
-{
- float viewAngle = m_fViewAngle - 90.0f;
-
- if ( !m_bFollowAngle )
- {
- // We don't use fViewAngle. We just show straight at all times.
- if ( m_bRotateMap )
- viewAngle = 90.0f;
- else
- viewAngle = 0.0f;
- }
-
- return viewAngle;
-}
-
-Vector2D CMapOverview::MapToPanel( const Vector2D &mappos )
-{
- int pwidth, pheight;
- Vector2D panelpos;
- float viewAngle = GetViewAngle();
-
- GetSize(pwidth, pheight);
-
- Vector offset;
- offset.x = mappos.x - m_MapCenter.x;
- offset.y = mappos.y - m_MapCenter.y;
- offset.z = 0;
-
- VectorYawRotate( offset, viewAngle, offset );
-
- // find the actual zoom from the animationvar m_fZoom and the map zoom scale
- float fScale = (m_fZoom * m_fFullZoom) / OVERVIEW_MAP_SIZE;
-
- offset.x *= fScale;
- offset.y *= fScale;
-
- panelpos.x = (pwidth * 0.5f) + (pheight * offset.x);
- panelpos.y = (pheight * 0.5f) + (pheight * offset.y);
-
- return panelpos;
-}
-
-void CMapOverview::SetTime( float time )
-{
- m_fWorldTime = time;
-}
-
-void CMapOverview::SetMap(const char * levelname)
-{
- // Reset players and objects, even if the map is the same as the previous one
- m_Objects.RemoveAll();
-
- m_fNextTrailUpdate = 0;// Set to 0 for immediate update. Our WorldTime var hasn't been updated to 0 for the new map yet
- m_fWorldTime = 0;// In release, we occasionally race and get this bug again if we gt a paint before an update. Reset this before the old value gets in to the timer.
- // Please note, UpdatePlayerTrails comes from PAINT, not UPDATE.
-
- InitTeamColorsAndIcons();
-
- // load new KeyValues
- if ( m_MapKeyValues && Q_strcmp( levelname, m_MapKeyValues->GetName() ) == 0 )
- {
- return; // map didn't change
- }
-
- if ( m_MapKeyValues )
- m_MapKeyValues->deleteThis();
-
- m_MapKeyValues = new KeyValues( levelname );
-
- char tempfile[MAX_PATH];
- Q_snprintf( tempfile, sizeof( tempfile ), "resource/overviews/%s.txt", levelname );
-
- if ( !m_MapKeyValues->LoadFromFile( g_pFullFileSystem, tempfile, "GAME" ) )
- {
- DevMsg( 1, "Error! CMapOverview::SetMap: couldn't load file %s.\n", tempfile );
- m_nMapTextureID = -1;
- m_MapOrigin.x = 0;
- m_MapOrigin.y = 0;
- m_fMapScale = 1;
- m_bRotateMap = false;
- m_fFullZoom = 1;
- return;
- }
-
- // TODO release old texture ?
-
- m_nMapTextureID = surface()->CreateNewTextureID();
-
- //if we have not uploaded yet, lets go ahead and do so
- surface()->DrawSetTextureFile( m_nMapTextureID, m_MapKeyValues->GetString("material"), true, false);
-
- int wide, tall;
-
- surface()->DrawGetTextureSize( m_nMapTextureID, wide, tall );
-
- if ( wide != tall )
- {
- DevMsg( 1, "Error! CMapOverview::SetMap: map image must be a square.\n" );
- m_nMapTextureID = -1;
- return;
- }
-
- m_MapOrigin.x = m_MapKeyValues->GetInt("pos_x");
- m_MapOrigin.y = m_MapKeyValues->GetInt("pos_y");
- m_fMapScale = m_MapKeyValues->GetFloat("scale", 1.0f);
- m_bRotateMap = m_MapKeyValues->GetInt("rotate")!=0;
- m_fFullZoom = m_MapKeyValues->GetFloat("zoom", 1.0f );
-}
-
-void CMapOverview::ResetRound()
-{
- for (int i=0; i<MAX_PLAYERS; i++)
- {
- MapPlayer_t *p = &m_Players[i];
-
- if ( p->team > TEAM_SPECTATOR )
- {
- p->health = 100;
- }
-
- Q_memset( p->trail, 0, sizeof(p->trail) );
-
- p->position = Vector( 0, 0, 0 );
- }
-
- m_Objects.RemoveAll();
-}
-
-void CMapOverview::OnMousePressed( MouseCode code )
-{
-
-}
-
-void CMapOverview::DrawCamera()
-{
- // draw a red center point
- surface()->DrawSetColor( 255,0,0,255 );
- Vector2D center = MapToPanel( m_ViewOrigin );
- surface()->DrawFilledRect( center.x-2, center.y-2, center.x+2, center.y+2);
-}
-
-void CMapOverview::FireGameEvent( IGameEvent *event )
-{
- const char * type = event->GetName();
-
- if ( Q_strcmp(type, "game_newmap") == 0 )
- {
- SetMap( event->GetString("mapname") );
- ResetRound();
- }
-
- else if ( Q_strcmp(type, "round_start") == 0 )
- {
- ResetRound();
- }
-
- else if ( Q_strcmp(type,"player_connect") == 0 )
- {
- int index = event->GetInt("index"); // = entity index - 1
-
- if ( index < 0 || index >= MAX_PLAYERS )
- return;
-
- MapPlayer_t *player = &m_Players[index];
-
- player->index = index;
- player->userid = event->GetInt("userid");
- Q_strncpy( player->name, event->GetString("name","unknown"), sizeof(player->name) );
-
- // Reset settings
- Q_memset( player->trail, 0, sizeof(player->trail) );
- player->team = TEAM_UNASSIGNED;
- player->health = 0;
- }
-
- else if ( Q_strcmp(type,"player_info") == 0 )
- {
- int index = event->GetInt("index"); // = entity index - 1
-
- if ( index < 0 || index >= MAX_PLAYERS )
- return;
-
- MapPlayer_t *player = &m_Players[index];
-
- player->index = index;
- player->userid = event->GetInt("userid");
- Q_strncpy( player->name, event->GetString("name","unknown"), sizeof(player->name) );
- }
-
- else if ( Q_strcmp(type,"player_team") == 0 )
- {
- MapPlayer_t *player = GetPlayerByUserID( event->GetInt("userid") );
-
- if ( !player )
- return;
-
- player->team = event->GetInt("team");
- player->icon = m_TeamIcons[ GetIconNumberFromTeamNumber(player->team) ];
- player->color = m_TeamColors[ GetIconNumberFromTeamNumber(player->team) ];
- }
-
- else if ( Q_strcmp(type,"player_death") == 0 )
- {
- MapPlayer_t *player = GetPlayerByUserID( event->GetInt("userid") );
-
- if ( !player )
- return;
-
- player->health = 0;
- Q_memset( player->trail, 0, sizeof(player->trail) ); // clear trails
- }
-
- else if ( Q_strcmp(type,"player_spawn") == 0 )
- {
- MapPlayer_t *player = GetPlayerByUserID( event->GetInt("userid") );
-
- if ( !player )
- return;
-
- player->health = 100;
- Q_memset( player->trail, 0, sizeof(player->trail) ); // clear trails
- }
-
- else if ( Q_strcmp(type,"player_disconnect") == 0 )
- {
- MapPlayer_t *player = GetPlayerByUserID( event->GetInt("userid") );
-
- if ( !player )
- return;
-
- Q_memset( player, 0, sizeof(MapPlayer_t) ); // clear player field
- }
-}
-
-void CMapOverview::SetMode(int mode)
-{
- m_flChangeSpeed = 0; // change size instantly
-
- if ( mode == MAP_MODE_OFF )
- {
- ShowPanel( false );
-
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapOff" );
- }
- else if ( mode == MAP_MODE_INSET )
- {
- if( m_nMapTextureID == -1 )
- {
- SetMode( MAP_MODE_OFF );
- return;
- }
-
- if ( m_nMode != MAP_MODE_OFF )
- m_flChangeSpeed = 1000; // zoom effect
-
- C_BasePlayer *pPlayer = CBasePlayer::GetLocalPlayer();
-
- if ( pPlayer )
- SetFollowEntity( pPlayer->entindex() );
-
- ShowPanel( true );
-
- if ( mode != m_nMode && RunHudAnimations() )
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapZoomToSmall" );
- }
- }
- else if ( mode == MAP_MODE_FULL )
- {
- if( m_nMapTextureID == -1 )
- {
- SetMode( MAP_MODE_OFF );
- return;
- }
-
- if ( m_nMode != MAP_MODE_OFF )
- m_flChangeSpeed = 1000; // zoom effect
-
- SetFollowEntity( 0 );
-
- ShowPanel( true );
-
- if ( mode != m_nMode && RunHudAnimations() )
- {
- g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapZoomToLarge" );
- }
- }
-
- // finally set mode
- m_nMode = mode;
-
- UpdateSizeAndPosition();
-}
-
-bool CMapOverview::ShouldDraw( void )
-{
- return ( m_nMode != MAP_MODE_OFF ) && CHudElement::ShouldDraw();
-}
-
-void CMapOverview::UpdateSizeAndPosition()
-{
- if ( g_pSpectatorGUI && g_pSpectatorGUI->IsVisible() )
- {
- int iScreenWide, iScreenTall;
- GetHudSize( iScreenWide, iScreenTall );
-
- int iTopBarHeight = g_pSpectatorGUI->GetTopBarHeight();
- int iBottomBarHeight = g_pSpectatorGUI->GetBottomBarHeight();
-
- iScreenTall -= ( iTopBarHeight + iBottomBarHeight );
-
- int x,y,w,h;
- GetBounds( x,y,w,h );
-
- if ( y < iTopBarHeight )
- y = iTopBarHeight;
-
- SetBounds( x,y,w,MIN(h,iScreenTall) );
- }
-}
-
-void CMapOverview::SetCenter(const Vector2D &mappos)
-{
- int width, height;
-
- GetSize( width, height);
-
- m_ViewOrigin = mappos;
- m_MapCenter = mappos;
-
- float fTwiceZoom = m_fZoom * m_fFullZoom * 2;
-
- width = height = OVERVIEW_MAP_SIZE / (fTwiceZoom);
-
- if( GetMode() != MAP_MODE_RADAR )
- {
- if ( m_MapCenter.x < width )
- m_MapCenter.x = width;
-
- if ( m_MapCenter.x > (OVERVIEW_MAP_SIZE-width) )
- m_MapCenter.x = (OVERVIEW_MAP_SIZE-width);
-
- if ( m_MapCenter.y < height )
- m_MapCenter.y = height;
-
- if ( m_MapCenter.y > (OVERVIEW_MAP_SIZE-height) )
- m_MapCenter.y = (OVERVIEW_MAP_SIZE-height);
-
- //center if in full map mode
- if ( m_fZoom <= 1.0 )
- {
- m_MapCenter.x = OVERVIEW_MAP_SIZE/2;
- m_MapCenter.y = OVERVIEW_MAP_SIZE/2;
- }
- }
-
-}
-
-void CMapOverview::SetFollowAngle(bool state)
-{
- m_bFollowAngle = state;
-}
-
-void CMapOverview::SetFollowEntity(int entindex)
-{
- m_nFollowEntity = entindex;
-}
-
-float CMapOverview::GetZoom( void )
-{
- return m_fZoom;
-}
-
-int CMapOverview::GetMode( void )
-{
- return m_nMode;
-}
-
-void CMapOverview::SetAngle(float angle)
-{
- m_fViewAngle = angle;
-}
-
-void CMapOverview::ShowPlayerNames(bool state)
-{
- m_bShowNames = state;
-}
-
-
-void CMapOverview::ShowPlayerHealth(bool state)
-{
- m_bShowHealth = state;
-}
-
-void CMapOverview::ShowPlayerTracks(float seconds)
-{
- m_fTrailUpdateInterval = seconds;
-}
-
-bool CMapOverview::SetTeamColor(int team, Color color)
-{
- if ( team < 0 || team>= MAX_TEAMS )
- return false;
-
- m_TeamColors[team] = color;
-
- return true;
-}
-
-CMapOverview::MapObject_t* CMapOverview::FindObjectByID(int objectID)
-{
- for ( int i = 0; i < m_Objects.Count(); i++ )
- {
- if ( m_Objects[i].objectID == objectID )
- return &m_Objects[i];
- }
-
- return NULL;
-}
-
-int CMapOverview::AddObject( const char *icon, int entity, float timeToLive )
-{
- MapObject_t obj; Q_memset( &obj, 0, sizeof(obj) );
-
- obj.objectID = m_ObjectCounterID++;
- obj.index = entity;
- obj.icon = AddIconTexture( icon );
- obj.size = m_flIconSize;
- obj.status = -1;
-
- if ( timeToLive > 0 )
- obj.endtime = gpGlobals->curtime + timeToLive;
- else
- obj.endtime = -1;
-
- m_Objects.AddToTail( obj );
-
- return obj.objectID;
-}
-
-void CMapOverview::SetObjectText( int objectID, const char *text, Color color )
-{
- MapObject_t* obj = FindObjectByID( objectID );
-
- if ( !obj )
- return;
-
- if ( text )
- {
- Q_strncpy( obj->name, text, sizeof(obj->name) );
- }
- else
- {
- Q_memset( obj->name, 0, sizeof(obj->name) );
- }
-
- obj->color = color;
-}
-
-void CMapOverview::SetObjectStatus( int objectID, float status, Color color )
-{
- MapObject_t* obj = FindObjectByID( objectID );
-
- if ( !obj )
- return;
-
- obj->status = status;
- obj->statusColor = color;
-}
-
-void CMapOverview::SetObjectIcon( int objectID, const char *icon, float size )
-{
- MapObject_t* obj = FindObjectByID( objectID );
-
- if ( !obj )
- return;
-
- obj->icon = AddIconTexture( icon );
- obj->size = size;
-}
-
-void CMapOverview::SetObjectPosition( int objectID, const Vector &position, const QAngle &angle )
-{
- MapObject_t* obj = FindObjectByID( objectID );
-
- if ( !obj )
- return;
-
- obj->angle = angle;
- obj->position = position;
-}
-
-void CMapOverview::AddObjectFlags( int objectID, int flags )
-{
- MapObject_t* obj = FindObjectByID( objectID );
-
- if ( !obj )
- return;
-
- obj->flags |= flags;
-}
-
-void CMapOverview::SetObjectFlags( int objectID, int flags )
-{
- MapObject_t* obj = FindObjectByID( objectID );
-
- if ( !obj )
- return;
-
- obj->flags = flags;
-}
-
-void CMapOverview::RemoveObjectByIndex( int index )
-{
- for ( int i = 0; i < m_Objects.Count(); i++ )
- {
- if ( m_Objects[i].index == index )
- {
- m_Objects.Remove( i );
- return;
- }
- }
-}
-
-void CMapOverview::RemoveObject( int objectID )
-{
- for ( int i = 0; i < m_Objects.Count(); i++ )
- {
- if ( m_Objects[i].objectID == objectID )
- {
- m_Objects.Remove( i );
- return;
- }
- }
-}
-
-void CMapOverview::UpdateObjects()
-{
- for ( int i = 0; i < m_Objects.Count(); i++ )
- {
- MapObject_t *obj = &m_Objects[i];
-
- if ( obj->endtime > 0 && obj->endtime < gpGlobals->curtime )
- {
- m_Objects.Remove( i );
- i--;
- continue;
- }
-
- if ( obj->index <= 0 )
- continue;
-
- C_BaseEntity *entity = ClientEntityList().GetEnt( obj->index );
-
- if ( !entity )
- continue;
-
- obj->position = entity->GetAbsOrigin();
- obj->angle = entity->GetAbsAngles();
- }
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: MapOverview.cpp: implementation of the CMapOverview class.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "mapoverview.h"
+#include <vgui/ISurface.h>
+#include <vgui/ILocalize.h>
+#include <filesystem.h>
+#include <KeyValues.h>
+#include <convar.h>
+#include "mathlib/mathlib.h"
+#include <game/client/iviewport.h>
+#include <igameresources.h>
+#include "gamevars_shared.h"
+#include "spectatorgui.h"
+#include "c_playerresource.h"
+#include "view.h"
+
+#include "clientmode.h"
+#include <vgui_controls/AnimationController.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+ConVar overview_health( "overview_health", "1", FCVAR_ARCHIVE | FCVAR_CLIENTCMD_CAN_EXECUTE, "Show player's health in map overview.\n" );
+ConVar overview_names ( "overview_names", "1", FCVAR_ARCHIVE | FCVAR_CLIENTCMD_CAN_EXECUTE, "Show player's names in map overview.\n" );
+ConVar overview_tracks( "overview_tracks", "1", FCVAR_ARCHIVE | FCVAR_CLIENTCMD_CAN_EXECUTE, "Show player's tracks in map overview.\n" );
+ConVar overview_locked( "overview_locked", "1", FCVAR_ARCHIVE | FCVAR_CLIENTCMD_CAN_EXECUTE, "Locks map angle, doesn't follow view angle.\n" );
+ConVar overview_alpha( "overview_alpha", "1.0", FCVAR_ARCHIVE | FCVAR_CLIENTCMD_CAN_EXECUTE, "Overview map translucency.\n" );
+
+IMapOverviewPanel *g_pMapOverview = NULL; // we assume only one overview is created
+
+static int AdjustValue( int curValue, int targetValue, int amount )
+{
+ if ( curValue > targetValue )
+ {
+ curValue -= amount;
+
+ if ( curValue < targetValue )
+ curValue = targetValue;
+ }
+ else if ( curValue < targetValue )
+ {
+ curValue += amount;
+
+ if ( curValue > targetValue )
+ curValue = targetValue;
+ }
+
+ return curValue;
+}
+
+CON_COMMAND( overview_zoom, "Sets overview map zoom: <zoom> [<time>] [rel]" )
+{
+ if ( !g_pMapOverview || args.ArgC() < 2 )
+ return;
+
+ float zoom = Q_atof( args[ 1 ] );
+
+ float time = 0;
+
+ if ( args.ArgC() >= 3 )
+ time = Q_atof( args[ 2 ] );
+
+ if ( args.ArgC() == 4 )
+ zoom *= g_pMapOverview->GetZoom();
+
+ // We are going to store their zoom pick as the resultant overview size that it sees. This way, the value will remain
+ // correct even on a different map that has a different intrinsic zoom.
+ float desiredViewSize = 0.0f;
+ desiredViewSize = (zoom * OVERVIEW_MAP_SIZE * g_pMapOverview->GetFullZoom()) / g_pMapOverview->GetMapScale();
+ g_pMapOverview->SetPlayerPreferredViewSize( desiredViewSize );
+
+ if( !g_pMapOverview->AllowConCommandsWhileAlive() )
+ {
+ C_BasePlayer *localPlayer = CBasePlayer::GetLocalPlayer();
+ if( localPlayer && CBasePlayer::GetLocalPlayer()->IsAlive() )
+ return;// Not allowed to execute commands while alive
+ else if( localPlayer && localPlayer->GetObserverMode() == OBS_MODE_DEATHCAM )
+ return;// In the death cam spiral counts as alive
+ }
+
+ g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( g_pMapOverview->GetAsPanel(), "zoom", zoom, 0.0, time, vgui::AnimationController::INTERPOLATOR_LINEAR );
+}
+
+CON_COMMAND( overview_mode, "Sets overview map mode off,small,large: <0|1|2>" )
+{
+ if ( !g_pMapOverview )
+ return;
+
+ int mode;
+
+ if ( args.ArgC() < 2 )
+ {
+ // toggle modes
+ mode = g_pMapOverview->GetMode() + 1;
+
+ if ( mode > CMapOverview::MAP_MODE_FULL )
+ mode = CMapOverview::MAP_MODE_OFF;
+ }
+ else
+ {
+ // set specific mode
+ mode = Q_atoi( args[ 1 ] );
+ }
+
+ if( mode != CMapOverview::MAP_MODE_RADAR )
+ g_pMapOverview->SetPlayerPreferredMode( mode );
+
+ if( !g_pMapOverview->AllowConCommandsWhileAlive() )
+ {
+ C_BasePlayer *localPlayer = CBasePlayer::GetLocalPlayer();
+ if( localPlayer && CBasePlayer::GetLocalPlayer()->IsAlive() )
+ return;// Not allowed to execute commands while alive
+ else if( localPlayer && localPlayer->GetObserverMode() == OBS_MODE_DEATHCAM )
+ return;// In the death cam spiral counts as alive
+ }
+
+ g_pMapOverview->SetMode( mode );
+}
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+
+using namespace vgui;
+
+CMapOverview::CMapOverview( const char *pElementName ) : BaseClass( NULL, pElementName ), CHudElement( pElementName )
+{
+ SetParent( g_pClientMode->GetViewport()->GetVPanel() );
+
+ SetBounds( 0,0, 256, 256 );
+ SetBgColor( Color( 0,0,0,100 ) );
+ SetPaintBackgroundEnabled( true );
+ ShowPanel( false );
+
+ // Make sure we actually have the font...
+ vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
+
+ m_hIconFont = pScheme->GetFont( "DefaultSmall" );
+
+ m_nMapTextureID = -1;
+ m_MapKeyValues = NULL;
+
+ m_MapOrigin = Vector( 0, 0, 0 );
+ m_fMapScale = 1.0f;
+ m_bFollowAngle = false;
+ SetMode( MAP_MODE_OFF );
+
+ m_fZoom = 3.0f;
+ m_MapCenter = Vector2D( 512, 512 );
+ m_ViewOrigin = Vector2D( 512, 512 );
+ m_fViewAngle = 0;
+ m_fTrailUpdateInterval = 1.0f;
+
+ m_bShowNames = true;
+ m_bShowHealth = true;
+ m_bShowTrails = true;
+
+ m_flChangeSpeed = 1000;
+ m_flIconSize = 64.0f;
+
+ m_ObjectCounterID = 1;
+
+ Reset();
+
+ Q_memset( m_Players, 0, sizeof(m_Players) );
+
+ InitTeamColorsAndIcons();
+
+ g_pMapOverview = this; // for cvars access etc
+}
+
+void CMapOverview::Init( void )
+{
+ // register for events as client listener
+ ListenForGameEvent( "game_newmap" );
+ ListenForGameEvent( "round_start" );
+ ListenForGameEvent( "player_connect" );
+ ListenForGameEvent( "player_info" );
+ ListenForGameEvent( "player_team" );
+ ListenForGameEvent( "player_spawn" );
+ ListenForGameEvent( "player_death" );
+ ListenForGameEvent( "player_disconnect" );
+}
+
+void CMapOverview::InitTeamColorsAndIcons()
+{
+ Q_memset( m_TeamIcons, 0, sizeof(m_TeamIcons) );
+ Q_memset( m_TeamColors, 0, sizeof(m_TeamColors) );
+ Q_memset( m_ObjectIcons, 0, sizeof(m_ObjectIcons) );
+
+ m_TextureIDs.RemoveAll();
+}
+
+int CMapOverview::AddIconTexture(const char *filename)
+{
+ int index = m_TextureIDs.Find( filename );
+
+ if ( m_TextureIDs.IsValidIndex( index ) )
+ {
+ // already known, return texture ID
+ return m_TextureIDs.Element(index);
+ }
+
+ index = surface()->CreateNewTextureID();
+ surface()->DrawSetTextureFile( index , filename, true, false);
+
+ m_TextureIDs.Insert( filename, index );
+
+ return index;
+}
+
+void CMapOverview::ApplySchemeSettings(vgui::IScheme *scheme)
+{
+ BaseClass::ApplySchemeSettings( scheme );
+
+ SetBgColor( Color( 0,0,0,100 ) );
+ SetPaintBackgroundEnabled( true );
+}
+
+CMapOverview::~CMapOverview()
+{
+ if ( m_MapKeyValues )
+ m_MapKeyValues->deleteThis();
+
+ g_pMapOverview = NULL;
+
+ //TODO release Textures ? clear lists
+}
+
+void CMapOverview::UpdatePlayers()
+{
+ if ( !g_PR )
+ return;
+
+ // first disable all players health
+ for ( int i=0; i<MAX_PLAYERS; i++ )
+ {
+ m_Players[i].health = 0;
+ m_Players[i].team = TEAM_SPECTATOR;
+ }
+
+ for ( int i = 1; i<= gpGlobals->maxClients; i++)
+ {
+ // update from global player resources
+ if ( g_PR && g_PR->IsConnected(i) )
+ {
+ MapPlayer_t *player = &m_Players[i-1];
+
+ player->health = g_PR->GetHealth( i );
+
+ if ( !g_PR->IsAlive( i ) )
+ {
+ player->health = 0;
+ }
+
+ if ( player->team != g_PR->GetTeam( i ) )
+ {
+ player->team = g_PR->GetTeam( i );
+ player->icon = m_TeamIcons[ GetIconNumberFromTeamNumber(player->team) ];
+ player->color = m_TeamColors[ GetIconNumberFromTeamNumber(player->team) ];
+ }
+ }
+
+ C_BasePlayer *pPlayer = UTIL_PlayerByIndex( i );
+
+ if ( !pPlayer )
+ continue;
+
+ // don't update if player is dormant
+ if ( pPlayer->IsDormant() )
+ continue;
+
+ // update position of active players in our PVS
+ Vector position = pPlayer->EyePosition();
+ QAngle angles = pPlayer->EyeAngles();
+
+ SetPlayerPositions( i-1, position, angles );
+ }
+}
+
+void CMapOverview::UpdatePlayerTrails()
+{
+ if ( m_fNextTrailUpdate > m_fWorldTime )
+ return;
+
+ m_fNextTrailUpdate = m_fWorldTime + 1.0f; // update once a second
+
+ for (int i=0; i<MAX_PLAYERS; i++)
+ {
+ MapPlayer_t *p = &m_Players[i];
+
+ // no trails for spectators or dead players
+ if ( (p->team <= TEAM_SPECTATOR) || (p->health <= 0) )
+ {
+ continue;
+ }
+
+ // move old trail points
+ for ( int j=MAX_TRAIL_LENGTH-1; j>0; j--)
+ {
+ p->trail[j]=p->trail[j-1];
+ }
+
+ p->trail[0] = WorldToMap ( p->position );
+ }
+}
+
+void CMapOverview::UpdateFollowEntity()
+{
+ if ( m_nFollowEntity != 0 )
+ {
+ C_BaseEntity *ent = ClientEntityList().GetEnt( m_nFollowEntity );
+
+ if ( ent )
+ {
+ Vector position = MainViewOrigin(); // Use MainViewOrigin so SourceTV works in 3rd person
+ QAngle angle = ent->EyeAngles();
+
+ if ( m_nFollowEntity <= MAX_PLAYERS )
+ {
+ SetPlayerPositions( m_nFollowEntity-1, position, angle );
+ }
+
+ SetCenter( WorldToMap(position) );
+ SetAngle( angle[YAW] );
+ }
+ }
+ else
+ {
+ SetCenter( Vector2D(OVERVIEW_MAP_SIZE/2,OVERVIEW_MAP_SIZE/2) );
+ SetAngle( 0 );
+ }
+}
+
+void CMapOverview::Paint()
+{
+ UpdateSizeAndPosition();
+
+ UpdateFollowEntity();
+
+ UpdateObjects();
+
+ UpdatePlayers();
+
+ UpdatePlayerTrails();
+
+ DrawMapTexture();
+
+ DrawMapPlayerTrails();
+
+ DrawObjects();
+
+ DrawMapPlayers();
+
+ DrawCamera();
+
+ BaseClass::Paint();
+}
+
+bool CMapOverview::CanPlayerBeSeen(MapPlayer_t *player)
+{
+ C_BasePlayer *localPlayer = C_BasePlayer::GetLocalPlayer();
+
+ if ( !localPlayer || !player )
+ return false;
+
+ // don't draw ourself
+ if ( localPlayer->GetUserID() == (player->userid) )
+ return false;
+
+ // Invalid guy.
+ if( player->position == Vector(0,0,0) )
+ return false;
+
+ // if local player is on spectator team, he can see everyone
+ if ( localPlayer->GetTeamNumber() <= TEAM_SPECTATOR )
+ return true;
+
+ // we never track unassigned or real spectators
+ if ( player->team <= TEAM_SPECTATOR )
+ return false;
+
+ // if observer is an active player, check mp_forcecamera:
+
+ if ( mp_forcecamera.GetInt() == OBS_ALLOW_NONE )
+ return false;
+
+ if ( mp_forcecamera.GetInt() == OBS_ALLOW_TEAM )
+ {
+ // true if both players are on the same team
+ return (localPlayer->GetTeamNumber() == player->team );
+ }
+
+ // by default we can see all players
+ return true;
+}
+
+/// allows mods to restrict health
+/// Note: index is 0-based
+bool CMapOverview::CanPlayerHealthBeSeen(MapPlayer_t *player)
+{
+ C_BasePlayer *localPlayer = C_BasePlayer::GetLocalPlayer();
+
+ if ( !localPlayer )
+ return false;
+
+ // real spectators can see everything
+ if ( localPlayer->GetTeamNumber() <= TEAM_SPECTATOR )
+ return true;
+
+ if ( mp_forcecamera.GetInt() != OBS_ALLOW_ALL )
+ {
+ // if forcecamera is on, only show health for teammates
+ return ( localPlayer->GetTeamNumber() == player->team );
+ }
+
+ return true;
+}
+
+// usually name rule is same as health rule
+bool CMapOverview::CanPlayerNameBeSeen(MapPlayer_t *player)
+{
+ return CanPlayerHealthBeSeen( player );
+}
+
+void CMapOverview::SetPlayerPositions(int index, const Vector &position, const QAngle &angle)
+{
+ MapPlayer_t *p = &m_Players[index];
+
+ p->angle = angle;
+ p->position = position;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: shows/hides the buy menu
+//-----------------------------------------------------------------------------
+void CMapOverview::ShowPanel(bool bShow)
+{
+ SetVisible( bShow );
+}
+
+void CMapOverview::OnThink( void )
+{
+ if ( NeedsUpdate() )
+ {
+ Update();
+ m_fNextUpdateTime = gpGlobals->curtime + 0.2f; // update 5 times a second
+ }
+}
+
+bool CMapOverview::NeedsUpdate( void )
+{
+ return m_fNextUpdateTime < gpGlobals->curtime;
+}
+
+void CMapOverview::Update( void )
+{
+ // update settings
+ m_bShowNames = overview_names.GetBool() && ( GetMode() != MAP_MODE_RADAR );
+ m_bShowHealth = overview_health.GetBool() && ( GetMode() != MAP_MODE_RADAR );
+ m_bFollowAngle = ( GetMode() != MAP_MODE_RADAR && !overview_locked.GetBool() ) || ( GetMode() == MAP_MODE_RADAR && !IsRadarLocked() );
+ m_fTrailUpdateInterval = overview_tracks.GetInt() && ( GetMode() != MAP_MODE_RADAR );
+
+ m_fWorldTime = gpGlobals->curtime;
+
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+
+ if ( !pPlayer )
+ return;
+
+ int specmode = GetSpectatorMode();
+
+ if ( specmode == OBS_MODE_IN_EYE || specmode == OBS_MODE_CHASE )
+ {
+ // follow target
+ SetFollowEntity( GetSpectatorTarget() );
+ }
+ else
+ {
+ // follow ourself otherwise
+ SetFollowEntity( pPlayer->entindex() );
+ }
+}
+
+void CMapOverview::Reset( void )
+{
+ m_fNextUpdateTime = 0;
+}
+
+void CMapOverview::SetData(KeyValues *data)
+{
+ m_fZoom = data->GetFloat( "zoom", m_fZoom );
+ m_nFollowEntity = data->GetInt( "entity", m_nFollowEntity );
+}
+
+
+CMapOverview::MapPlayer_t* CMapOverview::GetPlayerByUserID( int userID )
+{
+ for (int i=0; i<MAX_PLAYERS; i++)
+ {
+ MapPlayer_t *player = &m_Players[i];
+
+ if ( player->userid == userID )
+ return player;
+ }
+
+ return NULL;
+}
+
+bool CMapOverview::IsInPanel(Vector2D &pos)
+{
+ int x,y,w,t;
+
+ GetBounds( x,y,w,t );
+
+ return ( pos.x >= 0 && pos.x < w && pos.y >= 0 && pos.y < t );
+}
+
+void CMapOverview::DrawMapTexture()
+{
+ // now draw a box around the outside of this panel
+ int x0, y0, x1, y1;
+ int wide, tall;
+
+ GetSize(wide, tall);
+ x0 = 0; y0 = 0; x1 = wide - 2; y1 = tall - 2 ;
+
+ if ( m_nMapTextureID < 0 )
+ return;
+
+ Vertex_t points[4] =
+ {
+ Vertex_t( MapToPanel ( Vector2D(0,0) ), Vector2D(0,0) ),
+ Vertex_t( MapToPanel ( Vector2D(OVERVIEW_MAP_SIZE-1,0) ), Vector2D(1,0) ),
+ Vertex_t( MapToPanel ( Vector2D(OVERVIEW_MAP_SIZE-1,OVERVIEW_MAP_SIZE-1) ), Vector2D(1,1) ),
+ Vertex_t( MapToPanel ( Vector2D(0,OVERVIEW_MAP_SIZE-1) ), Vector2D(0,1) )
+ };
+
+ int alpha = 255.0f * overview_alpha.GetFloat(); clamp( alpha, 1, 255 );
+
+ surface()->DrawSetColor( 255,255,255, alpha );
+ surface()->DrawSetTexture( m_nMapTextureID );
+ surface()->DrawTexturedPolygon( 4, points );
+}
+
+void CMapOverview::DrawMapPlayerTrails()
+{
+ if ( m_fTrailUpdateInterval <= 0 )
+ return; // turned off
+
+ for (int i=0; i<MAX_PLAYERS; i++)
+ {
+ MapPlayer_t *player = &m_Players[i];
+
+ if ( !CanPlayerBeSeen(player) )
+ continue;
+
+ player->trail[0] = WorldToMap ( player->position );
+
+ for ( int i=0; i<(MAX_TRAIL_LENGTH-1); i++)
+ {
+ if ( player->trail[i+1].x == 0 && player->trail[i+1].y == 0 )
+ break;
+
+ Vector2D pos1 = MapToPanel( player->trail[i] );
+ Vector2D pos2 = MapToPanel( player->trail[i+1] );
+
+ int intensity = 255 - float(255.0f * i) / MAX_TRAIL_LENGTH;
+
+ Vector2D dist = pos1 - pos2;
+
+ // don't draw too long lines, player probably teleported
+ if ( dist.LengthSqr() < (128*128) )
+ {
+ surface()->DrawSetColor( player->color[0], player->color[1], player->color[2], intensity );
+ surface()->DrawLine( pos1.x, pos1.y, pos2.x, pos2.y );
+ }
+ }
+ }
+}
+
+void CMapOverview::DrawObjects( )
+{
+ surface()->DrawSetTextFont( m_hIconFont );
+
+ for (int i=0; i<m_Objects.Count(); i++)
+ {
+ MapObject_t *obj = &m_Objects[i];
+
+ const char *text = NULL;
+
+ if ( Q_strlen(obj->name) > 0 )
+ text = obj->name;
+
+ float flAngle = obj->angle[YAW];
+
+ if ( obj->flags & MAP_OBJECT_ALIGN_TO_MAP && m_bRotateMap )
+ {
+ if ( m_bRotateMap )
+ flAngle = 90;
+ else
+ flAngle = 0;
+ }
+
+ MapObject_t tempObj = *obj;
+ tempObj.angle[YAW] = flAngle;
+ tempObj.text = text;
+ tempObj.statusColor = obj->color;
+
+ // draw icon
+ if ( !DrawIcon( &tempObj ) )
+ continue;
+ }
+}
+
+bool CMapOverview::DrawIcon( MapObject_t *obj )
+{
+ int textureID = obj->icon;
+ Vector pos = obj->position;
+ float scale = obj->size;
+ float angle = obj->angle[YAW];
+ const char *text = obj->text;
+ Color *textColor = &obj->color;
+ float status = obj->status;
+ Color *statusColor = &obj->statusColor;
+
+ Vector offset; offset.z = 0;
+
+ Vector2D pospanel = WorldToMap( pos );
+ pospanel = MapToPanel( pospanel );
+
+ if ( !IsInPanel( pospanel ) )
+ return false; // player is not within overview panel
+
+ offset.x = -scale; offset.y = scale;
+ VectorYawRotate( offset, angle, offset );
+ Vector2D pos1 = WorldToMap( pos + offset );
+
+ offset.x = scale; offset.y = scale;
+ VectorYawRotate( offset, angle, offset );
+ Vector2D pos2 = WorldToMap( pos + offset );
+
+ offset.x = scale; offset.y = -scale;
+ VectorYawRotate( offset, angle, offset );
+ Vector2D pos3 = WorldToMap( pos + offset );
+
+ offset.x = -scale; offset.y = -scale;
+ VectorYawRotate( offset, angle, offset );
+ Vector2D pos4 = WorldToMap( pos + offset );
+
+ Vertex_t points[4] =
+ {
+ Vertex_t( MapToPanel ( pos1 ), Vector2D(0,0) ),
+ Vertex_t( MapToPanel ( pos2 ), Vector2D(1,0) ),
+ Vertex_t( MapToPanel ( pos3 ), Vector2D(1,1) ),
+ Vertex_t( MapToPanel ( pos4 ), Vector2D(0,1) )
+ };
+
+ surface()->DrawSetColor( 255, 255, 255, 255 );
+ surface()->DrawSetTexture( textureID );
+ surface()->DrawTexturedPolygon( 4, points );
+
+ int d = GetPixelOffset( scale);
+
+ pospanel.y += d + 4;
+
+ if ( status >=0.0f && status <= 1.0f && statusColor )
+ {
+ // health bar is 50x3 pixels
+ surface()->DrawSetColor( 0,0,0,255 );
+ surface()->DrawFilledRect( pospanel.x-d, pospanel.y-1, pospanel.x+d, pospanel.y+1 );
+
+ int length = (float)(d*2)*status;
+ surface()->DrawSetColor( statusColor->r(), statusColor->g(), statusColor->b(), 255 );
+ surface()->DrawFilledRect( pospanel.x-d, pospanel.y-1, pospanel.x-d+length, pospanel.y+1 );
+
+ pospanel.y += 3;
+ }
+
+ if ( text && textColor )
+ {
+ wchar_t iconText[ MAX_PLAYER_NAME_LENGTH*2 ];
+
+ g_pVGuiLocalize->ConvertANSIToUnicode( text, iconText, sizeof( iconText ) );
+
+ int wide, tall;
+ surface()->GetTextSize( m_hIconFont, iconText, wide, tall );
+
+ int x = pospanel.x-(wide/2);
+ int y = pospanel.y;
+
+ // draw black shadow text
+ surface()->DrawSetTextColor( 0, 0, 0, 255 );
+ surface()->DrawSetTextPos( x+1, y );
+ surface()->DrawPrintText( iconText, wcslen(iconText) );
+
+ // draw name in color
+ surface()->DrawSetTextColor( textColor->r(), textColor->g(), textColor->b(), 255 );
+ surface()->DrawSetTextPos( x, y );
+ surface()->DrawPrintText( iconText, wcslen(iconText) );
+ }
+
+ return true;
+}
+
+int CMapOverview::GetPixelOffset( float height )
+{
+ Vector2D pos2 = WorldToMap( Vector( height,0,0) );
+ pos2 = MapToPanel( pos2 );
+
+ Vector2D pos3 = WorldToMap( Vector(0,0,0) );
+ pos3 = MapToPanel( pos3 );
+
+ int a = pos2.y-pos3.y;
+ int b = pos2.x-pos3.x;
+
+ return (int)sqrt((float)(a*a+b*b)); // number of panel pixels for "scale" units in world
+}
+
+void CMapOverview::DrawMapPlayers()
+{
+ surface()->DrawSetTextFont( m_hIconFont );
+
+ Color colorGreen( 0, 255, 0, 255 ); // health bar color
+
+ for (int i=0; i<MAX_PLAYERS; i++)
+ {
+ MapPlayer_t *player = &m_Players[i];
+
+ if ( !CanPlayerBeSeen( player ) )
+ continue;
+
+ // don't draw dead players / spectators
+ if ( player->health <= 0 )
+ continue;
+
+ float status = -1;
+ const char *name = NULL;
+
+ if ( m_bShowNames && CanPlayerNameBeSeen( player ) )
+ name = player->name;
+
+ if ( m_bShowHealth && CanPlayerHealthBeSeen( player ) )
+ status = player->health/100.0f;
+
+ // convert from PlayerObject_t
+ MapObject_t tempObj;
+ memset( &tempObj, 0, sizeof(MapObject_t) );
+ tempObj.icon = player->icon;
+ tempObj.position = player->position;
+ tempObj.size = m_flIconSize;
+ tempObj.angle = player->angle;
+ tempObj.text = name;
+ tempObj.color = player->color;
+ tempObj.status = status;
+ tempObj.statusColor = colorGreen;
+
+ DrawIcon( &tempObj );
+ }
+}
+
+Vector2D CMapOverview::WorldToMap( const Vector &worldpos )
+{
+ Vector2D offset( worldpos.x - m_MapOrigin.x, worldpos.y - m_MapOrigin.y);
+
+ offset.x /= m_fMapScale;
+ offset.y /= -m_fMapScale;
+
+ return offset;
+}
+
+float CMapOverview::GetViewAngle( void )
+{
+ float viewAngle = m_fViewAngle - 90.0f;
+
+ if ( !m_bFollowAngle )
+ {
+ // We don't use fViewAngle. We just show straight at all times.
+ if ( m_bRotateMap )
+ viewAngle = 90.0f;
+ else
+ viewAngle = 0.0f;
+ }
+
+ return viewAngle;
+}
+
+Vector2D CMapOverview::MapToPanel( const Vector2D &mappos )
+{
+ int pwidth, pheight;
+ Vector2D panelpos;
+ float viewAngle = GetViewAngle();
+
+ GetSize(pwidth, pheight);
+
+ Vector offset;
+ offset.x = mappos.x - m_MapCenter.x;
+ offset.y = mappos.y - m_MapCenter.y;
+ offset.z = 0;
+
+ VectorYawRotate( offset, viewAngle, offset );
+
+ // find the actual zoom from the animationvar m_fZoom and the map zoom scale
+ float fScale = (m_fZoom * m_fFullZoom) / OVERVIEW_MAP_SIZE;
+
+ offset.x *= fScale;
+ offset.y *= fScale;
+
+ panelpos.x = (pwidth * 0.5f) + (pheight * offset.x);
+ panelpos.y = (pheight * 0.5f) + (pheight * offset.y);
+
+ return panelpos;
+}
+
+void CMapOverview::SetTime( float time )
+{
+ m_fWorldTime = time;
+}
+
+void CMapOverview::SetMap(const char * levelname)
+{
+ // Reset players and objects, even if the map is the same as the previous one
+ m_Objects.RemoveAll();
+
+ m_fNextTrailUpdate = 0;// Set to 0 for immediate update. Our WorldTime var hasn't been updated to 0 for the new map yet
+ m_fWorldTime = 0;// In release, we occasionally race and get this bug again if we gt a paint before an update. Reset this before the old value gets in to the timer.
+ // Please note, UpdatePlayerTrails comes from PAINT, not UPDATE.
+
+ InitTeamColorsAndIcons();
+
+ // load new KeyValues
+ if ( m_MapKeyValues && Q_strcmp( levelname, m_MapKeyValues->GetName() ) == 0 )
+ {
+ return; // map didn't change
+ }
+
+ if ( m_MapKeyValues )
+ m_MapKeyValues->deleteThis();
+
+ m_MapKeyValues = new KeyValues( levelname );
+
+ char tempfile[MAX_PATH];
+ Q_snprintf( tempfile, sizeof( tempfile ), "resource/overviews/%s.txt", levelname );
+
+ if ( !m_MapKeyValues->LoadFromFile( g_pFullFileSystem, tempfile, "GAME" ) )
+ {
+ DevMsg( 1, "Error! CMapOverview::SetMap: couldn't load file %s.\n", tempfile );
+ m_nMapTextureID = -1;
+ m_MapOrigin.x = 0;
+ m_MapOrigin.y = 0;
+ m_fMapScale = 1;
+ m_bRotateMap = false;
+ m_fFullZoom = 1;
+ return;
+ }
+
+ // TODO release old texture ?
+
+ m_nMapTextureID = surface()->CreateNewTextureID();
+
+ //if we have not uploaded yet, lets go ahead and do so
+ surface()->DrawSetTextureFile( m_nMapTextureID, m_MapKeyValues->GetString("material"), true, false);
+
+ int wide, tall;
+
+ surface()->DrawGetTextureSize( m_nMapTextureID, wide, tall );
+
+ if ( wide != tall )
+ {
+ DevMsg( 1, "Error! CMapOverview::SetMap: map image must be a square.\n" );
+ m_nMapTextureID = -1;
+ return;
+ }
+
+ m_MapOrigin.x = m_MapKeyValues->GetInt("pos_x");
+ m_MapOrigin.y = m_MapKeyValues->GetInt("pos_y");
+ m_fMapScale = m_MapKeyValues->GetFloat("scale", 1.0f);
+ m_bRotateMap = m_MapKeyValues->GetInt("rotate")!=0;
+ m_fFullZoom = m_MapKeyValues->GetFloat("zoom", 1.0f );
+}
+
+void CMapOverview::ResetRound()
+{
+ for (int i=0; i<MAX_PLAYERS; i++)
+ {
+ MapPlayer_t *p = &m_Players[i];
+
+ if ( p->team > TEAM_SPECTATOR )
+ {
+ p->health = 100;
+ }
+
+ Q_memset( p->trail, 0, sizeof(p->trail) );
+
+ p->position = Vector( 0, 0, 0 );
+ }
+
+ m_Objects.RemoveAll();
+}
+
+void CMapOverview::OnMousePressed( MouseCode code )
+{
+
+}
+
+void CMapOverview::DrawCamera()
+{
+ // draw a red center point
+ surface()->DrawSetColor( 255,0,0,255 );
+ Vector2D center = MapToPanel( m_ViewOrigin );
+ surface()->DrawFilledRect( center.x-2, center.y-2, center.x+2, center.y+2);
+}
+
+void CMapOverview::FireGameEvent( IGameEvent *event )
+{
+ const char * type = event->GetName();
+
+ if ( Q_strcmp(type, "game_newmap") == 0 )
+ {
+ SetMap( event->GetString("mapname") );
+ ResetRound();
+ }
+
+ else if ( Q_strcmp(type, "round_start") == 0 )
+ {
+ ResetRound();
+ }
+
+ else if ( Q_strcmp(type,"player_connect") == 0 )
+ {
+ int index = event->GetInt("index"); // = entity index - 1
+
+ if ( index < 0 || index >= MAX_PLAYERS )
+ return;
+
+ MapPlayer_t *player = &m_Players[index];
+
+ player->index = index;
+ player->userid = event->GetInt("userid");
+ Q_strncpy( player->name, event->GetString("name","unknown"), sizeof(player->name) );
+
+ // Reset settings
+ Q_memset( player->trail, 0, sizeof(player->trail) );
+ player->team = TEAM_UNASSIGNED;
+ player->health = 0;
+ }
+
+ else if ( Q_strcmp(type,"player_info") == 0 )
+ {
+ int index = event->GetInt("index"); // = entity index - 1
+
+ if ( index < 0 || index >= MAX_PLAYERS )
+ return;
+
+ MapPlayer_t *player = &m_Players[index];
+
+ player->index = index;
+ player->userid = event->GetInt("userid");
+ Q_strncpy( player->name, event->GetString("name","unknown"), sizeof(player->name) );
+ }
+
+ else if ( Q_strcmp(type,"player_team") == 0 )
+ {
+ MapPlayer_t *player = GetPlayerByUserID( event->GetInt("userid") );
+
+ if ( !player )
+ return;
+
+ player->team = event->GetInt("team");
+ player->icon = m_TeamIcons[ GetIconNumberFromTeamNumber(player->team) ];
+ player->color = m_TeamColors[ GetIconNumberFromTeamNumber(player->team) ];
+ }
+
+ else if ( Q_strcmp(type,"player_death") == 0 )
+ {
+ MapPlayer_t *player = GetPlayerByUserID( event->GetInt("userid") );
+
+ if ( !player )
+ return;
+
+ player->health = 0;
+ Q_memset( player->trail, 0, sizeof(player->trail) ); // clear trails
+ }
+
+ else if ( Q_strcmp(type,"player_spawn") == 0 )
+ {
+ MapPlayer_t *player = GetPlayerByUserID( event->GetInt("userid") );
+
+ if ( !player )
+ return;
+
+ player->health = 100;
+ Q_memset( player->trail, 0, sizeof(player->trail) ); // clear trails
+ }
+
+ else if ( Q_strcmp(type,"player_disconnect") == 0 )
+ {
+ MapPlayer_t *player = GetPlayerByUserID( event->GetInt("userid") );
+
+ if ( !player )
+ return;
+
+ Q_memset( player, 0, sizeof(MapPlayer_t) ); // clear player field
+ }
+}
+
+void CMapOverview::SetMode(int mode)
+{
+ m_flChangeSpeed = 0; // change size instantly
+
+ if ( mode == MAP_MODE_OFF )
+ {
+ ShowPanel( false );
+
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapOff" );
+ }
+ else if ( mode == MAP_MODE_INSET )
+ {
+ if( m_nMapTextureID == -1 )
+ {
+ SetMode( MAP_MODE_OFF );
+ return;
+ }
+
+ if ( m_nMode != MAP_MODE_OFF )
+ m_flChangeSpeed = 1000; // zoom effect
+
+ C_BasePlayer *pPlayer = CBasePlayer::GetLocalPlayer();
+
+ if ( pPlayer )
+ SetFollowEntity( pPlayer->entindex() );
+
+ ShowPanel( true );
+
+ if ( mode != m_nMode && RunHudAnimations() )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapZoomToSmall" );
+ }
+ }
+ else if ( mode == MAP_MODE_FULL )
+ {
+ if( m_nMapTextureID == -1 )
+ {
+ SetMode( MAP_MODE_OFF );
+ return;
+ }
+
+ if ( m_nMode != MAP_MODE_OFF )
+ m_flChangeSpeed = 1000; // zoom effect
+
+ SetFollowEntity( 0 );
+
+ ShowPanel( true );
+
+ if ( mode != m_nMode && RunHudAnimations() )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MapZoomToLarge" );
+ }
+ }
+
+ // finally set mode
+ m_nMode = mode;
+
+ UpdateSizeAndPosition();
+}
+
+bool CMapOverview::ShouldDraw( void )
+{
+ return ( m_nMode != MAP_MODE_OFF ) && CHudElement::ShouldDraw();
+}
+
+void CMapOverview::UpdateSizeAndPosition()
+{
+ if ( g_pSpectatorGUI && g_pSpectatorGUI->IsVisible() )
+ {
+ int iScreenWide, iScreenTall;
+ GetHudSize( iScreenWide, iScreenTall );
+
+ int iTopBarHeight = g_pSpectatorGUI->GetTopBarHeight();
+ int iBottomBarHeight = g_pSpectatorGUI->GetBottomBarHeight();
+
+ iScreenTall -= ( iTopBarHeight + iBottomBarHeight );
+
+ int x,y,w,h;
+ GetBounds( x,y,w,h );
+
+ if ( y < iTopBarHeight )
+ y = iTopBarHeight;
+
+ SetBounds( x,y,w,MIN(h,iScreenTall) );
+ }
+}
+
+void CMapOverview::SetCenter(const Vector2D &mappos)
+{
+ int width, height;
+
+ GetSize( width, height);
+
+ m_ViewOrigin = mappos;
+ m_MapCenter = mappos;
+
+ float fTwiceZoom = m_fZoom * m_fFullZoom * 2;
+
+ width = height = OVERVIEW_MAP_SIZE / (fTwiceZoom);
+
+ if( GetMode() != MAP_MODE_RADAR )
+ {
+ if ( m_MapCenter.x < width )
+ m_MapCenter.x = width;
+
+ if ( m_MapCenter.x > (OVERVIEW_MAP_SIZE-width) )
+ m_MapCenter.x = (OVERVIEW_MAP_SIZE-width);
+
+ if ( m_MapCenter.y < height )
+ m_MapCenter.y = height;
+
+ if ( m_MapCenter.y > (OVERVIEW_MAP_SIZE-height) )
+ m_MapCenter.y = (OVERVIEW_MAP_SIZE-height);
+
+ //center if in full map mode
+ if ( m_fZoom <= 1.0 )
+ {
+ m_MapCenter.x = OVERVIEW_MAP_SIZE/2;
+ m_MapCenter.y = OVERVIEW_MAP_SIZE/2;
+ }
+ }
+
+}
+
+void CMapOverview::SetFollowAngle(bool state)
+{
+ m_bFollowAngle = state;
+}
+
+void CMapOverview::SetFollowEntity(int entindex)
+{
+ m_nFollowEntity = entindex;
+}
+
+float CMapOverview::GetZoom( void )
+{
+ return m_fZoom;
+}
+
+int CMapOverview::GetMode( void )
+{
+ return m_nMode;
+}
+
+void CMapOverview::SetAngle(float angle)
+{
+ m_fViewAngle = angle;
+}
+
+void CMapOverview::ShowPlayerNames(bool state)
+{
+ m_bShowNames = state;
+}
+
+
+void CMapOverview::ShowPlayerHealth(bool state)
+{
+ m_bShowHealth = state;
+}
+
+void CMapOverview::ShowPlayerTracks(float seconds)
+{
+ m_fTrailUpdateInterval = seconds;
+}
+
+bool CMapOverview::SetTeamColor(int team, Color color)
+{
+ if ( team < 0 || team>= MAX_TEAMS )
+ return false;
+
+ m_TeamColors[team] = color;
+
+ return true;
+}
+
+CMapOverview::MapObject_t* CMapOverview::FindObjectByID(int objectID)
+{
+ for ( int i = 0; i < m_Objects.Count(); i++ )
+ {
+ if ( m_Objects[i].objectID == objectID )
+ return &m_Objects[i];
+ }
+
+ return NULL;
+}
+
+int CMapOverview::AddObject( const char *icon, int entity, float timeToLive )
+{
+ MapObject_t obj; Q_memset( &obj, 0, sizeof(obj) );
+
+ obj.objectID = m_ObjectCounterID++;
+ obj.index = entity;
+ obj.icon = AddIconTexture( icon );
+ obj.size = m_flIconSize;
+ obj.status = -1;
+
+ if ( timeToLive > 0 )
+ obj.endtime = gpGlobals->curtime + timeToLive;
+ else
+ obj.endtime = -1;
+
+ m_Objects.AddToTail( obj );
+
+ return obj.objectID;
+}
+
+void CMapOverview::SetObjectText( int objectID, const char *text, Color color )
+{
+ MapObject_t* obj = FindObjectByID( objectID );
+
+ if ( !obj )
+ return;
+
+ if ( text )
+ {
+ Q_strncpy( obj->name, text, sizeof(obj->name) );
+ }
+ else
+ {
+ Q_memset( obj->name, 0, sizeof(obj->name) );
+ }
+
+ obj->color = color;
+}
+
+void CMapOverview::SetObjectStatus( int objectID, float status, Color color )
+{
+ MapObject_t* obj = FindObjectByID( objectID );
+
+ if ( !obj )
+ return;
+
+ obj->status = status;
+ obj->statusColor = color;
+}
+
+void CMapOverview::SetObjectIcon( int objectID, const char *icon, float size )
+{
+ MapObject_t* obj = FindObjectByID( objectID );
+
+ if ( !obj )
+ return;
+
+ obj->icon = AddIconTexture( icon );
+ obj->size = size;
+}
+
+void CMapOverview::SetObjectPosition( int objectID, const Vector &position, const QAngle &angle )
+{
+ MapObject_t* obj = FindObjectByID( objectID );
+
+ if ( !obj )
+ return;
+
+ obj->angle = angle;
+ obj->position = position;
+}
+
+void CMapOverview::AddObjectFlags( int objectID, int flags )
+{
+ MapObject_t* obj = FindObjectByID( objectID );
+
+ if ( !obj )
+ return;
+
+ obj->flags |= flags;
+}
+
+void CMapOverview::SetObjectFlags( int objectID, int flags )
+{
+ MapObject_t* obj = FindObjectByID( objectID );
+
+ if ( !obj )
+ return;
+
+ obj->flags = flags;
+}
+
+void CMapOverview::RemoveObjectByIndex( int index )
+{
+ for ( int i = 0; i < m_Objects.Count(); i++ )
+ {
+ if ( m_Objects[i].index == index )
+ {
+ m_Objects.Remove( i );
+ return;
+ }
+ }
+}
+
+void CMapOverview::RemoveObject( int objectID )
+{
+ for ( int i = 0; i < m_Objects.Count(); i++ )
+ {
+ if ( m_Objects[i].objectID == objectID )
+ {
+ m_Objects.Remove( i );
+ return;
+ }
+ }
+}
+
+void CMapOverview::UpdateObjects()
+{
+ for ( int i = 0; i < m_Objects.Count(); i++ )
+ {
+ MapObject_t *obj = &m_Objects[i];
+
+ if ( obj->endtime > 0 && obj->endtime < gpGlobals->curtime )
+ {
+ m_Objects.Remove( i );
+ i--;
+ continue;
+ }
+
+ if ( obj->index <= 0 )
+ continue;
+
+ C_BaseEntity *entity = ClientEntityList().GetEnt( obj->index );
+
+ if ( !entity )
+ continue;
+
+ obj->position = entity->GetAbsOrigin();
+ obj->angle = entity->GetAbsAngles();
+ }
} \ No newline at end of file
diff --git a/mp/src/game/client/game_controls/NavProgress.cpp b/mp/src/game/client/game_controls/NavProgress.cpp
index 7b7e9767..8aef8c4e 100644
--- a/mp/src/game/client/game_controls/NavProgress.cpp
+++ b/mp/src/game/client/game_controls/NavProgress.cpp
@@ -1,137 +1,137 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include "NavProgress.h"
-
-#include <vgui/IScheme.h>
-#include <vgui/ILocalize.h>
-#include <vgui/ISurface.h>
-#include <filesystem.h>
-#include <KeyValues.h>
-#include <convar.h>
-
-#include <vgui_controls/Label.h>
-
-#include <game/client/iviewport.h>
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-using namespace vgui;
-
-//--------------------------------------------------------------------------------------------------------------
-CNavProgress::CNavProgress( IViewPort *pViewPort ) : Frame( NULL, PANEL_NAV_PROGRESS )
-{
- // initialize dialog
- m_pViewPort = pViewPort;
-
- // load the new scheme early!!
- SetScheme("ClientScheme");
- SetMoveable(false);
- SetSizeable(false);
- SetProportional(true);
-
- // hide the system buttons
- SetTitleBarVisible( false );
-
- m_pTitle = new Label( this, "TitleLabel", "" );
- m_pText = new Label( this, "TextLabel", "" );
-
- m_pProgressBarBorder = new Panel( this, "ProgressBarBorder" );
- m_pProgressBar = new Panel( this, "ProgressBar" );
- m_pProgressBarSizer = new Panel( this, "ProgressBarSizer" );
-
- LoadControlSettings("Resource/UI/NavProgress.res");
-
- Reset();
-}
-
-//--------------------------------------------------------------------------------------------------------------
-CNavProgress::~CNavProgress()
-{
-}
-
-//--------------------------------------------------------------------------------------------------------------
-void CNavProgress::ApplySchemeSettings(IScheme *pScheme)
-{
- BaseClass::ApplySchemeSettings( pScheme );
-
- SetPaintBackgroundType( 2 );
-
- m_pProgressBarSizer->SetVisible( false );
-
- m_pProgressBarBorder->SetBorder( pScheme->GetBorder( "ButtonDepressedBorder" ) );
- m_pProgressBarBorder->SetBgColor( Color( 0, 0, 0, 0 ) );
-
- m_pProgressBar->SetBorder( pScheme->GetBorder( "ButtonBorder" ) );
- m_pProgressBar->SetBgColor( pScheme->GetColor( "ProgressBar.FgColor", Color( 0, 0, 0, 0 ) ) );
-}
-
-//--------------------------------------------------------------------------------------------------------------
-void CNavProgress::PerformLayout()
-{
- BaseClass::PerformLayout();
-
- if ( m_numTicks )
- {
- int w = m_pProgressBarSizer->GetWide();
- w = w * m_currentTick / m_numTicks;
- m_pProgressBar->SetWide( w );
- }
-}
-
-//--------------------------------------------------------------------------------------------------------------
-void CNavProgress::Init( const char *title, int numTicks, int startTick )
-{
- m_pText->SetText( title );
-
- m_numTicks = MAX( 1, numTicks ); // non-zero, since we'll divide by this
- m_currentTick = MAX( 0, MIN( m_numTicks, startTick ) );
-
- InvalidateLayout();
-}
-
-//--------------------------------------------------------------------------------------------------------------
-void CNavProgress::SetData(KeyValues *data)
-{
- Init( data->GetString( "msg" ),
- data->GetInt( "total" ),
- data->GetInt( "current" ) );
-}
-
-//--------------------------------------------------------------------------------------------------------------
-void CNavProgress::ShowPanel( bool bShow )
-{
- if ( BaseClass::IsVisible() == bShow )
- return;
-
- m_pViewPort->ShowBackGround( bShow );
-
- if ( bShow )
- {
- Activate();
- SetMouseInputEnabled( true );
- }
- else
- {
- SetVisible( false );
- SetMouseInputEnabled( false );
- }
-}
-
-//--------------------------------------------------------------------------------------------------------------
-void CNavProgress::Reset( void )
-{
-}
-
-//--------------------------------------------------------------------------------------------------------------
-void CNavProgress::Update( void )
-{
-}
-
-//--------------------------------------------------------------------------------------------------------------
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "NavProgress.h"
+
+#include <vgui/IScheme.h>
+#include <vgui/ILocalize.h>
+#include <vgui/ISurface.h>
+#include <filesystem.h>
+#include <KeyValues.h>
+#include <convar.h>
+
+#include <vgui_controls/Label.h>
+
+#include <game/client/iviewport.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+//--------------------------------------------------------------------------------------------------------------
+CNavProgress::CNavProgress( IViewPort *pViewPort ) : Frame( NULL, PANEL_NAV_PROGRESS )
+{
+ // initialize dialog
+ m_pViewPort = pViewPort;
+
+ // load the new scheme early!!
+ SetScheme("ClientScheme");
+ SetMoveable(false);
+ SetSizeable(false);
+ SetProportional(true);
+
+ // hide the system buttons
+ SetTitleBarVisible( false );
+
+ m_pTitle = new Label( this, "TitleLabel", "" );
+ m_pText = new Label( this, "TextLabel", "" );
+
+ m_pProgressBarBorder = new Panel( this, "ProgressBarBorder" );
+ m_pProgressBar = new Panel( this, "ProgressBar" );
+ m_pProgressBarSizer = new Panel( this, "ProgressBarSizer" );
+
+ LoadControlSettings("Resource/UI/NavProgress.res");
+
+ Reset();
+}
+
+//--------------------------------------------------------------------------------------------------------------
+CNavProgress::~CNavProgress()
+{
+}
+
+//--------------------------------------------------------------------------------------------------------------
+void CNavProgress::ApplySchemeSettings(IScheme *pScheme)
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ SetPaintBackgroundType( 2 );
+
+ m_pProgressBarSizer->SetVisible( false );
+
+ m_pProgressBarBorder->SetBorder( pScheme->GetBorder( "ButtonDepressedBorder" ) );
+ m_pProgressBarBorder->SetBgColor( Color( 0, 0, 0, 0 ) );
+
+ m_pProgressBar->SetBorder( pScheme->GetBorder( "ButtonBorder" ) );
+ m_pProgressBar->SetBgColor( pScheme->GetColor( "ProgressBar.FgColor", Color( 0, 0, 0, 0 ) ) );
+}
+
+//--------------------------------------------------------------------------------------------------------------
+void CNavProgress::PerformLayout()
+{
+ BaseClass::PerformLayout();
+
+ if ( m_numTicks )
+ {
+ int w = m_pProgressBarSizer->GetWide();
+ w = w * m_currentTick / m_numTicks;
+ m_pProgressBar->SetWide( w );
+ }
+}
+
+//--------------------------------------------------------------------------------------------------------------
+void CNavProgress::Init( const char *title, int numTicks, int startTick )
+{
+ m_pText->SetText( title );
+
+ m_numTicks = MAX( 1, numTicks ); // non-zero, since we'll divide by this
+ m_currentTick = MAX( 0, MIN( m_numTicks, startTick ) );
+
+ InvalidateLayout();
+}
+
+//--------------------------------------------------------------------------------------------------------------
+void CNavProgress::SetData(KeyValues *data)
+{
+ Init( data->GetString( "msg" ),
+ data->GetInt( "total" ),
+ data->GetInt( "current" ) );
+}
+
+//--------------------------------------------------------------------------------------------------------------
+void CNavProgress::ShowPanel( bool bShow )
+{
+ if ( BaseClass::IsVisible() == bShow )
+ return;
+
+ m_pViewPort->ShowBackGround( bShow );
+
+ if ( bShow )
+ {
+ Activate();
+ SetMouseInputEnabled( true );
+ }
+ else
+ {
+ SetVisible( false );
+ SetMouseInputEnabled( false );
+ }
+}
+
+//--------------------------------------------------------------------------------------------------------------
+void CNavProgress::Reset( void )
+{
+}
+
+//--------------------------------------------------------------------------------------------------------------
+void CNavProgress::Update( void )
+{
+}
+
+//--------------------------------------------------------------------------------------------------------------
diff --git a/mp/src/game/client/game_controls/NavProgress.h b/mp/src/game/client/game_controls/NavProgress.h
index a0723271..9cae369e 100644
--- a/mp/src/game/client/game_controls/NavProgress.h
+++ b/mp/src/game/client/game_controls/NavProgress.h
@@ -1,59 +1,59 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-
-#ifndef NAVPROGRESS_H
-#define NAVPROGRESS_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui_controls/Frame.h>
-#include <vgui_controls/ProgressBar.h>
-
-#include <game/client/iviewport.h>
-
-class CNavProgress : public vgui::Frame, public IViewPortPanel
-{
-private:
- DECLARE_CLASS_SIMPLE( CNavProgress, vgui::Frame );
-
-public:
- CNavProgress(IViewPort *pViewPort);
- virtual ~CNavProgress();
-
- virtual const char *GetName( void ) { return PANEL_NAV_PROGRESS; }
- virtual void SetData(KeyValues *data);
- virtual void Reset();
- virtual void Update();
- virtual bool NeedsUpdate( void ) { return false; }
- virtual bool HasInputElements( void ) { return true; }
- virtual void ShowPanel( bool bShow );
-
- // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
- vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
- virtual bool IsVisible() { return BaseClass::IsVisible(); }
- virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
-
-public:
-
- virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
- virtual void PerformLayout();
- void Init( const char *title, int numTicks, int currentTick );
-
-protected:
- IViewPort *m_pViewPort;
-
- int m_numTicks;
- int m_currentTick;
-
- vgui::Label * m_pTitle;
- vgui::Label * m_pText;
- vgui::Panel * m_pProgressBarBorder;
- vgui::Panel * m_pProgressBar;
- vgui::Panel * m_pProgressBarSizer;
-};
-
-#endif // NAVPROGRESS_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#ifndef NAVPROGRESS_H
+#define NAVPROGRESS_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui_controls/Frame.h>
+#include <vgui_controls/ProgressBar.h>
+
+#include <game/client/iviewport.h>
+
+class CNavProgress : public vgui::Frame, public IViewPortPanel
+{
+private:
+ DECLARE_CLASS_SIMPLE( CNavProgress, vgui::Frame );
+
+public:
+ CNavProgress(IViewPort *pViewPort);
+ virtual ~CNavProgress();
+
+ virtual const char *GetName( void ) { return PANEL_NAV_PROGRESS; }
+ virtual void SetData(KeyValues *data);
+ virtual void Reset();
+ virtual void Update();
+ virtual bool NeedsUpdate( void ) { return false; }
+ virtual bool HasInputElements( void ) { return true; }
+ virtual void ShowPanel( bool bShow );
+
+ // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
+ vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
+ virtual bool IsVisible() { return BaseClass::IsVisible(); }
+ virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
+
+public:
+
+ virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
+ virtual void PerformLayout();
+ void Init( const char *title, int numTicks, int currentTick );
+
+protected:
+ IViewPort *m_pViewPort;
+
+ int m_numTicks;
+ int m_currentTick;
+
+ vgui::Label * m_pTitle;
+ vgui::Label * m_pText;
+ vgui::Panel * m_pProgressBarBorder;
+ vgui::Panel * m_pProgressBar;
+ vgui::Panel * m_pProgressBarSizer;
+};
+
+#endif // NAVPROGRESS_H
diff --git a/mp/src/game/client/game_controls/SpectatorGUI.cpp b/mp/src/game/client/game_controls/SpectatorGUI.cpp
index a2098b0b..1c95068a 100644
--- a/mp/src/game/client/game_controls/SpectatorGUI.cpp
+++ b/mp/src/game/client/game_controls/SpectatorGUI.cpp
@@ -1,850 +1,850 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include <cdll_client_int.h>
-#include <globalvars_base.h>
-#include <cdll_util.h>
-#include <KeyValues.h>
-
-#include "spectatorgui.h"
-
-#include <vgui/IScheme.h>
-#include <vgui/ILocalize.h>
-#include <vgui/ISurface.h>
-#include <vgui/IPanel.h>
-#include <vgui_controls/ImageList.h>
-#include <vgui_controls/MenuItem.h>
-#include <vgui_controls/TextImage.h>
-
-#include <stdio.h> // _snprintf define
-
-#include <game/client/iviewport.h>
-#include "commandmenu.h"
-#include "hltvcamera.h"
-#if defined( REPLAY_ENABLED )
-#include "replay/replaycamera.h"
-#endif
-
-#include <vgui_controls/TextEntry.h>
-#include <vgui_controls/Panel.h>
-#include <vgui_controls/ImagePanel.h>
-#include <vgui_controls/Menu.h>
-#include "IGameUIFuncs.h" // for key bindings
-#include <imapoverview.h>
-#include <shareddefs.h>
-#include <igameresources.h>
-
-#ifdef TF_CLIENT_DLL
-#include "tf_gamerules.h"
-void AddSubKeyNamed( KeyValues *pKeys, const char *pszName );
-#endif
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#ifndef _XBOX
-extern IGameUIFuncs *gameuifuncs; // for key binding details
-#endif
-
-// void DuckMessage(const char *str); // from vgui_teamfortressviewport.cpp
-
-ConVar spec_scoreboard( "spec_scoreboard", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
-
-CSpectatorGUI *g_pSpectatorGUI = NULL;
-
-
-// NB disconnect between localization text and observer mode enums
-static const char *s_SpectatorModes[] =
-{
- "#Spec_Mode0", // OBS_MODE_NONE = 0,
- "#Spec_Mode1", // OBS_MODE_DEATHCAM,
- "", // OBS_MODE_FREEZECAM,
- "#Spec_Mode2", // OBS_MODE_FIXED,
- "#Spec_Mode3", // OBS_MODE_IN_EYE,
- "#Spec_Mode4", // OBS_MODE_CHASE,
- "#Spec_Mode5", // OBS_MODE_ROAMING,
-};
-
-using namespace vgui;
-
-ConVar cl_spec_mode(
- "cl_spec_mode",
- "1",
- FCVAR_ARCHIVE | FCVAR_USERINFO | FCVAR_SERVER_CAN_EXECUTE,
- "spectator mode" );
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose: left and right buttons pointing buttons
-//-----------------------------------------------------------------------------
-class CSpecButton : public Button
-{
-public:
- CSpecButton(Panel *parent, const char *panelName): Button(parent, panelName, "") {}
-
-private:
- void ApplySchemeSettings(vgui::IScheme *pScheme)
- {
- Button::ApplySchemeSettings(pScheme);
- SetFont(pScheme->GetFont("Marlett", IsProportional()) );
- }
-};
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CSpectatorMenu::CSpectatorMenu( IViewPort *pViewPort ) : Frame( NULL, PANEL_SPECMENU )
-{
- m_iDuckKey = BUTTON_CODE_INVALID;
-
- m_pViewPort = pViewPort;
-
- SetMouseInputEnabled( true );
- SetKeyBoardInputEnabled( true );
- SetTitleBarVisible( false ); // don't draw a title bar
- SetMoveable( false );
- SetSizeable( false );
- SetProportional(true);
-
- SetScheme("ClientScheme");
-
- m_pPlayerList = new ComboBox(this, "playercombo", 10 , false);
- HFont hFallbackFont = scheme()->GetIScheme( GetScheme() )->GetFont( "DefaultVerySmallFallBack", false );
- if ( INVALID_FONT != hFallbackFont )
- {
- m_pPlayerList->SetUseFallbackFont( true, hFallbackFont );
- }
-
- m_pViewOptions = new ComboBox(this, "viewcombo", 10 , false );
- m_pConfigSettings = new ComboBox(this, "settingscombo", 10 , false );
-
- m_pLeftButton = new CSpecButton( this, "specprev");
- m_pLeftButton->SetText("3");
- m_pRightButton = new CSpecButton( this, "specnext");
- m_pRightButton->SetText("4");
-
- m_pPlayerList->SetText("");
- m_pViewOptions->SetText("#Spec_Modes");
- m_pConfigSettings->SetText("#Spec_Options");
-
- m_pPlayerList->SetOpenDirection( Menu::UP );
- m_pViewOptions->SetOpenDirection( Menu::UP );
- m_pConfigSettings->SetOpenDirection( Menu::UP );
-
- // create view config menu
- CommandMenu * menu = new CommandMenu(m_pConfigSettings, "spectatormenu", gViewPortInterface);
- menu->LoadFromFile( "Resource/spectatormenu.res" );
- m_pConfigSettings->SetMenu( menu ); // attach menu to combo box
-
- // create view mode menu
- menu = new CommandMenu(m_pViewOptions, "spectatormodes", gViewPortInterface);
- menu->LoadFromFile("Resource/spectatormodes.res");
- m_pViewOptions->SetMenu( menu ); // attach menu to combo box
-
- LoadControlSettings("Resource/UI/BottomSpectator.res");
- ListenForGameEvent( "spec_target_updated" );
-}
-
-void CSpectatorMenu::ApplySchemeSettings(IScheme *pScheme)
-{
- BaseClass::ApplySchemeSettings(pScheme);
- // need to MakeReadyForUse() on the menus so we can set their bg color before they are displayed
- m_pConfigSettings->GetMenu()->MakeReadyForUse();
- m_pViewOptions->GetMenu()->MakeReadyForUse();
- m_pPlayerList->GetMenu()->MakeReadyForUse();
-
- if ( g_pSpectatorGUI )
- {
- m_pConfigSettings->GetMenu()->SetBgColor( g_pSpectatorGUI->GetBlackBarColor() );
- m_pViewOptions->GetMenu()->SetBgColor( g_pSpectatorGUI->GetBlackBarColor() );
- m_pPlayerList->GetMenu()->SetBgColor( g_pSpectatorGUI->GetBlackBarColor() );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: makes the GUI fill the screen
-//-----------------------------------------------------------------------------
-void CSpectatorMenu::PerformLayout()
-{
- int w,h;
- GetHudSize(w, h);
-
- // fill the screen
- SetSize(w,GetTall());
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Handles changes to combo boxes
-//-----------------------------------------------------------------------------
-void CSpectatorMenu::OnTextChanged(KeyValues *data)
-{
- Panel *panel = reinterpret_cast<vgui::Panel *>( data->GetPtr("panel") );
-
- vgui::ComboBox *box = dynamic_cast<vgui::ComboBox *>( panel );
-
- if( box == m_pConfigSettings) // don't change the text in the config setting combo
- {
- m_pConfigSettings->SetText("#Spec_Options");
- }
- else if ( box == m_pPlayerList )
- {
- KeyValues *kv = box->GetActiveItemUserData();
- if ( kv && GameResources() )
- {
- const char *player = kv->GetString("player");
-
- int currentPlayerNum = GetSpectatorTarget();
- const char *currentPlayerName = GameResources()->GetPlayerName( currentPlayerNum );
-
- if ( !FStrEq( currentPlayerName, player ) )
- {
- char command[128];
- Q_snprintf( command, sizeof(command), "spec_player \"%s\"", player );
- engine->ClientCmd( command );
- }
- }
- }
-}
-
-void CSpectatorMenu::OnCommand( const char *command )
-{
- if (!stricmp(command, "specnext") )
- {
- engine->ClientCmd("spec_next");
- }
- else if (!stricmp(command, "specprev") )
- {
- engine->ClientCmd("spec_prev");
- }
-}
-
-void CSpectatorMenu::FireGameEvent( IGameEvent * event )
-{
- const char *pEventName = event->GetName();
-
- if ( Q_strcmp( "spec_target_updated", pEventName ) == 0 )
- {
- IGameResources *gr = GameResources();
- if ( !gr )
- return;
-
- // make sure the player combo box is up to date
- int playernum = GetSpectatorTarget();
- if ( playernum < 1 || playernum > MAX_PLAYERS )
- return;
-
- const char *selectedPlayerName = gr->GetPlayerName( playernum );
- const char *currentPlayerName = "";
- KeyValues *kv = m_pPlayerList->GetActiveItemUserData();
- if ( kv )
- {
- currentPlayerName = kv->GetString( "player" );
- }
- if ( !FStrEq( currentPlayerName, selectedPlayerName ) )
- {
- for ( int i=0; i<m_pPlayerList->GetItemCount(); ++i )
- {
- KeyValues *kv = m_pPlayerList->GetItemUserData( i );
- if ( kv && FStrEq( kv->GetString( "player" ), selectedPlayerName ) )
- {
- m_pPlayerList->ActivateItemByRow( i );
- break;
- }
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: when duck is pressed it hides the active part of the GUI
-//-----------------------------------------------------------------------------
-void CSpectatorMenu::OnKeyCodePressed(KeyCode code)
-{
- if ( code == m_iDuckKey )
- {
- // hide if DUCK is pressed again
- m_pViewPort->ShowPanel( this, false );
- }
-}
-
-void CSpectatorMenu::ShowPanel(bool bShow)
-{
- if ( BaseClass::IsVisible() == bShow )
- return;
-
- if ( bShow )
- {
- Activate();
- SetMouseInputEnabled( true );
- SetKeyBoardInputEnabled( true );
- }
- else
- {
- SetVisible( false );
- SetMouseInputEnabled( false );
- SetKeyBoardInputEnabled( false );
- }
-
- bool bIsEnabled = true;
-
- if ( engine->IsHLTV() && HLTVCamera()->IsPVSLocked() )
- {
- // when watching HLTV or Replay with a locked PVS, some elements are disabled
- bIsEnabled = false;
- }
-
- m_pLeftButton->SetVisible( bIsEnabled );
- m_pRightButton->SetVisible( bIsEnabled );
- m_pPlayerList->SetVisible( bIsEnabled );
- m_pViewOptions->SetVisible( bIsEnabled );
-}
-
-void CSpectatorMenu::Update( void )
-{
- IGameResources *gr = GameResources();
-
- Reset();
-
- if ( m_iDuckKey == BUTTON_CODE_INVALID )
- {
- m_iDuckKey = gameuifuncs->GetButtonCodeForBind( "duck" );
- }
-
- if ( !gr )
- return;
-
- int iPlayerIndex;
- for ( iPlayerIndex = 1 ; iPlayerIndex <= gpGlobals->maxClients; iPlayerIndex++ )
- {
-
- // does this slot in the array have a name?
- if ( !gr->IsConnected( iPlayerIndex ) )
- continue;
-
- if ( gr->IsLocalPlayer( iPlayerIndex ) )
- continue;
-
- if ( !gr->IsAlive( iPlayerIndex ) )
- continue;
-
- wchar_t playerText[ 80 ], playerName[ 64 ], *team, teamText[ 64 ];
- char localizeTeamName[64];
- char szPlayerIndex[16];
- g_pVGuiLocalize->ConvertANSIToUnicode( UTIL_SafeName( gr->GetPlayerName(iPlayerIndex) ), playerName, sizeof( playerName ) );
- const char * teamname = gr->GetTeamName( gr->GetTeam(iPlayerIndex) );
- if ( teamname )
- {
- Q_snprintf( localizeTeamName, sizeof( localizeTeamName ), "#%s", teamname );
- team=g_pVGuiLocalize->Find( localizeTeamName );
-
- if ( !team )
- {
- g_pVGuiLocalize->ConvertANSIToUnicode( teamname , teamText, sizeof( teamText ) );
- team = teamText;
- }
-
- g_pVGuiLocalize->ConstructString( playerText, sizeof( playerText ), g_pVGuiLocalize->Find( "#Spec_PlayerItem_Team" ), 2, playerName, team );
- }
- else
- {
- g_pVGuiLocalize->ConstructString( playerText, sizeof( playerText ), g_pVGuiLocalize->Find( "#Spec_PlayerItem" ), 1, playerName );
- }
-
- Q_snprintf( szPlayerIndex, sizeof( szPlayerIndex ), "%d", iPlayerIndex );
-
- KeyValues *kv = new KeyValues( "UserData", "player", gr->GetPlayerName( iPlayerIndex ), "index", szPlayerIndex );
- m_pPlayerList->AddItem( playerText, kv );
- kv->deleteThis();
- }
-
- // make sure the player combo box is up to date
- int playernum = GetSpectatorTarget();
- const char *selectedPlayerName = gr->GetPlayerName( playernum );
- for ( iPlayerIndex=0; iPlayerIndex<m_pPlayerList->GetItemCount(); ++iPlayerIndex )
- {
- KeyValues *kv = m_pPlayerList->GetItemUserData( iPlayerIndex );
- if ( kv && FStrEq( kv->GetString( "player" ), selectedPlayerName ) )
- {
- m_pPlayerList->ActivateItemByRow( iPlayerIndex );
- break;
- }
- }
-
- //=============================================================================
- // HPE_BEGIN:
- // [pfreese] make sure the view mode combo box is up to date - the spectator
- // mode can be changed multiple ways
- //=============================================================================
-
- int specmode = GetSpectatorMode();
- m_pViewOptions->SetText(s_SpectatorModes[specmode]);
-
- //=============================================================================
- // HPE_END
- //=============================================================================
-}
-
-//-----------------------------------------------------------------------------
-// main spectator panel
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CSpectatorGUI::CSpectatorGUI(IViewPort *pViewPort) : EditablePanel( NULL, PANEL_SPECGUI )
-{
-// m_bHelpShown = false;
-// m_bInsetVisible = false;
-// m_iDuckKey = KEY_NONE;
- SetSize( 10, 10 ); // Quiet "parent not sized yet" spew
- m_bSpecScoreboard = false;
-
- m_pViewPort = pViewPort;
- g_pSpectatorGUI = this;
-
- // initialize dialog
- SetVisible(false);
- SetProportional(true);
-
- // load the new scheme early!!
- SetScheme("ClientScheme");
- SetMouseInputEnabled( false );
- SetKeyBoardInputEnabled( false );
-
- m_pTopBar = new Panel( this, "topbar" );
- m_pBottomBarBlank = new Panel( this, "bottombarblank" );
-
- // m_pBannerImage = new ImagePanel( m_pTopBar, NULL );
- m_pPlayerLabel = new Label( this, "playerlabel", "" );
- m_pPlayerLabel->SetVisible( false );
- TextImage *image = m_pPlayerLabel->GetTextImage();
- if ( image )
- {
- HFont hFallbackFont = scheme()->GetIScheme( GetScheme() )->GetFont( "DefaultVerySmallFallBack", false );
- if ( INVALID_FONT != hFallbackFont )
- {
- image->SetUseFallbackFont( true, hFallbackFont );
- }
- }
-
- SetPaintBorderEnabled(false);
- SetPaintBackgroundEnabled(false);
-
- // m_pBannerImage->SetVisible(false);
- InvalidateLayout();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Destructor
-//-----------------------------------------------------------------------------
-CSpectatorGUI::~CSpectatorGUI()
-{
- g_pSpectatorGUI = NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the colour of the top and bottom bars
-//-----------------------------------------------------------------------------
-void CSpectatorGUI::ApplySchemeSettings(IScheme *pScheme)
-{
- KeyValues *pConditions = NULL;
-
-#ifdef TF_CLIENT_DLL
- if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
- {
- pConditions = new KeyValues( "conditions" );
- AddSubKeyNamed( pConditions, "if_mvm" );
- }
-#endif
-
- LoadControlSettings( GetResFile(), NULL, NULL, pConditions );
-
- if ( pConditions )
- {
- pConditions->deleteThis();
- }
-
- m_pBottomBarBlank->SetVisible( true );
- m_pTopBar->SetVisible( true );
-
- BaseClass::ApplySchemeSettings( pScheme );
- SetBgColor(Color( 0,0,0,0 ) ); // make the background transparent
- m_pTopBar->SetBgColor(GetBlackBarColor());
- m_pBottomBarBlank->SetBgColor(GetBlackBarColor());
- // m_pBottomBar->SetBgColor(Color( 0,0,0,0 ));
- SetPaintBorderEnabled(false);
-
- SetBorder( NULL );
-
-#ifdef CSTRIKE_DLL
- SetZPos(80); // guarantee it shows above the scope
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: makes the GUI fill the screen
-//-----------------------------------------------------------------------------
-void CSpectatorGUI::PerformLayout()
-{
- int w,h,x,y;
- GetHudSize(w, h);
-
- // fill the screen
- SetBounds(0,0,w,h);
-
- // stretch the bottom bar across the screen
- m_pBottomBarBlank->GetPos(x,y);
- m_pBottomBarBlank->SetSize( w, h - y );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: checks spec_scoreboard cvar to see if the scoreboard should be displayed
-//-----------------------------------------------------------------------------
-void CSpectatorGUI::OnThink()
-{
- BaseClass::OnThink();
-
- if ( IsVisible() )
- {
- if ( m_bSpecScoreboard != spec_scoreboard.GetBool() )
- {
- if ( !spec_scoreboard.GetBool() || !gViewPortInterface->GetActivePanel() )
- {
- m_bSpecScoreboard = spec_scoreboard.GetBool();
- gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, m_bSpecScoreboard );
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: sets the image to display for the banner in the top right corner
-//-----------------------------------------------------------------------------
-void CSpectatorGUI::SetLogoImage(const char *image)
-{
- if ( m_pBannerImage )
- {
- m_pBannerImage->SetImage( scheme()->GetImage(image, false) );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the text of a control by name
-//-----------------------------------------------------------------------------
-void CSpectatorGUI::SetLabelText(const char *textEntryName, const char *text)
-{
- Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
- if (entry)
- {
- entry->SetText(text);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the text of a control by name
-//-----------------------------------------------------------------------------
-void CSpectatorGUI::SetLabelText(const char *textEntryName, wchar_t *text)
-{
- Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
- if (entry)
- {
- entry->SetText(text);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the text of a control by name
-//-----------------------------------------------------------------------------
-void CSpectatorGUI::MoveLabelToFront(const char *textEntryName)
-{
- Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
- if (entry)
- {
- entry->MoveToFront();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: shows/hides the buy menu
-//-----------------------------------------------------------------------------
-void CSpectatorGUI::ShowPanel(bool bShow)
-{
- if ( bShow && !IsVisible() )
- {
- m_bSpecScoreboard = false;
- }
- SetVisible( bShow );
- if ( !bShow && m_bSpecScoreboard )
- {
- gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, false );
- }
-}
-
-bool CSpectatorGUI::ShouldShowPlayerLabel( int specmode )
-{
- return ( (specmode == OBS_MODE_IN_EYE) || (specmode == OBS_MODE_CHASE) );
-}
-//-----------------------------------------------------------------------------
-// Purpose: Updates the gui, rearranges elements
-//-----------------------------------------------------------------------------
-void CSpectatorGUI::Update()
-{
- int wide, tall;
- int bx, by, bwide, btall;
-
- GetHudSize(wide, tall);
- m_pTopBar->GetBounds( bx, by, bwide, btall );
-
- IGameResources *gr = GameResources();
- int specmode = GetSpectatorMode();
- int playernum = GetSpectatorTarget();
-
- IViewPortPanel *overview = gViewPortInterface->FindPanelByName( PANEL_OVERVIEW );
-
- if ( overview && overview->IsVisible() )
- {
- int mx, my, mwide, mtall;
-
- VPANEL p = overview->GetVPanel();
- vgui::ipanel()->GetPos( p, mx, my );
- vgui::ipanel()->GetSize( p, mwide, mtall );
-
- if ( my < btall )
- {
- // reduce to bar
- m_pTopBar->SetSize( wide - (mx + mwide), btall );
- m_pTopBar->SetPos( (mx + mwide), 0 );
- }
- else
- {
- // full top bar
- m_pTopBar->SetSize( wide , btall );
- m_pTopBar->SetPos( 0, 0 );
- }
- }
- else
- {
- // full top bar
- m_pTopBar->SetSize( wide , btall ); // change width, keep height
- m_pTopBar->SetPos( 0, 0 );
- }
-
- m_pPlayerLabel->SetVisible( ShouldShowPlayerLabel(specmode) );
-
- // update player name filed, text & color
-
- if ( playernum > 0 && playernum <= gpGlobals->maxClients && gr )
- {
- Color c = gr->GetTeamColor( gr->GetTeam(playernum) ); // Player's team color
-
- m_pPlayerLabel->SetFgColor( c );
-
- wchar_t playerText[ 80 ], playerName[ 64 ], health[ 10 ];
- V_wcsncpy( playerText, L"Unable to find #Spec_PlayerItem*", sizeof( playerText ) );
- memset( playerName, 0x0, sizeof( playerName ) );
-
- g_pVGuiLocalize->ConvertANSIToUnicode( UTIL_SafeName(gr->GetPlayerName( playernum )), playerName, sizeof( playerName ) );
- int iHealth = gr->GetHealth( playernum );
- if ( iHealth > 0 && gr->IsAlive(playernum) )
- {
- _snwprintf( health, ARRAYSIZE( health ), L"%i", iHealth );
- g_pVGuiLocalize->ConstructString( playerText, sizeof( playerText ), g_pVGuiLocalize->Find( "#Spec_PlayerItem_Team" ), 2, playerName, health );
- }
- else
- {
- g_pVGuiLocalize->ConstructString( playerText, sizeof( playerText ), g_pVGuiLocalize->Find( "#Spec_PlayerItem" ), 1, playerName );
- }
-
- m_pPlayerLabel->SetText( playerText );
- }
- else
- {
- m_pPlayerLabel->SetText( L"" );
- }
-
- // update extra info field
- wchar_t szEtxraInfo[1024];
- wchar_t szTitleLabel[1024];
- char tempstr[128];
-
- if ( engine->IsHLTV() )
- {
- // set spectator number and HLTV title
- Q_snprintf(tempstr,sizeof(tempstr),"Spectators : %d", HLTVCamera()->GetNumSpectators() );
- g_pVGuiLocalize->ConvertANSIToUnicode(tempstr,szEtxraInfo,sizeof(szEtxraInfo));
-
- Q_strncpy( tempstr, HLTVCamera()->GetTitleText(), sizeof(tempstr) );
- g_pVGuiLocalize->ConvertANSIToUnicode(tempstr,szTitleLabel,sizeof(szTitleLabel));
- }
- else
- {
- // otherwise show map name
- Q_FileBase( engine->GetLevelName(), tempstr, sizeof(tempstr) );
-
- wchar_t wMapName[64];
- g_pVGuiLocalize->ConvertANSIToUnicode(tempstr,wMapName,sizeof(wMapName));
- g_pVGuiLocalize->ConstructString( szEtxraInfo,sizeof( szEtxraInfo ), g_pVGuiLocalize->Find("#Spec_Map" ),1, wMapName );
-
- g_pVGuiLocalize->ConvertANSIToUnicode( "" ,szTitleLabel,sizeof(szTitleLabel));
- }
-
- SetLabelText("extrainfo", szEtxraInfo );
- SetLabelText("titlelabel", szTitleLabel );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Updates the timer label if one exists
-//-----------------------------------------------------------------------------
-void CSpectatorGUI::UpdateTimer()
-{
- wchar_t szText[ 63 ];
-
- int timer = 0;
-
- V_swprintf_safe ( szText, L"%d:%02d\n", (timer / 60), (timer % 60) );
-
- SetLabelText("timerlabel", szText );
-}
-
-static void ForwardSpecCmdToServer( const CCommand &args )
-{
- if ( engine->IsPlayingDemo() )
- return;
-
- if ( args.ArgC() == 1 )
- {
- // just forward the command without parameters
- engine->ServerCmd( args[ 0 ] );
- }
- else if ( args.ArgC() == 2 )
- {
- // forward the command with parameter
- char command[128];
- Q_snprintf( command, sizeof(command), "%s \"%s\"", args[ 0 ], args[ 1 ] );
- engine->ServerCmd( command );
- }
-}
-
-CON_COMMAND_F( spec_next, "Spectate next player", FCVAR_CLIENTCMD_CAN_EXECUTE )
-{
- C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
-
- if ( !pPlayer || !pPlayer->IsObserver() )
- return;
-
- if ( engine->IsHLTV() )
- {
- // handle the command clientside
- if ( !HLTVCamera()->IsPVSLocked() )
- {
- HLTVCamera()->SpecNextPlayer( false );
- }
- }
- else
- {
- ForwardSpecCmdToServer( args );
- }
-}
-
-CON_COMMAND_F( spec_prev, "Spectate previous player", FCVAR_CLIENTCMD_CAN_EXECUTE )
-{
- C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
-
- if ( !pPlayer || !pPlayer->IsObserver() )
- return;
-
- if ( engine->IsHLTV() )
- {
- // handle the command clientside
- if ( !HLTVCamera()->IsPVSLocked() )
- {
- HLTVCamera()->SpecNextPlayer( true );
- }
- }
- else
- {
- ForwardSpecCmdToServer( args );
- }
-}
-
-CON_COMMAND_F( spec_mode, "Set spectator mode", FCVAR_CLIENTCMD_CAN_EXECUTE )
-{
- C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
-
- if ( !pPlayer || !pPlayer->IsObserver() )
- return;
-
- if ( engine->IsHLTV() )
- {
- if ( HLTVCamera()->IsPVSLocked() )
- {
- // in locked mode we can only switch between first and 3rd person
- HLTVCamera()->ToggleChaseAsFirstPerson();
- }
- else
- {
- // we can choose any mode, not loked to PVS
- int mode;
-
- if ( args.ArgC() == 2 )
- {
- // set specifc mode
- mode = Q_atoi( args[1] );
- }
- else
- {
- // set next mode
- mode = HLTVCamera()->GetMode()+1;
-
- if ( mode > LAST_PLAYER_OBSERVERMODE )
- mode = OBS_MODE_IN_EYE;
- }
-
- // handle the command clientside
- HLTVCamera()->SetMode( mode );
- }
-
- // turn off auto director once user tried to change view settings
- HLTVCamera()->SetAutoDirector( false );
- }
- else
- {
- // we spectate on a game server, forward command
- ForwardSpecCmdToServer( args );
- }
-}
-
-CON_COMMAND_F( spec_player, "Spectate player by name", FCVAR_CLIENTCMD_CAN_EXECUTE )
-{
- C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
-
- if ( !pPlayer || !pPlayer->IsObserver() )
- return;
-
- if ( args.ArgC() != 2 )
- return;
-
- if ( engine->IsHLTV() )
- {
- // we can only switch primary spectator targets is PVS isnt locked by auto-director
- if ( !HLTVCamera()->IsPVSLocked() )
- {
- HLTVCamera()->SpecNamedPlayer( args[1] );
- }
- }
- else
- {
- ForwardSpecCmdToServer( args );
- }
-}
-
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include <cdll_client_int.h>
+#include <globalvars_base.h>
+#include <cdll_util.h>
+#include <KeyValues.h>
+
+#include "spectatorgui.h"
+
+#include <vgui/IScheme.h>
+#include <vgui/ILocalize.h>
+#include <vgui/ISurface.h>
+#include <vgui/IPanel.h>
+#include <vgui_controls/ImageList.h>
+#include <vgui_controls/MenuItem.h>
+#include <vgui_controls/TextImage.h>
+
+#include <stdio.h> // _snprintf define
+
+#include <game/client/iviewport.h>
+#include "commandmenu.h"
+#include "hltvcamera.h"
+#if defined( REPLAY_ENABLED )
+#include "replay/replaycamera.h"
+#endif
+
+#include <vgui_controls/TextEntry.h>
+#include <vgui_controls/Panel.h>
+#include <vgui_controls/ImagePanel.h>
+#include <vgui_controls/Menu.h>
+#include "IGameUIFuncs.h" // for key bindings
+#include <imapoverview.h>
+#include <shareddefs.h>
+#include <igameresources.h>
+
+#ifdef TF_CLIENT_DLL
+#include "tf_gamerules.h"
+void AddSubKeyNamed( KeyValues *pKeys, const char *pszName );
+#endif
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#ifndef _XBOX
+extern IGameUIFuncs *gameuifuncs; // for key binding details
+#endif
+
+// void DuckMessage(const char *str); // from vgui_teamfortressviewport.cpp
+
+ConVar spec_scoreboard( "spec_scoreboard", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
+
+CSpectatorGUI *g_pSpectatorGUI = NULL;
+
+
+// NB disconnect between localization text and observer mode enums
+static const char *s_SpectatorModes[] =
+{
+ "#Spec_Mode0", // OBS_MODE_NONE = 0,
+ "#Spec_Mode1", // OBS_MODE_DEATHCAM,
+ "", // OBS_MODE_FREEZECAM,
+ "#Spec_Mode2", // OBS_MODE_FIXED,
+ "#Spec_Mode3", // OBS_MODE_IN_EYE,
+ "#Spec_Mode4", // OBS_MODE_CHASE,
+ "#Spec_Mode5", // OBS_MODE_ROAMING,
+};
+
+using namespace vgui;
+
+ConVar cl_spec_mode(
+ "cl_spec_mode",
+ "1",
+ FCVAR_ARCHIVE | FCVAR_USERINFO | FCVAR_SERVER_CAN_EXECUTE,
+ "spectator mode" );
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: left and right buttons pointing buttons
+//-----------------------------------------------------------------------------
+class CSpecButton : public Button
+{
+public:
+ CSpecButton(Panel *parent, const char *panelName): Button(parent, panelName, "") {}
+
+private:
+ void ApplySchemeSettings(vgui::IScheme *pScheme)
+ {
+ Button::ApplySchemeSettings(pScheme);
+ SetFont(pScheme->GetFont("Marlett", IsProportional()) );
+ }
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CSpectatorMenu::CSpectatorMenu( IViewPort *pViewPort ) : Frame( NULL, PANEL_SPECMENU )
+{
+ m_iDuckKey = BUTTON_CODE_INVALID;
+
+ m_pViewPort = pViewPort;
+
+ SetMouseInputEnabled( true );
+ SetKeyBoardInputEnabled( true );
+ SetTitleBarVisible( false ); // don't draw a title bar
+ SetMoveable( false );
+ SetSizeable( false );
+ SetProportional(true);
+
+ SetScheme("ClientScheme");
+
+ m_pPlayerList = new ComboBox(this, "playercombo", 10 , false);
+ HFont hFallbackFont = scheme()->GetIScheme( GetScheme() )->GetFont( "DefaultVerySmallFallBack", false );
+ if ( INVALID_FONT != hFallbackFont )
+ {
+ m_pPlayerList->SetUseFallbackFont( true, hFallbackFont );
+ }
+
+ m_pViewOptions = new ComboBox(this, "viewcombo", 10 , false );
+ m_pConfigSettings = new ComboBox(this, "settingscombo", 10 , false );
+
+ m_pLeftButton = new CSpecButton( this, "specprev");
+ m_pLeftButton->SetText("3");
+ m_pRightButton = new CSpecButton( this, "specnext");
+ m_pRightButton->SetText("4");
+
+ m_pPlayerList->SetText("");
+ m_pViewOptions->SetText("#Spec_Modes");
+ m_pConfigSettings->SetText("#Spec_Options");
+
+ m_pPlayerList->SetOpenDirection( Menu::UP );
+ m_pViewOptions->SetOpenDirection( Menu::UP );
+ m_pConfigSettings->SetOpenDirection( Menu::UP );
+
+ // create view config menu
+ CommandMenu * menu = new CommandMenu(m_pConfigSettings, "spectatormenu", gViewPortInterface);
+ menu->LoadFromFile( "Resource/spectatormenu.res" );
+ m_pConfigSettings->SetMenu( menu ); // attach menu to combo box
+
+ // create view mode menu
+ menu = new CommandMenu(m_pViewOptions, "spectatormodes", gViewPortInterface);
+ menu->LoadFromFile("Resource/spectatormodes.res");
+ m_pViewOptions->SetMenu( menu ); // attach menu to combo box
+
+ LoadControlSettings("Resource/UI/BottomSpectator.res");
+ ListenForGameEvent( "spec_target_updated" );
+}
+
+void CSpectatorMenu::ApplySchemeSettings(IScheme *pScheme)
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+ // need to MakeReadyForUse() on the menus so we can set their bg color before they are displayed
+ m_pConfigSettings->GetMenu()->MakeReadyForUse();
+ m_pViewOptions->GetMenu()->MakeReadyForUse();
+ m_pPlayerList->GetMenu()->MakeReadyForUse();
+
+ if ( g_pSpectatorGUI )
+ {
+ m_pConfigSettings->GetMenu()->SetBgColor( g_pSpectatorGUI->GetBlackBarColor() );
+ m_pViewOptions->GetMenu()->SetBgColor( g_pSpectatorGUI->GetBlackBarColor() );
+ m_pPlayerList->GetMenu()->SetBgColor( g_pSpectatorGUI->GetBlackBarColor() );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: makes the GUI fill the screen
+//-----------------------------------------------------------------------------
+void CSpectatorMenu::PerformLayout()
+{
+ int w,h;
+ GetHudSize(w, h);
+
+ // fill the screen
+ SetSize(w,GetTall());
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Handles changes to combo boxes
+//-----------------------------------------------------------------------------
+void CSpectatorMenu::OnTextChanged(KeyValues *data)
+{
+ Panel *panel = reinterpret_cast<vgui::Panel *>( data->GetPtr("panel") );
+
+ vgui::ComboBox *box = dynamic_cast<vgui::ComboBox *>( panel );
+
+ if( box == m_pConfigSettings) // don't change the text in the config setting combo
+ {
+ m_pConfigSettings->SetText("#Spec_Options");
+ }
+ else if ( box == m_pPlayerList )
+ {
+ KeyValues *kv = box->GetActiveItemUserData();
+ if ( kv && GameResources() )
+ {
+ const char *player = kv->GetString("player");
+
+ int currentPlayerNum = GetSpectatorTarget();
+ const char *currentPlayerName = GameResources()->GetPlayerName( currentPlayerNum );
+
+ if ( !FStrEq( currentPlayerName, player ) )
+ {
+ char command[128];
+ Q_snprintf( command, sizeof(command), "spec_player \"%s\"", player );
+ engine->ClientCmd( command );
+ }
+ }
+ }
+}
+
+void CSpectatorMenu::OnCommand( const char *command )
+{
+ if (!stricmp(command, "specnext") )
+ {
+ engine->ClientCmd("spec_next");
+ }
+ else if (!stricmp(command, "specprev") )
+ {
+ engine->ClientCmd("spec_prev");
+ }
+}
+
+void CSpectatorMenu::FireGameEvent( IGameEvent * event )
+{
+ const char *pEventName = event->GetName();
+
+ if ( Q_strcmp( "spec_target_updated", pEventName ) == 0 )
+ {
+ IGameResources *gr = GameResources();
+ if ( !gr )
+ return;
+
+ // make sure the player combo box is up to date
+ int playernum = GetSpectatorTarget();
+ if ( playernum < 1 || playernum > MAX_PLAYERS )
+ return;
+
+ const char *selectedPlayerName = gr->GetPlayerName( playernum );
+ const char *currentPlayerName = "";
+ KeyValues *kv = m_pPlayerList->GetActiveItemUserData();
+ if ( kv )
+ {
+ currentPlayerName = kv->GetString( "player" );
+ }
+ if ( !FStrEq( currentPlayerName, selectedPlayerName ) )
+ {
+ for ( int i=0; i<m_pPlayerList->GetItemCount(); ++i )
+ {
+ KeyValues *kv = m_pPlayerList->GetItemUserData( i );
+ if ( kv && FStrEq( kv->GetString( "player" ), selectedPlayerName ) )
+ {
+ m_pPlayerList->ActivateItemByRow( i );
+ break;
+ }
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: when duck is pressed it hides the active part of the GUI
+//-----------------------------------------------------------------------------
+void CSpectatorMenu::OnKeyCodePressed(KeyCode code)
+{
+ if ( code == m_iDuckKey )
+ {
+ // hide if DUCK is pressed again
+ m_pViewPort->ShowPanel( this, false );
+ }
+}
+
+void CSpectatorMenu::ShowPanel(bool bShow)
+{
+ if ( BaseClass::IsVisible() == bShow )
+ return;
+
+ if ( bShow )
+ {
+ Activate();
+ SetMouseInputEnabled( true );
+ SetKeyBoardInputEnabled( true );
+ }
+ else
+ {
+ SetVisible( false );
+ SetMouseInputEnabled( false );
+ SetKeyBoardInputEnabled( false );
+ }
+
+ bool bIsEnabled = true;
+
+ if ( engine->IsHLTV() && HLTVCamera()->IsPVSLocked() )
+ {
+ // when watching HLTV or Replay with a locked PVS, some elements are disabled
+ bIsEnabled = false;
+ }
+
+ m_pLeftButton->SetVisible( bIsEnabled );
+ m_pRightButton->SetVisible( bIsEnabled );
+ m_pPlayerList->SetVisible( bIsEnabled );
+ m_pViewOptions->SetVisible( bIsEnabled );
+}
+
+void CSpectatorMenu::Update( void )
+{
+ IGameResources *gr = GameResources();
+
+ Reset();
+
+ if ( m_iDuckKey == BUTTON_CODE_INVALID )
+ {
+ m_iDuckKey = gameuifuncs->GetButtonCodeForBind( "duck" );
+ }
+
+ if ( !gr )
+ return;
+
+ int iPlayerIndex;
+ for ( iPlayerIndex = 1 ; iPlayerIndex <= gpGlobals->maxClients; iPlayerIndex++ )
+ {
+
+ // does this slot in the array have a name?
+ if ( !gr->IsConnected( iPlayerIndex ) )
+ continue;
+
+ if ( gr->IsLocalPlayer( iPlayerIndex ) )
+ continue;
+
+ if ( !gr->IsAlive( iPlayerIndex ) )
+ continue;
+
+ wchar_t playerText[ 80 ], playerName[ 64 ], *team, teamText[ 64 ];
+ char localizeTeamName[64];
+ char szPlayerIndex[16];
+ g_pVGuiLocalize->ConvertANSIToUnicode( UTIL_SafeName( gr->GetPlayerName(iPlayerIndex) ), playerName, sizeof( playerName ) );
+ const char * teamname = gr->GetTeamName( gr->GetTeam(iPlayerIndex) );
+ if ( teamname )
+ {
+ Q_snprintf( localizeTeamName, sizeof( localizeTeamName ), "#%s", teamname );
+ team=g_pVGuiLocalize->Find( localizeTeamName );
+
+ if ( !team )
+ {
+ g_pVGuiLocalize->ConvertANSIToUnicode( teamname , teamText, sizeof( teamText ) );
+ team = teamText;
+ }
+
+ g_pVGuiLocalize->ConstructString( playerText, sizeof( playerText ), g_pVGuiLocalize->Find( "#Spec_PlayerItem_Team" ), 2, playerName, team );
+ }
+ else
+ {
+ g_pVGuiLocalize->ConstructString( playerText, sizeof( playerText ), g_pVGuiLocalize->Find( "#Spec_PlayerItem" ), 1, playerName );
+ }
+
+ Q_snprintf( szPlayerIndex, sizeof( szPlayerIndex ), "%d", iPlayerIndex );
+
+ KeyValues *kv = new KeyValues( "UserData", "player", gr->GetPlayerName( iPlayerIndex ), "index", szPlayerIndex );
+ m_pPlayerList->AddItem( playerText, kv );
+ kv->deleteThis();
+ }
+
+ // make sure the player combo box is up to date
+ int playernum = GetSpectatorTarget();
+ const char *selectedPlayerName = gr->GetPlayerName( playernum );
+ for ( iPlayerIndex=0; iPlayerIndex<m_pPlayerList->GetItemCount(); ++iPlayerIndex )
+ {
+ KeyValues *kv = m_pPlayerList->GetItemUserData( iPlayerIndex );
+ if ( kv && FStrEq( kv->GetString( "player" ), selectedPlayerName ) )
+ {
+ m_pPlayerList->ActivateItemByRow( iPlayerIndex );
+ break;
+ }
+ }
+
+ //=============================================================================
+ // HPE_BEGIN:
+ // [pfreese] make sure the view mode combo box is up to date - the spectator
+ // mode can be changed multiple ways
+ //=============================================================================
+
+ int specmode = GetSpectatorMode();
+ m_pViewOptions->SetText(s_SpectatorModes[specmode]);
+
+ //=============================================================================
+ // HPE_END
+ //=============================================================================
+}
+
+//-----------------------------------------------------------------------------
+// main spectator panel
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CSpectatorGUI::CSpectatorGUI(IViewPort *pViewPort) : EditablePanel( NULL, PANEL_SPECGUI )
+{
+// m_bHelpShown = false;
+// m_bInsetVisible = false;
+// m_iDuckKey = KEY_NONE;
+ SetSize( 10, 10 ); // Quiet "parent not sized yet" spew
+ m_bSpecScoreboard = false;
+
+ m_pViewPort = pViewPort;
+ g_pSpectatorGUI = this;
+
+ // initialize dialog
+ SetVisible(false);
+ SetProportional(true);
+
+ // load the new scheme early!!
+ SetScheme("ClientScheme");
+ SetMouseInputEnabled( false );
+ SetKeyBoardInputEnabled( false );
+
+ m_pTopBar = new Panel( this, "topbar" );
+ m_pBottomBarBlank = new Panel( this, "bottombarblank" );
+
+ // m_pBannerImage = new ImagePanel( m_pTopBar, NULL );
+ m_pPlayerLabel = new Label( this, "playerlabel", "" );
+ m_pPlayerLabel->SetVisible( false );
+ TextImage *image = m_pPlayerLabel->GetTextImage();
+ if ( image )
+ {
+ HFont hFallbackFont = scheme()->GetIScheme( GetScheme() )->GetFont( "DefaultVerySmallFallBack", false );
+ if ( INVALID_FONT != hFallbackFont )
+ {
+ image->SetUseFallbackFont( true, hFallbackFont );
+ }
+ }
+
+ SetPaintBorderEnabled(false);
+ SetPaintBackgroundEnabled(false);
+
+ // m_pBannerImage->SetVisible(false);
+ InvalidateLayout();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor
+//-----------------------------------------------------------------------------
+CSpectatorGUI::~CSpectatorGUI()
+{
+ g_pSpectatorGUI = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the colour of the top and bottom bars
+//-----------------------------------------------------------------------------
+void CSpectatorGUI::ApplySchemeSettings(IScheme *pScheme)
+{
+ KeyValues *pConditions = NULL;
+
+#ifdef TF_CLIENT_DLL
+ if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
+ {
+ pConditions = new KeyValues( "conditions" );
+ AddSubKeyNamed( pConditions, "if_mvm" );
+ }
+#endif
+
+ LoadControlSettings( GetResFile(), NULL, NULL, pConditions );
+
+ if ( pConditions )
+ {
+ pConditions->deleteThis();
+ }
+
+ m_pBottomBarBlank->SetVisible( true );
+ m_pTopBar->SetVisible( true );
+
+ BaseClass::ApplySchemeSettings( pScheme );
+ SetBgColor(Color( 0,0,0,0 ) ); // make the background transparent
+ m_pTopBar->SetBgColor(GetBlackBarColor());
+ m_pBottomBarBlank->SetBgColor(GetBlackBarColor());
+ // m_pBottomBar->SetBgColor(Color( 0,0,0,0 ));
+ SetPaintBorderEnabled(false);
+
+ SetBorder( NULL );
+
+#ifdef CSTRIKE_DLL
+ SetZPos(80); // guarantee it shows above the scope
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: makes the GUI fill the screen
+//-----------------------------------------------------------------------------
+void CSpectatorGUI::PerformLayout()
+{
+ int w,h,x,y;
+ GetHudSize(w, h);
+
+ // fill the screen
+ SetBounds(0,0,w,h);
+
+ // stretch the bottom bar across the screen
+ m_pBottomBarBlank->GetPos(x,y);
+ m_pBottomBarBlank->SetSize( w, h - y );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: checks spec_scoreboard cvar to see if the scoreboard should be displayed
+//-----------------------------------------------------------------------------
+void CSpectatorGUI::OnThink()
+{
+ BaseClass::OnThink();
+
+ if ( IsVisible() )
+ {
+ if ( m_bSpecScoreboard != spec_scoreboard.GetBool() )
+ {
+ if ( !spec_scoreboard.GetBool() || !gViewPortInterface->GetActivePanel() )
+ {
+ m_bSpecScoreboard = spec_scoreboard.GetBool();
+ gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, m_bSpecScoreboard );
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets the image to display for the banner in the top right corner
+//-----------------------------------------------------------------------------
+void CSpectatorGUI::SetLogoImage(const char *image)
+{
+ if ( m_pBannerImage )
+ {
+ m_pBannerImage->SetImage( scheme()->GetImage(image, false) );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the text of a control by name
+//-----------------------------------------------------------------------------
+void CSpectatorGUI::SetLabelText(const char *textEntryName, const char *text)
+{
+ Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
+ if (entry)
+ {
+ entry->SetText(text);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the text of a control by name
+//-----------------------------------------------------------------------------
+void CSpectatorGUI::SetLabelText(const char *textEntryName, wchar_t *text)
+{
+ Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
+ if (entry)
+ {
+ entry->SetText(text);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the text of a control by name
+//-----------------------------------------------------------------------------
+void CSpectatorGUI::MoveLabelToFront(const char *textEntryName)
+{
+ Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
+ if (entry)
+ {
+ entry->MoveToFront();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: shows/hides the buy menu
+//-----------------------------------------------------------------------------
+void CSpectatorGUI::ShowPanel(bool bShow)
+{
+ if ( bShow && !IsVisible() )
+ {
+ m_bSpecScoreboard = false;
+ }
+ SetVisible( bShow );
+ if ( !bShow && m_bSpecScoreboard )
+ {
+ gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, false );
+ }
+}
+
+bool CSpectatorGUI::ShouldShowPlayerLabel( int specmode )
+{
+ return ( (specmode == OBS_MODE_IN_EYE) || (specmode == OBS_MODE_CHASE) );
+}
+//-----------------------------------------------------------------------------
+// Purpose: Updates the gui, rearranges elements
+//-----------------------------------------------------------------------------
+void CSpectatorGUI::Update()
+{
+ int wide, tall;
+ int bx, by, bwide, btall;
+
+ GetHudSize(wide, tall);
+ m_pTopBar->GetBounds( bx, by, bwide, btall );
+
+ IGameResources *gr = GameResources();
+ int specmode = GetSpectatorMode();
+ int playernum = GetSpectatorTarget();
+
+ IViewPortPanel *overview = gViewPortInterface->FindPanelByName( PANEL_OVERVIEW );
+
+ if ( overview && overview->IsVisible() )
+ {
+ int mx, my, mwide, mtall;
+
+ VPANEL p = overview->GetVPanel();
+ vgui::ipanel()->GetPos( p, mx, my );
+ vgui::ipanel()->GetSize( p, mwide, mtall );
+
+ if ( my < btall )
+ {
+ // reduce to bar
+ m_pTopBar->SetSize( wide - (mx + mwide), btall );
+ m_pTopBar->SetPos( (mx + mwide), 0 );
+ }
+ else
+ {
+ // full top bar
+ m_pTopBar->SetSize( wide , btall );
+ m_pTopBar->SetPos( 0, 0 );
+ }
+ }
+ else
+ {
+ // full top bar
+ m_pTopBar->SetSize( wide , btall ); // change width, keep height
+ m_pTopBar->SetPos( 0, 0 );
+ }
+
+ m_pPlayerLabel->SetVisible( ShouldShowPlayerLabel(specmode) );
+
+ // update player name filed, text & color
+
+ if ( playernum > 0 && playernum <= gpGlobals->maxClients && gr )
+ {
+ Color c = gr->GetTeamColor( gr->GetTeam(playernum) ); // Player's team color
+
+ m_pPlayerLabel->SetFgColor( c );
+
+ wchar_t playerText[ 80 ], playerName[ 64 ], health[ 10 ];
+ V_wcsncpy( playerText, L"Unable to find #Spec_PlayerItem*", sizeof( playerText ) );
+ memset( playerName, 0x0, sizeof( playerName ) );
+
+ g_pVGuiLocalize->ConvertANSIToUnicode( UTIL_SafeName(gr->GetPlayerName( playernum )), playerName, sizeof( playerName ) );
+ int iHealth = gr->GetHealth( playernum );
+ if ( iHealth > 0 && gr->IsAlive(playernum) )
+ {
+ _snwprintf( health, ARRAYSIZE( health ), L"%i", iHealth );
+ g_pVGuiLocalize->ConstructString( playerText, sizeof( playerText ), g_pVGuiLocalize->Find( "#Spec_PlayerItem_Team" ), 2, playerName, health );
+ }
+ else
+ {
+ g_pVGuiLocalize->ConstructString( playerText, sizeof( playerText ), g_pVGuiLocalize->Find( "#Spec_PlayerItem" ), 1, playerName );
+ }
+
+ m_pPlayerLabel->SetText( playerText );
+ }
+ else
+ {
+ m_pPlayerLabel->SetText( L"" );
+ }
+
+ // update extra info field
+ wchar_t szEtxraInfo[1024];
+ wchar_t szTitleLabel[1024];
+ char tempstr[128];
+
+ if ( engine->IsHLTV() )
+ {
+ // set spectator number and HLTV title
+ Q_snprintf(tempstr,sizeof(tempstr),"Spectators : %d", HLTVCamera()->GetNumSpectators() );
+ g_pVGuiLocalize->ConvertANSIToUnicode(tempstr,szEtxraInfo,sizeof(szEtxraInfo));
+
+ Q_strncpy( tempstr, HLTVCamera()->GetTitleText(), sizeof(tempstr) );
+ g_pVGuiLocalize->ConvertANSIToUnicode(tempstr,szTitleLabel,sizeof(szTitleLabel));
+ }
+ else
+ {
+ // otherwise show map name
+ Q_FileBase( engine->GetLevelName(), tempstr, sizeof(tempstr) );
+
+ wchar_t wMapName[64];
+ g_pVGuiLocalize->ConvertANSIToUnicode(tempstr,wMapName,sizeof(wMapName));
+ g_pVGuiLocalize->ConstructString( szEtxraInfo,sizeof( szEtxraInfo ), g_pVGuiLocalize->Find("#Spec_Map" ),1, wMapName );
+
+ g_pVGuiLocalize->ConvertANSIToUnicode( "" ,szTitleLabel,sizeof(szTitleLabel));
+ }
+
+ SetLabelText("extrainfo", szEtxraInfo );
+ SetLabelText("titlelabel", szTitleLabel );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Updates the timer label if one exists
+//-----------------------------------------------------------------------------
+void CSpectatorGUI::UpdateTimer()
+{
+ wchar_t szText[ 63 ];
+
+ int timer = 0;
+
+ V_swprintf_safe ( szText, L"%d:%02d\n", (timer / 60), (timer % 60) );
+
+ SetLabelText("timerlabel", szText );
+}
+
+static void ForwardSpecCmdToServer( const CCommand &args )
+{
+ if ( engine->IsPlayingDemo() )
+ return;
+
+ if ( args.ArgC() == 1 )
+ {
+ // just forward the command without parameters
+ engine->ServerCmd( args[ 0 ] );
+ }
+ else if ( args.ArgC() == 2 )
+ {
+ // forward the command with parameter
+ char command[128];
+ Q_snprintf( command, sizeof(command), "%s \"%s\"", args[ 0 ], args[ 1 ] );
+ engine->ServerCmd( command );
+ }
+}
+
+CON_COMMAND_F( spec_next, "Spectate next player", FCVAR_CLIENTCMD_CAN_EXECUTE )
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+
+ if ( !pPlayer || !pPlayer->IsObserver() )
+ return;
+
+ if ( engine->IsHLTV() )
+ {
+ // handle the command clientside
+ if ( !HLTVCamera()->IsPVSLocked() )
+ {
+ HLTVCamera()->SpecNextPlayer( false );
+ }
+ }
+ else
+ {
+ ForwardSpecCmdToServer( args );
+ }
+}
+
+CON_COMMAND_F( spec_prev, "Spectate previous player", FCVAR_CLIENTCMD_CAN_EXECUTE )
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+
+ if ( !pPlayer || !pPlayer->IsObserver() )
+ return;
+
+ if ( engine->IsHLTV() )
+ {
+ // handle the command clientside
+ if ( !HLTVCamera()->IsPVSLocked() )
+ {
+ HLTVCamera()->SpecNextPlayer( true );
+ }
+ }
+ else
+ {
+ ForwardSpecCmdToServer( args );
+ }
+}
+
+CON_COMMAND_F( spec_mode, "Set spectator mode", FCVAR_CLIENTCMD_CAN_EXECUTE )
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+
+ if ( !pPlayer || !pPlayer->IsObserver() )
+ return;
+
+ if ( engine->IsHLTV() )
+ {
+ if ( HLTVCamera()->IsPVSLocked() )
+ {
+ // in locked mode we can only switch between first and 3rd person
+ HLTVCamera()->ToggleChaseAsFirstPerson();
+ }
+ else
+ {
+ // we can choose any mode, not loked to PVS
+ int mode;
+
+ if ( args.ArgC() == 2 )
+ {
+ // set specifc mode
+ mode = Q_atoi( args[1] );
+ }
+ else
+ {
+ // set next mode
+ mode = HLTVCamera()->GetMode()+1;
+
+ if ( mode > LAST_PLAYER_OBSERVERMODE )
+ mode = OBS_MODE_IN_EYE;
+ }
+
+ // handle the command clientside
+ HLTVCamera()->SetMode( mode );
+ }
+
+ // turn off auto director once user tried to change view settings
+ HLTVCamera()->SetAutoDirector( false );
+ }
+ else
+ {
+ // we spectate on a game server, forward command
+ ForwardSpecCmdToServer( args );
+ }
+}
+
+CON_COMMAND_F( spec_player, "Spectate player by name", FCVAR_CLIENTCMD_CAN_EXECUTE )
+{
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+
+ if ( !pPlayer || !pPlayer->IsObserver() )
+ return;
+
+ if ( args.ArgC() != 2 )
+ return;
+
+ if ( engine->IsHLTV() )
+ {
+ // we can only switch primary spectator targets is PVS isnt locked by auto-director
+ if ( !HLTVCamera()->IsPVSLocked() )
+ {
+ HLTVCamera()->SpecNamedPlayer( args[1] );
+ }
+ }
+ else
+ {
+ ForwardSpecCmdToServer( args );
+ }
+}
+
+
+
diff --git a/mp/src/game/client/game_controls/basemodel_panel.cpp b/mp/src/game/client/game_controls/basemodel_panel.cpp
index aa82fb94..e4115ea4 100644
--- a/mp/src/game/client/game_controls/basemodel_panel.cpp
+++ b/mp/src/game/client/game_controls/basemodel_panel.cpp
@@ -1,653 +1,653 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-
-#include "cbase.h"
-#include "basemodel_panel.h"
-#include "activitylist.h"
-#include "animation.h"
-#include "vgui/IInput.h"
-#include "matsys_controls/manipulator.h"
-
-using namespace vgui;
-DECLARE_BUILD_FACTORY( CBaseModelPanel );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CBaseModelPanel::CBaseModelPanel( vgui::Panel *pParent, const char *pName ): BaseClass( pParent, pName )
-{
- m_bForcePos = false;
- m_bMousePressed = false;
- m_bAllowRotation = false;
- m_bAllowFullManipulation = false;
- m_bApplyManipulators = false;
- m_bForcedCameraPosition = false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CBaseModelPanel::~CBaseModelPanel()
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Load in the model portion of the panel's resource file.
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::ApplySettings( KeyValues *inResourceData )
-{
- BaseClass::ApplySettings( inResourceData );
-
- // Set whether we render to texture
- m_bRenderToTexture = inResourceData->GetBool( "render_texture", true );
-
- // Grab and set the camera FOV.
- float flFOV = GetCameraFOV();
- m_BMPResData.m_flFOV = inResourceData->GetInt( "fov", flFOV );
- SetCameraFOV( m_BMPResData.m_flFOV );
-
- // Do we allow rotation on these panels.
- m_bAllowRotation = inResourceData->GetBool( "allow_rot", false );
-
- // Do we allow full manipulation on these panels.
- m_bAllowFullManipulation = inResourceData->GetBool( "allow_manip", false );
-
- // Parse our resource file and apply all necessary updates to the MDL.
- for ( KeyValues *pData = inResourceData->GetFirstSubKey() ; pData != NULL ; pData = pData->GetNextKey() )
- {
- if ( !Q_stricmp( pData->GetName(), "model" ) )
- {
- ParseModelResInfo( pData );
- }
- }
-
- SetMouseInputEnabled( m_bAllowFullManipulation || m_bAllowRotation );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::ParseModelResInfo( KeyValues *inResourceData )
-{
- m_bForcePos = ( inResourceData->GetInt( "force_pos", 0 ) == 1 );
- m_BMPResData.m_pszModelName = ReadAndAllocStringValue( inResourceData, "modelname" );
- m_BMPResData.m_pszModelName_HWM = ReadAndAllocStringValue( inResourceData, "modelname_hwm" );
- m_BMPResData.m_pszVCD = ReadAndAllocStringValue( inResourceData, "vcd" );
- m_BMPResData.m_angModelPoseRot.Init( inResourceData->GetFloat( "angles_x", 0.0f ), inResourceData->GetFloat( "angles_y", 0.0f ), inResourceData->GetFloat( "angles_z", 0.0f ) );
- m_BMPResData.m_vecOriginOffset.Init( inResourceData->GetFloat( "origin_x", 110.0 ), inResourceData->GetFloat( "origin_y", 5.0 ), inResourceData->GetFloat( "origin_z", 5.0 ) );
- m_BMPResData.m_vecFramedOriginOffset.Init( inResourceData->GetFloat( "frame_origin_x", 110.0 ), inResourceData->GetFloat( "frame_origin_y", 5.0 ), inResourceData->GetFloat( "frame_origin_z", 5.0 ) );
- m_BMPResData.m_vecViewportOffset.Init();
- m_BMPResData.m_nSkin = inResourceData->GetInt( "skin", -1 );
- m_BMPResData.m_bUseSpotlight = ( inResourceData->GetInt( "spotlight", 0 ) == 1 );
-
- m_angPlayer = m_BMPResData.m_angModelPoseRot;
- m_vecPlayerPos = m_BMPResData.m_vecOriginOffset;
-
- for ( KeyValues *pData = inResourceData->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
- {
- if ( !Q_stricmp( pData->GetName(), "animation" ) )
- {
- ParseModelAnimInfo( pData );
- }
- else if ( !Q_stricmp( pData->GetName(), "attached_model" ) )
- {
- ParseModelAttachInfo( pData );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::ParseModelAnimInfo( KeyValues *inResourceData )
-{
- if ( !inResourceData )
- return;
-
- int iAnim = m_BMPResData.m_aAnimations.AddToTail();
- if ( iAnim == m_BMPResData.m_aAnimations.InvalidIndex() )
- return;
-
- m_BMPResData.m_aAnimations[iAnim].m_pszName = ReadAndAllocStringValue( inResourceData, "name" );
- m_BMPResData.m_aAnimations[iAnim].m_pszSequence = ReadAndAllocStringValue( inResourceData, "sequence" );
- m_BMPResData.m_aAnimations[iAnim].m_pszActivity = ReadAndAllocStringValue( inResourceData, "activity" );
- m_BMPResData.m_aAnimations[iAnim].m_bDefault = ( inResourceData->GetInt( "default", 0 ) == 1 );
-
- for ( KeyValues *pAnimData = inResourceData->GetFirstSubKey(); pAnimData != NULL; pAnimData = pAnimData->GetNextKey() )
- {
- if ( !Q_stricmp( pAnimData->GetName(), "pose_parameters" ) )
- {
- m_BMPResData.m_aAnimations[iAnim].m_pPoseParameters = pAnimData->MakeCopy();
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::ParseModelAttachInfo( KeyValues *inResourceData )
-{
- if ( !inResourceData )
- return;
-
- int iAttach = m_BMPResData.m_aAttachModels.AddToTail();
- if ( iAttach == m_BMPResData.m_aAttachModels.InvalidIndex() )
- return;
-
- m_BMPResData.m_aAttachModels[iAttach].m_pszModelName = ReadAndAllocStringValue( inResourceData, "modelname" );
- m_BMPResData.m_aAttachModels[iAttach].m_nSkin = inResourceData->GetInt( "skin", -1 );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::SetupModelDefaults( void )
-{
- SetupModelAnimDefaults();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::SetupModelAnimDefaults( void )
-{
- // Set the move_x parameter so the run activity works
- SetPoseParameterByName( "move_x", 1.0f );
-
- // Verify that we have animations for this model.
- int nAnimCount = m_BMPResData.m_aAnimations.Count();
- if ( nAnimCount == 0 )
- return;
-
- // Find the default animation if one exists.
- int iIndex = FindDefaultAnim();
- if ( iIndex == -1 )
- return;
-
- SetModelAnim( iIndex );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CBaseModelPanel::FindDefaultAnim( void )
-{
- int iIndex = -1;
-
- int nAnimCount = m_BMPResData.m_aAnimations.Count();
- for ( int iAnim = 0; iAnim < nAnimCount; ++iAnim )
- {
- if ( m_BMPResData.m_aAnimations[iAnim].m_bDefault )
- return iAnim;
- }
-
- return iIndex;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CBaseModelPanel::FindAnimByName( const char *pszName )
-{
- int iIndex = -1;
- if ( !pszName )
- return iIndex;
-
- int nAnimCount = m_BMPResData.m_aAnimations.Count();
- for ( int iAnim = 0; iAnim < nAnimCount; ++iAnim )
- {
- if ( !Q_stricmp( m_BMPResData.m_aAnimations[iAnim].m_pszName, pszName ) )
- return iAnim;
- }
-
- return iIndex;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CBaseModelPanel::FindSequenceFromActivity( CStudioHdr *pStudioHdr, const char *pszActivity )
-{
- if ( !pStudioHdr )
- return -1;
-
- for ( int iSeq = 0; iSeq < pStudioHdr->GetNumSeq(); ++iSeq )
- {
- mstudioseqdesc_t &seqDesc = pStudioHdr->pSeqdesc( iSeq );
- if ( !V_stricmp( seqDesc.pszActivityName(), pszActivity ) )
- {
- return iSeq;
- }
- }
-
- return -1;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::SetModelAnim( int iAnim )
-{
- int nAnimCount = m_BMPResData.m_aAnimations.Count();
- if ( nAnimCount == 0 || !m_BMPResData.m_aAnimations.IsValidIndex( iAnim ) )
- return;
-
- MDLCACHE_CRITICAL_SECTION();
-
- // Get the studio header of the root model.
- studiohdr_t *pStudioHdr = m_RootMDL.m_MDL.GetStudioHdr();
- if ( !pStudioHdr )
- return;
-
- CStudioHdr studioHdr( pStudioHdr, g_pMDLCache );
-
- // Do we have an activity or a sequence?
- int iSequence = ACT_INVALID;
- if ( m_BMPResData.m_aAnimations[iAnim].m_pszActivity && m_BMPResData.m_aAnimations[iAnim].m_pszActivity[0] )
- {
- iSequence = FindSequenceFromActivity( &studioHdr, m_BMPResData.m_aAnimations[iAnim].m_pszActivity );
- }
- else if ( m_BMPResData.m_aAnimations[iAnim].m_pszSequence && m_BMPResData.m_aAnimations[iAnim].m_pszSequence[0] )
- {
- iSequence = LookupSequence( &studioHdr, m_BMPResData.m_aAnimations[iAnim].m_pszSequence );
- }
-
- if ( iSequence != ACT_INVALID )
- {
- SetSequence( iSequence );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::SetMDL( MDLHandle_t handle, void *pProxyData )
-{
- MDLCACHE_CRITICAL_SECTION();
- studiohdr_t *pHdr = g_pMDLCache->GetStudioHdr( handle );
-
- if ( pHdr )
- {
- // SetMDL will cause the base CMdl code to set our localtoglobal indices if they aren't set.
- // We set them up here so that they're left alone by that code.
- CStudioHdr studioHdr( pHdr, g_pMDLCache );
- if (studioHdr.numflexcontrollers() > 0 && studioHdr.pFlexcontroller( LocalFlexController_t(0) )->localToGlobal == -1)
- {
- for (LocalFlexController_t i = LocalFlexController_t(0); i < studioHdr.numflexcontrollers(); i++)
- {
- int j = C_BaseFlex::AddGlobalFlexController( studioHdr.pFlexcontroller( i )->pszName() );
- studioHdr.pFlexcontroller( i )->localToGlobal = j;
- }
- }
- }
- else
- {
- handle = MDLHANDLE_INVALID;
- }
-
- // Clear our current sequence
- SetSequence( ACT_IDLE );
-
- BaseClass::SetMDL( handle, pProxyData );
-
- SetupModelDefaults();
-
- // Need to invalidate the layout so the panel will adjust is LookAt for the new model.
- InvalidateLayout();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::SetModelAnglesAndPosition( const QAngle &angRot, const Vector &vecPos )
-{
- BaseClass::SetModelAnglesAndPosition( angRot, vecPos );
-
- // Cache
- m_vecPlayerPos = vecPos;
- m_angPlayer = angRot;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::SetMDL( const char *pMDLName, void *pProxyData )
-{
- BaseClass::SetMDL( pMDLName, pProxyData );
-
- // Need to invalidate the layout so the panel will adjust is LookAt for the new model.
-// InvalidateLayout();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::PerformLayout()
-{
- BaseClass::PerformLayout();
-
- if ( m_bForcedCameraPosition )
- {
- return;
- }
-
- if ( m_bAllowFullManipulation )
- {
- // Set this to true if you want to keep the current rotation when changing models or poses
- const bool bPreserveManipulation = false;
-
- // Need to look at the target so we can rotate around it
- const Vector kVecFocalPoint( 0.0f, 0.0f, 60.0f );
- ResetCameraPivot();
- SetCameraOffset( -(m_vecPlayerPos + kVecFocalPoint) );
- SetCameraPositionAndAngles( kVecFocalPoint, vec3_angle, !bPreserveManipulation );
-
- // We want to move the player to the origin and facing the correct way,
- // but don't clobber m_angPlayer and m_vecPlayerPos, so use BaseClass.
- BaseClass::SetModelAnglesAndPosition( m_angPlayer, vec3_origin );
-
- // Once a manual transform has been done we want to apply it
- if ( m_bApplyManipulators )
- {
- ApplyManipulation();
- }
- else
- {
- SyncManipulation();
- }
- return;
- }
-
- if ( m_bForcePos )
- {
- ResetCameraPivot();
- SetCameraOffset( Vector( 0.0f, 0.0f, 0.0f ) );
- SetCameraPositionAndAngles( vec3_origin, vec3_angle );
- SetModelAnglesAndPosition( m_angPlayer, m_vecPlayerPos );
- }
-
- // Center and fill the frame with the model?
- if ( m_bStartFramed )
- {
- Vector vecBoundsMin, vecBoundsMax;
- if ( GetBoundingBox( vecBoundsMin, vecBoundsMax ) )
- {
- LookAtBounds( vecBoundsMin, vecBoundsMax );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::OnKeyCodePressed ( vgui::KeyCode code )
-{
- if ( m_bAllowFullManipulation )
- {
- BaseClass::OnKeyCodePressed( code );
- return;
- }
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::OnKeyCodeReleased( vgui::KeyCode code )
-{
- if ( m_bAllowFullManipulation )
- {
- BaseClass::OnKeyCodeReleased( code );
- return;
- }
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::OnMousePressed ( vgui::MouseCode code )
-{
- if ( m_bAllowFullManipulation )
- {
- BaseClass::OnMousePressed( code );
- return;
- }
-
- if ( !m_bAllowRotation )
- return;
-
- RequestFocus();
-
- EnableMouseCapture( true, code );
-
- // Warp the mouse to the center of the screen
- int width, height;
- GetSize( width, height );
- int x = width / 2;
- int y = height / 2;
-
- int xpos = x;
- int ypos = y;
- LocalToScreen( xpos, ypos );
- input()->SetCursorPos( xpos, ypos );
-
- m_nManipStartX = xpos;
- m_nManipStartY = ypos;
-
- m_bMousePressed = true;
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::OnMouseReleased( vgui::MouseCode code )
-{
- if ( m_bAllowFullManipulation )
- {
- BaseClass::OnMouseReleased( code );
- return;
- }
-
- if ( !m_bAllowRotation )
- return;
-
- EnableMouseCapture( false );
- m_bMousePressed = false;
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::OnCursorMoved( int x, int y )
-{
- if ( m_bAllowFullManipulation )
- {
- if ( m_pCurrentManip )
- {
- m_bApplyManipulators = true;
- }
- BaseClass::OnCursorMoved( x, y );
- return;
- }
-
- if ( !m_bAllowRotation )
- return;
-
- if ( m_bMousePressed )
- {
- WarpMouse( x, y );
- int xpos, ypos;
- input()->GetCursorPos( xpos, ypos );
-
- // Only want the x delta.
- float flDelta = xpos - m_nManipStartX;
-
- // Apply the delta and rotate the player.
- RotateYaw( flDelta );
- }
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::RotateYaw( float flDelta )
-{
- m_angPlayer.y += flDelta;
- if ( m_angPlayer.y > 360.0f )
- {
- m_angPlayer.y = m_angPlayer.y - 360.0f;
- }
- else if ( m_angPlayer.y < -360.0f )
- {
- m_angPlayer.y = m_angPlayer.y + 360.0f;
- }
-
- SetModelAnglesAndPosition( m_angPlayer, m_vecPlayerPos );
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-Vector CBaseModelPanel::GetPlayerPos() const
-{
- return m_vecPlayerPos;
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-QAngle CBaseModelPanel::GetPlayerAngles() const
-{
- return m_angPlayer;
-}
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::OnMouseWheeled( int delta )
-{
- if ( m_bAllowFullManipulation )
- {
- BaseClass::OnMouseWheeled( delta );
- return;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Set the camera to a distance that allows the object to fill the model panel.
-//-----------------------------------------------------------------------------
-void CBaseModelPanel::LookAtBounds( const Vector &vecBoundsMin, const Vector &vecBoundsMax )
-{
- // Get the model space render bounds.
- Vector vecMin = vecBoundsMin;
- Vector vecMax = vecBoundsMax;
- Vector vecCenter = ( vecMax + vecMin ) * 0.5f;
- vecMin -= vecCenter;
- vecMax -= vecCenter;
-
- // Get the bounds points and transform them by the desired model panel rotation.
- Vector aBoundsPoints[8];
- aBoundsPoints[0].Init( vecMax.x, vecMax.y, vecMax.z );
- aBoundsPoints[1].Init( vecMin.x, vecMax.y, vecMax.z );
- aBoundsPoints[2].Init( vecMax.x, vecMin.y, vecMax.z );
- aBoundsPoints[3].Init( vecMin.x, vecMin.y, vecMax.z );
- aBoundsPoints[4].Init( vecMax.x, vecMax.y, vecMin.z );
- aBoundsPoints[5].Init( vecMin.x, vecMax.y, vecMin.z );
- aBoundsPoints[6].Init( vecMax.x, vecMin.y, vecMin.z );
- aBoundsPoints[7].Init( vecMin.x, vecMin.y, vecMin.z );
-
- // Translated center point (offset from camera center).
- Vector vecTranslateCenter = -vecCenter;
-
- // Build the rotation matrix.
- matrix3x4_t matRotation;
- AngleMatrix( m_BMPResData.m_angModelPoseRot, matRotation );
-
- Vector aXFormPoints[8];
- for ( int iPoint = 0; iPoint < 8; ++iPoint )
- {
- VectorTransform( aBoundsPoints[iPoint], matRotation, aXFormPoints[iPoint] );
- }
-
- Vector vecXFormCenter;
- VectorTransform( -vecTranslateCenter, matRotation, vecXFormCenter );
-
- int w, h;
- GetSize( w, h );
- float flW = (float)w;
- float flH = (float)h;
-
- float flFOVx = DEG2RAD( m_BMPResData.m_flFOV * 0.5f );
- float flFOVy = CalcFovY( ( m_BMPResData.m_flFOV * 0.5f ), flW/flH );
- flFOVy = DEG2RAD( flFOVy );
-
- float flTanFOVx = tan( flFOVx );
- float flTanFOVy = tan( flFOVy );
-
- // Find the max value of x, y, or z
- Vector2D dist[8];
- float flDist = 0.0f;
- for ( int iPoint = 0; iPoint < 8; ++iPoint )
- {
- float flDistY = fabs( aXFormPoints[iPoint].y / flTanFOVx ) - aXFormPoints[iPoint].x;
- float flDistZ = fabs( aXFormPoints[iPoint].z / flTanFOVy ) - aXFormPoints[iPoint].x;
- dist[iPoint].x = flDistY;
- dist[iPoint].y = flDistZ;
- float flTestDist = MAX( flDistZ, flDistY );
- flDist = MAX( flDist, flTestDist );
- }
-
- // Screen space points.
- Vector2D aScreenPoints[8];
- Vector aCameraPoints[8];
- for ( int iPoint = 0; iPoint < 8; ++iPoint )
- {
- aCameraPoints[iPoint] = aXFormPoints[iPoint];
- aCameraPoints[iPoint].x += flDist;
-
- aScreenPoints[iPoint].x = aCameraPoints[iPoint].y / ( flTanFOVx * aCameraPoints[iPoint].x );
- aScreenPoints[iPoint].y = aCameraPoints[iPoint].z / ( flTanFOVy * aCameraPoints[iPoint].x );
-
- aScreenPoints[iPoint].x = ( aScreenPoints[iPoint].x * 0.5f + 0.5f ) * flW;
- aScreenPoints[iPoint].y = ( aScreenPoints[iPoint].y * 0.5f + 0.5f ) * flH;
- }
-
- // Find the min/max and center of the 2D bounding box of the object.
- Vector2D vecScreenMin( 99999.0f, 99999.0f ), vecScreenMax( -99999.0f, -99999.0f );
- for ( int iPoint = 0; iPoint < 8; ++iPoint )
- {
- vecScreenMin.x = MIN( vecScreenMin.x, aScreenPoints[iPoint].x );
- vecScreenMin.y = MIN( vecScreenMin.y, aScreenPoints[iPoint].y );
- vecScreenMax.x = MAX( vecScreenMax.x, aScreenPoints[iPoint].x );
- vecScreenMax.y = MAX( vecScreenMax.y, aScreenPoints[iPoint].y );
- }
-
- // Offset the model to the be the correct distance away from the camera.
- Vector vecModelPos;
- vecModelPos.x = flDist - vecXFormCenter.x;
- vecModelPos.y = -vecXFormCenter.y;
- vecModelPos.z = -vecXFormCenter.z;
- SetModelAnglesAndPosition( m_BMPResData.m_angModelPoseRot, vecModelPos );
- m_vecPlayerPos = vecModelPos;
-
- // Back project to figure out the camera offset to center the model.
- Vector2D vecPanelCenter( ( flW * 0.5f ), ( flH * 0.5f ) );
- Vector2D vecScreenCenter = ( vecScreenMax + vecScreenMin ) * 0.5f;
-
- Vector2D vecPanelCenterCamera, vecScreenCenterCamera;
- vecPanelCenterCamera.x = ( ( vecPanelCenter.x / flW ) * 2.0f ) - 0.5f;
- vecPanelCenterCamera.y = ( ( vecPanelCenter.y / flH ) * 2.0f ) - 0.5f;
- vecPanelCenterCamera.x *= ( flTanFOVx * flDist );
- vecPanelCenterCamera.y *= ( flTanFOVy * flDist );
- vecScreenCenterCamera.x = ( ( vecScreenCenter.x / flW ) * 2.0f ) - 0.5f;
- vecScreenCenterCamera.y = ( ( vecScreenCenter.y / flH ) * 2.0f ) - 0.5f;
- vecScreenCenterCamera.x *= ( flTanFOVx * flDist );
- vecScreenCenterCamera.y *= ( flTanFOVy * flDist );
-
- Vector2D vecCameraOffset( 0.0f, 0.0f );
- vecCameraOffset.x = vecPanelCenterCamera.x - vecScreenCenterCamera.x;
- vecCameraOffset.y = vecPanelCenterCamera.y - vecScreenCenterCamera.y;
-
- // Clear the camera pivot and set position matrix.
- ResetCameraPivot();
- if (m_bAllowRotation )
- {
- vecCameraOffset.x = 0.0f;
- }
- SetCameraOffset( Vector( 0.0f, -vecCameraOffset.x, -vecCameraOffset.y ) );
- UpdateCameraTransform();
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "cbase.h"
+#include "basemodel_panel.h"
+#include "activitylist.h"
+#include "animation.h"
+#include "vgui/IInput.h"
+#include "matsys_controls/manipulator.h"
+
+using namespace vgui;
+DECLARE_BUILD_FACTORY( CBaseModelPanel );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBaseModelPanel::CBaseModelPanel( vgui::Panel *pParent, const char *pName ): BaseClass( pParent, pName )
+{
+ m_bForcePos = false;
+ m_bMousePressed = false;
+ m_bAllowRotation = false;
+ m_bAllowFullManipulation = false;
+ m_bApplyManipulators = false;
+ m_bForcedCameraPosition = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBaseModelPanel::~CBaseModelPanel()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Load in the model portion of the panel's resource file.
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::ApplySettings( KeyValues *inResourceData )
+{
+ BaseClass::ApplySettings( inResourceData );
+
+ // Set whether we render to texture
+ m_bRenderToTexture = inResourceData->GetBool( "render_texture", true );
+
+ // Grab and set the camera FOV.
+ float flFOV = GetCameraFOV();
+ m_BMPResData.m_flFOV = inResourceData->GetInt( "fov", flFOV );
+ SetCameraFOV( m_BMPResData.m_flFOV );
+
+ // Do we allow rotation on these panels.
+ m_bAllowRotation = inResourceData->GetBool( "allow_rot", false );
+
+ // Do we allow full manipulation on these panels.
+ m_bAllowFullManipulation = inResourceData->GetBool( "allow_manip", false );
+
+ // Parse our resource file and apply all necessary updates to the MDL.
+ for ( KeyValues *pData = inResourceData->GetFirstSubKey() ; pData != NULL ; pData = pData->GetNextKey() )
+ {
+ if ( !Q_stricmp( pData->GetName(), "model" ) )
+ {
+ ParseModelResInfo( pData );
+ }
+ }
+
+ SetMouseInputEnabled( m_bAllowFullManipulation || m_bAllowRotation );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::ParseModelResInfo( KeyValues *inResourceData )
+{
+ m_bForcePos = ( inResourceData->GetInt( "force_pos", 0 ) == 1 );
+ m_BMPResData.m_pszModelName = ReadAndAllocStringValue( inResourceData, "modelname" );
+ m_BMPResData.m_pszModelName_HWM = ReadAndAllocStringValue( inResourceData, "modelname_hwm" );
+ m_BMPResData.m_pszVCD = ReadAndAllocStringValue( inResourceData, "vcd" );
+ m_BMPResData.m_angModelPoseRot.Init( inResourceData->GetFloat( "angles_x", 0.0f ), inResourceData->GetFloat( "angles_y", 0.0f ), inResourceData->GetFloat( "angles_z", 0.0f ) );
+ m_BMPResData.m_vecOriginOffset.Init( inResourceData->GetFloat( "origin_x", 110.0 ), inResourceData->GetFloat( "origin_y", 5.0 ), inResourceData->GetFloat( "origin_z", 5.0 ) );
+ m_BMPResData.m_vecFramedOriginOffset.Init( inResourceData->GetFloat( "frame_origin_x", 110.0 ), inResourceData->GetFloat( "frame_origin_y", 5.0 ), inResourceData->GetFloat( "frame_origin_z", 5.0 ) );
+ m_BMPResData.m_vecViewportOffset.Init();
+ m_BMPResData.m_nSkin = inResourceData->GetInt( "skin", -1 );
+ m_BMPResData.m_bUseSpotlight = ( inResourceData->GetInt( "spotlight", 0 ) == 1 );
+
+ m_angPlayer = m_BMPResData.m_angModelPoseRot;
+ m_vecPlayerPos = m_BMPResData.m_vecOriginOffset;
+
+ for ( KeyValues *pData = inResourceData->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
+ {
+ if ( !Q_stricmp( pData->GetName(), "animation" ) )
+ {
+ ParseModelAnimInfo( pData );
+ }
+ else if ( !Q_stricmp( pData->GetName(), "attached_model" ) )
+ {
+ ParseModelAttachInfo( pData );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::ParseModelAnimInfo( KeyValues *inResourceData )
+{
+ if ( !inResourceData )
+ return;
+
+ int iAnim = m_BMPResData.m_aAnimations.AddToTail();
+ if ( iAnim == m_BMPResData.m_aAnimations.InvalidIndex() )
+ return;
+
+ m_BMPResData.m_aAnimations[iAnim].m_pszName = ReadAndAllocStringValue( inResourceData, "name" );
+ m_BMPResData.m_aAnimations[iAnim].m_pszSequence = ReadAndAllocStringValue( inResourceData, "sequence" );
+ m_BMPResData.m_aAnimations[iAnim].m_pszActivity = ReadAndAllocStringValue( inResourceData, "activity" );
+ m_BMPResData.m_aAnimations[iAnim].m_bDefault = ( inResourceData->GetInt( "default", 0 ) == 1 );
+
+ for ( KeyValues *pAnimData = inResourceData->GetFirstSubKey(); pAnimData != NULL; pAnimData = pAnimData->GetNextKey() )
+ {
+ if ( !Q_stricmp( pAnimData->GetName(), "pose_parameters" ) )
+ {
+ m_BMPResData.m_aAnimations[iAnim].m_pPoseParameters = pAnimData->MakeCopy();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::ParseModelAttachInfo( KeyValues *inResourceData )
+{
+ if ( !inResourceData )
+ return;
+
+ int iAttach = m_BMPResData.m_aAttachModels.AddToTail();
+ if ( iAttach == m_BMPResData.m_aAttachModels.InvalidIndex() )
+ return;
+
+ m_BMPResData.m_aAttachModels[iAttach].m_pszModelName = ReadAndAllocStringValue( inResourceData, "modelname" );
+ m_BMPResData.m_aAttachModels[iAttach].m_nSkin = inResourceData->GetInt( "skin", -1 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::SetupModelDefaults( void )
+{
+ SetupModelAnimDefaults();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::SetupModelAnimDefaults( void )
+{
+ // Set the move_x parameter so the run activity works
+ SetPoseParameterByName( "move_x", 1.0f );
+
+ // Verify that we have animations for this model.
+ int nAnimCount = m_BMPResData.m_aAnimations.Count();
+ if ( nAnimCount == 0 )
+ return;
+
+ // Find the default animation if one exists.
+ int iIndex = FindDefaultAnim();
+ if ( iIndex == -1 )
+ return;
+
+ SetModelAnim( iIndex );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CBaseModelPanel::FindDefaultAnim( void )
+{
+ int iIndex = -1;
+
+ int nAnimCount = m_BMPResData.m_aAnimations.Count();
+ for ( int iAnim = 0; iAnim < nAnimCount; ++iAnim )
+ {
+ if ( m_BMPResData.m_aAnimations[iAnim].m_bDefault )
+ return iAnim;
+ }
+
+ return iIndex;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CBaseModelPanel::FindAnimByName( const char *pszName )
+{
+ int iIndex = -1;
+ if ( !pszName )
+ return iIndex;
+
+ int nAnimCount = m_BMPResData.m_aAnimations.Count();
+ for ( int iAnim = 0; iAnim < nAnimCount; ++iAnim )
+ {
+ if ( !Q_stricmp( m_BMPResData.m_aAnimations[iAnim].m_pszName, pszName ) )
+ return iAnim;
+ }
+
+ return iIndex;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CBaseModelPanel::FindSequenceFromActivity( CStudioHdr *pStudioHdr, const char *pszActivity )
+{
+ if ( !pStudioHdr )
+ return -1;
+
+ for ( int iSeq = 0; iSeq < pStudioHdr->GetNumSeq(); ++iSeq )
+ {
+ mstudioseqdesc_t &seqDesc = pStudioHdr->pSeqdesc( iSeq );
+ if ( !V_stricmp( seqDesc.pszActivityName(), pszActivity ) )
+ {
+ return iSeq;
+ }
+ }
+
+ return -1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::SetModelAnim( int iAnim )
+{
+ int nAnimCount = m_BMPResData.m_aAnimations.Count();
+ if ( nAnimCount == 0 || !m_BMPResData.m_aAnimations.IsValidIndex( iAnim ) )
+ return;
+
+ MDLCACHE_CRITICAL_SECTION();
+
+ // Get the studio header of the root model.
+ studiohdr_t *pStudioHdr = m_RootMDL.m_MDL.GetStudioHdr();
+ if ( !pStudioHdr )
+ return;
+
+ CStudioHdr studioHdr( pStudioHdr, g_pMDLCache );
+
+ // Do we have an activity or a sequence?
+ int iSequence = ACT_INVALID;
+ if ( m_BMPResData.m_aAnimations[iAnim].m_pszActivity && m_BMPResData.m_aAnimations[iAnim].m_pszActivity[0] )
+ {
+ iSequence = FindSequenceFromActivity( &studioHdr, m_BMPResData.m_aAnimations[iAnim].m_pszActivity );
+ }
+ else if ( m_BMPResData.m_aAnimations[iAnim].m_pszSequence && m_BMPResData.m_aAnimations[iAnim].m_pszSequence[0] )
+ {
+ iSequence = LookupSequence( &studioHdr, m_BMPResData.m_aAnimations[iAnim].m_pszSequence );
+ }
+
+ if ( iSequence != ACT_INVALID )
+ {
+ SetSequence( iSequence );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::SetMDL( MDLHandle_t handle, void *pProxyData )
+{
+ MDLCACHE_CRITICAL_SECTION();
+ studiohdr_t *pHdr = g_pMDLCache->GetStudioHdr( handle );
+
+ if ( pHdr )
+ {
+ // SetMDL will cause the base CMdl code to set our localtoglobal indices if they aren't set.
+ // We set them up here so that they're left alone by that code.
+ CStudioHdr studioHdr( pHdr, g_pMDLCache );
+ if (studioHdr.numflexcontrollers() > 0 && studioHdr.pFlexcontroller( LocalFlexController_t(0) )->localToGlobal == -1)
+ {
+ for (LocalFlexController_t i = LocalFlexController_t(0); i < studioHdr.numflexcontrollers(); i++)
+ {
+ int j = C_BaseFlex::AddGlobalFlexController( studioHdr.pFlexcontroller( i )->pszName() );
+ studioHdr.pFlexcontroller( i )->localToGlobal = j;
+ }
+ }
+ }
+ else
+ {
+ handle = MDLHANDLE_INVALID;
+ }
+
+ // Clear our current sequence
+ SetSequence( ACT_IDLE );
+
+ BaseClass::SetMDL( handle, pProxyData );
+
+ SetupModelDefaults();
+
+ // Need to invalidate the layout so the panel will adjust is LookAt for the new model.
+ InvalidateLayout();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::SetModelAnglesAndPosition( const QAngle &angRot, const Vector &vecPos )
+{
+ BaseClass::SetModelAnglesAndPosition( angRot, vecPos );
+
+ // Cache
+ m_vecPlayerPos = vecPos;
+ m_angPlayer = angRot;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::SetMDL( const char *pMDLName, void *pProxyData )
+{
+ BaseClass::SetMDL( pMDLName, pProxyData );
+
+ // Need to invalidate the layout so the panel will adjust is LookAt for the new model.
+// InvalidateLayout();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::PerformLayout()
+{
+ BaseClass::PerformLayout();
+
+ if ( m_bForcedCameraPosition )
+ {
+ return;
+ }
+
+ if ( m_bAllowFullManipulation )
+ {
+ // Set this to true if you want to keep the current rotation when changing models or poses
+ const bool bPreserveManipulation = false;
+
+ // Need to look at the target so we can rotate around it
+ const Vector kVecFocalPoint( 0.0f, 0.0f, 60.0f );
+ ResetCameraPivot();
+ SetCameraOffset( -(m_vecPlayerPos + kVecFocalPoint) );
+ SetCameraPositionAndAngles( kVecFocalPoint, vec3_angle, !bPreserveManipulation );
+
+ // We want to move the player to the origin and facing the correct way,
+ // but don't clobber m_angPlayer and m_vecPlayerPos, so use BaseClass.
+ BaseClass::SetModelAnglesAndPosition( m_angPlayer, vec3_origin );
+
+ // Once a manual transform has been done we want to apply it
+ if ( m_bApplyManipulators )
+ {
+ ApplyManipulation();
+ }
+ else
+ {
+ SyncManipulation();
+ }
+ return;
+ }
+
+ if ( m_bForcePos )
+ {
+ ResetCameraPivot();
+ SetCameraOffset( Vector( 0.0f, 0.0f, 0.0f ) );
+ SetCameraPositionAndAngles( vec3_origin, vec3_angle );
+ SetModelAnglesAndPosition( m_angPlayer, m_vecPlayerPos );
+ }
+
+ // Center and fill the frame with the model?
+ if ( m_bStartFramed )
+ {
+ Vector vecBoundsMin, vecBoundsMax;
+ if ( GetBoundingBox( vecBoundsMin, vecBoundsMax ) )
+ {
+ LookAtBounds( vecBoundsMin, vecBoundsMax );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::OnKeyCodePressed ( vgui::KeyCode code )
+{
+ if ( m_bAllowFullManipulation )
+ {
+ BaseClass::OnKeyCodePressed( code );
+ return;
+ }
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::OnKeyCodeReleased( vgui::KeyCode code )
+{
+ if ( m_bAllowFullManipulation )
+ {
+ BaseClass::OnKeyCodeReleased( code );
+ return;
+ }
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::OnMousePressed ( vgui::MouseCode code )
+{
+ if ( m_bAllowFullManipulation )
+ {
+ BaseClass::OnMousePressed( code );
+ return;
+ }
+
+ if ( !m_bAllowRotation )
+ return;
+
+ RequestFocus();
+
+ EnableMouseCapture( true, code );
+
+ // Warp the mouse to the center of the screen
+ int width, height;
+ GetSize( width, height );
+ int x = width / 2;
+ int y = height / 2;
+
+ int xpos = x;
+ int ypos = y;
+ LocalToScreen( xpos, ypos );
+ input()->SetCursorPos( xpos, ypos );
+
+ m_nManipStartX = xpos;
+ m_nManipStartY = ypos;
+
+ m_bMousePressed = true;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::OnMouseReleased( vgui::MouseCode code )
+{
+ if ( m_bAllowFullManipulation )
+ {
+ BaseClass::OnMouseReleased( code );
+ return;
+ }
+
+ if ( !m_bAllowRotation )
+ return;
+
+ EnableMouseCapture( false );
+ m_bMousePressed = false;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::OnCursorMoved( int x, int y )
+{
+ if ( m_bAllowFullManipulation )
+ {
+ if ( m_pCurrentManip )
+ {
+ m_bApplyManipulators = true;
+ }
+ BaseClass::OnCursorMoved( x, y );
+ return;
+ }
+
+ if ( !m_bAllowRotation )
+ return;
+
+ if ( m_bMousePressed )
+ {
+ WarpMouse( x, y );
+ int xpos, ypos;
+ input()->GetCursorPos( xpos, ypos );
+
+ // Only want the x delta.
+ float flDelta = xpos - m_nManipStartX;
+
+ // Apply the delta and rotate the player.
+ RotateYaw( flDelta );
+ }
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::RotateYaw( float flDelta )
+{
+ m_angPlayer.y += flDelta;
+ if ( m_angPlayer.y > 360.0f )
+ {
+ m_angPlayer.y = m_angPlayer.y - 360.0f;
+ }
+ else if ( m_angPlayer.y < -360.0f )
+ {
+ m_angPlayer.y = m_angPlayer.y + 360.0f;
+ }
+
+ SetModelAnglesAndPosition( m_angPlayer, m_vecPlayerPos );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+Vector CBaseModelPanel::GetPlayerPos() const
+{
+ return m_vecPlayerPos;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+QAngle CBaseModelPanel::GetPlayerAngles() const
+{
+ return m_angPlayer;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::OnMouseWheeled( int delta )
+{
+ if ( m_bAllowFullManipulation )
+ {
+ BaseClass::OnMouseWheeled( delta );
+ return;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Set the camera to a distance that allows the object to fill the model panel.
+//-----------------------------------------------------------------------------
+void CBaseModelPanel::LookAtBounds( const Vector &vecBoundsMin, const Vector &vecBoundsMax )
+{
+ // Get the model space render bounds.
+ Vector vecMin = vecBoundsMin;
+ Vector vecMax = vecBoundsMax;
+ Vector vecCenter = ( vecMax + vecMin ) * 0.5f;
+ vecMin -= vecCenter;
+ vecMax -= vecCenter;
+
+ // Get the bounds points and transform them by the desired model panel rotation.
+ Vector aBoundsPoints[8];
+ aBoundsPoints[0].Init( vecMax.x, vecMax.y, vecMax.z );
+ aBoundsPoints[1].Init( vecMin.x, vecMax.y, vecMax.z );
+ aBoundsPoints[2].Init( vecMax.x, vecMin.y, vecMax.z );
+ aBoundsPoints[3].Init( vecMin.x, vecMin.y, vecMax.z );
+ aBoundsPoints[4].Init( vecMax.x, vecMax.y, vecMin.z );
+ aBoundsPoints[5].Init( vecMin.x, vecMax.y, vecMin.z );
+ aBoundsPoints[6].Init( vecMax.x, vecMin.y, vecMin.z );
+ aBoundsPoints[7].Init( vecMin.x, vecMin.y, vecMin.z );
+
+ // Translated center point (offset from camera center).
+ Vector vecTranslateCenter = -vecCenter;
+
+ // Build the rotation matrix.
+ matrix3x4_t matRotation;
+ AngleMatrix( m_BMPResData.m_angModelPoseRot, matRotation );
+
+ Vector aXFormPoints[8];
+ for ( int iPoint = 0; iPoint < 8; ++iPoint )
+ {
+ VectorTransform( aBoundsPoints[iPoint], matRotation, aXFormPoints[iPoint] );
+ }
+
+ Vector vecXFormCenter;
+ VectorTransform( -vecTranslateCenter, matRotation, vecXFormCenter );
+
+ int w, h;
+ GetSize( w, h );
+ float flW = (float)w;
+ float flH = (float)h;
+
+ float flFOVx = DEG2RAD( m_BMPResData.m_flFOV * 0.5f );
+ float flFOVy = CalcFovY( ( m_BMPResData.m_flFOV * 0.5f ), flW/flH );
+ flFOVy = DEG2RAD( flFOVy );
+
+ float flTanFOVx = tan( flFOVx );
+ float flTanFOVy = tan( flFOVy );
+
+ // Find the max value of x, y, or z
+ Vector2D dist[8];
+ float flDist = 0.0f;
+ for ( int iPoint = 0; iPoint < 8; ++iPoint )
+ {
+ float flDistY = fabs( aXFormPoints[iPoint].y / flTanFOVx ) - aXFormPoints[iPoint].x;
+ float flDistZ = fabs( aXFormPoints[iPoint].z / flTanFOVy ) - aXFormPoints[iPoint].x;
+ dist[iPoint].x = flDistY;
+ dist[iPoint].y = flDistZ;
+ float flTestDist = MAX( flDistZ, flDistY );
+ flDist = MAX( flDist, flTestDist );
+ }
+
+ // Screen space points.
+ Vector2D aScreenPoints[8];
+ Vector aCameraPoints[8];
+ for ( int iPoint = 0; iPoint < 8; ++iPoint )
+ {
+ aCameraPoints[iPoint] = aXFormPoints[iPoint];
+ aCameraPoints[iPoint].x += flDist;
+
+ aScreenPoints[iPoint].x = aCameraPoints[iPoint].y / ( flTanFOVx * aCameraPoints[iPoint].x );
+ aScreenPoints[iPoint].y = aCameraPoints[iPoint].z / ( flTanFOVy * aCameraPoints[iPoint].x );
+
+ aScreenPoints[iPoint].x = ( aScreenPoints[iPoint].x * 0.5f + 0.5f ) * flW;
+ aScreenPoints[iPoint].y = ( aScreenPoints[iPoint].y * 0.5f + 0.5f ) * flH;
+ }
+
+ // Find the min/max and center of the 2D bounding box of the object.
+ Vector2D vecScreenMin( 99999.0f, 99999.0f ), vecScreenMax( -99999.0f, -99999.0f );
+ for ( int iPoint = 0; iPoint < 8; ++iPoint )
+ {
+ vecScreenMin.x = MIN( vecScreenMin.x, aScreenPoints[iPoint].x );
+ vecScreenMin.y = MIN( vecScreenMin.y, aScreenPoints[iPoint].y );
+ vecScreenMax.x = MAX( vecScreenMax.x, aScreenPoints[iPoint].x );
+ vecScreenMax.y = MAX( vecScreenMax.y, aScreenPoints[iPoint].y );
+ }
+
+ // Offset the model to the be the correct distance away from the camera.
+ Vector vecModelPos;
+ vecModelPos.x = flDist - vecXFormCenter.x;
+ vecModelPos.y = -vecXFormCenter.y;
+ vecModelPos.z = -vecXFormCenter.z;
+ SetModelAnglesAndPosition( m_BMPResData.m_angModelPoseRot, vecModelPos );
+ m_vecPlayerPos = vecModelPos;
+
+ // Back project to figure out the camera offset to center the model.
+ Vector2D vecPanelCenter( ( flW * 0.5f ), ( flH * 0.5f ) );
+ Vector2D vecScreenCenter = ( vecScreenMax + vecScreenMin ) * 0.5f;
+
+ Vector2D vecPanelCenterCamera, vecScreenCenterCamera;
+ vecPanelCenterCamera.x = ( ( vecPanelCenter.x / flW ) * 2.0f ) - 0.5f;
+ vecPanelCenterCamera.y = ( ( vecPanelCenter.y / flH ) * 2.0f ) - 0.5f;
+ vecPanelCenterCamera.x *= ( flTanFOVx * flDist );
+ vecPanelCenterCamera.y *= ( flTanFOVy * flDist );
+ vecScreenCenterCamera.x = ( ( vecScreenCenter.x / flW ) * 2.0f ) - 0.5f;
+ vecScreenCenterCamera.y = ( ( vecScreenCenter.y / flH ) * 2.0f ) - 0.5f;
+ vecScreenCenterCamera.x *= ( flTanFOVx * flDist );
+ vecScreenCenterCamera.y *= ( flTanFOVy * flDist );
+
+ Vector2D vecCameraOffset( 0.0f, 0.0f );
+ vecCameraOffset.x = vecPanelCenterCamera.x - vecScreenCenterCamera.x;
+ vecCameraOffset.y = vecPanelCenterCamera.y - vecScreenCenterCamera.y;
+
+ // Clear the camera pivot and set position matrix.
+ ResetCameraPivot();
+ if (m_bAllowRotation )
+ {
+ vecCameraOffset.x = 0.0f;
+ }
+ SetCameraOffset( Vector( 0.0f, -vecCameraOffset.x, -vecCameraOffset.y ) );
+ UpdateCameraTransform();
+}
+
diff --git a/mp/src/game/client/game_controls/basemodel_panel.h b/mp/src/game/client/game_controls/basemodel_panel.h
index 1ac498f2..b9fa0d68 100644
--- a/mp/src/game/client/game_controls/basemodel_panel.h
+++ b/mp/src/game/client/game_controls/basemodel_panel.h
@@ -1,225 +1,225 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-#ifndef BASEMODEL_PANEL_H
-#define BASEMODEL_PANEL_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "matsys_controls/mdlpanel.h"
-
-//-----------------------------------------------------------------------------
-// Resource file data used in posing the model inside of the model panel.
-//-----------------------------------------------------------------------------
-struct BMPResAnimData_t
-{
- const char *m_pszName;
- const char *m_pszSequence;
- const char *m_pszActivity;
- KeyValues *m_pPoseParameters;
- bool m_bDefault;
-
- BMPResAnimData_t()
- {
- m_pszName = NULL;
- m_pszSequence = NULL;
- m_pszActivity = NULL;
- m_pPoseParameters = NULL;
- m_bDefault = false;
- }
-
- ~BMPResAnimData_t()
- {
- if ( m_pszName && m_pszName[0] )
- {
- delete [] m_pszName;
- m_pszName = NULL;
- }
-
- if ( m_pszSequence && m_pszSequence[0] )
- {
- delete [] m_pszSequence;
- m_pszSequence = NULL;
- }
-
- if ( m_pszActivity && m_pszActivity[0] )
- {
- delete [] m_pszActivity;
- m_pszActivity = NULL;
- }
-
- if ( m_pPoseParameters )
- {
- m_pPoseParameters->deleteThis();
- m_pPoseParameters = NULL;
- }
- }
-};
-
-struct BMPResAttachData_t
-{
- const char *m_pszModelName;
- int m_nSkin;
-
- BMPResAttachData_t()
- {
- m_pszModelName = NULL;
- m_nSkin = 0;
- }
-
- ~BMPResAttachData_t()
- {
- if ( m_pszModelName && m_pszModelName[0] )
- {
- delete [] m_pszModelName;
- m_pszModelName = NULL;
- }
- }
-};
-
-struct BMPResData_t
-{
- float m_flFOV;
-
- const char *m_pszModelName;
- const char *m_pszModelName_HWM;
- const char *m_pszVCD;
- QAngle m_angModelPoseRot;
- Vector m_vecOriginOffset;
- Vector m_vecFramedOriginOffset;
- Vector2D m_vecViewportOffset;
- int m_nSkin;
- bool m_bUseSpotlight;
-
- CUtlVector<BMPResAnimData_t> m_aAnimations;
- CUtlVector<BMPResAttachData_t> m_aAttachModels;
-
- BMPResData_t()
- {
- m_flFOV = 0.0f;
-
- m_pszModelName = NULL;
- m_pszModelName_HWM = NULL;
- m_pszVCD = NULL;
- m_angModelPoseRot.Init();
- m_vecOriginOffset.Init();
- m_vecFramedOriginOffset.Init();
- m_vecViewportOffset.Init();
- m_nSkin = 0;
- m_bUseSpotlight = false;
- }
-
- ~BMPResData_t()
- {
- if ( m_pszModelName && m_pszModelName[0] )
- {
- delete [] m_pszModelName;
- m_pszModelName = NULL;
- }
-
- if ( m_pszModelName_HWM && m_pszModelName_HWM[0] )
- {
- delete [] m_pszModelName_HWM;
- m_pszModelName_HWM = NULL;
- }
-
- if ( m_pszVCD && m_pszVCD[0] )
- {
- delete [] m_pszVCD;
- m_pszVCD = NULL;
- }
-
- m_aAnimations.Purge();
- m_aAttachModels.Purge();
- }
-};
-
-//-----------------------------------------------------------------------------
-// Base Model Panel
-//
-// ...vgui::Panel |--> vgui
-// +->vgui::EditablePanel |
-// +->PotterWheelPanel |--> matsys_controls
-// +->MDLPanel |
-// +->BaseModelPanel |--> game_controls, client.dll
-//
-//-----------------------------------------------------------------------------
-class CBaseModelPanel : public CMDLPanel
-{
- DECLARE_CLASS_SIMPLE( CBaseModelPanel, CMDLPanel );
-
-public:
-
- // Constructor, Destructor.
- CBaseModelPanel( vgui::Panel *pParent, const char *pName );
- virtual ~CBaseModelPanel();
-
- // Overridden mdlpanel.h
- virtual void SetMDL( MDLHandle_t handle, void *pProxyData = NULL );
- virtual void SetMDL( const char *pMDLName, void *pProxyData = NULL );
- virtual void SetModelAnglesAndPosition( const QAngle &angRot, const Vector &vecPos );
-
- // Overridden methods of vgui::Panel
- virtual void ApplySettings( KeyValues *inResourceData );
- virtual void PerformLayout();
-
- // Animation.
- int FindDefaultAnim( void );
- int FindAnimByName( const char *pszName );
- void SetModelAnim( int iAnim );
-
- // Manipulation.
- virtual void OnKeyCodePressed ( vgui::KeyCode code );
- virtual void OnKeyCodeReleased( vgui::KeyCode code );
- virtual void OnMousePressed ( vgui::MouseCode code );
- virtual void OnMouseReleased( vgui::MouseCode code );
- virtual void OnCursorMoved( int x, int y );
- virtual void OnMouseWheeled( int delta );
-
- studiohdr_t* GetStudioHdr( void ) { return m_RootMDL.m_MDL.GetStudioHdr(); }
- void SetBody( unsigned int nBody ) { m_RootMDL.m_MDL.m_nBody = nBody; }
-
- void RotateYaw( float flDelta );
-
- Vector GetPlayerPos() const;
- QAngle GetPlayerAngles() const;
-
- void LookAtBounds( const Vector &vecBoundsMin, const Vector &vecBoundsMax );
-
- // Set to true if external code has set a specific camera position that shouldn't be clobbered by layout
- void SetForcedCameraPosition( bool bForcedCameraPosition ) { m_bForcedCameraPosition = bForcedCameraPosition; }
-
- int FindSequenceFromActivity( CStudioHdr *pStudioHdr, const char *pszActivity );
-
-protected:
-
- // Resource file data.
- void ParseModelResInfo( KeyValues *inResourceData );
- void ParseModelAnimInfo( KeyValues *inResourceData );
- void ParseModelAttachInfo( KeyValues *inResourceData );
-
- void SetupModelDefaults( void );
- void SetupModelAnimDefaults( void );
-
-public:
- BMPResData_t m_BMPResData; // Base model panel data set in the .res file.
- QAngle m_angPlayer;
- Vector m_vecPlayerPos;
-
-protected:
- bool m_bForcePos;
- bool m_bMousePressed;
- bool m_bAllowRotation;
- bool m_bAllowFullManipulation;
- bool m_bApplyManipulators;
- bool m_bForcedCameraPosition;
-
- // VGUI script accessible variables.
- CPanelAnimationVar( bool, m_bStartFramed, "start_framed", "0" );
- CPanelAnimationVar( bool, m_bDisableManipulation, "disable_manipulation", "0" );
-};
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+#ifndef BASEMODEL_PANEL_H
+#define BASEMODEL_PANEL_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "matsys_controls/mdlpanel.h"
+
+//-----------------------------------------------------------------------------
+// Resource file data used in posing the model inside of the model panel.
+//-----------------------------------------------------------------------------
+struct BMPResAnimData_t
+{
+ const char *m_pszName;
+ const char *m_pszSequence;
+ const char *m_pszActivity;
+ KeyValues *m_pPoseParameters;
+ bool m_bDefault;
+
+ BMPResAnimData_t()
+ {
+ m_pszName = NULL;
+ m_pszSequence = NULL;
+ m_pszActivity = NULL;
+ m_pPoseParameters = NULL;
+ m_bDefault = false;
+ }
+
+ ~BMPResAnimData_t()
+ {
+ if ( m_pszName && m_pszName[0] )
+ {
+ delete [] m_pszName;
+ m_pszName = NULL;
+ }
+
+ if ( m_pszSequence && m_pszSequence[0] )
+ {
+ delete [] m_pszSequence;
+ m_pszSequence = NULL;
+ }
+
+ if ( m_pszActivity && m_pszActivity[0] )
+ {
+ delete [] m_pszActivity;
+ m_pszActivity = NULL;
+ }
+
+ if ( m_pPoseParameters )
+ {
+ m_pPoseParameters->deleteThis();
+ m_pPoseParameters = NULL;
+ }
+ }
+};
+
+struct BMPResAttachData_t
+{
+ const char *m_pszModelName;
+ int m_nSkin;
+
+ BMPResAttachData_t()
+ {
+ m_pszModelName = NULL;
+ m_nSkin = 0;
+ }
+
+ ~BMPResAttachData_t()
+ {
+ if ( m_pszModelName && m_pszModelName[0] )
+ {
+ delete [] m_pszModelName;
+ m_pszModelName = NULL;
+ }
+ }
+};
+
+struct BMPResData_t
+{
+ float m_flFOV;
+
+ const char *m_pszModelName;
+ const char *m_pszModelName_HWM;
+ const char *m_pszVCD;
+ QAngle m_angModelPoseRot;
+ Vector m_vecOriginOffset;
+ Vector m_vecFramedOriginOffset;
+ Vector2D m_vecViewportOffset;
+ int m_nSkin;
+ bool m_bUseSpotlight;
+
+ CUtlVector<BMPResAnimData_t> m_aAnimations;
+ CUtlVector<BMPResAttachData_t> m_aAttachModels;
+
+ BMPResData_t()
+ {
+ m_flFOV = 0.0f;
+
+ m_pszModelName = NULL;
+ m_pszModelName_HWM = NULL;
+ m_pszVCD = NULL;
+ m_angModelPoseRot.Init();
+ m_vecOriginOffset.Init();
+ m_vecFramedOriginOffset.Init();
+ m_vecViewportOffset.Init();
+ m_nSkin = 0;
+ m_bUseSpotlight = false;
+ }
+
+ ~BMPResData_t()
+ {
+ if ( m_pszModelName && m_pszModelName[0] )
+ {
+ delete [] m_pszModelName;
+ m_pszModelName = NULL;
+ }
+
+ if ( m_pszModelName_HWM && m_pszModelName_HWM[0] )
+ {
+ delete [] m_pszModelName_HWM;
+ m_pszModelName_HWM = NULL;
+ }
+
+ if ( m_pszVCD && m_pszVCD[0] )
+ {
+ delete [] m_pszVCD;
+ m_pszVCD = NULL;
+ }
+
+ m_aAnimations.Purge();
+ m_aAttachModels.Purge();
+ }
+};
+
+//-----------------------------------------------------------------------------
+// Base Model Panel
+//
+// ...vgui::Panel |--> vgui
+// +->vgui::EditablePanel |
+// +->PotterWheelPanel |--> matsys_controls
+// +->MDLPanel |
+// +->BaseModelPanel |--> game_controls, client.dll
+//
+//-----------------------------------------------------------------------------
+class CBaseModelPanel : public CMDLPanel
+{
+ DECLARE_CLASS_SIMPLE( CBaseModelPanel, CMDLPanel );
+
+public:
+
+ // Constructor, Destructor.
+ CBaseModelPanel( vgui::Panel *pParent, const char *pName );
+ virtual ~CBaseModelPanel();
+
+ // Overridden mdlpanel.h
+ virtual void SetMDL( MDLHandle_t handle, void *pProxyData = NULL );
+ virtual void SetMDL( const char *pMDLName, void *pProxyData = NULL );
+ virtual void SetModelAnglesAndPosition( const QAngle &angRot, const Vector &vecPos );
+
+ // Overridden methods of vgui::Panel
+ virtual void ApplySettings( KeyValues *inResourceData );
+ virtual void PerformLayout();
+
+ // Animation.
+ int FindDefaultAnim( void );
+ int FindAnimByName( const char *pszName );
+ void SetModelAnim( int iAnim );
+
+ // Manipulation.
+ virtual void OnKeyCodePressed ( vgui::KeyCode code );
+ virtual void OnKeyCodeReleased( vgui::KeyCode code );
+ virtual void OnMousePressed ( vgui::MouseCode code );
+ virtual void OnMouseReleased( vgui::MouseCode code );
+ virtual void OnCursorMoved( int x, int y );
+ virtual void OnMouseWheeled( int delta );
+
+ studiohdr_t* GetStudioHdr( void ) { return m_RootMDL.m_MDL.GetStudioHdr(); }
+ void SetBody( unsigned int nBody ) { m_RootMDL.m_MDL.m_nBody = nBody; }
+
+ void RotateYaw( float flDelta );
+
+ Vector GetPlayerPos() const;
+ QAngle GetPlayerAngles() const;
+
+ void LookAtBounds( const Vector &vecBoundsMin, const Vector &vecBoundsMax );
+
+ // Set to true if external code has set a specific camera position that shouldn't be clobbered by layout
+ void SetForcedCameraPosition( bool bForcedCameraPosition ) { m_bForcedCameraPosition = bForcedCameraPosition; }
+
+ int FindSequenceFromActivity( CStudioHdr *pStudioHdr, const char *pszActivity );
+
+protected:
+
+ // Resource file data.
+ void ParseModelResInfo( KeyValues *inResourceData );
+ void ParseModelAnimInfo( KeyValues *inResourceData );
+ void ParseModelAttachInfo( KeyValues *inResourceData );
+
+ void SetupModelDefaults( void );
+ void SetupModelAnimDefaults( void );
+
+public:
+ BMPResData_t m_BMPResData; // Base model panel data set in the .res file.
+ QAngle m_angPlayer;
+ Vector m_vecPlayerPos;
+
+protected:
+ bool m_bForcePos;
+ bool m_bMousePressed;
+ bool m_bAllowRotation;
+ bool m_bAllowFullManipulation;
+ bool m_bApplyManipulators;
+ bool m_bForcedCameraPosition;
+
+ // VGUI script accessible variables.
+ CPanelAnimationVar( bool, m_bStartFramed, "start_framed", "0" );
+ CPanelAnimationVar( bool, m_bDisableManipulation, "disable_manipulation", "0" );
+};
+
#endif // BASEMODEL_PANEL_H \ No newline at end of file
diff --git a/mp/src/game/client/game_controls/basemodelpanel.cpp b/mp/src/game/client/game_controls/basemodelpanel.cpp
index 1c369d16..95008b4d 100644
--- a/mp/src/game/client/game_controls/basemodelpanel.cpp
+++ b/mp/src/game/client/game_controls/basemodelpanel.cpp
@@ -1,898 +1,898 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-
-#include "cbase.h"
-#include <KeyValues.h>
-#include <vgui/ISurface.h>
-#include <vgui/ISystem.h>
-#include <vgui/IScheme.h>
-#include <vgui_controls/AnimationController.h>
-#include <vgui_controls/EditablePanel.h>
-#include <vgui_controls/ImagePanel.h>
-#include <vgui/ISurface.h>
-#include <vgui/IImage.h>
-#include <vgui_controls/Label.h>
-
-#include "materialsystem/imaterialsystem.h"
-#include "engine/ivmodelinfo.h"
-
-#include "c_sceneentity.h"
-#include "gamestringpool.h"
-#include "model_types.h"
-#include "view_shared.h"
-#include "view.h"
-#include "ivrenderview.h"
-#include "iefx.h"
-#include "dlight.h"
-#include "activitylist.h"
-
-#include "basemodelpanel.h"
-
-bool UseHWMorphModels();
-
-
-using namespace vgui;
-
-DECLARE_BUILD_FACTORY( CModelPanel );
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CModelPanel::CModelPanel( vgui::Panel *pParent, const char *pName ) : vgui::EditablePanel( pParent, pName )
-{
- m_nFOV = 54;
- m_hModel = NULL;
- m_pModelInfo = NULL;
- m_hScene = NULL;
- m_iDefaultAnimation = 0;
- m_bPanelDirty = true;
- m_bStartFramed = false;
- m_bAllowOffscreen = false;
-
- ListenForGameEvent( "game_newmap" );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CModelPanel::~CModelPanel()
-{
- if ( m_pModelInfo )
- {
- delete m_pModelInfo;
- m_pModelInfo = NULL;
- }
-
- DeleteVCDData();
- DeleteModelData();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::ApplySettings( KeyValues *inResourceData )
-{
- BaseClass::ApplySettings( inResourceData );
-
- m_nFOV = inResourceData->GetInt( "fov", 54 );
- m_bStartFramed = inResourceData->GetInt( "start_framed", false );
- m_bAllowOffscreen = inResourceData->GetInt( "allow_offscreen", false );
-
- // do we have a valid "model" section in the .res file?
- for ( KeyValues *pData = inResourceData->GetFirstSubKey() ; pData != NULL ; pData = pData->GetNextKey() )
- {
- if ( !Q_stricmp( pData->GetName(), "model" ) )
- {
- ParseModelInfo( pData );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::ParseModelInfo( KeyValues *inResourceData )
-{
- // delete any current info
- if ( m_pModelInfo )
- {
- delete m_pModelInfo;
- m_pModelInfo = NULL;
- }
-
- m_pModelInfo = new CModelPanelModelInfo;
-
- if ( !m_pModelInfo )
- return;
-
- m_pModelInfo->m_pszModelName = ReadAndAllocStringValue( inResourceData, "modelname" );
- m_pModelInfo->m_pszModelName_HWM = ReadAndAllocStringValue( inResourceData, "modelname_hwm" );
- m_pModelInfo->m_nSkin = inResourceData->GetInt( "skin", -1 );
- m_pModelInfo->m_vecAbsAngles.Init( inResourceData->GetFloat( "angles_x", 0.0 ), inResourceData->GetFloat( "angles_y", 0.0 ), inResourceData->GetFloat( "angles_z", 0.0 ) );
- m_pModelInfo->m_vecOriginOffset.Init( inResourceData->GetFloat( "origin_x", 110.0 ), inResourceData->GetFloat( "origin_y", 5.0 ), inResourceData->GetFloat( "origin_z", 5.0 ) );
- m_pModelInfo->m_vecFramedOriginOffset.Init( inResourceData->GetFloat( "frame_origin_x", 110.0 ), inResourceData->GetFloat( "frame_origin_y", 5.0 ), inResourceData->GetFloat( "frame_origin_z", 5.0 ) );
- m_pModelInfo->m_pszVCD = ReadAndAllocStringValue( inResourceData, "vcd" );
- m_pModelInfo->m_bUseSpotlight = ( inResourceData->GetInt( "spotlight", 0 ) == 1 );
- m_pModelInfo->m_vecViewportOffset.Init();
-
- for ( KeyValues *pData = inResourceData->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
- {
- if ( !Q_stricmp( pData->GetName(), "animation" ) )
- {
- OnAddAnimation( pData );
- }
- else if ( !Q_stricmp( pData->GetName(), "attached_model" ) )
- {
- CModelPanelAttachedModelInfo *pAttachedModelInfo = new CModelPanelAttachedModelInfo;
-
- if ( pAttachedModelInfo )
- {
- pAttachedModelInfo->m_pszModelName = ReadAndAllocStringValue( pData, "modelname" );
- pAttachedModelInfo->m_nSkin = pData->GetInt( "skin", -1 );
-
- m_pModelInfo->m_AttachedModelsInfo.AddToTail( pAttachedModelInfo );
- }
- }
- }
-
- m_bPanelDirty = true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::OnAddAnimation( KeyValues *pData )
-{
- if ( !pData )
- return;
-
- CModelPanelModelAnimation *pAnimation = new CModelPanelModelAnimation;
-
- if ( pAnimation )
- {
- pAnimation->m_pszName = ReadAndAllocStringValue( pData, "name" );
- pAnimation->m_pszSequence = ReadAndAllocStringValue( pData, "sequence" );
- pAnimation->m_pszActivity = ReadAndAllocStringValue( pData, "activity" );
- pAnimation->m_bDefault = ( pData->GetInt( "default", 0 ) == 1 );
-
- for ( KeyValues *pAnimData = pData->GetFirstSubKey(); pAnimData != NULL; pAnimData = pAnimData->GetNextKey() )
- {
- if ( !Q_stricmp( pAnimData->GetName(), "pose_parameters" ) )
- {
- pAnimation->m_pPoseParameters = pAnimData->MakeCopy();
- }
- }
-
- m_pModelInfo->m_Animations.AddToTail( pAnimation );
- if ( pAnimation->m_bDefault )
- {
- m_iDefaultAnimation = m_pModelInfo->m_Animations.Find( pAnimation );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::FireGameEvent( IGameEvent * event )
-{
- const char *type = event->GetName();
-
- if ( Q_strcmp( type, "game_newmap" ) == 0 )
- {
- // force the models to re-setup themselves
- m_bPanelDirty = true;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::SetDefaultAnimation( const char *pszName )
-{
- if ( m_pModelInfo )
- {
- for ( int i = 0; i < m_pModelInfo->m_Animations.Count(); i++ )
- {
- if ( m_pModelInfo->m_Animations[i] && m_pModelInfo->m_Animations[i]->m_pszName )
- {
- if ( !Q_stricmp( m_pModelInfo->m_Animations[i]->m_pszName, pszName ) )
- {
- m_iDefaultAnimation = i;
- return;
- }
- }
- }
- }
-
- Assert( 0 );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Replaces the current model with a new one, without changing the camera settings
-//-----------------------------------------------------------------------------
-void CModelPanel::SwapModel( const char *pszName, const char *pszAttached )
-{
- if ( !m_pModelInfo || !pszName || !pszName[0] )
- return;
-
- int len = Q_strlen( pszName ) + 1;
- char *pAlloced = new char[ len ];
- Assert( pAlloced );
- Q_strncpy( pAlloced, pszName, len );
- m_pModelInfo->m_pszModelName = pAlloced;
-
- ClearAttachedModelInfos();
-
- if ( pszAttached )
- {
- CModelPanelAttachedModelInfo *pAttachedModelInfo = new CModelPanelAttachedModelInfo;
- if ( pAttachedModelInfo )
- {
- len = Q_strlen( pszAttached ) + 1;
- pAlloced = new char[ len ];
- Assert( pAlloced );
- Q_strncpy( pAlloced, pszAttached, len );
- pAttachedModelInfo->m_pszModelName = pAlloced;
- pAttachedModelInfo->m_nSkin = 0;
-
- m_pModelInfo->m_AttachedModelsInfo.AddToTail( pAttachedModelInfo );
- }
- }
-
- m_bPanelDirty = true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::DeleteVCDData( void )
-{
- if ( m_hScene.Get() )
- {
- m_hScene->StopClientOnlyScene();
-
- m_hScene->Remove();
- m_hScene = NULL;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::SetupVCD( void )
-{
- if ( !m_pModelInfo )
- return;
-
- DeleteVCDData();
-
- C_SceneEntity *pEnt = new class C_SceneEntity;
-
- if ( !pEnt )
- return;
-
- if ( pEnt->InitializeAsClientEntity( "", RENDER_GROUP_OTHER ) == false )
- {
- // we failed to initialize this entity so just return gracefully
- pEnt->Remove();
- return;
- }
-
- // setup the handle
- m_hScene = pEnt;
-
- // setup the scene
- pEnt->SetupClientOnlyScene( m_pModelInfo->m_pszVCD, m_hModel, true );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::ClearAttachedModelInfos( void )
-{
- if ( m_pModelInfo )
- {
- m_pModelInfo->m_AttachedModelsInfo.PurgeAndDeleteElements();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::DeleteModelData( void )
-{
- if ( m_hModel.Get() )
- {
- m_hModel->Remove();
- m_hModel = NULL;
- m_flFrameDistance = 0;
- }
-
- for ( int i = 0 ; i < m_AttachedModels.Count() ; i++ )
- {
- if ( m_AttachedModels[i].Get() )
- {
- m_AttachedModels[i]->Remove();
- }
- m_AttachedModels.Remove( i );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-const char *CModelPanel::GetModelName( void )
-{
- if ( !m_pModelInfo )
- return NULL;
-
- // check to see if we want to use a HWM model
- if ( UseHWMorphModels() )
- {
- // do we have a valid HWM model filename
- if ( m_pModelInfo->m_pszModelName_HWM && ( Q_strlen( m_pModelInfo->m_pszModelName_HWM ) > 0 ) )
- {
- // does the file exist
- model_t *pModel = (model_t *)engine->LoadModel( m_pModelInfo->m_pszModelName_HWM );
- if ( pModel )
- {
- return m_pModelInfo->m_pszModelName_HWM;
- }
- }
- }
-
- return m_pModelInfo->m_pszModelName;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::SetupModel( void )
-{
- if ( !m_pModelInfo )
- return;
-
- MDLCACHE_CRITICAL_SECTION();
-
- // remove any current models we're using
- DeleteModelData();
-
- const char *pszModelName = GetModelName();
- if ( !pszModelName || !pszModelName[0] )
- return;
-
- // create the new model
- CModelPanelModel *pEnt = new CModelPanelModel;
-
- if ( !pEnt )
- return;
-
- if ( pEnt->InitializeAsClientEntity( pszModelName, RENDER_GROUP_OPAQUE_ENTITY ) == false )
- {
- // we failed to initialize this entity so just return gracefully
- pEnt->Remove();
- return;
- }
-
- // setup the handle
- m_hModel = pEnt;
-
- pEnt->DontRecordInTools();
- pEnt->AddEffects( EF_NODRAW ); // don't let the renderer draw the model normally
-
- if ( m_pModelInfo->m_nSkin >= 0 )
- {
- pEnt->m_nSkin = m_pModelInfo->m_nSkin;
- }
-
- // do we have any animation information?
- if ( m_pModelInfo->m_Animations.Count() > 0 && m_pModelInfo->m_Animations.IsValidIndex( m_iDefaultAnimation ) )
- {
- CModelPanelModelAnimation *pAnim = m_pModelInfo->m_Animations[ m_iDefaultAnimation ];
- int sequence = ACT_INVALID;
- if ( pAnim->m_pszActivity && pAnim->m_pszActivity[0] )
- {
- Activity activity = (Activity)ActivityList_IndexForName( pAnim->m_pszActivity );
- sequence = pEnt->SelectWeightedSequence( activity );
- }
- else if ( pAnim->m_pszSequence && pAnim->m_pszSequence[0] )
- {
- sequence = pEnt->LookupSequence( pAnim->m_pszSequence );
- }
- if ( sequence != ACT_INVALID )
- {
- pEnt->ResetSequence( sequence );
- pEnt->SetCycle( 0 );
-
- if ( pAnim->m_pPoseParameters )
- {
- for ( KeyValues *pData = pAnim->m_pPoseParameters->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
- {
- const char *pName = pData->GetName();
- float flValue = pData->GetFloat();
-
- pEnt->SetPoseParameter( pName, flValue );
- }
- }
-
- pEnt->m_flAnimTime = gpGlobals->curtime;
- }
- }
-
- // setup any attached models
- for ( int i = 0 ; i < m_pModelInfo->m_AttachedModelsInfo.Count() ; i++ )
- {
- CModelPanelAttachedModelInfo *pInfo = m_pModelInfo->m_AttachedModelsInfo[i];
- C_BaseAnimating *pTemp = new C_BaseAnimating;
-
- if ( pTemp )
- {
- if ( pTemp->InitializeAsClientEntity( pInfo->m_pszModelName, RENDER_GROUP_OPAQUE_ENTITY ) == false )
- {
- // we failed to initialize this model so just skip it
- pTemp->Remove();
- continue;
- }
-
- pTemp->DontRecordInTools();
- pTemp->AddEffects( EF_NODRAW ); // don't let the renderer draw the model normally
- pTemp->FollowEntity( m_hModel.Get() ); // attach to parent model
-
- if ( pInfo->m_nSkin >= 0 )
- {
- pTemp->m_nSkin = pInfo->m_nSkin;
- }
-
- pTemp->m_flAnimTime = gpGlobals->curtime;
- m_AttachedModels.AddToTail( pTemp );
- }
- }
-
- CalculateFrameDistance();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::InitCubeMaps()
-{
- ITexture *pCubemapTexture;
-
- // Deal with the default cubemap
- if ( g_pMaterialSystemHardwareConfig->GetHDREnabled() )
- {
- pCubemapTexture = materials->FindTexture( "editor/cubemap.hdr", NULL, true );
- m_DefaultHDREnvCubemap.Init( pCubemapTexture );
- }
- else
- {
- pCubemapTexture = materials->FindTexture( "editor/cubemap", NULL, true );
- m_DefaultEnvCubemap.Init( pCubemapTexture );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: If the panel is marked as dirty, update it and mark it as clean
-//-----------------------------------------------------------------------------
-void CModelPanel::UpdateModel()
-{
- if ( m_bPanelDirty )
- {
- InitCubeMaps();
-
- SetupModel();
-
- // are we trying to play a VCD?
- if ( Q_strlen( m_pModelInfo->m_pszVCD ) > 0 )
- {
- SetupVCD();
- }
-
- m_bPanelDirty = false;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::Paint()
-{
- BaseClass::Paint();
-
- C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
-
- if ( !pLocalPlayer || !m_pModelInfo )
- return;
-
- MDLCACHE_CRITICAL_SECTION();
-
- UpdateModel();
-
- if ( !m_hModel.Get() )
- return;
-
- int i = 0;
- int x, y, w, h;
-
- GetBounds( x, y, w, h );
- ParentLocalToScreen( x, y );
-
- if ( !m_bAllowOffscreen && x < 0 )
- {
- // prevent x from being pushed off the left side of the screen
- // for modes like 1280 x 1024 (prevents model from being drawn in the panel)
- x = 0;
- }
-
- Vector vecExtraModelOffset( 0, 0, 0 );
- float flWidthRatio = ((float)w / (float)h ) / ( 4.0f / 3.0f );
-
- // is this a player model?
- if ( Q_strstr( GetModelName(), "models/player/" ) )
- {
- // need to know if the ratio is not 4/3
- // HACK! HACK! to get our player models to appear the way they do in 4/3 if we're using other aspect ratios
- if ( flWidthRatio > 1.05f )
- {
- vecExtraModelOffset.Init( -60, 0, 0 );
- }
- else if ( flWidthRatio < 0.95f )
- {
- vecExtraModelOffset.Init( 15, 0, 0 );
- }
- }
-
- m_hModel->SetAbsOrigin( m_pModelInfo->m_vecOriginOffset + vecExtraModelOffset );
- m_hModel->SetAbsAngles( QAngle( m_pModelInfo->m_vecAbsAngles.x, m_pModelInfo->m_vecAbsAngles.y, m_pModelInfo->m_vecAbsAngles.z ) );
-
- // do we have a valid sequence?
- if ( m_hModel->GetSequence() != -1 )
- {
- m_hModel->FrameAdvance( gpGlobals->frametime );
- }
-
- CMatRenderContextPtr pRenderContext( materials );
-
- // figure out what our viewport is right now
- int viewportX, viewportY, viewportWidth, viewportHeight;
- pRenderContext->GetViewport( viewportX, viewportY, viewportWidth, viewportHeight );
-
- // Now draw it.
- CViewSetup view;
- view.x = x + m_pModelInfo->m_vecViewportOffset.x + viewportX; // we actually want to offset by the
- view.y = y + m_pModelInfo->m_vecViewportOffset.y + viewportY; // viewport origin here because Push3DView expects global coords below
- view.width = w;
- view.height = h;
-
- view.m_bOrtho = false;
-
- // scale the FOV for aspect ratios other than 4/3
- view.fov = ScaleFOVByWidthRatio( m_nFOV, flWidthRatio );
-
- view.origin = vec3_origin;
- view.angles.Init();
- view.zNear = VIEW_NEARZ;
- view.zFar = 1000;
-
-
-
- // Not supported by queued material system - doesn't appear to be necessary
-// ITexture *pLocalCube = pRenderContext->GetLocalCubemap();
-
- if ( g_pMaterialSystemHardwareConfig->GetHDREnabled() )
- {
- pRenderContext->BindLocalCubemap( m_DefaultHDREnvCubemap );
- }
- else
- {
- pRenderContext->BindLocalCubemap( m_DefaultEnvCubemap );
- }
-
- pRenderContext->SetLightingOrigin( vec3_origin );
- pRenderContext->SetAmbientLight( 0.4, 0.4, 0.4 );
-
- static Vector white[6] =
- {
- Vector( 0.4, 0.4, 0.4 ),
- Vector( 0.4, 0.4, 0.4 ),
- Vector( 0.4, 0.4, 0.4 ),
- Vector( 0.4, 0.4, 0.4 ),
- Vector( 0.4, 0.4, 0.4 ),
- Vector( 0.4, 0.4, 0.4 ),
- };
-
- g_pStudioRender->SetAmbientLightColors( white );
- g_pStudioRender->SetLocalLights( 0, NULL );
-
- if ( m_pModelInfo->m_bUseSpotlight )
- {
- Vector vecMins, vecMaxs;
- m_hModel->GetRenderBounds( vecMins, vecMaxs );
- LightDesc_t spotLight( vec3_origin + Vector( 0, 0, 200 ), Vector( 1, 1, 1 ), m_hModel->GetAbsOrigin() + Vector( 0, 0, ( vecMaxs.z - vecMins.z ) * 0.75 ), 0.035, 0.873 );
- g_pStudioRender->SetLocalLights( 1, &spotLight );
- }
-
- Frustum dummyFrustum;
- render->Push3DView( view, 0, NULL, dummyFrustum );
-
- modelrender->SuppressEngineLighting( true );
- float color[3] = { 1.0f, 1.0f, 1.0f };
- render->SetColorModulation( color );
- render->SetBlend( 1.0f );
- m_hModel->DrawModel( STUDIO_RENDER );
-
- for ( i = 0 ; i < m_AttachedModels.Count() ; i++ )
- {
- if ( m_AttachedModels[i].Get() )
- {
- m_AttachedModels[i]->DrawModel( STUDIO_RENDER );
- }
- }
-
- modelrender->SuppressEngineLighting( false );
-
- render->PopView( dummyFrustum );
-
- pRenderContext->BindLocalCubemap( NULL );
-
- /*
- vgui::surface()->DrawSetColor( Color(0,0,0,255) );
- vgui::surface()->DrawOutlinedRect( 0,0, GetWide(), GetTall() );
- */
-
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CModelPanel::FindAnimByName( const char *pszName )
-{
- // first try to find the sequence using pszName as the friendly name
- for ( int iIndex = 0 ; iIndex < m_pModelInfo->m_Animations.Count() ; iIndex++ )
- {
- CModelPanelModelAnimation *pAnimation = m_pModelInfo->m_Animations[ iIndex ];
- if ( FStrEq( pAnimation->m_pszName, pszName ) )
- return iIndex;
- }
-
- return -1;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool CModelPanel::SetSequence( const char *pszName )
-{
- bool bRetVal = false;
- const char *pszAnim = NULL;
-
- MDLCACHE_CRITICAL_SECTION();
-
- if ( m_pModelInfo )
- {
- int iIndex = FindAnimByName(pszName);
- if ( iIndex != -1 )
- {
- pszAnim = m_pModelInfo->m_Animations[iIndex]->m_pszSequence;
- }
- else
- {
- // if not, just use the passed name as the sequence
- pszAnim = pszName;
- }
-
- if ( m_hModel.Get() )
- {
- int sequence = m_hModel->LookupSequence( pszAnim );
- if ( sequence != ACT_INVALID )
- {
- m_hModel->ResetSequence( sequence );
- m_hModel->SetCycle( 0 );
-
- bRetVal = true;
- }
- }
- }
-
- return bRetVal;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CModelPanel::OnSetAnimation( KeyValues *data )
-{
- UpdateModel();
-
- // If there's no model, these commands will be ignored.
- Assert(m_hModel);
-
- if ( data )
- {
- const char *pszAnimation = data->GetString( "animation", "" );
- const char *pszActivity = data->GetString( "activity", "" );
- if ( pszActivity && pszActivity[0] )
- {
- if ( m_hModel )
- {
- int iIndex = FindAnimByName(pszActivity);
- if ( iIndex != -1 )
- {
- pszActivity = m_pModelInfo->m_Animations[iIndex]->m_pszActivity;
- }
-
- Activity activity = (Activity)ActivityList_IndexForName( pszActivity );
- int sequence = m_hModel->SelectWeightedSequence( activity );
- if ( sequence != ACT_INVALID )
- {
- m_hModel->ResetSequence( sequence );
- m_hModel->SetCycle( 0 );
- }
- }
- }
- else
- {
- SetSequence( pszAnimation );
- }
- }
-}
-
-void CModelPanel::CalculateFrameDistanceInternal( const model_t *pModel )
-{
- // Get the model space render bounds.
- Vector vecMin, vecMax;
- modelinfo->GetModelRenderBounds( pModel, vecMin, vecMax );
- Vector vecCenter = ( vecMax + vecMin ) * 0.5f;
- vecMin -= vecCenter;
- vecMax -= vecCenter;
-
- // Get the bounds points and transform them by the desired model panel rotation.
- Vector aBoundsPoints[8];
- aBoundsPoints[0].Init( vecMax.x, vecMax.y, vecMax.z );
- aBoundsPoints[1].Init( vecMin.x, vecMax.y, vecMax.z );
- aBoundsPoints[2].Init( vecMax.x, vecMin.y, vecMax.z );
- aBoundsPoints[3].Init( vecMin.x, vecMin.y, vecMax.z );
- aBoundsPoints[4].Init( vecMax.x, vecMax.y, vecMin.z );
- aBoundsPoints[5].Init( vecMin.x, vecMax.y, vecMin.z );
- aBoundsPoints[6].Init( vecMax.x, vecMin.y, vecMin.z );
- aBoundsPoints[7].Init( vecMin.x, vecMin.y, vecMin.z );
-
- // Translated center point (offset from camera center).
- Vector vecTranslateCenter = -vecCenter;
-
- // Build the rotation matrix.
- QAngle angPanelAngles( m_pModelInfo->m_vecAbsAngles.x, m_pModelInfo->m_vecAbsAngles.y, m_pModelInfo->m_vecAbsAngles.z );
- matrix3x4_t matRotation;
- AngleMatrix( angPanelAngles, matRotation );
-
- Vector aXFormPoints[8];
- for ( int iPoint = 0; iPoint < 8; ++iPoint )
- {
- VectorTransform( aBoundsPoints[iPoint], matRotation, aXFormPoints[iPoint] );
- }
-
- Vector vecXFormCenter;
- VectorTransform( -vecTranslateCenter, matRotation, vecXFormCenter );
-
- int w, h;
- GetSize( w, h );
- float flW = (float)w;
- float flH = (float)h;
-
- float flFOVx = DEG2RAD( m_nFOV * 0.5f );
- float flFOVy = CalcFovY( ( m_nFOV * 0.5f ), flW/flH );
- flFOVy = DEG2RAD( flFOVy );
-
- float flTanFOVx = tan( flFOVx );
- float flTanFOVy = tan( flFOVy );
-
- // Find the max value of x, y, or z
- float flDist = 0.0f;
- for ( int iPoint = 0; iPoint < 8; ++iPoint )
- {
- float flDistZ = fabs( aXFormPoints[iPoint].z / flTanFOVy - aXFormPoints[iPoint].x );
- float flDistY = fabs( aXFormPoints[iPoint].y / flTanFOVx - aXFormPoints[iPoint].x );
- float flTestDist = MAX( flDistZ, flDistY );
- flDist = MAX( flDist, flTestDist );
- }
-
- // Scale the object down by 10%.
- flDist *= 1.10f;
-
- // Add the framing offset.
- vecXFormCenter += m_pModelInfo->m_vecFramedOriginOffset;
-
- // Zoom to the frame distance
- m_pModelInfo->m_vecOriginOffset.x = flDist - vecXFormCenter.x;
- m_pModelInfo->m_vecOriginOffset.y = -vecXFormCenter.y;
- m_pModelInfo->m_vecOriginOffset.z = -vecXFormCenter.z;
-
- // Screen space points.
- Vector2D aScreenPoints[8];
- Vector aCameraPoints[8];
- for ( int iPoint = 0; iPoint < 8; ++iPoint )
- {
- aCameraPoints[iPoint] = aXFormPoints[iPoint];
- aCameraPoints[iPoint].x += flDist;
-
- aScreenPoints[iPoint].x = aCameraPoints[iPoint].y / ( flTanFOVx * aCameraPoints[iPoint].x );
- aScreenPoints[iPoint].y = aCameraPoints[iPoint].z / ( flTanFOVy * aCameraPoints[iPoint].x );
-
- aScreenPoints[iPoint].x = ( aScreenPoints[iPoint].x * 0.5f + 0.5f ) * flW;
- aScreenPoints[iPoint].y = ( aScreenPoints[iPoint].y * 0.5f + 0.5f ) * flH;
- }
-
- // Find the min/max and center of the 2D bounding box of the object.
- Vector2D vecScreenMin( 99999.0f, 99999.0f ), vecScreenMax( -99999.0f, -99999.0f );
- for ( int iPoint = 0; iPoint < 8; ++iPoint )
- {
- vecScreenMin.x = MIN( vecScreenMin.x, aScreenPoints[iPoint].x );
- vecScreenMin.y = MIN( vecScreenMin.y, aScreenPoints[iPoint].y );
- vecScreenMax.x = MAX( vecScreenMax.x, aScreenPoints[iPoint].x );
- vecScreenMax.y = MAX( vecScreenMax.y, aScreenPoints[iPoint].y );
- }
-
- vecScreenMin.x = clamp( vecScreenMin.x, 0.0f, flW );
- vecScreenMin.y = clamp( vecScreenMin.y, 0.0f, flH );
- vecScreenMax.x = clamp( vecScreenMax.x, 0.0f, flW );
- vecScreenMax.y = clamp( vecScreenMax.y, 0.0f, flH );
-
- // Offset the view port based on the calculated model 2D center and the center of the viewport.
- Vector2D vecScreenCenter = ( vecScreenMax + vecScreenMin ) * 0.5f;
- m_pModelInfo->m_vecViewportOffset.x = -( ( flW * 0.5f ) - vecScreenCenter.x );
- m_pModelInfo->m_vecViewportOffset.y = -( ( flH * 0.5f ) - vecScreenCenter.y );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Calculates the distance the camera should be at to frame the model on the screen.
-//-----------------------------------------------------------------------------
-void CModelPanel::CalculateFrameDistance( void )
-{
- m_flFrameDistance = 0;
- if ( !m_hModel )
- return;
-
- // Compute a bounding radius for the model
- const model_t *mod = modelinfo->GetModel( m_hModel->GetModelIndex() );
- if ( !mod )
- return;
-
- if ( m_bStartFramed )
- {
- CalculateFrameDistanceInternal( mod );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Moves the camera forward/backward along the current view angle to
-// frame the model on the screen.
-//-----------------------------------------------------------------------------
-void CModelPanel::ZoomToFrameDistance( void )
-{
- if ( !m_flFrameDistance || !m_hModel )
- return;
-
- const model_t *mod = modelinfo->GetModel( m_hModel->GetModelIndex() );
- if ( !mod )
- return;
-
- // Move the model to the midpoint
- Vector mins, maxs, vecModelCenter;
- modelinfo->GetModelRenderBounds( mod, mins, maxs );
- VectorLerp( mins, maxs, 0.5f, vecModelCenter );
-
- vecModelCenter += m_pModelInfo->m_vecFramedOriginOffset;
-
- // Zoom to the frame distance
- m_pModelInfo->m_vecOriginOffset.x = m_flFrameDistance;
- m_pModelInfo->m_vecOriginOffset.y = -vecModelCenter.y;
- m_pModelInfo->m_vecOriginOffset.z = -vecModelCenter.z;
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+
+#include "cbase.h"
+#include <KeyValues.h>
+#include <vgui/ISurface.h>
+#include <vgui/ISystem.h>
+#include <vgui/IScheme.h>
+#include <vgui_controls/AnimationController.h>
+#include <vgui_controls/EditablePanel.h>
+#include <vgui_controls/ImagePanel.h>
+#include <vgui/ISurface.h>
+#include <vgui/IImage.h>
+#include <vgui_controls/Label.h>
+
+#include "materialsystem/imaterialsystem.h"
+#include "engine/ivmodelinfo.h"
+
+#include "c_sceneentity.h"
+#include "gamestringpool.h"
+#include "model_types.h"
+#include "view_shared.h"
+#include "view.h"
+#include "ivrenderview.h"
+#include "iefx.h"
+#include "dlight.h"
+#include "activitylist.h"
+
+#include "basemodelpanel.h"
+
+bool UseHWMorphModels();
+
+
+using namespace vgui;
+
+DECLARE_BUILD_FACTORY( CModelPanel );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CModelPanel::CModelPanel( vgui::Panel *pParent, const char *pName ) : vgui::EditablePanel( pParent, pName )
+{
+ m_nFOV = 54;
+ m_hModel = NULL;
+ m_pModelInfo = NULL;
+ m_hScene = NULL;
+ m_iDefaultAnimation = 0;
+ m_bPanelDirty = true;
+ m_bStartFramed = false;
+ m_bAllowOffscreen = false;
+
+ ListenForGameEvent( "game_newmap" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CModelPanel::~CModelPanel()
+{
+ if ( m_pModelInfo )
+ {
+ delete m_pModelInfo;
+ m_pModelInfo = NULL;
+ }
+
+ DeleteVCDData();
+ DeleteModelData();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::ApplySettings( KeyValues *inResourceData )
+{
+ BaseClass::ApplySettings( inResourceData );
+
+ m_nFOV = inResourceData->GetInt( "fov", 54 );
+ m_bStartFramed = inResourceData->GetInt( "start_framed", false );
+ m_bAllowOffscreen = inResourceData->GetInt( "allow_offscreen", false );
+
+ // do we have a valid "model" section in the .res file?
+ for ( KeyValues *pData = inResourceData->GetFirstSubKey() ; pData != NULL ; pData = pData->GetNextKey() )
+ {
+ if ( !Q_stricmp( pData->GetName(), "model" ) )
+ {
+ ParseModelInfo( pData );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::ParseModelInfo( KeyValues *inResourceData )
+{
+ // delete any current info
+ if ( m_pModelInfo )
+ {
+ delete m_pModelInfo;
+ m_pModelInfo = NULL;
+ }
+
+ m_pModelInfo = new CModelPanelModelInfo;
+
+ if ( !m_pModelInfo )
+ return;
+
+ m_pModelInfo->m_pszModelName = ReadAndAllocStringValue( inResourceData, "modelname" );
+ m_pModelInfo->m_pszModelName_HWM = ReadAndAllocStringValue( inResourceData, "modelname_hwm" );
+ m_pModelInfo->m_nSkin = inResourceData->GetInt( "skin", -1 );
+ m_pModelInfo->m_vecAbsAngles.Init( inResourceData->GetFloat( "angles_x", 0.0 ), inResourceData->GetFloat( "angles_y", 0.0 ), inResourceData->GetFloat( "angles_z", 0.0 ) );
+ m_pModelInfo->m_vecOriginOffset.Init( inResourceData->GetFloat( "origin_x", 110.0 ), inResourceData->GetFloat( "origin_y", 5.0 ), inResourceData->GetFloat( "origin_z", 5.0 ) );
+ m_pModelInfo->m_vecFramedOriginOffset.Init( inResourceData->GetFloat( "frame_origin_x", 110.0 ), inResourceData->GetFloat( "frame_origin_y", 5.0 ), inResourceData->GetFloat( "frame_origin_z", 5.0 ) );
+ m_pModelInfo->m_pszVCD = ReadAndAllocStringValue( inResourceData, "vcd" );
+ m_pModelInfo->m_bUseSpotlight = ( inResourceData->GetInt( "spotlight", 0 ) == 1 );
+ m_pModelInfo->m_vecViewportOffset.Init();
+
+ for ( KeyValues *pData = inResourceData->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
+ {
+ if ( !Q_stricmp( pData->GetName(), "animation" ) )
+ {
+ OnAddAnimation( pData );
+ }
+ else if ( !Q_stricmp( pData->GetName(), "attached_model" ) )
+ {
+ CModelPanelAttachedModelInfo *pAttachedModelInfo = new CModelPanelAttachedModelInfo;
+
+ if ( pAttachedModelInfo )
+ {
+ pAttachedModelInfo->m_pszModelName = ReadAndAllocStringValue( pData, "modelname" );
+ pAttachedModelInfo->m_nSkin = pData->GetInt( "skin", -1 );
+
+ m_pModelInfo->m_AttachedModelsInfo.AddToTail( pAttachedModelInfo );
+ }
+ }
+ }
+
+ m_bPanelDirty = true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::OnAddAnimation( KeyValues *pData )
+{
+ if ( !pData )
+ return;
+
+ CModelPanelModelAnimation *pAnimation = new CModelPanelModelAnimation;
+
+ if ( pAnimation )
+ {
+ pAnimation->m_pszName = ReadAndAllocStringValue( pData, "name" );
+ pAnimation->m_pszSequence = ReadAndAllocStringValue( pData, "sequence" );
+ pAnimation->m_pszActivity = ReadAndAllocStringValue( pData, "activity" );
+ pAnimation->m_bDefault = ( pData->GetInt( "default", 0 ) == 1 );
+
+ for ( KeyValues *pAnimData = pData->GetFirstSubKey(); pAnimData != NULL; pAnimData = pAnimData->GetNextKey() )
+ {
+ if ( !Q_stricmp( pAnimData->GetName(), "pose_parameters" ) )
+ {
+ pAnimation->m_pPoseParameters = pAnimData->MakeCopy();
+ }
+ }
+
+ m_pModelInfo->m_Animations.AddToTail( pAnimation );
+ if ( pAnimation->m_bDefault )
+ {
+ m_iDefaultAnimation = m_pModelInfo->m_Animations.Find( pAnimation );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::FireGameEvent( IGameEvent * event )
+{
+ const char *type = event->GetName();
+
+ if ( Q_strcmp( type, "game_newmap" ) == 0 )
+ {
+ // force the models to re-setup themselves
+ m_bPanelDirty = true;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::SetDefaultAnimation( const char *pszName )
+{
+ if ( m_pModelInfo )
+ {
+ for ( int i = 0; i < m_pModelInfo->m_Animations.Count(); i++ )
+ {
+ if ( m_pModelInfo->m_Animations[i] && m_pModelInfo->m_Animations[i]->m_pszName )
+ {
+ if ( !Q_stricmp( m_pModelInfo->m_Animations[i]->m_pszName, pszName ) )
+ {
+ m_iDefaultAnimation = i;
+ return;
+ }
+ }
+ }
+ }
+
+ Assert( 0 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Replaces the current model with a new one, without changing the camera settings
+//-----------------------------------------------------------------------------
+void CModelPanel::SwapModel( const char *pszName, const char *pszAttached )
+{
+ if ( !m_pModelInfo || !pszName || !pszName[0] )
+ return;
+
+ int len = Q_strlen( pszName ) + 1;
+ char *pAlloced = new char[ len ];
+ Assert( pAlloced );
+ Q_strncpy( pAlloced, pszName, len );
+ m_pModelInfo->m_pszModelName = pAlloced;
+
+ ClearAttachedModelInfos();
+
+ if ( pszAttached )
+ {
+ CModelPanelAttachedModelInfo *pAttachedModelInfo = new CModelPanelAttachedModelInfo;
+ if ( pAttachedModelInfo )
+ {
+ len = Q_strlen( pszAttached ) + 1;
+ pAlloced = new char[ len ];
+ Assert( pAlloced );
+ Q_strncpy( pAlloced, pszAttached, len );
+ pAttachedModelInfo->m_pszModelName = pAlloced;
+ pAttachedModelInfo->m_nSkin = 0;
+
+ m_pModelInfo->m_AttachedModelsInfo.AddToTail( pAttachedModelInfo );
+ }
+ }
+
+ m_bPanelDirty = true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::DeleteVCDData( void )
+{
+ if ( m_hScene.Get() )
+ {
+ m_hScene->StopClientOnlyScene();
+
+ m_hScene->Remove();
+ m_hScene = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::SetupVCD( void )
+{
+ if ( !m_pModelInfo )
+ return;
+
+ DeleteVCDData();
+
+ C_SceneEntity *pEnt = new class C_SceneEntity;
+
+ if ( !pEnt )
+ return;
+
+ if ( pEnt->InitializeAsClientEntity( "", RENDER_GROUP_OTHER ) == false )
+ {
+ // we failed to initialize this entity so just return gracefully
+ pEnt->Remove();
+ return;
+ }
+
+ // setup the handle
+ m_hScene = pEnt;
+
+ // setup the scene
+ pEnt->SetupClientOnlyScene( m_pModelInfo->m_pszVCD, m_hModel, true );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::ClearAttachedModelInfos( void )
+{
+ if ( m_pModelInfo )
+ {
+ m_pModelInfo->m_AttachedModelsInfo.PurgeAndDeleteElements();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::DeleteModelData( void )
+{
+ if ( m_hModel.Get() )
+ {
+ m_hModel->Remove();
+ m_hModel = NULL;
+ m_flFrameDistance = 0;
+ }
+
+ for ( int i = 0 ; i < m_AttachedModels.Count() ; i++ )
+ {
+ if ( m_AttachedModels[i].Get() )
+ {
+ m_AttachedModels[i]->Remove();
+ }
+ m_AttachedModels.Remove( i );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+const char *CModelPanel::GetModelName( void )
+{
+ if ( !m_pModelInfo )
+ return NULL;
+
+ // check to see if we want to use a HWM model
+ if ( UseHWMorphModels() )
+ {
+ // do we have a valid HWM model filename
+ if ( m_pModelInfo->m_pszModelName_HWM && ( Q_strlen( m_pModelInfo->m_pszModelName_HWM ) > 0 ) )
+ {
+ // does the file exist
+ model_t *pModel = (model_t *)engine->LoadModel( m_pModelInfo->m_pszModelName_HWM );
+ if ( pModel )
+ {
+ return m_pModelInfo->m_pszModelName_HWM;
+ }
+ }
+ }
+
+ return m_pModelInfo->m_pszModelName;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::SetupModel( void )
+{
+ if ( !m_pModelInfo )
+ return;
+
+ MDLCACHE_CRITICAL_SECTION();
+
+ // remove any current models we're using
+ DeleteModelData();
+
+ const char *pszModelName = GetModelName();
+ if ( !pszModelName || !pszModelName[0] )
+ return;
+
+ // create the new model
+ CModelPanelModel *pEnt = new CModelPanelModel;
+
+ if ( !pEnt )
+ return;
+
+ if ( pEnt->InitializeAsClientEntity( pszModelName, RENDER_GROUP_OPAQUE_ENTITY ) == false )
+ {
+ // we failed to initialize this entity so just return gracefully
+ pEnt->Remove();
+ return;
+ }
+
+ // setup the handle
+ m_hModel = pEnt;
+
+ pEnt->DontRecordInTools();
+ pEnt->AddEffects( EF_NODRAW ); // don't let the renderer draw the model normally
+
+ if ( m_pModelInfo->m_nSkin >= 0 )
+ {
+ pEnt->m_nSkin = m_pModelInfo->m_nSkin;
+ }
+
+ // do we have any animation information?
+ if ( m_pModelInfo->m_Animations.Count() > 0 && m_pModelInfo->m_Animations.IsValidIndex( m_iDefaultAnimation ) )
+ {
+ CModelPanelModelAnimation *pAnim = m_pModelInfo->m_Animations[ m_iDefaultAnimation ];
+ int sequence = ACT_INVALID;
+ if ( pAnim->m_pszActivity && pAnim->m_pszActivity[0] )
+ {
+ Activity activity = (Activity)ActivityList_IndexForName( pAnim->m_pszActivity );
+ sequence = pEnt->SelectWeightedSequence( activity );
+ }
+ else if ( pAnim->m_pszSequence && pAnim->m_pszSequence[0] )
+ {
+ sequence = pEnt->LookupSequence( pAnim->m_pszSequence );
+ }
+ if ( sequence != ACT_INVALID )
+ {
+ pEnt->ResetSequence( sequence );
+ pEnt->SetCycle( 0 );
+
+ if ( pAnim->m_pPoseParameters )
+ {
+ for ( KeyValues *pData = pAnim->m_pPoseParameters->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
+ {
+ const char *pName = pData->GetName();
+ float flValue = pData->GetFloat();
+
+ pEnt->SetPoseParameter( pName, flValue );
+ }
+ }
+
+ pEnt->m_flAnimTime = gpGlobals->curtime;
+ }
+ }
+
+ // setup any attached models
+ for ( int i = 0 ; i < m_pModelInfo->m_AttachedModelsInfo.Count() ; i++ )
+ {
+ CModelPanelAttachedModelInfo *pInfo = m_pModelInfo->m_AttachedModelsInfo[i];
+ C_BaseAnimating *pTemp = new C_BaseAnimating;
+
+ if ( pTemp )
+ {
+ if ( pTemp->InitializeAsClientEntity( pInfo->m_pszModelName, RENDER_GROUP_OPAQUE_ENTITY ) == false )
+ {
+ // we failed to initialize this model so just skip it
+ pTemp->Remove();
+ continue;
+ }
+
+ pTemp->DontRecordInTools();
+ pTemp->AddEffects( EF_NODRAW ); // don't let the renderer draw the model normally
+ pTemp->FollowEntity( m_hModel.Get() ); // attach to parent model
+
+ if ( pInfo->m_nSkin >= 0 )
+ {
+ pTemp->m_nSkin = pInfo->m_nSkin;
+ }
+
+ pTemp->m_flAnimTime = gpGlobals->curtime;
+ m_AttachedModels.AddToTail( pTemp );
+ }
+ }
+
+ CalculateFrameDistance();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::InitCubeMaps()
+{
+ ITexture *pCubemapTexture;
+
+ // Deal with the default cubemap
+ if ( g_pMaterialSystemHardwareConfig->GetHDREnabled() )
+ {
+ pCubemapTexture = materials->FindTexture( "editor/cubemap.hdr", NULL, true );
+ m_DefaultHDREnvCubemap.Init( pCubemapTexture );
+ }
+ else
+ {
+ pCubemapTexture = materials->FindTexture( "editor/cubemap", NULL, true );
+ m_DefaultEnvCubemap.Init( pCubemapTexture );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: If the panel is marked as dirty, update it and mark it as clean
+//-----------------------------------------------------------------------------
+void CModelPanel::UpdateModel()
+{
+ if ( m_bPanelDirty )
+ {
+ InitCubeMaps();
+
+ SetupModel();
+
+ // are we trying to play a VCD?
+ if ( Q_strlen( m_pModelInfo->m_pszVCD ) > 0 )
+ {
+ SetupVCD();
+ }
+
+ m_bPanelDirty = false;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::Paint()
+{
+ BaseClass::Paint();
+
+ C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
+
+ if ( !pLocalPlayer || !m_pModelInfo )
+ return;
+
+ MDLCACHE_CRITICAL_SECTION();
+
+ UpdateModel();
+
+ if ( !m_hModel.Get() )
+ return;
+
+ int i = 0;
+ int x, y, w, h;
+
+ GetBounds( x, y, w, h );
+ ParentLocalToScreen( x, y );
+
+ if ( !m_bAllowOffscreen && x < 0 )
+ {
+ // prevent x from being pushed off the left side of the screen
+ // for modes like 1280 x 1024 (prevents model from being drawn in the panel)
+ x = 0;
+ }
+
+ Vector vecExtraModelOffset( 0, 0, 0 );
+ float flWidthRatio = ((float)w / (float)h ) / ( 4.0f / 3.0f );
+
+ // is this a player model?
+ if ( Q_strstr( GetModelName(), "models/player/" ) )
+ {
+ // need to know if the ratio is not 4/3
+ // HACK! HACK! to get our player models to appear the way they do in 4/3 if we're using other aspect ratios
+ if ( flWidthRatio > 1.05f )
+ {
+ vecExtraModelOffset.Init( -60, 0, 0 );
+ }
+ else if ( flWidthRatio < 0.95f )
+ {
+ vecExtraModelOffset.Init( 15, 0, 0 );
+ }
+ }
+
+ m_hModel->SetAbsOrigin( m_pModelInfo->m_vecOriginOffset + vecExtraModelOffset );
+ m_hModel->SetAbsAngles( QAngle( m_pModelInfo->m_vecAbsAngles.x, m_pModelInfo->m_vecAbsAngles.y, m_pModelInfo->m_vecAbsAngles.z ) );
+
+ // do we have a valid sequence?
+ if ( m_hModel->GetSequence() != -1 )
+ {
+ m_hModel->FrameAdvance( gpGlobals->frametime );
+ }
+
+ CMatRenderContextPtr pRenderContext( materials );
+
+ // figure out what our viewport is right now
+ int viewportX, viewportY, viewportWidth, viewportHeight;
+ pRenderContext->GetViewport( viewportX, viewportY, viewportWidth, viewportHeight );
+
+ // Now draw it.
+ CViewSetup view;
+ view.x = x + m_pModelInfo->m_vecViewportOffset.x + viewportX; // we actually want to offset by the
+ view.y = y + m_pModelInfo->m_vecViewportOffset.y + viewportY; // viewport origin here because Push3DView expects global coords below
+ view.width = w;
+ view.height = h;
+
+ view.m_bOrtho = false;
+
+ // scale the FOV for aspect ratios other than 4/3
+ view.fov = ScaleFOVByWidthRatio( m_nFOV, flWidthRatio );
+
+ view.origin = vec3_origin;
+ view.angles.Init();
+ view.zNear = VIEW_NEARZ;
+ view.zFar = 1000;
+
+
+
+ // Not supported by queued material system - doesn't appear to be necessary
+// ITexture *pLocalCube = pRenderContext->GetLocalCubemap();
+
+ if ( g_pMaterialSystemHardwareConfig->GetHDREnabled() )
+ {
+ pRenderContext->BindLocalCubemap( m_DefaultHDREnvCubemap );
+ }
+ else
+ {
+ pRenderContext->BindLocalCubemap( m_DefaultEnvCubemap );
+ }
+
+ pRenderContext->SetLightingOrigin( vec3_origin );
+ pRenderContext->SetAmbientLight( 0.4, 0.4, 0.4 );
+
+ static Vector white[6] =
+ {
+ Vector( 0.4, 0.4, 0.4 ),
+ Vector( 0.4, 0.4, 0.4 ),
+ Vector( 0.4, 0.4, 0.4 ),
+ Vector( 0.4, 0.4, 0.4 ),
+ Vector( 0.4, 0.4, 0.4 ),
+ Vector( 0.4, 0.4, 0.4 ),
+ };
+
+ g_pStudioRender->SetAmbientLightColors( white );
+ g_pStudioRender->SetLocalLights( 0, NULL );
+
+ if ( m_pModelInfo->m_bUseSpotlight )
+ {
+ Vector vecMins, vecMaxs;
+ m_hModel->GetRenderBounds( vecMins, vecMaxs );
+ LightDesc_t spotLight( vec3_origin + Vector( 0, 0, 200 ), Vector( 1, 1, 1 ), m_hModel->GetAbsOrigin() + Vector( 0, 0, ( vecMaxs.z - vecMins.z ) * 0.75 ), 0.035, 0.873 );
+ g_pStudioRender->SetLocalLights( 1, &spotLight );
+ }
+
+ Frustum dummyFrustum;
+ render->Push3DView( view, 0, NULL, dummyFrustum );
+
+ modelrender->SuppressEngineLighting( true );
+ float color[3] = { 1.0f, 1.0f, 1.0f };
+ render->SetColorModulation( color );
+ render->SetBlend( 1.0f );
+ m_hModel->DrawModel( STUDIO_RENDER );
+
+ for ( i = 0 ; i < m_AttachedModels.Count() ; i++ )
+ {
+ if ( m_AttachedModels[i].Get() )
+ {
+ m_AttachedModels[i]->DrawModel( STUDIO_RENDER );
+ }
+ }
+
+ modelrender->SuppressEngineLighting( false );
+
+ render->PopView( dummyFrustum );
+
+ pRenderContext->BindLocalCubemap( NULL );
+
+ /*
+ vgui::surface()->DrawSetColor( Color(0,0,0,255) );
+ vgui::surface()->DrawOutlinedRect( 0,0, GetWide(), GetTall() );
+ */
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CModelPanel::FindAnimByName( const char *pszName )
+{
+ // first try to find the sequence using pszName as the friendly name
+ for ( int iIndex = 0 ; iIndex < m_pModelInfo->m_Animations.Count() ; iIndex++ )
+ {
+ CModelPanelModelAnimation *pAnimation = m_pModelInfo->m_Animations[ iIndex ];
+ if ( FStrEq( pAnimation->m_pszName, pszName ) )
+ return iIndex;
+ }
+
+ return -1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CModelPanel::SetSequence( const char *pszName )
+{
+ bool bRetVal = false;
+ const char *pszAnim = NULL;
+
+ MDLCACHE_CRITICAL_SECTION();
+
+ if ( m_pModelInfo )
+ {
+ int iIndex = FindAnimByName(pszName);
+ if ( iIndex != -1 )
+ {
+ pszAnim = m_pModelInfo->m_Animations[iIndex]->m_pszSequence;
+ }
+ else
+ {
+ // if not, just use the passed name as the sequence
+ pszAnim = pszName;
+ }
+
+ if ( m_hModel.Get() )
+ {
+ int sequence = m_hModel->LookupSequence( pszAnim );
+ if ( sequence != ACT_INVALID )
+ {
+ m_hModel->ResetSequence( sequence );
+ m_hModel->SetCycle( 0 );
+
+ bRetVal = true;
+ }
+ }
+ }
+
+ return bRetVal;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CModelPanel::OnSetAnimation( KeyValues *data )
+{
+ UpdateModel();
+
+ // If there's no model, these commands will be ignored.
+ Assert(m_hModel);
+
+ if ( data )
+ {
+ const char *pszAnimation = data->GetString( "animation", "" );
+ const char *pszActivity = data->GetString( "activity", "" );
+ if ( pszActivity && pszActivity[0] )
+ {
+ if ( m_hModel )
+ {
+ int iIndex = FindAnimByName(pszActivity);
+ if ( iIndex != -1 )
+ {
+ pszActivity = m_pModelInfo->m_Animations[iIndex]->m_pszActivity;
+ }
+
+ Activity activity = (Activity)ActivityList_IndexForName( pszActivity );
+ int sequence = m_hModel->SelectWeightedSequence( activity );
+ if ( sequence != ACT_INVALID )
+ {
+ m_hModel->ResetSequence( sequence );
+ m_hModel->SetCycle( 0 );
+ }
+ }
+ }
+ else
+ {
+ SetSequence( pszAnimation );
+ }
+ }
+}
+
+void CModelPanel::CalculateFrameDistanceInternal( const model_t *pModel )
+{
+ // Get the model space render bounds.
+ Vector vecMin, vecMax;
+ modelinfo->GetModelRenderBounds( pModel, vecMin, vecMax );
+ Vector vecCenter = ( vecMax + vecMin ) * 0.5f;
+ vecMin -= vecCenter;
+ vecMax -= vecCenter;
+
+ // Get the bounds points and transform them by the desired model panel rotation.
+ Vector aBoundsPoints[8];
+ aBoundsPoints[0].Init( vecMax.x, vecMax.y, vecMax.z );
+ aBoundsPoints[1].Init( vecMin.x, vecMax.y, vecMax.z );
+ aBoundsPoints[2].Init( vecMax.x, vecMin.y, vecMax.z );
+ aBoundsPoints[3].Init( vecMin.x, vecMin.y, vecMax.z );
+ aBoundsPoints[4].Init( vecMax.x, vecMax.y, vecMin.z );
+ aBoundsPoints[5].Init( vecMin.x, vecMax.y, vecMin.z );
+ aBoundsPoints[6].Init( vecMax.x, vecMin.y, vecMin.z );
+ aBoundsPoints[7].Init( vecMin.x, vecMin.y, vecMin.z );
+
+ // Translated center point (offset from camera center).
+ Vector vecTranslateCenter = -vecCenter;
+
+ // Build the rotation matrix.
+ QAngle angPanelAngles( m_pModelInfo->m_vecAbsAngles.x, m_pModelInfo->m_vecAbsAngles.y, m_pModelInfo->m_vecAbsAngles.z );
+ matrix3x4_t matRotation;
+ AngleMatrix( angPanelAngles, matRotation );
+
+ Vector aXFormPoints[8];
+ for ( int iPoint = 0; iPoint < 8; ++iPoint )
+ {
+ VectorTransform( aBoundsPoints[iPoint], matRotation, aXFormPoints[iPoint] );
+ }
+
+ Vector vecXFormCenter;
+ VectorTransform( -vecTranslateCenter, matRotation, vecXFormCenter );
+
+ int w, h;
+ GetSize( w, h );
+ float flW = (float)w;
+ float flH = (float)h;
+
+ float flFOVx = DEG2RAD( m_nFOV * 0.5f );
+ float flFOVy = CalcFovY( ( m_nFOV * 0.5f ), flW/flH );
+ flFOVy = DEG2RAD( flFOVy );
+
+ float flTanFOVx = tan( flFOVx );
+ float flTanFOVy = tan( flFOVy );
+
+ // Find the max value of x, y, or z
+ float flDist = 0.0f;
+ for ( int iPoint = 0; iPoint < 8; ++iPoint )
+ {
+ float flDistZ = fabs( aXFormPoints[iPoint].z / flTanFOVy - aXFormPoints[iPoint].x );
+ float flDistY = fabs( aXFormPoints[iPoint].y / flTanFOVx - aXFormPoints[iPoint].x );
+ float flTestDist = MAX( flDistZ, flDistY );
+ flDist = MAX( flDist, flTestDist );
+ }
+
+ // Scale the object down by 10%.
+ flDist *= 1.10f;
+
+ // Add the framing offset.
+ vecXFormCenter += m_pModelInfo->m_vecFramedOriginOffset;
+
+ // Zoom to the frame distance
+ m_pModelInfo->m_vecOriginOffset.x = flDist - vecXFormCenter.x;
+ m_pModelInfo->m_vecOriginOffset.y = -vecXFormCenter.y;
+ m_pModelInfo->m_vecOriginOffset.z = -vecXFormCenter.z;
+
+ // Screen space points.
+ Vector2D aScreenPoints[8];
+ Vector aCameraPoints[8];
+ for ( int iPoint = 0; iPoint < 8; ++iPoint )
+ {
+ aCameraPoints[iPoint] = aXFormPoints[iPoint];
+ aCameraPoints[iPoint].x += flDist;
+
+ aScreenPoints[iPoint].x = aCameraPoints[iPoint].y / ( flTanFOVx * aCameraPoints[iPoint].x );
+ aScreenPoints[iPoint].y = aCameraPoints[iPoint].z / ( flTanFOVy * aCameraPoints[iPoint].x );
+
+ aScreenPoints[iPoint].x = ( aScreenPoints[iPoint].x * 0.5f + 0.5f ) * flW;
+ aScreenPoints[iPoint].y = ( aScreenPoints[iPoint].y * 0.5f + 0.5f ) * flH;
+ }
+
+ // Find the min/max and center of the 2D bounding box of the object.
+ Vector2D vecScreenMin( 99999.0f, 99999.0f ), vecScreenMax( -99999.0f, -99999.0f );
+ for ( int iPoint = 0; iPoint < 8; ++iPoint )
+ {
+ vecScreenMin.x = MIN( vecScreenMin.x, aScreenPoints[iPoint].x );
+ vecScreenMin.y = MIN( vecScreenMin.y, aScreenPoints[iPoint].y );
+ vecScreenMax.x = MAX( vecScreenMax.x, aScreenPoints[iPoint].x );
+ vecScreenMax.y = MAX( vecScreenMax.y, aScreenPoints[iPoint].y );
+ }
+
+ vecScreenMin.x = clamp( vecScreenMin.x, 0.0f, flW );
+ vecScreenMin.y = clamp( vecScreenMin.y, 0.0f, flH );
+ vecScreenMax.x = clamp( vecScreenMax.x, 0.0f, flW );
+ vecScreenMax.y = clamp( vecScreenMax.y, 0.0f, flH );
+
+ // Offset the view port based on the calculated model 2D center and the center of the viewport.
+ Vector2D vecScreenCenter = ( vecScreenMax + vecScreenMin ) * 0.5f;
+ m_pModelInfo->m_vecViewportOffset.x = -( ( flW * 0.5f ) - vecScreenCenter.x );
+ m_pModelInfo->m_vecViewportOffset.y = -( ( flH * 0.5f ) - vecScreenCenter.y );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Calculates the distance the camera should be at to frame the model on the screen.
+//-----------------------------------------------------------------------------
+void CModelPanel::CalculateFrameDistance( void )
+{
+ m_flFrameDistance = 0;
+ if ( !m_hModel )
+ return;
+
+ // Compute a bounding radius for the model
+ const model_t *mod = modelinfo->GetModel( m_hModel->GetModelIndex() );
+ if ( !mod )
+ return;
+
+ if ( m_bStartFramed )
+ {
+ CalculateFrameDistanceInternal( mod );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Moves the camera forward/backward along the current view angle to
+// frame the model on the screen.
+//-----------------------------------------------------------------------------
+void CModelPanel::ZoomToFrameDistance( void )
+{
+ if ( !m_flFrameDistance || !m_hModel )
+ return;
+
+ const model_t *mod = modelinfo->GetModel( m_hModel->GetModelIndex() );
+ if ( !mod )
+ return;
+
+ // Move the model to the midpoint
+ Vector mins, maxs, vecModelCenter;
+ modelinfo->GetModelRenderBounds( mod, mins, maxs );
+ VectorLerp( mins, maxs, 0.5f, vecModelCenter );
+
+ vecModelCenter += m_pModelInfo->m_vecFramedOriginOffset;
+
+ // Zoom to the frame distance
+ m_pModelInfo->m_vecOriginOffset.x = m_flFrameDistance;
+ m_pModelInfo->m_vecOriginOffset.y = -vecModelCenter.y;
+ m_pModelInfo->m_vecOriginOffset.z = -vecModelCenter.z;
+}
+
diff --git a/mp/src/game/client/game_controls/basemodelpanel.h b/mp/src/game/client/game_controls/basemodelpanel.h
index 0d264677..76c0058d 100644
--- a/mp/src/game/client/game_controls/basemodelpanel.h
+++ b/mp/src/game/client/game_controls/basemodelpanel.h
@@ -1,233 +1,233 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef BASEMODELPANEL_H
-#define BASEMODELPANEL_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui/IScheme.h>
-#include <vgui_controls/ImagePanel.h>
-#include <vgui_controls/EditablePanel.h>
-#include "GameEventListener.h"
-#include "KeyValues.h"
-
-class C_SceneEntity;
-
-
-class CModelPanelModel : public C_BaseFlex
-{
-public:
- CModelPanelModel(){}
- DECLARE_CLASS( CModelPanelModel, C_BaseFlex );
-
- virtual bool IsMenuModel() const{ return true; }
-};
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class CModelPanelModelAnimation
-{
-public:
- CModelPanelModelAnimation()
- {
- m_pszName = NULL;
- m_pszSequence = NULL;
- m_pszActivity = NULL;
- m_pPoseParameters = NULL;
- m_bDefault = false;
- }
-
- ~CModelPanelModelAnimation()
- {
- if ( m_pszName && m_pszName[0] )
- {
- delete [] m_pszName;
- m_pszName = NULL;
- }
-
- if ( m_pszSequence && m_pszSequence[0] )
- {
- delete [] m_pszSequence;
- m_pszSequence = NULL;
- }
-
- if ( m_pszActivity && m_pszActivity[0] )
- {
- delete [] m_pszActivity;
- m_pszActivity = NULL;
- }
-
- if ( m_pPoseParameters )
- {
- m_pPoseParameters->deleteThis();
- m_pPoseParameters = NULL;
- }
- }
-
-public:
- const char *m_pszName;
- const char *m_pszSequence;
- const char *m_pszActivity;
- KeyValues *m_pPoseParameters;
- bool m_bDefault;
-};
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class CModelPanelAttachedModelInfo
-{
-public:
- CModelPanelAttachedModelInfo()
- {
- m_pszModelName = NULL;
- m_nSkin = 0;
- }
-
- ~CModelPanelAttachedModelInfo()
- {
- if ( m_pszModelName && m_pszModelName[0] )
- {
- delete [] m_pszModelName;
- m_pszModelName = NULL;
- }
- }
-
-public:
- const char *m_pszModelName;
- int m_nSkin;
-};
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class CModelPanelModelInfo
-{
-public:
- CModelPanelModelInfo()
- {
- m_pszModelName = NULL;
- m_pszModelName_HWM = NULL;
- m_nSkin = -1;
- m_vecAbsAngles.Init();
- m_vecOriginOffset.Init();
- m_vecFramedOriginOffset.Init();
- m_bUseSpotlight = false;
- }
-
- ~CModelPanelModelInfo()
- {
- if ( m_pszModelName && m_pszModelName[0] )
- {
- delete [] m_pszModelName;
- m_pszModelName = NULL;
- }
-
- if ( m_pszModelName_HWM && m_pszModelName_HWM[0] )
- {
- delete [] m_pszModelName_HWM;
- m_pszModelName_HWM = NULL;
- }
-
- if ( m_pszVCD && m_pszVCD[0] )
- {
- delete [] m_pszVCD;
- m_pszVCD = NULL;
- }
-
- m_Animations.PurgeAndDeleteElements();
- m_AttachedModelsInfo.PurgeAndDeleteElements();
- }
-
-public:
- const char *m_pszModelName;
- const char *m_pszModelName_HWM;
- int m_nSkin;
- const char *m_pszVCD;
- Vector m_vecAbsAngles;
- Vector m_vecOriginOffset;
- Vector2D m_vecViewportOffset;
- Vector m_vecFramedOriginOffset;
- bool m_bUseSpotlight;
-
- CUtlVector<CModelPanelModelAnimation*> m_Animations;
- CUtlVector<CModelPanelAttachedModelInfo*> m_AttachedModelsInfo;
-};
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-class CModelPanel : public vgui::EditablePanel, public CGameEventListener
-{
-public:
- DECLARE_CLASS_SIMPLE( CModelPanel, vgui::EditablePanel );
-
- CModelPanel( vgui::Panel *parent, const char *name );
- virtual ~CModelPanel();
-
- virtual void Paint();
- virtual void ApplySettings( KeyValues *inResourceData );
- virtual void DeleteVCDData( void );
- virtual void DeleteModelData( void );
-
- virtual void SetFOV( int nFOV ){ m_nFOV = nFOV; }
- virtual void SetPanelDirty( void ){ m_bPanelDirty = true; }
- virtual bool SetSequence( const char *pszSequence );
-
- MESSAGE_FUNC_PARAMS( OnAddAnimation, "AddAnimation", data );
- MESSAGE_FUNC_PARAMS( OnSetAnimation, "SetAnimation", data );
-
- void SetDefaultAnimation( const char *pszName );
- void SwapModel( const char *pszName, const char *pszAttached = NULL );
-
- virtual void ParseModelInfo( KeyValues *inResourceData );
-
- void ClearAttachedModelInfos( void );
-
- void CalculateFrameDistance( void );
- void ZoomToFrameDistance( void );
-
- void UpdateModel();
-public: // IGameEventListener:
- virtual void FireGameEvent( IGameEvent * event );
-
-protected:
- virtual void SetupModel( void );
- virtual void SetupVCD( void );
- virtual const char *GetModelName( void );
-
-private:
- void InitCubeMaps();
- int FindAnimByName( const char *pszName );
- void CalculateFrameDistanceInternal( const model_t *pModel );
-
-public:
- int m_nFOV;
- float m_flFrameDistance;
- bool m_bStartFramed;
- CModelPanelModelInfo *m_pModelInfo;
-
- CHandle<CModelPanelModel> m_hModel;
- CUtlVector<CHandle<C_BaseAnimating> > m_AttachedModels;
-
- CHandle<C_SceneEntity> m_hScene;
-
-private:
- bool m_bPanelDirty;
- int m_iDefaultAnimation;
-
- bool m_bAllowOffscreen;
-
- CTextureReference m_DefaultEnvCubemap;
- CTextureReference m_DefaultHDREnvCubemap;
-};
-
-
-#endif // BASEMODELPANEL_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef BASEMODELPANEL_H
+#define BASEMODELPANEL_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui/IScheme.h>
+#include <vgui_controls/ImagePanel.h>
+#include <vgui_controls/EditablePanel.h>
+#include "GameEventListener.h"
+#include "KeyValues.h"
+
+class C_SceneEntity;
+
+
+class CModelPanelModel : public C_BaseFlex
+{
+public:
+ CModelPanelModel(){}
+ DECLARE_CLASS( CModelPanelModel, C_BaseFlex );
+
+ virtual bool IsMenuModel() const{ return true; }
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CModelPanelModelAnimation
+{
+public:
+ CModelPanelModelAnimation()
+ {
+ m_pszName = NULL;
+ m_pszSequence = NULL;
+ m_pszActivity = NULL;
+ m_pPoseParameters = NULL;
+ m_bDefault = false;
+ }
+
+ ~CModelPanelModelAnimation()
+ {
+ if ( m_pszName && m_pszName[0] )
+ {
+ delete [] m_pszName;
+ m_pszName = NULL;
+ }
+
+ if ( m_pszSequence && m_pszSequence[0] )
+ {
+ delete [] m_pszSequence;
+ m_pszSequence = NULL;
+ }
+
+ if ( m_pszActivity && m_pszActivity[0] )
+ {
+ delete [] m_pszActivity;
+ m_pszActivity = NULL;
+ }
+
+ if ( m_pPoseParameters )
+ {
+ m_pPoseParameters->deleteThis();
+ m_pPoseParameters = NULL;
+ }
+ }
+
+public:
+ const char *m_pszName;
+ const char *m_pszSequence;
+ const char *m_pszActivity;
+ KeyValues *m_pPoseParameters;
+ bool m_bDefault;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CModelPanelAttachedModelInfo
+{
+public:
+ CModelPanelAttachedModelInfo()
+ {
+ m_pszModelName = NULL;
+ m_nSkin = 0;
+ }
+
+ ~CModelPanelAttachedModelInfo()
+ {
+ if ( m_pszModelName && m_pszModelName[0] )
+ {
+ delete [] m_pszModelName;
+ m_pszModelName = NULL;
+ }
+ }
+
+public:
+ const char *m_pszModelName;
+ int m_nSkin;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CModelPanelModelInfo
+{
+public:
+ CModelPanelModelInfo()
+ {
+ m_pszModelName = NULL;
+ m_pszModelName_HWM = NULL;
+ m_nSkin = -1;
+ m_vecAbsAngles.Init();
+ m_vecOriginOffset.Init();
+ m_vecFramedOriginOffset.Init();
+ m_bUseSpotlight = false;
+ }
+
+ ~CModelPanelModelInfo()
+ {
+ if ( m_pszModelName && m_pszModelName[0] )
+ {
+ delete [] m_pszModelName;
+ m_pszModelName = NULL;
+ }
+
+ if ( m_pszModelName_HWM && m_pszModelName_HWM[0] )
+ {
+ delete [] m_pszModelName_HWM;
+ m_pszModelName_HWM = NULL;
+ }
+
+ if ( m_pszVCD && m_pszVCD[0] )
+ {
+ delete [] m_pszVCD;
+ m_pszVCD = NULL;
+ }
+
+ m_Animations.PurgeAndDeleteElements();
+ m_AttachedModelsInfo.PurgeAndDeleteElements();
+ }
+
+public:
+ const char *m_pszModelName;
+ const char *m_pszModelName_HWM;
+ int m_nSkin;
+ const char *m_pszVCD;
+ Vector m_vecAbsAngles;
+ Vector m_vecOriginOffset;
+ Vector2D m_vecViewportOffset;
+ Vector m_vecFramedOriginOffset;
+ bool m_bUseSpotlight;
+
+ CUtlVector<CModelPanelModelAnimation*> m_Animations;
+ CUtlVector<CModelPanelAttachedModelInfo*> m_AttachedModelsInfo;
+};
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+class CModelPanel : public vgui::EditablePanel, public CGameEventListener
+{
+public:
+ DECLARE_CLASS_SIMPLE( CModelPanel, vgui::EditablePanel );
+
+ CModelPanel( vgui::Panel *parent, const char *name );
+ virtual ~CModelPanel();
+
+ virtual void Paint();
+ virtual void ApplySettings( KeyValues *inResourceData );
+ virtual void DeleteVCDData( void );
+ virtual void DeleteModelData( void );
+
+ virtual void SetFOV( int nFOV ){ m_nFOV = nFOV; }
+ virtual void SetPanelDirty( void ){ m_bPanelDirty = true; }
+ virtual bool SetSequence( const char *pszSequence );
+
+ MESSAGE_FUNC_PARAMS( OnAddAnimation, "AddAnimation", data );
+ MESSAGE_FUNC_PARAMS( OnSetAnimation, "SetAnimation", data );
+
+ void SetDefaultAnimation( const char *pszName );
+ void SwapModel( const char *pszName, const char *pszAttached = NULL );
+
+ virtual void ParseModelInfo( KeyValues *inResourceData );
+
+ void ClearAttachedModelInfos( void );
+
+ void CalculateFrameDistance( void );
+ void ZoomToFrameDistance( void );
+
+ void UpdateModel();
+public: // IGameEventListener:
+ virtual void FireGameEvent( IGameEvent * event );
+
+protected:
+ virtual void SetupModel( void );
+ virtual void SetupVCD( void );
+ virtual const char *GetModelName( void );
+
+private:
+ void InitCubeMaps();
+ int FindAnimByName( const char *pszName );
+ void CalculateFrameDistanceInternal( const model_t *pModel );
+
+public:
+ int m_nFOV;
+ float m_flFrameDistance;
+ bool m_bStartFramed;
+ CModelPanelModelInfo *m_pModelInfo;
+
+ CHandle<CModelPanelModel> m_hModel;
+ CUtlVector<CHandle<C_BaseAnimating> > m_AttachedModels;
+
+ CHandle<C_SceneEntity> m_hScene;
+
+private:
+ bool m_bPanelDirty;
+ int m_iDefaultAnimation;
+
+ bool m_bAllowOffscreen;
+
+ CTextureReference m_DefaultEnvCubemap;
+ CTextureReference m_DefaultHDREnvCubemap;
+};
+
+
+#endif // BASEMODELPANEL_H
diff --git a/mp/src/game/client/game_controls/baseviewport.cpp b/mp/src/game/client/game_controls/baseviewport.cpp
index ad07f4c7..0b99ef63 100644
--- a/mp/src/game/client/game_controls/baseviewport.cpp
+++ b/mp/src/game/client/game_controls/baseviewport.cpp
@@ -1,721 +1,721 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Client DLL VGUI2 Viewport
-//
-// $Workfile: $
-// $Date: $
-//
-//-----------------------------------------------------------------------------
-// $Log: $
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#pragma warning( disable : 4800 ) // disable forcing int to bool performance warning
-
-#include "cbase.h"
-#include <cdll_client_int.h>
-#include <cdll_util.h>
-#include <globalvars_base.h>
-
-// VGUI panel includes
-#include <vgui_controls/Panel.h>
-#include <vgui_controls/AnimationController.h>
-#include <vgui/ISurface.h>
-#include <KeyValues.h>
-#include <vgui/IScheme.h>
-#include <vgui/IVGui.h>
-#include <vgui/ILocalize.h>
-#include <vgui/IPanel.h>
-#include <vgui_controls/Button.h>
-
-#include <igameresources.h>
-
-// sub dialogs
-#include "clientscoreboarddialog.h"
-#include "spectatorgui.h"
-#include "teammenu.h"
-#include "vguitextwindow.h"
-#include "IGameUIFuncs.h"
-#include "mapoverview.h"
-#include "hud.h"
-#include "NavProgress.h"
-#include "commentary_modelviewer.h"
-
-// our definition
-#include "baseviewport.h"
-#include <filesystem.h>
-#include <convar.h>
-#include "ienginevgui.h"
-#include "iclientmode.h"
-
-#include "tier0/etwprof.h"
-
-#if defined( REPLAY_ENABLED )
-#include "replay/ireplaysystem.h"
-#include "replay/ienginereplay.h"
-#endif
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-IViewPort *gViewPortInterface = NULL;
-
-vgui::Panel *g_lastPanel = NULL; // used for mouseover buttons, keeps track of the last active panel
-vgui::Button *g_lastButton = NULL; // used for mouseover buttons, keeps track of the last active button
-using namespace vgui;
-
-ConVar hud_autoreloadscript("hud_autoreloadscript", "0", FCVAR_NONE, "Automatically reloads the animation script each time one is ran");
-
-static ConVar cl_leveloverviewmarker( "cl_leveloverviewmarker", "0", FCVAR_CHEAT );
-
-CON_COMMAND( showpanel, "Shows a viewport panel <name>" )
-{
- if ( !gViewPortInterface )
- return;
-
- if ( args.ArgC() != 2 )
- return;
-
- gViewPortInterface->ShowPanel( args[ 1 ], true );
-}
-
-CON_COMMAND( hidepanel, "Hides a viewport panel <name>" )
-{
- if ( !gViewPortInterface )
- return;
-
- if ( args.ArgC() != 2 )
- return;
-
- gViewPortInterface->ShowPanel( args[ 1 ], false );
-}
-
-/* global helper functions
-
-bool Helper_LoadFile( IBaseFileSystem *pFileSystem, const char *pFilename, CUtlVector<char> &buf )
-{
- FileHandle_t hFile = pFileSystem->Open( pFilename, "rt" );
- if ( hFile == FILESYSTEM_INVALID_HANDLE )
- {
- Warning( "Helper_LoadFile: missing %s\n", pFilename );
- return false;
- }
-
- unsigned long len = pFileSystem->Size( hFile );
- buf.SetSize( len );
- pFileSystem->Read( buf.Base(), buf.Count(), hFile );
- pFileSystem->Close( hFile );
-
- return true;
-} */
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CBaseViewport::LoadHudAnimations( void )
-{
- const char *HUDANIMATION_MANIFEST_FILE = "scripts/hudanimations_manifest.txt";
- KeyValues *manifest = new KeyValues( HUDANIMATION_MANIFEST_FILE );
- if ( manifest->LoadFromFile( g_pFullFileSystem, HUDANIMATION_MANIFEST_FILE, "GAME" ) == false )
- {
- manifest->deleteThis();
- return false;
- }
-
- bool bClearScript = true;
-
- // Load each file defined in the text
- for ( KeyValues *sub = manifest->GetFirstSubKey(); sub != NULL; sub = sub->GetNextKey() )
- {
- if ( !Q_stricmp( sub->GetName(), "file" ) )
- {
- // Add it
- if ( m_pAnimController->SetScriptFile( GetVPanel(), sub->GetString(), bClearScript ) == false )
- {
- Assert( 0 );
- }
-
- bClearScript = false;
- continue;
- }
- }
-
- manifest->deleteThis();
- return true;
-}
-
-//================================================================
-CBaseViewport::CBaseViewport() : vgui::EditablePanel( NULL, "CBaseViewport")
-{
- SetSize( 10, 10 ); // Quiet "parent not sized yet" spew
- gViewPortInterface = this;
- m_bInitialized = false;
-
- m_GameuiFuncs = NULL;
- m_GameEventManager = NULL;
- SetKeyBoardInputEnabled( false );
- SetMouseInputEnabled( false );
-
-#ifndef _XBOX
- m_pBackGround = NULL;
-#endif
- m_bHasParent = false;
- m_pActivePanel = NULL;
- m_pLastActivePanel = NULL;
- g_lastPanel = NULL;
-
- vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
- SetScheme(scheme);
- SetProportional( true );
-
- m_pAnimController = new vgui::AnimationController(this);
- // create our animation controller
- m_pAnimController->SetScheme(scheme);
- m_pAnimController->SetProportional(true);
-
- // Attempt to load all hud animations
- if ( LoadHudAnimations() == false )
- {
- // Fall back to just the main
- if ( m_pAnimController->SetScriptFile( GetVPanel(), "scripts/HudAnimations.txt", true ) == false )
- {
- Assert(0);
- }
- }
-
- m_OldSize[ 0 ] = m_OldSize[ 1 ] = -1;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Updates hud to handle the new screen size
-//-----------------------------------------------------------------------------
-void CBaseViewport::OnScreenSizeChanged(int iOldWide, int iOldTall)
-{
- BaseClass::OnScreenSizeChanged(iOldWide, iOldTall);
-
- IViewPortPanel* pSpecGuiPanel = FindPanelByName(PANEL_SPECGUI);
- bool bSpecGuiWasVisible = pSpecGuiPanel && pSpecGuiPanel->IsVisible();
-
- // reload the script file, so the screen positions in it are correct for the new resolution
- ReloadScheme( NULL );
-
- // recreate all the default panels
- RemoveAllPanels();
-#ifndef _XBOX
- m_pBackGround = new CBackGroundPanel( NULL );
- m_pBackGround->SetZPos( -20 ); // send it to the back
- m_pBackGround->SetVisible( false );
-#endif
- CreateDefaultPanels();
-#ifndef _XBOX
- vgui::ipanel()->MoveToBack( m_pBackGround->GetVPanel() ); // really send it to the back
-#endif
-
- // hide all panels when reconnecting
- ShowPanel( PANEL_ALL, false );
-
- // re-enable the spectator gui if it was previously visible
- if ( bSpecGuiWasVisible )
- {
- ShowPanel( PANEL_SPECGUI, true );
- }
-}
-
-void CBaseViewport::CreateDefaultPanels( void )
-{
-#ifndef _XBOX
- AddNewPanel( CreatePanelByName( PANEL_SCOREBOARD ), "PANEL_SCOREBOARD" );
- AddNewPanel( CreatePanelByName( PANEL_INFO ), "PANEL_INFO" );
- AddNewPanel( CreatePanelByName( PANEL_SPECGUI ), "PANEL_SPECGUI" );
- AddNewPanel( CreatePanelByName( PANEL_SPECMENU ), "PANEL_SPECMENU" );
- AddNewPanel( CreatePanelByName( PANEL_NAV_PROGRESS ), "PANEL_NAV_PROGRESS" );
- // AddNewPanel( CreatePanelByName( PANEL_TEAM ), "PANEL_TEAM" );
- // AddNewPanel( CreatePanelByName( PANEL_CLASS ), "PANEL_CLASS" );
- // AddNewPanel( CreatePanelByName( PANEL_BUY ), "PANEL_BUY" );
-#endif
-}
-
-void CBaseViewport::UpdateAllPanels( void )
-{
- int count = m_Panels.Count();
-
- for (int i=0; i< count; i++ )
- {
- IViewPortPanel *p = m_Panels[i];
-
- if ( p->IsVisible() )
- {
- p->Update();
- }
- }
-}
-
-IViewPortPanel* CBaseViewport::CreatePanelByName(const char *szPanelName)
-{
- IViewPortPanel* newpanel = NULL;
-
-#ifndef _XBOX
- if ( Q_strcmp(PANEL_SCOREBOARD, szPanelName) == 0 )
- {
- newpanel = new CClientScoreBoardDialog( this );
- }
- else if ( Q_strcmp(PANEL_INFO, szPanelName) == 0 )
- {
- newpanel = new CTextWindow( this );
- }
-/* else if ( Q_strcmp(PANEL_OVERVIEW, szPanelName) == 0 )
- {
- newpanel = new CMapOverview( this );
- }
- */
- else if ( Q_strcmp(PANEL_TEAM, szPanelName) == 0 )
- {
- newpanel = new CTeamMenu( this );
- }
- else if ( Q_strcmp(PANEL_SPECMENU, szPanelName) == 0 )
- {
- newpanel = new CSpectatorMenu( this );
- }
- else if ( Q_strcmp(PANEL_SPECGUI, szPanelName) == 0 )
- {
- newpanel = new CSpectatorGUI( this );
- }
-#if !defined( TF_CLIENT_DLL )
- else if ( Q_strcmp(PANEL_NAV_PROGRESS, szPanelName) == 0 )
- {
- newpanel = new CNavProgress( this );
- }
-#endif // TF_CLIENT_DLL
-#endif
-
- if ( Q_strcmp(PANEL_COMMENTARY_MODELVIEWER, szPanelName) == 0 )
- {
- newpanel = new CCommentaryModelViewer( this );
- }
-
- return newpanel;
-}
-
-
-bool CBaseViewport::AddNewPanel( IViewPortPanel* pPanel, char const *pchDebugName )
-{
- if ( !pPanel )
- {
- DevMsg("CBaseViewport::AddNewPanel(%s): NULL panel.\n", pchDebugName );
- return false;
- }
-
- // we created a new panel, initialize it
- if ( FindPanelByName( pPanel->GetName() ) != NULL )
- {
- DevMsg("CBaseViewport::AddNewPanel: panel with name '%s' already exists.\n", pPanel->GetName() );
- return false;
- }
-
- m_Panels.AddToTail( pPanel );
- pPanel->SetParent( GetVPanel() );
-
- return true;
-}
-
-IViewPortPanel* CBaseViewport::FindPanelByName(const char *szPanelName)
-{
- int count = m_Panels.Count();
-
- for (int i=0; i< count; i++ )
- {
- if ( Q_strcmp(m_Panels[i]->GetName(), szPanelName) == 0 )
- return m_Panels[i];
- }
-
- return NULL;
-}
-
-void CBaseViewport::PostMessageToPanel( IViewPortPanel* pPanel, KeyValues *pKeyValues )
-{
- PostMessage( pPanel->GetVPanel(), pKeyValues );
-}
-
-void CBaseViewport::PostMessageToPanel( const char *pName, KeyValues *pKeyValues )
-{
- if ( Q_strcmp( pName, PANEL_ALL ) == 0 )
- {
- for (int i=0; i< m_Panels.Count(); i++ )
- {
- PostMessageToPanel( m_Panels[i], pKeyValues );
- }
-
- return;
- }
-
- IViewPortPanel * panel = NULL;
-
- if ( Q_strcmp( pName, PANEL_ACTIVE ) == 0 )
- {
- panel = m_pActivePanel;
- }
- else
- {
- panel = FindPanelByName( pName );
- }
-
- if ( !panel )
- return;
-
- PostMessageToPanel( panel, pKeyValues );
-}
-
-
-void CBaseViewport::ShowPanel( const char *pName, bool state )
-{
- if ( Q_strcmp( pName, PANEL_ALL ) == 0 )
- {
- for (int i=0; i< m_Panels.Count(); i++ )
- {
- ShowPanel( m_Panels[i], state );
- }
-
- return;
- }
-
- IViewPortPanel * panel = NULL;
-
- if ( Q_strcmp( pName, PANEL_ACTIVE ) == 0 )
- {
- panel = m_pActivePanel;
- }
- else
- {
- panel = FindPanelByName( pName );
- }
-
- if ( !panel )
- return;
-
- ShowPanel( panel, state );
-}
-
-void CBaseViewport::ShowPanel( IViewPortPanel* pPanel, bool state )
-{
- if ( state )
- {
- // if this is an 'active' panel, deactivate old active panel
- if ( pPanel->HasInputElements() )
- {
- // don't show input panels during normal demo playback
-#if defined( REPLAY_ENABLED )
- if ( engine->IsPlayingDemo() && !engine->IsHLTV() && !g_pEngineClientReplay->IsPlayingReplayDemo() )
-#else
- if ( engine->IsPlayingDemo() && !engine->IsHLTV() )
-#endif
- return;
- if ( (m_pActivePanel != NULL) && (m_pActivePanel != pPanel) && (m_pActivePanel->IsVisible()) )
- {
- // store a pointer to the currently active panel
- // so we can restore it later
- m_pLastActivePanel = m_pActivePanel;
- m_pActivePanel->ShowPanel( false );
- }
-
- m_pActivePanel = pPanel;
- }
- }
- else
- {
- // if this is our current active panel
- // update m_pActivePanel pointer
- if ( m_pActivePanel == pPanel )
- {
- m_pActivePanel = NULL;
- }
-
- // restore the previous active panel if it exists
- if( m_pLastActivePanel )
- {
- m_pActivePanel = m_pLastActivePanel;
- m_pLastActivePanel = NULL;
-
- m_pActivePanel->ShowPanel( true );
- }
- }
-
- // just show/hide panel
- pPanel->ShowPanel( state );
-
- UpdateAllPanels(); // let other panels rearrange
-}
-
-IViewPortPanel* CBaseViewport::GetActivePanel( void )
-{
- return m_pActivePanel;
-}
-
-void CBaseViewport::RemoveAllPanels( void)
-{
- g_lastPanel = NULL;
- for ( int i=0; i < m_Panels.Count(); i++ )
- {
- vgui::VPANEL vPanel = m_Panels[i]->GetVPanel();
- vgui::ipanel()->DeletePanel( vPanel );
- }
-#ifndef _XBOX
- if ( m_pBackGround )
- {
- m_pBackGround->MarkForDeletion();
- m_pBackGround = NULL;
- }
-#endif
- m_Panels.Purge();
- m_pActivePanel = NULL;
- m_pLastActivePanel = NULL;
-}
-
-CBaseViewport::~CBaseViewport()
-{
- m_bInitialized = false;
-
-#ifndef _XBOX
- if ( !m_bHasParent && m_pBackGround )
- {
- m_pBackGround->MarkForDeletion();
- }
- m_pBackGround = NULL;
-#endif
- RemoveAllPanels();
-
- gameeventmanager->RemoveListener( this );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: called when the VGUI subsystem starts up
-// Creates the sub panels and initialises them
-//-----------------------------------------------------------------------------
-void CBaseViewport::Start( IGameUIFuncs *pGameUIFuncs, IGameEventManager2 * pGameEventManager )
-{
- m_GameuiFuncs = pGameUIFuncs;
- m_GameEventManager = pGameEventManager;
-#ifndef _XBOX
- m_pBackGround = new CBackGroundPanel( NULL );
- m_pBackGround->SetZPos( -20 ); // send it to the back
- m_pBackGround->SetVisible( false );
-#endif
- CreateDefaultPanels();
-
- m_GameEventManager->AddListener( this, "game_newmap", false );
-
- m_bInitialized = true;
-}
-
-/*
-
-//-----------------------------------------------------------------------------
-// Purpose: Updates the spectator panel with new player info
-//-----------------------------------------------------------------------------
-void CBaseViewport::UpdateSpectatorPanel()
-{
- char bottomText[128];
- int player = -1;
- const char *name;
- Q_snprintf(bottomText,sizeof( bottomText ), "#Spec_Mode%d", m_pClientDllInterface->SpectatorMode() );
-
- m_pClientDllInterface->CheckSettings();
- // check if we're locked onto a target, show the player's name
- if ( (m_pClientDllInterface->SpectatorTarget() > 0) && (m_pClientDllInterface->SpectatorTarget() <= m_pClientDllInterface->GetMaxPlayers()) && (m_pClientDllInterface->SpectatorMode() != OBS_ROAMING) )
- {
- player = m_pClientDllInterface->SpectatorTarget();
- }
-
- // special case in free map and inset off, don't show names
- if ( ((m_pClientDllInterface->SpectatorMode() == OBS_MAP_FREE) && !m_pClientDllInterface->PipInsetOff()) || player == -1 )
- name = NULL;
- else
- name = m_pClientDllInterface->GetPlayerInfo(player).name;
-
- // create player & health string
- if ( player && name )
- {
- Q_strncpy( bottomText, name, sizeof( bottomText ) );
- }
- char szMapName[64];
- Q_FileBase( const_cast<char *>(m_pClientDllInterface->GetLevelName()), szMapName );
-
- m_pSpectatorGUI->Update(bottomText, player, m_pClientDllInterface->SpectatorMode(), m_pClientDllInterface->IsSpectateOnly(), m_pClientDllInterface->SpectatorNumber(), szMapName );
- m_pSpectatorGUI->UpdateSpectatorPlayerList();
-} */
-
-// Return TRUE if the HUD's allowed to print text messages
-bool CBaseViewport::AllowedToPrintText( void )
-{
-
- /* int iId = GetCurrentMenuID();
- if ( iId == MENU_TEAM || iId == MENU_CLASS || iId == MENU_INTRO || iId == MENU_CLASSHELP )
- return false; */
- // TODO ask every aktive elemet if it allows to draw text while visible
-
- return ( m_pActivePanel == NULL);
-}
-
-void CBaseViewport::OnThink()
-{
- // Clear our active panel pointer if the panel has made
- // itself invisible. Need this so we don't bring up dead panels
- // if they are stored as the last active panel
- if( m_pActivePanel && !m_pActivePanel->IsVisible() )
- {
- if( m_pLastActivePanel )
- {
- m_pActivePanel = m_pLastActivePanel;
- ShowPanel( m_pActivePanel, true );
- m_pLastActivePanel = NULL;
- }
- else
- m_pActivePanel = NULL;
- }
-
- m_pAnimController->UpdateAnimations( gpGlobals->curtime );
-
- // check the auto-reload cvar
- m_pAnimController->SetAutoReloadScript(hud_autoreloadscript.GetBool());
-
- int count = m_Panels.Count();
-
- for (int i=0; i< count; i++ )
- {
- IViewPortPanel *panel = m_Panels[i];
- if ( panel->NeedsUpdate() && panel->IsVisible() )
- {
- panel->Update();
- }
- }
-
- int w, h;
- vgui::ipanel()->GetSize( enginevgui->GetPanel( PANEL_CLIENTDLL ), w, h );
-
- if ( m_OldSize[ 0 ] != w || m_OldSize[ 1 ] != h )
- {
- m_OldSize[ 0 ] = w;
- m_OldSize[ 1 ] = h;
- g_pClientMode->Layout();
- }
-
- BaseClass::OnThink();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the parent for each panel to use
-//-----------------------------------------------------------------------------
-void CBaseViewport::SetParent(vgui::VPANEL parent)
-{
- EditablePanel::SetParent( parent );
- // force ourselves to be proportional - when we set our parent above, if our new
- // parent happened to be non-proportional (such as the vgui root panel), we got
- // slammed to be nonproportional
- EditablePanel::SetProportional( true );
-
-#ifndef _XBOX
- m_pBackGround->SetParent( (vgui::VPANEL)parent );
-#endif
-
- // set proportionality on animation controller
- m_pAnimController->SetProportional( true );
-
- m_bHasParent = (parent != 0);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: called when the engine shows the base client VGUI panel (i.e when entering a new level or exiting GameUI )
-//-----------------------------------------------------------------------------
-void CBaseViewport::ActivateClientUI()
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: called when the engine hides the base client VGUI panel (i.e when the GameUI is comming up )
-//-----------------------------------------------------------------------------
-void CBaseViewport::HideClientUI()
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: passes death msgs to the scoreboard to display specially
-//-----------------------------------------------------------------------------
-void CBaseViewport::FireGameEvent( IGameEvent * event)
-{
- const char * type = event->GetName();
-
- if ( Q_strcmp(type, "game_newmap") == 0 )
- {
- // hide all panels when reconnecting
- ShowPanel( PANEL_ALL, false );
-
- if ( engine->IsHLTV() )
- {
- ShowPanel( PANEL_SPECGUI, true );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CBaseViewport::ReloadScheme(const char *fromFile)
-{
- CETWScope timer( "CBaseViewport::ReloadScheme" );
-
- // See if scheme should change
-
- if ( fromFile != NULL )
- {
- // "resource/ClientScheme.res"
- vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), fromFile, "HudScheme" );
-
- SetScheme(scheme);
- SetProportional( true );
- m_pAnimController->SetScheme(scheme);
- }
-
- // Force a reload
- if ( LoadHudAnimations() == false )
- {
- // Fall back to just the main
- if ( m_pAnimController->SetScriptFile( GetVPanel(), "scripts/HudAnimations.txt", true ) == false )
- {
- Assert(0);
- }
- }
-
- SetProportional( true );
-
- KeyValuesAD pConditions( "conditions" );
- g_pClientMode->ComputeVguiResConditions( pConditions );
-
- // reload the .res file from disk
- LoadControlSettings( "scripts/HudLayout.res", NULL, NULL, pConditions );
-
- gHUD.RefreshHudTextures();
-
- InvalidateLayout( true, true );
-
- // reset the hud
- gHUD.ResetHUD();
-}
-
-int CBaseViewport::GetDeathMessageStartHeight( void )
-{
- return YRES(2);
-}
-
-void CBaseViewport::Paint()
-{
- if ( cl_leveloverviewmarker.GetInt() > 0 )
- {
- int size = cl_leveloverviewmarker.GetInt();
- // draw a 1024x1024 pixel box
- vgui::surface()->DrawSetColor( 255, 0, 0, 255 );
- vgui::surface()->DrawLine( size, 0, size, size );
- vgui::surface()->DrawLine( 0, size, size, size );
- }
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Client DLL VGUI2 Viewport
+//
+// $Workfile: $
+// $Date: $
+//
+//-----------------------------------------------------------------------------
+// $Log: $
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#pragma warning( disable : 4800 ) // disable forcing int to bool performance warning
+
+#include "cbase.h"
+#include <cdll_client_int.h>
+#include <cdll_util.h>
+#include <globalvars_base.h>
+
+// VGUI panel includes
+#include <vgui_controls/Panel.h>
+#include <vgui_controls/AnimationController.h>
+#include <vgui/ISurface.h>
+#include <KeyValues.h>
+#include <vgui/IScheme.h>
+#include <vgui/IVGui.h>
+#include <vgui/ILocalize.h>
+#include <vgui/IPanel.h>
+#include <vgui_controls/Button.h>
+
+#include <igameresources.h>
+
+// sub dialogs
+#include "clientscoreboarddialog.h"
+#include "spectatorgui.h"
+#include "teammenu.h"
+#include "vguitextwindow.h"
+#include "IGameUIFuncs.h"
+#include "mapoverview.h"
+#include "hud.h"
+#include "NavProgress.h"
+#include "commentary_modelviewer.h"
+
+// our definition
+#include "baseviewport.h"
+#include <filesystem.h>
+#include <convar.h>
+#include "ienginevgui.h"
+#include "iclientmode.h"
+
+#include "tier0/etwprof.h"
+
+#if defined( REPLAY_ENABLED )
+#include "replay/ireplaysystem.h"
+#include "replay/ienginereplay.h"
+#endif
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+IViewPort *gViewPortInterface = NULL;
+
+vgui::Panel *g_lastPanel = NULL; // used for mouseover buttons, keeps track of the last active panel
+vgui::Button *g_lastButton = NULL; // used for mouseover buttons, keeps track of the last active button
+using namespace vgui;
+
+ConVar hud_autoreloadscript("hud_autoreloadscript", "0", FCVAR_NONE, "Automatically reloads the animation script each time one is ran");
+
+static ConVar cl_leveloverviewmarker( "cl_leveloverviewmarker", "0", FCVAR_CHEAT );
+
+CON_COMMAND( showpanel, "Shows a viewport panel <name>" )
+{
+ if ( !gViewPortInterface )
+ return;
+
+ if ( args.ArgC() != 2 )
+ return;
+
+ gViewPortInterface->ShowPanel( args[ 1 ], true );
+}
+
+CON_COMMAND( hidepanel, "Hides a viewport panel <name>" )
+{
+ if ( !gViewPortInterface )
+ return;
+
+ if ( args.ArgC() != 2 )
+ return;
+
+ gViewPortInterface->ShowPanel( args[ 1 ], false );
+}
+
+/* global helper functions
+
+bool Helper_LoadFile( IBaseFileSystem *pFileSystem, const char *pFilename, CUtlVector<char> &buf )
+{
+ FileHandle_t hFile = pFileSystem->Open( pFilename, "rt" );
+ if ( hFile == FILESYSTEM_INVALID_HANDLE )
+ {
+ Warning( "Helper_LoadFile: missing %s\n", pFilename );
+ return false;
+ }
+
+ unsigned long len = pFileSystem->Size( hFile );
+ buf.SetSize( len );
+ pFileSystem->Read( buf.Base(), buf.Count(), hFile );
+ pFileSystem->Close( hFile );
+
+ return true;
+} */
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CBaseViewport::LoadHudAnimations( void )
+{
+ const char *HUDANIMATION_MANIFEST_FILE = "scripts/hudanimations_manifest.txt";
+ KeyValues *manifest = new KeyValues( HUDANIMATION_MANIFEST_FILE );
+ if ( manifest->LoadFromFile( g_pFullFileSystem, HUDANIMATION_MANIFEST_FILE, "GAME" ) == false )
+ {
+ manifest->deleteThis();
+ return false;
+ }
+
+ bool bClearScript = true;
+
+ // Load each file defined in the text
+ for ( KeyValues *sub = manifest->GetFirstSubKey(); sub != NULL; sub = sub->GetNextKey() )
+ {
+ if ( !Q_stricmp( sub->GetName(), "file" ) )
+ {
+ // Add it
+ if ( m_pAnimController->SetScriptFile( GetVPanel(), sub->GetString(), bClearScript ) == false )
+ {
+ Assert( 0 );
+ }
+
+ bClearScript = false;
+ continue;
+ }
+ }
+
+ manifest->deleteThis();
+ return true;
+}
+
+//================================================================
+CBaseViewport::CBaseViewport() : vgui::EditablePanel( NULL, "CBaseViewport")
+{
+ SetSize( 10, 10 ); // Quiet "parent not sized yet" spew
+ gViewPortInterface = this;
+ m_bInitialized = false;
+
+ m_GameuiFuncs = NULL;
+ m_GameEventManager = NULL;
+ SetKeyBoardInputEnabled( false );
+ SetMouseInputEnabled( false );
+
+#ifndef _XBOX
+ m_pBackGround = NULL;
+#endif
+ m_bHasParent = false;
+ m_pActivePanel = NULL;
+ m_pLastActivePanel = NULL;
+ g_lastPanel = NULL;
+
+ vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
+ SetScheme(scheme);
+ SetProportional( true );
+
+ m_pAnimController = new vgui::AnimationController(this);
+ // create our animation controller
+ m_pAnimController->SetScheme(scheme);
+ m_pAnimController->SetProportional(true);
+
+ // Attempt to load all hud animations
+ if ( LoadHudAnimations() == false )
+ {
+ // Fall back to just the main
+ if ( m_pAnimController->SetScriptFile( GetVPanel(), "scripts/HudAnimations.txt", true ) == false )
+ {
+ Assert(0);
+ }
+ }
+
+ m_OldSize[ 0 ] = m_OldSize[ 1 ] = -1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Updates hud to handle the new screen size
+//-----------------------------------------------------------------------------
+void CBaseViewport::OnScreenSizeChanged(int iOldWide, int iOldTall)
+{
+ BaseClass::OnScreenSizeChanged(iOldWide, iOldTall);
+
+ IViewPortPanel* pSpecGuiPanel = FindPanelByName(PANEL_SPECGUI);
+ bool bSpecGuiWasVisible = pSpecGuiPanel && pSpecGuiPanel->IsVisible();
+
+ // reload the script file, so the screen positions in it are correct for the new resolution
+ ReloadScheme( NULL );
+
+ // recreate all the default panels
+ RemoveAllPanels();
+#ifndef _XBOX
+ m_pBackGround = new CBackGroundPanel( NULL );
+ m_pBackGround->SetZPos( -20 ); // send it to the back
+ m_pBackGround->SetVisible( false );
+#endif
+ CreateDefaultPanels();
+#ifndef _XBOX
+ vgui::ipanel()->MoveToBack( m_pBackGround->GetVPanel() ); // really send it to the back
+#endif
+
+ // hide all panels when reconnecting
+ ShowPanel( PANEL_ALL, false );
+
+ // re-enable the spectator gui if it was previously visible
+ if ( bSpecGuiWasVisible )
+ {
+ ShowPanel( PANEL_SPECGUI, true );
+ }
+}
+
+void CBaseViewport::CreateDefaultPanels( void )
+{
+#ifndef _XBOX
+ AddNewPanel( CreatePanelByName( PANEL_SCOREBOARD ), "PANEL_SCOREBOARD" );
+ AddNewPanel( CreatePanelByName( PANEL_INFO ), "PANEL_INFO" );
+ AddNewPanel( CreatePanelByName( PANEL_SPECGUI ), "PANEL_SPECGUI" );
+ AddNewPanel( CreatePanelByName( PANEL_SPECMENU ), "PANEL_SPECMENU" );
+ AddNewPanel( CreatePanelByName( PANEL_NAV_PROGRESS ), "PANEL_NAV_PROGRESS" );
+ // AddNewPanel( CreatePanelByName( PANEL_TEAM ), "PANEL_TEAM" );
+ // AddNewPanel( CreatePanelByName( PANEL_CLASS ), "PANEL_CLASS" );
+ // AddNewPanel( CreatePanelByName( PANEL_BUY ), "PANEL_BUY" );
+#endif
+}
+
+void CBaseViewport::UpdateAllPanels( void )
+{
+ int count = m_Panels.Count();
+
+ for (int i=0; i< count; i++ )
+ {
+ IViewPortPanel *p = m_Panels[i];
+
+ if ( p->IsVisible() )
+ {
+ p->Update();
+ }
+ }
+}
+
+IViewPortPanel* CBaseViewport::CreatePanelByName(const char *szPanelName)
+{
+ IViewPortPanel* newpanel = NULL;
+
+#ifndef _XBOX
+ if ( Q_strcmp(PANEL_SCOREBOARD, szPanelName) == 0 )
+ {
+ newpanel = new CClientScoreBoardDialog( this );
+ }
+ else if ( Q_strcmp(PANEL_INFO, szPanelName) == 0 )
+ {
+ newpanel = new CTextWindow( this );
+ }
+/* else if ( Q_strcmp(PANEL_OVERVIEW, szPanelName) == 0 )
+ {
+ newpanel = new CMapOverview( this );
+ }
+ */
+ else if ( Q_strcmp(PANEL_TEAM, szPanelName) == 0 )
+ {
+ newpanel = new CTeamMenu( this );
+ }
+ else if ( Q_strcmp(PANEL_SPECMENU, szPanelName) == 0 )
+ {
+ newpanel = new CSpectatorMenu( this );
+ }
+ else if ( Q_strcmp(PANEL_SPECGUI, szPanelName) == 0 )
+ {
+ newpanel = new CSpectatorGUI( this );
+ }
+#if !defined( TF_CLIENT_DLL )
+ else if ( Q_strcmp(PANEL_NAV_PROGRESS, szPanelName) == 0 )
+ {
+ newpanel = new CNavProgress( this );
+ }
+#endif // TF_CLIENT_DLL
+#endif
+
+ if ( Q_strcmp(PANEL_COMMENTARY_MODELVIEWER, szPanelName) == 0 )
+ {
+ newpanel = new CCommentaryModelViewer( this );
+ }
+
+ return newpanel;
+}
+
+
+bool CBaseViewport::AddNewPanel( IViewPortPanel* pPanel, char const *pchDebugName )
+{
+ if ( !pPanel )
+ {
+ DevMsg("CBaseViewport::AddNewPanel(%s): NULL panel.\n", pchDebugName );
+ return false;
+ }
+
+ // we created a new panel, initialize it
+ if ( FindPanelByName( pPanel->GetName() ) != NULL )
+ {
+ DevMsg("CBaseViewport::AddNewPanel: panel with name '%s' already exists.\n", pPanel->GetName() );
+ return false;
+ }
+
+ m_Panels.AddToTail( pPanel );
+ pPanel->SetParent( GetVPanel() );
+
+ return true;
+}
+
+IViewPortPanel* CBaseViewport::FindPanelByName(const char *szPanelName)
+{
+ int count = m_Panels.Count();
+
+ for (int i=0; i< count; i++ )
+ {
+ if ( Q_strcmp(m_Panels[i]->GetName(), szPanelName) == 0 )
+ return m_Panels[i];
+ }
+
+ return NULL;
+}
+
+void CBaseViewport::PostMessageToPanel( IViewPortPanel* pPanel, KeyValues *pKeyValues )
+{
+ PostMessage( pPanel->GetVPanel(), pKeyValues );
+}
+
+void CBaseViewport::PostMessageToPanel( const char *pName, KeyValues *pKeyValues )
+{
+ if ( Q_strcmp( pName, PANEL_ALL ) == 0 )
+ {
+ for (int i=0; i< m_Panels.Count(); i++ )
+ {
+ PostMessageToPanel( m_Panels[i], pKeyValues );
+ }
+
+ return;
+ }
+
+ IViewPortPanel * panel = NULL;
+
+ if ( Q_strcmp( pName, PANEL_ACTIVE ) == 0 )
+ {
+ panel = m_pActivePanel;
+ }
+ else
+ {
+ panel = FindPanelByName( pName );
+ }
+
+ if ( !panel )
+ return;
+
+ PostMessageToPanel( panel, pKeyValues );
+}
+
+
+void CBaseViewport::ShowPanel( const char *pName, bool state )
+{
+ if ( Q_strcmp( pName, PANEL_ALL ) == 0 )
+ {
+ for (int i=0; i< m_Panels.Count(); i++ )
+ {
+ ShowPanel( m_Panels[i], state );
+ }
+
+ return;
+ }
+
+ IViewPortPanel * panel = NULL;
+
+ if ( Q_strcmp( pName, PANEL_ACTIVE ) == 0 )
+ {
+ panel = m_pActivePanel;
+ }
+ else
+ {
+ panel = FindPanelByName( pName );
+ }
+
+ if ( !panel )
+ return;
+
+ ShowPanel( panel, state );
+}
+
+void CBaseViewport::ShowPanel( IViewPortPanel* pPanel, bool state )
+{
+ if ( state )
+ {
+ // if this is an 'active' panel, deactivate old active panel
+ if ( pPanel->HasInputElements() )
+ {
+ // don't show input panels during normal demo playback
+#if defined( REPLAY_ENABLED )
+ if ( engine->IsPlayingDemo() && !engine->IsHLTV() && !g_pEngineClientReplay->IsPlayingReplayDemo() )
+#else
+ if ( engine->IsPlayingDemo() && !engine->IsHLTV() )
+#endif
+ return;
+ if ( (m_pActivePanel != NULL) && (m_pActivePanel != pPanel) && (m_pActivePanel->IsVisible()) )
+ {
+ // store a pointer to the currently active panel
+ // so we can restore it later
+ m_pLastActivePanel = m_pActivePanel;
+ m_pActivePanel->ShowPanel( false );
+ }
+
+ m_pActivePanel = pPanel;
+ }
+ }
+ else
+ {
+ // if this is our current active panel
+ // update m_pActivePanel pointer
+ if ( m_pActivePanel == pPanel )
+ {
+ m_pActivePanel = NULL;
+ }
+
+ // restore the previous active panel if it exists
+ if( m_pLastActivePanel )
+ {
+ m_pActivePanel = m_pLastActivePanel;
+ m_pLastActivePanel = NULL;
+
+ m_pActivePanel->ShowPanel( true );
+ }
+ }
+
+ // just show/hide panel
+ pPanel->ShowPanel( state );
+
+ UpdateAllPanels(); // let other panels rearrange
+}
+
+IViewPortPanel* CBaseViewport::GetActivePanel( void )
+{
+ return m_pActivePanel;
+}
+
+void CBaseViewport::RemoveAllPanels( void)
+{
+ g_lastPanel = NULL;
+ for ( int i=0; i < m_Panels.Count(); i++ )
+ {
+ vgui::VPANEL vPanel = m_Panels[i]->GetVPanel();
+ vgui::ipanel()->DeletePanel( vPanel );
+ }
+#ifndef _XBOX
+ if ( m_pBackGround )
+ {
+ m_pBackGround->MarkForDeletion();
+ m_pBackGround = NULL;
+ }
+#endif
+ m_Panels.Purge();
+ m_pActivePanel = NULL;
+ m_pLastActivePanel = NULL;
+}
+
+CBaseViewport::~CBaseViewport()
+{
+ m_bInitialized = false;
+
+#ifndef _XBOX
+ if ( !m_bHasParent && m_pBackGround )
+ {
+ m_pBackGround->MarkForDeletion();
+ }
+ m_pBackGround = NULL;
+#endif
+ RemoveAllPanels();
+
+ gameeventmanager->RemoveListener( this );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: called when the VGUI subsystem starts up
+// Creates the sub panels and initialises them
+//-----------------------------------------------------------------------------
+void CBaseViewport::Start( IGameUIFuncs *pGameUIFuncs, IGameEventManager2 * pGameEventManager )
+{
+ m_GameuiFuncs = pGameUIFuncs;
+ m_GameEventManager = pGameEventManager;
+#ifndef _XBOX
+ m_pBackGround = new CBackGroundPanel( NULL );
+ m_pBackGround->SetZPos( -20 ); // send it to the back
+ m_pBackGround->SetVisible( false );
+#endif
+ CreateDefaultPanels();
+
+ m_GameEventManager->AddListener( this, "game_newmap", false );
+
+ m_bInitialized = true;
+}
+
+/*
+
+//-----------------------------------------------------------------------------
+// Purpose: Updates the spectator panel with new player info
+//-----------------------------------------------------------------------------
+void CBaseViewport::UpdateSpectatorPanel()
+{
+ char bottomText[128];
+ int player = -1;
+ const char *name;
+ Q_snprintf(bottomText,sizeof( bottomText ), "#Spec_Mode%d", m_pClientDllInterface->SpectatorMode() );
+
+ m_pClientDllInterface->CheckSettings();
+ // check if we're locked onto a target, show the player's name
+ if ( (m_pClientDllInterface->SpectatorTarget() > 0) && (m_pClientDllInterface->SpectatorTarget() <= m_pClientDllInterface->GetMaxPlayers()) && (m_pClientDllInterface->SpectatorMode() != OBS_ROAMING) )
+ {
+ player = m_pClientDllInterface->SpectatorTarget();
+ }
+
+ // special case in free map and inset off, don't show names
+ if ( ((m_pClientDllInterface->SpectatorMode() == OBS_MAP_FREE) && !m_pClientDllInterface->PipInsetOff()) || player == -1 )
+ name = NULL;
+ else
+ name = m_pClientDllInterface->GetPlayerInfo(player).name;
+
+ // create player & health string
+ if ( player && name )
+ {
+ Q_strncpy( bottomText, name, sizeof( bottomText ) );
+ }
+ char szMapName[64];
+ Q_FileBase( const_cast<char *>(m_pClientDllInterface->GetLevelName()), szMapName );
+
+ m_pSpectatorGUI->Update(bottomText, player, m_pClientDllInterface->SpectatorMode(), m_pClientDllInterface->IsSpectateOnly(), m_pClientDllInterface->SpectatorNumber(), szMapName );
+ m_pSpectatorGUI->UpdateSpectatorPlayerList();
+} */
+
+// Return TRUE if the HUD's allowed to print text messages
+bool CBaseViewport::AllowedToPrintText( void )
+{
+
+ /* int iId = GetCurrentMenuID();
+ if ( iId == MENU_TEAM || iId == MENU_CLASS || iId == MENU_INTRO || iId == MENU_CLASSHELP )
+ return false; */
+ // TODO ask every aktive elemet if it allows to draw text while visible
+
+ return ( m_pActivePanel == NULL);
+}
+
+void CBaseViewport::OnThink()
+{
+ // Clear our active panel pointer if the panel has made
+ // itself invisible. Need this so we don't bring up dead panels
+ // if they are stored as the last active panel
+ if( m_pActivePanel && !m_pActivePanel->IsVisible() )
+ {
+ if( m_pLastActivePanel )
+ {
+ m_pActivePanel = m_pLastActivePanel;
+ ShowPanel( m_pActivePanel, true );
+ m_pLastActivePanel = NULL;
+ }
+ else
+ m_pActivePanel = NULL;
+ }
+
+ m_pAnimController->UpdateAnimations( gpGlobals->curtime );
+
+ // check the auto-reload cvar
+ m_pAnimController->SetAutoReloadScript(hud_autoreloadscript.GetBool());
+
+ int count = m_Panels.Count();
+
+ for (int i=0; i< count; i++ )
+ {
+ IViewPortPanel *panel = m_Panels[i];
+ if ( panel->NeedsUpdate() && panel->IsVisible() )
+ {
+ panel->Update();
+ }
+ }
+
+ int w, h;
+ vgui::ipanel()->GetSize( enginevgui->GetPanel( PANEL_CLIENTDLL ), w, h );
+
+ if ( m_OldSize[ 0 ] != w || m_OldSize[ 1 ] != h )
+ {
+ m_OldSize[ 0 ] = w;
+ m_OldSize[ 1 ] = h;
+ g_pClientMode->Layout();
+ }
+
+ BaseClass::OnThink();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the parent for each panel to use
+//-----------------------------------------------------------------------------
+void CBaseViewport::SetParent(vgui::VPANEL parent)
+{
+ EditablePanel::SetParent( parent );
+ // force ourselves to be proportional - when we set our parent above, if our new
+ // parent happened to be non-proportional (such as the vgui root panel), we got
+ // slammed to be nonproportional
+ EditablePanel::SetProportional( true );
+
+#ifndef _XBOX
+ m_pBackGround->SetParent( (vgui::VPANEL)parent );
+#endif
+
+ // set proportionality on animation controller
+ m_pAnimController->SetProportional( true );
+
+ m_bHasParent = (parent != 0);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: called when the engine shows the base client VGUI panel (i.e when entering a new level or exiting GameUI )
+//-----------------------------------------------------------------------------
+void CBaseViewport::ActivateClientUI()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: called when the engine hides the base client VGUI panel (i.e when the GameUI is comming up )
+//-----------------------------------------------------------------------------
+void CBaseViewport::HideClientUI()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: passes death msgs to the scoreboard to display specially
+//-----------------------------------------------------------------------------
+void CBaseViewport::FireGameEvent( IGameEvent * event)
+{
+ const char * type = event->GetName();
+
+ if ( Q_strcmp(type, "game_newmap") == 0 )
+ {
+ // hide all panels when reconnecting
+ ShowPanel( PANEL_ALL, false );
+
+ if ( engine->IsHLTV() )
+ {
+ ShowPanel( PANEL_SPECGUI, true );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CBaseViewport::ReloadScheme(const char *fromFile)
+{
+ CETWScope timer( "CBaseViewport::ReloadScheme" );
+
+ // See if scheme should change
+
+ if ( fromFile != NULL )
+ {
+ // "resource/ClientScheme.res"
+ vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), fromFile, "HudScheme" );
+
+ SetScheme(scheme);
+ SetProportional( true );
+ m_pAnimController->SetScheme(scheme);
+ }
+
+ // Force a reload
+ if ( LoadHudAnimations() == false )
+ {
+ // Fall back to just the main
+ if ( m_pAnimController->SetScriptFile( GetVPanel(), "scripts/HudAnimations.txt", true ) == false )
+ {
+ Assert(0);
+ }
+ }
+
+ SetProportional( true );
+
+ KeyValuesAD pConditions( "conditions" );
+ g_pClientMode->ComputeVguiResConditions( pConditions );
+
+ // reload the .res file from disk
+ LoadControlSettings( "scripts/HudLayout.res", NULL, NULL, pConditions );
+
+ gHUD.RefreshHudTextures();
+
+ InvalidateLayout( true, true );
+
+ // reset the hud
+ gHUD.ResetHUD();
+}
+
+int CBaseViewport::GetDeathMessageStartHeight( void )
+{
+ return YRES(2);
+}
+
+void CBaseViewport::Paint()
+{
+ if ( cl_leveloverviewmarker.GetInt() > 0 )
+ {
+ int size = cl_leveloverviewmarker.GetInt();
+ // draw a 1024x1024 pixel box
+ vgui::surface()->DrawSetColor( 255, 0, 0, 255 );
+ vgui::surface()->DrawLine( size, 0, size, size );
+ vgui::surface()->DrawLine( 0, size, size, size );
+ }
+}
diff --git a/mp/src/game/client/game_controls/baseviewport.h b/mp/src/game/client/game_controls/baseviewport.h
index ebbccd2a..4e4c64e8 100644
--- a/mp/src/game/client/game_controls/baseviewport.h
+++ b/mp/src/game/client/game_controls/baseviewport.h
@@ -1,148 +1,148 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef TEAMFORTRESSVIEWPORT_H
-#define TEAMFORTRESSVIEWPORT_H
-
-// viewport interface for the rest of the dll
-#include <game/client/iviewport.h>
-
-#include <utlqueue.h> // a vector based queue template to manage our VGUI menu queue
-#include <vgui_controls/Frame.h>
-#include "vguitextwindow.h"
-#include "vgui/ISurface.h"
-#include "commandmenu.h"
-#include <igameevents.h>
-
-using namespace vgui;
-
-class IBaseFileSystem;
-class IGameUIFuncs;
-class IGameEventManager;
-
-//==============================================================================
-class CBaseViewport : public vgui::EditablePanel, public IViewPort, public IGameEventListener2
-{
- DECLARE_CLASS_SIMPLE( CBaseViewport, vgui::EditablePanel );
-
-public:
- CBaseViewport();
- virtual ~CBaseViewport();
-
- virtual IViewPortPanel* CreatePanelByName(const char *szPanelName);
- virtual IViewPortPanel* FindPanelByName(const char *szPanelName);
- virtual IViewPortPanel* GetActivePanel( void );
- virtual void RemoveAllPanels( void);
-
- virtual void ShowPanel( const char *pName, bool state );
- virtual void ShowPanel( IViewPortPanel* pPanel, bool state );
- virtual bool AddNewPanel( IViewPortPanel* pPanel, char const *pchDebugName );
- virtual void CreateDefaultPanels( void );
- virtual void UpdateAllPanels( void );
- virtual void PostMessageToPanel( const char *pName, KeyValues *pKeyValues );
-
- virtual void Start( IGameUIFuncs *pGameUIFuncs, IGameEventManager2 *pGameEventManager );
- virtual void SetParent(vgui::VPANEL parent);
-
- virtual void ReloadScheme(const char *fromFile);
- virtual void ActivateClientUI();
- virtual void HideClientUI();
- virtual bool AllowedToPrintText( void );
-
-#ifndef _XBOX
- virtual int GetViewPortScheme() { return m_pBackGround->GetScheme(); }
- virtual VPANEL GetViewPortPanel() { return m_pBackGround->GetVParent(); }
-#endif
- virtual AnimationController *GetAnimationController() { return m_pAnimController; }
-
- virtual void ShowBackGround(bool bShow)
- {
-#ifndef _XBOX
- m_pBackGround->SetVisible( bShow );
-#endif
- }
-
- virtual int GetDeathMessageStartHeight( void );
-
- // virtual void ChatInputPosition( int *x, int *y );
-
-public: // IGameEventListener:
- virtual void FireGameEvent( IGameEvent * event);
-
-
-protected:
-
- bool LoadHudAnimations( void );
-
-#ifndef _XBOX
- class CBackGroundPanel : public vgui::Frame
- {
- private:
- typedef vgui::Frame BaseClass;
- public:
- CBackGroundPanel( vgui::Panel *parent) : Frame( parent, "ViewPortBackGround" )
- {
- SetScheme("ClientScheme");
-
- SetTitleBarVisible( false );
- SetMoveable(false);
- SetSizeable(false);
- SetProportional(true);
- }
- private:
-
- virtual void ApplySchemeSettings(IScheme *pScheme)
- {
- BaseClass::ApplySchemeSettings(pScheme);
- SetBgColor(pScheme->GetColor("ViewportBG", Color( 0,0,0,0 ) ));
- }
-
- virtual void PerformLayout()
- {
- int w,h;
- GetHudSize(w, h);
-
- // fill the screen
- SetBounds(0,0,w,h);
-
- BaseClass::PerformLayout();
- }
-
- virtual void OnMousePressed(MouseCode code) { }// don't respond to mouse clicks
- virtual vgui::VPANEL IsWithinTraverse( int x, int y, bool traversePopups )
- {
- return ( vgui::VPANEL )0;
- }
-
- };
-#endif
-protected:
-
- virtual void Paint();
- virtual void OnThink();
- virtual void OnScreenSizeChanged(int iOldWide, int iOldTall);
- void PostMessageToPanel( IViewPortPanel* pPanel, KeyValues *pKeyValues );
-
-protected:
- IGameUIFuncs* m_GameuiFuncs; // for key binding details
- IGameEventManager2* m_GameEventManager;
-#ifndef _XBOX
- CBackGroundPanel *m_pBackGround;
-#endif
- CUtlVector<IViewPortPanel*> m_Panels;
-
- bool m_bHasParent; // Used to track if child windows have parents or not.
- bool m_bInitialized;
- IViewPortPanel *m_pActivePanel;
- IViewPortPanel *m_pLastActivePanel;
- vgui::HCursor m_hCursorNone;
- vgui::AnimationController *m_pAnimController;
- int m_OldSize[2];
-};
-
-
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef TEAMFORTRESSVIEWPORT_H
+#define TEAMFORTRESSVIEWPORT_H
+
+// viewport interface for the rest of the dll
+#include <game/client/iviewport.h>
+
+#include <utlqueue.h> // a vector based queue template to manage our VGUI menu queue
+#include <vgui_controls/Frame.h>
+#include "vguitextwindow.h"
+#include "vgui/ISurface.h"
+#include "commandmenu.h"
+#include <igameevents.h>
+
+using namespace vgui;
+
+class IBaseFileSystem;
+class IGameUIFuncs;
+class IGameEventManager;
+
+//==============================================================================
+class CBaseViewport : public vgui::EditablePanel, public IViewPort, public IGameEventListener2
+{
+ DECLARE_CLASS_SIMPLE( CBaseViewport, vgui::EditablePanel );
+
+public:
+ CBaseViewport();
+ virtual ~CBaseViewport();
+
+ virtual IViewPortPanel* CreatePanelByName(const char *szPanelName);
+ virtual IViewPortPanel* FindPanelByName(const char *szPanelName);
+ virtual IViewPortPanel* GetActivePanel( void );
+ virtual void RemoveAllPanels( void);
+
+ virtual void ShowPanel( const char *pName, bool state );
+ virtual void ShowPanel( IViewPortPanel* pPanel, bool state );
+ virtual bool AddNewPanel( IViewPortPanel* pPanel, char const *pchDebugName );
+ virtual void CreateDefaultPanels( void );
+ virtual void UpdateAllPanels( void );
+ virtual void PostMessageToPanel( const char *pName, KeyValues *pKeyValues );
+
+ virtual void Start( IGameUIFuncs *pGameUIFuncs, IGameEventManager2 *pGameEventManager );
+ virtual void SetParent(vgui::VPANEL parent);
+
+ virtual void ReloadScheme(const char *fromFile);
+ virtual void ActivateClientUI();
+ virtual void HideClientUI();
+ virtual bool AllowedToPrintText( void );
+
+#ifndef _XBOX
+ virtual int GetViewPortScheme() { return m_pBackGround->GetScheme(); }
+ virtual VPANEL GetViewPortPanel() { return m_pBackGround->GetVParent(); }
+#endif
+ virtual AnimationController *GetAnimationController() { return m_pAnimController; }
+
+ virtual void ShowBackGround(bool bShow)
+ {
+#ifndef _XBOX
+ m_pBackGround->SetVisible( bShow );
+#endif
+ }
+
+ virtual int GetDeathMessageStartHeight( void );
+
+ // virtual void ChatInputPosition( int *x, int *y );
+
+public: // IGameEventListener:
+ virtual void FireGameEvent( IGameEvent * event);
+
+
+protected:
+
+ bool LoadHudAnimations( void );
+
+#ifndef _XBOX
+ class CBackGroundPanel : public vgui::Frame
+ {
+ private:
+ typedef vgui::Frame BaseClass;
+ public:
+ CBackGroundPanel( vgui::Panel *parent) : Frame( parent, "ViewPortBackGround" )
+ {
+ SetScheme("ClientScheme");
+
+ SetTitleBarVisible( false );
+ SetMoveable(false);
+ SetSizeable(false);
+ SetProportional(true);
+ }
+ private:
+
+ virtual void ApplySchemeSettings(IScheme *pScheme)
+ {
+ BaseClass::ApplySchemeSettings(pScheme);
+ SetBgColor(pScheme->GetColor("ViewportBG", Color( 0,0,0,0 ) ));
+ }
+
+ virtual void PerformLayout()
+ {
+ int w,h;
+ GetHudSize(w, h);
+
+ // fill the screen
+ SetBounds(0,0,w,h);
+
+ BaseClass::PerformLayout();
+ }
+
+ virtual void OnMousePressed(MouseCode code) { }// don't respond to mouse clicks
+ virtual vgui::VPANEL IsWithinTraverse( int x, int y, bool traversePopups )
+ {
+ return ( vgui::VPANEL )0;
+ }
+
+ };
+#endif
+protected:
+
+ virtual void Paint();
+ virtual void OnThink();
+ virtual void OnScreenSizeChanged(int iOldWide, int iOldTall);
+ void PostMessageToPanel( IViewPortPanel* pPanel, KeyValues *pKeyValues );
+
+protected:
+ IGameUIFuncs* m_GameuiFuncs; // for key binding details
+ IGameEventManager2* m_GameEventManager;
+#ifndef _XBOX
+ CBackGroundPanel *m_pBackGround;
+#endif
+ CUtlVector<IViewPortPanel*> m_Panels;
+
+ bool m_bHasParent; // Used to track if child windows have parents or not.
+ bool m_bInitialized;
+ IViewPortPanel *m_pActivePanel;
+ IViewPortPanel *m_pLastActivePanel;
+ vgui::HCursor m_hCursorNone;
+ vgui::AnimationController *m_pAnimController;
+ int m_OldSize[2];
+};
+
+
+#endif
diff --git a/mp/src/game/client/game_controls/buymenu.cpp b/mp/src/game/client/game_controls/buymenu.cpp
index 0b16f35d..40cbeab7 100644
--- a/mp/src/game/client/game_controls/buymenu.cpp
+++ b/mp/src/game/client/game_controls/buymenu.cpp
@@ -1,150 +1,150 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include "buymenu.h"
-
-#include "buysubmenu.h"
-using namespace vgui;
-
-#include "mouseoverpanelbutton.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CBuyMenu::CBuyMenu(IViewPort *pViewPort) : WizardPanel( NULL, PANEL_BUY )
-{
- SetScheme("ClientScheme");
- SetTitle( "#Cstrike_Buy_Menu", true);
-
- SetMoveable(false);
- SetSizeable(false);
- SetProportional(true);
-
- // hide the system buttons
- SetTitleBarVisible( false );
-
- SetAutoDelete( false ); // we reuse this panel, don't let WizardPanel delete us
-
- LoadControlSettings( "Resource/UI/BuyMenu.res" );
- ShowButtons( false );
-
- m_pViewPort = pViewPort;
-
- m_pMainMenu = new CBuySubMenu( this, "mainmenu" );
- m_pMainMenu->LoadControlSettings( "Resource/UI/MainBuyMenu.res" );
- m_pMainMenu->SetVisible( false );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Destructor
-//-----------------------------------------------------------------------------
-CBuyMenu::~CBuyMenu()
-{
- if ( m_pMainMenu )
- m_pMainMenu->DeleteSubPanels(); //?
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: shows/hides the buy menu
-//-----------------------------------------------------------------------------
-void CBuyMenu::ShowPanel(bool bShow)
-{
- if ( BaseClass::IsVisible() == bShow )
- return;
-
- if ( bShow )
- {
- Update();
-
- Run( m_pMainMenu );
-
- SetMouseInputEnabled( true );
-
- engine->ClientCmd_Unrestricted( "gameui_preventescapetoshow\n" );
- }
- else
- {
- engine->ClientCmd_Unrestricted( "gameui_allowescapetoshow\n" );
-
- SetVisible( false );
- SetMouseInputEnabled( false );
- }
-
- m_pViewPort->ShowBackGround( bShow );
-}
-
-
-void CBuyMenu::Update()
-{
- //Don't need to do anything, but do need to implement this function as base is pure virtual
- NULL;
-}
-void CBuyMenu::OnClose()
-{
- engine->ClientCmd_Unrestricted( "gameui_allowescapetoshow\n" );
-
- BaseClass::OnClose();
- ResetHistory();
-}
-
-void CBuyMenu::OnKeyCodePressed( vgui::KeyCode code )
-{
- int nDir = 0;
-
- switch ( code )
- {
- case KEY_XBUTTON_UP:
- case KEY_XSTICK1_UP:
- case KEY_XSTICK2_UP:
- case KEY_UP:
- nDir = -1;
- break;
-
- case KEY_XBUTTON_DOWN:
- case KEY_XSTICK1_DOWN:
- case KEY_XSTICK2_DOWN:
- case KEY_DOWN:
- nDir = 1;
- break;
- }
-
- if ( nDir != 0 )
- {
- Panel *pSubPanel = ( GetCurrentSubPanel() ? GetCurrentSubPanel() : m_pMainMenu );
-
- CUtlSortVector< SortedPanel_t, CSortedPanelYLess > vecSortedButtons;
- VguiPanelGetSortedChildButtonList( pSubPanel, (void*)&vecSortedButtons, "&", 0 );
-
- if ( VguiPanelNavigateSortedChildButtonList( (void*)&vecSortedButtons, nDir ) != -1 )
- {
- // Handled!
- return;
- }
- }
- else
- {
- BaseClass::OnKeyCodePressed( code );
- }
-}
-
-void CBuyMenu::OnKeyCodeTyped( KeyCode code )
-{
- if ( code == KEY_ESCAPE )
- {
- OnClose();
- }
- else
- {
- BaseClass::OnKeyCodeTyped( code );
- }
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "buymenu.h"
+
+#include "buysubmenu.h"
+using namespace vgui;
+
+#include "mouseoverpanelbutton.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CBuyMenu::CBuyMenu(IViewPort *pViewPort) : WizardPanel( NULL, PANEL_BUY )
+{
+ SetScheme("ClientScheme");
+ SetTitle( "#Cstrike_Buy_Menu", true);
+
+ SetMoveable(false);
+ SetSizeable(false);
+ SetProportional(true);
+
+ // hide the system buttons
+ SetTitleBarVisible( false );
+
+ SetAutoDelete( false ); // we reuse this panel, don't let WizardPanel delete us
+
+ LoadControlSettings( "Resource/UI/BuyMenu.res" );
+ ShowButtons( false );
+
+ m_pViewPort = pViewPort;
+
+ m_pMainMenu = new CBuySubMenu( this, "mainmenu" );
+ m_pMainMenu->LoadControlSettings( "Resource/UI/MainBuyMenu.res" );
+ m_pMainMenu->SetVisible( false );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor
+//-----------------------------------------------------------------------------
+CBuyMenu::~CBuyMenu()
+{
+ if ( m_pMainMenu )
+ m_pMainMenu->DeleteSubPanels(); //?
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: shows/hides the buy menu
+//-----------------------------------------------------------------------------
+void CBuyMenu::ShowPanel(bool bShow)
+{
+ if ( BaseClass::IsVisible() == bShow )
+ return;
+
+ if ( bShow )
+ {
+ Update();
+
+ Run( m_pMainMenu );
+
+ SetMouseInputEnabled( true );
+
+ engine->ClientCmd_Unrestricted( "gameui_preventescapetoshow\n" );
+ }
+ else
+ {
+ engine->ClientCmd_Unrestricted( "gameui_allowescapetoshow\n" );
+
+ SetVisible( false );
+ SetMouseInputEnabled( false );
+ }
+
+ m_pViewPort->ShowBackGround( bShow );
+}
+
+
+void CBuyMenu::Update()
+{
+ //Don't need to do anything, but do need to implement this function as base is pure virtual
+ NULL;
+}
+void CBuyMenu::OnClose()
+{
+ engine->ClientCmd_Unrestricted( "gameui_allowescapetoshow\n" );
+
+ BaseClass::OnClose();
+ ResetHistory();
+}
+
+void CBuyMenu::OnKeyCodePressed( vgui::KeyCode code )
+{
+ int nDir = 0;
+
+ switch ( code )
+ {
+ case KEY_XBUTTON_UP:
+ case KEY_XSTICK1_UP:
+ case KEY_XSTICK2_UP:
+ case KEY_UP:
+ nDir = -1;
+ break;
+
+ case KEY_XBUTTON_DOWN:
+ case KEY_XSTICK1_DOWN:
+ case KEY_XSTICK2_DOWN:
+ case KEY_DOWN:
+ nDir = 1;
+ break;
+ }
+
+ if ( nDir != 0 )
+ {
+ Panel *pSubPanel = ( GetCurrentSubPanel() ? GetCurrentSubPanel() : m_pMainMenu );
+
+ CUtlSortVector< SortedPanel_t, CSortedPanelYLess > vecSortedButtons;
+ VguiPanelGetSortedChildButtonList( pSubPanel, (void*)&vecSortedButtons, "&", 0 );
+
+ if ( VguiPanelNavigateSortedChildButtonList( (void*)&vecSortedButtons, nDir ) != -1 )
+ {
+ // Handled!
+ return;
+ }
+ }
+ else
+ {
+ BaseClass::OnKeyCodePressed( code );
+ }
+}
+
+void CBuyMenu::OnKeyCodeTyped( KeyCode code )
+{
+ if ( code == KEY_ESCAPE )
+ {
+ OnClose();
+ }
+ else
+ {
+ BaseClass::OnKeyCodeTyped( code );
+ }
+}
+
diff --git a/mp/src/game/client/game_controls/buymenu.h b/mp/src/game/client/game_controls/buymenu.h
index f392317d..bdaff26e 100644
--- a/mp/src/game/client/game_controls/buymenu.h
+++ b/mp/src/game/client/game_controls/buymenu.h
@@ -1,66 +1,66 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef BUYMENU_H
-#define BUYMENU_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui_controls/WizardPanel.h>
-#include <game/client/iviewport.h>
-#include "vgui/KeyCode.h"
-
-class CBuySubMenu;
-
-namespace vgui
-{
- class Panel;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Draws the class menu
-//-----------------------------------------------------------------------------
-class CBuyMenu : public vgui::WizardPanel, public IViewPortPanel
-{
-private:
- DECLARE_CLASS_SIMPLE( CBuyMenu, vgui::WizardPanel );
-
-public:
- CBuyMenu(IViewPort *pViewPort);
- ~CBuyMenu();
-
- virtual const char *GetName( void ) { return PANEL_BUY; }
- virtual void SetData(KeyValues *data) {};
- virtual void Reset() {};
- virtual void Update();
- virtual bool NeedsUpdate( void ) { return false; }
- virtual bool HasInputElements( void ) { return true; }
- virtual void ShowPanel( bool bShow );
-
- // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
- vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
- virtual bool IsVisible() { return BaseClass::IsVisible(); }
- virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
-
- virtual void OnKeyCodePressed( vgui::KeyCode code );
- virtual void OnKeyCodeTyped( vgui::KeyCode code );
-
-public:
- virtual void OnClose();
-
-protected:
-
- CBuySubMenu *m_pMainMenu;
- IViewPort *m_pViewPort;
-
- int m_iTeam;
- int m_iClass;
-};
-
-
-#endif // BUYMENU_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef BUYMENU_H
+#define BUYMENU_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui_controls/WizardPanel.h>
+#include <game/client/iviewport.h>
+#include "vgui/KeyCode.h"
+
+class CBuySubMenu;
+
+namespace vgui
+{
+ class Panel;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Draws the class menu
+//-----------------------------------------------------------------------------
+class CBuyMenu : public vgui::WizardPanel, public IViewPortPanel
+{
+private:
+ DECLARE_CLASS_SIMPLE( CBuyMenu, vgui::WizardPanel );
+
+public:
+ CBuyMenu(IViewPort *pViewPort);
+ ~CBuyMenu();
+
+ virtual const char *GetName( void ) { return PANEL_BUY; }
+ virtual void SetData(KeyValues *data) {};
+ virtual void Reset() {};
+ virtual void Update();
+ virtual bool NeedsUpdate( void ) { return false; }
+ virtual bool HasInputElements( void ) { return true; }
+ virtual void ShowPanel( bool bShow );
+
+ // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
+ vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
+ virtual bool IsVisible() { return BaseClass::IsVisible(); }
+ virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
+
+ virtual void OnKeyCodePressed( vgui::KeyCode code );
+ virtual void OnKeyCodeTyped( vgui::KeyCode code );
+
+public:
+ virtual void OnClose();
+
+protected:
+
+ CBuySubMenu *m_pMainMenu;
+ IViewPort *m_pViewPort;
+
+ int m_iTeam;
+ int m_iClass;
+};
+
+
+#endif // BUYMENU_H
diff --git a/mp/src/game/client/game_controls/buysubmenu.cpp b/mp/src/game/client/game_controls/buysubmenu.cpp
index f1ea2e4f..6bee2e5c 100644
--- a/mp/src/game/client/game_controls/buysubmenu.cpp
+++ b/mp/src/game/client/game_controls/buysubmenu.cpp
@@ -1,171 +1,171 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include "buysubmenu.h"
-
-#include <KeyValues.h>
-#include <vgui_controls/WizardPanel.h>
-#include <filesystem.h>
-#include <game/client/iviewport.h>
-#include <cdll_client_int.h>
-
-#include "mouseoverpanelbutton.h"
-// #include "cs_gamerules.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-using namespace vgui;
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CBuySubMenu::CBuySubMenu(vgui::Panel *parent, const char *name) : WizardSubPanel(parent, name)
-{
- m_NextPanel = NULL;
- m_pFirstButton = NULL;
- SetProportional(true);
-
- m_pPanel = new EditablePanel( this, "ItemInfo" );// info window about these items
- m_pPanel->SetProportional( true );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Destructor
-//-----------------------------------------------------------------------------
-CBuySubMenu::~CBuySubMenu()
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: magic override to allow vgui to create mouse over buttons for us
-//-----------------------------------------------------------------------------
-Panel *CBuySubMenu::CreateControlByName( const char *controlName )
-{
- if( !Q_stricmp( "MouseOverPanelButton", controlName ) )
- {
- MouseOverPanelButton *newButton = CreateNewMouseOverPanelButton( m_pPanel );
-
- if( !m_pFirstButton )
- {
- m_pFirstButton = newButton;
- }
- return newButton;
- }
- else
- {
- return BaseClass::CreateControlByName( controlName );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Make the first buttons page get displayed when the menu becomes visible
-//-----------------------------------------------------------------------------
-void CBuySubMenu::SetVisible( bool state )
-{
- BaseClass::SetVisible( state );
-
- for( int i = 0; i< GetChildCount(); i++ ) // get all the buy buttons to performlayout
- {
- MouseOverPanelButton *buyButton = dynamic_cast<MouseOverPanelButton *>(GetChild(i));
- if ( buyButton )
- {
- if( buyButton == m_pFirstButton && state == true )
- buyButton->ShowPage();
- else
- buyButton->HidePage();
-
- buyButton->InvalidateLayout();
- }
- }
-}
-
-CBuySubMenu* CBuySubMenu::CreateNewSubMenu()
-{
- return new CBuySubMenu( this );
-}
-
-MouseOverPanelButton* CBuySubMenu::CreateNewMouseOverPanelButton(EditablePanel *panel)
-{
- return new MouseOverPanelButton(this, NULL, panel);
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Called when the user picks a class
-//-----------------------------------------------------------------------------
-void CBuySubMenu::OnCommand( const char *command)
-{
- if ( Q_strstr( command, ".res" ) ) // if its a .res file then its a new menu
- {
- int i;
- // check the cache
- for ( i = 0; i < m_SubMenus.Count(); i++ )
- {
- if ( !Q_stricmp( m_SubMenus[i].filename, command ) )
- {
- m_NextPanel = m_SubMenus[i].panel;
- Assert( m_NextPanel );
- m_NextPanel->InvalidateLayout(); // force it to reset it prices
- break;
- }
- }
-
- if ( i == m_SubMenus.Count() )
- {
- // not there, add a new entry
- SubMenuEntry_t newEntry;
- memset( &newEntry, 0x0, sizeof( newEntry ) );
-
- CBuySubMenu *newMenu = CreateNewSubMenu();
- newMenu->LoadControlSettings( command );
- m_NextPanel = newMenu;
- Q_strncpy( newEntry.filename, command, sizeof( newEntry.filename ) );
- newEntry.panel = newMenu;
- m_SubMenus.AddToTail( newEntry );
- }
-
- GetWizardPanel()->OnNextButton();
- }
- else
- {
- GetWizardPanel()->Close();
- gViewPortInterface->ShowBackGround( false );
-
- if ( Q_stricmp( command, "vguicancel" ) != 0 )
- engine->ClientCmd( command );
-
- BaseClass::OnCommand(command);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Causes the panel to delete itself when it closes
-//-----------------------------------------------------------------------------
-void CBuySubMenu::DeleteSubPanels()
-{
- if ( m_NextPanel )
- {
- m_NextPanel->SetVisible( false );
- m_NextPanel = NULL;
- }
-
- m_pFirstButton = NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: return the next panel to show
-//-----------------------------------------------------------------------------
-vgui::WizardSubPanel *CBuySubMenu::GetNextSubPanel()
-{
- return m_NextPanel;
-}
-
-
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "buysubmenu.h"
+
+#include <KeyValues.h>
+#include <vgui_controls/WizardPanel.h>
+#include <filesystem.h>
+#include <game/client/iviewport.h>
+#include <cdll_client_int.h>
+
+#include "mouseoverpanelbutton.h"
+// #include "cs_gamerules.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CBuySubMenu::CBuySubMenu(vgui::Panel *parent, const char *name) : WizardSubPanel(parent, name)
+{
+ m_NextPanel = NULL;
+ m_pFirstButton = NULL;
+ SetProportional(true);
+
+ m_pPanel = new EditablePanel( this, "ItemInfo" );// info window about these items
+ m_pPanel->SetProportional( true );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor
+//-----------------------------------------------------------------------------
+CBuySubMenu::~CBuySubMenu()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: magic override to allow vgui to create mouse over buttons for us
+//-----------------------------------------------------------------------------
+Panel *CBuySubMenu::CreateControlByName( const char *controlName )
+{
+ if( !Q_stricmp( "MouseOverPanelButton", controlName ) )
+ {
+ MouseOverPanelButton *newButton = CreateNewMouseOverPanelButton( m_pPanel );
+
+ if( !m_pFirstButton )
+ {
+ m_pFirstButton = newButton;
+ }
+ return newButton;
+ }
+ else
+ {
+ return BaseClass::CreateControlByName( controlName );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Make the first buttons page get displayed when the menu becomes visible
+//-----------------------------------------------------------------------------
+void CBuySubMenu::SetVisible( bool state )
+{
+ BaseClass::SetVisible( state );
+
+ for( int i = 0; i< GetChildCount(); i++ ) // get all the buy buttons to performlayout
+ {
+ MouseOverPanelButton *buyButton = dynamic_cast<MouseOverPanelButton *>(GetChild(i));
+ if ( buyButton )
+ {
+ if( buyButton == m_pFirstButton && state == true )
+ buyButton->ShowPage();
+ else
+ buyButton->HidePage();
+
+ buyButton->InvalidateLayout();
+ }
+ }
+}
+
+CBuySubMenu* CBuySubMenu::CreateNewSubMenu()
+{
+ return new CBuySubMenu( this );
+}
+
+MouseOverPanelButton* CBuySubMenu::CreateNewMouseOverPanelButton(EditablePanel *panel)
+{
+ return new MouseOverPanelButton(this, NULL, panel);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Called when the user picks a class
+//-----------------------------------------------------------------------------
+void CBuySubMenu::OnCommand( const char *command)
+{
+ if ( Q_strstr( command, ".res" ) ) // if its a .res file then its a new menu
+ {
+ int i;
+ // check the cache
+ for ( i = 0; i < m_SubMenus.Count(); i++ )
+ {
+ if ( !Q_stricmp( m_SubMenus[i].filename, command ) )
+ {
+ m_NextPanel = m_SubMenus[i].panel;
+ Assert( m_NextPanel );
+ m_NextPanel->InvalidateLayout(); // force it to reset it prices
+ break;
+ }
+ }
+
+ if ( i == m_SubMenus.Count() )
+ {
+ // not there, add a new entry
+ SubMenuEntry_t newEntry;
+ memset( &newEntry, 0x0, sizeof( newEntry ) );
+
+ CBuySubMenu *newMenu = CreateNewSubMenu();
+ newMenu->LoadControlSettings( command );
+ m_NextPanel = newMenu;
+ Q_strncpy( newEntry.filename, command, sizeof( newEntry.filename ) );
+ newEntry.panel = newMenu;
+ m_SubMenus.AddToTail( newEntry );
+ }
+
+ GetWizardPanel()->OnNextButton();
+ }
+ else
+ {
+ GetWizardPanel()->Close();
+ gViewPortInterface->ShowBackGround( false );
+
+ if ( Q_stricmp( command, "vguicancel" ) != 0 )
+ engine->ClientCmd( command );
+
+ BaseClass::OnCommand(command);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Causes the panel to delete itself when it closes
+//-----------------------------------------------------------------------------
+void CBuySubMenu::DeleteSubPanels()
+{
+ if ( m_NextPanel )
+ {
+ m_NextPanel->SetVisible( false );
+ m_NextPanel = NULL;
+ }
+
+ m_pFirstButton = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: return the next panel to show
+//-----------------------------------------------------------------------------
+vgui::WizardSubPanel *CBuySubMenu::GetNextSubPanel()
+{
+ return m_NextPanel;
+}
+
+
+
+
diff --git a/mp/src/game/client/game_controls/buysubmenu.h b/mp/src/game/client/game_controls/buysubmenu.h
index 9cf7c79e..f3b8c256 100644
--- a/mp/src/game/client/game_controls/buysubmenu.h
+++ b/mp/src/game/client/game_controls/buysubmenu.h
@@ -1,59 +1,59 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef BUYSUBMENU_H
-#define BUYSUBMENU_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui_controls/WizardSubPanel.h>
-#include <vgui_controls/Button.h>
-#include <utlvector.h>
-#include "mouseoverpanelbutton.h"
-
-class CBuyMenu;
-
-//-----------------------------------------------------------------------------
-// Purpose: Draws the class menu
-//-----------------------------------------------------------------------------
-class CBuySubMenu : public vgui::WizardSubPanel
-{
-private:
- DECLARE_CLASS_SIMPLE( CBuySubMenu, vgui::WizardSubPanel );
-
-public:
- CBuySubMenu(vgui::Panel *parent,const char *name = "BuySubMenu");
- ~CBuySubMenu();
-
- virtual void SetVisible( bool state );
- virtual void DeleteSubPanels();
-
-protected:
-
- // command callbacks
- virtual void OnCommand( const char *command );
- virtual vgui::WizardSubPanel *GetNextSubPanel(); // this is the last menu in the list
- virtual vgui::Panel *CreateControlByName(const char *controlName);
- virtual CBuySubMenu* CreateNewSubMenu();
- virtual MouseOverPanelButton* CreateNewMouseOverPanelButton(vgui::EditablePanel *panel);
-
- typedef struct
- {
- char filename[_MAX_PATH];
- CBuySubMenu *panel;
- } SubMenuEntry_t;
-
- vgui::EditablePanel *m_pPanel;
- MouseOverPanelButton *m_pFirstButton;
-
- CUtlVector<SubMenuEntry_t> m_SubMenus; // a cache of buy submenus, so we don't need to construct them each time
-
- vgui::WizardSubPanel *m_NextPanel;
-};
-
-#endif // BUYSUBMENU_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef BUYSUBMENU_H
+#define BUYSUBMENU_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui_controls/WizardSubPanel.h>
+#include <vgui_controls/Button.h>
+#include <utlvector.h>
+#include "mouseoverpanelbutton.h"
+
+class CBuyMenu;
+
+//-----------------------------------------------------------------------------
+// Purpose: Draws the class menu
+//-----------------------------------------------------------------------------
+class CBuySubMenu : public vgui::WizardSubPanel
+{
+private:
+ DECLARE_CLASS_SIMPLE( CBuySubMenu, vgui::WizardSubPanel );
+
+public:
+ CBuySubMenu(vgui::Panel *parent,const char *name = "BuySubMenu");
+ ~CBuySubMenu();
+
+ virtual void SetVisible( bool state );
+ virtual void DeleteSubPanels();
+
+protected:
+
+ // command callbacks
+ virtual void OnCommand( const char *command );
+ virtual vgui::WizardSubPanel *GetNextSubPanel(); // this is the last menu in the list
+ virtual vgui::Panel *CreateControlByName(const char *controlName);
+ virtual CBuySubMenu* CreateNewSubMenu();
+ virtual MouseOverPanelButton* CreateNewMouseOverPanelButton(vgui::EditablePanel *panel);
+
+ typedef struct
+ {
+ char filename[_MAX_PATH];
+ CBuySubMenu *panel;
+ } SubMenuEntry_t;
+
+ vgui::EditablePanel *m_pPanel;
+ MouseOverPanelButton *m_pFirstButton;
+
+ CUtlVector<SubMenuEntry_t> m_SubMenus; // a cache of buy submenus, so we don't need to construct them each time
+
+ vgui::WizardSubPanel *m_NextPanel;
+};
+
+#endif // BUYSUBMENU_H
diff --git a/mp/src/game/client/game_controls/classmenu.cpp b/mp/src/game/client/game_controls/classmenu.cpp
index 64516f02..b71b75fa 100644
--- a/mp/src/game/client/game_controls/classmenu.cpp
+++ b/mp/src/game/client/game_controls/classmenu.cpp
@@ -1,316 +1,316 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-
-#include "cbase.h"
-#include <stdio.h>
-
-#include <cdll_client_int.h>
-
-#include "classmenu.h"
-
-#include <vgui/IScheme.h>
-#include <vgui/ILocalize.h>
-#include <vgui/ISurface.h>
-#include <KeyValues.h>
-#include <vgui_controls/ImageList.h>
-#include <filesystem.h>
-
-#include <vgui_controls/TextEntry.h>
-#include <vgui_controls/Button.h>
-#include <vgui_controls/Panel.h>
-
-#include "cdll_util.h"
-#include "IGameUIFuncs.h" // for key bindings
-#ifndef _XBOX
-extern IGameUIFuncs *gameuifuncs; // for key binding details
-#endif
-#include <game/client/iviewport.h>
-
-#include <stdlib.h> // MAX_PATH define
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-using namespace vgui;
-
-#ifdef TF_CLIENT_DLL
-#define HUD_CLASSAUTOKILL_FLAGS ( FCVAR_CLIENTDLL | FCVAR_ARCHIVE | FCVAR_USERINFO )
-#else
-#define HUD_CLASSAUTOKILL_FLAGS ( FCVAR_CLIENTDLL | FCVAR_ARCHIVE )
-#endif // !TF_CLIENT_DLL
-
-ConVar hud_classautokill( "hud_classautokill", "1", HUD_CLASSAUTOKILL_FLAGS, "Automatically kill player after choosing a new playerclass." );
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CClassMenu::CClassMenu(IViewPort *pViewPort) : Frame(NULL, PANEL_CLASS)
-{
- m_pViewPort = pViewPort;
- m_iScoreBoardKey = BUTTON_CODE_INVALID; // this is looked up in Activate()
- m_iTeam = 0;
-
- // 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 class
- m_pPanel = new EditablePanel( this, "ClassInfo" );
-
- LoadControlSettings( "Resource/UI/ClassMenu.res" );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CClassMenu::CClassMenu(IViewPort *pViewPort, const char *panelName) : Frame(NULL, panelName)
-{
- m_pViewPort = pViewPort;
- m_iScoreBoardKey = BUTTON_CODE_INVALID; // this is looked up in Activate()
- m_iTeam = 0;
-
- // 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 class
- m_pPanel = new EditablePanel( this, "ClassInfo" );
-
- // Inheriting classes are responsible for calling LoadControlSettings()!
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Destructor
-//-----------------------------------------------------------------------------
-CClassMenu::~CClassMenu()
-{
-}
-
-MouseOverPanelButton* CClassMenu::CreateNewMouseOverPanelButton(EditablePanel *panel)
-{
- return new MouseOverPanelButton(this, "MouseOverPanelButton", panel);
-}
-
-
-Panel *CClassMenu::CreateControlByName(const char *controlName)
-{
- if( !Q_stricmp( "MouseOverPanelButton", controlName ) )
- {
- MouseOverPanelButton *newButton = CreateNewMouseOverPanelButton( m_pPanel );
-
- m_mouseoverButtons.AddToTail( newButton );
- return newButton;
- }
- else
- {
- return BaseClass::CreateControlByName( controlName );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CClassMenu::Reset()
-{
- for ( int i = 0 ; i < GetChildCount() ; ++i )
- {
- // Hide the subpanel for the MouseOverPanelButtons
- MouseOverPanelButton *pPanel = dynamic_cast<MouseOverPanelButton *>( GetChild( i ) );
-
- if ( pPanel )
- {
- pPanel->HidePage();
- }
- }
-
- // Turn the first button back on again (so we have a default description shown)
- Assert( m_mouseoverButtons.Count() );
- for ( int i=0; i<m_mouseoverButtons.Count(); ++i )
- {
- if ( i == 0 )
- {
- m_mouseoverButtons[i]->ShowPage(); // Show the first page
- }
- else
- {
- m_mouseoverButtons[i]->HidePage(); // Hide the rest
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Called when the user picks a class
-//-----------------------------------------------------------------------------
-void CClassMenu::OnCommand( const char *command )
-{
- if ( Q_stricmp( command, "vguicancel" ) )
- {
- engine->ClientCmd( const_cast<char *>( command ) );
-
-#if !defined( CSTRIKE_DLL ) && !defined( TF_CLIENT_DLL )
- // They entered a command to change their class, kill them so they spawn with
- // the new class right away
- if ( hud_classautokill.GetBool() )
- {
- engine->ClientCmd( "kill" );
- }
-#endif // !CSTRIKE_DLL && !TF_CLIENT_DLL
- }
-
- Close();
-
- gViewPortInterface->ShowBackGround( false );
-
- BaseClass::OnCommand( command );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: shows the class menu
-//-----------------------------------------------------------------------------
-void CClassMenu::ShowPanel(bool bShow)
-{
- if ( bShow )
- {
- Activate();
- SetMouseInputEnabled( true );
-
- // load a default class page
- for ( int i=0; i<m_mouseoverButtons.Count(); ++i )
- {
- if ( i == 0 )
- {
- m_mouseoverButtons[i]->ShowPage(); // Show the first page
- }
- else
- {
- m_mouseoverButtons[i]->HidePage(); // Hide the rest
- }
- }
-
- if ( m_iScoreBoardKey == BUTTON_CODE_INVALID )
- {
- m_iScoreBoardKey = gameuifuncs->GetButtonCodeForBind( "showscores" );
- }
- }
- else
- {
- SetVisible( false );
- SetMouseInputEnabled( false );
- }
-
- m_pViewPort->ShowBackGround( bShow );
-}
-
-
-void CClassMenu::SetData(KeyValues *data)
-{
- m_iTeam = data->GetInt( "team" );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the text of a control by name
-//-----------------------------------------------------------------------------
-void CClassMenu::SetLabelText(const char *textEntryName, const char *text)
-{
- Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
- if (entry)
- {
- entry->SetText(text);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the visibility of a button by name
-//-----------------------------------------------------------------------------
-void CClassMenu::SetVisibleButton(const char *textEntryName, bool state)
-{
- Button *entry = dynamic_cast<Button *>(FindChildByName(textEntryName));
- if (entry)
- {
- entry->SetVisible(state);
- }
-}
-
-void CClassMenu::OnKeyCodePressed(KeyCode code)
-{
- int nDir = 0;
-
- switch ( code )
- {
- case KEY_XBUTTON_UP:
- case KEY_XSTICK1_UP:
- case KEY_XSTICK2_UP:
- case KEY_UP:
- case KEY_XBUTTON_LEFT:
- case KEY_XSTICK1_LEFT:
- case KEY_XSTICK2_LEFT:
- case KEY_LEFT:
- nDir = -1;
- break;
-
- case KEY_XBUTTON_DOWN:
- case KEY_XSTICK1_DOWN:
- case KEY_XSTICK2_DOWN:
- case KEY_DOWN:
- case KEY_XBUTTON_RIGHT:
- case KEY_XSTICK1_RIGHT:
- case KEY_XSTICK2_RIGHT:
- case KEY_RIGHT:
- nDir = 1;
- break;
- }
-
- if ( m_iScoreBoardKey != BUTTON_CODE_INVALID && m_iScoreBoardKey == code )
- {
- gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, true );
- gViewPortInterface->PostMessageToPanel( PANEL_SCOREBOARD, new KeyValues( "PollHideCode", "code", code ) );
- }
- else if ( nDir != 0 )
- {
- CUtlSortVector< SortedPanel_t, CSortedPanelYLess > vecSortedButtons;
- VguiPanelGetSortedChildButtonList( this, (void*)&vecSortedButtons, "&", 0 );
-
- int nNewArmed = VguiPanelNavigateSortedChildButtonList( (void*)&vecSortedButtons, nDir );
-
- if ( nNewArmed != -1 )
- {
- // Handled!
- if ( nNewArmed < m_mouseoverButtons.Count() )
- {
- m_mouseoverButtons[ nNewArmed ]->OnCursorEntered();
- }
- return;
- }
- }
- else
- {
- BaseClass::OnKeyCodePressed( code );
- }
-}
-
-
-
-
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+
+#include "cbase.h"
+#include <stdio.h>
+
+#include <cdll_client_int.h>
+
+#include "classmenu.h"
+
+#include <vgui/IScheme.h>
+#include <vgui/ILocalize.h>
+#include <vgui/ISurface.h>
+#include <KeyValues.h>
+#include <vgui_controls/ImageList.h>
+#include <filesystem.h>
+
+#include <vgui_controls/TextEntry.h>
+#include <vgui_controls/Button.h>
+#include <vgui_controls/Panel.h>
+
+#include "cdll_util.h"
+#include "IGameUIFuncs.h" // for key bindings
+#ifndef _XBOX
+extern IGameUIFuncs *gameuifuncs; // for key binding details
+#endif
+#include <game/client/iviewport.h>
+
+#include <stdlib.h> // MAX_PATH define
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+#ifdef TF_CLIENT_DLL
+#define HUD_CLASSAUTOKILL_FLAGS ( FCVAR_CLIENTDLL | FCVAR_ARCHIVE | FCVAR_USERINFO )
+#else
+#define HUD_CLASSAUTOKILL_FLAGS ( FCVAR_CLIENTDLL | FCVAR_ARCHIVE )
+#endif // !TF_CLIENT_DLL
+
+ConVar hud_classautokill( "hud_classautokill", "1", HUD_CLASSAUTOKILL_FLAGS, "Automatically kill player after choosing a new playerclass." );
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CClassMenu::CClassMenu(IViewPort *pViewPort) : Frame(NULL, PANEL_CLASS)
+{
+ m_pViewPort = pViewPort;
+ m_iScoreBoardKey = BUTTON_CODE_INVALID; // this is looked up in Activate()
+ m_iTeam = 0;
+
+ // 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 class
+ m_pPanel = new EditablePanel( this, "ClassInfo" );
+
+ LoadControlSettings( "Resource/UI/ClassMenu.res" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CClassMenu::CClassMenu(IViewPort *pViewPort, const char *panelName) : Frame(NULL, panelName)
+{
+ m_pViewPort = pViewPort;
+ m_iScoreBoardKey = BUTTON_CODE_INVALID; // this is looked up in Activate()
+ m_iTeam = 0;
+
+ // 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 class
+ m_pPanel = new EditablePanel( this, "ClassInfo" );
+
+ // Inheriting classes are responsible for calling LoadControlSettings()!
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor
+//-----------------------------------------------------------------------------
+CClassMenu::~CClassMenu()
+{
+}
+
+MouseOverPanelButton* CClassMenu::CreateNewMouseOverPanelButton(EditablePanel *panel)
+{
+ return new MouseOverPanelButton(this, "MouseOverPanelButton", panel);
+}
+
+
+Panel *CClassMenu::CreateControlByName(const char *controlName)
+{
+ if( !Q_stricmp( "MouseOverPanelButton", controlName ) )
+ {
+ MouseOverPanelButton *newButton = CreateNewMouseOverPanelButton( m_pPanel );
+
+ m_mouseoverButtons.AddToTail( newButton );
+ return newButton;
+ }
+ else
+ {
+ return BaseClass::CreateControlByName( controlName );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CClassMenu::Reset()
+{
+ for ( int i = 0 ; i < GetChildCount() ; ++i )
+ {
+ // Hide the subpanel for the MouseOverPanelButtons
+ MouseOverPanelButton *pPanel = dynamic_cast<MouseOverPanelButton *>( GetChild( i ) );
+
+ if ( pPanel )
+ {
+ pPanel->HidePage();
+ }
+ }
+
+ // Turn the first button back on again (so we have a default description shown)
+ Assert( m_mouseoverButtons.Count() );
+ for ( int i=0; i<m_mouseoverButtons.Count(); ++i )
+ {
+ if ( i == 0 )
+ {
+ m_mouseoverButtons[i]->ShowPage(); // Show the first page
+ }
+ else
+ {
+ m_mouseoverButtons[i]->HidePage(); // Hide the rest
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Called when the user picks a class
+//-----------------------------------------------------------------------------
+void CClassMenu::OnCommand( const char *command )
+{
+ if ( Q_stricmp( command, "vguicancel" ) )
+ {
+ engine->ClientCmd( const_cast<char *>( command ) );
+
+#if !defined( CSTRIKE_DLL ) && !defined( TF_CLIENT_DLL )
+ // They entered a command to change their class, kill them so they spawn with
+ // the new class right away
+ if ( hud_classautokill.GetBool() )
+ {
+ engine->ClientCmd( "kill" );
+ }
+#endif // !CSTRIKE_DLL && !TF_CLIENT_DLL
+ }
+
+ Close();
+
+ gViewPortInterface->ShowBackGround( false );
+
+ BaseClass::OnCommand( command );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: shows the class menu
+//-----------------------------------------------------------------------------
+void CClassMenu::ShowPanel(bool bShow)
+{
+ if ( bShow )
+ {
+ Activate();
+ SetMouseInputEnabled( true );
+
+ // load a default class page
+ for ( int i=0; i<m_mouseoverButtons.Count(); ++i )
+ {
+ if ( i == 0 )
+ {
+ m_mouseoverButtons[i]->ShowPage(); // Show the first page
+ }
+ else
+ {
+ m_mouseoverButtons[i]->HidePage(); // Hide the rest
+ }
+ }
+
+ if ( m_iScoreBoardKey == BUTTON_CODE_INVALID )
+ {
+ m_iScoreBoardKey = gameuifuncs->GetButtonCodeForBind( "showscores" );
+ }
+ }
+ else
+ {
+ SetVisible( false );
+ SetMouseInputEnabled( false );
+ }
+
+ m_pViewPort->ShowBackGround( bShow );
+}
+
+
+void CClassMenu::SetData(KeyValues *data)
+{
+ m_iTeam = data->GetInt( "team" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the text of a control by name
+//-----------------------------------------------------------------------------
+void CClassMenu::SetLabelText(const char *textEntryName, const char *text)
+{
+ Label *entry = dynamic_cast<Label *>(FindChildByName(textEntryName));
+ if (entry)
+ {
+ entry->SetText(text);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the visibility of a button by name
+//-----------------------------------------------------------------------------
+void CClassMenu::SetVisibleButton(const char *textEntryName, bool state)
+{
+ Button *entry = dynamic_cast<Button *>(FindChildByName(textEntryName));
+ if (entry)
+ {
+ entry->SetVisible(state);
+ }
+}
+
+void CClassMenu::OnKeyCodePressed(KeyCode code)
+{
+ int nDir = 0;
+
+ switch ( code )
+ {
+ case KEY_XBUTTON_UP:
+ case KEY_XSTICK1_UP:
+ case KEY_XSTICK2_UP:
+ case KEY_UP:
+ case KEY_XBUTTON_LEFT:
+ case KEY_XSTICK1_LEFT:
+ case KEY_XSTICK2_LEFT:
+ case KEY_LEFT:
+ nDir = -1;
+ break;
+
+ case KEY_XBUTTON_DOWN:
+ case KEY_XSTICK1_DOWN:
+ case KEY_XSTICK2_DOWN:
+ case KEY_DOWN:
+ case KEY_XBUTTON_RIGHT:
+ case KEY_XSTICK1_RIGHT:
+ case KEY_XSTICK2_RIGHT:
+ case KEY_RIGHT:
+ nDir = 1;
+ break;
+ }
+
+ if ( m_iScoreBoardKey != BUTTON_CODE_INVALID && m_iScoreBoardKey == code )
+ {
+ gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, true );
+ gViewPortInterface->PostMessageToPanel( PANEL_SCOREBOARD, new KeyValues( "PollHideCode", "code", code ) );
+ }
+ else if ( nDir != 0 )
+ {
+ CUtlSortVector< SortedPanel_t, CSortedPanelYLess > vecSortedButtons;
+ VguiPanelGetSortedChildButtonList( this, (void*)&vecSortedButtons, "&", 0 );
+
+ int nNewArmed = VguiPanelNavigateSortedChildButtonList( (void*)&vecSortedButtons, nDir );
+
+ if ( nNewArmed != -1 )
+ {
+ // Handled!
+ if ( nNewArmed < m_mouseoverButtons.Count() )
+ {
+ m_mouseoverButtons[ nNewArmed ]->OnCursorEntered();
+ }
+ return;
+ }
+ }
+ else
+ {
+ BaseClass::OnKeyCodePressed( code );
+ }
+}
+
+
+
+
+
+
diff --git a/mp/src/game/client/game_controls/classmenu.h b/mp/src/game/client/game_controls/classmenu.h
index 13a21227..16988559 100644
--- a/mp/src/game/client/game_controls/classmenu.h
+++ b/mp/src/game/client/game_controls/classmenu.h
@@ -1,79 +1,79 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef CLASSMENU_H
-#define CLASSMENU_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui_controls/Frame.h>
-#include <vgui_controls/Button.h>
-#include <vgui_controls/HTML.h>
-#include <utlvector.h>
-#include <vgui/ILocalize.h>
-#include <vgui/KeyCode.h>
-#include <game/client/iviewport.h>
-
-#include "mouseoverpanelbutton.h"
-
-namespace vgui
-{
- class TextEntry;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Draws the class menu
-//-----------------------------------------------------------------------------
-class CClassMenu : public vgui::Frame, public IViewPortPanel
-{
-private:
- DECLARE_CLASS_SIMPLE( CClassMenu, vgui::Frame );
-
-public:
- CClassMenu(IViewPort *pViewPort);
- CClassMenu(IViewPort *pViewPort, const char *panelName );
- virtual ~CClassMenu();
-
- virtual const char *GetName( void ) { return PANEL_CLASS; }
- virtual void SetData(KeyValues *data);
- virtual void Reset();
- virtual void Update() {};
- virtual bool NeedsUpdate( void ) { return false; }
- virtual bool HasInputElements( void ) { return true; }
- virtual void ShowPanel( bool bShow );
-
- // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
- vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
- virtual bool IsVisible() { return BaseClass::IsVisible(); }
- virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
-
-protected:
-
- virtual vgui::Panel *CreateControlByName(const char *controlName);
- virtual MouseOverPanelButton* CreateNewMouseOverPanelButton(vgui::EditablePanel *panel);
-
- //vgui2 overrides
- virtual void OnKeyCodePressed(vgui::KeyCode code);
-
- // helper functions
- void SetLabelText(const char *textEntryName, const char *text);
- void SetVisibleButton(const char *textEntryName, bool state);
-
- // command callbacks
- void OnCommand( const char *command );
-
- IViewPort *m_pViewPort;
- ButtonCode_t m_iScoreBoardKey;
- int m_iTeam;
- vgui::EditablePanel *m_pPanel;
-
- CUtlVector< MouseOverPanelButton * > m_mouseoverButtons;
-};
-
-
-#endif // CLASSMENU_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef CLASSMENU_H
+#define CLASSMENU_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui_controls/Frame.h>
+#include <vgui_controls/Button.h>
+#include <vgui_controls/HTML.h>
+#include <utlvector.h>
+#include <vgui/ILocalize.h>
+#include <vgui/KeyCode.h>
+#include <game/client/iviewport.h>
+
+#include "mouseoverpanelbutton.h"
+
+namespace vgui
+{
+ class TextEntry;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Draws the class menu
+//-----------------------------------------------------------------------------
+class CClassMenu : public vgui::Frame, public IViewPortPanel
+{
+private:
+ DECLARE_CLASS_SIMPLE( CClassMenu, vgui::Frame );
+
+public:
+ CClassMenu(IViewPort *pViewPort);
+ CClassMenu(IViewPort *pViewPort, const char *panelName );
+ virtual ~CClassMenu();
+
+ virtual const char *GetName( void ) { return PANEL_CLASS; }
+ virtual void SetData(KeyValues *data);
+ virtual void Reset();
+ virtual void Update() {};
+ virtual bool NeedsUpdate( void ) { return false; }
+ virtual bool HasInputElements( void ) { return true; }
+ virtual void ShowPanel( bool bShow );
+
+ // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
+ vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
+ virtual bool IsVisible() { return BaseClass::IsVisible(); }
+ virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
+
+protected:
+
+ virtual vgui::Panel *CreateControlByName(const char *controlName);
+ virtual MouseOverPanelButton* CreateNewMouseOverPanelButton(vgui::EditablePanel *panel);
+
+ //vgui2 overrides
+ virtual void OnKeyCodePressed(vgui::KeyCode code);
+
+ // helper functions
+ void SetLabelText(const char *textEntryName, const char *text);
+ void SetVisibleButton(const char *textEntryName, bool state);
+
+ // command callbacks
+ void OnCommand( const char *command );
+
+ IViewPort *m_pViewPort;
+ ButtonCode_t m_iScoreBoardKey;
+ int m_iTeam;
+ vgui::EditablePanel *m_pPanel;
+
+ CUtlVector< MouseOverPanelButton * > m_mouseoverButtons;
+};
+
+
+#endif // CLASSMENU_H
diff --git a/mp/src/game/client/game_controls/clientscoreboarddialog.h b/mp/src/game/client/game_controls/clientscoreboarddialog.h
index b6294cee..210934d8 100644
--- a/mp/src/game/client/game_controls/clientscoreboarddialog.h
+++ b/mp/src/game/client/game_controls/clientscoreboarddialog.h
@@ -1,127 +1,127 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef CLIENTSCOREBOARDDIALOG_H
-#define CLIENTSCOREBOARDDIALOG_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui_controls/EditablePanel.h>
-#include <game/client/iviewport.h>
-#include "GameEventListener.h"
-
-#define TYPE_NOTEAM 0 // NOTEAM must be zero :)
-#define TYPE_TEAM 1 // a section for a single team
-#define TYPE_PLAYERS 2
-#define TYPE_SPECTATORS 3 // a section for a spectator group
-#define TYPE_BLANK 4
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Game ScoreBoard
-//-----------------------------------------------------------------------------
-class CClientScoreBoardDialog : public vgui::EditablePanel, public IViewPortPanel, public CGameEventListener
-{
-private:
- DECLARE_CLASS_SIMPLE( CClientScoreBoardDialog, vgui::EditablePanel );
-
-protected:
-// column widths at 640
- enum { NAME_WIDTH = 160, SCORE_WIDTH = 60, DEATH_WIDTH = 60, PING_WIDTH = 80, VOICE_WIDTH = 0, FRIENDS_WIDTH = 0 };
- // total = 340
-
-public:
- CClientScoreBoardDialog( IViewPort *pViewPort );
- ~CClientScoreBoardDialog();
-
- virtual const char *GetName( void ) { return PANEL_SCOREBOARD; }
- virtual void SetData(KeyValues *data) {};
- virtual void Reset();
- virtual void Update();
- virtual bool NeedsUpdate( void );
- virtual bool HasInputElements( void ) { return true; }
- virtual void ShowPanel( bool bShow );
-
- virtual bool ShowAvatars()
- {
-#ifdef CSS_PERF_TEST
- return false;
-#endif
- return IsPC();
- }
-
- // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
- vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
- virtual bool IsVisible() { return BaseClass::IsVisible(); }
- virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
-
- // IGameEventListener interface:
- virtual void FireGameEvent( IGameEvent *event);
-
- virtual void UpdatePlayerAvatar( int playerIndex, KeyValues *kv );
-
-protected:
- MESSAGE_FUNC_INT( OnPollHideCode, "PollHideCode", code );
-
- // functions to override
- virtual bool GetPlayerScoreInfo(int playerIndex, KeyValues *outPlayerInfo);
- virtual void InitScoreboardSections();
- virtual void UpdateTeamInfo();
- virtual void UpdatePlayerInfo();
- virtual void OnThink();
- virtual void AddHeader(); // add the start header of the scoreboard
- virtual void AddSection(int teamType, int teamNumber); // add a new section header for a team
- virtual int GetAdditionalHeight() { return 0; }
-
- // sorts players within a section
- static bool StaticPlayerSortFunc(vgui::SectionedListPanel *list, int itemID1, int itemID2);
-
- virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
-
- virtual void PostApplySchemeSettings( vgui::IScheme *pScheme );
-
- // finds the player in the scoreboard
- int FindItemIDForPlayerIndex(int playerIndex);
-
- int m_iNumTeams;
-
- vgui::SectionedListPanel *m_pPlayerList;
- int m_iSectionId; // the current section we are entering into
-
- int s_VoiceImage[5];
- int TrackerImage;
- int m_HLTVSpectators;
- int m_ReplaySpectators;
- float m_fNextUpdateTime;
-
- void MoveLabelToFront(const char *textEntryName);
- void MoveToCenterOfScreen();
-
- vgui::ImageList *m_pImageList;
- CUtlMap<CSteamID,int> m_mapAvatarsToImageList;
-
- CPanelAnimationVar( int, m_iAvatarWidth, "avatar_width", "34" ); // Avatar width doesn't scale with resolution
- CPanelAnimationVarAliasType( int, m_iNameWidth, "name_width", "136", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iClassWidth, "class_width", "35", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iScoreWidth, "score_width", "35", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iDeathWidth, "death_width", "35", "proportional_int" );
- CPanelAnimationVarAliasType( int, m_iPingWidth, "ping_width", "23", "proportional_int" );
-
-private:
- int m_iPlayerIndexSymbol;
- int m_iDesiredHeight;
- IViewPort *m_pViewPort;
- ButtonCode_t m_nCloseKey;
-
-
- // methods
- void FillScoreBoard();
-};
-
-
-#endif // CLIENTSCOREBOARDDIALOG_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef CLIENTSCOREBOARDDIALOG_H
+#define CLIENTSCOREBOARDDIALOG_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui_controls/EditablePanel.h>
+#include <game/client/iviewport.h>
+#include "GameEventListener.h"
+
+#define TYPE_NOTEAM 0 // NOTEAM must be zero :)
+#define TYPE_TEAM 1 // a section for a single team
+#define TYPE_PLAYERS 2
+#define TYPE_SPECTATORS 3 // a section for a spectator group
+#define TYPE_BLANK 4
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Game ScoreBoard
+//-----------------------------------------------------------------------------
+class CClientScoreBoardDialog : public vgui::EditablePanel, public IViewPortPanel, public CGameEventListener
+{
+private:
+ DECLARE_CLASS_SIMPLE( CClientScoreBoardDialog, vgui::EditablePanel );
+
+protected:
+// column widths at 640
+ enum { NAME_WIDTH = 160, SCORE_WIDTH = 60, DEATH_WIDTH = 60, PING_WIDTH = 80, VOICE_WIDTH = 0, FRIENDS_WIDTH = 0 };
+ // total = 340
+
+public:
+ CClientScoreBoardDialog( IViewPort *pViewPort );
+ ~CClientScoreBoardDialog();
+
+ virtual const char *GetName( void ) { return PANEL_SCOREBOARD; }
+ virtual void SetData(KeyValues *data) {};
+ virtual void Reset();
+ virtual void Update();
+ virtual bool NeedsUpdate( void );
+ virtual bool HasInputElements( void ) { return true; }
+ virtual void ShowPanel( bool bShow );
+
+ virtual bool ShowAvatars()
+ {
+#ifdef CSS_PERF_TEST
+ return false;
+#endif
+ return IsPC();
+ }
+
+ // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
+ vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
+ virtual bool IsVisible() { return BaseClass::IsVisible(); }
+ virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
+
+ // IGameEventListener interface:
+ virtual void FireGameEvent( IGameEvent *event);
+
+ virtual void UpdatePlayerAvatar( int playerIndex, KeyValues *kv );
+
+protected:
+ MESSAGE_FUNC_INT( OnPollHideCode, "PollHideCode", code );
+
+ // functions to override
+ virtual bool GetPlayerScoreInfo(int playerIndex, KeyValues *outPlayerInfo);
+ virtual void InitScoreboardSections();
+ virtual void UpdateTeamInfo();
+ virtual void UpdatePlayerInfo();
+ virtual void OnThink();
+ virtual void AddHeader(); // add the start header of the scoreboard
+ virtual void AddSection(int teamType, int teamNumber); // add a new section header for a team
+ virtual int GetAdditionalHeight() { return 0; }
+
+ // sorts players within a section
+ static bool StaticPlayerSortFunc(vgui::SectionedListPanel *list, int itemID1, int itemID2);
+
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
+
+ virtual void PostApplySchemeSettings( vgui::IScheme *pScheme );
+
+ // finds the player in the scoreboard
+ int FindItemIDForPlayerIndex(int playerIndex);
+
+ int m_iNumTeams;
+
+ vgui::SectionedListPanel *m_pPlayerList;
+ int m_iSectionId; // the current section we are entering into
+
+ int s_VoiceImage[5];
+ int TrackerImage;
+ int m_HLTVSpectators;
+ int m_ReplaySpectators;
+ float m_fNextUpdateTime;
+
+ void MoveLabelToFront(const char *textEntryName);
+ void MoveToCenterOfScreen();
+
+ vgui::ImageList *m_pImageList;
+ CUtlMap<CSteamID,int> m_mapAvatarsToImageList;
+
+ CPanelAnimationVar( int, m_iAvatarWidth, "avatar_width", "34" ); // Avatar width doesn't scale with resolution
+ CPanelAnimationVarAliasType( int, m_iNameWidth, "name_width", "136", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iClassWidth, "class_width", "35", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iScoreWidth, "score_width", "35", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iDeathWidth, "death_width", "35", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iPingWidth, "ping_width", "23", "proportional_int" );
+
+private:
+ int m_iPlayerIndexSymbol;
+ int m_iDesiredHeight;
+ IViewPort *m_pViewPort;
+ ButtonCode_t m_nCloseKey;
+
+
+ // methods
+ void FillScoreBoard();
+};
+
+
+#endif // CLIENTSCOREBOARDDIALOG_H
diff --git a/mp/src/game/client/game_controls/commandmenu.cpp b/mp/src/game/client/game_controls/commandmenu.cpp
index 492e3d57..f86b2f21 100644
--- a/mp/src/game/client/game_controls/commandmenu.cpp
+++ b/mp/src/game/client/game_controls/commandmenu.cpp
@@ -1,361 +1,361 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//===========================================================================//
-
-#include "cbase.h"
-#include <cdll_client_int.h>
-#include <cdll_util.h>
-#include <globalvars_base.h>
-#include <icvar.h>
-#include <filesystem.h>
-
-#include "commandmenu.h"
-#include "vgui_controls/MenuItem.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-
-CommandMenu::CommandMenu( Panel *parent, const char *panelName, IViewPort * viewport) : Menu( parent, panelName )
-{
- if ( !viewport )
- return;
-
- m_ViewPort = viewport;
- SetVisible( false );
- m_CurrentMenu = this;
-
- m_MenuKeys = NULL;
-}
-
-bool CommandMenu::LoadFromFile( const char * fileName) // load menu from KeyValues
-{
- KeyValues * kv = new KeyValues(fileName);
-
- if ( !kv->LoadFromFile( g_pFullFileSystem, fileName, "GAME" ) )
- return false;
-
- bool ret = LoadFromKeyValues( kv );
-
- kv->deleteThis();
- return ret;
-}
-
-CommandMenu::~CommandMenu()
-{
- ClearMenu();
-}
-
-void CommandMenu::OnMessage(const KeyValues *params, VPANEL fromPanel)
-{
- char text[255];
- bool bHandled = false;
-
- KeyValues *param1 = const_cast<KeyValues *>(params);
-
- // toggle attached cvar, if any
- Q_strncpy( text, param1->GetString("toggle"), sizeof( text ) );
-
- if ( text[0] )
- {
- ConVarRef convar( text );
- if ( convar.IsValid() )
- {
- // toggle cvar
-
- if ( convar.GetInt() )
- {
- convar.SetValue( 0 );
- }
- else
- {
- convar.SetValue( 1 );
- }
-
- UpdateMenu();
- }
- else
- {
- Msg("CommandComboBox::OnMessage: cvar %s not found.\n", param1->GetString("typedata") );
- }
-
- bHandled = true;
- }
-
- // execute attached command, if any
- Q_strncpy( text, param1->GetString("command"), sizeof( text ) );
- if ( text[0] )
- {
- engine->ClientCmd( text );
- bHandled = true;
- }
-
- // fire custom message, if any
- Q_strncpy( text, param1->GetString("custom"), sizeof( text ) );
- if ( text[0] )
- {
- OnCustomItem( param1 ); // let derived class decide what to do
- bHandled = true;
- }
-
- if ( bHandled )
- {
- PostMessage( GetParent(), new KeyValues("CommandMenuClosed") );
- }
-
- BaseClass::OnMessage( params, fromPanel );
-}
-
-void CommandMenu::StartNewSubMenu(KeyValues * params)
-{
- CommandMenuItem menuitem;
- menuitem.menu = m_CurrentMenu;
-
- Menu * menu = new Menu( this, params->GetString("name") ); // create new menu
-
- menuitem.itemnr = m_CurrentMenu->AddCascadingMenuItem( params->GetString("label"), this, menu, params ); // add to current menu as item
-
- m_MenuItems.AddToTail( menuitem ); // add to global list
-
- m_pMenuStack.Push( m_CurrentMenu ); // remember current menu
-
- m_CurrentMenu = menu; // continue adding items in new menu
-}
-
-void CommandMenu::FinishSubMenu()
-{
- m_CurrentMenu = m_pMenuStack.Top(); // get menu one level above
- m_pMenuStack.Pop(); // remove it from stack
-}
-
-void CommandMenu::AddMenuCommandItem(KeyValues * params)
-{
- CommandMenuItem menuitem; // create new menuItem
- menuitem.menu = m_CurrentMenu; // save the current menu context
- menuitem.itemnr = m_CurrentMenu->AddMenuItem( params->GetString("label"), params->MakeCopy(), this, params ); // add it
- m_MenuItems.AddToTail( menuitem ); // add to global list
-}
-
-void CommandMenu::AddMenuToggleItem(KeyValues * params)
-{
- CommandMenuItem menuitem; // create new menuItem
- menuitem.menu = m_CurrentMenu; // save the current menu context
- menuitem.itemnr = m_CurrentMenu->AddCheckableMenuItem( params->GetString("label"), params->MakeCopy(), this, params ); // add it
- m_MenuItems.AddToTail( menuitem ); // add to global list
-}
-
-void CommandMenu::AddMenuCustomItem(KeyValues * params)
-{
- CommandMenuItem menuitem; // create new menuItem
- menuitem.menu = m_CurrentMenu; // save the current menu context
- menuitem.itemnr = AddCustomItem( params, m_CurrentMenu );
- m_MenuItems.AddToTail( menuitem ); // add to global list
-}
-
-void CommandMenu::ClearMenu()
-{
- SetVisible( false );
- m_pMenuStack.Clear();
- m_MenuItems.RemoveAll();
- // DeleteAllItems();
- MarkForDeletion();
-
- if ( m_MenuKeys )
- {
- m_MenuKeys->deleteThis();
- m_MenuKeys = NULL;
- }
-
-}
-
-void CommandMenu::RebuildMenu()
-{
- if ( !m_MenuKeys )
- return;
-
- m_pMenuStack.Clear();
- m_MenuItems.RemoveAll();
- DeleteAllItems();
-
- LoadFromKeyValues( m_MenuKeys ); // and reload respecting new team, mapname etc.
-}
-
-void CommandMenu::UpdateMenu()
-{
- char text[255];
-
- int num = m_MenuItems.Count();
-
- for (int i=0; i < num; i++)
- {
- CommandMenuItem menuitem = m_MenuItems.Element(i);
- KeyValues * keys = menuitem.menu->GetItemUserData( menuitem.itemnr );
-
- if ( !keys )
- continue;
-
- // let custom menu items update themself
- Q_strncpy( text, keys->GetString("custom"), sizeof(text) );
-
- if ( text[0] )
- {
- // let derived class modify the menu item
- UpdateCustomItem( keys, menuitem.menu->GetMenuItem(menuitem.itemnr) );
- continue;
- }
-
- // update toggle buttons
- Q_strncpy( text, keys->GetString("toggle"), sizeof(text) );
-
- if ( text[0] )
- {
- // set toggle state equal to cvar state
- ConVarRef convar( text );
-
- if ( convar.IsValid() )
- {
- menuitem.menu->SetMenuItemChecked( menuitem.itemnr, convar.GetBool() );
- }
- }
- }
-}
-
-void CommandMenu::SetVisible(bool state)
-{
- if ( state && !IsVisible() )
- {
- UpdateMenu();
- }
-
- BaseClass::SetVisible( state );
-}
-
-bool CommandMenu::CheckRules(const char *rule, const char *ruledata)
-{
- if ( !rule || !ruledata )
- {
- return true; // no rule defined, show item
- }
-
- if ( Q_strcmp( rule, "team") == 0 )
- {
- // if team is same as specified in rule, show item
- return ( Q_strcmp( m_CurrentTeam, ruledata ) == 0 );
- }
- else if ( Q_strcmp( rule, "map") == 0 )
- {
- // if team is same as specified in rule, show item
- return ( Q_strcmp( m_CurrentMap, ruledata ) == 0 );
- }
-
- return true;
-}
-
-KeyValues * CommandMenu::GetKeyValues()
-{
- return m_MenuKeys;
-}
-
-bool CommandMenu::LoadFromKeyValues( KeyValues * params )
-{
- if ( !params )
- return false;
-
- Q_snprintf( m_CurrentTeam, 4, "%i", GetLocalPlayerTeam() );
-
- Q_FileBase( engine->GetLevelName(), m_CurrentMap, sizeof(m_CurrentMap) );
-
- if ( params != m_MenuKeys )
- {
- if ( m_MenuKeys )
- m_MenuKeys->deleteThis();
-
- m_MenuKeys = params->MakeCopy(); // save keyvalues
- }
-
- // iterate through all menu items
-
- KeyValues * subkey = m_MenuKeys->GetFirstSubKey();
-
- while ( subkey )
- {
- if ( subkey->GetDataType() == KeyValues::TYPE_NONE )
- {
- if ( !LoadFromKeyValuesInternal( subkey, 0 ) ) // recursive call
- return false;
- }
-
- subkey = subkey->GetNextKey();
- }
-
- UpdateMenu();
-
- return true;
-}
-
-bool CommandMenu::LoadFromKeyValuesInternal(KeyValues * key, int depth)
-{
- char text[255];
- KeyValues * subkey = NULL;
-
- if ( depth > 100 )
- {
- Msg("CommandMenu::LoadFromKeyValueInternal: depth > 100.\n");
- return false;
- }
-
- Q_strncpy( text, key->GetString("custom"), sizeof(text) ); // get type
-
- if ( text[0] )
- {
- AddMenuCustomItem( key ); // do whatever custom item wants to
- return true;
- }
-
- if ( !CheckRules( key->GetString("rule"), key->GetString("ruledata") ) )
- {
- return true;
- }
-
- // rules OK add subkey
- Q_strncpy( text, key->GetString("toggle"), sizeof(text) ); // get type
-
- if ( text[0] )
- {
- AddMenuToggleItem( key );
- return true;
- }
-
- Q_strncpy( text, key->GetString("command"), sizeof(text) ); // get type
-
- if ( text[0] )
- {
- AddMenuCommandItem( key );
- return true;
- }
-
- // not a command, nor a toggle. Must be a submenu:
-
- StartNewSubMenu( key ); // create submenu
-
- // iterate through all subkeys
-
- subkey = key->GetFirstSubKey();
-
- while ( subkey )
- {
- if ( subkey->GetDataType() == KeyValues::TYPE_NONE )
- {
- LoadFromKeyValuesInternal( subkey, depth+1 ); // recursive call
- }
-
- subkey = subkey->GetNextKey();
- }
-
- FinishSubMenu(); // go one level back
-
- return true;
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//===========================================================================//
+
+#include "cbase.h"
+#include <cdll_client_int.h>
+#include <cdll_util.h>
+#include <globalvars_base.h>
+#include <icvar.h>
+#include <filesystem.h>
+
+#include "commandmenu.h"
+#include "vgui_controls/MenuItem.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+CommandMenu::CommandMenu( Panel *parent, const char *panelName, IViewPort * viewport) : Menu( parent, panelName )
+{
+ if ( !viewport )
+ return;
+
+ m_ViewPort = viewport;
+ SetVisible( false );
+ m_CurrentMenu = this;
+
+ m_MenuKeys = NULL;
+}
+
+bool CommandMenu::LoadFromFile( const char * fileName) // load menu from KeyValues
+{
+ KeyValues * kv = new KeyValues(fileName);
+
+ if ( !kv->LoadFromFile( g_pFullFileSystem, fileName, "GAME" ) )
+ return false;
+
+ bool ret = LoadFromKeyValues( kv );
+
+ kv->deleteThis();
+ return ret;
+}
+
+CommandMenu::~CommandMenu()
+{
+ ClearMenu();
+}
+
+void CommandMenu::OnMessage(const KeyValues *params, VPANEL fromPanel)
+{
+ char text[255];
+ bool bHandled = false;
+
+ KeyValues *param1 = const_cast<KeyValues *>(params);
+
+ // toggle attached cvar, if any
+ Q_strncpy( text, param1->GetString("toggle"), sizeof( text ) );
+
+ if ( text[0] )
+ {
+ ConVarRef convar( text );
+ if ( convar.IsValid() )
+ {
+ // toggle cvar
+
+ if ( convar.GetInt() )
+ {
+ convar.SetValue( 0 );
+ }
+ else
+ {
+ convar.SetValue( 1 );
+ }
+
+ UpdateMenu();
+ }
+ else
+ {
+ Msg("CommandComboBox::OnMessage: cvar %s not found.\n", param1->GetString("typedata") );
+ }
+
+ bHandled = true;
+ }
+
+ // execute attached command, if any
+ Q_strncpy( text, param1->GetString("command"), sizeof( text ) );
+ if ( text[0] )
+ {
+ engine->ClientCmd( text );
+ bHandled = true;
+ }
+
+ // fire custom message, if any
+ Q_strncpy( text, param1->GetString("custom"), sizeof( text ) );
+ if ( text[0] )
+ {
+ OnCustomItem( param1 ); // let derived class decide what to do
+ bHandled = true;
+ }
+
+ if ( bHandled )
+ {
+ PostMessage( GetParent(), new KeyValues("CommandMenuClosed") );
+ }
+
+ BaseClass::OnMessage( params, fromPanel );
+}
+
+void CommandMenu::StartNewSubMenu(KeyValues * params)
+{
+ CommandMenuItem menuitem;
+ menuitem.menu = m_CurrentMenu;
+
+ Menu * menu = new Menu( this, params->GetString("name") ); // create new menu
+
+ menuitem.itemnr = m_CurrentMenu->AddCascadingMenuItem( params->GetString("label"), this, menu, params ); // add to current menu as item
+
+ m_MenuItems.AddToTail( menuitem ); // add to global list
+
+ m_pMenuStack.Push( m_CurrentMenu ); // remember current menu
+
+ m_CurrentMenu = menu; // continue adding items in new menu
+}
+
+void CommandMenu::FinishSubMenu()
+{
+ m_CurrentMenu = m_pMenuStack.Top(); // get menu one level above
+ m_pMenuStack.Pop(); // remove it from stack
+}
+
+void CommandMenu::AddMenuCommandItem(KeyValues * params)
+{
+ CommandMenuItem menuitem; // create new menuItem
+ menuitem.menu = m_CurrentMenu; // save the current menu context
+ menuitem.itemnr = m_CurrentMenu->AddMenuItem( params->GetString("label"), params->MakeCopy(), this, params ); // add it
+ m_MenuItems.AddToTail( menuitem ); // add to global list
+}
+
+void CommandMenu::AddMenuToggleItem(KeyValues * params)
+{
+ CommandMenuItem menuitem; // create new menuItem
+ menuitem.menu = m_CurrentMenu; // save the current menu context
+ menuitem.itemnr = m_CurrentMenu->AddCheckableMenuItem( params->GetString("label"), params->MakeCopy(), this, params ); // add it
+ m_MenuItems.AddToTail( menuitem ); // add to global list
+}
+
+void CommandMenu::AddMenuCustomItem(KeyValues * params)
+{
+ CommandMenuItem menuitem; // create new menuItem
+ menuitem.menu = m_CurrentMenu; // save the current menu context
+ menuitem.itemnr = AddCustomItem( params, m_CurrentMenu );
+ m_MenuItems.AddToTail( menuitem ); // add to global list
+}
+
+void CommandMenu::ClearMenu()
+{
+ SetVisible( false );
+ m_pMenuStack.Clear();
+ m_MenuItems.RemoveAll();
+ // DeleteAllItems();
+ MarkForDeletion();
+
+ if ( m_MenuKeys )
+ {
+ m_MenuKeys->deleteThis();
+ m_MenuKeys = NULL;
+ }
+
+}
+
+void CommandMenu::RebuildMenu()
+{
+ if ( !m_MenuKeys )
+ return;
+
+ m_pMenuStack.Clear();
+ m_MenuItems.RemoveAll();
+ DeleteAllItems();
+
+ LoadFromKeyValues( m_MenuKeys ); // and reload respecting new team, mapname etc.
+}
+
+void CommandMenu::UpdateMenu()
+{
+ char text[255];
+
+ int num = m_MenuItems.Count();
+
+ for (int i=0; i < num; i++)
+ {
+ CommandMenuItem menuitem = m_MenuItems.Element(i);
+ KeyValues * keys = menuitem.menu->GetItemUserData( menuitem.itemnr );
+
+ if ( !keys )
+ continue;
+
+ // let custom menu items update themself
+ Q_strncpy( text, keys->GetString("custom"), sizeof(text) );
+
+ if ( text[0] )
+ {
+ // let derived class modify the menu item
+ UpdateCustomItem( keys, menuitem.menu->GetMenuItem(menuitem.itemnr) );
+ continue;
+ }
+
+ // update toggle buttons
+ Q_strncpy( text, keys->GetString("toggle"), sizeof(text) );
+
+ if ( text[0] )
+ {
+ // set toggle state equal to cvar state
+ ConVarRef convar( text );
+
+ if ( convar.IsValid() )
+ {
+ menuitem.menu->SetMenuItemChecked( menuitem.itemnr, convar.GetBool() );
+ }
+ }
+ }
+}
+
+void CommandMenu::SetVisible(bool state)
+{
+ if ( state && !IsVisible() )
+ {
+ UpdateMenu();
+ }
+
+ BaseClass::SetVisible( state );
+}
+
+bool CommandMenu::CheckRules(const char *rule, const char *ruledata)
+{
+ if ( !rule || !ruledata )
+ {
+ return true; // no rule defined, show item
+ }
+
+ if ( Q_strcmp( rule, "team") == 0 )
+ {
+ // if team is same as specified in rule, show item
+ return ( Q_strcmp( m_CurrentTeam, ruledata ) == 0 );
+ }
+ else if ( Q_strcmp( rule, "map") == 0 )
+ {
+ // if team is same as specified in rule, show item
+ return ( Q_strcmp( m_CurrentMap, ruledata ) == 0 );
+ }
+
+ return true;
+}
+
+KeyValues * CommandMenu::GetKeyValues()
+{
+ return m_MenuKeys;
+}
+
+bool CommandMenu::LoadFromKeyValues( KeyValues * params )
+{
+ if ( !params )
+ return false;
+
+ Q_snprintf( m_CurrentTeam, 4, "%i", GetLocalPlayerTeam() );
+
+ Q_FileBase( engine->GetLevelName(), m_CurrentMap, sizeof(m_CurrentMap) );
+
+ if ( params != m_MenuKeys )
+ {
+ if ( m_MenuKeys )
+ m_MenuKeys->deleteThis();
+
+ m_MenuKeys = params->MakeCopy(); // save keyvalues
+ }
+
+ // iterate through all menu items
+
+ KeyValues * subkey = m_MenuKeys->GetFirstSubKey();
+
+ while ( subkey )
+ {
+ if ( subkey->GetDataType() == KeyValues::TYPE_NONE )
+ {
+ if ( !LoadFromKeyValuesInternal( subkey, 0 ) ) // recursive call
+ return false;
+ }
+
+ subkey = subkey->GetNextKey();
+ }
+
+ UpdateMenu();
+
+ return true;
+}
+
+bool CommandMenu::LoadFromKeyValuesInternal(KeyValues * key, int depth)
+{
+ char text[255];
+ KeyValues * subkey = NULL;
+
+ if ( depth > 100 )
+ {
+ Msg("CommandMenu::LoadFromKeyValueInternal: depth > 100.\n");
+ return false;
+ }
+
+ Q_strncpy( text, key->GetString("custom"), sizeof(text) ); // get type
+
+ if ( text[0] )
+ {
+ AddMenuCustomItem( key ); // do whatever custom item wants to
+ return true;
+ }
+
+ if ( !CheckRules( key->GetString("rule"), key->GetString("ruledata") ) )
+ {
+ return true;
+ }
+
+ // rules OK add subkey
+ Q_strncpy( text, key->GetString("toggle"), sizeof(text) ); // get type
+
+ if ( text[0] )
+ {
+ AddMenuToggleItem( key );
+ return true;
+ }
+
+ Q_strncpy( text, key->GetString("command"), sizeof(text) ); // get type
+
+ if ( text[0] )
+ {
+ AddMenuCommandItem( key );
+ return true;
+ }
+
+ // not a command, nor a toggle. Must be a submenu:
+
+ StartNewSubMenu( key ); // create submenu
+
+ // iterate through all subkeys
+
+ subkey = key->GetFirstSubKey();
+
+ while ( subkey )
+ {
+ if ( subkey->GetDataType() == KeyValues::TYPE_NONE )
+ {
+ LoadFromKeyValuesInternal( subkey, depth+1 ); // recursive call
+ }
+
+ subkey = subkey->GetNextKey();
+ }
+
+ FinishSubMenu(); // go one level back
+
+ return true;
} \ No newline at end of file
diff --git a/mp/src/game/client/game_controls/commandmenu.h b/mp/src/game/client/game_controls/commandmenu.h
index 8ed1cc1b..9f800491 100644
--- a/mp/src/game/client/game_controls/commandmenu.h
+++ b/mp/src/game/client/game_controls/commandmenu.h
@@ -1,77 +1,77 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================
-
-
-#ifndef COMMANDMENU_H
-#define COMMANDMENU_H
-
-#include <vgui_controls/Menu.h>
-#include <game/client/iviewport.h>
-#include <filesystem.h>
-#include "utlstack.h"
-#include "utlvector.h"
-#include <KeyValues.h>
-
-using namespace vgui;
-
-class CommandMenu : public Menu
-{
-private:
- DECLARE_CLASS_SIMPLE( CommandMenu, Menu );
-
- typedef struct
- {
- Menu * menu;
- int itemnr;
- } CommandMenuItem;
-
- public:
- CommandMenu( Panel *parent, const char *panelName, IViewPort * viewport );
- ~CommandMenu();
-
- bool LoadFromFile(const char * fileName); // load menu from file (via KeyValues)
- void UpdateMenu(); // call to update all menu items, check buttons etc
- void RebuildMenu(); // rebuilds menu respecting changed game state (map, team etc)
- void ClearMenu(); // destroy menu
-
- public:
- // overwrite these in your derived class
- // virtual CommandMenu * CommandMenu::Factory(Panel *parent, const char *panelName, IViewPort * viewport = NULL, IFileSystem * pFileSytem = NULL); // overwrite
- virtual int AddCustomItem(KeyValues * params, Menu * menu) {return 0;} // return MenuItem nr
- virtual void UpdateCustomItem(KeyValues * params, MenuItem * item ) {}; // maybe change your item
- virtual void OnCustomItem(KeyValues * params) {}; // a custom item was pressed
- virtual bool CheckRules(const char *rule, const char *ruledata); // check a menu item rule
- virtual void SetVisible(bool state);
-
- // DON'T touch anything below !
-
- protected:
-
- void OnMessage(const KeyValues *params, VPANEL fromPanel);
- void StartNewSubMenu(KeyValues * params);
- void FinishSubMenu();
- void AddMenuCommandItem(KeyValues * params);
- void AddMenuCustomItem(KeyValues * params);
- void AddMenuToggleItem(KeyValues * params);
- bool LoadFromKeyValuesInternal(KeyValues * key, int depth);
- bool LoadFromKeyValues( KeyValues * key); //
-
- KeyValues * GetKeyValues(); // returns keyValues for current menu or NULL
-
-
- IViewPort * m_ViewPort; // viewport interface
- Menu * m_CurrentMenu; // Current menu while building CommandComoboBox
- char m_CurrentTeam[4];
- char m_CurrentMap[256];
-
- KeyValues* m_MenuKeys;
-
- CUtlStack<vgui::Menu*>m_pMenuStack;
- CUtlVector<CommandMenuItem>m_MenuItems;
-};
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================
+
+
+#ifndef COMMANDMENU_H
+#define COMMANDMENU_H
+
+#include <vgui_controls/Menu.h>
+#include <game/client/iviewport.h>
+#include <filesystem.h>
+#include "utlstack.h"
+#include "utlvector.h"
+#include <KeyValues.h>
+
+using namespace vgui;
+
+class CommandMenu : public Menu
+{
+private:
+ DECLARE_CLASS_SIMPLE( CommandMenu, Menu );
+
+ typedef struct
+ {
+ Menu * menu;
+ int itemnr;
+ } CommandMenuItem;
+
+ public:
+ CommandMenu( Panel *parent, const char *panelName, IViewPort * viewport );
+ ~CommandMenu();
+
+ bool LoadFromFile(const char * fileName); // load menu from file (via KeyValues)
+ void UpdateMenu(); // call to update all menu items, check buttons etc
+ void RebuildMenu(); // rebuilds menu respecting changed game state (map, team etc)
+ void ClearMenu(); // destroy menu
+
+ public:
+ // overwrite these in your derived class
+ // virtual CommandMenu * CommandMenu::Factory(Panel *parent, const char *panelName, IViewPort * viewport = NULL, IFileSystem * pFileSytem = NULL); // overwrite
+ virtual int AddCustomItem(KeyValues * params, Menu * menu) {return 0;} // return MenuItem nr
+ virtual void UpdateCustomItem(KeyValues * params, MenuItem * item ) {}; // maybe change your item
+ virtual void OnCustomItem(KeyValues * params) {}; // a custom item was pressed
+ virtual bool CheckRules(const char *rule, const char *ruledata); // check a menu item rule
+ virtual void SetVisible(bool state);
+
+ // DON'T touch anything below !
+
+ protected:
+
+ void OnMessage(const KeyValues *params, VPANEL fromPanel);
+ void StartNewSubMenu(KeyValues * params);
+ void FinishSubMenu();
+ void AddMenuCommandItem(KeyValues * params);
+ void AddMenuCustomItem(KeyValues * params);
+ void AddMenuToggleItem(KeyValues * params);
+ bool LoadFromKeyValuesInternal(KeyValues * key, int depth);
+ bool LoadFromKeyValues( KeyValues * key); //
+
+ KeyValues * GetKeyValues(); // returns keyValues for current menu or NULL
+
+
+ IViewPort * m_ViewPort; // viewport interface
+ Menu * m_CurrentMenu; // Current menu while building CommandComoboBox
+ char m_CurrentTeam[4];
+ char m_CurrentMap[256];
+
+ KeyValues* m_MenuKeys;
+
+ CUtlStack<vgui::Menu*>m_pMenuStack;
+ CUtlVector<CommandMenuItem>m_MenuItems;
+};
+
#endif // COMMANDMENU_H \ No newline at end of file
diff --git a/mp/src/game/client/game_controls/imagemouseoverbutton.h b/mp/src/game/client/game_controls/imagemouseoverbutton.h
index 8562b8da..9dee5d73 100644
--- a/mp/src/game/client/game_controls/imagemouseoverbutton.h
+++ b/mp/src/game/client/game_controls/imagemouseoverbutton.h
@@ -1,256 +1,256 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef IMAGE_MOUSE_OVER_BUTTON_H
-#define IMAGE_MOUSE_OVER_BUTTON_H
-
-#include "vgui/ISurface.h"
-#include "vgui/IScheme.h"
-#include "mouseoverpanelbutton.h"
-
-//===============================================
-// CImageMouseOverButton - used for class images
-//===============================================
-
-template <class T>
-class CImageMouseOverButton : public MouseOverButton<T>
-{
-private:
- //DECLARE_CLASS_SIMPLE( CImageMouseOverButton, MouseOverButton );
-
-public:
- CImageMouseOverButton( vgui::Panel *parent, const char *panelName, T *templatePanel );
-
- virtual void ApplySettings( KeyValues *inResourceData );
- virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
- virtual void OnSizeChanged( int newWide, int newTall );
-
- void RecalculateImageSizes( void );
- void SetActiveImage( const char *imagename );
- void SetInactiveImage( const char *imagename );
- void SetActiveImage( vgui::IImage *image );
- void SetInactiveImage( vgui::IImage *image );
-
-public:
- virtual void Paint();
- virtual void ShowPage( void );
- virtual void HidePage( void );
-
-private:
- vgui::IImage *m_pActiveImage;
- char *m_pszActiveImageName;
-
- vgui::IImage *m_pInactiveImage;
- char *m_pszInactiveImageName;
-
- bool m_bScaleImage;
-};
-
-template <class T>
-CImageMouseOverButton<T>::CImageMouseOverButton( vgui::Panel *parent, const char *panelName, T *templatePanel ) :
- MouseOverButton<T>( parent, panelName, templatePanel )
-{
- m_pszActiveImageName = NULL;
- m_pszInactiveImageName = NULL;
-
- m_pActiveImage = NULL;
- m_pInactiveImage = NULL;
-}
-
-template <class T>
-void CImageMouseOverButton<T>::ApplySettings( KeyValues *inResourceData )
-{
- m_bScaleImage = inResourceData->GetInt( "scaleImage", 0 );
-
- // Active Image
- delete [] m_pszActiveImageName;
- m_pszActiveImageName = NULL;
-
- const char *activeImageName = inResourceData->GetString( "activeimage", "" );
- if ( *activeImageName )
- {
- this->SetActiveImage( activeImageName );
- }
-
- // Inactive Image
- delete [] m_pszInactiveImageName;
- m_pszInactiveImageName = NULL;
-
- const char *inactiveImageName = inResourceData->GetString( "inactiveimage", "" );
- if ( *inactiveImageName )
- {
- this->SetInactiveImage( inactiveImageName );
- }
-
- MouseOverButton<T>::ApplySettings( inResourceData );
-
- this->InvalidateLayout( false, true ); // force applyschemesettings to run
-}
-
-template <class T>
-void CImageMouseOverButton<T>::ApplySchemeSettings( vgui::IScheme *pScheme )
-{
- MouseOverButton<T>::ApplySchemeSettings( pScheme );
-
- if ( m_pszActiveImageName && strlen( m_pszActiveImageName ) > 0 )
- {
- this->SetActiveImage( vgui::scheme()->GetImage( m_pszActiveImageName, m_bScaleImage ) );
- }
-
- if ( m_pszInactiveImageName && strlen( m_pszInactiveImageName ) > 0 )
- {
- this->SetInactiveImage( vgui::scheme()->GetImage( m_pszInactiveImageName, m_bScaleImage ) );
- }
-
- vgui::IBorder *pBorder = pScheme->GetBorder( "NoBorder" );
- this->SetDefaultBorder( pBorder);
- this->SetDepressedBorder( pBorder );
- this->SetKeyFocusBorder( pBorder );
-
- Color blank(0,0,0,0);
- this->SetDefaultColor( this->GetButtonFgColor(), blank );
- this->SetArmedColor( this->GetButtonArmedFgColor(), blank );
- this->SetDepressedColor( this->GetButtonDepressedFgColor(), blank );
-}
-
-template <class T>
-void CImageMouseOverButton<T>::RecalculateImageSizes( void )
-{
- // Reset our images, which will force them to recalculate their size.
- // Necessary for images shared with other scaling buttons.
- this->SetActiveImage( m_pActiveImage );
- this->SetInactiveImage( m_pInactiveImage );
-}
-
-template <class T>
-void CImageMouseOverButton<T>::SetActiveImage( const char *imagename )
-{
- int len = Q_strlen( imagename ) + 1;
- m_pszActiveImageName = new char[ len ];
- Q_strncpy( m_pszActiveImageName, imagename, len );
-}
-
-template <class T>
-void CImageMouseOverButton<T>::SetInactiveImage( const char *imagename )
-{
- int len = Q_strlen( imagename ) + 1;
- m_pszInactiveImageName = new char[ len ];
- Q_strncpy( m_pszInactiveImageName, imagename, len );
-}
-
-template <class T>
-void CImageMouseOverButton<T>::SetActiveImage( vgui::IImage *image )
-{
- m_pActiveImage = image;
-
- if ( m_pActiveImage )
- {
- int wide, tall;
- if ( m_bScaleImage )
- {
- // scaling, force the image size to be our size
- this->GetSize( wide, tall );
- m_pActiveImage->SetSize( wide, tall );
- }
- else
- {
- // not scaling, so set our size to the image size
- m_pActiveImage->GetSize( wide, tall );
- this->SetSize( wide, tall );
- }
- }
-
- this->Repaint();
-}
-
-template <class T>
-void CImageMouseOverButton<T>::SetInactiveImage( vgui::IImage *image )
-{
- m_pInactiveImage = image;
-
- if ( m_pInactiveImage )
- {
- int wide, tall;
- if ( m_bScaleImage)
- {
- // scaling, force the image size to be our size
- this->GetSize( wide, tall );
- m_pInactiveImage->SetSize( wide, tall );
- }
- else
- {
- // not scaling, so set our size to the image size
- m_pInactiveImage->GetSize( wide, tall );
- this->SetSize( wide, tall );
- }
- }
-
- this->Repaint();
-}
-
-template <class T>
-void CImageMouseOverButton<T>::OnSizeChanged( int newWide, int newTall )
-{
- if ( m_bScaleImage )
- {
- // scaling, force the image size to be our size
-
- if ( m_pActiveImage )
- m_pActiveImage->SetSize( newWide, newTall );
-
- if ( m_pInactiveImage )
- m_pInactiveImage->SetSize( newWide, newTall );
- }
- MouseOverButton<T>::OnSizeChanged( newWide, newTall );
-}
-
-template <class T>
-void CImageMouseOverButton<T>::Paint()
-{
- this->SetActiveImage( m_pActiveImage );
- this->SetInactiveImage( m_pInactiveImage );
-
- if ( this->IsArmed() )
- {
- // draw the active image
- if ( m_pActiveImage )
- {
- vgui::surface()->DrawSetColor( 255, 255, 255, 255 );
- m_pActiveImage->SetPos( 0, 0 );
- m_pActiveImage->Paint();
- }
- }
- else
- {
- // draw the inactive image
- if ( m_pInactiveImage )
- {
- vgui::surface()->DrawSetColor( 255, 255, 255, 255 );
- m_pInactiveImage->SetPos( 0, 0 );
- m_pInactiveImage->Paint();
- }
- }
-
- MouseOverButton<T>::Paint();
-}
-
-template <class T>
-void CImageMouseOverButton<T>::ShowPage( void )
-{
- MouseOverButton<T>::ShowPage();
-
- // send message to parent that we triggered something
- this->PostActionSignal( new KeyValues( "ShowPage", "page", this->GetName() ) );
-}
-
-template <class T>
-void CImageMouseOverButton<T>::HidePage( void )
-{
- MouseOverButton<T>::HidePage();
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef IMAGE_MOUSE_OVER_BUTTON_H
+#define IMAGE_MOUSE_OVER_BUTTON_H
+
+#include "vgui/ISurface.h"
+#include "vgui/IScheme.h"
+#include "mouseoverpanelbutton.h"
+
+//===============================================
+// CImageMouseOverButton - used for class images
+//===============================================
+
+template <class T>
+class CImageMouseOverButton : public MouseOverButton<T>
+{
+private:
+ //DECLARE_CLASS_SIMPLE( CImageMouseOverButton, MouseOverButton );
+
+public:
+ CImageMouseOverButton( vgui::Panel *parent, const char *panelName, T *templatePanel );
+
+ virtual void ApplySettings( KeyValues *inResourceData );
+ virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
+ virtual void OnSizeChanged( int newWide, int newTall );
+
+ void RecalculateImageSizes( void );
+ void SetActiveImage( const char *imagename );
+ void SetInactiveImage( const char *imagename );
+ void SetActiveImage( vgui::IImage *image );
+ void SetInactiveImage( vgui::IImage *image );
+
+public:
+ virtual void Paint();
+ virtual void ShowPage( void );
+ virtual void HidePage( void );
+
+private:
+ vgui::IImage *m_pActiveImage;
+ char *m_pszActiveImageName;
+
+ vgui::IImage *m_pInactiveImage;
+ char *m_pszInactiveImageName;
+
+ bool m_bScaleImage;
+};
+
+template <class T>
+CImageMouseOverButton<T>::CImageMouseOverButton( vgui::Panel *parent, const char *panelName, T *templatePanel ) :
+ MouseOverButton<T>( parent, panelName, templatePanel )
+{
+ m_pszActiveImageName = NULL;
+ m_pszInactiveImageName = NULL;
+
+ m_pActiveImage = NULL;
+ m_pInactiveImage = NULL;
+}
+
+template <class T>
+void CImageMouseOverButton<T>::ApplySettings( KeyValues *inResourceData )
+{
+ m_bScaleImage = inResourceData->GetInt( "scaleImage", 0 );
+
+ // Active Image
+ delete [] m_pszActiveImageName;
+ m_pszActiveImageName = NULL;
+
+ const char *activeImageName = inResourceData->GetString( "activeimage", "" );
+ if ( *activeImageName )
+ {
+ this->SetActiveImage( activeImageName );
+ }
+
+ // Inactive Image
+ delete [] m_pszInactiveImageName;
+ m_pszInactiveImageName = NULL;
+
+ const char *inactiveImageName = inResourceData->GetString( "inactiveimage", "" );
+ if ( *inactiveImageName )
+ {
+ this->SetInactiveImage( inactiveImageName );
+ }
+
+ MouseOverButton<T>::ApplySettings( inResourceData );
+
+ this->InvalidateLayout( false, true ); // force applyschemesettings to run
+}
+
+template <class T>
+void CImageMouseOverButton<T>::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ MouseOverButton<T>::ApplySchemeSettings( pScheme );
+
+ if ( m_pszActiveImageName && strlen( m_pszActiveImageName ) > 0 )
+ {
+ this->SetActiveImage( vgui::scheme()->GetImage( m_pszActiveImageName, m_bScaleImage ) );
+ }
+
+ if ( m_pszInactiveImageName && strlen( m_pszInactiveImageName ) > 0 )
+ {
+ this->SetInactiveImage( vgui::scheme()->GetImage( m_pszInactiveImageName, m_bScaleImage ) );
+ }
+
+ vgui::IBorder *pBorder = pScheme->GetBorder( "NoBorder" );
+ this->SetDefaultBorder( pBorder);
+ this->SetDepressedBorder( pBorder );
+ this->SetKeyFocusBorder( pBorder );
+
+ Color blank(0,0,0,0);
+ this->SetDefaultColor( this->GetButtonFgColor(), blank );
+ this->SetArmedColor( this->GetButtonArmedFgColor(), blank );
+ this->SetDepressedColor( this->GetButtonDepressedFgColor(), blank );
+}
+
+template <class T>
+void CImageMouseOverButton<T>::RecalculateImageSizes( void )
+{
+ // Reset our images, which will force them to recalculate their size.
+ // Necessary for images shared with other scaling buttons.
+ this->SetActiveImage( m_pActiveImage );
+ this->SetInactiveImage( m_pInactiveImage );
+}
+
+template <class T>
+void CImageMouseOverButton<T>::SetActiveImage( const char *imagename )
+{
+ int len = Q_strlen( imagename ) + 1;
+ m_pszActiveImageName = new char[ len ];
+ Q_strncpy( m_pszActiveImageName, imagename, len );
+}
+
+template <class T>
+void CImageMouseOverButton<T>::SetInactiveImage( const char *imagename )
+{
+ int len = Q_strlen( imagename ) + 1;
+ m_pszInactiveImageName = new char[ len ];
+ Q_strncpy( m_pszInactiveImageName, imagename, len );
+}
+
+template <class T>
+void CImageMouseOverButton<T>::SetActiveImage( vgui::IImage *image )
+{
+ m_pActiveImage = image;
+
+ if ( m_pActiveImage )
+ {
+ int wide, tall;
+ if ( m_bScaleImage )
+ {
+ // scaling, force the image size to be our size
+ this->GetSize( wide, tall );
+ m_pActiveImage->SetSize( wide, tall );
+ }
+ else
+ {
+ // not scaling, so set our size to the image size
+ m_pActiveImage->GetSize( wide, tall );
+ this->SetSize( wide, tall );
+ }
+ }
+
+ this->Repaint();
+}
+
+template <class T>
+void CImageMouseOverButton<T>::SetInactiveImage( vgui::IImage *image )
+{
+ m_pInactiveImage = image;
+
+ if ( m_pInactiveImage )
+ {
+ int wide, tall;
+ if ( m_bScaleImage)
+ {
+ // scaling, force the image size to be our size
+ this->GetSize( wide, tall );
+ m_pInactiveImage->SetSize( wide, tall );
+ }
+ else
+ {
+ // not scaling, so set our size to the image size
+ m_pInactiveImage->GetSize( wide, tall );
+ this->SetSize( wide, tall );
+ }
+ }
+
+ this->Repaint();
+}
+
+template <class T>
+void CImageMouseOverButton<T>::OnSizeChanged( int newWide, int newTall )
+{
+ if ( m_bScaleImage )
+ {
+ // scaling, force the image size to be our size
+
+ if ( m_pActiveImage )
+ m_pActiveImage->SetSize( newWide, newTall );
+
+ if ( m_pInactiveImage )
+ m_pInactiveImage->SetSize( newWide, newTall );
+ }
+ MouseOverButton<T>::OnSizeChanged( newWide, newTall );
+}
+
+template <class T>
+void CImageMouseOverButton<T>::Paint()
+{
+ this->SetActiveImage( m_pActiveImage );
+ this->SetInactiveImage( m_pInactiveImage );
+
+ if ( this->IsArmed() )
+ {
+ // draw the active image
+ if ( m_pActiveImage )
+ {
+ vgui::surface()->DrawSetColor( 255, 255, 255, 255 );
+ m_pActiveImage->SetPos( 0, 0 );
+ m_pActiveImage->Paint();
+ }
+ }
+ else
+ {
+ // draw the inactive image
+ if ( m_pInactiveImage )
+ {
+ vgui::surface()->DrawSetColor( 255, 255, 255, 255 );
+ m_pInactiveImage->SetPos( 0, 0 );
+ m_pInactiveImage->Paint();
+ }
+ }
+
+ MouseOverButton<T>::Paint();
+}
+
+template <class T>
+void CImageMouseOverButton<T>::ShowPage( void )
+{
+ MouseOverButton<T>::ShowPage();
+
+ // send message to parent that we triggered something
+ this->PostActionSignal( new KeyValues( "ShowPage", "page", this->GetName() ) );
+}
+
+template <class T>
+void CImageMouseOverButton<T>::HidePage( void )
+{
+ MouseOverButton<T>::HidePage();
+}
+
#endif //IMAGE_MOUSE_OVER_BUTTON_H \ No newline at end of file
diff --git a/mp/src/game/client/game_controls/intromenu.cpp b/mp/src/game/client/game_controls/intromenu.cpp
index 21290f26..bf31a83d 100644
--- a/mp/src/game/client/game_controls/intromenu.cpp
+++ b/mp/src/game/client/game_controls/intromenu.cpp
@@ -1,122 +1,122 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-
-#include "cbase.h"
-#include "intromenu.h"
-#include <networkstringtabledefs.h>
-#include <cdll_client_int.h>
-#include <vgui/IScheme.h>
-#include <vgui/ILocalize.h>
-#include <vgui/ISurface.h>
-#include <filesystem.h>
-#include <KeyValues.h>
-#include <convar.h>
-#include <game/client/iviewport.h>
-#include "spectatorgui.h"
-#include "gamerules.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-using namespace vgui;
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CIntroMenu::CIntroMenu( IViewPort *pViewPort ) : Frame( NULL, PANEL_INTRO )
-{
- // initialize dialog
- m_pViewPort = pViewPort;
-
- m_pTitleLabel = NULL;
-
- // load the new scheme early!!
- SetScheme( "ClientScheme" );
- SetMoveable( false );
- SetSizeable( false );
- SetProportional( true );
-
- // hide the system buttons
- SetTitleBarVisible( false );
-
- Reset();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Destructor
-//-----------------------------------------------------------------------------
-CIntroMenu::~CIntroMenu()
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the color of the top and bottom bars
-//-----------------------------------------------------------------------------
-void CIntroMenu::ApplySchemeSettings( IScheme *pScheme )
-{
- BaseClass::ApplySchemeSettings( pScheme );
-
- LoadControlSettings("Resource/UI/IntroMenu.res");
-
- m_pTitleLabel = dynamic_cast<Label *>( FindChildByName( "titlelabel" ) );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CIntroMenu::Reset( void )
-{
- Update();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CIntroMenu::Update( void )
-{
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CIntroMenu::OnCommand( const char *command )
-{
- if ( !Q_strcmp( command, "skip" ) )
- {
- engine->ClientCmd( "intro_skip" );
- m_pViewPort->ShowPanel( this, false );
- }
-
- BaseClass::OnCommand( command );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CIntroMenu::ShowPanel( bool bShow )
-{
- if ( BaseClass::IsVisible() == bShow )
- return;
-
- m_pViewPort->ShowBackGround( bShow );
-
- if ( bShow )
- {
- Activate();
-
- if ( GameRules() )
- {
- SetDialogVariable( "gamemode", g_pVGuiLocalize->Find( GameRules()->GetGameTypeName() ) );
- }
-
- SetMouseInputEnabled( true );
- }
- else
- {
- SetVisible( false );
- SetMouseInputEnabled( false );
- }
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "cbase.h"
+#include "intromenu.h"
+#include <networkstringtabledefs.h>
+#include <cdll_client_int.h>
+#include <vgui/IScheme.h>
+#include <vgui/ILocalize.h>
+#include <vgui/ISurface.h>
+#include <filesystem.h>
+#include <KeyValues.h>
+#include <convar.h>
+#include <game/client/iviewport.h>
+#include "spectatorgui.h"
+#include "gamerules.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CIntroMenu::CIntroMenu( IViewPort *pViewPort ) : Frame( NULL, PANEL_INTRO )
+{
+ // initialize dialog
+ m_pViewPort = pViewPort;
+
+ m_pTitleLabel = NULL;
+
+ // load the new scheme early!!
+ SetScheme( "ClientScheme" );
+ SetMoveable( false );
+ SetSizeable( false );
+ SetProportional( true );
+
+ // hide the system buttons
+ SetTitleBarVisible( false );
+
+ Reset();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor
+//-----------------------------------------------------------------------------
+CIntroMenu::~CIntroMenu()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets the color of the top and bottom bars
+//-----------------------------------------------------------------------------
+void CIntroMenu::ApplySchemeSettings( IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ LoadControlSettings("Resource/UI/IntroMenu.res");
+
+ m_pTitleLabel = dynamic_cast<Label *>( FindChildByName( "titlelabel" ) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CIntroMenu::Reset( void )
+{
+ Update();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CIntroMenu::Update( void )
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CIntroMenu::OnCommand( const char *command )
+{
+ if ( !Q_strcmp( command, "skip" ) )
+ {
+ engine->ClientCmd( "intro_skip" );
+ m_pViewPort->ShowPanel( this, false );
+ }
+
+ BaseClass::OnCommand( command );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CIntroMenu::ShowPanel( bool bShow )
+{
+ if ( BaseClass::IsVisible() == bShow )
+ return;
+
+ m_pViewPort->ShowBackGround( bShow );
+
+ if ( bShow )
+ {
+ Activate();
+
+ if ( GameRules() )
+ {
+ SetDialogVariable( "gamemode", g_pVGuiLocalize->Find( GameRules()->GetGameTypeName() ) );
+ }
+
+ SetMouseInputEnabled( true );
+ }
+ else
+ {
+ SetVisible( false );
+ SetMouseInputEnabled( false );
+ }
+}
diff --git a/mp/src/game/client/game_controls/intromenu.h b/mp/src/game/client/game_controls/intromenu.h
index 43fa5874..02043ecd 100644
--- a/mp/src/game/client/game_controls/intromenu.h
+++ b/mp/src/game/client/game_controls/intromenu.h
@@ -1,57 +1,57 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================
-
-#ifndef INTROMENU_H
-#define INTROMENU_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-#include <vgui_controls/Frame.h>
-#include <vgui_controls/Button.h>
-#include <vgui_controls/Label.h>
-
-#include <game/client/iviewport.h>
-
-namespace vgui
-{
- class TextEntry;
-}
-
-class CIntroMenu : public vgui::Frame, public IViewPortPanel
-{
-private:
- DECLARE_CLASS_SIMPLE( CIntroMenu, vgui::Frame );
-
-public:
- CIntroMenu( IViewPort *pViewPort );
- virtual ~CIntroMenu();
-
- virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
-
- virtual const char *GetName( void ){ return PANEL_INTRO; }
- virtual void SetData( KeyValues *data ){ return; }
- virtual void Reset();
- virtual void Update();
- virtual bool NeedsUpdate( void ) { return false; }
- virtual bool HasInputElements( void ) { return true; }
- virtual void ShowPanel( bool bShow );
-
- // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
- vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
- virtual bool IsVisible() { return BaseClass::IsVisible(); }
- virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
-
-protected:
- // vgui overrides
- virtual void OnCommand( const char *command );
-
- IViewPort *m_pViewPort;
- vgui::Label *m_pTitleLabel;
-};
-
-#endif // INTROMENU_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#ifndef INTROMENU_H
+#define INTROMENU_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include <vgui_controls/Frame.h>
+#include <vgui_controls/Button.h>
+#include <vgui_controls/Label.h>
+
+#include <game/client/iviewport.h>
+
+namespace vgui
+{
+ class TextEntry;
+}
+
+class CIntroMenu : public vgui::Frame, public IViewPortPanel
+{
+private:
+ DECLARE_CLASS_SIMPLE( CIntroMenu, vgui::Frame );
+
+public:
+ CIntroMenu( IViewPort *pViewPort );
+ virtual ~CIntroMenu();
+
+ virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
+
+ virtual const char *GetName( void ){ return PANEL_INTRO; }
+ virtual void SetData( KeyValues *data ){ return; }
+ virtual void Reset();
+ virtual void Update();
+ virtual bool NeedsUpdate( void ) { return false; }
+ virtual bool HasInputElements( void ) { return true; }
+ virtual void ShowPanel( bool bShow );
+
+ // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
+ vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
+ virtual bool IsVisible() { return BaseClass::IsVisible(); }
+ virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
+
+protected:
+ // vgui overrides
+ virtual void OnCommand( const char *command );
+
+ IViewPort *m_pViewPort;
+ vgui::Label *m_pTitleLabel;
+};
+
+#endif // INTROMENU_H
diff --git a/mp/src/game/client/game_controls/mapoverview.h b/mp/src/game/client/game_controls/mapoverview.h
index c3196b4f..edaa2d1b 100644
--- a/mp/src/game/client/game_controls/mapoverview.h
+++ b/mp/src/game/client/game_controls/mapoverview.h
@@ -1,275 +1,275 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: MiniMap.h: interface for the CMiniMap class.
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#if !defined HLTVPANEL_H
-#define HLTVPANEL_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui_controls/Panel.h>
-#include <game/client/iviewport.h>
-#include "mathlib/vector.h"
-#include <igameevents.h>
-#include <shareddefs.h>
-#include <const.h>
-#include "hudelement.h"
-
-class IMapOverviewPanel
-{
-public:
- virtual void SetMode( int mode ) = 0;
- virtual int GetMode( void ) = 0;
- virtual void FlashEntity( int entityID ) = 0;
- virtual void SetPlayerPositions(int index, const Vector &position, const QAngle &angle) = 0;
- virtual void SetVisible(bool state) = 0;
- virtual float GetZoom( void ) = 0;
- virtual vgui::Panel *GetAsPanel() = 0;
- virtual bool AllowConCommandsWhileAlive() = 0;
- virtual void SetPlayerPreferredMode( int mode ) = 0;
- virtual void SetPlayerPreferredViewSize( float viewSize ) = 0;
- virtual bool IsVisible() = 0;
- virtual void GetBounds(int &x, int &y, int &wide, int &tall) = 0;
- virtual float GetFullZoom( void ) = 0;
- virtual float GetMapScale( void ) = 0;
-};
-
-#define MAX_TRAIL_LENGTH 30
-#define OVERVIEW_MAP_SIZE 1024 // an overview map is 1024x1024 pixels
-
-typedef bool ( *FnCustomMapOverviewObjectPaint )( int textureID, Vector pos, float scale, float angle, const char *text, Color *textColor, float status, Color *statusColor );
-
-
-class CMapOverview : public CHudElement, public vgui::Panel, public IMapOverviewPanel
-{
- DECLARE_CLASS_SIMPLE( CMapOverview, vgui::Panel );
-
-public:
-
- enum
- {
- MAP_MODE_OFF = 0, // Totally off
- MAP_MODE_INSET, // A little map up in a corner
- MAP_MODE_FULL, // Full screen, full map
- MAP_MODE_RADAR // In game radar, extra functionality
- };
-
- CMapOverview( const char *pElementName );
- virtual ~CMapOverview();
-
- virtual bool ShouldDraw( void );
- vgui::Panel *GetAsPanel(){ return this; }
- virtual bool AllowConCommandsWhileAlive(){return true;}
- virtual void SetPlayerPreferredMode( int mode ){}
- virtual void SetPlayerPreferredViewSize( float viewSize ){};
-
-protected: // private structures & types
-
- float GetViewAngle( void ); // The angle that determines the viewport twist from map texture to panel drawing.
-
- // list of game events the hLTV takes care of
-
- typedef struct {
- int xpos;
- int ypos;
- } FootStep_t;
-
- typedef struct MapPlayer_s {
- int index; // player's index
- int userid; // user ID on server
- int icon; // players texture icon ID
- Color color; // players team color
- char name[MAX_PLAYER_NAME_LENGTH];
- int team; // N,T,CT
- int health; // 0..100, 7 bit
- Vector position; // current x,y pos
- QAngle angle; // view origin 0..360
- Vector2D trail[MAX_TRAIL_LENGTH]; // save 1 footstep each second for 1 minute
- } MapPlayer_t;
-
- typedef struct MapObject_s {
- int objectID; // unique object ID
- int index; // entity index if any
- int icon; // players texture icon ID
- Color color; // players team color
- char name[MAX_PLAYER_NAME_LENGTH]; // show text under icon
- Vector position; // current x,y pos
- QAngle angle; // view origin 0..360
- float endtime; // time stop showing object
- float size; // object size
- float status; // green status bar [0..1], -1 = disabled
- Color statusColor; // color of status bar
- int flags; // MAB_OBJECT_*
- const char *text; // text to draw underneath the icon
- } MapObject_t;
-
-#define MAP_OBJECT_ALIGN_TO_MAP (1<<0)
-
-public: // IViewPortPanel interface:
-
- virtual const char *GetName( void ) { return PANEL_OVERVIEW; }
- virtual void SetData(KeyValues *data);
- virtual void Reset();
- virtual void OnThink();
- virtual void Update();
- virtual bool NeedsUpdate( void );
- virtual bool HasInputElements( void ) { return false; }
- virtual void ShowPanel( bool bShow );
- virtual void Init( void );
-
- // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
- vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
- virtual bool IsVisible() { return BaseClass::IsVisible(); }
- virtual void GetBounds(int &x, int &y, int &wide, int &tall) { BaseClass::GetBounds(x, y, wide, tall); }
- virtual void SetParent(vgui::VPANEL parent) { BaseClass::SetParent(parent); }
-
-public: // IGameEventListener
-
- virtual void FireGameEvent( IGameEvent *event);
-
-public: // VGUI overrides
-
- virtual void Paint();
- virtual void OnMousePressed( vgui::MouseCode code );
- virtual void ApplySchemeSettings(vgui::IScheme *scheme);
- virtual void SetVisible(bool state){BaseClass::SetVisible(state);}
-
-public:
-
- virtual float GetZoom( void );
- virtual int GetMode( void );
- virtual float GetFullZoom( void ){ return m_fFullZoom; }
- virtual float GetMapScale( void ){ return m_fMapScale; }
-
- // Player settings:
- virtual void ShowPlayerNames(bool state);
- virtual void ShowPlayerHealth(bool state);
- virtual void ShowPlayerTracks(float seconds);
- virtual void SetPlayerPositions(int index, const Vector &position, const QAngle &angle);
-
- // general settings:
- virtual void SetMap(const char * map);
- virtual void SetTime( float time );
- virtual void SetMode( int mode );
- virtual bool SetTeamColor(int team, Color color);
- virtual void SetFollowAngle(bool state);
- virtual void SetFollowEntity(int entindex); // 0 = off
- virtual void SetCenter( const Vector2D &mappos);
- virtual void SetAngle( float angle);
- virtual Vector2D WorldToMap( const Vector &worldpos );
-
- // Object settings
- virtual int AddObject( const char *icon, int entity, float timeToLive ); // returns object ID, 0 = no entity, -1 = forever
- virtual void SetObjectIcon( int objectID, const char *icon, float size ); // icon world size
- virtual void SetObjectText( int objectID, const char *text, Color color ); // text under icon
- virtual void SetObjectStatus( int objectID, float value, Color statusColor ); // status bar under icon
- virtual void SetObjectPosition( int objectID, const Vector &position, const QAngle &angle ); // world pos/angles
- virtual void AddObjectFlags( int objectID, int flags );
- virtual void SetObjectFlags( int objectID, int flags );
- virtual void RemoveObject( int objectID );
- virtual void RemoveObjectByIndex( int index );
- virtual void FlashEntity( int entityID ){}
-
- // rules that define if you can see a player on the overview or not
- virtual bool CanPlayerBeSeen(MapPlayer_t *player);
-
- /// allows mods to restrict health
- virtual bool CanPlayerHealthBeSeen(MapPlayer_t *player);
-
- /// allows mods to restrict names (e.g. CS when mp_playerid is non-zero)
- virtual bool CanPlayerNameBeSeen(MapPlayer_t *player);
-
- virtual int GetIconNumberFromTeamNumber( int teamNumber ){return teamNumber;}
-
-protected:
-
- virtual void DrawCamera();
- virtual void DrawObjects();
- virtual void DrawMapTexture();
- virtual void DrawMapPlayers();
- virtual void DrawMapPlayerTrails();
- virtual void UpdatePlayerTrails();
- virtual void ResetRound();
- virtual void InitTeamColorsAndIcons();
- virtual void UpdateSizeAndPosition();
- virtual bool RunHudAnimations(){ return true; }
-
- bool IsInPanel(Vector2D &pos);
- MapPlayer_t* GetPlayerByUserID( int userID );
- int AddIconTexture(const char *filename);
- Vector2D MapToPanel( const Vector2D &mappos );
- int GetPixelOffset( float height );
- void UpdateFollowEntity();
- virtual void UpdatePlayers();
- void UpdateObjects(); // objects bound to entities
- MapObject_t* FindObjectByID(int objectID);
- virtual bool IsRadarLocked() {return false;}
-
- virtual bool DrawIcon( MapObject_t *obj );
-
- /*virtual bool DrawIcon( int textureID,
- int offscreenTextureID,
- Vector pos,
- float scale,
- float angle,
- int alpha = 255,
- const char *text = NULL,
- Color *textColor = NULL,
- float status = -1,
- Color *statusColor = NULL,
- int objectType = OBJECT_TYPE_NORMAL );*/
-
- int m_nMode;
- Vector2D m_vPosition;
- Vector2D m_vSize;
- float m_flChangeSpeed;
- float m_flIconSize;
-
-
- IViewPort * m_pViewPort;
- MapPlayer_t m_Players[MAX_PLAYERS];
- CUtlDict< int, int> m_TextureIDs;
- CUtlVector<MapObject_t> m_Objects;
-
- Color m_TeamColors[MAX_TEAMS];
- int m_TeamIcons[MAX_TEAMS];
- int m_ObjectIcons[64];
- int m_ObjectCounterID;
- vgui::HFont m_hIconFont;
-
-
- bool m_bShowNames;
- bool m_bShowTrails;
- bool m_bShowHealth;
-
- int m_nMapTextureID; // texture id for current overview image
-
- KeyValues * m_MapKeyValues; // keyvalues describing overview parameters
-
- Vector m_MapOrigin; // read from KeyValues files
- float m_fMapScale; // origin and scale used when screenshot was made
- bool m_bRotateMap; // if true roatate map around 90 degress, so it fits better to 4:3 screen ratio
-
- int m_nFollowEntity;// entity number to follow, 0 = off
- CPanelAnimationVar( float, m_fZoom, "zoom", "1.0" ); // current zoom n = overview panel shows 1/n^2 of whole map'
- float m_fFullZoom; // best zoom factor for full map view (1.0 is map is a square)
- Vector2D m_ViewOrigin; // map coordinates that are in the center of the pverview panel
- Vector2D m_MapCenter; // map coordinates that are in the center of the pverview panel
-
- float m_fNextUpdateTime;
- float m_fViewAngle; // rotation of overview map
- float m_fWorldTime; // current world time
- float m_fNextTrailUpdate; // next time to update player trails
- float m_fTrailUpdateInterval; // if -1 don't show trails
- bool m_bFollowAngle; // if true, map rotates with view angle
-
-
-};
-
-extern IMapOverviewPanel *g_pMapOverview;
-
-#endif //
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: MiniMap.h: interface for the CMiniMap class.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#if !defined HLTVPANEL_H
+#define HLTVPANEL_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui_controls/Panel.h>
+#include <game/client/iviewport.h>
+#include "mathlib/vector.h"
+#include <igameevents.h>
+#include <shareddefs.h>
+#include <const.h>
+#include "hudelement.h"
+
+class IMapOverviewPanel
+{
+public:
+ virtual void SetMode( int mode ) = 0;
+ virtual int GetMode( void ) = 0;
+ virtual void FlashEntity( int entityID ) = 0;
+ virtual void SetPlayerPositions(int index, const Vector &position, const QAngle &angle) = 0;
+ virtual void SetVisible(bool state) = 0;
+ virtual float GetZoom( void ) = 0;
+ virtual vgui::Panel *GetAsPanel() = 0;
+ virtual bool AllowConCommandsWhileAlive() = 0;
+ virtual void SetPlayerPreferredMode( int mode ) = 0;
+ virtual void SetPlayerPreferredViewSize( float viewSize ) = 0;
+ virtual bool IsVisible() = 0;
+ virtual void GetBounds(int &x, int &y, int &wide, int &tall) = 0;
+ virtual float GetFullZoom( void ) = 0;
+ virtual float GetMapScale( void ) = 0;
+};
+
+#define MAX_TRAIL_LENGTH 30
+#define OVERVIEW_MAP_SIZE 1024 // an overview map is 1024x1024 pixels
+
+typedef bool ( *FnCustomMapOverviewObjectPaint )( int textureID, Vector pos, float scale, float angle, const char *text, Color *textColor, float status, Color *statusColor );
+
+
+class CMapOverview : public CHudElement, public vgui::Panel, public IMapOverviewPanel
+{
+ DECLARE_CLASS_SIMPLE( CMapOverview, vgui::Panel );
+
+public:
+
+ enum
+ {
+ MAP_MODE_OFF = 0, // Totally off
+ MAP_MODE_INSET, // A little map up in a corner
+ MAP_MODE_FULL, // Full screen, full map
+ MAP_MODE_RADAR // In game radar, extra functionality
+ };
+
+ CMapOverview( const char *pElementName );
+ virtual ~CMapOverview();
+
+ virtual bool ShouldDraw( void );
+ vgui::Panel *GetAsPanel(){ return this; }
+ virtual bool AllowConCommandsWhileAlive(){return true;}
+ virtual void SetPlayerPreferredMode( int mode ){}
+ virtual void SetPlayerPreferredViewSize( float viewSize ){};
+
+protected: // private structures & types
+
+ float GetViewAngle( void ); // The angle that determines the viewport twist from map texture to panel drawing.
+
+ // list of game events the hLTV takes care of
+
+ typedef struct {
+ int xpos;
+ int ypos;
+ } FootStep_t;
+
+ typedef struct MapPlayer_s {
+ int index; // player's index
+ int userid; // user ID on server
+ int icon; // players texture icon ID
+ Color color; // players team color
+ char name[MAX_PLAYER_NAME_LENGTH];
+ int team; // N,T,CT
+ int health; // 0..100, 7 bit
+ Vector position; // current x,y pos
+ QAngle angle; // view origin 0..360
+ Vector2D trail[MAX_TRAIL_LENGTH]; // save 1 footstep each second for 1 minute
+ } MapPlayer_t;
+
+ typedef struct MapObject_s {
+ int objectID; // unique object ID
+ int index; // entity index if any
+ int icon; // players texture icon ID
+ Color color; // players team color
+ char name[MAX_PLAYER_NAME_LENGTH]; // show text under icon
+ Vector position; // current x,y pos
+ QAngle angle; // view origin 0..360
+ float endtime; // time stop showing object
+ float size; // object size
+ float status; // green status bar [0..1], -1 = disabled
+ Color statusColor; // color of status bar
+ int flags; // MAB_OBJECT_*
+ const char *text; // text to draw underneath the icon
+ } MapObject_t;
+
+#define MAP_OBJECT_ALIGN_TO_MAP (1<<0)
+
+public: // IViewPortPanel interface:
+
+ virtual const char *GetName( void ) { return PANEL_OVERVIEW; }
+ virtual void SetData(KeyValues *data);
+ virtual void Reset();
+ virtual void OnThink();
+ virtual void Update();
+ virtual bool NeedsUpdate( void );
+ virtual bool HasInputElements( void ) { return false; }
+ virtual void ShowPanel( bool bShow );
+ virtual void Init( void );
+
+ // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
+ vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
+ virtual bool IsVisible() { return BaseClass::IsVisible(); }
+ virtual void GetBounds(int &x, int &y, int &wide, int &tall) { BaseClass::GetBounds(x, y, wide, tall); }
+ virtual void SetParent(vgui::VPANEL parent) { BaseClass::SetParent(parent); }
+
+public: // IGameEventListener
+
+ virtual void FireGameEvent( IGameEvent *event);
+
+public: // VGUI overrides
+
+ virtual void Paint();
+ virtual void OnMousePressed( vgui::MouseCode code );
+ virtual void ApplySchemeSettings(vgui::IScheme *scheme);
+ virtual void SetVisible(bool state){BaseClass::SetVisible(state);}
+
+public:
+
+ virtual float GetZoom( void );
+ virtual int GetMode( void );
+ virtual float GetFullZoom( void ){ return m_fFullZoom; }
+ virtual float GetMapScale( void ){ return m_fMapScale; }
+
+ // Player settings:
+ virtual void ShowPlayerNames(bool state);
+ virtual void ShowPlayerHealth(bool state);
+ virtual void ShowPlayerTracks(float seconds);
+ virtual void SetPlayerPositions(int index, const Vector &position, const QAngle &angle);
+
+ // general settings:
+ virtual void SetMap(const char * map);
+ virtual void SetTime( float time );
+ virtual void SetMode( int mode );
+ virtual bool SetTeamColor(int team, Color color);
+ virtual void SetFollowAngle(bool state);
+ virtual void SetFollowEntity(int entindex); // 0 = off
+ virtual void SetCenter( const Vector2D &mappos);
+ virtual void SetAngle( float angle);
+ virtual Vector2D WorldToMap( const Vector &worldpos );
+
+ // Object settings
+ virtual int AddObject( const char *icon, int entity, float timeToLive ); // returns object ID, 0 = no entity, -1 = forever
+ virtual void SetObjectIcon( int objectID, const char *icon, float size ); // icon world size
+ virtual void SetObjectText( int objectID, const char *text, Color color ); // text under icon
+ virtual void SetObjectStatus( int objectID, float value, Color statusColor ); // status bar under icon
+ virtual void SetObjectPosition( int objectID, const Vector &position, const QAngle &angle ); // world pos/angles
+ virtual void AddObjectFlags( int objectID, int flags );
+ virtual void SetObjectFlags( int objectID, int flags );
+ virtual void RemoveObject( int objectID );
+ virtual void RemoveObjectByIndex( int index );
+ virtual void FlashEntity( int entityID ){}
+
+ // rules that define if you can see a player on the overview or not
+ virtual bool CanPlayerBeSeen(MapPlayer_t *player);
+
+ /// allows mods to restrict health
+ virtual bool CanPlayerHealthBeSeen(MapPlayer_t *player);
+
+ /// allows mods to restrict names (e.g. CS when mp_playerid is non-zero)
+ virtual bool CanPlayerNameBeSeen(MapPlayer_t *player);
+
+ virtual int GetIconNumberFromTeamNumber( int teamNumber ){return teamNumber;}
+
+protected:
+
+ virtual void DrawCamera();
+ virtual void DrawObjects();
+ virtual void DrawMapTexture();
+ virtual void DrawMapPlayers();
+ virtual void DrawMapPlayerTrails();
+ virtual void UpdatePlayerTrails();
+ virtual void ResetRound();
+ virtual void InitTeamColorsAndIcons();
+ virtual void UpdateSizeAndPosition();
+ virtual bool RunHudAnimations(){ return true; }
+
+ bool IsInPanel(Vector2D &pos);
+ MapPlayer_t* GetPlayerByUserID( int userID );
+ int AddIconTexture(const char *filename);
+ Vector2D MapToPanel( const Vector2D &mappos );
+ int GetPixelOffset( float height );
+ void UpdateFollowEntity();
+ virtual void UpdatePlayers();
+ void UpdateObjects(); // objects bound to entities
+ MapObject_t* FindObjectByID(int objectID);
+ virtual bool IsRadarLocked() {return false;}
+
+ virtual bool DrawIcon( MapObject_t *obj );
+
+ /*virtual bool DrawIcon( int textureID,
+ int offscreenTextureID,
+ Vector pos,
+ float scale,
+ float angle,
+ int alpha = 255,
+ const char *text = NULL,
+ Color *textColor = NULL,
+ float status = -1,
+ Color *statusColor = NULL,
+ int objectType = OBJECT_TYPE_NORMAL );*/
+
+ int m_nMode;
+ Vector2D m_vPosition;
+ Vector2D m_vSize;
+ float m_flChangeSpeed;
+ float m_flIconSize;
+
+
+ IViewPort * m_pViewPort;
+ MapPlayer_t m_Players[MAX_PLAYERS];
+ CUtlDict< int, int> m_TextureIDs;
+ CUtlVector<MapObject_t> m_Objects;
+
+ Color m_TeamColors[MAX_TEAMS];
+ int m_TeamIcons[MAX_TEAMS];
+ int m_ObjectIcons[64];
+ int m_ObjectCounterID;
+ vgui::HFont m_hIconFont;
+
+
+ bool m_bShowNames;
+ bool m_bShowTrails;
+ bool m_bShowHealth;
+
+ int m_nMapTextureID; // texture id for current overview image
+
+ KeyValues * m_MapKeyValues; // keyvalues describing overview parameters
+
+ Vector m_MapOrigin; // read from KeyValues files
+ float m_fMapScale; // origin and scale used when screenshot was made
+ bool m_bRotateMap; // if true roatate map around 90 degress, so it fits better to 4:3 screen ratio
+
+ int m_nFollowEntity;// entity number to follow, 0 = off
+ CPanelAnimationVar( float, m_fZoom, "zoom", "1.0" ); // current zoom n = overview panel shows 1/n^2 of whole map'
+ float m_fFullZoom; // best zoom factor for full map view (1.0 is map is a square)
+ Vector2D m_ViewOrigin; // map coordinates that are in the center of the pverview panel
+ Vector2D m_MapCenter; // map coordinates that are in the center of the pverview panel
+
+ float m_fNextUpdateTime;
+ float m_fViewAngle; // rotation of overview map
+ float m_fWorldTime; // current world time
+ float m_fNextTrailUpdate; // next time to update player trails
+ float m_fTrailUpdateInterval; // if -1 don't show trails
+ bool m_bFollowAngle; // if true, map rotates with view angle
+
+
+};
+
+extern IMapOverviewPanel *g_pMapOverview;
+
+#endif //
diff --git a/mp/src/game/client/game_controls/mouseoverhtmlbutton.h b/mp/src/game/client/game_controls/mouseoverhtmlbutton.h
index b4143029..e3800832 100644
--- a/mp/src/game/client/game_controls/mouseoverhtmlbutton.h
+++ b/mp/src/game/client/game_controls/mouseoverhtmlbutton.h
@@ -1,119 +1,119 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef MOUSEOVERHTMLBUTTON_H
-#define MOUSEOVERHTMLBUTTON_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Triggers a new html page when the mouse goes over the button
-//-----------------------------------------------------------------------------
-class MouseOverHTMLButton : public vgui::Button
-{
-public:
- MouseOverHTMLButton(vgui::Panel *parent, const char *panelName, vgui::HTML *html, const char *page) :
- Button( parent, panelName, "MouseOverHTMLButton")
- {
- m_pHTML = html;
- m_iClass = 0;
- m_iIndex = -1;
- m_bAddShortCut = true;
- if ( page )
- {
- Q_strncpy( m_sPage, page, sizeof( m_sPage ) );
- }
- else
- {
- memset(m_sPage, 0x0, sizeof( m_sPage ) );
- }
- }
-
- void SetClass(int pClass, int index) { m_iClass = pClass; m_iIndex = index;}
- int GetClass() { return m_iClass; }
-
- void SetAddHotKey( bool state ) { m_bAddShortCut = state; }
-
- void SetPage( const char *page )
- {
- if ( page )
- {
- Q_strncpy( m_sPage, page, sizeof( m_sPage ) );
- }
- else
- {
- memset(m_sPage, 0x0, sizeof( m_sPage ) );
- }
- }
-
- void SetHTML( vgui::HTML *html)
- {
- m_pHTML = html;
- }
-
-
-private:
-
- virtual void OnCursorEntered()
- {
- Button::OnCursorEntered();
- if ( m_pHTML && strlen(m_sPage) > 0 )
- {
- m_pHTML->OpenURL(m_sPage);
- }
- }
-
- virtual void SetText(const char *text)
- {
- if ( m_iIndex != -1 )
- {
- wchar_t newText[ 128 ];
- wchar_t localizeText[ 128 ];
- wchar_t *ansiLocal;
- if ( text[0] == '#' && ( ansiLocal = g_pVGuiLocalize->Find( text ) ) )
- {
- // wcsncpy will crash if ansiLocal is null... *sigh*
- wcsncpy(localizeText, ansiLocal, sizeof(localizeText)/sizeof(wchar_t));
- }
- else
- {
- g_pVGuiLocalize->ConvertANSIToUnicode( text, localizeText, sizeof( localizeText ) );
- }
-
- if ( m_bAddShortCut )
- {
-#ifdef WIN32
- _snwprintf( newText, sizeof( newText )/ sizeof( wchar_t ), L"&%i %s", m_iIndex, localizeText);
-#else
- _snwprintf( newText, sizeof( newText )/ sizeof( wchar_t ), L"&%i %S", m_iIndex, localizeText);
-#endif
-
- }
- else
- {
- memcpy( newText, localizeText, sizeof( newText ) );
- }
-
- Button::SetText( newText );
- }
- else
- {
- Button::SetText( text );
- }
- }
-
- vgui::HTML *m_pHTML;
- char m_sPage[ 255 ];
- int m_iClass;
- int m_iIndex;
- bool m_bAddShortCut;
-};
-
-
-#endif // MOUSEOVERHTMLBUTTON_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef MOUSEOVERHTMLBUTTON_H
+#define MOUSEOVERHTMLBUTTON_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Triggers a new html page when the mouse goes over the button
+//-----------------------------------------------------------------------------
+class MouseOverHTMLButton : public vgui::Button
+{
+public:
+ MouseOverHTMLButton(vgui::Panel *parent, const char *panelName, vgui::HTML *html, const char *page) :
+ Button( parent, panelName, "MouseOverHTMLButton")
+ {
+ m_pHTML = html;
+ m_iClass = 0;
+ m_iIndex = -1;
+ m_bAddShortCut = true;
+ if ( page )
+ {
+ Q_strncpy( m_sPage, page, sizeof( m_sPage ) );
+ }
+ else
+ {
+ memset(m_sPage, 0x0, sizeof( m_sPage ) );
+ }
+ }
+
+ void SetClass(int pClass, int index) { m_iClass = pClass; m_iIndex = index;}
+ int GetClass() { return m_iClass; }
+
+ void SetAddHotKey( bool state ) { m_bAddShortCut = state; }
+
+ void SetPage( const char *page )
+ {
+ if ( page )
+ {
+ Q_strncpy( m_sPage, page, sizeof( m_sPage ) );
+ }
+ else
+ {
+ memset(m_sPage, 0x0, sizeof( m_sPage ) );
+ }
+ }
+
+ void SetHTML( vgui::HTML *html)
+ {
+ m_pHTML = html;
+ }
+
+
+private:
+
+ virtual void OnCursorEntered()
+ {
+ Button::OnCursorEntered();
+ if ( m_pHTML && strlen(m_sPage) > 0 )
+ {
+ m_pHTML->OpenURL(m_sPage);
+ }
+ }
+
+ virtual void SetText(const char *text)
+ {
+ if ( m_iIndex != -1 )
+ {
+ wchar_t newText[ 128 ];
+ wchar_t localizeText[ 128 ];
+ wchar_t *ansiLocal;
+ if ( text[0] == '#' && ( ansiLocal = g_pVGuiLocalize->Find( text ) ) )
+ {
+ // wcsncpy will crash if ansiLocal is null... *sigh*
+ wcsncpy(localizeText, ansiLocal, sizeof(localizeText)/sizeof(wchar_t));
+ }
+ else
+ {
+ g_pVGuiLocalize->ConvertANSIToUnicode( text, localizeText, sizeof( localizeText ) );
+ }
+
+ if ( m_bAddShortCut )
+ {
+#ifdef WIN32
+ _snwprintf( newText, sizeof( newText )/ sizeof( wchar_t ), L"&%i %s", m_iIndex, localizeText);
+#else
+ _snwprintf( newText, sizeof( newText )/ sizeof( wchar_t ), L"&%i %S", m_iIndex, localizeText);
+#endif
+
+ }
+ else
+ {
+ memcpy( newText, localizeText, sizeof( newText ) );
+ }
+
+ Button::SetText( newText );
+ }
+ else
+ {
+ Button::SetText( text );
+ }
+ }
+
+ vgui::HTML *m_pHTML;
+ char m_sPage[ 255 ];
+ int m_iClass;
+ int m_iIndex;
+ bool m_bAddShortCut;
+};
+
+
+#endif // MOUSEOVERHTMLBUTTON_H
diff --git a/mp/src/game/client/game_controls/mouseoverpanelbutton.h b/mp/src/game/client/game_controls/mouseoverpanelbutton.h
index f39edc59..9e4e245d 100644
--- a/mp/src/game/client/game_controls/mouseoverpanelbutton.h
+++ b/mp/src/game/client/game_controls/mouseoverpanelbutton.h
@@ -1,186 +1,186 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef MOUSEOVERPANELBUTTON_H
-#define MOUSEOVERPANELBUTTON_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui/IScheme.h>
-#include <vgui_controls/Button.h>
-#include <vgui/KeyCode.h>
-#include <filesystem.h>
-
-extern vgui::Panel *g_lastPanel;
-extern vgui::Button *g_lastButton;
-
-//-----------------------------------------------------------------------------
-// Purpose: Triggers a new panel when the mouse goes over the button
-//
-// the new panel has the same dimensions as the passed templatePanel and is of
-// the same class.
-//
-// must at least inherit from vgui::EditablePanel to support LoadControlSettings
-//-----------------------------------------------------------------------------
-template <class T>
-class MouseOverButton : public vgui::Button
-{
-private:
- DECLARE_CLASS_SIMPLE( MouseOverButton, vgui::Button );
-
-public:
- MouseOverButton(vgui::Panel *parent, const char *panelName, T *templatePanel ) :
- Button( parent, panelName, "MouseOverButton")
- {
- m_pPanel = new T( parent, NULL );
- m_pPanel ->SetVisible( false );
-
- // copy size&pos from template panel
- int x,y,wide,tall;
- templatePanel->GetBounds( x, y, wide, tall );
- m_pPanel->SetBounds( x, y, wide, tall );
- int px, py;
- templatePanel->GetPinOffset( px, py );
- int rx, ry;
- templatePanel->GetResizeOffset( rx, ry );
- // Apply pin settings from template, too
- m_pPanel->SetAutoResize( templatePanel->GetPinCorner(), templatePanel->GetAutoResize(), px, py, rx, ry );
-
- m_bPreserveArmedButtons = false;
- m_bUpdateDefaultButtons = false;
- }
-
- virtual void SetPreserveArmedButtons( bool bPreserve ){ m_bPreserveArmedButtons = bPreserve; }
- virtual void SetUpdateDefaultButtons( bool bUpdate ){ m_bUpdateDefaultButtons = bUpdate; }
-
- virtual void ShowPage()
- {
- if( m_pPanel )
- {
- m_pPanel->SetVisible( true );
- m_pPanel->MoveToFront();
- g_lastPanel = m_pPanel;
- }
- }
-
- virtual void HidePage()
- {
- if ( m_pPanel )
- {
- m_pPanel->SetVisible( false );
- }
- }
-
- const char *GetClassPage( const char *className )
- {
- static char classPanel[ _MAX_PATH ];
- Q_snprintf( classPanel, sizeof( classPanel ), "classes/%s.res", className);
-
- if ( g_pFullFileSystem->FileExists( classPanel, IsX360() ? "MOD" : "GAME" ) )
- {
- }
- else if (g_pFullFileSystem->FileExists( "classes/default.res", IsX360() ? "MOD" : "GAME" ) )
- {
- Q_snprintf ( classPanel, sizeof( classPanel ), "classes/default.res" );
- }
- else
- {
- return NULL;
- }
-
- return classPanel;
- }
-
-#ifdef REFRESH_CLASSMENU_TOOL
-
- void RefreshClassPage( void )
- {
- m_pPanel->LoadControlSettings( GetClassPage( GetName() ) );
- }
-
-#endif
-
- virtual void ApplySettings( KeyValues *resourceData )
- {
- BaseClass::ApplySettings( resourceData );
-
- // name, position etc of button is set, now load matching
- // resource file for associated info panel:
- m_pPanel->LoadControlSettings( GetClassPage( GetName() ) );
- }
-
- T *GetClassPanel( void ) { return m_pPanel; }
-
- virtual void OnCursorExited()
- {
- if ( !m_bPreserveArmedButtons )
- {
- BaseClass::OnCursorExited();
- }
- }
-
- virtual void OnCursorEntered()
- {
- BaseClass::OnCursorEntered();
-
- if ( !IsEnabled() )
- return;
-
- // are we updating the default buttons?
- if ( m_bUpdateDefaultButtons )
- {
- SetAsDefaultButton( 1 );
- }
-
- // are we preserving the armed state (and need to turn off the old button)?
- if ( m_bPreserveArmedButtons )
- {
- if ( g_lastButton && g_lastButton != this )
- {
- g_lastButton->SetArmed( false );
- }
-
- g_lastButton = this;
- }
-
- // turn on our panel (if it isn't already)
- if ( m_pPanel && ( !m_pPanel->IsVisible() ) )
- {
- // turn off the previous panel
- if ( g_lastPanel && g_lastPanel->IsVisible() )
- {
- g_lastPanel->SetVisible( false );
- }
-
- ShowPage();
- }
- }
-
- virtual void OnKeyCodeReleased( vgui::KeyCode code )
- {
- BaseClass::OnKeyCodeReleased( code );
-
- if ( m_bPreserveArmedButtons )
- {
- if ( g_lastButton )
- {
- g_lastButton->SetArmed( true );
- }
- }
- }
-
-private:
-
- T *m_pPanel;
- bool m_bPreserveArmedButtons;
- bool m_bUpdateDefaultButtons;
-};
-
-#define MouseOverPanelButton MouseOverButton<vgui::EditablePanel>
-
-#endif // MOUSEOVERPANELBUTTON_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef MOUSEOVERPANELBUTTON_H
+#define MOUSEOVERPANELBUTTON_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui/IScheme.h>
+#include <vgui_controls/Button.h>
+#include <vgui/KeyCode.h>
+#include <filesystem.h>
+
+extern vgui::Panel *g_lastPanel;
+extern vgui::Button *g_lastButton;
+
+//-----------------------------------------------------------------------------
+// Purpose: Triggers a new panel when the mouse goes over the button
+//
+// the new panel has the same dimensions as the passed templatePanel and is of
+// the same class.
+//
+// must at least inherit from vgui::EditablePanel to support LoadControlSettings
+//-----------------------------------------------------------------------------
+template <class T>
+class MouseOverButton : public vgui::Button
+{
+private:
+ DECLARE_CLASS_SIMPLE( MouseOverButton, vgui::Button );
+
+public:
+ MouseOverButton(vgui::Panel *parent, const char *panelName, T *templatePanel ) :
+ Button( parent, panelName, "MouseOverButton")
+ {
+ m_pPanel = new T( parent, NULL );
+ m_pPanel ->SetVisible( false );
+
+ // copy size&pos from template panel
+ int x,y,wide,tall;
+ templatePanel->GetBounds( x, y, wide, tall );
+ m_pPanel->SetBounds( x, y, wide, tall );
+ int px, py;
+ templatePanel->GetPinOffset( px, py );
+ int rx, ry;
+ templatePanel->GetResizeOffset( rx, ry );
+ // Apply pin settings from template, too
+ m_pPanel->SetAutoResize( templatePanel->GetPinCorner(), templatePanel->GetAutoResize(), px, py, rx, ry );
+
+ m_bPreserveArmedButtons = false;
+ m_bUpdateDefaultButtons = false;
+ }
+
+ virtual void SetPreserveArmedButtons( bool bPreserve ){ m_bPreserveArmedButtons = bPreserve; }
+ virtual void SetUpdateDefaultButtons( bool bUpdate ){ m_bUpdateDefaultButtons = bUpdate; }
+
+ virtual void ShowPage()
+ {
+ if( m_pPanel )
+ {
+ m_pPanel->SetVisible( true );
+ m_pPanel->MoveToFront();
+ g_lastPanel = m_pPanel;
+ }
+ }
+
+ virtual void HidePage()
+ {
+ if ( m_pPanel )
+ {
+ m_pPanel->SetVisible( false );
+ }
+ }
+
+ const char *GetClassPage( const char *className )
+ {
+ static char classPanel[ _MAX_PATH ];
+ Q_snprintf( classPanel, sizeof( classPanel ), "classes/%s.res", className);
+
+ if ( g_pFullFileSystem->FileExists( classPanel, IsX360() ? "MOD" : "GAME" ) )
+ {
+ }
+ else if (g_pFullFileSystem->FileExists( "classes/default.res", IsX360() ? "MOD" : "GAME" ) )
+ {
+ Q_snprintf ( classPanel, sizeof( classPanel ), "classes/default.res" );
+ }
+ else
+ {
+ return NULL;
+ }
+
+ return classPanel;
+ }
+
+#ifdef REFRESH_CLASSMENU_TOOL
+
+ void RefreshClassPage( void )
+ {
+ m_pPanel->LoadControlSettings( GetClassPage( GetName() ) );
+ }
+
+#endif
+
+ virtual void ApplySettings( KeyValues *resourceData )
+ {
+ BaseClass::ApplySettings( resourceData );
+
+ // name, position etc of button is set, now load matching
+ // resource file for associated info panel:
+ m_pPanel->LoadControlSettings( GetClassPage( GetName() ) );
+ }
+
+ T *GetClassPanel( void ) { return m_pPanel; }
+
+ virtual void OnCursorExited()
+ {
+ if ( !m_bPreserveArmedButtons )
+ {
+ BaseClass::OnCursorExited();
+ }
+ }
+
+ virtual void OnCursorEntered()
+ {
+ BaseClass::OnCursorEntered();
+
+ if ( !IsEnabled() )
+ return;
+
+ // are we updating the default buttons?
+ if ( m_bUpdateDefaultButtons )
+ {
+ SetAsDefaultButton( 1 );
+ }
+
+ // are we preserving the armed state (and need to turn off the old button)?
+ if ( m_bPreserveArmedButtons )
+ {
+ if ( g_lastButton && g_lastButton != this )
+ {
+ g_lastButton->SetArmed( false );
+ }
+
+ g_lastButton = this;
+ }
+
+ // turn on our panel (if it isn't already)
+ if ( m_pPanel && ( !m_pPanel->IsVisible() ) )
+ {
+ // turn off the previous panel
+ if ( g_lastPanel && g_lastPanel->IsVisible() )
+ {
+ g_lastPanel->SetVisible( false );
+ }
+
+ ShowPage();
+ }
+ }
+
+ virtual void OnKeyCodeReleased( vgui::KeyCode code )
+ {
+ BaseClass::OnKeyCodeReleased( code );
+
+ if ( m_bPreserveArmedButtons )
+ {
+ if ( g_lastButton )
+ {
+ g_lastButton->SetArmed( true );
+ }
+ }
+ }
+
+private:
+
+ T *m_pPanel;
+ bool m_bPreserveArmedButtons;
+ bool m_bUpdateDefaultButtons;
+};
+
+#define MouseOverPanelButton MouseOverButton<vgui::EditablePanel>
+
+#endif // MOUSEOVERPANELBUTTON_H
diff --git a/mp/src/game/client/game_controls/spectatorgui.h b/mp/src/game/client/game_controls/spectatorgui.h
index e8981973..29626085 100644
--- a/mp/src/game/client/game_controls/spectatorgui.h
+++ b/mp/src/game/client/game_controls/spectatorgui.h
@@ -1,154 +1,154 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef SPECTATORGUI_H
-#define SPECTATORGUI_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui/IScheme.h>
-#include <vgui/KeyCode.h>
-#include <vgui_controls/Frame.h>
-#include <vgui_controls/EditablePanel.h>
-#include <vgui_controls/Button.h>
-#include <vgui_controls/ComboBox.h>
-#include <igameevents.h>
-#include "GameEventListener.h"
-
-#include <game/client/iviewport.h>
-
-class KeyValues;
-
-namespace vgui
-{
- class TextEntry;
- class Button;
- class Panel;
- class ImagePanel;
- class ComboBox;
-}
-
-#define BLACK_BAR_COLOR Color(0, 0, 0, 196)
-
-class IBaseFileSystem;
-
-//-----------------------------------------------------------------------------
-// Purpose: Spectator UI
-//-----------------------------------------------------------------------------
-class CSpectatorGUI : public vgui::EditablePanel, public IViewPortPanel
-{
- DECLARE_CLASS_SIMPLE( CSpectatorGUI, vgui::EditablePanel );
-
-public:
- CSpectatorGUI( IViewPort *pViewPort );
- virtual ~CSpectatorGUI();
-
- virtual const char *GetName( void ) { return PANEL_SPECGUI; }
- virtual void SetData(KeyValues *data) {};
- virtual void Reset() {};
- virtual void Update();
- virtual bool NeedsUpdate( void ) { return false; }
- virtual bool HasInputElements( void ) { return false; }
- virtual void ShowPanel( bool bShow );
-
- // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
- vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
- virtual bool IsVisible() { return BaseClass::IsVisible(); }
- virtual void SetParent(vgui::VPANEL parent) { BaseClass::SetParent(parent); }
- virtual void OnThink();
-
- virtual int GetTopBarHeight() { return m_pTopBar->GetTall(); }
- virtual int GetBottomBarHeight() { return m_pBottomBarBlank->GetTall(); }
-
- virtual bool ShouldShowPlayerLabel( int specmode );
-
- virtual Color GetBlackBarColor( void ) { return BLACK_BAR_COLOR; }
-
- virtual const char *GetResFile( void ) { return "Resource/UI/Spectator.res"; }
-
-protected:
-
- void SetLabelText(const char *textEntryName, const char *text);
- void SetLabelText(const char *textEntryName, wchar_t *text);
- void MoveLabelToFront(const char *textEntryName);
- void UpdateTimer();
- void SetLogoImage(const char *image);
-
-protected:
- enum { INSET_OFFSET = 2 } ;
-
- // vgui overrides
- virtual void PerformLayout();
- virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
-// virtual void OnCommand( const char *command );
-
- vgui::Panel *m_pTopBar;
- vgui::Panel *m_pBottomBarBlank;
-
- vgui::ImagePanel *m_pBannerImage;
- vgui::Label *m_pPlayerLabel;
-
- IViewPort *m_pViewPort;
-
- // bool m_bHelpShown;
- // bool m_bInsetVisible;
- bool m_bSpecScoreboard;
-};
-
-
-//-----------------------------------------------------------------------------
-// Purpose: the bottom bar panel, this is a separate panel because it
-// wants mouse input and the main window doesn't
-//----------------------------------------------------------------------------
-class CSpectatorMenu : public vgui::Frame, public IViewPortPanel, public CGameEventListener
-{
- DECLARE_CLASS_SIMPLE( CSpectatorMenu, vgui::Frame );
-
-public:
- CSpectatorMenu( IViewPort *pViewPort );
- ~CSpectatorMenu() {}
-
- virtual const char *GetName( void ) { return PANEL_SPECMENU; }
- virtual void SetData(KeyValues *data) {};
- virtual void Reset( void ) { m_pPlayerList->DeleteAllItems(); }
- virtual void Update( void );
- virtual bool NeedsUpdate( void ) { return false; }
- virtual bool HasInputElements( void ) { return true; }
- virtual void ShowPanel( bool bShow );
- virtual void FireGameEvent( IGameEvent *event );
-
- // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
- virtual bool IsVisible() { return BaseClass::IsVisible(); }
- vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
- virtual void SetParent(vgui::VPANEL parent) { BaseClass::SetParent(parent); }
-
-private:
- // VGUI2 overrides
- MESSAGE_FUNC_PARAMS( OnTextChanged, "TextChanged", data );
- virtual void OnCommand( const char *command );
- virtual void OnKeyCodePressed(vgui::KeyCode code);
- virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
- virtual void PerformLayout();
-
- void SetViewModeText( const char *text ) { m_pViewOptions->SetText( text ); }
- void SetPlayerFgColor( Color c1 ) { m_pPlayerList->SetFgColor(c1); }
-
- vgui::ComboBox *m_pPlayerList;
- vgui::ComboBox *m_pViewOptions;
- vgui::ComboBox *m_pConfigSettings;
-
- vgui::Button *m_pLeftButton;
- vgui::Button *m_pRightButton;
-
- IViewPort *m_pViewPort;
- ButtonCode_t m_iDuckKey;
-};
-
-extern CSpectatorGUI * g_pSpectatorGUI;
-
-#endif // SPECTATORGUI_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef SPECTATORGUI_H
+#define SPECTATORGUI_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui/IScheme.h>
+#include <vgui/KeyCode.h>
+#include <vgui_controls/Frame.h>
+#include <vgui_controls/EditablePanel.h>
+#include <vgui_controls/Button.h>
+#include <vgui_controls/ComboBox.h>
+#include <igameevents.h>
+#include "GameEventListener.h"
+
+#include <game/client/iviewport.h>
+
+class KeyValues;
+
+namespace vgui
+{
+ class TextEntry;
+ class Button;
+ class Panel;
+ class ImagePanel;
+ class ComboBox;
+}
+
+#define BLACK_BAR_COLOR Color(0, 0, 0, 196)
+
+class IBaseFileSystem;
+
+//-----------------------------------------------------------------------------
+// Purpose: Spectator UI
+//-----------------------------------------------------------------------------
+class CSpectatorGUI : public vgui::EditablePanel, public IViewPortPanel
+{
+ DECLARE_CLASS_SIMPLE( CSpectatorGUI, vgui::EditablePanel );
+
+public:
+ CSpectatorGUI( IViewPort *pViewPort );
+ virtual ~CSpectatorGUI();
+
+ virtual const char *GetName( void ) { return PANEL_SPECGUI; }
+ virtual void SetData(KeyValues *data) {};
+ virtual void Reset() {};
+ virtual void Update();
+ virtual bool NeedsUpdate( void ) { return false; }
+ virtual bool HasInputElements( void ) { return false; }
+ virtual void ShowPanel( bool bShow );
+
+ // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
+ vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
+ virtual bool IsVisible() { return BaseClass::IsVisible(); }
+ virtual void SetParent(vgui::VPANEL parent) { BaseClass::SetParent(parent); }
+ virtual void OnThink();
+
+ virtual int GetTopBarHeight() { return m_pTopBar->GetTall(); }
+ virtual int GetBottomBarHeight() { return m_pBottomBarBlank->GetTall(); }
+
+ virtual bool ShouldShowPlayerLabel( int specmode );
+
+ virtual Color GetBlackBarColor( void ) { return BLACK_BAR_COLOR; }
+
+ virtual const char *GetResFile( void ) { return "Resource/UI/Spectator.res"; }
+
+protected:
+
+ void SetLabelText(const char *textEntryName, const char *text);
+ void SetLabelText(const char *textEntryName, wchar_t *text);
+ void MoveLabelToFront(const char *textEntryName);
+ void UpdateTimer();
+ void SetLogoImage(const char *image);
+
+protected:
+ enum { INSET_OFFSET = 2 } ;
+
+ // vgui overrides
+ virtual void PerformLayout();
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
+// virtual void OnCommand( const char *command );
+
+ vgui::Panel *m_pTopBar;
+ vgui::Panel *m_pBottomBarBlank;
+
+ vgui::ImagePanel *m_pBannerImage;
+ vgui::Label *m_pPlayerLabel;
+
+ IViewPort *m_pViewPort;
+
+ // bool m_bHelpShown;
+ // bool m_bInsetVisible;
+ bool m_bSpecScoreboard;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: the bottom bar panel, this is a separate panel because it
+// wants mouse input and the main window doesn't
+//----------------------------------------------------------------------------
+class CSpectatorMenu : public vgui::Frame, public IViewPortPanel, public CGameEventListener
+{
+ DECLARE_CLASS_SIMPLE( CSpectatorMenu, vgui::Frame );
+
+public:
+ CSpectatorMenu( IViewPort *pViewPort );
+ ~CSpectatorMenu() {}
+
+ virtual const char *GetName( void ) { return PANEL_SPECMENU; }
+ virtual void SetData(KeyValues *data) {};
+ virtual void Reset( void ) { m_pPlayerList->DeleteAllItems(); }
+ virtual void Update( void );
+ virtual bool NeedsUpdate( void ) { return false; }
+ virtual bool HasInputElements( void ) { return true; }
+ virtual void ShowPanel( bool bShow );
+ virtual void FireGameEvent( IGameEvent *event );
+
+ // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
+ virtual bool IsVisible() { return BaseClass::IsVisible(); }
+ vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
+ virtual void SetParent(vgui::VPANEL parent) { BaseClass::SetParent(parent); }
+
+private:
+ // VGUI2 overrides
+ MESSAGE_FUNC_PARAMS( OnTextChanged, "TextChanged", data );
+ virtual void OnCommand( const char *command );
+ virtual void OnKeyCodePressed(vgui::KeyCode code);
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
+ virtual void PerformLayout();
+
+ void SetViewModeText( const char *text ) { m_pViewOptions->SetText( text ); }
+ void SetPlayerFgColor( Color c1 ) { m_pPlayerList->SetFgColor(c1); }
+
+ vgui::ComboBox *m_pPlayerList;
+ vgui::ComboBox *m_pViewOptions;
+ vgui::ComboBox *m_pConfigSettings;
+
+ vgui::Button *m_pLeftButton;
+ vgui::Button *m_pRightButton;
+
+ IViewPort *m_pViewPort;
+ ButtonCode_t m_iDuckKey;
+};
+
+extern CSpectatorGUI * g_pSpectatorGUI;
+
+#endif // SPECTATORGUI_H
diff --git a/mp/src/game/client/game_controls/teammenu.cpp b/mp/src/game/client/game_controls/teammenu.cpp
index 638534e7..c242c936 100644
--- a/mp/src/game/client/game_controls/teammenu.cpp
+++ b/mp/src/game/client/game_controls/teammenu.cpp
@@ -1,444 +1,444 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include <cdll_client_int.h>
-
-#include "teammenu.h"
-
-#include <vgui/IScheme.h>
-#include <vgui/ILocalize.h>
-#include <vgui/ISurface.h>
-#include <KeyValues.h>
-#include <vgui_controls/ImageList.h>
-#include <filesystem.h>
-
-#include <vgui_controls/RichText.h>
-#include <vgui_controls/Label.h>
-#include <vgui_controls/Button.h>
-#include <vgui_controls/HTML.h>
-
-#include "IGameUIFuncs.h" // for key bindings
-#include <igameresources.h>
-#include <game/client/iviewport.h>
-#include <stdlib.h> // MAX_PATH define
-#include <stdio.h>
-#include "byteswap.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-extern IGameUIFuncs *gameuifuncs; // for key binding details
-
-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 = BUTTON_CODE_INVALID; // this is looked up in Activate()
- m_iScoreBoardKey = BUTTON_CODE_INVALID; // 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" );
-
-#if defined( ENABLE_HTML_WINDOW )
- m_pMapInfoHTML = new HTML( this, "MapInfoHTML");
-#endif
-
- 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");
- OnClose();
-}
-
-
-//-----------------------------------------------------------------------------
-// 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 == BUTTON_CODE_INVALID ) // you need to lookup the jump key AFTER the engine has loaded
- {
- m_iJumpKey = gameuifuncs->GetButtonCodeForBind( "jump" );
- }
-
- if ( m_iScoreBoardKey == BUTTON_CODE_INVALID )
- {
- m_iScoreBoardKey = gameuifuncs->GetButtonCodeForBind( "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 ( !g_pFullFileSystem->FileExists( mapRES ) )
- {
- // try english
- Q_snprintf( mapRES, sizeof( mapRES ), "resource/maphtml/%s_english.html", mapName );
- }
- else
- {
- bFoundHTML = true;
- }
-
- if( bFoundHTML || g_pFullFileSystem->FileExists( mapRES ) )
- {
- // it's a local HTML file
- char localURL[ _MAX_PATH + 7 ];
- Q_strncpy( localURL, "file://", sizeof( localURL ) );
-
- char pPathData[ _MAX_PATH ];
- g_pFullFileSystem->GetLocalPath( mapRES, pPathData, sizeof(pPathData) );
- Q_strncat( localURL, pPathData, sizeof( localURL ), COPY_ALL_CHARACTERS );
-
- // force steam to dump a local copy
- g_pFullFileSystem->GetLocalCopy( pPathData );
-
- m_pMapInfo->SetVisible( false );
-
-#if defined( ENABLE_HTML_WINDOW )
- m_pMapInfoHTML->SetVisible( true );
- m_pMapInfoHTML->OpenURL( localURL, NULL );
-#endif
- InvalidateLayout();
- Repaint();
-
- return;
- }
- else
- {
- m_pMapInfo->SetVisible( true );
-
-#if defined( ENABLE_HTML_WINDOW )
- m_pMapInfoHTML->SetVisible( false );
-#endif
- }
-
- Q_snprintf( mapRES, sizeof( mapRES ), "maps/%s.txt", mapName);
-
- // if no map specific description exists, load default text
- if( !g_pFullFileSystem->FileExists( mapRES ) )
- {
- if ( g_pFullFileSystem->FileExists( "maps/default.txt" ) )
- {
- Q_snprintf ( mapRES, sizeof( mapRES ), "maps/default.txt");
- }
- else
- {
- m_pMapInfo->SetText( "" );
- return;
- }
- }
-
- FileHandle_t f = g_pFullFileSystem->Open( mapRES, "r" );
-
- // read into a memory block
- int fileSize = g_pFullFileSystem->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 = g_pFullFileSystem->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<char *>( memBlock );
- data[ bytesRead ] = 0;
- data[ bytesRead+1 ] = 0;
- }
-
-#ifndef WIN32
- if ( ((ucs2 *)memBlock)[0] == 0xFEFF )
- {
- // convert the win32 ucs2 data to wchar_t
- dataSize*=2;// need to *2 to account for ucs2 to wchar_t (4byte) growth
- wchar_t *memBlockConverted = (wchar_t *)malloc(dataSize);
- V_UCS2ToUnicode( (ucs2 *)memBlock, memBlockConverted, dataSize );
- free(memBlock);
- memBlock = memBlockConverted;
- }
-#else
- // null-terminate the stream (redundant, since we memset & then trimmed the transformed buffer already)
- memBlock[dataSize / sizeof(wchar_t) - 1] = 0x0000;
-#endif
- // ensure little-endian unicode reads correctly on all platforms
- CByteswap byteSwap;
- byteSwap.SetTargetBigEndian( false );
- byteSwap.SwapBufferToTargetEndian( memBlock, memBlock, dataSize/sizeof(wchar_t) );
-
- // 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<char *>( memBlock ) );
- }
- else
- {
- m_pMapInfo->SetText( memBlock+1 );
- }
- // go back to the top of the text buffer
- m_pMapInfo->GotoTextStart();
-
- g_pFullFileSystem->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<Label *>(FindChildByName(textEntryName));
- if (entry)
- {
- entry->SetText(text);
- }
-}
-
-void CTeamMenu::OnKeyCodePressed(KeyCode code)
-{
- int nDir = 0;
-
- switch ( code )
- {
- case KEY_XBUTTON_UP:
- case KEY_XSTICK1_UP:
- case KEY_XSTICK2_UP:
- case KEY_UP:
- case KEY_XBUTTON_LEFT:
- case KEY_XSTICK1_LEFT:
- case KEY_XSTICK2_LEFT:
- case KEY_LEFT:
- nDir = -1;
- break;
-
- case KEY_XBUTTON_DOWN:
- case KEY_XSTICK1_DOWN:
- case KEY_XSTICK2_DOWN:
- case KEY_DOWN:
- case KEY_XBUTTON_RIGHT:
- case KEY_XSTICK1_RIGHT:
- case KEY_XSTICK2_RIGHT:
- case KEY_RIGHT:
- nDir = 1;
- break;
- }
-
- if ( m_iScoreBoardKey != BUTTON_CODE_INVALID && m_iScoreBoardKey == code )
- {
- gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, true );
- gViewPortInterface->PostMessageToPanel( PANEL_SCOREBOARD, new KeyValues( "PollHideCode", "code", code ) );
- }
- else if ( nDir != 0 )
- {
- CUtlSortVector< SortedPanel_t, CSortedPanelYLess > vecSortedButtons;
- VguiPanelGetSortedChildButtonList( this, (void*)&vecSortedButtons, "&", 0 );
-
- if ( VguiPanelNavigateSortedChildButtonList( (void*)&vecSortedButtons, nDir ) != -1 )
- {
- // Handled!
- return;
- }
- }
- else
- {
- BaseClass::OnKeyCodePressed( code );
- }
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include <cdll_client_int.h>
+
+#include "teammenu.h"
+
+#include <vgui/IScheme.h>
+#include <vgui/ILocalize.h>
+#include <vgui/ISurface.h>
+#include <KeyValues.h>
+#include <vgui_controls/ImageList.h>
+#include <filesystem.h>
+
+#include <vgui_controls/RichText.h>
+#include <vgui_controls/Label.h>
+#include <vgui_controls/Button.h>
+#include <vgui_controls/HTML.h>
+
+#include "IGameUIFuncs.h" // for key bindings
+#include <igameresources.h>
+#include <game/client/iviewport.h>
+#include <stdlib.h> // MAX_PATH define
+#include <stdio.h>
+#include "byteswap.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+extern IGameUIFuncs *gameuifuncs; // for key binding details
+
+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 = BUTTON_CODE_INVALID; // this is looked up in Activate()
+ m_iScoreBoardKey = BUTTON_CODE_INVALID; // 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" );
+
+#if defined( ENABLE_HTML_WINDOW )
+ m_pMapInfoHTML = new HTML( this, "MapInfoHTML");
+#endif
+
+ 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");
+ OnClose();
+}
+
+
+//-----------------------------------------------------------------------------
+// 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 == BUTTON_CODE_INVALID ) // you need to lookup the jump key AFTER the engine has loaded
+ {
+ m_iJumpKey = gameuifuncs->GetButtonCodeForBind( "jump" );
+ }
+
+ if ( m_iScoreBoardKey == BUTTON_CODE_INVALID )
+ {
+ m_iScoreBoardKey = gameuifuncs->GetButtonCodeForBind( "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 ( !g_pFullFileSystem->FileExists( mapRES ) )
+ {
+ // try english
+ Q_snprintf( mapRES, sizeof( mapRES ), "resource/maphtml/%s_english.html", mapName );
+ }
+ else
+ {
+ bFoundHTML = true;
+ }
+
+ if( bFoundHTML || g_pFullFileSystem->FileExists( mapRES ) )
+ {
+ // it's a local HTML file
+ char localURL[ _MAX_PATH + 7 ];
+ Q_strncpy( localURL, "file://", sizeof( localURL ) );
+
+ char pPathData[ _MAX_PATH ];
+ g_pFullFileSystem->GetLocalPath( mapRES, pPathData, sizeof(pPathData) );
+ Q_strncat( localURL, pPathData, sizeof( localURL ), COPY_ALL_CHARACTERS );
+
+ // force steam to dump a local copy
+ g_pFullFileSystem->GetLocalCopy( pPathData );
+
+ m_pMapInfo->SetVisible( false );
+
+#if defined( ENABLE_HTML_WINDOW )
+ m_pMapInfoHTML->SetVisible( true );
+ m_pMapInfoHTML->OpenURL( localURL, NULL );
+#endif
+ InvalidateLayout();
+ Repaint();
+
+ return;
+ }
+ else
+ {
+ m_pMapInfo->SetVisible( true );
+
+#if defined( ENABLE_HTML_WINDOW )
+ m_pMapInfoHTML->SetVisible( false );
+#endif
+ }
+
+ Q_snprintf( mapRES, sizeof( mapRES ), "maps/%s.txt", mapName);
+
+ // if no map specific description exists, load default text
+ if( !g_pFullFileSystem->FileExists( mapRES ) )
+ {
+ if ( g_pFullFileSystem->FileExists( "maps/default.txt" ) )
+ {
+ Q_snprintf ( mapRES, sizeof( mapRES ), "maps/default.txt");
+ }
+ else
+ {
+ m_pMapInfo->SetText( "" );
+ return;
+ }
+ }
+
+ FileHandle_t f = g_pFullFileSystem->Open( mapRES, "r" );
+
+ // read into a memory block
+ int fileSize = g_pFullFileSystem->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 = g_pFullFileSystem->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<char *>( memBlock );
+ data[ bytesRead ] = 0;
+ data[ bytesRead+1 ] = 0;
+ }
+
+#ifndef WIN32
+ if ( ((ucs2 *)memBlock)[0] == 0xFEFF )
+ {
+ // convert the win32 ucs2 data to wchar_t
+ dataSize*=2;// need to *2 to account for ucs2 to wchar_t (4byte) growth
+ wchar_t *memBlockConverted = (wchar_t *)malloc(dataSize);
+ V_UCS2ToUnicode( (ucs2 *)memBlock, memBlockConverted, dataSize );
+ free(memBlock);
+ memBlock = memBlockConverted;
+ }
+#else
+ // null-terminate the stream (redundant, since we memset & then trimmed the transformed buffer already)
+ memBlock[dataSize / sizeof(wchar_t) - 1] = 0x0000;
+#endif
+ // ensure little-endian unicode reads correctly on all platforms
+ CByteswap byteSwap;
+ byteSwap.SetTargetBigEndian( false );
+ byteSwap.SwapBufferToTargetEndian( memBlock, memBlock, dataSize/sizeof(wchar_t) );
+
+ // 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<char *>( memBlock ) );
+ }
+ else
+ {
+ m_pMapInfo->SetText( memBlock+1 );
+ }
+ // go back to the top of the text buffer
+ m_pMapInfo->GotoTextStart();
+
+ g_pFullFileSystem->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<Label *>(FindChildByName(textEntryName));
+ if (entry)
+ {
+ entry->SetText(text);
+ }
+}
+
+void CTeamMenu::OnKeyCodePressed(KeyCode code)
+{
+ int nDir = 0;
+
+ switch ( code )
+ {
+ case KEY_XBUTTON_UP:
+ case KEY_XSTICK1_UP:
+ case KEY_XSTICK2_UP:
+ case KEY_UP:
+ case KEY_XBUTTON_LEFT:
+ case KEY_XSTICK1_LEFT:
+ case KEY_XSTICK2_LEFT:
+ case KEY_LEFT:
+ nDir = -1;
+ break;
+
+ case KEY_XBUTTON_DOWN:
+ case KEY_XSTICK1_DOWN:
+ case KEY_XSTICK2_DOWN:
+ case KEY_DOWN:
+ case KEY_XBUTTON_RIGHT:
+ case KEY_XSTICK1_RIGHT:
+ case KEY_XSTICK2_RIGHT:
+ case KEY_RIGHT:
+ nDir = 1;
+ break;
+ }
+
+ if ( m_iScoreBoardKey != BUTTON_CODE_INVALID && m_iScoreBoardKey == code )
+ {
+ gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, true );
+ gViewPortInterface->PostMessageToPanel( PANEL_SCOREBOARD, new KeyValues( "PollHideCode", "code", code ) );
+ }
+ else if ( nDir != 0 )
+ {
+ CUtlSortVector< SortedPanel_t, CSortedPanelYLess > vecSortedButtons;
+ VguiPanelGetSortedChildButtonList( this, (void*)&vecSortedButtons, "&", 0 );
+
+ if ( VguiPanelNavigateSortedChildButtonList( (void*)&vecSortedButtons, nDir ) != -1 )
+ {
+ // Handled!
+ return;
+ }
+ }
+ else
+ {
+ BaseClass::OnKeyCodePressed( code );
+ }
+}
diff --git a/mp/src/game/client/game_controls/teammenu.h b/mp/src/game/client/game_controls/teammenu.h
index 624d7662..a1eab0f5 100644
--- a/mp/src/game/client/game_controls/teammenu.h
+++ b/mp/src/game/client/game_controls/teammenu.h
@@ -1,86 +1,86 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef TEAMMENU_H
-#define TEAMMENU_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui_controls/Frame.h>
-#include <vgui_controls/Button.h>
-
-#include <game/client/iviewport.h>
-
-#include <vgui/KeyCode.h>
-#include <utlvector.h>
-
-namespace vgui
-{
- class RichText;
- class HTML;
-}
-class TeamFortressViewport;
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Displays the team menu
-//-----------------------------------------------------------------------------
-class CTeamMenu : public vgui::Frame, public IViewPortPanel
-{
-private:
- DECLARE_CLASS_SIMPLE( CTeamMenu, vgui::Frame );
-
-public:
- CTeamMenu(IViewPort *pViewPort);
- virtual ~CTeamMenu();
-
- virtual const char *GetName( void ) { return PANEL_TEAM; }
- virtual void SetData(KeyValues *data) {};
- virtual void Reset() {};
- virtual void Update();
- virtual bool NeedsUpdate( void ) { return false; }
- virtual bool HasInputElements( void ) { return true; }
- virtual void ShowPanel( bool bShow );
-
- // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
- vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
- virtual bool IsVisible() { return BaseClass::IsVisible(); }
- virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
-
-public:
-
- void AutoAssign();
-
-protected:
-
- // int GetNumTeams() { return m_iNumTeams; }
-
- // VGUI2 overrides
- virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
- virtual void OnKeyCodePressed(vgui::KeyCode code);
-
- // helper functions
- virtual void SetLabelText(const char *textEntryName, const char *text);
- virtual void LoadMapPage( const char *mapName );
- // virtual void MakeTeamButtons( void );
-
- // command callbacks
- // MESSAGE_FUNC_INT( OnTeamButton, "TeamButton", team );
-
- IViewPort *m_pViewPort;
- vgui::RichText *m_pMapInfo;
- vgui::HTML *m_pMapInfoHTML;
-// int m_iNumTeams;
- ButtonCode_t m_iJumpKey;
- ButtonCode_t m_iScoreBoardKey;
-
- char m_szMapName[ MAX_PATH ];
-};
-
-
-#endif // TEAMMENU_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef TEAMMENU_H
+#define TEAMMENU_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui_controls/Frame.h>
+#include <vgui_controls/Button.h>
+
+#include <game/client/iviewport.h>
+
+#include <vgui/KeyCode.h>
+#include <utlvector.h>
+
+namespace vgui
+{
+ class RichText;
+ class HTML;
+}
+class TeamFortressViewport;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Displays the team menu
+//-----------------------------------------------------------------------------
+class CTeamMenu : public vgui::Frame, public IViewPortPanel
+{
+private:
+ DECLARE_CLASS_SIMPLE( CTeamMenu, vgui::Frame );
+
+public:
+ CTeamMenu(IViewPort *pViewPort);
+ virtual ~CTeamMenu();
+
+ virtual const char *GetName( void ) { return PANEL_TEAM; }
+ virtual void SetData(KeyValues *data) {};
+ virtual void Reset() {};
+ virtual void Update();
+ virtual bool NeedsUpdate( void ) { return false; }
+ virtual bool HasInputElements( void ) { return true; }
+ virtual void ShowPanel( bool bShow );
+
+ // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
+ vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
+ virtual bool IsVisible() { return BaseClass::IsVisible(); }
+ virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
+
+public:
+
+ void AutoAssign();
+
+protected:
+
+ // int GetNumTeams() { return m_iNumTeams; }
+
+ // VGUI2 overrides
+ virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
+ virtual void OnKeyCodePressed(vgui::KeyCode code);
+
+ // helper functions
+ virtual void SetLabelText(const char *textEntryName, const char *text);
+ virtual void LoadMapPage( const char *mapName );
+ // virtual void MakeTeamButtons( void );
+
+ // command callbacks
+ // MESSAGE_FUNC_INT( OnTeamButton, "TeamButton", team );
+
+ IViewPort *m_pViewPort;
+ vgui::RichText *m_pMapInfo;
+ vgui::HTML *m_pMapInfoHTML;
+// int m_iNumTeams;
+ ButtonCode_t m_iJumpKey;
+ ButtonCode_t m_iScoreBoardKey;
+
+ char m_szMapName[ MAX_PATH ];
+};
+
+
+#endif // TEAMMENU_H
diff --git a/mp/src/game/client/game_controls/vguitextwindow.cpp b/mp/src/game/client/game_controls/vguitextwindow.cpp
index 5b967ade..450fa07c 100644
--- a/mp/src/game/client/game_controls/vguitextwindow.cpp
+++ b/mp/src/game/client/game_controls/vguitextwindow.cpp
@@ -1,430 +1,430 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "cbase.h"
-#include "vguitextwindow.h"
-#include <networkstringtabledefs.h>
-#include <cdll_client_int.h>
-
-#include <vgui/IScheme.h>
-#include <vgui/ILocalize.h>
-#include <vgui/ISurface.h>
-#include <filesystem.h>
-#include <KeyValues.h>
-#include <convar.h>
-#include <vgui_controls/ImageList.h>
-
-#include <vgui_controls/TextEntry.h>
-#include <vgui_controls/Button.h>
-
-#include <game/client/iviewport.h>
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-using namespace vgui;
-extern INetworkStringTable *g_pStringTableInfoPanel;
-
-#define TEMP_HTML_FILE "textwindow_temp.html"
-
-ConVar cl_disablehtmlmotd( "cl_disablehtmlmotd", "0", FCVAR_ARCHIVE, "Disable HTML motds." );
-
-//=============================================================================
-// HPE_BEGIN:
-// [Forrest] Replaced text window command string with TEXTWINDOW_CMD enumeration
-// of options. Passing a command string is dangerous and allowed a server network
-// message to run arbitrary commands on the client.
-//=============================================================================
-CON_COMMAND( showinfo, "Shows a info panel: <type> <title> <message> [<command number>]" )
-{
- if ( !gViewPortInterface )
- return;
-
- if ( args.ArgC() < 4 )
- return;
-
- IViewPortPanel * panel = gViewPortInterface->FindPanelByName( PANEL_INFO );
-
- if ( panel )
- {
- KeyValues *kv = new KeyValues("data");
- kv->SetInt( "type", Q_atoi(args[ 1 ]) );
- kv->SetString( "title", args[ 2 ] );
- kv->SetString( "message", args[ 3 ] );
-
- if ( args.ArgC() == 5 )
- kv->SetString( "command", args[ 4 ] );
-
- panel->SetData( kv );
-
- gViewPortInterface->ShowPanel( panel, true );
-
- kv->deleteThis();
- }
- else
- {
- Msg("Couldn't find info panel.\n" );
- }
-}
-//=============================================================================
-// HPE_END
-//=============================================================================
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CTextWindow::CTextWindow(IViewPort *pViewPort) : Frame(NULL, PANEL_INFO )
-{
- // initialize dialog
- m_pViewPort = pViewPort;
-
-// SetTitle("", true);
-
- m_szTitle[0] = '\0';
- m_szMessage[0] = '\0';
- m_szMessageFallback[0] = '\0';
- m_nExitCommand = TEXTWINDOW_CMD_NONE;
- m_bShownURL = false;
- m_bUnloadOnDismissal = false;
-
- // load the new scheme early!!
- SetScheme("ClientScheme");
- SetMoveable(false);
- SetSizeable(false);
- SetProportional(true);
-
- // hide the system buttons
- SetTitleBarVisible( false );
-
- m_pTextMessage = new TextEntry( this, "TextMessage" );
-#if defined( ENABLE_CHROMEHTMLWINDOW )
- m_pHTMLMessage = new CMOTDHTML( this,"HTMLMessage" );
-#else
- m_pHTMLMessage = NULL;
-#endif
- m_pTitleLabel = new Label( this, "MessageTitle", "Message Title" );
- m_pOK = new Button(this, "ok", "#PropertyDialog_OK");
-
- m_pOK->SetCommand("okay");
- m_pTextMessage->SetMultiline( true );
- m_nContentType = TYPE_TEXT;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CTextWindow::ApplySchemeSettings( IScheme *pScheme )
-{
- BaseClass::ApplySchemeSettings( pScheme );
-
- LoadControlSettings("Resource/UI/TextWindow.res");
-
- Reset();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Destructor
-//-----------------------------------------------------------------------------
-CTextWindow::~CTextWindow()
-{
- // remove temp file again
- g_pFullFileSystem->RemoveFile( TEMP_HTML_FILE, "DEFAULT_WRITE_PATH" );
-}
-
-void CTextWindow::Reset( void )
-{
- //=============================================================================
- // HPE_BEGIN:
- // [Forrest] Replace strange hard-coded default message with hard-coded error message.
- //=============================================================================
- Q_strcpy( m_szTitle, "Error loading info message." );
- Q_strcpy( m_szMessage, "" );
- Q_strcpy( m_szMessageFallback, "" );
- //=============================================================================
- // HPE_END
- //=============================================================================
-
- m_nExitCommand = TEXTWINDOW_CMD_NONE;
- m_nContentType = TYPE_TEXT;
- m_bShownURL = false;
- m_bUnloadOnDismissal = false;
- Update();
-}
-
-void CTextWindow::ShowText( const char *text )
-{
- m_pTextMessage->SetVisible( true );
- m_pTextMessage->SetText( text );
- m_pTextMessage->GotoTextStart();
-}
-
-void CTextWindow::ShowURL( const char *URL, bool bAllowUserToDisable )
-{
-#if defined( ENABLE_CHROMEHTMLWINDOW )
- if ( bAllowUserToDisable && cl_disablehtmlmotd.GetBool() )
- {
- // User has disabled HTML TextWindows. Show the fallback as text only.
- if ( g_pStringTableInfoPanel )
- {
- int index = g_pStringTableInfoPanel->FindStringIndex( "motd_text" );
- if ( index != ::INVALID_STRING_INDEX )
- {
- int length = 0;
- const char *data = (const char *)g_pStringTableInfoPanel->GetStringUserData( index, &length );
- if ( data && data[0] )
- {
- m_pHTMLMessage->SetVisible( false );
- ShowText( data );
- }
- }
- }
- return;
- }
-
- m_pHTMLMessage->SetVisible( true );
- m_pHTMLMessage->OpenURL( URL, NULL );
- m_bShownURL = true;
-
-#endif
-}
-
-void CTextWindow::ShowIndex( const char *entry )
-{
- const char *data = NULL;
- int length = 0;
-
- if ( NULL == g_pStringTableInfoPanel )
- return;
-
- int index = g_pStringTableInfoPanel->FindStringIndex( m_szMessage );
-
- if ( index != ::INVALID_STRING_INDEX )
- data = (const char *)g_pStringTableInfoPanel->GetStringUserData( index, &length );
-
- if ( !data || !data[0] )
- return; // nothing to show
-
- // is this a web URL ?
- if ( !Q_strncmp( data, "http://", 7 ) || !Q_strncmp( data, "https://", 8 ) )
- {
- ShowURL( data );
- return;
- }
-
- // try to figure out if this is HTML or not
- if ( data[0] != '<' )
- {
- ShowText( data );
- return;
- }
-
- // data is a HTML, we have to write to a file and then load the file
- FileHandle_t hFile = g_pFullFileSystem->Open( TEMP_HTML_FILE, "wb", "DEFAULT_WRITE_PATH" );
-
- if ( hFile == FILESYSTEM_INVALID_HANDLE )
- return;
-
- g_pFullFileSystem->Write( data, length, hFile );
- g_pFullFileSystem->Close( hFile );
-
- if ( g_pFullFileSystem->Size( TEMP_HTML_FILE ) != (unsigned int)length )
- return; // something went wrong while writing
-
- ShowFile( TEMP_HTML_FILE );
-}
-
-void CTextWindow::ShowFile( const char *filename )
-{
- if ( Q_stristr( filename, ".htm" ) || Q_stristr( filename, ".html" ) )
- {
- // it's a local HTML file
- char localURL[ _MAX_PATH + 7 ];
- Q_strncpy( localURL, "file://", sizeof( localURL ) );
-
- char pPathData[ _MAX_PATH ];
- g_pFullFileSystem->GetLocalPath( filename, pPathData, sizeof(pPathData) );
- Q_strncat( localURL, pPathData, sizeof( localURL ), COPY_ALL_CHARACTERS );
-
- ShowURL( localURL );
- }
- else
- {
- // read from local text from file
- FileHandle_t f = g_pFullFileSystem->Open( m_szMessage, "rb", "GAME" );
-
- if ( !f )
- return;
-
- char buffer[2048];
-
- int size = MIN( g_pFullFileSystem->Size( f ), sizeof(buffer)-1 ); // just allow 2KB
-
- g_pFullFileSystem->Read( buffer, size, f );
- g_pFullFileSystem->Close( f );
-
- buffer[size]=0; //terminate string
-
- ShowText( buffer );
- }
-}
-
-void CTextWindow::Update( void )
-{
- SetTitle( m_szTitle, false );
-
- m_pTitleLabel->SetText( m_szTitle );
-
-#if defined( ENABLE_CHROMEHTMLWINDOW )
- m_pHTMLMessage->SetVisible( false );
-#endif
- m_pTextMessage->SetVisible( false );
-
- if ( m_nContentType == TYPE_INDEX )
- {
- ShowIndex( m_szMessage );
- }
- else if ( m_nContentType == TYPE_URL )
- {
- ShowURL( m_szMessage );
- }
- else if ( m_nContentType == TYPE_FILE )
- {
- ShowFile( m_szMessage );
- }
- else if ( m_nContentType == TYPE_TEXT )
- {
- ShowText( m_szMessage );
- }
- else
- {
- DevMsg("CTextWindow::Update: unknown content type %i\n", m_nContentType );
- }
-}
-
-void CTextWindow::OnCommand( const char *command )
-{
- if (!Q_strcmp(command, "okay"))
- {
- //=============================================================================
- // HPE_BEGIN:
- // [Forrest] Replaced text window command string with TEXTWINDOW_CMD enumeration
- // of options. Passing a command string is dangerous and allowed a server network
- // message to run arbitrary commands on the client.
- //=============================================================================
- const char *pszCommand = NULL;
- switch ( m_nExitCommand )
- {
- case TEXTWINDOW_CMD_NONE:
- break;
-
- case TEXTWINDOW_CMD_JOINGAME:
- pszCommand = "joingame";
- break;
-
- case TEXTWINDOW_CMD_CHANGETEAM:
- pszCommand = "changeteam";
- break;
-
- case TEXTWINDOW_CMD_IMPULSE101:
- pszCommand = "impulse 101";
- break;
-
- case TEXTWINDOW_CMD_MAPINFO:
- pszCommand = "mapinfo";
- break;
-
- case TEXTWINDOW_CMD_CLOSED_HTMLPAGE:
- pszCommand = "closed_htmlpage";
- break;
-
- case TEXTWINDOW_CMD_CHOOSETEAM:
- pszCommand = "chooseteam";
- break;
-
- default:
- DevMsg("CTextWindow::OnCommand: unknown exit command value %i\n", m_nExitCommand );
- break;
- }
-
- if ( pszCommand != NULL )
- {
- engine->ClientCmd_Unrestricted( pszCommand );
- }
- //=============================================================================
- // HPE_END
- //=============================================================================
-
- m_pViewPort->ShowPanel( this, false );
- }
-
- BaseClass::OnCommand(command);
-}
-
-void CTextWindow::OnKeyCodePressed( vgui::KeyCode code )
-{
- if ( code == KEY_XBUTTON_A || code == KEY_XBUTTON_B )
- {
- OnCommand( "okay" );
- return;
- }
-
- BaseClass::OnKeyCodePressed(code);
-}
-
-void CTextWindow::SetData(KeyValues *data)
-{
- SetData( data->GetInt( "type" ), data->GetString( "title" ), data->GetString( "msg" ), data->GetString( "msg_fallback" ), data->GetInt( "cmd" ), data->GetBool( "unload" ) );
-}
-
-void CTextWindow::SetData( int type, const char *title, const char *message, const char *message_fallback, int command, bool bUnload )
-{
- Q_strncpy( m_szTitle, title, sizeof( m_szTitle ) );
- Q_strncpy( m_szMessage, message, sizeof( m_szMessage ) );
- Q_strncpy( m_szMessageFallback, message_fallback, sizeof( m_szMessageFallback ) );
-
- m_nExitCommand = command;
-
- m_nContentType = type;
- m_bUnloadOnDismissal = bUnload;
-
- Update();
-}
-
-void CTextWindow::ShowPanel( bool bShow )
-{
- if ( BaseClass::IsVisible() == bShow )
- return;
-
- m_pViewPort->ShowBackGround( bShow );
-
- if ( bShow )
- {
- Activate();
- SetMouseInputEnabled( true );
- }
- else
- {
- SetVisible( false );
- SetMouseInputEnabled( false );
-
-#if defined( ENABLE_CHROMEHTMLWINDOW )
- if ( m_bUnloadOnDismissal && m_bShownURL )
- {
- m_pHTMLMessage->OpenURL( "about:blank", NULL );
- m_bShownURL = false;
- }
-#endif
- }
-}
-
-bool CTextWindow::CMOTDHTML::OnStartRequest( const char *url, const char *target, const char *pchPostData, bool bIsRedirect )
-{
- if ( Q_strstr( url, "steam://" ) )
- return false;
-
- return BaseClass::OnStartRequest( url, target, pchPostData, bIsRedirect );
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "vguitextwindow.h"
+#include <networkstringtabledefs.h>
+#include <cdll_client_int.h>
+
+#include <vgui/IScheme.h>
+#include <vgui/ILocalize.h>
+#include <vgui/ISurface.h>
+#include <filesystem.h>
+#include <KeyValues.h>
+#include <convar.h>
+#include <vgui_controls/ImageList.h>
+
+#include <vgui_controls/TextEntry.h>
+#include <vgui_controls/Button.h>
+
+#include <game/client/iviewport.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+extern INetworkStringTable *g_pStringTableInfoPanel;
+
+#define TEMP_HTML_FILE "textwindow_temp.html"
+
+ConVar cl_disablehtmlmotd( "cl_disablehtmlmotd", "0", FCVAR_ARCHIVE, "Disable HTML motds." );
+
+//=============================================================================
+// HPE_BEGIN:
+// [Forrest] Replaced text window command string with TEXTWINDOW_CMD enumeration
+// of options. Passing a command string is dangerous and allowed a server network
+// message to run arbitrary commands on the client.
+//=============================================================================
+CON_COMMAND( showinfo, "Shows a info panel: <type> <title> <message> [<command number>]" )
+{
+ if ( !gViewPortInterface )
+ return;
+
+ if ( args.ArgC() < 4 )
+ return;
+
+ IViewPortPanel * panel = gViewPortInterface->FindPanelByName( PANEL_INFO );
+
+ if ( panel )
+ {
+ KeyValues *kv = new KeyValues("data");
+ kv->SetInt( "type", Q_atoi(args[ 1 ]) );
+ kv->SetString( "title", args[ 2 ] );
+ kv->SetString( "message", args[ 3 ] );
+
+ if ( args.ArgC() == 5 )
+ kv->SetString( "command", args[ 4 ] );
+
+ panel->SetData( kv );
+
+ gViewPortInterface->ShowPanel( panel, true );
+
+ kv->deleteThis();
+ }
+ else
+ {
+ Msg("Couldn't find info panel.\n" );
+ }
+}
+//=============================================================================
+// HPE_END
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CTextWindow::CTextWindow(IViewPort *pViewPort) : Frame(NULL, PANEL_INFO )
+{
+ // initialize dialog
+ m_pViewPort = pViewPort;
+
+// SetTitle("", true);
+
+ m_szTitle[0] = '\0';
+ m_szMessage[0] = '\0';
+ m_szMessageFallback[0] = '\0';
+ m_nExitCommand = TEXTWINDOW_CMD_NONE;
+ m_bShownURL = false;
+ m_bUnloadOnDismissal = false;
+
+ // load the new scheme early!!
+ SetScheme("ClientScheme");
+ SetMoveable(false);
+ SetSizeable(false);
+ SetProportional(true);
+
+ // hide the system buttons
+ SetTitleBarVisible( false );
+
+ m_pTextMessage = new TextEntry( this, "TextMessage" );
+#if defined( ENABLE_CHROMEHTMLWINDOW )
+ m_pHTMLMessage = new CMOTDHTML( this,"HTMLMessage" );
+#else
+ m_pHTMLMessage = NULL;
+#endif
+ m_pTitleLabel = new Label( this, "MessageTitle", "Message Title" );
+ m_pOK = new Button(this, "ok", "#PropertyDialog_OK");
+
+ m_pOK->SetCommand("okay");
+ m_pTextMessage->SetMultiline( true );
+ m_nContentType = TYPE_TEXT;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTextWindow::ApplySchemeSettings( IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ LoadControlSettings("Resource/UI/TextWindow.res");
+
+ Reset();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor
+//-----------------------------------------------------------------------------
+CTextWindow::~CTextWindow()
+{
+ // remove temp file again
+ g_pFullFileSystem->RemoveFile( TEMP_HTML_FILE, "DEFAULT_WRITE_PATH" );
+}
+
+void CTextWindow::Reset( void )
+{
+ //=============================================================================
+ // HPE_BEGIN:
+ // [Forrest] Replace strange hard-coded default message with hard-coded error message.
+ //=============================================================================
+ Q_strcpy( m_szTitle, "Error loading info message." );
+ Q_strcpy( m_szMessage, "" );
+ Q_strcpy( m_szMessageFallback, "" );
+ //=============================================================================
+ // HPE_END
+ //=============================================================================
+
+ m_nExitCommand = TEXTWINDOW_CMD_NONE;
+ m_nContentType = TYPE_TEXT;
+ m_bShownURL = false;
+ m_bUnloadOnDismissal = false;
+ Update();
+}
+
+void CTextWindow::ShowText( const char *text )
+{
+ m_pTextMessage->SetVisible( true );
+ m_pTextMessage->SetText( text );
+ m_pTextMessage->GotoTextStart();
+}
+
+void CTextWindow::ShowURL( const char *URL, bool bAllowUserToDisable )
+{
+#if defined( ENABLE_CHROMEHTMLWINDOW )
+ if ( bAllowUserToDisable && cl_disablehtmlmotd.GetBool() )
+ {
+ // User has disabled HTML TextWindows. Show the fallback as text only.
+ if ( g_pStringTableInfoPanel )
+ {
+ int index = g_pStringTableInfoPanel->FindStringIndex( "motd_text" );
+ if ( index != ::INVALID_STRING_INDEX )
+ {
+ int length = 0;
+ const char *data = (const char *)g_pStringTableInfoPanel->GetStringUserData( index, &length );
+ if ( data && data[0] )
+ {
+ m_pHTMLMessage->SetVisible( false );
+ ShowText( data );
+ }
+ }
+ }
+ return;
+ }
+
+ m_pHTMLMessage->SetVisible( true );
+ m_pHTMLMessage->OpenURL( URL, NULL );
+ m_bShownURL = true;
+
+#endif
+}
+
+void CTextWindow::ShowIndex( const char *entry )
+{
+ const char *data = NULL;
+ int length = 0;
+
+ if ( NULL == g_pStringTableInfoPanel )
+ return;
+
+ int index = g_pStringTableInfoPanel->FindStringIndex( m_szMessage );
+
+ if ( index != ::INVALID_STRING_INDEX )
+ data = (const char *)g_pStringTableInfoPanel->GetStringUserData( index, &length );
+
+ if ( !data || !data[0] )
+ return; // nothing to show
+
+ // is this a web URL ?
+ if ( !Q_strncmp( data, "http://", 7 ) || !Q_strncmp( data, "https://", 8 ) )
+ {
+ ShowURL( data );
+ return;
+ }
+
+ // try to figure out if this is HTML or not
+ if ( data[0] != '<' )
+ {
+ ShowText( data );
+ return;
+ }
+
+ // data is a HTML, we have to write to a file and then load the file
+ FileHandle_t hFile = g_pFullFileSystem->Open( TEMP_HTML_FILE, "wb", "DEFAULT_WRITE_PATH" );
+
+ if ( hFile == FILESYSTEM_INVALID_HANDLE )
+ return;
+
+ g_pFullFileSystem->Write( data, length, hFile );
+ g_pFullFileSystem->Close( hFile );
+
+ if ( g_pFullFileSystem->Size( TEMP_HTML_FILE ) != (unsigned int)length )
+ return; // something went wrong while writing
+
+ ShowFile( TEMP_HTML_FILE );
+}
+
+void CTextWindow::ShowFile( const char *filename )
+{
+ if ( Q_stristr( filename, ".htm" ) || Q_stristr( filename, ".html" ) )
+ {
+ // it's a local HTML file
+ char localURL[ _MAX_PATH + 7 ];
+ Q_strncpy( localURL, "file://", sizeof( localURL ) );
+
+ char pPathData[ _MAX_PATH ];
+ g_pFullFileSystem->GetLocalPath( filename, pPathData, sizeof(pPathData) );
+ Q_strncat( localURL, pPathData, sizeof( localURL ), COPY_ALL_CHARACTERS );
+
+ ShowURL( localURL );
+ }
+ else
+ {
+ // read from local text from file
+ FileHandle_t f = g_pFullFileSystem->Open( m_szMessage, "rb", "GAME" );
+
+ if ( !f )
+ return;
+
+ char buffer[2048];
+
+ int size = MIN( g_pFullFileSystem->Size( f ), sizeof(buffer)-1 ); // just allow 2KB
+
+ g_pFullFileSystem->Read( buffer, size, f );
+ g_pFullFileSystem->Close( f );
+
+ buffer[size]=0; //terminate string
+
+ ShowText( buffer );
+ }
+}
+
+void CTextWindow::Update( void )
+{
+ SetTitle( m_szTitle, false );
+
+ m_pTitleLabel->SetText( m_szTitle );
+
+#if defined( ENABLE_CHROMEHTMLWINDOW )
+ m_pHTMLMessage->SetVisible( false );
+#endif
+ m_pTextMessage->SetVisible( false );
+
+ if ( m_nContentType == TYPE_INDEX )
+ {
+ ShowIndex( m_szMessage );
+ }
+ else if ( m_nContentType == TYPE_URL )
+ {
+ ShowURL( m_szMessage );
+ }
+ else if ( m_nContentType == TYPE_FILE )
+ {
+ ShowFile( m_szMessage );
+ }
+ else if ( m_nContentType == TYPE_TEXT )
+ {
+ ShowText( m_szMessage );
+ }
+ else
+ {
+ DevMsg("CTextWindow::Update: unknown content type %i\n", m_nContentType );
+ }
+}
+
+void CTextWindow::OnCommand( const char *command )
+{
+ if (!Q_strcmp(command, "okay"))
+ {
+ //=============================================================================
+ // HPE_BEGIN:
+ // [Forrest] Replaced text window command string with TEXTWINDOW_CMD enumeration
+ // of options. Passing a command string is dangerous and allowed a server network
+ // message to run arbitrary commands on the client.
+ //=============================================================================
+ const char *pszCommand = NULL;
+ switch ( m_nExitCommand )
+ {
+ case TEXTWINDOW_CMD_NONE:
+ break;
+
+ case TEXTWINDOW_CMD_JOINGAME:
+ pszCommand = "joingame";
+ break;
+
+ case TEXTWINDOW_CMD_CHANGETEAM:
+ pszCommand = "changeteam";
+ break;
+
+ case TEXTWINDOW_CMD_IMPULSE101:
+ pszCommand = "impulse 101";
+ break;
+
+ case TEXTWINDOW_CMD_MAPINFO:
+ pszCommand = "mapinfo";
+ break;
+
+ case TEXTWINDOW_CMD_CLOSED_HTMLPAGE:
+ pszCommand = "closed_htmlpage";
+ break;
+
+ case TEXTWINDOW_CMD_CHOOSETEAM:
+ pszCommand = "chooseteam";
+ break;
+
+ default:
+ DevMsg("CTextWindow::OnCommand: unknown exit command value %i\n", m_nExitCommand );
+ break;
+ }
+
+ if ( pszCommand != NULL )
+ {
+ engine->ClientCmd_Unrestricted( pszCommand );
+ }
+ //=============================================================================
+ // HPE_END
+ //=============================================================================
+
+ m_pViewPort->ShowPanel( this, false );
+ }
+
+ BaseClass::OnCommand(command);
+}
+
+void CTextWindow::OnKeyCodePressed( vgui::KeyCode code )
+{
+ if ( code == KEY_XBUTTON_A || code == KEY_XBUTTON_B )
+ {
+ OnCommand( "okay" );
+ return;
+ }
+
+ BaseClass::OnKeyCodePressed(code);
+}
+
+void CTextWindow::SetData(KeyValues *data)
+{
+ SetData( data->GetInt( "type" ), data->GetString( "title" ), data->GetString( "msg" ), data->GetString( "msg_fallback" ), data->GetInt( "cmd" ), data->GetBool( "unload" ) );
+}
+
+void CTextWindow::SetData( int type, const char *title, const char *message, const char *message_fallback, int command, bool bUnload )
+{
+ Q_strncpy( m_szTitle, title, sizeof( m_szTitle ) );
+ Q_strncpy( m_szMessage, message, sizeof( m_szMessage ) );
+ Q_strncpy( m_szMessageFallback, message_fallback, sizeof( m_szMessageFallback ) );
+
+ m_nExitCommand = command;
+
+ m_nContentType = type;
+ m_bUnloadOnDismissal = bUnload;
+
+ Update();
+}
+
+void CTextWindow::ShowPanel( bool bShow )
+{
+ if ( BaseClass::IsVisible() == bShow )
+ return;
+
+ m_pViewPort->ShowBackGround( bShow );
+
+ if ( bShow )
+ {
+ Activate();
+ SetMouseInputEnabled( true );
+ }
+ else
+ {
+ SetVisible( false );
+ SetMouseInputEnabled( false );
+
+#if defined( ENABLE_CHROMEHTMLWINDOW )
+ if ( m_bUnloadOnDismissal && m_bShownURL )
+ {
+ m_pHTMLMessage->OpenURL( "about:blank", NULL );
+ m_bShownURL = false;
+ }
+#endif
+ }
+}
+
+bool CTextWindow::CMOTDHTML::OnStartRequest( const char *url, const char *target, const char *pchPostData, bool bIsRedirect )
+{
+ if ( Q_strstr( url, "steam://" ) )
+ return false;
+
+ return BaseClass::OnStartRequest( url, target, pchPostData, bIsRedirect );
+}
diff --git a/mp/src/game/client/game_controls/vguitextwindow.h b/mp/src/game/client/game_controls/vguitextwindow.h
index 213b241e..4557c7bf 100644
--- a/mp/src/game/client/game_controls/vguitextwindow.h
+++ b/mp/src/game/client/game_controls/vguitextwindow.h
@@ -1,104 +1,104 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef VGUITEXTWINDOW_H
-#define VGUITEXTWINDOW_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <vgui_controls/Frame.h>
-#include <vgui_controls/Button.h>
-#include <vgui_controls/HTML.h>
-
-#include <game/client/iviewport.h>
-#include "shareddefs.h"
-
-namespace vgui
-{
- class TextEntry;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: displays the MOTD
-//-----------------------------------------------------------------------------
-
-class CTextWindow : public vgui::Frame, public IViewPortPanel
-{
-private:
- DECLARE_CLASS_SIMPLE( CTextWindow, vgui::Frame );
-
-public:
- CTextWindow(IViewPort *pViewPort);
- virtual ~CTextWindow();
-
- virtual const char *GetName( void ) { return PANEL_INFO; }
- virtual void SetData(KeyValues *data);
- virtual void Reset();
- virtual void Update();
- virtual bool NeedsUpdate( void ) { return false; }
- virtual bool HasInputElements( void ) { return true; }
- virtual void ShowPanel( bool bShow );
-
- // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
- vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
- virtual bool IsVisible() { return BaseClass::IsVisible(); }
- virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
-
-public:
-
- virtual void SetData( int type, const char *title, const char *message, const char *message_fallback, int command, bool bUnload );
- virtual void ShowFile( const char *filename );
- virtual void ShowText( const char *text );
- virtual void ShowURL( const char *URL, bool bAllowUserToDisable = true );
- virtual void ShowIndex( const char *entry );
-
- virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
-
-protected:
- // vgui overrides
- virtual void OnCommand( const char *command );
-
- void OnKeyCodePressed( vgui::KeyCode code );
-
- IViewPort *m_pViewPort;
- char m_szTitle[255];
- char m_szMessage[2048];
- char m_szMessageFallback[2048];
- //=============================================================================
- // HPE_BEGIN:
- // [Forrest] Replaced text window command string with TEXTWINDOW_CMD enumeration
- // of options. Passing a command string is dangerous and allowed a server network
- // message to run arbitrary commands on the client.
- //=============================================================================
- int m_nExitCommand;
- //=============================================================================
- // HPE_END
- //=============================================================================
- int m_nContentType;
- bool m_bShownURL;
- bool m_bUnloadOnDismissal;
-
- vgui::TextEntry *m_pTextMessage;
-
- class CMOTDHTML : public vgui::HTML
- {
- private:
- DECLARE_CLASS_SIMPLE( CMOTDHTML, vgui::HTML );
-
- public:
- CMOTDHTML( Panel *parent, const char *pchName ) : vgui::HTML( parent, pchName ) {}
- virtual bool OnStartRequest( const char *url, const char *target, const char *pchPostData, bool bIsRedirect ) OVERRIDE;
- };
- CMOTDHTML *m_pHTMLMessage;
-
- vgui::Button *m_pOK;
- vgui::Label *m_pTitleLabel;
-};
-
-
-#endif // VGUITEXTWINDOW_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef VGUITEXTWINDOW_H
+#define VGUITEXTWINDOW_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <vgui_controls/Frame.h>
+#include <vgui_controls/Button.h>
+#include <vgui_controls/HTML.h>
+
+#include <game/client/iviewport.h>
+#include "shareddefs.h"
+
+namespace vgui
+{
+ class TextEntry;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: displays the MOTD
+//-----------------------------------------------------------------------------
+
+class CTextWindow : public vgui::Frame, public IViewPortPanel
+{
+private:
+ DECLARE_CLASS_SIMPLE( CTextWindow, vgui::Frame );
+
+public:
+ CTextWindow(IViewPort *pViewPort);
+ virtual ~CTextWindow();
+
+ virtual const char *GetName( void ) { return PANEL_INFO; }
+ virtual void SetData(KeyValues *data);
+ virtual void Reset();
+ virtual void Update();
+ virtual bool NeedsUpdate( void ) { return false; }
+ virtual bool HasInputElements( void ) { return true; }
+ virtual void ShowPanel( bool bShow );
+
+ // both vgui::Frame and IViewPortPanel define these, so explicitly define them here as passthroughs to vgui
+ vgui::VPANEL GetVPanel( void ) { return BaseClass::GetVPanel(); }
+ virtual bool IsVisible() { return BaseClass::IsVisible(); }
+ virtual void SetParent( vgui::VPANEL parent ) { BaseClass::SetParent( parent ); }
+
+public:
+
+ virtual void SetData( int type, const char *title, const char *message, const char *message_fallback, int command, bool bUnload );
+ virtual void ShowFile( const char *filename );
+ virtual void ShowText( const char *text );
+ virtual void ShowURL( const char *URL, bool bAllowUserToDisable = true );
+ virtual void ShowIndex( const char *entry );
+
+ virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
+
+protected:
+ // vgui overrides
+ virtual void OnCommand( const char *command );
+
+ void OnKeyCodePressed( vgui::KeyCode code );
+
+ IViewPort *m_pViewPort;
+ char m_szTitle[255];
+ char m_szMessage[2048];
+ char m_szMessageFallback[2048];
+ //=============================================================================
+ // HPE_BEGIN:
+ // [Forrest] Replaced text window command string with TEXTWINDOW_CMD enumeration
+ // of options. Passing a command string is dangerous and allowed a server network
+ // message to run arbitrary commands on the client.
+ //=============================================================================
+ int m_nExitCommand;
+ //=============================================================================
+ // HPE_END
+ //=============================================================================
+ int m_nContentType;
+ bool m_bShownURL;
+ bool m_bUnloadOnDismissal;
+
+ vgui::TextEntry *m_pTextMessage;
+
+ class CMOTDHTML : public vgui::HTML
+ {
+ private:
+ DECLARE_CLASS_SIMPLE( CMOTDHTML, vgui::HTML );
+
+ public:
+ CMOTDHTML( Panel *parent, const char *pchName ) : vgui::HTML( parent, pchName ) {}
+ virtual bool OnStartRequest( const char *url, const char *target, const char *pchPostData, bool bIsRedirect ) OVERRIDE;
+ };
+ CMOTDHTML *m_pHTMLMessage;
+
+ vgui::Button *m_pOK;
+ vgui::Label *m_pTitleLabel;
+};
+
+
+#endif // VGUITEXTWINDOW_H