summaryrefslogtreecommitdiff
path: root/game/client/dod/dod_hud_objectiveicons.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/dod/dod_hud_objectiveicons.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/dod/dod_hud_objectiveicons.cpp')
-rw-r--r--game/client/dod/dod_hud_objectiveicons.cpp903
1 files changed, 903 insertions, 0 deletions
diff --git a/game/client/dod/dod_hud_objectiveicons.cpp b/game/client/dod/dod_hud_objectiveicons.cpp
new file mode 100644
index 0000000..0fb260a
--- /dev/null
+++ b/game/client/dod/dod_hud_objectiveicons.cpp
@@ -0,0 +1,903 @@
+//========= 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/ISurface.h>
+#include "c_baseplayer.h"
+#include <vgui_controls/Panel.h>
+#include "dod_gamerules.h"
+#include "iclientmode.h"
+#include "c_dod_objective_resource.h"
+#include "c_dod_playerresource.h"
+#include "c_dod_player.h"
+#include "VGuiMatSurface/IMatSystemSurface.h"
+#include "hud_macros.h"
+#include <baseviewport.h> //for IViewPortPanel
+#include "spectatorgui.h"
+#include "dod_round_timer.h"
+#include "vgui_controls/AnimationController.h"
+#include "dod_hud_freezepanel.h"
+
+class CHudObjectiveIcons : public CHudElement, public vgui::Panel
+{
+public:
+ DECLARE_CLASS_SIMPLE( CHudObjectiveIcons, vgui::Panel );
+
+ CHudObjectiveIcons( const char *pName );
+
+ virtual void ApplySchemeSettings( IScheme *scheme );
+ virtual void Paint();
+ virtual void Init();
+ virtual void VidInit();
+ virtual void Reset();
+
+ virtual void FireGameEvent( IGameEvent *event );
+
+ void DrawBackgroundBox( int xpos, int ypos, int nBoxWidth, int nBoxHeight, bool bCutCorner );
+
+ virtual bool IsVisible( void );
+
+private:
+
+ vgui::Label *m_pTimer;
+ vgui::Label *m_pTimeAdded;
+
+ CHudTexture *m_pIconDefended;
+
+ int m_iCPTextures[8];
+ int m_iCPCappingTextures[8];
+
+ int m_iBackgroundTexture;
+ Color m_clrBackground;
+ Color m_clrBorder;
+
+ int m_iLastCP; // the index of the area we were last in
+
+ CHudTexture *m_pC4Icon;
+ CHudTexture *m_pExplodedIcon;
+ CHudTexture *m_pC4PlantedBG;
+
+ int m_iSecondsAdded; // how many seconds were added in the last time_added event
+ bool bInTimerWarningAnim;
+ float m_flDrawTimeAddedUntil;
+
+ CPanelAnimationVar( vgui::HFont, m_hTimerFont, "TimerFont", "Default" );
+ CPanelAnimationVar( vgui::HFont, m_hTimerFontSmall, "TimerFontSmall", "DefaultSmall" );
+
+ CPanelAnimationVar( vgui::HFont, m_hTextFont, "ChatFont", "Default" );
+
+ CPanelAnimationVarAliasType( int, m_nIconSize, "iconsize", "24", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_nSeparatorWidth, "separator_width", "7", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_nCornerCutSize, "CornerCutSize", "5", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_nBackgroundOverlap, "BackgroundOverlap", "5", "proportional_int" );
+
+ CPanelAnimationVarAliasType( int, m_iIconStartX, "icon_start_x", "10", "proportional_int" );
+ CPanelAnimationVarAliasType( int, m_iIconStartY, "icon_start_y", "10", "proportional_int" );
+ CPanelAnimationVarAliasType( float, m_flIconExpand, "icon_expand", "0", "proportional_float" );
+
+ CPanelAnimationVar( Color, m_clrTimer, "TimerBG", "255 0 0 128" );
+
+ CPanelAnimationVarAliasType( int, m_nTimeAddedHeight, "time_added_height", "12", "proportional_int" );
+ CPanelAnimationVar( float, m_flTimeAddedExpandPercent, "time_added_height_anim", "0.0" );
+ CPanelAnimationVar( float, m_flTimeAddedAlpha, "time_added_alpha", "0" );
+
+ CPanelAnimationVar( float, m_flTimeAddedDuration, "time_added_duration", "3.5" );
+};
+
+DECLARE_HUDELEMENT( CHudObjectiveIcons );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CHudObjectiveIcons::CHudObjectiveIcons( const char *pName ) : vgui::Panel( NULL, "HudObjectiveIcons" ), CHudElement( pName )
+{
+ SetParent( g_pClientMode->GetViewport() );
+ SetHiddenBits( 0 );
+
+ m_pTimer = new vgui::Label( this, "HudObjectivesRoundTimer", " " );
+ if ( m_pTimer )
+ {
+ m_pTimer->SetContentAlignment( Label::a_center );
+ }
+
+ m_pTimeAdded = new vgui::Label( this, "HudObjectivesTimeAdded", " " );
+ if ( m_pTimeAdded )
+ {
+ m_pTimeAdded->SetContentAlignment( Label::a_center );
+ }
+
+ m_iBackgroundTexture = vgui::surface()->DrawGetTextureId( "vgui/white" );
+ if ( m_iBackgroundTexture == -1 )
+ {
+ m_iBackgroundTexture = vgui::surface()->CreateNewTextureID();
+ }
+ vgui::surface()->DrawSetTextureFile( m_iBackgroundTexture, "vgui/white", true, true );
+
+ m_iLastCP = -1;
+
+ m_iSecondsAdded = 0;
+ bInTimerWarningAnim = false;
+
+ m_flDrawTimeAddedUntil = -1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudObjectiveIcons::Init( void )
+{
+ for( int i = 0 ; i < 8 ; i++ )
+ {
+ m_iCPTextures[i] = vgui::surface()->CreateNewTextureID();
+ m_iCPCappingTextures[i] = vgui::surface()->CreateNewTextureID();
+ }
+
+ ListenForGameEvent( "dod_timer_time_added" );
+ ListenForGameEvent( "dod_timer_flash" );
+}
+
+void CHudObjectiveIcons::VidInit( void )
+{
+ m_flTimeAddedExpandPercent = 0.0;
+ m_flTimeAddedAlpha = 0.0;
+ m_flDrawTimeAddedUntil = -1;
+
+ CHudElement::VidInit();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudObjectiveIcons::Reset( void )
+{
+ m_iLastCP = -1;
+ m_flIconExpand = 0;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CHudObjectiveIcons::IsVisible( void )
+{
+ if ( IsTakingAFreezecamScreenshot() )
+ return false;
+
+ return BaseClass::IsVisible();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudObjectiveIcons::FireGameEvent( IGameEvent *event )
+{
+ const char *eventname = event->GetName();
+
+ if ( FStrEq( "dod_timer_time_added", eventname ) )
+ {
+ // show time added under the timer, flash
+ m_iSecondsAdded = event->GetInt( "seconds_added" );
+
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "TimerFlash" );
+
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "ShowTimeAdded" );
+
+ if ( !m_pTimeAdded->IsVisible() )
+ {
+ m_pTimeAdded->SetVisible( true );
+ }
+
+ wchar_t wText[12];
+
+ int iSecondsToDraw = abs(m_iSecondsAdded);
+ bool bNegative = ( m_iSecondsAdded < 0 );
+
+#ifdef WIN32
+ _snwprintf( wText, sizeof(wText)/sizeof(wchar_t), L"%s %d:%02d", bNegative ? L"-" : L"+", iSecondsToDraw / 60, iSecondsToDraw % 60 );
+#else
+ _snwprintf( wText, sizeof(wText)/sizeof(wchar_t), L"%S %d:%02d", bNegative ? L"-" : L"+", iSecondsToDraw / 60, iSecondsToDraw % 60 );
+#endif
+
+ m_pTimeAdded->SetText( wText );
+
+ m_flDrawTimeAddedUntil = gpGlobals->curtime + m_flTimeAddedDuration;
+
+ }
+ else if ( FStrEq( "dod_timer_flash", eventname ) )
+ {
+ // generic flash, used for 5, 2, 1 minute warnings
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "TimerFlash" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudObjectiveIcons::ApplySchemeSettings( IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ m_hTextFont = pScheme->GetFont( "ChatFont" );
+ m_hTimerFontSmall = pScheme->GetFont( "TimerFontSmall" );
+
+ m_clrBackground = pScheme->GetColor( "HudPanelBackground", GetFgColor() );
+ m_clrBorder = pScheme->GetColor( "HudPanelBorder", GetBgColor() );
+
+ m_pC4Icon = gHUD.GetIcon( "icon_c4" );
+ m_pExplodedIcon = gHUD.GetIcon( "icon_c4_exploded" );
+ m_pC4PlantedBG = gHUD.GetIcon( "icon_c4_planted_bg" );
+ m_pIconDefended = gHUD.GetIcon( "icon_defended" );
+
+ m_pTimer->SetFont( m_hTimerFont );
+ m_pTimeAdded->SetFont( m_hTimerFontSmall );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudObjectiveIcons::DrawBackgroundBox( int xpos, int ypos, int nBoxWidth, int nBoxHeight, bool bCutCorner )
+{
+ int nCornerCutSize = bCutCorner ? m_nCornerCutSize : 0;
+ vgui::Vertex_t verts[5];
+
+ verts[0].Init( Vector2D( xpos, ypos ) );
+ verts[1].Init( Vector2D( xpos + nBoxWidth, ypos ) );
+ verts[2].Init( Vector2D( xpos + nBoxWidth + 1, ypos + nBoxHeight - nCornerCutSize + 1 ) );
+ verts[3].Init( Vector2D( xpos + nBoxWidth - nCornerCutSize + 1, ypos + nBoxHeight + 1 ) );
+ verts[4].Init( Vector2D( xpos, ypos + nBoxHeight ) );
+
+ vgui::surface()->DrawSetTexture( m_iBackgroundTexture );
+ vgui::surface()->DrawSetColor( Color( m_clrBackground ) );
+ vgui::surface()->DrawTexturedPolygon( 5, verts );
+
+ vgui::Vertex_t borderverts[5];
+
+ borderverts[0].Init( Vector2D( xpos, ypos ) );
+ borderverts[1].Init( Vector2D( xpos + nBoxWidth, ypos ) );
+ borderverts[2].Init( Vector2D( xpos + nBoxWidth, ypos + nBoxHeight - nCornerCutSize ) );
+ borderverts[3].Init( Vector2D( xpos + nBoxWidth - nCornerCutSize, ypos + nBoxHeight ) );
+ borderverts[4].Init( Vector2D( xpos, ypos + nBoxHeight ) );
+
+ vgui::surface()->DrawSetColor( Color( m_clrBorder ) );
+ vgui::surface()->DrawTexturedPolyLine( borderverts, 5 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CHudObjectiveIcons::Paint()
+{
+ int ypos = m_iIconStartY;
+ int xpos = m_iIconStartX;
+ static Color clrIcon( 255, 255, 255, 255 );
+
+ if( !g_pObjectiveResource ) // MATTTODO: hasn't been transmited yet .. fix ?
+ {
+ return;
+ }
+
+ // Hide the time added if it is time to do so
+ if ( m_flDrawTimeAddedUntil > 0 && m_flDrawTimeAddedUntil < gpGlobals->curtime )
+ {
+ g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HideTimeAdded" );
+
+ m_flDrawTimeAddedUntil = -1;
+ }
+
+ vgui::surface()->DrawSetTextFont( m_hTextFont );
+ vgui::surface()->DrawSetColor( clrIcon );
+
+ if ( g_pSpectatorGUI && g_pSpectatorGUI->IsVisible() )
+ {
+ ypos += g_pSpectatorGUI->GetTopBarHeight();
+ }
+
+ int num = g_pObjectiveResource->GetNumControlPoints();
+ bool bShowTimer = ( g_DODRoundTimer != NULL );
+
+ if ( num <= 0 && !bShowTimer )
+ {
+ if ( m_pTimer && m_pTimer->IsVisible() )
+ {
+ m_pTimer->SetVisible( false );
+ }
+
+ if ( m_pTimeAdded && m_pTimeAdded->IsVisible() )
+ {
+ m_pTimeAdded->SetVisible( false );
+ }
+
+ return; // nothing to draw yet
+ }
+
+ int iLastVisible = 0;
+
+ int k;
+
+ // let's count how many visible capture points we have (for cutting the corner of the last visible one)
+ for( k = 0 ; k < num ; k++ )
+ {
+ if( g_pObjectiveResource->IsCPVisible( k ) )
+ {
+ iLastVisible = k;
+ }
+ }
+
+ // do we have a round timer?
+ if( bShowTimer )
+ {
+ if ( m_pTimer )
+ {
+ if ( !m_pTimer->IsVisible() )
+ {
+ m_pTimer->SetVisible( true );
+ }
+
+ m_pTimer->SetBounds( xpos, ypos, 2 * m_nIconSize, m_nIconSize );
+ m_pTimer->SetBgColor( m_clrTimer );
+
+ m_pTimeAdded->SetBounds( xpos, ypos + m_nIconSize, 2 * m_nIconSize, m_nTimeAddedHeight + m_nBackgroundOverlap );
+ m_pTimeAdded->SetBgColor( Color(0,0,0,0) );
+
+ int iRoundTime = (int)g_DODRoundTimer->GetTimeRemaining();
+
+ int minutes = iRoundTime / 60;
+ int seconds = iRoundTime % 60;
+
+ if( minutes < 0 ) minutes = 0;
+ if( minutes > 99 ) minutes = 99;
+ if( seconds < 0 ) seconds = 0;
+
+ // cut the corner if this is all we're drawing
+
+ // figure out the height. will change if we're drawing the +1:00 below it
+ int boxHeight = 2*m_nBackgroundOverlap + m_nIconSize + (int)( (float)m_nTimeAddedHeight * m_flTimeAddedExpandPercent );
+
+ DrawBackgroundBox( xpos - m_nBackgroundOverlap, ypos - m_nBackgroundOverlap, m_pTimer->GetWide() + 2 * m_nBackgroundOverlap, boxHeight, ( num <= 0 ) ? true : false );
+
+ // set the time
+ char szTime[16];
+ Q_snprintf( szTime, sizeof( szTime ), "%02d:%02d", minutes, seconds );
+ m_pTimer->SetText( szTime );
+
+ m_pTimeAdded->SetAlpha( (int)m_flTimeAddedAlpha );
+
+ xpos += ( m_pTimer->GetWide() + m_nSeparatorWidth + m_nBackgroundOverlap * 2 );
+ }
+ }
+ else
+ {
+ if ( m_pTimer && m_pTimer->IsVisible() )
+ {
+ m_pTimer->SetVisible( false );
+ }
+ }
+
+ C_DODPlayer *pPlayer = C_DODPlayer::GetLocalDODPlayer();
+ int iCurrentCapAreaIndex = pPlayer->GetCPIndex();
+
+ if ( pPlayer->IsAlive() == false )
+ {
+ m_iLastCP = -1;
+ }
+
+ int index;
+
+ for( index = 0 ; index < num ; index++ )
+ {
+ if( g_pObjectiveResource->IsCPVisible( index ) )
+ {
+ int iOwnerIcon = g_pObjectiveResource->GetCPCurrentOwnerIcon( index );
+
+ float uv1 = 0.0f;
+ float uv2 = 1.0f;
+
+ float flXPos = (float)xpos;
+ float flYPos = (float)ypos;
+ float flIconSize = (float)m_nIconSize;
+
+ if ( index == iCurrentCapAreaIndex )
+ {
+ // animate the current cp
+ flXPos -= m_flIconExpand;
+ flYPos -= m_flIconExpand;
+ flIconSize += m_flIconExpand*2;
+
+ m_iLastCP = iCurrentCapAreaIndex;
+ }
+ else if ( m_iLastCP == index )
+ {
+ // as a backup, animate out of the one we just left
+ flXPos -= m_flIconExpand;
+ flYPos -= m_flIconExpand;
+ flIconSize += m_flIconExpand*2;
+ }
+
+
+ int iBombsRequired = g_pObjectiveResource->GetBombsRequired( index );
+
+ if ( iBombsRequired > 0 )
+ {
+ DrawBackgroundBox( flXPos - m_nBackgroundOverlap, flYPos - m_nBackgroundOverlap, flIconSize + 2 * m_nBackgroundOverlap, flIconSize + 2 * m_nBackgroundOverlap + m_nTimeAddedHeight, ( index != iLastVisible ) ? false : true );
+ }
+ else
+ {
+ DrawBackgroundBox( flXPos - m_nBackgroundOverlap, flYPos - m_nBackgroundOverlap, flIconSize + 2 * m_nBackgroundOverlap, flIconSize + 2 * m_nBackgroundOverlap, ( index != iLastVisible ) ? false : true );
+ }
+
+ // Draw the background for the icon
+
+ // allow for error
+ if ( g_pObjectiveResource->IsBombSetAtPoint( index ) )
+ {
+ // if bomb timer is > 0, draw swipe
+ float flBombTime = g_pObjectiveResource->GetBombTimeForPoint( index ); // round up
+
+ // draw the 'white' version underneath
+ int iBlankIcon = g_pObjectiveResource->GetCPTimerCapIcon( index );
+
+ if ( iBlankIcon == 0 )
+ {
+ iBlankIcon = g_pObjectiveResource->GetIconForTeam( index, TEAM_UNASSIGNED );
+ }
+
+ const char *szMatName = GetMaterialNameFromIndex( iBlankIcon );
+
+ vgui::surface()->DrawSetTextureFile( m_iCPTextures[index], szMatName, true, false );
+
+ Vector2D uv11( uv1, uv1 );
+ Vector2D uv21( uv2, uv1 );
+ Vector2D uv22( uv2, uv2 );
+ Vector2D uv12( uv1, uv2 );
+
+ vgui::Vertex_t vert[4];
+ vert[0].Init( Vector2D( flXPos, flYPos ), uv11 );
+ vert[1].Init( Vector2D( flXPos + flIconSize, flYPos ), uv21 );
+ vert[2].Init( Vector2D( flXPos + flIconSize, flYPos + flIconSize ), uv22 );
+ vert[3].Init( Vector2D( flXPos, flYPos + flIconSize ), uv12 );
+
+ vgui::surface()->DrawSetColor( Color(255,255,255,255) );
+ vgui::surface()->DrawTexturedPolygon( 4, vert );
+
+ // draw the real version in a circular swipe
+ float flPercentRemaining = ( flBombTime / DOD_BOMB_TIMER_LENGTH );
+
+ float flHalfWide = (float)flIconSize / 2.0f;
+ float flHalfTall = (float)flIconSize / 2.0f;
+
+ const float flCompleteCircle = ( 2.0f * M_PI );
+ const float fl90degrees = flCompleteCircle * 0.25f;
+ const float fl45degrees = fl90degrees * 0.5f;
+
+ float flEndAngle = flCompleteCircle * flPercentRemaining; // clockwise
+
+ typedef struct
+ {
+ Vector2D vecTrailing;
+ Vector2D vecLeading;
+ } icon_quadrant_t;
+
+ /*
+ Quadrants are numbered 0 - 7 counter-clockwise
+ _________________
+ | 0 | 7 |
+ | | |
+ | 1 | 6 |
+ -----------------
+ | 2 | 5 |
+ | | |
+ | 3 | 4 |
+ -----------------
+ */
+
+ // Encode the leading and trailing edge of each quadrant
+ // in the range 0.0 -> 1.0
+
+ icon_quadrant_t quadrants[8];
+ quadrants[0].vecTrailing.Init( 0.5, 0.0 );
+ quadrants[0].vecLeading.Init( 0.0, 0.0 );
+
+ quadrants[1].vecTrailing.Init( 0.0, 0.0 );
+ quadrants[1].vecLeading.Init( 0.0, 0.5 );
+
+ quadrants[2].vecTrailing.Init( 0.0, 0.5 );
+ quadrants[2].vecLeading.Init( 0.0, 1.0 );
+
+ quadrants[3].vecTrailing.Init( 0.0, 1.0 );
+ quadrants[3].vecLeading.Init( 0.5, 1.0 );
+
+ quadrants[4].vecTrailing.Init( 0.5, 1.0 );
+ quadrants[4].vecLeading.Init( 1.0, 1.0 );
+
+ quadrants[5].vecTrailing.Init( 1.0, 1.0 );
+ quadrants[5].vecLeading.Init( 1.0, 0.5 );
+
+ quadrants[6].vecTrailing.Init( 1.0, 0.5 );
+ quadrants[6].vecLeading.Init( 1.0, 0.0 );
+
+ quadrants[7].vecTrailing.Init( 1.0, 0.0 );
+ quadrants[7].vecLeading.Init( 0.5, 0.0 );
+
+ szMatName = GetMaterialNameFromIndex( iOwnerIcon );
+
+ vgui::surface()->DrawSetTextureFile( m_iCPTextures[index], szMatName, true, false );
+ vgui::surface()->DrawSetColor( Color(255,255,255,255) );
+
+ Vector2D uvMid( 0.5, 0.5 );
+ Vector2D vecMid( flXPos + flHalfWide, flYPos + flHalfTall );
+
+ int j;
+ for ( j=0;j<=7;j++ )
+ {
+ float flMinAngle = j * fl45degrees;
+
+ float flAngle = clamp( flEndAngle - flMinAngle, 0, fl45degrees );
+
+ if ( flAngle <= 0 )
+ {
+ // past our quadrant, draw nothing
+ continue;
+ }
+ else
+ {
+ // draw our segment
+ vgui::Vertex_t vert[3];
+
+ // vert 0 is mid ( 0.5, 0.5 )
+ vert[0].Init( vecMid, uvMid );
+
+ int xdir = 0, ydir = 0;
+
+ switch( j )
+ {
+ case 0:
+ case 7:
+ //right
+ xdir = 1;
+ ydir = 0;
+ break;
+
+ case 1:
+ case 2:
+ //up
+ xdir = 0;
+ ydir = -1;
+ break;
+
+ case 3:
+ case 4:
+ //left
+ xdir = -1;
+ ydir = 0;
+ break;
+
+ case 5:
+ case 6:
+ //down
+ xdir = 0;
+ ydir = 1;
+ break;
+ }
+
+ Vector2D vec1;
+ Vector2D uv1;
+
+ // vert 1 is the variable vert based on leading edge
+ vec1.x = flXPos + quadrants[j].vecTrailing.x * flIconSize - xdir * tan(flAngle) * flHalfWide;
+ vec1.y = flYPos + quadrants[j].vecTrailing.y * flIconSize - ydir * tan(flAngle) * flHalfTall;
+
+ uv1.x = quadrants[j].vecTrailing.x - xdir * abs( quadrants[j].vecLeading.x - quadrants[j].vecTrailing.x ) * tan(flAngle);
+ uv1.y = quadrants[j].vecTrailing.y - ydir * abs( quadrants[j].vecLeading.y - quadrants[j].vecTrailing.y ) * tan(flAngle);
+
+ vert[1].Init( vec1, uv1 );
+
+ // vert 2 is our trailing edge
+ vert[2].Init( Vector2D( flXPos + quadrants[j].vecTrailing.x * flIconSize,
+ flYPos + quadrants[j].vecTrailing.y * flIconSize ),
+ quadrants[j].vecTrailing );
+
+ vgui::surface()->DrawTexturedPolygon( 3, vert );
+ }
+ }
+
+ if ( g_pObjectiveResource->IsBombBeingDefused( index ) )
+ {
+ float flSize = 0.75;
+ int iconX = (int)( flXPos + flIconSize * ( ( 1.0 - flSize ) / 2 ) );
+ int iconY = (int)( flYPos + flIconSize * ( ( 1.0 - flSize ) / 2 ) );
+ int iconW = (int)( flIconSize * flSize );
+
+ Color c(255,255,255,255);
+ m_pIconDefended->DrawSelf( iconX, iconY, iconW, iconW, c );
+ }
+ }
+ else
+ {
+ // Draw the owner's icon
+ if( iOwnerIcon != 0 )
+ {
+ const char *szMatName = GetMaterialNameFromIndex( iOwnerIcon );
+
+ vgui::surface()->DrawSetTextureFile( m_iCPTextures[index], szMatName, true, false );
+
+ /*
+ // re-enable if we want to have animating cp icons
+ // todo: framerate
+ IVguiMatInfo *pMat = vgui::surface()->DrawGetTextureMatInfoFactory( m_iCPTextures[index] );
+
+ if ( !pMat )
+ return;
+
+ int iNumFrames = pMat->GetNumAnimationFrames();
+
+ IVguiMatInfoVar *m_pFrameVar;
+
+ bool bFound = false;
+ m_pFrameVar = pMat->FindVarFactory( "$frame", &bFound );
+
+ static int frame = 0;
+
+ if ( bFound )
+ {
+ frame++;
+ m_pFrameVar->SetIntValue( frame % iNumFrames );
+ }
+ */
+
+ Vector2D uv11( uv1, uv1 );
+ Vector2D uv21( uv2, uv1 );
+ Vector2D uv22( uv2, uv2 );
+ Vector2D uv12( uv1, uv2 );
+
+ vgui::Vertex_t vert[4];
+ vert[0].Init( Vector2D( flXPos, flYPos ), uv11 );
+ vert[1].Init( Vector2D( flXPos + flIconSize, flYPos ), uv21 );
+ vert[2].Init( Vector2D( flXPos + flIconSize, flYPos + flIconSize ), uv22 );
+ vert[3].Init( Vector2D( flXPos, flYPos + flIconSize ), uv12 );
+
+ vgui::surface()->DrawSetColor( Color(255,255,255,255) );
+ vgui::surface()->DrawTexturedPolygon( 4, vert );
+ }
+ }
+
+ // see if there are players in the area
+ int iNumAllies = g_pObjectiveResource->GetNumPlayersInArea( index, TEAM_ALLIES );
+ int iNumAxis = g_pObjectiveResource->GetNumPlayersInArea( index, TEAM_AXIS );
+
+ int iCappingTeam = g_pObjectiveResource->GetCappingTeam( index );
+
+ // Draw bomb icons under cap points
+ if ( iBombsRequired > 0 )
+ {
+ int iBombsRemaining = g_pObjectiveResource->GetBombsRemaining( index );
+
+ bool bBombPlanted = g_pObjectiveResource->IsBombSetAtPoint( index );
+
+ int yIcon = ypos + flIconSize + YRES(2);
+
+ int iIconHalfWidth = XRES(5);
+ int iIconWidth = iIconHalfWidth * 2;
+
+ Color c(255,255,255,255);
+
+ switch( iBombsRequired )
+ {
+ case 1:
+ {
+ int xMid = xpos + ( flIconSize * 0.50f );
+
+ switch( iBombsRemaining )
+ {
+ case 0:
+ m_pExplodedIcon->DrawSelf( xMid - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
+ break;
+ case 1:
+ if ( bBombPlanted )
+ {
+ // draw the background behind 1
+ int alpha = (float)( abs( sin(2*gpGlobals->curtime) ) * 205.0 + 50.0 );
+ m_pC4PlantedBG->DrawSelf( xMid - iIconWidth, yIcon - iIconHalfWidth, iIconWidth*2, iIconWidth*2, Color( 255,255,255,alpha) );
+ }
+ m_pC4Icon->DrawSelf( xMid - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
+ break;
+ }
+ }
+ break;
+ case 2:
+ {
+ int xMid1 = xpos + ( flIconSize * 0.25f );
+ int xMid2 = xpos + ( flIconSize * 0.75f );
+
+ switch( iBombsRemaining )
+ {
+ case 0:
+ m_pExplodedIcon->DrawSelf( xMid1 - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
+ m_pExplodedIcon->DrawSelf( xMid2 - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
+ break;
+ case 1:
+ if ( bBombPlanted )
+ {
+ // draw the background behind 1
+ int alpha = (float)( abs( sin(2*gpGlobals->curtime) ) * 205.0 + 50.0 );
+ m_pC4PlantedBG->DrawSelf( xMid1 - iIconWidth, yIcon - iIconHalfWidth, iIconWidth*2, iIconWidth*2, Color( 255,255,255,alpha) );
+ }
+ m_pC4Icon->DrawSelf( xMid1 - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
+ m_pExplodedIcon->DrawSelf( xMid2 - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
+ break;
+ case 2:
+ if ( bBombPlanted )
+ {
+ // draw the background behind 2
+ int alpha = (float)( abs( sin(2*gpGlobals->curtime) ) * 205.0 + 50.0 );
+ m_pC4PlantedBG->DrawSelf( xMid2 - iIconWidth, yIcon - iIconHalfWidth, iIconWidth*2, iIconWidth*2, Color( 255,255,255,alpha) );
+ }
+ m_pC4Icon->DrawSelf( xMid1 - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
+ m_pC4Icon->DrawSelf( xMid2 - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
+ break;
+ }
+ }
+ break;
+ default:
+ {
+ // general solution for > 2 bombs
+
+ if ( iBombsRemaining > 0 )
+ {
+ // draw a bomb icon, then a 'x 3' for how many there are remaining
+
+ if ( bBombPlanted )
+ {
+ // draw the background behind 2
+ int alpha = (float)( abs( sin( 2*gpGlobals->curtime) ) * 205.0 + 50.0 );
+ m_pC4PlantedBG->DrawSelf( xpos - iIconHalfWidth, yIcon - iIconHalfWidth, iIconWidth*2, iIconWidth*2, Color( 255,255,255,alpha) );
+ }
+
+ m_pC4Icon->DrawSelf( xpos, yIcon, iIconWidth, iIconWidth, c );
+
+ // draw text saying how many bombs there are
+ {
+ wchar_t wText[6];
+ _snwprintf( wText, sizeof(wText)/sizeof(wchar_t), L"x %d", iBombsRemaining );
+
+ vgui::surface()->DrawSetTextColor( g_PR->GetTeamColor( TEAM_SPECTATOR ) );
+
+ // set pos centered under icon
+ vgui::surface()->DrawSetTextPos( xpos + ( flIconSize * 0.50f ), yIcon + YRES(2) );
+
+ for ( wchar_t *wch = wText ; *wch != 0 ; wch++ )
+ {
+ vgui::surface()->DrawUnicodeChar( *wch );
+ }
+ }
+
+ }
+ else
+ {
+ int xMid = xpos + ( flIconSize * 0.50f );
+ m_pExplodedIcon->DrawSelf( xMid - iIconHalfWidth, yIcon, iIconWidth, iIconWidth, c );
+ }
+ }
+ break;
+ }
+ }
+
+ // see if one team is partially capping,
+ // should show a 1/2 under the cap icon
+ if ( iCappingTeam == TEAM_UNASSIGNED )
+ {
+ if ( iNumAllies > 0 && iNumAxis == 0 )
+ {
+ iCappingTeam = TEAM_ALLIES;
+ }
+ else if ( iNumAxis > 0 && iNumAllies == 0 )
+ {
+ iCappingTeam = TEAM_AXIS;
+ }
+
+ if ( iCappingTeam == TEAM_UNASSIGNED || iCappingTeam == g_pObjectiveResource->GetOwningTeam( index ) )
+ {
+ // no team is capping, even partially
+ // or the person in the area already owns it
+ xpos += ( m_nIconSize + m_nSeparatorWidth + m_nBackgroundOverlap * 2 );
+ continue;
+ }
+ }
+
+ // Draw the number of cappers below the icon
+ int numPlayers = g_pObjectiveResource->GetNumPlayersInArea( index, iCappingTeam );
+ int requiredPlayers = g_pObjectiveResource->GetRequiredCappers( index, iCappingTeam );
+
+ if ( requiredPlayers > 1 )
+ {
+ numPlayers = MIN( numPlayers, requiredPlayers );
+
+ wchar_t wText[6];
+ _snwprintf( wText, sizeof(wText)/sizeof(wchar_t), L"%d/%d", numPlayers, requiredPlayers );
+
+ vgui::surface()->DrawSetTextColor( g_PR->GetTeamColor( iCappingTeam ) );
+
+ // get string length
+ int len = g_pMatSystemSurface->DrawTextLen( m_hTextFont, "2/2" );
+
+ // set pos centered under icon
+ vgui::surface()->DrawSetTextPos( xpos + ( m_nIconSize / 2.0f ) - ( len / 2 ), ypos + flIconSize + m_nBackgroundOverlap + YRES( 2 ) ); // + 2 to account for the outlined box
+
+ for ( wchar_t *wch = wText ; *wch != 0 ; wch++ )
+ {
+ vgui::surface()->DrawUnicodeChar( *wch );
+ }
+ }
+
+ if ( g_pObjectiveResource->GetCappingTeam( index ) != TEAM_UNASSIGNED )
+ {
+ int iCapperIcon = g_pObjectiveResource->GetCPCappingIcon( index );
+
+ // Draw the capper's icon
+ if( iOwnerIcon != iCapperIcon && iCapperIcon != 0 )
+ {
+ // axis caps swipe from right to left...allied from left to right
+ bool bAxis = ( g_pObjectiveResource->GetCappingTeam(index) == TEAM_AXIS ) ? true : false;
+
+ //swipe!
+ float flCapPercentage = g_pObjectiveResource->GetCPCapPercentage(index);
+
+ // reversing the direction of the swipe effect
+ if ( bAxis )
+ {
+ flCapPercentage = 1.0f - g_pObjectiveResource->GetCPCapPercentage(index);
+ }
+
+ float width = ( flIconSize * flCapPercentage );
+ const char *szCappingMatName = GetMaterialNameFromIndex( iCapperIcon );
+
+ vgui::surface()->DrawSetTextureFile( m_iCPCappingTextures[index], szCappingMatName, true, false );
+
+ vgui::Vertex_t vert[4];
+
+ Vector2D uv11( uv1, uv1 );
+ Vector2D uv21( flCapPercentage, uv1 );
+ Vector2D uv22( flCapPercentage, uv2 );
+ Vector2D uv12( uv1, uv2 );
+
+ // reversing the direction of the swipe effect
+ if ( bAxis )
+ {
+ uv11.x = flCapPercentage;
+ uv21.x = uv2;
+ uv22.x = uv2;
+ uv12.x = flCapPercentage;
+ }
+
+ Vector2D upperLeft ( flXPos, flYPos );
+ Vector2D upperRight( flXPos + width, flYPos );
+ Vector2D lowerRight( flXPos + width, flYPos + flIconSize );
+ Vector2D lowerLeft ( flXPos, flYPos + flIconSize );
+
+ /// reversing the direction of the swipe effect
+ if ( bAxis )
+ {
+ upperLeft.x = flXPos + width;
+ upperRight.x = flXPos + flIconSize;
+ lowerRight.x = flXPos + flIconSize;
+ lowerLeft.x = flXPos + width;
+ }
+
+ vert[0].Init( upperLeft, uv11 );
+ vert[1].Init( upperRight, uv21 );
+ vert[2].Init( lowerRight, uv22 );
+ vert[3].Init( lowerLeft, uv12 );
+
+ vgui::surface()->DrawSetColor( Color(255,255,255,255) );
+ vgui::surface()->DrawTexturedPolygon( 4, vert );
+ }
+ }
+
+ xpos += ( m_nIconSize + m_nSeparatorWidth + m_nBackgroundOverlap * 2 );
+ }
+ }
+}