mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-01-04 03:05:30 +03:00
1623 lines
52 KiB
C++
1623 lines
52 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
#include "cbase.h"
|
|
#include "c_baseentity.h"
|
|
#include "hud.h"
|
|
#include "hudelement.h"
|
|
#include "clientmode.h"
|
|
#include <vgui_controls/Panel.h>
|
|
#include <vgui/ISurface.h>
|
|
#include <vgui/ILocalize.h>
|
|
#include <vgui/IScheme.h>
|
|
#include <vgui_controls/AnimationController.h>
|
|
#include "materialsystem/imaterialsystemhardwareconfig.h"
|
|
#include "soundenvelope.h"
|
|
#include "convar.h"
|
|
#include "hud_closecaption.h"
|
|
#include "in_buttons.h"
|
|
#ifdef MAPBASE
|
|
#include "vgui_controls/Label.h"
|
|
#include "vgui_controls/ImagePanel.h"
|
|
#include "vgui_controls/AnimationController.h"
|
|
#include "filesystem.h"
|
|
#include "scenefilecache/ISceneFileCache.h"
|
|
#include "choreoscene.h"
|
|
#include "c_sceneentity.h"
|
|
#endif
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
#define MAX_SPEAKER_NAME 256
|
|
#define MAX_COUNT_STRING 64
|
|
|
|
extern ConVar english;
|
|
extern ConVar closecaption;
|
|
class C_PointCommentaryNode;
|
|
|
|
CUtlVector< CHandle<C_PointCommentaryNode> > g_CommentaryNodes;
|
|
bool IsInCommentaryMode( void )
|
|
{
|
|
return (g_CommentaryNodes.Count() > 0);
|
|
}
|
|
|
|
static bool g_bTracingVsCommentaryNodes = false;
|
|
|
|
#ifdef MAPBASE
|
|
ConVar commentary_type_force( "commentary_type_force", "-1", FCVAR_NONE, "Forces all commentary nodes to use the specified type." );
|
|
ConVar commentary_type_text_endtime( "commentary_type_text_endtime", "120" );
|
|
ConVar commentary_type_image_endtime( "commentary_type_image_endtime", "120" );
|
|
ConVar commentary_audio_element_below_cc( "commentary_audio_element_below_cc", "1", FCVAR_NONE, "Allows commentary audio elements to display even when CC is enabled (although this is done by inverting their Y axis)" );
|
|
ConVar commentary_audio_element_below_cc_margin( "commentary_audio_element_below_cc_margin", "4" );
|
|
ConVar commentary_combine_speaker_and_printname( "commentary_combine_speaker_and_printname", "1" );
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
class CHudCommentary : public CHudElement, public vgui::Panel
|
|
{
|
|
DECLARE_CLASS_SIMPLE( CHudCommentary, vgui::Panel );
|
|
public:
|
|
CHudCommentary( const char *name );
|
|
|
|
virtual void Init( void );
|
|
virtual void VidInit( void );
|
|
virtual void LevelInit( void ) { g_CommentaryNodes.Purge(); }
|
|
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
|
|
|
|
void StartCommentary( C_PointCommentaryNode *pNode, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime );
|
|
#ifdef MAPBASE
|
|
void StartTextCommentary( C_PointCommentaryNode *pNode, const char *pszText, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime );
|
|
void StartImageCommentary( C_PointCommentaryNode *pNode, const char *pszImage, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime );
|
|
void StartSceneCommentary( C_PointCommentaryNode *pNode, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime );
|
|
#endif
|
|
void StopCommentary( void );
|
|
bool IsTheActiveNode( C_PointCommentaryNode *pNode ) { return (pNode == m_hActiveNode); }
|
|
|
|
#ifdef MAPBASE
|
|
void CombineSpeakerAndPrintName( const char *pszPrintName );
|
|
void RepositionCloseCaption();
|
|
#endif
|
|
|
|
// vgui overrides
|
|
virtual void Paint( void );
|
|
virtual bool ShouldDraw( void );
|
|
#ifdef MAPBASE
|
|
virtual void PerformLayout();
|
|
void ResolveBounds( int width, int height );
|
|
#endif
|
|
|
|
private:
|
|
CHandle<C_PointCommentaryNode> m_hActiveNode;
|
|
bool m_bShouldPaint;
|
|
float m_flStartTime;
|
|
float m_flEndTime;
|
|
wchar_t m_szSpeakers[MAX_SPEAKER_NAME];
|
|
wchar_t m_szCount[MAX_COUNT_STRING];
|
|
CMaterialReference m_matIcon;
|
|
bool m_bHiding;
|
|
#ifdef MAPBASE
|
|
int m_iCommentaryType;
|
|
float m_flPanelScale;
|
|
float m_flOverrideX;
|
|
float m_flOverrideY;
|
|
|
|
vgui::Label *m_pLabel;
|
|
vgui::ImagePanel *m_pImage;
|
|
vgui::HFont m_hFont;
|
|
|
|
// HACKHACK: Needed as a failsafe to prevent desync
|
|
int m_iCCDefaultY;
|
|
#endif
|
|
|
|
// Painting
|
|
CPanelAnimationVarAliasType( int, m_iBarX, "bar_xpos", "8", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iBarY, "bar_ypos", "8", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iBarTall, "bar_height", "16", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iBarWide, "bar_width", "16", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iSpeakersX, "speaker_xpos", "8", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iSpeakersY, "speaker_ypos", "8", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iCountXFR, "count_xpos_from_right", "8", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iCountY, "count_ypos", "8", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iIconX, "icon_xpos", "8", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iIconY, "icon_ypos", "8", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iIconWide, "icon_width", "8", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iIconTall, "icon_height", "8", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_nIconTextureId, "icon_texture", "vgui/hud/icon_commentary", "textureid" );
|
|
|
|
#ifdef MAPBASE
|
|
CPanelAnimationVarAliasType( int, m_iTypeAudioX, "type_audio_xpos", "190", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iTypeAudioY, "type_audio_ypos", "350", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iTypeAudioW, "type_audio_wide", "380", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iTypeAudioT, "type_audio_tall", "40", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iTypeTextX, "type_text_xpos", "180", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iTypeTextY, "type_text_ypos", "150", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iTypeTextW, "type_text_wide", "400", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iTypeTextT, "type_text_tall", "200", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iTypeTextCountXFR, "type_text_count_xpos_from_right", "10", "proportional_int" );
|
|
CPanelAnimationVarAliasType( int, m_iTypeTextCountYFB, "type_text_count_ypos_from_bottom", "10", "proportional_int" );
|
|
CPanelAnimationVar( Color, m_TextBackgroundColor, "BackgroundColorTextContent", "0 0 0 224" );
|
|
CPanelAnimationVar( Color, m_TypeTextContentColor, "TextContentColor", "255 230 180 255" );
|
|
CPanelAnimationVar( int, m_iTextBorderSpace, "type_text_border_space", "8" );
|
|
#endif
|
|
|
|
CPanelAnimationVar( bool, m_bUseScriptBGColor, "use_script_bgcolor", "0" );
|
|
#ifdef MAPBASE
|
|
CPanelAnimationVar( Color, m_BackgroundColor, "BackgroundColor", "Panel.BgColor" );
|
|
CPanelAnimationVar( Color, m_ForegroundColor, "ForegroundColor", "255 170 0 255" );
|
|
#else
|
|
CPanelAnimationVar( Color, m_BackgroundColor, "BackgroundColor", "0 0 0 0" );
|
|
#endif
|
|
CPanelAnimationVar( Color, m_BGOverrideColor, "BackgroundOverrideColor", "Panel.BgColor" );
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
class C_PointCommentaryNode : public C_BaseAnimating, public IChoreoEventCallback
|
|
{
|
|
DECLARE_CLASS( C_PointCommentaryNode, C_BaseAnimating );
|
|
public:
|
|
DECLARE_CLIENTCLASS();
|
|
DECLARE_DATADESC();
|
|
#ifdef MAPBASE_VSCRIPT
|
|
DECLARE_ENT_SCRIPTDESC();
|
|
#endif
|
|
|
|
virtual void OnPreDataChanged( DataUpdateType_t type );
|
|
virtual void OnDataChanged( DataUpdateType_t type );
|
|
|
|
void StartAudioCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer );
|
|
#ifdef MAPBASE
|
|
void StartTextCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer );
|
|
void StartImageCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer );
|
|
void StartSceneCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer );
|
|
|
|
// From IChoreoEventCallback
|
|
virtual void StartEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event );
|
|
#else
|
|
virtual void StartEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) {}
|
|
#endif
|
|
virtual void EndEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) {}
|
|
virtual void ProcessEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) {}
|
|
virtual bool CheckEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ) { return true; }
|
|
|
|
void ClientThink();
|
|
|
|
void OnRestore( void )
|
|
{
|
|
BaseClass::OnRestore();
|
|
|
|
if ( m_bActive )
|
|
{
|
|
StopLoopingSounds();
|
|
m_bRestartAfterRestore = true;
|
|
}
|
|
|
|
AddAndLockCommentaryHudGroup();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
virtual void SetDormant( bool bDormant )
|
|
{
|
|
if ( !IsDormant() && bDormant )
|
|
{
|
|
RemoveAndUnlockCommentaryHudGroup();
|
|
}
|
|
|
|
BaseClass::SetDormant( bDormant );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Cleanup
|
|
//-----------------------------------------------------------------------------
|
|
void UpdateOnRemove( void )
|
|
{
|
|
RemoveAndUnlockCommentaryHudGroup();
|
|
|
|
StopLoopingSounds();
|
|
BaseClass::UpdateOnRemove();
|
|
}
|
|
|
|
void StopLoopingSounds( void );
|
|
|
|
virtual bool TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace );
|
|
|
|
void AddAndLockCommentaryHudGroup( void )
|
|
{
|
|
if ( !g_CommentaryNodes.Count() )
|
|
{
|
|
int iRenderGroup = gHUD.LookupRenderGroupIndexByName( "commentary" );
|
|
gHUD.LockRenderGroup( iRenderGroup );
|
|
|
|
#ifdef MAPBASE
|
|
// Special commentary localization file (useful for things like text nodes or print names)
|
|
g_pVGuiLocalize->AddFile( "resource/commentary_%language%.txt" );
|
|
#endif
|
|
}
|
|
|
|
if ( g_CommentaryNodes.Find(this) == g_CommentaryNodes.InvalidIndex() )
|
|
{
|
|
g_CommentaryNodes.AddToTail( this );
|
|
}
|
|
}
|
|
|
|
void RemoveAndUnlockCommentaryHudGroup( void )
|
|
{
|
|
g_CommentaryNodes.FindAndRemove( this );
|
|
|
|
if ( !g_CommentaryNodes.Count() )
|
|
{
|
|
int iRenderGroup = gHUD.LookupRenderGroupIndexByName( "commentary" );
|
|
gHUD.UnlockRenderGroup( iRenderGroup );
|
|
}
|
|
}
|
|
|
|
#ifdef MAPBASE_VSCRIPT // VScript funcs
|
|
bool IsActive() { return m_bActive; }
|
|
|
|
int GetCommentaryType() { return m_iCommentaryType; }
|
|
void SetCommentaryType( int iType ) { m_iCommentaryType = iType; }
|
|
|
|
const char *GetCommentaryFile() { return m_iszCommentaryFile; }
|
|
void SetCommentaryFile( const char *pszNewFile ) { Q_strncpy( m_iszCommentaryFile, pszNewFile, sizeof( m_iszCommentaryFile ) ); }
|
|
const char *GetSpeakers() { return m_iszSpeakers; }
|
|
void SetSpeakers( const char *pszSpeakers ) { Q_strncpy( m_iszSpeakers, pszSpeakers, sizeof( m_iszSpeakers ) ); }
|
|
const char *GetPrintName() { return m_iszPrintName; }
|
|
void SetPrintName( const char *pszPrintName ) { Q_strncpy( m_iszPrintName, pszPrintName, sizeof( m_iszPrintName ) ); }
|
|
#endif
|
|
|
|
public:
|
|
// Data received from the server
|
|
bool m_bActive;
|
|
bool m_bWasActive;
|
|
float m_flStartTime;
|
|
char m_iszCommentaryFile[MAX_PATH];
|
|
char m_iszCommentaryFileNoHDR[MAX_PATH];
|
|
char m_iszSpeakers[MAX_SPEAKER_NAME];
|
|
int m_iNodeNumber;
|
|
int m_iNodeNumberMax;
|
|
CSoundPatch *m_sndCommentary;
|
|
EHANDLE m_hViewPosition;
|
|
bool m_bRestartAfterRestore;
|
|
#ifdef MAPBASE
|
|
char m_iszPrintName[MAX_SPEAKER_NAME];
|
|
int m_iCommentaryType;
|
|
float m_flPanelScale;
|
|
float m_flPanelX;
|
|
float m_flPanelY;
|
|
|
|
CChoreoScene *m_pScene;
|
|
//CHandle<C_SceneEntity> m_hScene;
|
|
EHANDLE m_hSceneOrigin;
|
|
#endif
|
|
|
|
#ifdef MAPBASE_VSCRIPT
|
|
static ScriptHook_t g_Hook_PreStartCommentaryClient;
|
|
#endif
|
|
};
|
|
|
|
IMPLEMENT_CLIENTCLASS_DT(C_PointCommentaryNode, DT_PointCommentaryNode, CPointCommentaryNode)
|
|
RecvPropBool( RECVINFO( m_bActive ) ),
|
|
RecvPropTime( RECVINFO( m_flStartTime ) ),
|
|
RecvPropString( RECVINFO(m_iszCommentaryFile) ),
|
|
RecvPropString( RECVINFO(m_iszCommentaryFileNoHDR) ),
|
|
RecvPropString( RECVINFO(m_iszSpeakers) ),
|
|
RecvPropInt( RECVINFO( m_iNodeNumber ) ),
|
|
RecvPropInt( RECVINFO( m_iNodeNumberMax ) ),
|
|
RecvPropEHandle( RECVINFO(m_hViewPosition) ),
|
|
#ifdef MAPBASE
|
|
RecvPropString( RECVINFO( m_iszPrintName ) ),
|
|
RecvPropInt( RECVINFO( m_iCommentaryType ) ),
|
|
RecvPropFloat( RECVINFO( m_flPanelScale ) ),
|
|
RecvPropFloat( RECVINFO( m_flPanelX ) ),
|
|
RecvPropFloat( RECVINFO( m_flPanelY ) ),
|
|
#endif
|
|
END_RECV_TABLE()
|
|
|
|
BEGIN_DATADESC( C_PointCommentaryNode )
|
|
DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ),
|
|
DEFINE_FIELD( m_bWasActive, FIELD_BOOLEAN ),
|
|
DEFINE_SOUNDPATCH( m_sndCommentary ),
|
|
END_DATADESC()
|
|
|
|
#ifdef MAPBASE_VSCRIPT
|
|
ScriptHook_t C_PointCommentaryNode::g_Hook_PreStartCommentaryClient;
|
|
|
|
BEGIN_ENT_SCRIPTDESC( C_PointCommentaryNode, C_BaseAnimating, "Commentary nodes which play commentary in commentary mode." )
|
|
|
|
DEFINE_SCRIPTFUNC( IsActive, "" )
|
|
DEFINE_SCRIPTFUNC( GetCommentaryFile, "" )
|
|
DEFINE_SCRIPTFUNC( SetCommentaryFile, "" )
|
|
DEFINE_SCRIPTFUNC( GetSpeakers, "" )
|
|
DEFINE_SCRIPTFUNC( SetSpeakers, "" )
|
|
DEFINE_SCRIPTFUNC( GetPrintName, "" )
|
|
DEFINE_SCRIPTFUNC( SetPrintName, "" )
|
|
DEFINE_SCRIPTFUNC( GetCommentaryType, "" )
|
|
DEFINE_SCRIPTFUNC( SetCommentaryType, "" )
|
|
|
|
DEFINE_SIMPLE_SCRIPTHOOK( C_PointCommentaryNode::g_Hook_PreStartCommentaryClient, "PreStartCommentaryClient", FIELD_BOOLEAN, "Called just before commentary begins on the client. Use this to modify variables or commentary behavior before it begins. Returning false will prevent the commentary from starting." )
|
|
|
|
END_SCRIPTDESC();
|
|
#endif
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void C_PointCommentaryNode::OnPreDataChanged( DataUpdateType_t updateType )
|
|
{
|
|
BaseClass::OnPreDataChanged( updateType );
|
|
|
|
m_bWasActive = m_bActive;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void C_PointCommentaryNode::OnDataChanged( DataUpdateType_t updateType )
|
|
{
|
|
BaseClass::OnDataChanged( updateType );
|
|
|
|
if ( updateType == DATA_UPDATE_CREATED )
|
|
{
|
|
AddAndLockCommentaryHudGroup();
|
|
}
|
|
|
|
if ( m_bWasActive == m_bActive && !m_bRestartAfterRestore )
|
|
return;
|
|
|
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
|
if ( m_bActive && pPlayer )
|
|
{
|
|
#ifdef MAPBASE_VSCRIPT
|
|
if (m_ScriptScope.IsInitialized() && g_Hook_PreStartCommentaryClient.CanRunInScope( m_ScriptScope ))
|
|
{
|
|
ScriptVariant_t functionReturn;
|
|
if (g_Hook_PreStartCommentaryClient.Call( m_ScriptScope, &functionReturn, NULL ) && functionReturn.m_type == FIELD_BOOLEAN)
|
|
{
|
|
// Don't play the commentary if it returned false
|
|
if (functionReturn.m_bool == false)
|
|
{
|
|
engine->ServerCmd( "commentary_finishnode\n" );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// Use the HDR / Non-HDR version based on whether we're running HDR or not
|
|
char *pszCommentaryFile;
|
|
if ( g_pMaterialSystemHardwareConfig->GetHDRType() == HDR_TYPE_NONE && m_iszCommentaryFileNoHDR && m_iszCommentaryFileNoHDR[0] )
|
|
{
|
|
pszCommentaryFile = m_iszCommentaryFileNoHDR;
|
|
}
|
|
else
|
|
{
|
|
pszCommentaryFile = m_iszCommentaryFile;
|
|
}
|
|
if ( !pszCommentaryFile || !pszCommentaryFile[0] )
|
|
{
|
|
engine->ServerCmd( "commentary_finishnode\n" );
|
|
return;
|
|
}
|
|
|
|
#ifdef MAPBASE
|
|
int iCommentaryType = m_iCommentaryType;
|
|
if (commentary_type_force.GetInt() != -1)
|
|
iCommentaryType = commentary_type_force.GetInt();
|
|
|
|
switch (iCommentaryType)
|
|
{
|
|
case COMMENTARY_TYPE_TEXT:
|
|
StartTextCommentary( pszCommentaryFile, pPlayer );
|
|
break;
|
|
|
|
case COMMENTARY_TYPE_IMAGE:
|
|
StartImageCommentary( pszCommentaryFile, pPlayer );
|
|
break;
|
|
|
|
case COMMENTARY_TYPE_SCENE:
|
|
StartSceneCommentary( pszCommentaryFile, pPlayer );
|
|
break;
|
|
|
|
default:
|
|
case COMMENTARY_TYPE_AUDIO:
|
|
StartAudioCommentary( pszCommentaryFile, pPlayer );
|
|
break;
|
|
}
|
|
#else
|
|
StartAudioCommentary( pszCommentaryFile, pPlayer );
|
|
#endif
|
|
}
|
|
else if ( m_bWasActive )
|
|
{
|
|
StopLoopingSounds();
|
|
|
|
CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary );
|
|
if ( pHudCommentary->IsTheActiveNode(this) )
|
|
{
|
|
pHudCommentary->StopCommentary();
|
|
}
|
|
}
|
|
|
|
m_bRestartAfterRestore = false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void C_PointCommentaryNode::StartAudioCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer )
|
|
{
|
|
EmitSound_t es;
|
|
es.m_nChannel = CHAN_STATIC;
|
|
es.m_pSoundName = pszCommentaryFile;
|
|
es.m_SoundLevel = SNDLVL_GUNFIRE;
|
|
es.m_nFlags = SND_SHOULDPAUSE;
|
|
|
|
CBaseEntity *pSoundEntity;
|
|
if ( m_hViewPosition )
|
|
{
|
|
pSoundEntity = m_hViewPosition;
|
|
}
|
|
else if ( render->GetViewEntity() )
|
|
{
|
|
pSoundEntity = cl_entitylist->GetEnt( render->GetViewEntity() );
|
|
es.m_SoundLevel = SNDLVL_NONE;
|
|
}
|
|
else
|
|
{
|
|
pSoundEntity = pPlayer;
|
|
}
|
|
CSingleUserRecipientFilter filter( pPlayer );
|
|
m_sndCommentary = (CSoundEnvelopeController::GetController()).SoundCreate( filter, pSoundEntity->entindex(), es );
|
|
if ( m_sndCommentary )
|
|
{
|
|
(CSoundEnvelopeController::GetController()).SoundSetCloseCaptionDuration( m_sndCommentary, -1 );
|
|
(CSoundEnvelopeController::GetController()).Play( m_sndCommentary, 1.0f, 100, m_flStartTime );
|
|
}
|
|
|
|
// Get the duration so we know when it finishes
|
|
float flDuration = enginesound->GetSoundDuration( STRING( CSoundEnvelopeController::GetController().SoundGetName( m_sndCommentary ) ) ) ;
|
|
bool bSubtitlesEnabled = false;
|
|
|
|
CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption );
|
|
if ( pHudCloseCaption )
|
|
{
|
|
// This is where we play the commentary close caption (and lock the other captions out).
|
|
// Also, if close captions are off we force a caption in non-English
|
|
if ( closecaption.GetBool() || ( !closecaption.GetBool() && !english.GetBool() ) )
|
|
{
|
|
// Clear the close caption element in preparation
|
|
pHudCloseCaption->Reset();
|
|
|
|
// Process the commentary caption
|
|
pHudCloseCaption->ProcessCaptionDirect( pszCommentaryFile, flDuration );
|
|
|
|
// Find the close caption hud element & lock it
|
|
pHudCloseCaption->Lock();
|
|
|
|
bSubtitlesEnabled = true;
|
|
}
|
|
}
|
|
|
|
char *pszSpeakers = m_iszSpeakers;
|
|
|
|
// Tell the HUD element
|
|
CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary );
|
|
pHudCommentary->StartCommentary( this, pszSpeakers, m_iNodeNumber, m_iNodeNumberMax, m_flStartTime, m_flStartTime + flDuration );
|
|
}
|
|
|
|
#ifdef MAPBASE
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void C_PointCommentaryNode::StartTextCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer )
|
|
{
|
|
// Get the duration so we know when it finishes
|
|
//float flDuration = enginesound->GetSoundDuration( STRING( CSoundEnvelopeController::GetController().SoundGetName( m_sndCommentary ) ) ) ;
|
|
|
|
// TODO: Determine from text length?
|
|
float flDuration = commentary_type_text_endtime.GetFloat();
|
|
|
|
// Tell the HUD element
|
|
CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary );
|
|
pHudCommentary->StartTextCommentary( this, pszCommentaryFile, m_iszSpeakers, m_iNodeNumber, m_iNodeNumberMax, m_flStartTime, m_flStartTime + flDuration );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void C_PointCommentaryNode::StartImageCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer )
|
|
{
|
|
// Get the duration so we know when it finishes
|
|
//float flDuration = enginesound->GetSoundDuration( STRING( CSoundEnvelopeController::GetController().SoundGetName( m_sndCommentary ) ) ) ;
|
|
|
|
float flDuration = commentary_type_image_endtime.GetFloat();
|
|
|
|
// Tell the HUD element
|
|
CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary );
|
|
pHudCommentary->StartImageCommentary( this, pszCommentaryFile, m_iszSpeakers, m_iNodeNumber, m_iNodeNumberMax, m_flStartTime, m_flStartTime + flDuration );
|
|
}
|
|
|
|
extern CChoreoStringPool g_ChoreoStringPool;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void C_PointCommentaryNode::StartSceneCommentary( const char *pszCommentaryFile, C_BasePlayer *pPlayer )
|
|
{
|
|
char loadfile[MAX_PATH];
|
|
Q_strncpy( loadfile, pszCommentaryFile, sizeof( loadfile ) );
|
|
Q_SetExtension( loadfile, ".vcd", sizeof( loadfile ) );
|
|
Q_FixSlashes( loadfile );
|
|
|
|
//
|
|
// Raw scene file support
|
|
//
|
|
void *pBuffer = 0;
|
|
size_t bufsize = scenefilecache->GetSceneBufferSize( loadfile );
|
|
if ( bufsize > 0 )
|
|
{
|
|
// Definitely in scenes.image
|
|
pBuffer = malloc( bufsize );
|
|
if ( !scenefilecache->GetSceneData( pszCommentaryFile, (byte *)pBuffer, bufsize ) )
|
|
{
|
|
free( pBuffer );
|
|
}
|
|
|
|
|
|
if ( IsBufferBinaryVCD( (char*)pBuffer, bufsize ) )
|
|
{
|
|
m_pScene = new CChoreoScene( NULL );
|
|
CUtlBuffer buf( pBuffer, bufsize, CUtlBuffer::READ_ONLY );
|
|
if ( !m_pScene->RestoreFromBinaryBuffer( buf, loadfile, &g_ChoreoStringPool ) )
|
|
{
|
|
Warning( "Unable to restore scene '%s'\n", loadfile );
|
|
delete m_pScene;
|
|
m_pScene = NULL;
|
|
}
|
|
}
|
|
}
|
|
else if (filesystem->ReadFileEx( loadfile, "MOD", &pBuffer, true ))
|
|
{
|
|
// Not in scenes.image, but it's a raw file
|
|
g_TokenProcessor.SetBuffer((char*)pBuffer);
|
|
m_pScene = ChoreoLoadScene( loadfile, this, &g_TokenProcessor, Scene_Printf );
|
|
}
|
|
|
|
free( pBuffer );
|
|
|
|
if( m_pScene )
|
|
{
|
|
m_pScene->SetPrintFunc( Scene_Printf );
|
|
m_pScene->SetEventCallbackInterface( this );
|
|
}
|
|
else
|
|
{
|
|
// Cancel commentary (TODO: clean up?)
|
|
return;
|
|
}
|
|
|
|
int types[ 2 ];
|
|
types[ 0 ] = CChoreoEvent::SPEAK;
|
|
//types[ 1 ] = CChoreoEvent::GENERIC; // TODO: Support for the game_text event?
|
|
m_pScene->RemoveEventsExceptTypes( types, 1 );
|
|
|
|
// Iterate events and precache necessary resources
|
|
for ( int i = 0; i < m_pScene->GetNumEvents(); i++ )
|
|
{
|
|
CChoreoEvent *event = m_pScene->GetEvent( i );
|
|
if ( !event )
|
|
continue;
|
|
|
|
// load any necessary data
|
|
switch (event->GetType() )
|
|
{
|
|
default:
|
|
break;
|
|
case CChoreoEvent::SPEAK:
|
|
{
|
|
// Defined in SoundEmitterSystem.cpp
|
|
// NOTE: The script entries associated with .vcds are forced to preload to avoid
|
|
// loading hitches during triggering
|
|
CBaseEntity::PrecacheScriptSound( event->GetParameters() );
|
|
|
|
if ( event->GetCloseCaptionType() == CChoreoEvent::CC_MASTER &&
|
|
event->GetNumSlaves() > 0 )
|
|
{
|
|
char tok[ CChoreoEvent::MAX_CCTOKEN_STRING ];
|
|
if ( event->GetPlaybackCloseCaptionToken( tok, sizeof( tok ) ) )
|
|
{
|
|
CBaseEntity::PrecacheScriptSound( tok );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
PrecacheScriptSound( "AI_BaseNPC.SentenceStop" );
|
|
|
|
if ( m_hViewPosition )
|
|
{
|
|
m_hSceneOrigin = m_hViewPosition;
|
|
}
|
|
else if ( render->GetViewEntity() )
|
|
{
|
|
m_hSceneOrigin = cl_entitylist->GetEnt( render->GetViewEntity() );
|
|
}
|
|
else
|
|
{
|
|
m_hSceneOrigin = pPlayer;
|
|
}
|
|
|
|
// Get the duration so we know when it finishes
|
|
float flDuration = m_pScene->GetDuration();
|
|
|
|
// Add a tiny amount of time at the end to ensure audio doesn't get cut off
|
|
flDuration += 0.5f;
|
|
|
|
CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption );
|
|
if ( pHudCloseCaption )
|
|
{
|
|
// This is where we play the commentary close caption (and lock the other captions out).
|
|
// Also, if close captions are off we force a caption in non-English
|
|
if ( closecaption.GetBool() || ( !closecaption.GetBool() && !english.GetBool() ) )
|
|
{
|
|
// Clear the close caption element in preparation
|
|
pHudCloseCaption->Reset();
|
|
|
|
// Find the close caption hud element & lock it
|
|
pHudCloseCaption->Lock();
|
|
}
|
|
}
|
|
|
|
// Tell the HUD element
|
|
CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary );
|
|
pHudCommentary->StartSceneCommentary( this, m_iszSpeakers, m_iNodeNumber, m_iNodeNumberMax, m_flStartTime, m_flStartTime + flDuration );
|
|
|
|
// Start thinking for the scene
|
|
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: All events are leading edge triggered
|
|
// Input : currenttime -
|
|
// *event -
|
|
//-----------------------------------------------------------------------------
|
|
void C_PointCommentaryNode::StartEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event )
|
|
{
|
|
Assert( event );
|
|
|
|
if ( !Q_stricmp( event->GetName(), "NULL" ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
//Msg("Starting event \"%s\" (%s)\n", event->GetName(), event->GetParameters());
|
|
|
|
// load any necessary data
|
|
switch (event->GetType() )
|
|
{
|
|
default:
|
|
break;
|
|
case CChoreoEvent::SPEAK:
|
|
{
|
|
CSingleUserRecipientFilter filter( C_BasePlayer::GetLocalPlayer() );
|
|
|
|
EmitSound_t es;
|
|
es.m_nChannel = CHAN_VOICE2;
|
|
es.m_flVolume = 1;
|
|
es.m_SoundLevel = SNDLVL_GUNFIRE;
|
|
//es.m_nFlags = SND_SHOULDPAUSE;
|
|
|
|
es.m_bEmitCloseCaption = false;
|
|
es.m_pSoundName = event->GetParameters();
|
|
|
|
// Just in case
|
|
if (!m_hSceneOrigin)
|
|
m_hSceneOrigin = C_BasePlayer::GetLocalPlayer();
|
|
|
|
EmitSound( filter, m_hSceneOrigin->entindex(), es );
|
|
|
|
// Close captioning only on master token no matter what...
|
|
// Also, if close captions are off we force a caption in non-English
|
|
if ( event->GetCloseCaptionType() == CChoreoEvent::CC_MASTER && closecaption.GetBool() || ( !closecaption.GetBool() && !english.GetBool() ) )
|
|
{
|
|
char tok[ CChoreoEvent::MAX_CCTOKEN_STRING ];
|
|
bool validtoken = event->GetPlaybackCloseCaptionToken( tok, sizeof( tok ) );
|
|
if ( validtoken )
|
|
{
|
|
CRC32_t tokenCRC;
|
|
CRC32_Init( &tokenCRC );
|
|
|
|
char lowercase[ 256 ];
|
|
Q_strncpy( lowercase, tok, sizeof( lowercase ) );
|
|
Q_strlower( lowercase );
|
|
|
|
CRC32_ProcessBuffer( &tokenCRC, lowercase, Q_strlen( lowercase ) );
|
|
CRC32_Final( &tokenCRC );
|
|
|
|
float endtime = event->GetLastSlaveEndTime();
|
|
float durationShort = event->GetDuration();
|
|
float durationLong = endtime - event->GetStartTime();
|
|
float duration = MAX( durationShort, durationLong );
|
|
|
|
CHudCloseCaption *hudCloseCaption = GET_HUDELEMENT( CHudCloseCaption );
|
|
if ( hudCloseCaption )
|
|
{
|
|
hudCloseCaption->ProcessCaptionDirect( lowercase, duration );
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
break;
|
|
// TODO: Support for the game_text event?
|
|
/*
|
|
case CChoreoEvent::GENERIC:
|
|
{
|
|
|
|
}
|
|
break;
|
|
*/
|
|
}
|
|
|
|
event->m_flPrevTime = currenttime;
|
|
}
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void C_PointCommentaryNode::ClientThink()
|
|
{
|
|
BaseClass::ClientThink();
|
|
|
|
#ifdef MAPBASE
|
|
if (m_iCommentaryType == COMMENTARY_TYPE_SCENE && m_pScene)
|
|
{
|
|
m_pScene->Think( gpGlobals->curtime - m_flStartTime );
|
|
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Shut down the commentary
|
|
//-----------------------------------------------------------------------------
|
|
void C_PointCommentaryNode::StopLoopingSounds( void )
|
|
{
|
|
if ( m_sndCommentary != NULL )
|
|
{
|
|
(CSoundEnvelopeController::GetController()).SoundDestroy( m_sndCommentary );
|
|
m_sndCommentary = NULL;
|
|
}
|
|
|
|
#ifdef MAPBASE
|
|
if ( m_pScene )
|
|
{
|
|
delete m_pScene;
|
|
m_pScene = NULL;
|
|
|
|
// Must do this to terminate audio
|
|
// (TODO: This causes problems when players switch from a scene node immediately to a regular audio node)
|
|
if (m_hSceneOrigin)
|
|
m_hSceneOrigin->EmitSound( "AI_BaseNPC.SentenceStop" );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: No client side trace collisions
|
|
//-----------------------------------------------------------------------------
|
|
bool C_PointCommentaryNode::TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace )
|
|
{
|
|
if ( !g_bTracingVsCommentaryNodes )
|
|
return false;
|
|
|
|
return BaseClass::TestCollision( ray, mask, trace );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
bool IsNodeUnderCrosshair( C_BasePlayer *pPlayer )
|
|
{
|
|
// See if the player's looking at a commentary node
|
|
trace_t tr;
|
|
Vector vecSrc = pPlayer->EyePosition();
|
|
Vector vecForward;
|
|
AngleVectors( pPlayer->EyeAngles(), &vecForward );
|
|
|
|
g_bTracingVsCommentaryNodes = true;
|
|
UTIL_TraceLine( vecSrc, vecSrc + vecForward * MAX_TRACE_LENGTH, MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr );
|
|
g_bTracingVsCommentaryNodes = false;
|
|
|
|
if ( !tr.m_pEnt )
|
|
return false;
|
|
|
|
return dynamic_cast<C_PointCommentaryNode*>(tr.m_pEnt);
|
|
}
|
|
|
|
//===================================================================================================================
|
|
// COMMENTARY HUD ELEMENT
|
|
//===================================================================================================================
|
|
DECLARE_HUDELEMENT( CHudCommentary );
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
CHudCommentary::CHudCommentary( const char *name ) : vgui::Panel( NULL, "HudCommentary" ), CHudElement( name )
|
|
{
|
|
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
|
SetParent( pParent );
|
|
|
|
SetPaintBorderEnabled( false );
|
|
SetHiddenBits( HIDEHUD_PLAYERDEAD );
|
|
|
|
m_hActiveNode = NULL;
|
|
m_bShouldPaint = true;
|
|
|
|
#ifdef MAPBASE
|
|
m_pLabel = new vgui::Label( this, "HudCommentaryTextLabel", L"Textual commentary" );
|
|
m_pImage = new vgui::ImagePanel( this, "HudCommentaryImagePanel" );
|
|
m_pImage->SetShouldScaleImage( true );
|
|
|
|
m_iCCDefaultY = 0;
|
|
#endif
|
|
}
|
|
|
|
void CHudCommentary::ApplySchemeSettings( vgui::IScheme *pScheme )
|
|
{
|
|
BaseClass::ApplySchemeSettings( pScheme );
|
|
|
|
if ( m_bUseScriptBGColor )
|
|
{
|
|
SetBgColor( m_BGOverrideColor );
|
|
}
|
|
|
|
#ifdef MAPBASE
|
|
m_pLabel->SetPaintBackgroundType( 2 );
|
|
m_pLabel->SetSize( 0, GetTall() );
|
|
#endif
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CHudCommentary::Paint()
|
|
{
|
|
float flDuration = (m_flEndTime - m_flStartTime);
|
|
float flPercentage = clamp( ( gpGlobals->curtime - m_flStartTime ) / flDuration, 0.f, 1.f );
|
|
|
|
if ( !m_hActiveNode )
|
|
{
|
|
if ( !m_bHiding )
|
|
{
|
|
m_bHiding = true;
|
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HideCommentary" );
|
|
|
|
CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption );
|
|
if ( pHudCloseCaption )
|
|
{
|
|
pHudCloseCaption->Reset();
|
|
|
|
#ifdef MAPBASE
|
|
// Reset close caption element if needed
|
|
if (pHudCloseCaption->IsUsingCommentaryDimensions())
|
|
{
|
|
int ccX, ccY;
|
|
pHudCloseCaption->GetPos( ccX, ccY );
|
|
//pHudCloseCaption->SetPos( ccX, ccY + m_iTypeAudioT );
|
|
|
|
// Run this animation command instead of setting the position directly
|
|
g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( pHudCloseCaption, "YPos", ccY + m_iTypeAudioT, 0.0f, 0.4f, vgui::AnimationController::INTERPOLATOR_ACCEL );
|
|
|
|
pHudCloseCaption->SetUsingCommentaryDimensions( false );
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Detect the end of the commentary
|
|
if ( flPercentage >= 1 && m_hActiveNode )
|
|
{
|
|
#ifdef MAPBASE
|
|
// Ensure that the scene is terminated
|
|
if (m_iCommentaryType == COMMENTARY_TYPE_SCENE)
|
|
m_hActiveNode->StopLoopingSounds();
|
|
|
|
// Reset close caption element if needed
|
|
CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption );
|
|
if (pHudCloseCaption && pHudCloseCaption->IsUsingCommentaryDimensions())
|
|
{
|
|
int ccX, ccY;
|
|
pHudCloseCaption->GetPos( ccX, ccY );
|
|
//pHudCloseCaption->SetPos( ccX, ccY + m_iTypeAudioT );
|
|
|
|
// Run this animation command instead of setting the position directly
|
|
g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( pHudCloseCaption, "YPos", ccY + m_iTypeAudioT, 0.0f, 0.4f, vgui::AnimationController::INTERPOLATOR_ACCEL );
|
|
|
|
pHudCloseCaption->SetUsingCommentaryDimensions( false );
|
|
}
|
|
#endif
|
|
|
|
m_hActiveNode = NULL;
|
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HideCommentary" );
|
|
|
|
engine->ServerCmd( "commentary_finishnode\n" );
|
|
}
|
|
}
|
|
|
|
if ( !m_bShouldPaint )
|
|
return;
|
|
|
|
int x, y, wide, tall;
|
|
GetBounds( x, y, wide, tall );
|
|
|
|
int xOffset = m_iBarX;
|
|
int yOffset = m_iBarY;
|
|
|
|
// Find our fade based on our time shown
|
|
Color clr = m_ForegroundColor;
|
|
|
|
#ifdef MAPBASE
|
|
switch (m_iCommentaryType)
|
|
{
|
|
case COMMENTARY_TYPE_TEXT:
|
|
{
|
|
// Figure out the size before setting bounds
|
|
int lW, lT;
|
|
m_pLabel->GetContentSize( lW, lT );
|
|
|
|
lT += (m_iTextBorderSpace * 2);
|
|
|
|
vgui::surface()->DrawSetColor( clr );
|
|
vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset + (m_iBarWide * m_flPanelScale), yOffset + (lT /** m_flPanelScale*/) ); //m_iTypeTextT - (yOffset /*+ m_iBarTall*/) );
|
|
} break;
|
|
|
|
case COMMENTARY_TYPE_IMAGE:
|
|
{
|
|
// Figure out the size before setting bounds
|
|
int iW, iT;
|
|
m_pImage->GetSize( iW, iT );
|
|
//vgui::surface()->DrawGetTextureSize( m_pImage->GetImage()->GetID(), iW, iT );
|
|
|
|
iW += (m_iTextBorderSpace * 2);
|
|
iT += (m_iTextBorderSpace * 2);
|
|
|
|
vgui::surface()->DrawSetColor( clr );
|
|
vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset + iW, yOffset + iT ); //m_iTypeTextT - (yOffset /*+ m_iBarTall*/) );
|
|
} break;
|
|
|
|
default:
|
|
case COMMENTARY_TYPE_SCENE:
|
|
case COMMENTARY_TYPE_AUDIO:
|
|
{
|
|
// Draw the progress bar
|
|
vgui::surface()->DrawSetColor( clr );
|
|
vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset+(m_iBarWide*m_flPanelScale), yOffset+m_iBarTall );
|
|
vgui::surface()->DrawSetColor( clr );
|
|
vgui::surface()->DrawFilledRect( xOffset+2, yOffset+2, xOffset+(int)(flPercentage*(m_iBarWide*m_flPanelScale))-2, yOffset+m_iBarTall-2 );
|
|
} break;
|
|
}
|
|
#else
|
|
// Draw the progress bar
|
|
vgui::surface()->DrawSetColor( clr );
|
|
vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset+m_iBarWide, yOffset+m_iBarTall );
|
|
vgui::surface()->DrawSetColor( clr );
|
|
vgui::surface()->DrawFilledRect( xOffset+2, yOffset+2, xOffset+(int)(flPercentage*m_iBarWide)-2, yOffset+m_iBarTall-2 );
|
|
#endif
|
|
|
|
// Draw the speaker names
|
|
vgui::surface()->DrawSetTextFont( m_hFont );
|
|
vgui::surface()->DrawSetTextColor( clr );
|
|
vgui::surface()->DrawSetTextPos( m_iSpeakersX, m_iSpeakersY );
|
|
vgui::surface()->DrawPrintText( m_szSpeakers, wcslen(m_szSpeakers) );
|
|
|
|
if ( COMMENTARY_BUTTONS & IN_ATTACK )
|
|
{
|
|
int iY = m_iBarY + m_iBarTall + YRES(4);
|
|
wchar_t wzFinal[512] = L"";
|
|
|
|
wchar_t *pszText = g_pVGuiLocalize->Find( "#Commentary_PrimaryAttack" );
|
|
if ( pszText )
|
|
{
|
|
UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ) );
|
|
vgui::surface()->DrawSetTextPos( m_iSpeakersX, iY );
|
|
vgui::surface()->DrawPrintText( wzFinal, wcslen(wzFinal) );
|
|
}
|
|
|
|
pszText = g_pVGuiLocalize->Find( "#Commentary_SecondaryAttack" );
|
|
if ( pszText )
|
|
{
|
|
int w, h;
|
|
UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ) );
|
|
vgui::surface()->GetTextSize( m_hFont, wzFinal, w, h );
|
|
vgui::surface()->DrawSetTextPos( m_iBarX + m_iBarWide - w, iY );
|
|
vgui::surface()->DrawPrintText( wzFinal, wcslen(wzFinal) );
|
|
}
|
|
}
|
|
|
|
// Draw the commentary count
|
|
// Determine our text size, and move that far in from the right hand size (plus the offset)
|
|
int iCountWide, iCountTall;
|
|
vgui::surface()->GetTextSize( m_hFont, m_szCount, iCountWide, iCountTall );
|
|
|
|
#ifdef MAPBASE
|
|
if (m_iCommentaryType != COMMENTARY_TYPE_AUDIO && m_iCommentaryType != COMMENTARY_TYPE_SCENE)
|
|
vgui::surface()->DrawSetTextPos( wide - m_iTypeTextCountXFR - iCountWide, tall - m_iTypeTextCountYFB - iCountTall );
|
|
else
|
|
#endif
|
|
vgui::surface()->DrawSetTextPos( wide - m_iCountXFR - iCountWide, m_iCountY );
|
|
|
|
vgui::surface()->DrawPrintText( m_szCount, wcslen( m_szCount ) );
|
|
|
|
// Draw the icon
|
|
vgui::surface()->DrawSetColor( Color(255,170,0,GetAlpha()) );
|
|
vgui::surface()->DrawSetTexture(m_nIconTextureId);
|
|
vgui::surface()->DrawTexturedRect( m_iIconX, m_iIconY, m_iIconWide, m_iIconTall );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
bool CHudCommentary::ShouldDraw()
|
|
{
|
|
return ( m_hActiveNode || GetAlpha() > 0 );
|
|
}
|
|
|
|
#ifdef MAPBASE
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CHudCommentary::PerformLayout()
|
|
{
|
|
BaseClass::PerformLayout();
|
|
|
|
switch (m_iCommentaryType)
|
|
{
|
|
case COMMENTARY_TYPE_TEXT:
|
|
{
|
|
int xOffset = m_iBarX;
|
|
int yOffset = m_iBarY;
|
|
|
|
m_pLabel->SetBounds(
|
|
xOffset + m_iTextBorderSpace, yOffset + m_iTextBorderSpace,
|
|
(float)(m_iBarWide * m_flPanelScale) - m_iTextBorderSpace, GetTall() );
|
|
|
|
// Figure out the size before setting bounds
|
|
int lW, lT;
|
|
m_pLabel->GetContentSize( lW, lT );
|
|
|
|
//lT = (float)lT * m_flPanelScale; // Don't affect height when scaling
|
|
|
|
m_pLabel->SetTall( lT );
|
|
|
|
lW += (float)((m_iTextBorderSpace * 2) + (xOffset * 2));
|
|
lT += (float)((m_iTextBorderSpace * 2) + (yOffset * 2));
|
|
|
|
ResolveBounds( lW, lT );
|
|
} break;
|
|
|
|
case COMMENTARY_TYPE_IMAGE:
|
|
{
|
|
int xOffset = m_iBarX;
|
|
int yOffset = m_iBarY;
|
|
|
|
// Figure out the size before setting bounds
|
|
int iW, iT;
|
|
//m_pImage->GetImage()->GetSize( iW, iT );
|
|
vgui::surface()->DrawGetTextureSize( m_pImage->GetImage()->GetID(), iW, iT );
|
|
if (iW <= 0)
|
|
iW = 1;
|
|
|
|
int iTargetSize = (m_iBarWide - m_iTextBorderSpace);
|
|
iT *= (iTargetSize / iW);
|
|
iW = iTargetSize;
|
|
|
|
iW = (float)iW * m_flPanelScale;
|
|
iT = (float)iT * m_flPanelScale;
|
|
|
|
m_pImage->SetBounds(
|
|
xOffset + m_iTextBorderSpace,
|
|
yOffset + m_iTextBorderSpace,
|
|
iW, iT );
|
|
|
|
iW += (float)((m_iTextBorderSpace * 2) + (xOffset * 2));
|
|
iT += (float)((m_iTextBorderSpace * 2) + (yOffset * 2));
|
|
|
|
ResolveBounds( iW, iT );
|
|
} break;
|
|
|
|
default:
|
|
case COMMENTARY_TYPE_SCENE:
|
|
case COMMENTARY_TYPE_AUDIO:
|
|
break;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Resolves position on screen; Heavily borrows from CHudMessage::XPosition/YPosition
|
|
//-----------------------------------------------------------------------------
|
|
void CHudCommentary::ResolveBounds( int width, int height )
|
|
{
|
|
int xPos;
|
|
int yPos;
|
|
|
|
// ====== X ======
|
|
if ( m_flOverrideX == -1 )
|
|
{
|
|
xPos = (ScreenWidth() - width) * 0.5f;
|
|
}
|
|
else
|
|
{
|
|
if ( m_flOverrideX < 0 )
|
|
xPos = (1.0 + m_flOverrideX) * ScreenWidth() - width; // Align to right
|
|
else
|
|
xPos = m_flOverrideX * (ScreenWidth() - width);
|
|
}
|
|
|
|
// Clamp to edge of screen
|
|
if ( xPos + width > ScreenWidth() )
|
|
xPos = ScreenWidth() - width;
|
|
else if ( xPos < 0 )
|
|
xPos = 0;
|
|
|
|
// ====== Y ======
|
|
if ( m_flOverrideY == -1 )
|
|
{
|
|
yPos = (ScreenHeight() - height) * 0.5f;
|
|
}
|
|
else
|
|
{
|
|
if ( m_flOverrideY < 0 )
|
|
yPos = (1.0 + m_flOverrideY) * ScreenHeight() - height; // Align to bottom
|
|
else
|
|
yPos = m_flOverrideY * (ScreenHeight() - height);
|
|
}
|
|
|
|
// Clamp to edge of screen
|
|
if ( yPos + height > ScreenHeight() )
|
|
yPos = ScreenHeight() - height;
|
|
else if ( yPos < 0 )
|
|
yPos = 0;
|
|
|
|
SetBounds( xPos, yPos, width, height );
|
|
}
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CHudCommentary::Init( void )
|
|
{
|
|
m_matIcon.Init( "vgui/hud/icon_commentary", TEXTURE_GROUP_VGUI );
|
|
|
|
#ifdef MAPBASE
|
|
SetProportional( true );
|
|
#endif
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CHudCommentary::VidInit( void )
|
|
{
|
|
SetAlpha(0);
|
|
StopCommentary();
|
|
#ifdef MAPBASE
|
|
m_iCCDefaultY = 0;
|
|
#endif
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CHudCommentary::StartCommentary( C_PointCommentaryNode *pNode, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime )
|
|
{
|
|
if ( (flEndTime - flStartTime) <= 0 )
|
|
return;
|
|
|
|
m_hActiveNode = pNode;
|
|
m_flStartTime = flStartTime;
|
|
m_flEndTime = flEndTime;
|
|
m_bHiding = false;
|
|
#ifdef MAPBASE
|
|
m_iCommentaryType = COMMENTARY_TYPE_AUDIO;
|
|
m_flPanelScale = pNode->m_flPanelScale;
|
|
m_flOverrideX = pNode->m_flPanelX;
|
|
m_flOverrideY = pNode->m_flPanelY;
|
|
#endif
|
|
g_pVGuiLocalize->ConvertANSIToUnicode( pszSpeakers, m_szSpeakers, sizeof( m_szSpeakers ) );
|
|
|
|
#ifdef MAPBASE
|
|
SetBounds( m_iTypeAudioX, m_iTypeAudioY, m_iTypeAudioW, m_iTypeAudioT );
|
|
SetBgColor( m_bUseScriptBGColor ? m_BGOverrideColor : m_BackgroundColor );
|
|
|
|
m_pLabel->SetPaintEnabled( false );
|
|
m_pImage->SetPaintEnabled( false );
|
|
m_pImage->EvictImage();
|
|
|
|
// Get our scheme and font information
|
|
vgui::HScheme scheme = GetScheme();
|
|
m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" );
|
|
if ( !m_hFont )
|
|
{
|
|
m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" );
|
|
}
|
|
#endif
|
|
|
|
// Don't draw the element itself if closecaptions are on (and captions are always on in non-english mode)
|
|
ConVarRef pCVar( "closecaption" );
|
|
if ( pCVar.IsValid() )
|
|
{
|
|
m_bShouldPaint = ( !pCVar.GetBool() && english.GetBool() );
|
|
}
|
|
else
|
|
{
|
|
m_bShouldPaint = true;
|
|
}
|
|
|
|
#ifdef MAPBASE
|
|
if (!m_bShouldPaint && commentary_audio_element_below_cc.GetBool())
|
|
{
|
|
m_bShouldPaint = true;
|
|
RepositionCloseCaption();
|
|
}
|
|
|
|
if (commentary_combine_speaker_and_printname.GetBool() && pNode && pNode->m_iszPrintName[0] != '\0')
|
|
{
|
|
CombineSpeakerAndPrintName( pNode->m_iszPrintName );
|
|
}
|
|
#endif
|
|
|
|
SetPaintBackgroundEnabled( m_bShouldPaint );
|
|
|
|
char sz[MAX_COUNT_STRING];
|
|
Q_snprintf( sz, sizeof(sz), "%d \\ %d", iNode, iNodeMax );
|
|
g_pVGuiLocalize->ConvertANSIToUnicode( sz, m_szCount, sizeof(m_szCount) );
|
|
|
|
// If the commentary just started, play the commentary fade in.
|
|
if ( fabs(flStartTime - gpGlobals->curtime) < 1.0 )
|
|
{
|
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "ShowCommentary" );
|
|
}
|
|
else
|
|
{
|
|
// We're reloading a savegame that has an active commentary going in it. Don't fade in.
|
|
SetAlpha( 255 );
|
|
}
|
|
}
|
|
|
|
#ifdef MAPBASE
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CHudCommentary::StartTextCommentary( C_PointCommentaryNode *pNode, const char *pszText, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime )
|
|
{
|
|
if ( (flEndTime - flStartTime) <= 0 )
|
|
return;
|
|
|
|
m_hActiveNode = pNode;
|
|
m_flStartTime = flStartTime;
|
|
m_flEndTime = flEndTime;
|
|
m_bHiding = false;
|
|
m_iCommentaryType = COMMENTARY_TYPE_TEXT;
|
|
m_flPanelScale = pNode->m_flPanelScale;
|
|
m_flOverrideX = pNode->m_flPanelX;
|
|
m_flOverrideY = pNode->m_flPanelY;
|
|
g_pVGuiLocalize->ConvertANSIToUnicode( pszSpeakers, m_szSpeakers, sizeof( m_szSpeakers ) );
|
|
|
|
SetBounds( m_iTypeTextX, m_iTypeTextY, m_iTypeTextW, m_iTypeTextT );
|
|
SetBgColor( m_bUseScriptBGColor ? m_BGOverrideColor : m_TextBackgroundColor );
|
|
|
|
// Get our scheme and font information
|
|
vgui::HScheme scheme = GetScheme();
|
|
m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" );
|
|
if ( !m_hFont )
|
|
{
|
|
m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" );
|
|
}
|
|
|
|
m_pLabel->SetText( pszText );
|
|
m_pLabel->SetFont( m_hFont );
|
|
m_pLabel->SetWrap( true );
|
|
m_pLabel->SetPaintEnabled( true );
|
|
m_pLabel->SetPaintBackgroundEnabled( false );
|
|
m_pLabel->SetPaintBorderEnabled( false );
|
|
//m_pLabel->SizeToContents();
|
|
m_pLabel->SetContentAlignment( vgui::Label::a_northwest );
|
|
m_pLabel->SetFgColor( m_TypeTextContentColor );
|
|
|
|
m_pImage->SetPaintEnabled( false );
|
|
m_pImage->EvictImage();
|
|
|
|
m_bShouldPaint = true;
|
|
|
|
if (commentary_combine_speaker_and_printname.GetBool() && pNode && pNode->m_iszPrintName[0] != '\0')
|
|
{
|
|
CombineSpeakerAndPrintName( pNode->m_iszPrintName );
|
|
}
|
|
|
|
SetPaintBackgroundEnabled( m_bShouldPaint );
|
|
|
|
char sz[MAX_COUNT_STRING];
|
|
Q_snprintf( sz, sizeof(sz), "%d \\ %d", iNode, iNodeMax );
|
|
g_pVGuiLocalize->ConvertANSIToUnicode( sz, m_szCount, sizeof(m_szCount) );
|
|
|
|
// If the commentary just started, play the commentary fade in.
|
|
if ( fabs(flStartTime - gpGlobals->curtime) < 1.0 )
|
|
{
|
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "ShowCommentary" );
|
|
}
|
|
else
|
|
{
|
|
// We're reloading a savegame that has an active commentary going in it. Don't fade in.
|
|
SetAlpha( 255 );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CHudCommentary::StartImageCommentary( C_PointCommentaryNode *pNode, const char *pszImage, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime )
|
|
{
|
|
if ( (flEndTime - flStartTime) <= 0 )
|
|
return;
|
|
|
|
m_hActiveNode = pNode;
|
|
m_flStartTime = flStartTime;
|
|
m_flEndTime = flEndTime;
|
|
m_bHiding = false;
|
|
m_iCommentaryType = COMMENTARY_TYPE_IMAGE;
|
|
m_flPanelScale = pNode->m_flPanelScale;
|
|
m_flOverrideX = pNode->m_flPanelX;
|
|
m_flOverrideY = pNode->m_flPanelY;
|
|
g_pVGuiLocalize->ConvertANSIToUnicode( pszSpeakers, m_szSpeakers, sizeof( m_szSpeakers ) );
|
|
|
|
SetBounds( m_iTypeTextX, m_iTypeTextY, m_iTypeTextW, m_iTypeTextT );
|
|
SetBgColor( m_bUseScriptBGColor ? m_BGOverrideColor : m_TextBackgroundColor );
|
|
|
|
m_pLabel->SetPaintEnabled( false );
|
|
|
|
m_pImage->SetPaintEnabled( true );
|
|
m_pImage->SetImage( pszImage );
|
|
m_pImage->SetWide( m_iBarWide - m_iTextBorderSpace );
|
|
|
|
// Get our scheme and font information
|
|
vgui::HScheme scheme = GetScheme();
|
|
m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" );
|
|
if ( !m_hFont )
|
|
{
|
|
m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" );
|
|
}
|
|
|
|
m_bShouldPaint = true;
|
|
|
|
if (commentary_combine_speaker_and_printname.GetBool() && pNode && pNode->m_iszPrintName[0] != '\0')
|
|
{
|
|
CombineSpeakerAndPrintName( pNode->m_iszPrintName );
|
|
}
|
|
|
|
SetPaintBackgroundEnabled( m_bShouldPaint );
|
|
|
|
char sz[MAX_COUNT_STRING];
|
|
Q_snprintf( sz, sizeof(sz), "%d \\ %d", iNode, iNodeMax );
|
|
g_pVGuiLocalize->ConvertANSIToUnicode( sz, m_szCount, sizeof(m_szCount) );
|
|
|
|
// If the commentary just started, play the commentary fade in.
|
|
if ( fabs(flStartTime - gpGlobals->curtime) < 1.0 )
|
|
{
|
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "ShowCommentary" );
|
|
}
|
|
else
|
|
{
|
|
// We're reloading a savegame that has an active commentary going in it. Don't fade in.
|
|
SetAlpha( 255 );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CHudCommentary::StartSceneCommentary( C_PointCommentaryNode *pNode, char *pszSpeakers, int iNode, int iNodeMax, float flStartTime, float flEndTime )
|
|
{
|
|
if ( (flEndTime - flStartTime) <= 0 )
|
|
return;
|
|
|
|
m_hActiveNode = pNode;
|
|
m_flStartTime = flStartTime;
|
|
m_flEndTime = flEndTime;
|
|
m_bHiding = false;
|
|
m_iCommentaryType = COMMENTARY_TYPE_SCENE;
|
|
m_flPanelScale = pNode->m_flPanelScale;
|
|
m_flOverrideX = pNode->m_flPanelX;
|
|
m_flOverrideY = pNode->m_flPanelY;
|
|
g_pVGuiLocalize->ConvertANSIToUnicode( pszSpeakers, m_szSpeakers, sizeof( m_szSpeakers ) );
|
|
|
|
SetBounds( m_iTypeAudioX, m_iTypeAudioY, m_iTypeAudioW, m_iTypeAudioT );
|
|
SetBgColor( m_bUseScriptBGColor ? m_BGOverrideColor : m_BackgroundColor );
|
|
|
|
m_pLabel->SetPaintEnabled( false );
|
|
m_pImage->SetPaintEnabled( false );
|
|
m_pImage->EvictImage();
|
|
|
|
// Get our scheme and font information
|
|
vgui::HScheme scheme = GetScheme();
|
|
m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" );
|
|
if ( !m_hFont )
|
|
{
|
|
m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" );
|
|
}
|
|
|
|
// Don't draw the element itself if closecaptions are on (and captions are always on in non-english mode)
|
|
ConVarRef pCVar( "closecaption" );
|
|
if ( pCVar.IsValid() )
|
|
{
|
|
m_bShouldPaint = ( !pCVar.GetBool() && english.GetBool() );
|
|
}
|
|
else
|
|
{
|
|
m_bShouldPaint = true;
|
|
}
|
|
|
|
if (!m_bShouldPaint && commentary_audio_element_below_cc.GetBool())
|
|
{
|
|
m_bShouldPaint = true;
|
|
RepositionCloseCaption();
|
|
}
|
|
|
|
if (commentary_combine_speaker_and_printname.GetBool() && pNode && pNode->m_iszPrintName[0] != '\0')
|
|
{
|
|
CombineSpeakerAndPrintName( pNode->m_iszPrintName );
|
|
}
|
|
|
|
SetPaintBackgroundEnabled( m_bShouldPaint );
|
|
|
|
char sz[MAX_COUNT_STRING];
|
|
Q_snprintf( sz, sizeof(sz), "%d \\ %d", iNode, iNodeMax );
|
|
g_pVGuiLocalize->ConvertANSIToUnicode( sz, m_szCount, sizeof(m_szCount) );
|
|
|
|
// If the commentary just started, play the commentary fade in.
|
|
if ( fabs(flStartTime - gpGlobals->curtime) < 1.0 )
|
|
{
|
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "ShowCommentary" );
|
|
}
|
|
else
|
|
{
|
|
// We're reloading a savegame that has an active commentary going in it. Don't fade in.
|
|
SetAlpha( 255 );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CHudCommentary::StopCommentary( void )
|
|
{
|
|
m_hActiveNode = NULL;
|
|
|
|
#ifdef MAPBASE
|
|
// Reset close caption element if needed
|
|
CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption );
|
|
if (pHudCloseCaption && pHudCloseCaption->IsUsingCommentaryDimensions())
|
|
{
|
|
int ccX, ccY;
|
|
pHudCloseCaption->GetPos( ccX, ccY );
|
|
//pHudCloseCaption->SetPos( ccX, ccY + m_iTypeAudioT );
|
|
|
|
// Run this animation command instead of setting the position directly
|
|
g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( pHudCloseCaption, "YPos", ccY + m_iTypeAudioT, 0.0f, 0.4f, vgui::AnimationController::INTERPOLATOR_ACCEL );
|
|
|
|
pHudCloseCaption->SetUsingCommentaryDimensions( false );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#ifdef MAPBASE
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CHudCommentary::CombineSpeakerAndPrintName( const char *pszPrintName )
|
|
{
|
|
wchar_t *pszLocal = g_pVGuiLocalize->Find( pszPrintName );
|
|
if (m_szSpeakers[0] == '\0' || !m_bShouldPaint) // Use m_bShouldPaint as an indicator of whether or not we use subtitles
|
|
{
|
|
if (pszPrintName[0] == '#' && pszLocal)
|
|
wcsncpy( m_szSpeakers, pszLocal, sizeof( m_szSpeakers ) / sizeof( wchar_t ) );
|
|
else
|
|
g_pVGuiLocalize->ConvertANSIToUnicode( pszPrintName, m_szSpeakers, sizeof( m_szSpeakers ) );
|
|
}
|
|
else
|
|
{
|
|
static wchar_t iszPrintNameLocalized[MAX_SPEAKER_NAME];
|
|
|
|
if (pszPrintName[0] == '#' && pszLocal)
|
|
wcsncpy( iszPrintNameLocalized, pszLocal, sizeof( iszPrintNameLocalized ) / sizeof( wchar_t ) );
|
|
else
|
|
g_pVGuiLocalize->ConvertANSIToUnicode( pszPrintName, iszPrintNameLocalized, sizeof( iszPrintNameLocalized ) );
|
|
|
|
V_snwprintf( m_szSpeakers, sizeof( m_szSpeakers ), L"%ls ~ %ls", m_szSpeakers, iszPrintNameLocalized );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CHudCommentary::RepositionCloseCaption()
|
|
{
|
|
// Invert the Y axis
|
|
//SetPos( m_iTypeAudioX, ScreenHeight() - m_iTypeAudioY );
|
|
|
|
// Place underneath the close caption element
|
|
CHudCloseCaption *pHudCloseCaption = (CHudCloseCaption *)GET_HUDELEMENT( CHudCloseCaption );
|
|
if (pHudCloseCaption /*&& !pHudCloseCaption->IsUsingCommentaryDimensions()*/)
|
|
{
|
|
int ccX, ccY;
|
|
pHudCloseCaption->GetPos( ccX, ccY );
|
|
|
|
// Save the default position in case we need to do a hard reset
|
|
// (this usually happens when players begin commentary before the CC element's return animation command is finished)
|
|
if (m_iCCDefaultY == 0)
|
|
{
|
|
m_iCCDefaultY = ccY;
|
|
}
|
|
|
|
if (!pHudCloseCaption->IsUsingCommentaryDimensions())
|
|
{
|
|
if (m_iCCDefaultY != ccY && !pHudCloseCaption->IsUsingCommentaryDimensions())
|
|
{
|
|
DevMsg( "CHudCommentary had to reset misaligned CC element Y (%i) to default Y (%i)\n", ccY, m_iCCDefaultY );
|
|
ccY = m_iCCDefaultY;
|
|
}
|
|
|
|
ccY -= m_iTypeAudioT;
|
|
|
|
// Run this animation command instead of setting the position directly
|
|
g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( pHudCloseCaption, "YPos", ccY, 0.0f, 0.2f, vgui::AnimationController::INTERPOLATOR_DEACCEL );
|
|
//pHudCloseCaption->SetPos( ccX, ccY );
|
|
|
|
pHudCloseCaption->SetUsingCommentaryDimensions( true );
|
|
}
|
|
|
|
SetPos( ccX, ccY + pHudCloseCaption->GetTall() + commentary_audio_element_below_cc_margin.GetInt() );
|
|
|
|
m_flPanelScale = (float)pHudCloseCaption->GetWide() / (float)GetWide();
|
|
SetWide( pHudCloseCaption->GetWide() );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
bool CommentaryModeShouldSwallowInput( C_BasePlayer *pPlayer )
|
|
{
|
|
if ( !IsInCommentaryMode() )
|
|
return false;
|
|
|
|
if ( pPlayer->m_nButtons & COMMENTARY_BUTTONS )
|
|
{
|
|
// Always steal the secondary attack
|
|
if ( pPlayer->m_nButtons & IN_ATTACK2 )
|
|
return true;
|
|
|
|
// See if there's any nodes ahead of us.
|
|
if ( IsNodeUnderCrosshair( pPlayer ) )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
} |