diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf/vgui/drawing_panel.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/tf/vgui/drawing_panel.cpp')
| -rw-r--r-- | game/client/tf/vgui/drawing_panel.cpp | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/game/client/tf/vgui/drawing_panel.cpp b/game/client/tf/vgui/drawing_panel.cpp new file mode 100644 index 0000000..f6e764a --- /dev/null +++ b/game/client/tf/vgui/drawing_panel.cpp @@ -0,0 +1,335 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "drawing_panel.h" +#include "softline.h" +#include <vgui/IScheme.h> +#include <vgui/IVGui.h> +#include "voice_status.h" +// memdbgon must be the last include file in a .cpp file!!! +#include <tier0/memdbgon.h> + +extern ConVar cl_mute_all_comms; + +Color g_DrawPanel_TeamColors[TF_TEAM_COUNT] = +{ + COLOR_TF_SPECTATOR, // unassigned + COLOR_TF_SPECTATOR, // spectator + COLOR_TF_RED, // red + COLOR_TF_BLUE, // blue +}; + +DECLARE_BUILD_FACTORY( CDrawingPanel ); + +CDrawingPanel::CDrawingPanel( Panel *parent, const char*name ) : Panel( parent, name ) +{ + m_bDrawingLines = false; + m_fLastMapLine = 0; + m_iMouseX = 0; + m_iMouseY = 0; + m_iPanelType = DRAWING_PANEL_TYPE_NONE; + m_bTeamColors = false; + + m_nWhiteTexture = vgui::surface()->CreateNewTextureID(); + vgui::surface()->DrawSetTextureFile( m_nWhiteTexture, "vgui/white", true, false ); + + ListenForGameEvent( "cl_drawline" ); +} + +void CDrawingPanel::SetVisible( bool bState ) +{ + ClearAllLines(); + + BaseClass::SetVisible( bState ); +} + +void CDrawingPanel::ReadColor( const char* pszToken, Color& color ) +{ + if ( pszToken && *pszToken ) + { + int r = 0, g = 0, b = 0, a = 255; + if ( sscanf( pszToken, "%d %d %d %d", &r, &g, &b, &a ) >= 3 ) + { + // it's a direct color + color = Color( r, g, b, a ); + } + else + { + vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() ); + color = pScheme->GetColor( pszToken, Color( 0, 0, 0, 0 ) ); + } + } +} + +void CDrawingPanel::ApplySettings( KeyValues *inResourceData ) +{ + BaseClass::ApplySettings( inResourceData ); + + ReadColor( inResourceData->GetString( "linecolor", "" ), m_colorLine ); + m_bTeamColors = inResourceData->GetBool( "team_colors", false ); +} + +void CDrawingPanel::Paint() +{ + for ( int iIndex = 0; iIndex < ARRAYSIZE( m_vecDrawnLines ); iIndex++ ) + { + //Draw the lines + for ( int i = 0; i < m_vecDrawnLines[iIndex].Count(); i++ ) + { + if ( !m_vecDrawnLines[iIndex][i].bSetBlipCentre ) + { + Vector vecBlipPos; + vecBlipPos.x = m_vecDrawnLines[iIndex][i].worldpos.x; + vecBlipPos.y = m_vecDrawnLines[iIndex][i].worldpos.y; + vecBlipPos.z = 0; + //Msg("drawing line with blippos %f, %f\n", vecBlipPos.x, vecBlipPos.y); + m_vecDrawnLines[iIndex][i].blipcentre = m_vecDrawnLines[iIndex][i].worldpos; + //Msg(" which is blipcentre=%f, %f\n", m_MapLines[i].blipcentre.x, m_MapLines[i].blipcentre.y); + m_vecDrawnLines[iIndex][i].bSetBlipCentre = true; + } + + float x = m_vecDrawnLines[iIndex][i].blipcentre.x; + float y = m_vecDrawnLines[iIndex][i].blipcentre.y; + + if ( m_vecDrawnLines[iIndex][i].bLink ) + { + if ( i > 1 ) + { + m_vecDrawnLines[iIndex][i].linkpos = m_vecDrawnLines[iIndex][i-1].worldpos; + + if ( !m_vecDrawnLines[iIndex][i].bSetLinkBlipCentre ) + { + Vector vecBlipPos2; + vecBlipPos2.x = m_vecDrawnLines[iIndex][i].linkpos.x; + vecBlipPos2.y = m_vecDrawnLines[iIndex][i].linkpos.y; + vecBlipPos2.z = 0; + m_vecDrawnLines[iIndex][i].linkblipcentre = m_vecDrawnLines[iIndex][i].linkpos; + m_vecDrawnLines[iIndex][i].bSetLinkBlipCentre = true; + } + + float x2 = m_vecDrawnLines[iIndex][i].linkblipcentre.x; + float y2 = m_vecDrawnLines[iIndex][i].linkblipcentre.y; + + int alpha = 255; + if ( m_iPanelType == DRAWING_PANEL_TYPE_MATCH_SUMMARY ) + { + float t = gpGlobals->curtime - m_vecDrawnLines[iIndex][i].created_time; + + if ( t < DRAWN_LINE_SOLID_TIME ) + { + + } + else if ( t < DRAWN_LINE_SOLID_TIME + DRAWN_LINE_FADE_TIME ) + { + alpha = 255 - ( ( t - DRAWN_LINE_SOLID_TIME ) / DRAWN_LINE_FADE_TIME ) * 255.0f; + } + else + { + continue; + } + } + + //Msg("drawing line from %f,%f to %f,%f\n", x, y, x2, y2); + + vgui::surface()->DrawSetTexture( m_nWhiteTexture ); + vgui::Vertex_t start, end; + + Color drawColor = m_colorLine; + if ( m_bTeamColors ) + { + C_BasePlayer *pPlayer = UTIL_PlayerByIndex( iIndex ); + if ( pPlayer ) + { + drawColor = g_DrawPanel_TeamColors[ pPlayer->GetTeamNumber() ]; + } + } + + // draw main line + vgui::surface()->DrawSetColor( Color( drawColor.r(), drawColor.g(), drawColor.b(), alpha ) ); + start.Init( Vector2D( x, y ), Vector2D( 0, 0 ) ); + end.Init( Vector2D( x2, y2 ), Vector2D( 1, 1 ) ); + SoftLine::DrawPolygonLine( start, end ); + + // draw translucent ones around it to give it some softness + vgui::surface()->DrawSetColor( Color( drawColor.r(), drawColor.g(), drawColor.b(), 0.5f * alpha ) ); + + start.Init( Vector2D( x - 0.50f, y - 0.50f ), Vector2D( 0, 0 ) ); + end.Init( Vector2D( x2 - 0.50f, y2 - 0.50f ), Vector2D( 1, 1 ) ); + SoftLine::DrawPolygonLine( start, end ); + + start.Init( Vector2D( x + 0.50f, y - 0.50f ), Vector2D( 0, 0 ) ); + end.Init( Vector2D( x2 + 0.50f, y2 - 0.50f ), Vector2D( 1, 1 ) ); + SoftLine::DrawPolygonLine( start, end ); + + start.Init( Vector2D( x - 0.50f, y + 0.50f ), Vector2D( 0, 0 ) ); + end.Init( Vector2D( x2 - 0.50f, y2 + 0.50f ), Vector2D( 1, 1 ) ); + SoftLine::DrawPolygonLine( start, end ); + + start.Init( Vector2D( x + 0.50f, y + 0.50f ), Vector2D( 0, 0 ) ); + end.Init( Vector2D( x2 + 0.50f, y2 + 0.50f ), Vector2D( 1, 1 ) ); + SoftLine::DrawPolygonLine( start, end ); + } + } + } + } +} + +void CDrawingPanel::OnMousePressed( vgui::MouseCode code ) +{ + if ( code != MOUSE_LEFT ) + return; + + SendMapLine( m_iMouseX, m_iMouseY, true ); + m_bDrawingLines = true; +} + +void CDrawingPanel::OnMouseReleased( vgui::MouseCode code ) +{ + if ( code != MOUSE_LEFT ) + return; + + m_bDrawingLines = false; +} + +void CDrawingPanel::OnCursorExited() +{ + //Msg("CDrawingPanel::OnCursorExited\n"); + m_bDrawingLines = false; +} + +void CDrawingPanel::OnThink() +{ + if ( m_iPanelType == DRAWING_PANEL_TYPE_MATCH_SUMMARY ) + { + // clean up any segments that have faded out + for ( int iIndex = 0; iIndex < ARRAYSIZE( m_vecDrawnLines ); iIndex++ ) + { + for ( int i = m_vecDrawnLines[iIndex].Count() - 1; i >= 0; i-- ) + { + if ( gpGlobals->curtime - m_vecDrawnLines[iIndex][i].created_time > DRAWN_LINE_SOLID_TIME + DRAWN_LINE_FADE_TIME ) + { + m_vecDrawnLines[iIndex].Remove( i ); + } + } + } + } +} + +void CDrawingPanel::OnCursorMoved( int x, int y ) +{ + //Msg("CDrawingPanel::OnCursorMoved %d,%d\n", x, y); + m_iMouseX = x; + m_iMouseY = y; + + const float flLineInterval = 1.f / 60.f; + + if ( m_bDrawingLines && gpGlobals->curtime >= m_fLastMapLine + flLineInterval ) + { + SendMapLine( x, y, false ); + } + +} + +void CDrawingPanel::SendMapLine( int x, int y, bool bInitial ) +{ + if ( engine->IsPlayingDemo() ) + return; + + int iIndex = GetLocalPlayerIndex(); + int nMaxLines = 750; // 12.5 seconds of drawing at 60fps + if ( m_iPanelType == DRAWING_PANEL_TYPE_MATCH_SUMMARY ) + { + nMaxLines = 120; // 2 seconds of drawing at 60fps + } + + // Stop adding lines after this much + if ( m_vecDrawnLines[iIndex].Count() >= nMaxLines ) + return; + + int linetype = bInitial ? 0 : 1; + + m_fLastMapLine = gpGlobals->curtime; + + // short circuit add it to your own list + MapLine line; + line.worldpos.x = x; + line.worldpos.y = y; + line.created_time = gpGlobals->curtime; + if ( linetype == 1 ) // links to a previous + { + line.bLink = true; + } + + m_vecDrawnLines[iIndex].AddToTail( line ); + + if ( m_iPanelType == DRAWING_PANEL_TYPE_MATCH_SUMMARY ) + { + // notify the server of this! + KeyValues *kv = new KeyValues( "cl_drawline" ); + kv->SetInt( "panel", m_iPanelType ); + kv->SetInt( "line", linetype ); + kv->SetFloat( "x", (float)x / (float)GetWide() ); + kv->SetFloat( "y", (float)y / (float)GetTall() ); + engine->ServerCmdKeyValues( kv ); + } +} + +void CDrawingPanel::ClearLines( int iIndex ) +{ + m_vecDrawnLines[iIndex].Purge(); +} + +void CDrawingPanel::ClearAllLines() +{ + for ( int iIndex = 0; iIndex < ARRAYSIZE( m_vecDrawnLines ); iIndex++ ) + { + m_vecDrawnLines[iIndex].Purge(); + } +} + +void CDrawingPanel::FireGameEvent( IGameEvent *event ) +{ + if ( FStrEq( event->GetName(), "cl_drawline" ) ) + { + int iIndex = event->GetInt( "player" ); + + // if this is NOT the local player (we've already stored our own data) + if ( ( iIndex != GetLocalPlayerIndex() ) || engine->IsPlayingDemo() ) + { + // If a player is muted for voice, also mute them for lines because jerks gonna jerk. + if ( cl_mute_all_comms.GetBool() && ( iIndex != 0 ) ) + { + if ( GetClientVoiceMgr() && GetClientVoiceMgr()->IsPlayerBlocked( iIndex ) ) + { + ClearLines( iIndex ); + return; + } + } + + int iPanelType = event->GetInt( "panel" ); + + // if this message is about our panel type + if ( iPanelType == m_iPanelType ) + { + int iLineType = event->GetInt( "line" ); + float x = event->GetFloat( "x" ); + float y = event->GetFloat( "y" ); + + MapLine line; + line.worldpos.x = (int)( x * GetWide() ); + line.worldpos.y = (int)( y * GetTall() ); + line.created_time = gpGlobals->curtime; + if ( iLineType == 1 ) // links to a previous + { + line.bLink = true; + } + + m_vecDrawnLines[iIndex].AddToTail( line ); + } + } + } +}
\ No newline at end of file |