mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-14 12:46:58 +00:00
1
This commit is contained in:
@@ -0,0 +1,496 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hudelement.h"
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/ILocalize.h>
|
||||
#include "c_baseplayer.h"
|
||||
#include "voice_status.h"
|
||||
#include "clientmode_shared.h"
|
||||
#include "c_playerresource.h"
|
||||
#include "voice_common.h"
|
||||
#include "vgui_avatarimage.h"
|
||||
|
||||
ConVar *sv_alltalk = NULL;
|
||||
|
||||
//=============================================================================
|
||||
// Icon for the local player using voice
|
||||
//=============================================================================
|
||||
class CHudVoiceSelfStatus : public CHudElement, public vgui::Panel
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS_SIMPLE( CHudVoiceSelfStatus, vgui::Panel );
|
||||
|
||||
CHudVoiceSelfStatus( const char *name );
|
||||
|
||||
virtual bool ShouldDraw();
|
||||
virtual void Paint();
|
||||
virtual void VidInit();
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||
|
||||
private:
|
||||
CHudTexture *m_pVoiceIcon;
|
||||
|
||||
Color m_clrIcon;
|
||||
};
|
||||
|
||||
|
||||
DECLARE_HUDELEMENT( CHudVoiceSelfStatus );
|
||||
|
||||
|
||||
CHudVoiceSelfStatus::CHudVoiceSelfStatus( const char *pName ) :
|
||||
vgui::Panel( NULL, "HudVoiceSelfStatus" ), CHudElement( pName )
|
||||
{
|
||||
SetParent( g_pClientMode->GetViewport() );
|
||||
|
||||
m_pVoiceIcon = NULL;
|
||||
|
||||
SetHiddenBits( 0 );
|
||||
|
||||
m_clrIcon = Color(255,255,255,255);
|
||||
}
|
||||
|
||||
void CHudVoiceSelfStatus::ApplySchemeSettings(vgui::IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
#ifdef HL2MP
|
||||
SetBgColor( Color( 0, 0, 0, 0 ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
void CHudVoiceSelfStatus::VidInit( void )
|
||||
{
|
||||
m_pVoiceIcon = gHUD.GetIcon( "voice_self" );
|
||||
}
|
||||
|
||||
bool CHudVoiceSelfStatus::ShouldDraw()
|
||||
{
|
||||
return GetClientVoiceMgr()->IsLocalPlayerSpeaking();
|
||||
}
|
||||
|
||||
void CHudVoiceSelfStatus::Paint()
|
||||
{
|
||||
if( !m_pVoiceIcon )
|
||||
return;
|
||||
|
||||
int x, y, w, h;
|
||||
GetBounds( x, y, w, h );
|
||||
|
||||
m_pVoiceIcon->DrawSelf( 0, 0, w, h, m_clrIcon );
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// Icons for other players using voice
|
||||
//=============================================================================
|
||||
class CHudVoiceStatus : public CHudElement, public vgui::Panel
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS_SIMPLE( CHudVoiceStatus, vgui::Panel );
|
||||
|
||||
CHudVoiceStatus( const char *name );
|
||||
~CHudVoiceStatus( void );
|
||||
|
||||
virtual bool ShouldDraw();
|
||||
virtual void Paint();
|
||||
virtual void VidInit();
|
||||
virtual void Init();
|
||||
virtual void OnThink();
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||
|
||||
protected:
|
||||
void ClearActiveList();
|
||||
int FindActiveSpeaker( int playerId );
|
||||
|
||||
private:
|
||||
CHudTexture *m_pVoiceIcon;
|
||||
int m_iDeadImageID;
|
||||
|
||||
Color m_clrIcon;
|
||||
|
||||
struct ActiveSpeaker
|
||||
{
|
||||
int playerId;
|
||||
CAvatarImage* pAvatar;
|
||||
bool bSpeaking;
|
||||
float fAlpha;
|
||||
};
|
||||
|
||||
CUtlLinkedList< ActiveSpeaker > m_SpeakingList;
|
||||
// CUtlLinkedList< CAvatarImagePanel* > m_SpeakingListAvatar;
|
||||
|
||||
CPanelAnimationVar( vgui::HFont, m_NameFont, "Default", "Default" );
|
||||
|
||||
CPanelAnimationVarAliasType( float, item_tall, "item_tall", "16", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, item_wide, "item_wide", "160", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, item_spacing, "item_spacing", "2", "proportional_float" );
|
||||
|
||||
CPanelAnimationVarAliasType( bool, show_avatar, "show_avatar", "0", "bool" );
|
||||
CPanelAnimationVarAliasType( bool, show_friend, "show_friend", "1", "bool" );
|
||||
CPanelAnimationVarAliasType( float, avatar_ypos, "avatar_ypos", "0", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, avatar_xpos, "avatar_xpos", "16", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, avatar_tall, "avatar_tall", "16", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, avatar_wide, "avatar_wide", "16", "proportional_float" );
|
||||
|
||||
CPanelAnimationVarAliasType( bool, show_voice_icon, "show_voice_icon", "1", "bool" );
|
||||
CPanelAnimationVarAliasType( float, voice_icon_ypos, "icon_ypos", "0", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, voice_icon_xpos, "icon_xpos", "24", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, voice_icon_tall, "icon_tall", "16", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, voice_icon_wide, "icon_wide", "16", "proportional_float" );
|
||||
|
||||
CPanelAnimationVarAliasType( bool, show_dead_icon, "show_dead_icon", "1", "bool" );
|
||||
CPanelAnimationVarAliasType( float, dead_icon_ypos, "dead_ypos", "0", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, dead_icon_xpos, "dead_xpos", "0", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, dead_icon_tall, "dead_tall", "16", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, dead_icon_wide, "dead_wide", "16", "proportional_float" );
|
||||
|
||||
CPanelAnimationVarAliasType( float, text_xpos, "text_xpos", "40", "proportional_float" );
|
||||
|
||||
CPanelAnimationVarAliasType( float, fade_in_time, "fade_in_time", "0.0", "float" );
|
||||
CPanelAnimationVarAliasType( float, fade_out_time, "fade_out_time", "0.0", "float" );
|
||||
};
|
||||
|
||||
|
||||
DECLARE_HUDELEMENT( CHudVoiceStatus );
|
||||
|
||||
|
||||
CHudVoiceStatus::CHudVoiceStatus( const char *pName ) :
|
||||
vgui::Panel( NULL, "HudVoiceStatus" ), CHudElement( pName )
|
||||
{
|
||||
SetParent( g_pClientMode->GetViewport() );
|
||||
|
||||
m_pVoiceIcon = NULL;
|
||||
|
||||
SetHiddenBits( 0 );
|
||||
|
||||
m_clrIcon = Color(255,255,255,255);
|
||||
|
||||
m_iDeadImageID = surface()->DrawGetTextureId( "hud/leaderboard_dead" );
|
||||
if ( m_iDeadImageID == -1 ) // we didn't find it, so create a new one
|
||||
{
|
||||
m_iDeadImageID = surface()->CreateNewTextureID();
|
||||
surface()->DrawSetTextureFile( m_iDeadImageID, "hud/leaderboard_dead", true, false );
|
||||
}
|
||||
}
|
||||
|
||||
CHudVoiceStatus::~CHudVoiceStatus()
|
||||
{
|
||||
ClearActiveList();
|
||||
}
|
||||
|
||||
void CHudVoiceStatus::ApplySchemeSettings(vgui::IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
#ifdef HL2MP
|
||||
SetBgColor( Color( 0, 0, 0, 0 ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
void CHudVoiceStatus::Init( void )
|
||||
{
|
||||
ClearActiveList();
|
||||
}
|
||||
|
||||
void CHudVoiceStatus::VidInit( void )
|
||||
{
|
||||
m_pVoiceIcon = gHUD.GetIcon( "voice_player" );
|
||||
}
|
||||
|
||||
void CHudVoiceStatus::OnThink( void )
|
||||
{
|
||||
for ( int iPlayerIndex=1; iPlayerIndex<=gpGlobals->maxClients; iPlayerIndex++ )
|
||||
{
|
||||
int activeSpeakerIndex = FindActiveSpeaker(iPlayerIndex);
|
||||
bool bSpeaking = GetClientVoiceMgr()->IsPlayerSpeaking(iPlayerIndex);
|
||||
|
||||
if (activeSpeakerIndex != m_SpeakingList.InvalidIndex() )
|
||||
{
|
||||
// update their speaking status
|
||||
m_SpeakingList[activeSpeakerIndex].bSpeaking = bSpeaking;
|
||||
}
|
||||
else
|
||||
{
|
||||
//=============================================================================
|
||||
// HPE_BEGIN:
|
||||
// [Forrest] Don't use UTIL_PlayerByIndex here. It may be null for some players when
|
||||
// a match starts because the server only passes full player info as it affects
|
||||
// the client.
|
||||
//=============================================================================
|
||||
// if they are talking and not in the list, add them to the end
|
||||
if( bSpeaking )
|
||||
{
|
||||
ActiveSpeaker activeSpeaker;
|
||||
activeSpeaker.playerId = iPlayerIndex;
|
||||
activeSpeaker.bSpeaking = true;
|
||||
activeSpeaker.fAlpha = 0.0f;
|
||||
activeSpeaker.pAvatar = NULL;
|
||||
|
||||
//=============================================================================
|
||||
// HPE_BEGIN:
|
||||
// [pfreese] If a player is now talking set up their avatar
|
||||
//=============================================================================
|
||||
|
||||
activeSpeaker.pAvatar = new CAvatarImage();
|
||||
#ifdef CSTRIKE_DLL
|
||||
// [jpaquin] this allows counter strike to display default avatars for bots. It can't be a virtual function on
|
||||
// C_BasePlayer because there would be no way to get a game specific default image if the player is null.
|
||||
extern vgui::IImage* GetDefaultAvatarImage( C_BasePlayer *pPlayer );
|
||||
activeSpeaker.pAvatar->SetDefaultImage( GetDefaultAvatarImage( UTIL_PlayerByIndex( activeSpeaker.playerId ) ) );
|
||||
#endif
|
||||
activeSpeaker.pAvatar->SetDrawFriend(show_friend);
|
||||
player_info_t pi;
|
||||
if ( engine->GetPlayerInfo( iPlayerIndex, &pi ) )
|
||||
{
|
||||
if ( steamapicontext != NULL && steamapicontext->SteamUtils() != NULL )
|
||||
{
|
||||
CSteamID steamIDForPlayer( pi.friendsID, 1, GetUniverse(), k_EAccountTypeIndividual );
|
||||
activeSpeaker.pAvatar->SetAvatarSteamID(steamIDForPlayer, k_EAvatarSize32x32);
|
||||
}
|
||||
}
|
||||
|
||||
activeSpeaker.pAvatar->SetAvatarSize( avatar_wide, avatar_tall);
|
||||
|
||||
//=============================================================================
|
||||
// HPE_END
|
||||
//=============================================================================
|
||||
|
||||
m_SpeakingList.AddToTail(activeSpeaker);
|
||||
}
|
||||
//=============================================================================
|
||||
// HPE_END
|
||||
//=============================================================================
|
||||
}
|
||||
}
|
||||
|
||||
float fTime = gpGlobals->frametime;
|
||||
|
||||
for ( int i = m_SpeakingList.Head(); i != m_SpeakingList.InvalidIndex(); )
|
||||
{
|
||||
ActiveSpeaker& activeSpeaker = m_SpeakingList[i];
|
||||
|
||||
if (activeSpeaker.bSpeaking)
|
||||
{
|
||||
if ( fade_in_time > 0.0f )
|
||||
{
|
||||
activeSpeaker.fAlpha += fTime / fade_in_time;
|
||||
if ( activeSpeaker.fAlpha > 1.0f )
|
||||
activeSpeaker.fAlpha = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
activeSpeaker.fAlpha = 1.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fade_out_time > 0.0f )
|
||||
{
|
||||
activeSpeaker.fAlpha -= fTime / fade_out_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
activeSpeaker.fAlpha = 0.0f;
|
||||
}
|
||||
|
||||
if ( activeSpeaker.fAlpha <= 0.0f )
|
||||
{
|
||||
// completely faded, remove them them from the list
|
||||
delete activeSpeaker.pAvatar;
|
||||
int iNext = m_SpeakingList.Next(i);
|
||||
m_SpeakingList.Remove(i);
|
||||
i = iNext;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
i = m_SpeakingList.Next(i);
|
||||
}
|
||||
}
|
||||
|
||||
bool CHudVoiceStatus::ShouldDraw()
|
||||
{
|
||||
if ( IsInFreezeCam() == true )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CHudVoiceStatus::Paint()
|
||||
{
|
||||
if( !m_pVoiceIcon )
|
||||
return;
|
||||
|
||||
int x, y, w, h;
|
||||
GetBounds( x, y, w, h );
|
||||
|
||||
// Heights to draw the current voice item at
|
||||
int ypos = h - item_tall;
|
||||
|
||||
int length = m_SpeakingList.Count();
|
||||
|
||||
int iFontHeight = 0;
|
||||
|
||||
if( length > 0 )
|
||||
{
|
||||
surface()->DrawSetTextFont( m_NameFont );
|
||||
surface()->DrawSetTextColor( Color(255,255,255,255) );
|
||||
iFontHeight = surface()->GetFontTall( m_NameFont );
|
||||
}
|
||||
|
||||
if ( !sv_alltalk )
|
||||
sv_alltalk = cvar->FindVar( "sv_alltalk" );
|
||||
|
||||
//draw everyone in the list!
|
||||
FOR_EACH_LL(m_SpeakingList, i)
|
||||
{
|
||||
int playerId = m_SpeakingList[i].playerId;
|
||||
bool bIsAlive = g_PR->IsAlive( playerId );
|
||||
|
||||
float oldAlphaMultiplier = surface()->DrawGetAlphaMultiplier();
|
||||
surface()->DrawSetAlphaMultiplier(oldAlphaMultiplier * m_SpeakingList[i].fAlpha);
|
||||
|
||||
Color c = g_PR->GetTeamColor( g_PR ? g_PR->GetTeam(playerId) : TEAM_UNASSIGNED );
|
||||
|
||||
c[3] = 128;
|
||||
|
||||
const char *pName = g_PR ? g_PR->GetPlayerName(playerId) : "unknown";
|
||||
wchar_t szconverted[ 64 ];
|
||||
|
||||
// Add the location, if any
|
||||
bool usedLocation = false;
|
||||
if ( sv_alltalk && !sv_alltalk->GetBool() )
|
||||
{
|
||||
C_BasePlayer *pPlayer = UTIL_PlayerByIndex( playerId );
|
||||
if ( pPlayer )
|
||||
{
|
||||
const char *asciiLocation = pPlayer->GetLastKnownPlaceName();
|
||||
if ( asciiLocation && *asciiLocation )
|
||||
{
|
||||
const wchar_t *unicodeLocation = g_pVGuiLocalize->Find( asciiLocation );
|
||||
if ( unicodeLocation && *unicodeLocation )
|
||||
{
|
||||
wchar_t *formatStr = g_pVGuiLocalize->Find( "#Voice_UseLocation" );
|
||||
if ( formatStr )
|
||||
{
|
||||
wchar_t unicodeName[ 64 ];
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( pName, unicodeName, sizeof( unicodeName ) );
|
||||
|
||||
g_pVGuiLocalize->ConstructString_safe( szconverted,
|
||||
formatStr, 2, unicodeName, unicodeLocation );
|
||||
|
||||
usedLocation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !usedLocation )
|
||||
{
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( pName, szconverted, sizeof(szconverted) );
|
||||
}
|
||||
|
||||
// Draw the item background
|
||||
surface()->DrawSetColor( c );
|
||||
surface()->DrawFilledRect( 0, ypos, item_wide, ypos + item_tall );
|
||||
|
||||
if ( show_dead_icon && bIsAlive == false && m_iDeadImageID != -1 )
|
||||
{
|
||||
// draw background for dead icon
|
||||
// surface()->DrawFilledRect(dead_icon_xpos, ypos, 0, ypos + dead_icon_tall);
|
||||
|
||||
Vertex_t vert[4];
|
||||
float uv1 = 0.0f;
|
||||
float uv2 = 1.0f;
|
||||
|
||||
// Draw the dead material
|
||||
surface()->DrawSetTexture( m_iDeadImageID );
|
||||
|
||||
vert[0].Init( Vector2D( dead_icon_xpos, ypos + dead_icon_ypos ), Vector2D( uv1, uv1 ) );
|
||||
vert[1].Init( Vector2D( dead_icon_xpos + dead_icon_wide, ypos + dead_icon_ypos ), Vector2D( uv2, uv1 ) );
|
||||
vert[2].Init( Vector2D( dead_icon_xpos + dead_icon_wide, ypos + dead_icon_ypos + dead_icon_tall ), Vector2D( uv2, uv2 ) );
|
||||
vert[3].Init( Vector2D( dead_icon_xpos, ypos + dead_icon_ypos + dead_icon_tall ), Vector2D( uv1, uv2 ) );
|
||||
|
||||
surface()->DrawSetColor(COLOR_WHITE);
|
||||
surface()->DrawTexturedPolygon( 4, vert );
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// HPE_BEGIN:
|
||||
// [pfreese] Draw the avatar for the given player
|
||||
//=============================================================================
|
||||
|
||||
// Draw the players icon
|
||||
if (show_avatar && m_SpeakingList[i].pAvatar)
|
||||
{
|
||||
m_SpeakingList[i].pAvatar->SetPos( avatar_xpos, ypos + avatar_ypos );
|
||||
m_SpeakingList[i].pAvatar->Paint();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// HPE_END
|
||||
//=============================================================================
|
||||
|
||||
// Draw the voice icon
|
||||
if (show_voice_icon)
|
||||
m_pVoiceIcon->DrawSelf( voice_icon_xpos, ypos + voice_icon_ypos, voice_icon_wide, voice_icon_tall, m_clrIcon );
|
||||
|
||||
// Draw the player's name
|
||||
surface()->DrawSetTextColor(COLOR_WHITE);
|
||||
surface()->DrawSetTextPos( text_xpos, ypos + ( item_tall / 2 ) - ( iFontHeight / 2 ) );
|
||||
|
||||
int iTextSpace = item_wide - text_xpos;
|
||||
|
||||
// write as much of the name as will fit, truncate the rest and add ellipses
|
||||
int iNameLength = wcslen(szconverted);
|
||||
const wchar_t *pszconverted = szconverted;
|
||||
int iTextWidthCounter = 0;
|
||||
for( int j=0;j<iNameLength;j++ )
|
||||
{
|
||||
iTextWidthCounter += surface()->GetCharacterWidth( m_NameFont, pszconverted[j] );
|
||||
|
||||
if( iTextWidthCounter > iTextSpace )
|
||||
{
|
||||
if( j > 3 )
|
||||
{
|
||||
szconverted[j-2] = '.';
|
||||
szconverted[j-1] = '.';
|
||||
szconverted[j] = '\0';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
surface()->DrawPrintText( szconverted, wcslen(szconverted) );
|
||||
|
||||
ypos -= ( item_spacing + item_tall );
|
||||
|
||||
surface()->DrawSetAlphaMultiplier(oldAlphaMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
int CHudVoiceStatus::FindActiveSpeaker( int playerId )
|
||||
{
|
||||
FOR_EACH_LL(m_SpeakingList, i)
|
||||
{
|
||||
if (m_SpeakingList[i].playerId == playerId)
|
||||
return i;
|
||||
}
|
||||
return m_SpeakingList.InvalidIndex();
|
||||
}
|
||||
|
||||
void CHudVoiceStatus::ClearActiveList()
|
||||
{
|
||||
FOR_EACH_LL(m_SpeakingList, i)
|
||||
{
|
||||
delete m_SpeakingList[i].pAvatar;
|
||||
}
|
||||
|
||||
m_SpeakingList.RemoveAll();
|
||||
}
|
||||
Reference in New Issue
Block a user