diff options
| author | Narendra Umate <[email protected]> | 2013-12-02 23:36:05 -0800 |
|---|---|---|
| committer | Narendra Umate <[email protected]> | 2013-12-02 23:36:05 -0800 |
| commit | 8737f191f3b59f001a77bf6c08091109211c1c9f (patch) | |
| tree | dbbf05c004d9b026f2c1f23f06600fe0add82c36 /mp/src/game/client/game_controls | |
| parent | Update .gitignore. (diff) | |
| parent | Make .xcconfigs text files too. (diff) | |
| download | source-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')
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 |