From 20f29c555218d0748b5a32359b9e45db1e44ef55 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Sat, 17 Jul 2021 00:32:56 -0500 Subject: [PATCH 1/4] Added prototype for a new type of commentary node which displays text instead of playing audio --- .../game/client/c_point_commentary_node.cpp | 305 ++++++++++++++---- sp/src/game/server/CommentarySystem.cpp | 10 + 2 files changed, 254 insertions(+), 61 deletions(-) diff --git a/sp/src/game/client/c_point_commentary_node.cpp b/sp/src/game/client/c_point_commentary_node.cpp index 47ea96ef..a24973a8 100644 --- a/sp/src/game/client/c_point_commentary_node.cpp +++ b/sp/src/game/client/c_point_commentary_node.cpp @@ -18,6 +18,9 @@ #include "convar.h" #include "hud_closecaption.h" #include "in_buttons.h" +#ifdef MAPBASE +#include "vgui_controls/Label.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -37,6 +40,11 @@ bool IsInCommentaryMode( void ) static bool g_bTracingVsCommentaryNodes = false; +#ifdef MAPBASE +ConVar commentary_text_force( "commentary_text_force", "0", FCVAR_NONE, "Forces all commentary nodes to use the text type." ); +ConVar commentary_text_endtime( "commentary_text_endtime", "120" ); +#endif + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -52,6 +60,9 @@ public: 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 ); +#endif void StopCommentary( void ); bool IsTheActiveNode( C_PointCommentaryNode *pNode ) { return (pNode == m_hActiveNode); } @@ -68,6 +79,11 @@ private: wchar_t m_szCount[MAX_COUNT_STRING]; CMaterialReference m_matIcon; bool m_bHiding; +#ifdef MAPBASE + bool m_bTextCommentary; // NOTE: If any more types are needed, use an enum + wchar_t *m_pszText; + vgui::Label *m_pLabel; +#endif // Painting CPanelAnimationVarAliasType( int, m_iBarX, "bar_xpos", "8", "proportional_int" ); @@ -84,8 +100,27 @@ private: 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_iTypeTextCountY, "type_text_count_ypos", "184", "proportional_int" ); + CPanelAnimationVar( Color, m_TextBackgroundColor, "type_text_bg", "0 0 0 192" ); + CPanelAnimationVar( Color, m_TextColor, "type_text_fg", "255 230 180 255" ); +#endif + CPanelAnimationVar( bool, m_bUseScriptBGColor, "use_script_bgcolor", "0" ); +#ifdef MAPBASE + CPanelAnimationVar( Color, m_BackgroundColor, "BackgroundColor", "Panel.BgColor" ); +#else CPanelAnimationVar( Color, m_BackgroundColor, "BackgroundColor", "0 0 0 0" ); +#endif CPanelAnimationVar( Color, m_BGOverrideColor, "BackgroundOverrideColor", "Panel.BgColor" ); }; @@ -102,6 +137,11 @@ public: 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 ); +#endif + void OnRestore( void ) { BaseClass::OnRestore(); @@ -181,6 +221,9 @@ public: CSoundPatch *m_sndCommentary; EHANDLE m_hViewPosition; bool m_bRestartAfterRestore; +#ifdef MAPBASE + bool m_bTextCommentary; +#endif }; IMPLEMENT_CLIENTCLASS_DT(C_PointCommentaryNode, DT_PointCommentaryNode, CPointCommentaryNode) @@ -192,6 +235,9 @@ IMPLEMENT_CLIENTCLASS_DT(C_PointCommentaryNode, DT_PointCommentaryNode, CPointCo RecvPropInt( RECVINFO( m_iNodeNumber ) ), RecvPropInt( RECVINFO( m_iNodeNumberMax ) ), RecvPropEHandle( RECVINFO(m_hViewPosition) ), +#ifdef MAPBASE + RecvPropBool( RECVINFO( m_bTextCommentary ) ), +#endif END_RECV_TABLE() BEGIN_DATADESC( C_PointCommentaryNode ) @@ -245,58 +291,12 @@ void C_PointCommentaryNode::OnDataChanged( DataUpdateType_t updateType ) return; } - 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; - } +#ifdef MAPBASE + if (m_bTextCommentary || commentary_text_force.GetBool()) + StartTextCommentary( pszCommentaryFile, pPlayer ); 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 ) ) ) ; - - 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(); - } - } - - // Tell the HUD element - CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary ); - pHudCommentary->StartCommentary( this, m_iszSpeakers, m_iNodeNumber, m_iNodeNumberMax, m_flStartTime, m_flStartTime + flDuration ); +#endif + StartAudioCommentary( pszCommentaryFile, pPlayer ); } else if ( m_bWasActive ) { @@ -312,6 +312,83 @@ void C_PointCommentaryNode::OnDataChanged( DataUpdateType_t updateType ) 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 ) ) ) ; + + 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(); + } + } + + // Tell the HUD element + CHudCommentary *pHudCommentary = (CHudCommentary *)GET_HUDELEMENT( CHudCommentary ); + pHudCommentary->StartCommentary( this, m_iszSpeakers, 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_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 ); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Shut down the commentary //----------------------------------------------------------------------------- @@ -374,6 +451,10 @@ CHudCommentary::CHudCommentary( const char *name ) : vgui::Panel( NULL, "HudComm m_hActiveNode = NULL; m_bShouldPaint = true; + +#ifdef MAPBASE + m_pLabel = new vgui::Label( this, "HudCommentaryTextLabel", "" ); +#endif } void CHudCommentary::ApplySchemeSettings( vgui::IScheme *pScheme ) @@ -384,6 +465,11 @@ void CHudCommentary::ApplySchemeSettings( vgui::IScheme *pScheme ) { SetBgColor( m_BGOverrideColor ); } + +#ifdef MAPBASE + m_pLabel->SetPaintBackgroundType( 2 ); + m_pLabel->SetSize( 0, GetTall() ); +#endif } //----------------------------------------------------------------------------- @@ -426,19 +512,12 @@ void CHudCommentary::Paint() int x, y, wide, tall; GetBounds( x, y, wide, tall ); - int xOffset = m_iBarX; + int xOffset = m_iBarX; int yOffset = m_iBarY; // Find our fade based on our time shown Color clr = Color( 255, 170, 0, GetAlpha() ); - // 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 ); - - // Draw the speaker names // Get our scheme and font information vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" ); @@ -446,6 +525,34 @@ void CHudCommentary::Paint() { hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" ); } + +#ifdef MAPBASE + if (m_bTextCommentary) + { + vgui::surface()->DrawSetColor( clr ); + vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset + m_iBarWide, m_iTypeTextT - (yOffset + m_iBarTall) ); + + m_pLabel->SetFgColor( m_TextColor ); + m_pLabel->SetBounds( xOffset + 4, yOffset + 4, m_iBarWide - 4, m_iTypeTextT - (m_iBarTall + 4) ); + m_pLabel->SetFont( hFont ); + + // Draw the speaker names + /*vgui::surface()->DrawSetTextFont( hFont ); + vgui::surface()->DrawSetTextColor( Color( 255, 200, 100, GetAlpha() ) ); + vgui::surface()->DrawSetTextPos( xOffset+4, yOffset+4 ); + vgui::surface()->DrawPrintText( m_pszText, wcslen( m_pszText ) );*/ + } + else +#endif + { + // 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 ); + } + + // Draw the speaker names vgui::surface()->DrawSetTextFont( hFont ); vgui::surface()->DrawSetTextColor( clr ); vgui::surface()->DrawSetTextPos( m_iSpeakersX, m_iSpeakersY ); @@ -479,8 +586,15 @@ void CHudCommentary::Paint() // Determine our text size, and move that far in from the right hand size (plus the offset) int iCountWide, iCountTall; vgui::surface()->GetTextSize( hFont, m_szCount, iCountWide, iCountTall ); + +#ifdef MAPBASE + if (m_bTextCommentary) + vgui::surface()->DrawSetTextPos( wide - m_iTypeTextCountXFR - iCountWide, m_iTypeTextCountY ); + else +#endif vgui::surface()->DrawSetTextPos( wide - m_iCountXFR - iCountWide, m_iCountY ); - vgui::surface()->DrawPrintText( m_szCount, wcslen(m_szCount) ); + + vgui::surface()->DrawPrintText( m_szCount, wcslen( m_szCount ) ); // Draw the icon vgui::surface()->DrawSetColor( Color(255,170,0,GetAlpha()) ); @@ -525,7 +639,17 @@ void CHudCommentary::StartCommentary( C_PointCommentaryNode *pNode, char *pszSpe m_flStartTime = flStartTime; m_flEndTime = flEndTime; m_bHiding = false; - g_pVGuiLocalize->ConvertANSIToUnicode( pszSpeakers, m_szSpeakers, sizeof(m_szSpeakers) ); +#ifdef MAPBASE + m_bTextCommentary = false; +#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 ); +#endif // Don't draw the element itself if closecaptions are on (and captions are always on in non-english mode) ConVarRef pCVar( "closecaption" ); @@ -555,6 +679,65 @@ void CHudCommentary::StartCommentary( C_PointCommentaryNode *pNode, char *pszSpe } } +#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_bTextCommentary = true; + 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->SetText( pszText ); + 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 ); + + /* + // Find a localization token first. + // If one isn't found, use this static buffer. + static wchar_t szRawTextBuf[512]; + m_pszText = g_pVGuiLocalize->Find( pszText ); + if (!m_pszText) + { + g_pVGuiLocalize->ConvertANSIToUnicode( pszText, szRawTextBuf, sizeof( szRawTextBuf ) ); + m_pszText = szRawTextBuf; + } + */ + + m_bShouldPaint = true; + 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: //----------------------------------------------------------------------------- diff --git a/sp/src/game/server/CommentarySystem.cpp b/sp/src/game/server/CommentarySystem.cpp index 4d010151..23a8a5b8 100644 --- a/sp/src/game/server/CommentarySystem.cpp +++ b/sp/src/game/server/CommentarySystem.cpp @@ -138,6 +138,10 @@ private: CNetworkVar( string_t, m_iszSpeakers ); CNetworkVar( int, m_iNodeNumber ); CNetworkVar( int, m_iNodeNumberMax ); + +#ifdef MAPBASE + CNetworkVar( bool, m_bTextCommentary ); +#endif }; BEGIN_DATADESC( CPointCommentaryNode ) @@ -166,6 +170,9 @@ BEGIN_DATADESC( CPointCommentaryNode ) DEFINE_FIELD( m_bPreventChangesWhileMoving, FIELD_BOOLEAN ), DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "start_disabled" ), DEFINE_KEYFIELD( m_vecTeleportOrigin, FIELD_VECTOR, "teleport_origin" ), +#ifdef MAPBASE + DEFINE_KEYFIELD( m_bTextCommentary, FIELD_BOOLEAN, "type" ), // Open to additional types in the future +#endif // Outputs DEFINE_OUTPUT( m_pOnCommentaryStarted, "OnCommentaryStarted" ), @@ -192,6 +199,9 @@ IMPLEMENT_SERVERCLASS_ST( CPointCommentaryNode, DT_PointCommentaryNode ) SendPropInt( SENDINFO(m_iNodeNumber), 8, SPROP_UNSIGNED ), SendPropInt( SENDINFO(m_iNodeNumberMax), 8, SPROP_UNSIGNED ), SendPropEHandle( SENDINFO(m_hViewPosition) ), +#ifdef MAPBASE + SendPropBool( SENDINFO( m_bTextCommentary ) ), +#endif END_SEND_TABLE() LINK_ENTITY_TO_CLASS( point_commentary_node, CPointCommentaryNode ); From f67a1b95e53b84a477adeee0457d37a68ea18676 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Sat, 17 Jul 2021 03:58:09 -0500 Subject: [PATCH 2/4] Updated text commentary nodes --- .../game/client/c_point_commentary_node.cpp | 44 +++++++++++-------- sp/src/game/server/CommentarySystem.cpp | 5 +++ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/sp/src/game/client/c_point_commentary_node.cpp b/sp/src/game/client/c_point_commentary_node.cpp index a24973a8..b59cf253 100644 --- a/sp/src/game/client/c_point_commentary_node.cpp +++ b/sp/src/game/client/c_point_commentary_node.cpp @@ -110,7 +110,7 @@ private: 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_iTypeTextCountY, "type_text_count_ypos", "184", "proportional_int" ); + CPanelAnimationVarAliasType( int, m_iTypeTextCountYFB, "type_text_count_ypos_from_bottom", "16", "proportional_int" ); CPanelAnimationVar( Color, m_TextBackgroundColor, "type_text_bg", "0 0 0 192" ); CPanelAnimationVar( Color, m_TextColor, "type_text_fg", "255 230 180 255" ); #endif @@ -380,7 +380,7 @@ void C_PointCommentaryNode::StartTextCommentary( const char *pszCommentaryFile, // Get the duration so we know when it finishes //float flDuration = enginesound->GetSoundDuration( STRING( CSoundEnvelopeController::GetController().SoundGetName( m_sndCommentary ) ) ) ; - // TODO: Determine from text length + // TODO: Determine from text length? float flDuration = commentary_text_endtime.GetFloat(); // Tell the HUD element @@ -529,11 +529,19 @@ void CHudCommentary::Paint() #ifdef MAPBASE if (m_bTextCommentary) { - vgui::surface()->DrawSetColor( clr ); - vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset + m_iBarWide, m_iTypeTextT - (yOffset + m_iBarTall) ); + // TODO: Make this a control? + static int iTextBorderSpace = 8; + + // Figure out the size before setting bounds + int lW, lT; + m_pLabel->GetContentSize( lW, lT ); m_pLabel->SetFgColor( m_TextColor ); - m_pLabel->SetBounds( xOffset + 4, yOffset + 4, m_iBarWide - 4, m_iTypeTextT - (m_iBarTall + 4) ); + m_pLabel->SetBounds( + xOffset + iTextBorderSpace, + yOffset + iTextBorderSpace, + m_iBarWide - iTextBorderSpace, + lT /*m_iTypeTextT - ((yOffset * 2) + iTextBorderSpace)*/ ); m_pLabel->SetFont( hFont ); // Draw the speaker names @@ -541,6 +549,14 @@ void CHudCommentary::Paint() vgui::surface()->DrawSetTextColor( Color( 255, 200, 100, GetAlpha() ) ); vgui::surface()->DrawSetTextPos( xOffset+4, yOffset+4 ); vgui::surface()->DrawPrintText( m_pszText, wcslen( m_pszText ) );*/ + + lT += (iTextBorderSpace * 2); + + vgui::surface()->DrawSetColor( clr ); + vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset + m_iBarWide, yOffset + lT ); //m_iTypeTextT - (yOffset /*+ m_iBarTall*/) ); + + lT += (yOffset * 2); + SetBounds( x, ( (float)m_iTypeTextT * MAX( (200.0f / (float)lT), 1.75f ) ), wide, lT ); } else #endif @@ -589,7 +605,7 @@ void CHudCommentary::Paint() #ifdef MAPBASE if (m_bTextCommentary) - vgui::surface()->DrawSetTextPos( wide - m_iTypeTextCountXFR - iCountWide, m_iTypeTextCountY ); + vgui::surface()->DrawSetTextPos( wide - m_iTypeTextCountXFR - iCountWide, tall - m_iTypeTextCountYFB - iCountTall ); else #endif vgui::surface()->DrawSetTextPos( wide - m_iCountXFR - iCountWide, m_iCountY ); @@ -616,6 +632,10 @@ bool CHudCommentary::ShouldDraw() void CHudCommentary::Init( void ) { m_matIcon.Init( "vgui/hud/icon_commentary", TEXTURE_GROUP_VGUI ); + +#ifdef MAPBASE + SetProportional( true ); +#endif } //----------------------------------------------------------------------------- @@ -706,18 +726,6 @@ void CHudCommentary::StartTextCommentary( C_PointCommentaryNode *pNode, const ch //m_pLabel->SizeToContents(); m_pLabel->SetContentAlignment( vgui::Label::a_northwest ); - /* - // Find a localization token first. - // If one isn't found, use this static buffer. - static wchar_t szRawTextBuf[512]; - m_pszText = g_pVGuiLocalize->Find( pszText ); - if (!m_pszText) - { - g_pVGuiLocalize->ConvertANSIToUnicode( pszText, szRawTextBuf, sizeof( szRawTextBuf ) ); - m_pszText = szRawTextBuf; - } - */ - m_bShouldPaint = true; SetPaintBackgroundEnabled( m_bShouldPaint ); diff --git a/sp/src/game/server/CommentarySystem.cpp b/sp/src/game/server/CommentarySystem.cpp index 23a8a5b8..6c435d3f 100644 --- a/sp/src/game/server/CommentarySystem.cpp +++ b/sp/src/game/server/CommentarySystem.cpp @@ -905,6 +905,11 @@ void CPointCommentaryNode::Spawn( void ) char *szModel = (char *)STRING( GetModelName() ); if (!szModel || !*szModel) { +#ifdef MAPBASE + if (m_bTextCommentary) + szModel = "models/extras/info_text.mdl"; + else +#endif szModel = "models/extras/info_speech.mdl"; SetModelName( AllocPooledString(szModel) ); } From 3ab83ba1c2bf98e610ea1bf77bf2fa6a7cd54144 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Sun, 18 Jul 2021 01:27:33 -0500 Subject: [PATCH 3/4] Added image commentary nodes and better scaling/positioning for the text commentary panel --- .../game/client/c_point_commentary_node.cpp | 377 +++++++++++++++--- sp/src/game/server/CommentarySystem.cpp | 45 ++- sp/src/game/shared/shareddefs.h | 11 + 3 files changed, 366 insertions(+), 67 deletions(-) diff --git a/sp/src/game/client/c_point_commentary_node.cpp b/sp/src/game/client/c_point_commentary_node.cpp index b59cf253..bfef3c0a 100644 --- a/sp/src/game/client/c_point_commentary_node.cpp +++ b/sp/src/game/client/c_point_commentary_node.cpp @@ -20,6 +20,7 @@ #include "in_buttons.h" #ifdef MAPBASE #include "vgui_controls/Label.h" +#include "vgui_controls/ImagePanel.h" #endif // memdbgon must be the last include file in a .cpp file!!! @@ -41,8 +42,9 @@ bool IsInCommentaryMode( void ) static bool g_bTracingVsCommentaryNodes = false; #ifdef MAPBASE -ConVar commentary_text_force( "commentary_text_force", "0", FCVAR_NONE, "Forces all commentary nodes to use the text type." ); -ConVar commentary_text_endtime( "commentary_text_endtime", "120" ); +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" ); #endif //----------------------------------------------------------------------------- @@ -62,6 +64,7 @@ public: 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 ); #endif void StopCommentary( void ); bool IsTheActiveNode( C_PointCommentaryNode *pNode ) { return (pNode == m_hActiveNode); } @@ -69,6 +72,10 @@ public: // vgui overrides virtual void Paint( void ); virtual bool ShouldDraw( void ); +#ifdef MAPBASE + virtual void PerformLayout(); + void ResolveBounds( int width, int height ); +#endif private: CHandle m_hActiveNode; @@ -80,9 +87,14 @@ private: CMaterialReference m_matIcon; bool m_bHiding; #ifdef MAPBASE - bool m_bTextCommentary; // NOTE: If any more types are needed, use an enum - wchar_t *m_pszText; + int m_iCommentaryType; + float m_flPanelScale; + float m_flOverrideX; + float m_flOverrideY; + vgui::Label *m_pLabel; + vgui::ImagePanel *m_pImage; + vgui::HFont m_hFont; #endif // Painting @@ -110,14 +122,16 @@ private: 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", "16", "proportional_int" ); - CPanelAnimationVar( Color, m_TextBackgroundColor, "type_text_bg", "0 0 0 192" ); - CPanelAnimationVar( Color, m_TextColor, "type_text_fg", "255 230 180 255" ); + CPanelAnimationVarAliasType( int, m_iTypeTextCountYFB, "type_text_count_ypos_from_bottom", "10", "proportional_int" ); + CPanelAnimationVar( Color, m_TextBackgroundColor, "BackgroundColorTextContent", "0 0 0 192" ); + 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 @@ -140,6 +154,7 @@ public: 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 ); #endif void OnRestore( void ) @@ -222,7 +237,10 @@ public: EHANDLE m_hViewPosition; bool m_bRestartAfterRestore; #ifdef MAPBASE - bool m_bTextCommentary; + int m_iCommentaryType; + float m_flPanelScale; + float m_flPanelX; + float m_flPanelY; #endif }; @@ -236,7 +254,10 @@ IMPLEMENT_CLIENTCLASS_DT(C_PointCommentaryNode, DT_PointCommentaryNode, CPointCo RecvPropInt( RECVINFO( m_iNodeNumberMax ) ), RecvPropEHandle( RECVINFO(m_hViewPosition) ), #ifdef MAPBASE - RecvPropBool( RECVINFO( m_bTextCommentary ) ), + RecvPropInt( RECVINFO( m_iCommentaryType ) ), + RecvPropFloat( RECVINFO( m_flPanelScale ) ), + RecvPropFloat( RECVINFO( m_flPanelX ) ), + RecvPropFloat( RECVINFO( m_flPanelY ) ), #endif END_RECV_TABLE() @@ -292,11 +313,28 @@ void C_PointCommentaryNode::OnDataChanged( DataUpdateType_t updateType ) } #ifdef MAPBASE - if (m_bTextCommentary || commentary_text_force.GetBool()) - StartTextCommentary( pszCommentaryFile, pPlayer ); - else + 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; + + default: + case COMMENTARY_TYPE_AUDIO: + StartAudioCommentary( pszCommentaryFile, pPlayer ); + break; + } +#else + StartAudioCommentary( pszCommentaryFile, pPlayer ); #endif - StartAudioCommentary( pszCommentaryFile, pPlayer ); } else if ( m_bWasActive ) { @@ -381,12 +419,27 @@ void C_PointCommentaryNode::StartTextCommentary( const char *pszCommentaryFile, //float flDuration = enginesound->GetSoundDuration( STRING( CSoundEnvelopeController::GetController().SoundGetName( m_sndCommentary ) ) ) ; // TODO: Determine from text length? - float flDuration = commentary_text_endtime.GetFloat(); + 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 ); +} #endif //----------------------------------------------------------------------------- @@ -454,6 +507,8 @@ CHudCommentary::CHudCommentary( const char *name ) : vgui::Panel( NULL, "HudComm #ifdef MAPBASE m_pLabel = new vgui::Label( this, "HudCommentaryTextLabel", "" ); + m_pImage = new vgui::ImagePanel( this, "HudCommentaryImagePanel" ); + m_pImage->SetShouldScaleImage( true ); #endif } @@ -516,60 +571,57 @@ void CHudCommentary::Paint() int yOffset = m_iBarY; // Find our fade based on our time shown - Color clr = Color( 255, 170, 0, GetAlpha() ); - - // Get our scheme and font information - vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); - vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" ); - if ( !hFont ) - { - hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" ); - } + Color clr = m_ForegroundColor; #ifdef MAPBASE - if (m_bTextCommentary) + switch (m_iCommentaryType) { - // TODO: Make this a control? - static int iTextBorderSpace = 8; + case COMMENTARY_TYPE_TEXT: + { + // Figure out the size before setting bounds + int lW, lT; + m_pLabel->GetContentSize( lW, lT ); - // Figure out the size before setting bounds - int lW, lT; - m_pLabel->GetContentSize( lW, lT ); + lT += (m_iTextBorderSpace * 2); - m_pLabel->SetFgColor( m_TextColor ); - m_pLabel->SetBounds( - xOffset + iTextBorderSpace, - yOffset + iTextBorderSpace, - m_iBarWide - iTextBorderSpace, - lT /*m_iTypeTextT - ((yOffset * 2) + iTextBorderSpace)*/ ); - m_pLabel->SetFont( hFont ); + vgui::surface()->DrawSetColor( clr ); + vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset + (m_iBarWide * m_flPanelScale), yOffset + (lT /** m_flPanelScale*/) ); //m_iTypeTextT - (yOffset /*+ m_iBarTall*/) ); + } break; - // Draw the speaker names - /*vgui::surface()->DrawSetTextFont( hFont ); - vgui::surface()->DrawSetTextColor( Color( 255, 200, 100, GetAlpha() ) ); - vgui::surface()->DrawSetTextPos( xOffset+4, yOffset+4 ); - vgui::surface()->DrawPrintText( m_pszText, wcslen( m_pszText ) );*/ + 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 ); - lT += (iTextBorderSpace * 2); + iW += (m_iTextBorderSpace * 2); + iT += (m_iTextBorderSpace * 2); - vgui::surface()->DrawSetColor( clr ); - vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset + m_iBarWide, yOffset + lT ); //m_iTypeTextT - (yOffset /*+ m_iBarTall*/) ); + vgui::surface()->DrawSetColor( clr ); + vgui::surface()->DrawOutlinedRect( xOffset, yOffset, xOffset + iW, yOffset + iT ); //m_iTypeTextT - (yOffset /*+ m_iBarTall*/) ); + } break; - lT += (yOffset * 2); - SetBounds( x, ( (float)m_iTypeTextT * MAX( (200.0f / (float)lT), 1.75f ) ), wide, lT ); + default: + case COMMENTARY_TYPE_AUDIO: + { + // 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 ); + } break; } - else +#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 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 ); - } // Draw the speaker names - vgui::surface()->DrawSetTextFont( hFont ); + vgui::surface()->DrawSetTextFont( m_hFont ); vgui::surface()->DrawSetTextColor( clr ); vgui::surface()->DrawSetTextPos( m_iSpeakersX, m_iSpeakersY ); vgui::surface()->DrawPrintText( m_szSpeakers, wcslen(m_szSpeakers) ); @@ -592,7 +644,7 @@ void CHudCommentary::Paint() { int w, h; UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ) ); - vgui::surface()->GetTextSize( hFont, wzFinal, w, h ); + vgui::surface()->GetTextSize( m_hFont, wzFinal, w, h ); vgui::surface()->DrawSetTextPos( m_iBarX + m_iBarWide - w, iY ); vgui::surface()->DrawPrintText( wzFinal, wcslen(wzFinal) ); } @@ -601,10 +653,10 @@ void CHudCommentary::Paint() // 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( hFont, m_szCount, iCountWide, iCountTall ); + vgui::surface()->GetTextSize( m_hFont, m_szCount, iCountWide, iCountTall ); #ifdef MAPBASE - if (m_bTextCommentary) + if (m_iCommentaryType != COMMENTARY_TYPE_AUDIO) vgui::surface()->DrawSetTextPos( wide - m_iTypeTextCountXFR - iCountWide, tall - m_iTypeTextCountYFB - iCountTall ); else #endif @@ -626,6 +678,128 @@ 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; + + int x, y, wide, tall; + GetBounds( x, y, wide, tall ); + + // Figure out the size before setting bounds + int lW, lT; + m_pLabel->GetContentSize( lW, lT ); + + lW = (float)(m_iBarWide * m_flPanelScale) - m_iTextBorderSpace; + //lT = (float)lT * m_flPanelScale; // Don't affect height when scaling + + m_pLabel->SetBounds( + xOffset + m_iTextBorderSpace, + yOffset + m_iTextBorderSpace, + lW, 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_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: //----------------------------------------------------------------------------- @@ -660,7 +834,10 @@ void CHudCommentary::StartCommentary( C_PointCommentaryNode *pNode, char *pszSpe m_flEndTime = flEndTime; m_bHiding = false; #ifdef MAPBASE - m_bTextCommentary = false; + 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 ) ); @@ -669,6 +846,16 @@ void CHudCommentary::StartCommentary( C_PointCommentaryNode *pNode, char *pszSpe 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 = vgui::scheme()->GetScheme( "ClientScheme" ); + 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) @@ -712,19 +899,89 @@ void CHudCommentary::StartTextCommentary( C_PointCommentaryNode *pNode, const ch m_flStartTime = flStartTime; m_flEndTime = flEndTime; m_bHiding = false; - m_bTextCommentary = true; + 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 = vgui::scheme()->GetScheme( "ClientScheme" ); + 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; + 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 = vgui::scheme()->GetScheme( "ClientScheme" ); + m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" ); + if ( !m_hFont ) + { + m_hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" ); + } m_bShouldPaint = true; SetPaintBackgroundEnabled( m_bShouldPaint ); diff --git a/sp/src/game/server/CommentarySystem.cpp b/sp/src/game/server/CommentarySystem.cpp index 6c435d3f..906c9daf 100644 --- a/sp/src/game/server/CommentarySystem.cpp +++ b/sp/src/game/server/CommentarySystem.cpp @@ -74,6 +74,15 @@ public: DECLARE_DATADESC(); DECLARE_SERVERCLASS(); + CPointCommentaryNode() + { +#ifdef MAPBASE + m_flPanelScale = 1.0f; + m_flPanelX = -1.0f; + m_flPanelY = -1.0f; +#endif + } + void Spawn( void ); void Precache( void ); void Activate( void ); @@ -140,7 +149,10 @@ private: CNetworkVar( int, m_iNodeNumberMax ); #ifdef MAPBASE - CNetworkVar( bool, m_bTextCommentary ); + CNetworkVar( int, m_iCommentaryType ); + CNetworkVar( float, m_flPanelScale ); + CNetworkVar( float, m_flPanelX ); + CNetworkVar( float, m_flPanelY ); #endif }; @@ -171,7 +183,10 @@ BEGIN_DATADESC( CPointCommentaryNode ) DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "start_disabled" ), DEFINE_KEYFIELD( m_vecTeleportOrigin, FIELD_VECTOR, "teleport_origin" ), #ifdef MAPBASE - DEFINE_KEYFIELD( m_bTextCommentary, FIELD_BOOLEAN, "type" ), // Open to additional types in the future + DEFINE_KEYFIELD( m_iCommentaryType, FIELD_INTEGER, "type" ), + DEFINE_KEYFIELD( m_flPanelScale, FIELD_FLOAT, "panelscale" ), + DEFINE_KEYFIELD( m_flPanelX, FIELD_FLOAT, "x" ), + DEFINE_KEYFIELD( m_flPanelY, FIELD_FLOAT, "y" ), #endif // Outputs @@ -200,7 +215,10 @@ IMPLEMENT_SERVERCLASS_ST( CPointCommentaryNode, DT_PointCommentaryNode ) SendPropInt( SENDINFO(m_iNodeNumberMax), 8, SPROP_UNSIGNED ), SendPropEHandle( SENDINFO(m_hViewPosition) ), #ifdef MAPBASE - SendPropBool( SENDINFO( m_bTextCommentary ) ), + SendPropInt( SENDINFO( m_iCommentaryType ), 2, SPROP_UNSIGNED ), + SendPropFloat( SENDINFO( m_flPanelScale ) ), + SendPropFloat( SENDINFO( m_flPanelX ) ), + SendPropFloat( SENDINFO( m_flPanelY ) ), #endif END_SEND_TABLE() @@ -906,11 +924,24 @@ void CPointCommentaryNode::Spawn( void ) if (!szModel || !*szModel) { #ifdef MAPBASE - if (m_bTextCommentary) - szModel = "models/extras/info_text.mdl"; - else -#endif + switch (m_iCommentaryType) + { + case COMMENTARY_TYPE_TEXT: + szModel = "models/extras/info_text.mdl"; + break; + + case COMMENTARY_TYPE_IMAGE: + szModel = "models/extras/info_image.mdl"; // TODO + break; + + default: + case COMMENTARY_TYPE_AUDIO: + szModel = "models/extras/info_speech.mdl"; + break; + } +#else szModel = "models/extras/info_speech.mdl"; +#endif SetModelName( AllocPooledString(szModel) ); } diff --git a/sp/src/game/shared/shareddefs.h b/sp/src/game/shared/shareddefs.h index d30843dc..0ddb6e1d 100644 --- a/sp/src/game/shared/shareddefs.h +++ b/sp/src/game/shared/shareddefs.h @@ -1048,4 +1048,15 @@ enum }; #endif // TF_DLL || TF_CLIENT_DLL +#ifdef MAPBASE +// Developer commentary types +enum +{ + COMMENTARY_TYPE_AUDIO, // Play commentary audio (default) + + COMMENTARY_TYPE_TEXT, // Display text data + COMMENTARY_TYPE_IMAGE, // Display an image +}; +#endif + #endif // SHAREDDEFS_H From 2f4ea05c8ae0cb277e948ff91a4d7906edadfde2 Mon Sep 17 00:00:00 2001 From: Blixibon Date: Sat, 24 Jul 2021 00:36:05 -0500 Subject: [PATCH 4/4] Added view target/position scales for commentary nodes --- sp/src/game/server/CommentarySystem.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/sp/src/game/server/CommentarySystem.cpp b/sp/src/game/server/CommentarySystem.cpp index 906c9daf..ba5aaba8 100644 --- a/sp/src/game/server/CommentarySystem.cpp +++ b/sp/src/game/server/CommentarySystem.cpp @@ -77,6 +77,8 @@ public: CPointCommentaryNode() { #ifdef MAPBASE + m_flViewTargetSpeedScale = 1.0f; + m_flViewPositionSpeedScale = 1.0f; m_flPanelScale = 1.0f; m_flPanelX = -1.0f; m_flPanelY = -1.0f; @@ -128,6 +130,10 @@ private: string_t m_iszViewPosition; CNetworkVar( EHANDLE, m_hViewPosition ); EHANDLE m_hViewPositionMover; // Entity used to blend the view to the viewposition entity +#ifdef MAPBASE + float m_flViewTargetSpeedScale; + float m_flViewPositionSpeedScale; +#endif bool m_bPreventMovement; bool m_bUnderCrosshair; bool m_bUnstoppable; @@ -183,6 +189,8 @@ BEGIN_DATADESC( CPointCommentaryNode ) DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "start_disabled" ), DEFINE_KEYFIELD( m_vecTeleportOrigin, FIELD_VECTOR, "teleport_origin" ), #ifdef MAPBASE + DEFINE_KEYFIELD( m_flViewTargetSpeedScale, FIELD_FLOAT, "viewtarget_speed" ), + DEFINE_KEYFIELD( m_flViewPositionSpeedScale, FIELD_FLOAT, "viewposition_speed" ), DEFINE_KEYFIELD( m_iCommentaryType, FIELD_INTEGER, "type" ), DEFINE_KEYFIELD( m_flPanelScale, FIELD_FLOAT, "panelscale" ), DEFINE_KEYFIELD( m_flPanelX, FIELD_FLOAT, "x" ), @@ -1260,6 +1268,10 @@ void CPointCommentaryNode::UpdateViewThink( void ) float dx = AngleDiff( angGoal.x, angCurrent.x ); float dy = AngleDiff( angGoal.y, angCurrent.y ); float mod = 1.0 - ExponentialDecay( 0.5, 0.3, gpGlobals->frametime ); +#ifdef MAPBASE + if (m_flViewTargetSpeedScale != 1.0f) + mod *= m_flViewTargetSpeedScale; +#endif float dxmod = dx * mod; float dymod = dy * mod; @@ -1300,7 +1312,11 @@ void CPointCommentaryNode::UpdateViewThink( void ) } // Blend to the target position over time. - float flCurTime = (gpGlobals->curtime - m_flStartTime); + float flCurTime = (gpGlobals->curtime - m_flStartTime); +#ifdef MAPBASE + if (m_flViewPositionSpeedScale != 1.0f) + flCurTime *= m_flViewPositionSpeedScale; +#endif float flBlendPerc = clamp( flCurTime * 0.5f, 0.f, 1.f ); // Figure out the current view position @@ -1325,6 +1341,10 @@ void CPointCommentaryNode::UpdateViewPostThink( void ) { // Blend back to the player's position over time. float flCurTime = (gpGlobals->curtime - m_flFinishedTime); +#ifdef MAPBASE + if (m_flViewPositionSpeedScale != 1.0f) + flCurTime *= m_flViewPositionSpeedScale; +#endif float flTimeToBlend = MIN( 2.0, m_flFinishedTime - m_flStartTime ); float flBlendPerc = 1.0f - clamp( flCurTime / flTimeToBlend, 0.f, 1.f );