mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-27 00:26:50 +00:00
398 lines
9.8 KiB
C++
398 lines
9.8 KiB
C++
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================
|
||
|
|
||
|
#include "cbase.h"
|
||
|
#include "hud.h"
|
||
|
#include "hudelement.h"
|
||
|
#include "hud_macros.h"
|
||
|
#include "iclientmode.h"
|
||
|
#include "vgui_controls/AnimationController.h"
|
||
|
#include "vgui_controls/Label.h"
|
||
|
#include "vgui/ILocalize.h"
|
||
|
#include "vgui/ISurface.h"
|
||
|
#include "text_message.h"
|
||
|
#include "dod_hud_freezepanel.h"
|
||
|
|
||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||
|
#include "tier0/memdbgon.h"
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Displays current ammunition level
|
||
|
//-----------------------------------------------------------------------------
|
||
|
class CDODHudHintDisplay : public vgui::Panel, public CHudElement
|
||
|
{
|
||
|
DECLARE_CLASS_SIMPLE( CDODHudHintDisplay, vgui::Panel );
|
||
|
|
||
|
public:
|
||
|
CDODHudHintDisplay( const char *pElementName );
|
||
|
|
||
|
void Init();
|
||
|
void Reset();
|
||
|
void MsgFunc_HintText( bf_read &msg );
|
||
|
void FireGameEvent( IGameEvent * event);
|
||
|
|
||
|
bool SetHintText( wchar_t *text );
|
||
|
|
||
|
virtual void PerformLayout();
|
||
|
|
||
|
virtual bool IsVisible( void );
|
||
|
|
||
|
protected:
|
||
|
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
|
||
|
virtual void OnThink();
|
||
|
|
||
|
private:
|
||
|
vgui::HFont m_hFont;
|
||
|
Color m_bgColor;
|
||
|
vgui::Label *m_pLabel;
|
||
|
CUtlVector<vgui::Label *> m_Labels;
|
||
|
CPanelAnimationVarAliasType( int, m_iTextX, "text_xpos", "8", "proportional_int" );
|
||
|
CPanelAnimationVarAliasType( int, m_iTextY, "text_ypos", "8", "proportional_int" );
|
||
|
CPanelAnimationVarAliasType( int, m_iCenterX, "center_x", "0", "proportional_int" );
|
||
|
CPanelAnimationVarAliasType( int, m_iCenterY, "center_y", "0", "proportional_int" );
|
||
|
};
|
||
|
|
||
|
DECLARE_HUDELEMENT( CDODHudHintDisplay );
|
||
|
DECLARE_HUD_MESSAGE( CDODHudHintDisplay, HintText );
|
||
|
|
||
|
#define MAX_HINT_STRINGS 5
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Constructor
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CDODHudHintDisplay::CDODHudHintDisplay( const char *pElementName ) : BaseClass(NULL, "HudHintDisplay"), CHudElement( pElementName )
|
||
|
{
|
||
|
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||
|
SetParent( pParent );
|
||
|
SetVisible( false );
|
||
|
SetAlpha( 0 );
|
||
|
m_pLabel = new vgui::Label( this, "HudHintDisplayLabel", "" );
|
||
|
|
||
|
RegisterForRenderGroup( "winpanel" );
|
||
|
RegisterForRenderGroup( "freezepanel" );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CDODHudHintDisplay::Init()
|
||
|
{
|
||
|
HOOK_HUD_MESSAGE( CDODHudHintDisplay, HintText );
|
||
|
|
||
|
// listen for client side events
|
||
|
ListenForGameEvent( "player_hintmessage" );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CDODHudHintDisplay::Reset()
|
||
|
{
|
||
|
SetHintText( NULL );
|
||
|
SetAlpha( 0 );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CDODHudHintDisplay::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||
|
{
|
||
|
BaseClass::ApplySchemeSettings( pScheme );
|
||
|
|
||
|
SetFgColor( GetSchemeColor("HintMessageFg", pScheme) );
|
||
|
m_hFont = pScheme->GetFont( "HudHintText", true );
|
||
|
m_pLabel->SetBgColor( GetSchemeColor("HintMessageBg", pScheme) );
|
||
|
m_pLabel->SetPaintBackgroundType( 2 );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Sets the hint text, replacing variables as necessary
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CDODHudHintDisplay::SetHintText( wchar_t *text )
|
||
|
{
|
||
|
// clear the existing text
|
||
|
for (int i = 0; i < m_Labels.Count(); i++)
|
||
|
{
|
||
|
m_Labels[i]->MarkForDeletion();
|
||
|
}
|
||
|
m_Labels.RemoveAll();
|
||
|
|
||
|
wchar_t *p = text;
|
||
|
|
||
|
while ( p )
|
||
|
{
|
||
|
wchar_t *line = p;
|
||
|
wchar_t *end = wcschr( p, L'\n' );
|
||
|
if ( end )
|
||
|
{
|
||
|
//*end = 0; //eek
|
||
|
p = end+1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
p = NULL;
|
||
|
}
|
||
|
|
||
|
// copy to a new buf if there are vars
|
||
|
wchar_t buf[512];
|
||
|
buf[0] = '\0';
|
||
|
int pos = 0;
|
||
|
|
||
|
wchar_t *ws = line;
|
||
|
while( ws != end && *ws != 0 )
|
||
|
{
|
||
|
// check for variables
|
||
|
if ( *ws == '%' )
|
||
|
{
|
||
|
++ws;
|
||
|
|
||
|
wchar_t *end = wcschr( ws, '%' );
|
||
|
if ( end )
|
||
|
{
|
||
|
wchar_t token[64];
|
||
|
wcsncpy( token, ws, end - ws );
|
||
|
token[end - ws] = 0;
|
||
|
|
||
|
ws += end - ws;
|
||
|
|
||
|
// lookup key names
|
||
|
char binding[64];
|
||
|
g_pVGuiLocalize->ConvertUnicodeToANSI( token, binding, sizeof(binding) );
|
||
|
|
||
|
const char *key = engine->Key_LookupBinding( *binding == '+' ? binding + 1 : binding );
|
||
|
if ( !key )
|
||
|
{
|
||
|
key = "< not bound >";
|
||
|
}
|
||
|
|
||
|
//!! change some key names into better names
|
||
|
char friendlyName[64];
|
||
|
Q_snprintf( friendlyName, sizeof(friendlyName), "%s", key );
|
||
|
Q_strupr( friendlyName );
|
||
|
|
||
|
g_pVGuiLocalize->ConvertANSIToUnicode( friendlyName, token, sizeof(token) );
|
||
|
|
||
|
buf[pos] = '\0';
|
||
|
wcscat( buf, token );
|
||
|
pos += wcslen(token);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
buf[pos] = *ws;
|
||
|
++pos;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
buf[pos] = *ws;
|
||
|
++pos;
|
||
|
}
|
||
|
|
||
|
++ws;
|
||
|
}
|
||
|
|
||
|
buf[pos] = '\0';
|
||
|
|
||
|
// put it in a label
|
||
|
//vgui::Label *label = vgui::SETUP_PANEL(new vgui::Label(this, NULL, line));
|
||
|
vgui::Label *label = vgui::SETUP_PANEL(new vgui::Label(this, NULL, buf));
|
||
|
label->SetFont( m_hFont );
|
||
|
label->SetPaintBackgroundEnabled( false );
|
||
|
label->SetPaintBorderEnabled( false );
|
||
|
label->SizeToContents();
|
||
|
label->SetContentAlignment( vgui::Label::a_west );
|
||
|
label->SetFgColor( GetFgColor() );
|
||
|
m_Labels.AddToTail( vgui::SETUP_PANEL(label) );
|
||
|
}
|
||
|
InvalidateLayout( true );
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Resizes the label
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CDODHudHintDisplay::PerformLayout()
|
||
|
{
|
||
|
BaseClass::PerformLayout();
|
||
|
int i;
|
||
|
|
||
|
int wide, tall;
|
||
|
GetSize( wide, tall );
|
||
|
|
||
|
// find the widest line
|
||
|
int labelWide = 0;
|
||
|
for ( i=0; i<m_Labels.Count(); ++i )
|
||
|
{
|
||
|
labelWide = MAX( labelWide, m_Labels[i]->GetWide() );
|
||
|
}
|
||
|
|
||
|
// find the total height
|
||
|
int fontTall = vgui::surface()->GetFontTall( m_hFont );
|
||
|
int labelTall = fontTall * m_Labels.Count();
|
||
|
|
||
|
labelWide += m_iTextX*2;
|
||
|
labelTall += m_iTextY*2;
|
||
|
int x, y;
|
||
|
if ( m_iCenterX < 0 )
|
||
|
{
|
||
|
x = 0;
|
||
|
}
|
||
|
else if ( m_iCenterX > 0 )
|
||
|
{
|
||
|
x = wide - labelWide;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
x = (wide - labelWide) / 2;
|
||
|
}
|
||
|
|
||
|
if ( m_iCenterY > 0 )
|
||
|
{
|
||
|
y = 0;
|
||
|
}
|
||
|
else if ( m_iCenterY < 0 )
|
||
|
{
|
||
|
y = tall - labelTall;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
y = (tall - labelTall) / 2;
|
||
|
}
|
||
|
m_pLabel->SetBounds( x, y, labelWide, labelTall );
|
||
|
|
||
|
// now lay out the sub-labels
|
||
|
for ( i=0; i<m_Labels.Count(); ++i )
|
||
|
{
|
||
|
int xOffset = (labelWide - m_Labels[i]->GetWide())/2;
|
||
|
m_Labels[i]->SetPos( x + xOffset, y + m_iTextY + i*fontTall );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Updates the label color each frame
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CDODHudHintDisplay::OnThink()
|
||
|
{
|
||
|
m_pLabel->SetFgColor(GetFgColor());
|
||
|
for (int i = 0; i < m_Labels.Count(); i++)
|
||
|
{
|
||
|
m_Labels[i]->SetFgColor(GetFgColor());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Activates the hint display
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CDODHudHintDisplay::MsgFunc_HintText( bf_read &msg )
|
||
|
{
|
||
|
// read the string(s)
|
||
|
char szString[255];
|
||
|
static wchar_t szBuf[128];
|
||
|
static wchar_t *pszBuf;
|
||
|
|
||
|
// init buffers & pointers
|
||
|
szBuf[0] = 0;
|
||
|
pszBuf = szBuf;
|
||
|
|
||
|
// read string and localize it
|
||
|
msg.ReadString( szString, sizeof(szString) );
|
||
|
|
||
|
char *tmpStr = hudtextmessage->LookupString( szString, NULL );
|
||
|
|
||
|
// try to localize
|
||
|
if ( tmpStr )
|
||
|
{
|
||
|
pszBuf = g_pVGuiLocalize->Find( tmpStr );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pszBuf = g_pVGuiLocalize->Find( szString );
|
||
|
}
|
||
|
|
||
|
if ( !pszBuf )
|
||
|
{
|
||
|
// use plain ASCII string
|
||
|
g_pVGuiLocalize->ConvertANSIToUnicode( szString, szBuf, sizeof(szBuf) );
|
||
|
pszBuf = szBuf;
|
||
|
}
|
||
|
|
||
|
// make it visible
|
||
|
if ( SetHintText( pszBuf ) )
|
||
|
{
|
||
|
SetVisible( true );
|
||
|
//SetAlpha( 255 );
|
||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HintMessageShow" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// it's being cleared, hide the panel
|
||
|
//SetAlpha( 0 );
|
||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HintMessageHide" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Activates the hint display upon recieving a hint
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CDODHudHintDisplay::FireGameEvent( IGameEvent * event)
|
||
|
{
|
||
|
// we sometimes hide the element when it's covered, don't start
|
||
|
// a hint during that time
|
||
|
if ( !ShouldDraw() )
|
||
|
return;
|
||
|
|
||
|
static wchar_t *pszBuf;
|
||
|
static wchar_t szBuf[128];
|
||
|
|
||
|
const char *hintmessage = event->GetString( "hintmessage" );
|
||
|
|
||
|
char *tmpStr = hudtextmessage->LookupString( hintmessage, NULL );
|
||
|
|
||
|
// try to localize
|
||
|
if ( tmpStr )
|
||
|
{
|
||
|
pszBuf = g_pVGuiLocalize->Find( tmpStr );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pszBuf = g_pVGuiLocalize->Find( hintmessage );
|
||
|
}
|
||
|
|
||
|
if ( !pszBuf )
|
||
|
{
|
||
|
// its not in titles.txt or dod_english.txt, just print the text of it
|
||
|
// use plain ASCII string
|
||
|
g_pVGuiLocalize->ConvertANSIToUnicode( hintmessage, szBuf, sizeof(szBuf) );
|
||
|
pszBuf = szBuf;
|
||
|
}
|
||
|
|
||
|
// make it visible
|
||
|
if ( SetHintText( pszBuf ) )
|
||
|
{
|
||
|
SetVisible( true );
|
||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HintMessageShow" );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// it's being cleared, hide the panel
|
||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HintMessageHide" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool CDODHudHintDisplay::IsVisible( void )
|
||
|
{
|
||
|
if ( IsTakingAFreezecamScreenshot() )
|
||
|
return false;
|
||
|
|
||
|
if ( !ShouldDraw() )
|
||
|
return false;
|
||
|
|
||
|
return BaseClass::IsVisible();
|
||
|
}
|
||
|
|