You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
946 lines
27 KiB
946 lines
27 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "hudelement.h" |
|
#include <vgui_controls/Panel.h> |
|
#include <vgui_controls/Label.h> |
|
#include <vgui_controls/EditablePanel.h> |
|
#include <vgui_controls/ImagePanel.h> |
|
#include <vgui/ISurface.h> |
|
#include "c_baseplayer.h" |
|
#include "iclientmode.h" |
|
#include "c_team_objectiveresource.h" |
|
#include "c_team.h" |
|
#include "view.h" |
|
#include "teamplay_gamerules.h" |
|
|
|
#define INTRO_NUM_FAKE_PLAYERS 3 |
|
|
|
extern ConVar mp_capstyle; |
|
extern ConVar mp_blockstyle; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Draws the progress bar |
|
//----------------------------------------------------------------------------- |
|
class CHudCapturePanelProgressBar : public vgui::ImagePanel |
|
{ |
|
public: |
|
DECLARE_CLASS_SIMPLE( CHudCapturePanelProgressBar, vgui::ImagePanel ); |
|
|
|
CHudCapturePanelProgressBar( vgui::Panel *parent, const char *name ); |
|
|
|
virtual void Paint(); |
|
|
|
void SetPercentage( float flPercentage ){ m_flPercent = flPercentage; } |
|
|
|
private: |
|
|
|
float m_flPercent; |
|
int m_iTexture; |
|
|
|
CPanelAnimationVar( Color, m_clrActive, "color_active", "HudCaptureProgressBar.Active" ); |
|
CPanelAnimationVar( Color, m_clrInActive, "color_inactive", "HudCaptureProgressBar.InActive" ); |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
class CHudCapturePanelIcon : public vgui::ImagePanel |
|
{ |
|
public: |
|
DECLARE_CLASS_SIMPLE( CHudCapturePanelIcon, vgui::ImagePanel ); |
|
|
|
CHudCapturePanelIcon( vgui::Panel *parent, const char *name ); |
|
|
|
virtual void Paint(); |
|
|
|
void SetActive( bool state ){ m_bActive = state; } |
|
|
|
private: |
|
|
|
bool m_bActive; |
|
int m_iTexture; |
|
|
|
CPanelAnimationVar( Color, m_clrActive, "color_active", "HudCaptureIcon.Active" ); |
|
CPanelAnimationVar( Color, m_clrInActive, "color_inactive", "HudCaptureIcon.InActive" ); |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
//----------------------------------------------------------------------------- |
|
class CHudCapturePanel : public CHudElement, public vgui::EditablePanel |
|
{ |
|
public: |
|
DECLARE_CLASS_SIMPLE( CHudCapturePanel, vgui::EditablePanel ); |
|
|
|
CHudCapturePanel( const char *pElementName ); |
|
|
|
virtual void Init( void ); |
|
virtual void LevelInit( void ); |
|
virtual void OnThink(); |
|
virtual void ApplySchemeSettings( vgui::IScheme *pScheme ); |
|
virtual void OnScreenSizeChanged( int iOldWide, int iOldTall ); |
|
virtual void FireGameEvent( IGameEvent *event ); |
|
|
|
private: |
|
|
|
int m_iCurrentCP; // the index of the control point the local is currently in |
|
|
|
int m_iOriginalYPos; |
|
|
|
CHudCapturePanelProgressBar *m_pProgressBar; |
|
|
|
CUtlVector<CHudCapturePanelIcon *> m_PlayerIcons; |
|
|
|
bool m_bInitializedFlags; |
|
vgui::ImagePanel *m_pTeamFlags[ MAX_TEAMS ]; |
|
|
|
vgui::Label *m_pMessage; |
|
|
|
vgui::Panel *m_pBackground; |
|
|
|
CPanelAnimationVarAliasType( float, m_nSpaceBetweenIcons, "icon_space", "2", "proportional_float" ); |
|
|
|
// For demonstrations of the element in the intro |
|
bool m_bFakingCapture; |
|
bool m_bFakingMultCapture; |
|
float m_flFakeCaptureTime; |
|
C_BaseAnimating *m_pFakePlayers[INTRO_NUM_FAKE_PLAYERS]; |
|
}; |
|
|
|
DECLARE_HUDELEMENT( CHudCapturePanel ); |
|
|
|
ConVar hud_capturepanel( "hud_capturepanel", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Set to 0 to not draw the HUD capture panel" ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CHudCapturePanelProgressBar::CHudCapturePanelProgressBar( vgui::Panel *parent, const char *name ) : vgui::ImagePanel( parent, name ) |
|
{ |
|
m_flPercent = 0.0f; |
|
|
|
m_iTexture = vgui::surface()->DrawGetTextureId( "vgui/progress_bar" ); |
|
if ( m_iTexture == -1 ) // we didn't find it, so create a new one |
|
{ |
|
m_iTexture = vgui::surface()->CreateNewTextureID(); |
|
vgui::surface()->DrawSetTextureFile( m_iTexture, "vgui/progress_bar", true, false ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudCapturePanelProgressBar::Paint() |
|
{ |
|
int wide, tall; |
|
GetSize( wide, tall ); |
|
|
|
float uv1 = 0.0f, uv2 = 1.0f; |
|
Vector2D uv11( uv1, uv1 ); |
|
Vector2D uv21( uv2, uv1 ); |
|
Vector2D uv22( uv2, uv2 ); |
|
Vector2D uv12( uv1, uv2 ); |
|
|
|
vgui::Vertex_t verts[4]; |
|
verts[0].Init( Vector2D( 0, 0 ), uv11 ); |
|
verts[1].Init( Vector2D( wide, 0 ), uv21 ); |
|
verts[2].Init( Vector2D( wide, tall ), uv22 ); |
|
verts[3].Init( Vector2D( 0, tall ), uv12 ); |
|
|
|
// first, just draw the whole thing inactive. |
|
vgui::surface()->DrawSetTexture( m_iTexture ); |
|
vgui::surface()->DrawSetColor( m_clrInActive ); |
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
|
|
// now, let's calculate the "active" part of the progress bar |
|
vgui::surface()->DrawSetColor( m_clrActive ); |
|
|
|
// we're going to do this using quadrants |
|
// ------------------------- |
|
// | | | |
|
// | | | |
|
// | 4 | 1 | |
|
// | | | |
|
// | | | |
|
// ------------------------- |
|
// | | | |
|
// | | | |
|
// | 3 | 2 | |
|
// | | | |
|
// | | | |
|
// ------------------------- |
|
|
|
float flCompleteCircle = ( 2.0f * M_PI ); |
|
float fl90degrees = flCompleteCircle / 4.0f; |
|
|
|
float flEndAngle = flCompleteCircle * ( 1.0f - m_flPercent ); // count DOWN (counter-clockwise) |
|
// float flEndAngle = flCompleteCircle * m_flPercent; // count UP (clockwise) |
|
|
|
float flHalfWide = (float)wide / 2.0f; |
|
float flHalfTall = (float)tall / 2.0f; |
|
|
|
if ( flEndAngle >= fl90degrees * 3.0f ) // >= 270 degrees |
|
{ |
|
// draw the first and second quadrants |
|
uv11.Init( 0.5f, 0.0f ); |
|
uv21.Init( 1.0f, 0.0f ); |
|
uv22.Init( 1.0f, 1.0f ); |
|
uv12.Init( 0.5, 1.0f ); |
|
|
|
verts[0].Init( Vector2D( flHalfWide, 0.0f ), uv11 ); |
|
verts[1].Init( Vector2D( wide, 0.0f ), uv21 ); |
|
verts[2].Init( Vector2D( wide, tall ), uv22 ); |
|
verts[3].Init( Vector2D( flHalfWide, tall ), uv12 ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
|
|
// draw the third quadrant |
|
uv11.Init( 0.0f, 0.5f ); |
|
uv21.Init( 0.5f, 0.5f ); |
|
uv22.Init( 0.5f, 1.0f ); |
|
uv12.Init( 0.0f, 1.0f ); |
|
|
|
verts[0].Init( Vector2D( 0.0f, flHalfTall ), uv11 ); |
|
verts[1].Init( Vector2D( flHalfWide, flHalfTall ), uv21 ); |
|
verts[2].Init( Vector2D( flHalfWide, tall ), uv22 ); |
|
verts[3].Init( Vector2D( 0.0f, tall ), uv12 ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
|
|
// draw the partial fourth quadrant |
|
if ( flEndAngle > fl90degrees * 3.5f ) // > 315 degrees |
|
{ |
|
uv11.Init( 0.0f, 0.0f ); |
|
uv21.Init( 0.5f - ( tan(fl90degrees * 4.0f - flEndAngle) * 0.5 ), 0.0f ); |
|
uv22.Init( 0.5f, 0.5f ); |
|
uv12.Init( 0.0f, 0.5f ); |
|
|
|
verts[0].Init( Vector2D( 0.0f, 0.0f ), uv11 ); |
|
verts[1].Init( Vector2D( flHalfWide - ( tan(fl90degrees * 4.0f - flEndAngle) * flHalfTall ), 0.0f ), uv21 ); |
|
verts[2].Init( Vector2D( flHalfWide, flHalfTall ), uv22 ); |
|
verts[3].Init( Vector2D( 0.0f, flHalfTall ), uv12 ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
} |
|
else // <= 315 degrees |
|
{ |
|
uv11.Init( 0.0f, 0.5f ); |
|
uv21.Init( 0.0f, 0.5f - ( tan(flEndAngle - fl90degrees * 3.0f) * 0.5 ) ); |
|
uv22.Init( 0.5f, 0.5f ); |
|
uv12.Init( 0.0f, 0.5f ); |
|
|
|
verts[0].Init( Vector2D( 0.0f, flHalfTall ), uv11 ); |
|
verts[1].Init( Vector2D( 0.0f, flHalfTall - ( tan(flEndAngle - fl90degrees * 3.0f) * flHalfWide ) ), uv21 ); |
|
verts[2].Init( Vector2D( flHalfWide, flHalfTall ), uv22 ); |
|
verts[3].Init( Vector2D( 0.0f, flHalfTall ), uv12 ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
} |
|
} |
|
else if ( flEndAngle >= fl90degrees * 2.0f ) // >= 180 degrees |
|
{ |
|
// draw the first and second quadrants |
|
uv11.Init( 0.5f, 0.0f ); |
|
uv21.Init( 1.0f, 0.0f ); |
|
uv22.Init( 1.0f, 1.0f ); |
|
uv12.Init( 0.5, 1.0f ); |
|
|
|
verts[0].Init( Vector2D( flHalfWide, 0.0f ), uv11 ); |
|
verts[1].Init( Vector2D( wide, 0.0f ), uv21 ); |
|
verts[2].Init( Vector2D( wide, tall ), uv22 ); |
|
verts[3].Init( Vector2D( flHalfWide, tall ), uv12 ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
|
|
// draw the partial third quadrant |
|
if ( flEndAngle > fl90degrees * 2.5f ) // > 225 degrees |
|
{ |
|
uv11.Init( 0.5f, 0.5f ); |
|
uv21.Init( 0.5f, 1.0f ); |
|
uv22.Init( 0.0f, 1.0f ); |
|
uv12.Init( 0.0f, 0.5f + ( tan(fl90degrees * 3.0f - flEndAngle) * 0.5 ) ); |
|
|
|
verts[0].Init( Vector2D( flHalfWide, flHalfTall ), uv11 ); |
|
verts[1].Init( Vector2D( flHalfWide, tall ), uv21 ); |
|
verts[2].Init( Vector2D( 0.0f, tall ), uv22 ); |
|
verts[3].Init( Vector2D( 0.0f, flHalfTall + ( tan(fl90degrees * 3.0f - flEndAngle) * flHalfWide ) ), uv12 ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
} |
|
else // <= 225 degrees |
|
{ |
|
uv11.Init( 0.5f, 0.5f ); |
|
uv21.Init( 0.5f, 1.0f ); |
|
uv22.Init( 0.5f - ( tan( flEndAngle - fl90degrees * 2.0f) * 0.5 ), 1.0f ); |
|
uv12.Init( 0.5f, 0.5f ); |
|
|
|
verts[0].Init( Vector2D( flHalfWide, flHalfTall ), uv11 ); |
|
verts[1].Init( Vector2D( flHalfWide, tall ), uv21 ); |
|
verts[2].Init( Vector2D( flHalfWide - ( tan(flEndAngle - fl90degrees * 2.0f) * flHalfTall ), tall ), uv22 ); |
|
verts[3].Init( Vector2D( flHalfWide, flHalfTall ), uv12 ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
} |
|
} |
|
else if ( flEndAngle >= fl90degrees ) // >= 90 degrees |
|
{ |
|
// draw the first quadrant |
|
uv11.Init( 0.5f, 0.0f ); |
|
uv21.Init( 1.0f, 0.0f ); |
|
uv22.Init( 1.0f, 0.5f ); |
|
uv12.Init( 0.5f, 0.5f ); |
|
|
|
verts[0].Init( Vector2D( flHalfWide, 0.0f ), uv11 ); |
|
verts[1].Init( Vector2D( wide, 0.0f ), uv21 ); |
|
verts[2].Init( Vector2D( wide, flHalfTall ), uv22 ); |
|
verts[3].Init( Vector2D( flHalfWide, flHalfTall ), uv12 ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
|
|
// draw the partial second quadrant |
|
if ( flEndAngle > fl90degrees * 1.5f ) // > 135 degrees |
|
{ |
|
uv11.Init( 0.5f, 0.5f ); |
|
uv21.Init( 1.0f, 0.5f ); |
|
uv22.Init( 1.0f, 1.0f ); |
|
uv12.Init( 0.5f + ( tan(fl90degrees * 2.0f - flEndAngle) * 0.5f ), 1.0f ); |
|
|
|
verts[0].Init( Vector2D( flHalfWide, flHalfTall ), uv11 ); |
|
verts[1].Init( Vector2D( wide, flHalfTall ), uv21 ); |
|
verts[2].Init( Vector2D( wide, tall ), uv22 ); |
|
verts[3].Init( Vector2D( flHalfWide + ( tan(fl90degrees * 2.0f - flEndAngle) * flHalfTall ), tall ), uv12 ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
} |
|
else // <= 135 degrees |
|
{ |
|
uv11.Init( 0.5f, 0.5f ); |
|
uv21.Init( 1.0f, 0.5f ); |
|
uv22.Init( 1.0f, 0.5f + ( tan(flEndAngle - fl90degrees) * 0.5f ) ); |
|
uv12.Init( 0.5f, 0.5f ); |
|
|
|
verts[0].Init( Vector2D( flHalfWide, flHalfTall ), uv11 ); |
|
verts[1].Init( Vector2D( wide, flHalfTall ), uv21 ); |
|
verts[2].Init( Vector2D( wide, flHalfTall + ( tan(flEndAngle - fl90degrees) * flHalfWide ) ), uv22 ); |
|
verts[3].Init( Vector2D( flHalfWide, flHalfTall ), uv12 ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
} |
|
} |
|
else // > 0 degrees |
|
{ |
|
if ( flEndAngle > fl90degrees / 2.0f ) // > 45 degrees |
|
{ |
|
uv11.Init( 0.5f, 0.0f ); |
|
uv21.Init( 1.0f, 0.0f ); |
|
uv22.Init( 1.0f, 0.5f - ( tan(fl90degrees - flEndAngle) * 0.5 ) ); |
|
uv12.Init( 0.5f, 0.5f ); |
|
|
|
verts[0].Init( Vector2D( flHalfWide, 0.0f ), uv11 ); |
|
verts[1].Init( Vector2D( wide, 0.0f ), uv21 ); |
|
verts[2].Init( Vector2D( wide, flHalfTall - ( tan(fl90degrees - flEndAngle) * flHalfWide ) ), uv22 ); |
|
verts[3].Init( Vector2D( flHalfWide, flHalfTall ), uv12 ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
} |
|
else // <= 45 degrees |
|
{ |
|
uv11.Init( 0.5f, 0.0f ); |
|
uv21.Init( 0.5 + ( tan(flEndAngle) * 0.5 ), 0.0f ); |
|
uv22.Init( 0.5f, 0.5f ); |
|
uv12.Init( 0.5f, 0.0f ); |
|
|
|
verts[0].Init( Vector2D( flHalfWide, 0.0f ), uv11 ); |
|
verts[1].Init( Vector2D( flHalfWide + ( tan(flEndAngle) * flHalfTall ), 0.0f ), uv21 ); |
|
verts[2].Init( Vector2D( flHalfWide, flHalfTall ), uv22 ); |
|
verts[3].Init( Vector2D( flHalfWide, 0.0f ), uv12 ); |
|
|
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CHudCapturePanelIcon::CHudCapturePanelIcon( vgui::Panel *parent, const char *name ) : vgui::ImagePanel( parent, name ) |
|
{ |
|
m_bActive = false; |
|
|
|
m_iTexture = vgui::surface()->DrawGetTextureId( "vgui/capture_icon" ); |
|
if ( m_iTexture == -1 ) // we didn't find it, so create a new one |
|
{ |
|
m_iTexture = vgui::surface()->CreateNewTextureID(); |
|
vgui::surface()->DrawSetTextureFile( m_iTexture, "vgui/capture_icon", true, false ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudCapturePanelIcon::Paint() |
|
{ |
|
int wide, tall; |
|
GetSize( wide, tall ); |
|
|
|
float uv1 = 0.0f, uv2 = 1.0f; |
|
Vector2D uv11( uv1, uv1 ); |
|
Vector2D uv12( uv1, uv2 ); |
|
Vector2D uv21( uv2, uv1 ); |
|
Vector2D uv22( uv2, uv2 ); |
|
|
|
vgui::Vertex_t verts[4]; |
|
verts[0].Init( Vector2D( 0, 0 ), uv11 ); |
|
verts[1].Init( Vector2D( wide, 0 ), uv21 ); |
|
verts[2].Init( Vector2D( wide, tall ), uv22 ); |
|
verts[3].Init( Vector2D( 0, tall ), uv12 ); |
|
|
|
// just draw the whole thing |
|
vgui::surface()->DrawSetTexture( m_iTexture ); |
|
vgui::surface()->DrawSetColor( m_bActive ? m_clrActive : m_clrInActive ); |
|
vgui::surface()->DrawTexturedPolygon( 4, verts ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor |
|
//----------------------------------------------------------------------------- |
|
CHudCapturePanel::CHudCapturePanel( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudCapturePanel" ) |
|
{ |
|
SetParent( g_pClientMode->GetViewport() ); |
|
|
|
m_iCurrentCP = -1; |
|
m_bFakingCapture = false; |
|
|
|
m_pBackground = new vgui::Panel( this, "CapturePanelBackground" ); |
|
m_pProgressBar = new CHudCapturePanelProgressBar( this, "CapturePanelProgressBar" ); |
|
|
|
for ( int i = 0 ; i < 5 ; i++ ) |
|
{ |
|
CHudCapturePanelIcon *pPanel; |
|
char szName[64]; |
|
|
|
Q_snprintf( szName, sizeof( szName ), "CapturePanelPlayerIcon%d", i + 1 ); |
|
pPanel = new CHudCapturePanelIcon( this, szName ); |
|
|
|
m_PlayerIcons.AddToTail( pPanel ); |
|
} |
|
|
|
m_bInitializedFlags = false; |
|
for ( int i = 0; i < MAX_TEAMS; i++ ) |
|
{ |
|
m_pTeamFlags[i] = NULL; |
|
} |
|
|
|
m_pMessage = new vgui::Label( this, "CapturePanelMessage", " " ); |
|
|
|
// load control settings... |
|
LoadControlSettings( "resource/UI/HudCapturePanel.res" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudCapturePanel::Init( void ) |
|
{ |
|
ListenForGameEvent( "controlpoint_starttouch" ); |
|
ListenForGameEvent( "controlpoint_endtouch" ); |
|
ListenForGameEvent( "teamplay_round_start" ); |
|
ListenForGameEvent( "controlpoint_fake_capture" ); |
|
ListenForGameEvent( "controlpoint_fake_capture_mult" ); |
|
ListenForGameEvent( "intro_finish" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudCapturePanel::LevelInit( void ) |
|
{ |
|
m_iCurrentCP = -1; |
|
m_bFakingCapture = false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudCapturePanel::OnScreenSizeChanged( int iOldWide, int iOldTall ) |
|
{ |
|
LoadControlSettings( "resource/UI/HudCapturePanel.res" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudCapturePanel::ApplySchemeSettings( vgui::IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
if ( m_pBackground ) |
|
{ |
|
m_pBackground->SetBgColor( GetSchemeColor( "HintMessageBg", pScheme ) ); |
|
m_pBackground->SetPaintBackgroundType( 2 ); |
|
} |
|
|
|
SetFgColor( GetSchemeColor( "HudProgressBar.Active", pScheme ) ); |
|
|
|
int iX; |
|
GetPos( iX, m_iOriginalYPos ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudCapturePanel::OnThink() |
|
{ |
|
BaseClass::OnThink(); |
|
|
|
if ( !GetNumberOfTeams() ) |
|
return; |
|
|
|
if ( !m_bInitializedFlags ) |
|
{ |
|
m_bInitializedFlags = true; |
|
for ( int i = 0; i < GetNumberOfTeams(); i++ ) |
|
{ |
|
if ( i == TEAM_SPECTATOR ) |
|
continue; |
|
|
|
m_pTeamFlags[i] = dynamic_cast< vgui::ImagePanel * >(FindChildByName( VarArgs("CapturePanelTeamFlag_%d", i) )); |
|
} |
|
InvalidateLayout(); |
|
} |
|
|
|
if ( m_bFakingCapture && gpGlobals->curtime > m_flFakeCaptureTime ) |
|
{ |
|
m_bFakingCapture = false; |
|
if ( m_bFakingMultCapture ) |
|
{ |
|
for ( int i = 0; i < INTRO_NUM_FAKE_PLAYERS; i++ ) |
|
{ |
|
m_pFakePlayers[i]->Release(); |
|
m_pFakePlayers[i] = NULL; |
|
} |
|
} |
|
} |
|
|
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); |
|
|
|
if ( pPlayer ) |
|
{ |
|
bool bInCapZone = ( m_iCurrentCP >= 0 ); |
|
|
|
// Turn off the panel and children if the player is dead or not in a cap zone |
|
if ( !m_bFakingCapture && (!bInCapZone || !hud_capturepanel.GetBool() || !pPlayer->IsAlive()) ) |
|
{ |
|
if ( IsVisible() ) |
|
{ |
|
SetVisible( false ); |
|
} |
|
return; |
|
} |
|
|
|
int nOwningTeam = ObjectiveResource()->GetOwningTeam( m_iCurrentCP ); |
|
int nPlayerTeam = pPlayer->GetTeamNumber(); |
|
|
|
int nNumTeammates = ObjectiveResource()->GetNumPlayersInArea( m_iCurrentCP, nPlayerTeam ); |
|
int nRequiredTeammates = ObjectiveResource()->GetRequiredCappers( m_iCurrentCP, nPlayerTeam ); |
|
|
|
int nNumEnemies = 0; |
|
bool bEnemyTeamReadyToCap = false; |
|
for ( int i = LAST_SHARED_TEAM+1; i < GetNumberOfTeams(); i++ ) |
|
{ |
|
if ( i == nPlayerTeam ) |
|
continue; |
|
|
|
int iTeamInArea = ObjectiveResource()->GetNumPlayersInArea( m_iCurrentCP, i ); |
|
nNumEnemies += iTeamInArea; |
|
|
|
if ( iTeamInArea >= ObjectiveResource()->GetRequiredCappers( m_iCurrentCP, i ) ) |
|
{ |
|
// There's an enemy team here that has enough players to cap |
|
bEnemyTeamReadyToCap = true; |
|
} |
|
} |
|
|
|
int iCappingTeam = ObjectiveResource()->GetCappingTeam( m_iCurrentCP ); |
|
|
|
// If we're faking it, stomp all the data |
|
if ( m_bFakingCapture ) |
|
{ |
|
nOwningTeam = TEAM_UNASSIGNED; |
|
iCappingTeam = nPlayerTeam; |
|
|
|
if ( m_bFakingMultCapture ) |
|
{ |
|
nNumTeammates = nRequiredTeammates = 3; |
|
} |
|
else |
|
{ |
|
nNumTeammates = nRequiredTeammates = 1; |
|
} |
|
nNumEnemies = 0; |
|
bEnemyTeamReadyToCap = false; |
|
} |
|
|
|
// If we're in more-players-cap-faster mode, we have no required amount. |
|
// Just show the number of players in the zone. |
|
if ( mp_capstyle.GetInt() == 1 ) |
|
{ |
|
// Clip to max number of players we can show |
|
if ( nNumTeammates > 5 ) |
|
{ |
|
nNumTeammates = 5; |
|
} |
|
|
|
nRequiredTeammates = nNumTeammates; |
|
} |
|
|
|
// if we already own this capture point and there are no enemies in the area |
|
// or we're playing minirounds and the current cap zone is not in the current round |
|
if ( ( nOwningTeam == nPlayerTeam && !bEnemyTeamReadyToCap ) || |
|
( ObjectiveResource()->PlayingMiniRounds() && !ObjectiveResource()->IsInMiniRound( m_iCurrentCP ) ) ) |
|
{ |
|
// don't need to do anything |
|
if ( IsVisible() ) |
|
{ |
|
SetVisible( false ); |
|
} |
|
return; |
|
} |
|
|
|
// okay, turn on the capture point panel |
|
if ( !IsVisible() ) |
|
{ |
|
SetVisible( true ); |
|
} |
|
|
|
// If there's a hint onscreen, move ourselves off it |
|
int iX,iY; |
|
GetPos( iX, iY ); |
|
if ( pPlayer->Hints() && pPlayer->Hints()->HintIsCurrentlyVisible() ) |
|
{ |
|
int iMovedY = (m_iOriginalYPos - YRES(50)); |
|
if ( iY != iMovedY ) |
|
{ |
|
SetPos( iX, iMovedY ); |
|
} |
|
} |
|
else if ( iY != m_iOriginalYPos ) |
|
{ |
|
SetPos( iX, m_iOriginalYPos ); |
|
} |
|
|
|
// set the correct flag image |
|
for ( int i = 0; i < GetNumberOfTeams(); i++ ) |
|
{ |
|
if ( !m_pTeamFlags[i] ) |
|
continue; |
|
|
|
m_pTeamFlags[i]->SetVisible( nOwningTeam == i ); |
|
} |
|
|
|
// arrange the player icons |
|
for ( int i = 0 ; i < m_PlayerIcons.Count() ; i++ ) |
|
{ |
|
CHudCapturePanelIcon *pPanel = m_PlayerIcons[i]; |
|
|
|
if ( !pPanel ) |
|
{ |
|
continue; |
|
} |
|
|
|
if ( i < nRequiredTeammates ) |
|
{ |
|
if ( i < nNumTeammates ) |
|
{ |
|
pPanel->SetActive( true ); |
|
|
|
if ( !pPanel->IsVisible() ) |
|
pPanel->SetVisible( true ); |
|
} |
|
else |
|
{ |
|
pPanel->SetActive( false ); |
|
|
|
if ( !pPanel->IsVisible() ) |
|
pPanel->SetVisible( true ); |
|
} |
|
} |
|
else |
|
{ |
|
if ( pPanel->IsVisible() ) |
|
pPanel->SetVisible( false ); |
|
} |
|
} |
|
|
|
int wide = 0, tall = 0, iconWide = 0, iconTall = 0; |
|
GetSize( wide, tall ); |
|
|
|
vgui::ImagePanel *pPanel = m_PlayerIcons[0]; |
|
if ( pPanel ) |
|
pPanel->GetSize( iconWide, iconTall ); |
|
|
|
int width = ( nRequiredTeammates * iconWide ) + ( ( nRequiredTeammates - 1 ) * m_nSpaceBetweenIcons ); |
|
int xpos = wide / 2.0 - width / 2.0; |
|
|
|
// rearrange the player icon panels |
|
for ( int i = 0 ; i < nRequiredTeammates ; i++ ) |
|
{ |
|
CHudCapturePanelIcon *pPanel = m_PlayerIcons[i]; |
|
|
|
if ( pPanel ) |
|
{ |
|
int x, y, w, t; |
|
pPanel->GetBounds( x, y, w, t ); |
|
pPanel->SetBounds( xpos, y, w, t ); |
|
} |
|
|
|
xpos += iconWide + m_nSpaceBetweenIcons; |
|
} |
|
|
|
// are we capping an area? |
|
if ( iCappingTeam == TEAM_UNASSIGNED || iCappingTeam != nPlayerTeam ) |
|
{ |
|
// turn off the progress bar, we're not capping |
|
if ( m_pProgressBar && m_pProgressBar->IsVisible() ) |
|
{ |
|
m_pProgressBar->SetVisible( false ); |
|
} |
|
|
|
// turn on the message |
|
if ( m_pMessage ) |
|
{ |
|
m_pMessage->SetFgColor( GetFgColor() ); |
|
|
|
if ( !m_pMessage->IsVisible() ) |
|
{ |
|
m_pMessage->SetVisible( true ); |
|
} |
|
|
|
char szReason[256]; |
|
|
|
// If a team's not allowed to cap a point, don't count players in it at all |
|
if ( !TeamplayGameRules()->TeamMayCapturePoint( nPlayerTeam, m_iCurrentCP ) ) |
|
{ |
|
m_pMessage->SetText( "#Team_Capture_Linear" ); |
|
|
|
if ( m_pTeamFlags[ nOwningTeam ] ) |
|
{ |
|
m_pTeamFlags[ nOwningTeam ]->SetVisible( false ); |
|
} |
|
} |
|
else if ( !TeamplayGameRules()->PlayerMayCapturePoint( pPlayer, m_iCurrentCP, szReason, sizeof(szReason) ) ) |
|
{ |
|
m_pMessage->SetText( szReason ); |
|
|
|
if ( m_pTeamFlags[ nOwningTeam ] ) |
|
{ |
|
m_pTeamFlags[ nOwningTeam ]->SetVisible( false ); |
|
} |
|
} |
|
else if ( nNumTeammates >= nRequiredTeammates && nNumEnemies > 0 ) |
|
{ |
|
m_pMessage->SetText( "#Team_Capture_Blocked" ); |
|
} |
|
else if ( bEnemyTeamReadyToCap ) |
|
{ |
|
m_pMessage->SetText( "#Team_Blocking_Capture" ); |
|
} |
|
else if ( mp_blockstyle.GetInt() == 1 && iCappingTeam != TEAM_UNASSIGNED ) |
|
{ |
|
m_pMessage->SetText( "#Team_Blocking_Capture" ); |
|
|
|
for ( int i = 0; i < GetNumberOfTeams(); i++ ) |
|
{ |
|
if ( m_pTeamFlags[i] ) |
|
{ |
|
m_pTeamFlags[i]->SetVisible( false ); |
|
} |
|
} |
|
} |
|
else if ( !ObjectiveResource()->TeamCanCapPoint( m_iCurrentCP, nPlayerTeam ) ) |
|
{ |
|
m_pMessage->SetText( "#Team_Cannot_Capture" ); |
|
|
|
if ( m_pTeamFlags[ nOwningTeam ] ) |
|
{ |
|
m_pTeamFlags[ nOwningTeam ]->SetVisible( false ); |
|
} |
|
} |
|
else |
|
{ |
|
m_pMessage->SetText( "#Team_Waiting_for_teammate" ); |
|
} |
|
|
|
if ( m_pBackground ) |
|
{ |
|
// do we need to resize our background? |
|
int textW, textH, bgX, bgY, bgW, bgH; |
|
m_pMessage->GetContentSize( textW, textH ); |
|
m_pBackground->GetBounds( bgX, bgY, bgW, bgH ); |
|
|
|
if ( bgW < textW ) |
|
{ |
|
m_pBackground->SetBounds( bgX + ( bgW / 2.0 ) - ( ( textW + XRES(3) ) / 2.0 ), bgY, textW + XRES(3), bgH ); |
|
} |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
// turn on the progress bar, we're capping |
|
if ( m_pProgressBar ) |
|
{ |
|
if ( !m_pProgressBar->IsVisible() ) |
|
{ |
|
m_pProgressBar->SetVisible( true ); |
|
} |
|
|
|
if ( m_bFakingCapture ) |
|
{ |
|
float flProgress = RemapVal( m_flFakeCaptureTime - gpGlobals->curtime, 0, 5.0, 0, 1 ); |
|
m_pProgressBar->SetPercentage( flProgress ); |
|
} |
|
else |
|
{ |
|
m_pProgressBar->SetPercentage( ObjectiveResource()->GetCPCapPercentage( m_iCurrentCP ) ); |
|
} |
|
} |
|
|
|
// If our cap is being paused by blocking enemies, show that |
|
if ( mp_blockstyle.GetInt() == 1 && nNumTeammates == 0 ) |
|
{ |
|
m_pMessage->SetText( "#Team_Capture_Blocked" ); |
|
|
|
if ( !m_pMessage->IsVisible() ) |
|
{ |
|
m_pMessage->SetVisible( true ); |
|
} |
|
|
|
for ( int i = 0; i < GetNumberOfTeams(); i++ ) |
|
{ |
|
if ( m_pTeamFlags[i] ) |
|
{ |
|
m_pTeamFlags[i]->SetVisible( false ); |
|
} |
|
} |
|
} |
|
else if ( m_pMessage && m_pMessage->IsVisible() ) |
|
{ |
|
// turn off the message |
|
m_pMessage->SetVisible( false ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudCapturePanel::FireGameEvent( IGameEvent *event ) |
|
{ |
|
m_iCurrentCP = -1; |
|
return; |
|
|
|
const char *eventname = event->GetName(); |
|
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); |
|
|
|
if ( FStrEq( "controlpoint_starttouch", eventname ) ) |
|
{ |
|
int iPlayer = event->GetInt( "player" ); |
|
if ( pPlayer && iPlayer == pPlayer->entindex() ) |
|
{ |
|
m_iCurrentCP = event->GetInt( "area" ); |
|
} |
|
} |
|
else if ( FStrEq( "controlpoint_endtouch", eventname ) ) |
|
{ |
|
int iPlayer = event->GetInt( "player" ); |
|
if ( pPlayer && iPlayer == pPlayer->entindex() ) |
|
{ |
|
Assert( m_iCurrentCP == event->GetInt( "area" ) ); |
|
m_iCurrentCP = -1; |
|
} |
|
} |
|
else if ( FStrEq( "teamplay_round_start", eventname ) ) |
|
{ |
|
m_iCurrentCP = -1; |
|
} |
|
else if ( FStrEq( "controlpoint_fake_capture", eventname ) ) |
|
{ |
|
int iPlayer = event->GetInt( "player" ); |
|
if ( pPlayer && iPlayer == pPlayer->entindex() ) |
|
{ |
|
m_iCurrentCP = event->GetInt( "int_data" ); |
|
m_bFakingCapture = true; |
|
m_bFakingMultCapture = false; |
|
m_flFakeCaptureTime = gpGlobals->curtime + 5.0; |
|
} |
|
} |
|
else if ( FStrEq( "controlpoint_fake_capture_mult", eventname ) ) |
|
{ |
|
int iPlayer = event->GetInt( "player" ); |
|
if ( pPlayer && iPlayer == pPlayer->entindex() ) |
|
{ |
|
m_iCurrentCP = event->GetInt( "int_data" ); |
|
m_bFakingCapture = true; |
|
m_bFakingMultCapture = true; |
|
m_flFakeCaptureTime = gpGlobals->curtime + 5.0; |
|
|
|
// Trace forward & find the world |
|
trace_t tr; |
|
Vector vecEnd; |
|
VectorMA( MainViewOrigin(), MAX_TRACE_LENGTH, MainViewForward(), vecEnd ); |
|
UTIL_TraceLine( MainViewOrigin(), vecEnd, MASK_SOLID_BRUSHONLY, pPlayer, COLLISION_GROUP_NONE, &tr ); |
|
if ( !tr.startsolid && tr.fraction < 1.0 ) |
|
{ |
|
Vector vecPositions[INTRO_NUM_FAKE_PLAYERS] = |
|
{ |
|
Vector( 100, 100, 0 ), |
|
Vector( 0, -100, 0 ), |
|
Vector( -100, 0, 0 ), |
|
}; |
|
const char *pszModels[INTRO_NUM_FAKE_PLAYERS] = |
|
{ |
|
"models/player/engineer.mdl", |
|
"models/player/medic.mdl", |
|
"models/player/soldier.mdl", |
|
}; |
|
for ( int i = 0; i < INTRO_NUM_FAKE_PLAYERS; i++ ) |
|
{ |
|
m_pFakePlayers[i] = new C_BaseAnimating; |
|
if ( m_pFakePlayers[i]->InitializeAsClientEntity( pszModels[i], RENDER_GROUP_OPAQUE_ENTITY ) ) |
|
{ |
|
Vector vecOrigin = tr.endpos + vecPositions[i]; |
|
m_pFakePlayers[i]->SetAbsOrigin( vecOrigin ); |
|
m_pFakePlayers[i]->SetAbsAngles( QAngle(0,RandomInt(0,360),0) ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
else if ( FStrEq( "intro_finish", eventname ) ) |
|
{ |
|
int iPlayer = event->GetInt( "player" ); |
|
if ( pPlayer && iPlayer == pPlayer->entindex() ) |
|
{ |
|
m_iCurrentCP = -1; |
|
m_bFakingCapture = false; |
|
m_bFakingMultCapture = false; |
|
m_flFakeCaptureTime = 0; |
|
|
|
for ( int i = 0; i < INTRO_NUM_FAKE_PLAYERS; i++ ) |
|
{ |
|
if ( m_pFakePlayers[i] ) |
|
{ |
|
m_pFakePlayers[i]->Release(); |
|
m_pFakePlayers[i] = NULL; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
|