summaryrefslogtreecommitdiff
path: root/game/client/dod/dod_headiconmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/client/dod/dod_headiconmanager.cpp')
-rw-r--r--game/client/dod/dod_headiconmanager.cpp215
1 files changed, 215 insertions, 0 deletions
diff --git a/game/client/dod/dod_headiconmanager.cpp b/game/client/dod/dod_headiconmanager.cpp
new file mode 100644
index 0000000..f24a6f1
--- /dev/null
+++ b/game/client/dod/dod_headiconmanager.cpp
@@ -0,0 +1,215 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================
+#include "cbase.h"
+#include <string.h>
+#include <stdio.h>
+#include "dod_headiconmanager.h"
+#include "c_playerresource.h"
+#include "cliententitylist.h"
+#include "c_baseplayer.h"
+#include "materialsystem/imesh.h"
+#include "view.h"
+#include "materialsystem/imaterial.h"
+#include "tier0/dbg.h"
+#include "cdll_int.h"
+
+#include "dod_shareddefs.h"
+#include "c_dod_player.h"
+#include "voice_status.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+static CHeadIconManager s_HeadIconMgr;
+
+CHeadIconManager* HeadIconManager()
+{
+ return &s_HeadIconMgr;
+}
+
+CHeadIconManager::CHeadIconManager()
+{
+ m_pAlliesIconMaterial = NULL;
+ m_pAxisIconMaterial = NULL;
+}
+
+CHeadIconManager::~CHeadIconManager()
+{
+ Shutdown();
+}
+
+bool CHeadIconManager::Init()
+{
+ if ( !m_pAlliesIconMaterial )
+ {
+ m_pAlliesIconMaterial = materials->FindMaterial( "sprites/player_icons/american", TEXTURE_GROUP_VGUI );
+ }
+
+ if ( !m_pAxisIconMaterial )
+ {
+ m_pAxisIconMaterial = materials->FindMaterial( "sprites/player_icons/german", TEXTURE_GROUP_VGUI );
+ }
+
+ if ( IsErrorMaterial( m_pAlliesIconMaterial ) ||
+ IsErrorMaterial( m_pAxisIconMaterial ) )
+ {
+ Assert(!"Can't find head icon materials");
+ return false;
+ }
+
+ m_pAlliesIconMaterial->IncrementReferenceCount();
+ m_pAxisIconMaterial->IncrementReferenceCount();
+ m_PlayerDrawn.ClearAll();
+
+ return true;
+}
+
+void CHeadIconManager::Shutdown()
+{
+ if ( m_pAlliesIconMaterial )
+ {
+ m_pAlliesIconMaterial->DecrementReferenceCount();
+ m_pAlliesIconMaterial = NULL;
+ }
+
+ if ( m_pAxisIconMaterial )
+ {
+ m_pAxisIconMaterial->DecrementReferenceCount();
+ m_pAxisIconMaterial = NULL;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Call from player render calls to indicate a head icon should be drawn for this player this frame
+//-----------------------------------------------------------------------------
+void CHeadIconManager::PlayerDrawn( C_BasePlayer *pPlayer )
+{
+ m_PlayerDrawn.Set( pPlayer->entindex() - 1 );
+}
+
+
+ConVar cl_headiconoffset( "cl_headiconoffset", "24", FCVAR_CHEAT );
+ConVar cl_headiconsize( "cl_headiconsize", "8", FCVAR_CHEAT );
+ConVar cl_identiconmode( "cl_identiconmode", "2", FCVAR_ARCHIVE, "2 - icons over teammates' heads\n1- icons over target teammate\n0 - no head icons" );
+
+void CHeadIconManager::DrawHeadIcons()
+{
+ CMatRenderContextPtr pRenderContext( materials );
+
+ CBitVec<MAX_PLAYERS> playerDrawn = m_PlayerDrawn;
+ m_PlayerDrawn.ClearAll();
+
+ if ( cl_identiconmode.GetInt() <= 0 )
+ return;
+
+ C_DODPlayer *pLocalPlayer = C_DODPlayer::GetLocalDODPlayer();
+
+ if ( !pLocalPlayer )
+ return;
+
+ if ( pLocalPlayer->GetTeamNumber() != TEAM_ALLIES &&
+ pLocalPlayer->GetTeamNumber() != TEAM_AXIS )
+ {
+ return;
+ }
+
+ Vector vUp = CurrentViewUp();
+ Vector vRight = CurrentViewRight();
+ if ( fabs( vRight.z ) > 0.95 ) // don't draw it edge-on
+ return;
+
+ vRight.z = 0;
+ VectorNormalize( vRight );
+
+ float flSize = cl_headiconsize.GetFloat();
+
+ for(int i=0; i < MAX_PLAYERS; i++)
+ {
+ if ( !playerDrawn.IsBitSet( i ) )
+ continue;
+
+ if ( cl_identiconmode.GetInt() == 1 )
+ {
+ // only draw if this player is our status bar target
+ if ( (i+1) != pLocalPlayer->GetIDTarget() )
+ continue;
+ }
+
+ IClientNetworkable *pClient = cl_entitylist->GetClientEntity( i+1 );
+
+ // Don't show an icon if the player is not in our PVS.
+ if ( !pClient || pClient->IsDormant() )
+ continue;
+
+ C_DODPlayer *pPlayer = dynamic_cast<C_DODPlayer*>(pClient);
+ if( !pPlayer )
+ continue;
+
+ // Don't show an icon for dead or spectating players (ie: invisible entities).
+ if( pPlayer->IsPlayerDead() )
+ continue;
+
+ if( pPlayer == pLocalPlayer )
+ continue;
+
+ if( pPlayer->GetTeamNumber() != pLocalPlayer->GetTeamNumber() )
+ continue;
+
+ if ( GetClientVoiceMgr()->IsPlayerSpeaking( i+1 ) )
+ continue;
+
+ if ( C_BasePlayer::GetLocalPlayer()->GetObserverMode() == OBS_MODE_IN_EYE &&
+ C_BasePlayer::GetLocalPlayer()->GetObserverTarget() == pPlayer )
+ continue;
+
+ IMaterial *pMaterial = pPlayer->GetHeadIconMaterial();
+ if ( !pMaterial )
+ continue;
+
+ pRenderContext->Bind( pMaterial );
+
+ Vector vOrigin;
+ QAngle vAngle;
+
+ int iHeadAttach = pPlayer->LookupAttachment( "head" );
+
+ pPlayer->GetAttachment( iHeadAttach, vOrigin, vAngle );
+
+ vOrigin.z += cl_headiconoffset.GetFloat();
+
+ // Align it towards the viewer
+
+ IMesh *pMesh = pRenderContext->GetDynamicMesh();
+ CMeshBuilder meshBuilder;
+ meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
+
+ meshBuilder.Color3f( 1.0, 1.0, 1.0 );
+ meshBuilder.TexCoord2f( 0,0,0 );
+ meshBuilder.Position3fv( (vOrigin + (vRight * -flSize) + (vUp * flSize)).Base() );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color3f( 1.0, 1.0, 1.0 );
+ meshBuilder.TexCoord2f( 0,1,0 );
+ meshBuilder.Position3fv( (vOrigin + (vRight * flSize) + (vUp * flSize)).Base() );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color3f( 1.0, 1.0, 1.0 );
+ meshBuilder.TexCoord2f( 0,1,1 );
+ meshBuilder.Position3fv( (vOrigin + (vRight * flSize) + (vUp * -flSize)).Base() );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Color3f( 1.0, 1.0, 1.0 );
+ meshBuilder.TexCoord2f( 0,0,1 );
+ meshBuilder.Position3fv( (vOrigin + (vRight * -flSize) + (vUp * -flSize)).Base() );
+ meshBuilder.AdvanceVertex();
+ meshBuilder.End();
+ pMesh->Draw();
+ }
+} \ No newline at end of file