예제 #1
0
//-----------------------------------------------------------------------------
// Purpose: Text chat input/output hud element
//-----------------------------------------------------------------------------
CBaseHudChat::CBaseHudChat( const char *pElementName )
: CHudElement( pElementName ), BaseClass( NULL, "HudChat" )
{
	vgui::Panel *pParent = g_pClientMode->GetViewport();
	SetParent( pParent );

	vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme");
	SetScheme(scheme);

	m_nMessageMode = 0;

	CBaseHudChatLine *line = m_ChatLines[ 0 ];

	if ( line )
	{
		vgui::HFont font = line->GetFont();
		m_iFontHeight = vgui::surface()->GetFontTall( font ) + 2;

		// Put input area at bottom
		int w, h;
		GetSize( w, h );
		m_pChatInput->SetBounds( 1, h - m_iFontHeight - 1, w-2, m_iFontHeight );
	}

	if ( IsPC() )
	{
		vgui::ivgui()->AddTickSignal( GetVPanel() );
	}

	// (We don't actually want input until they bring up the chat line).
	MakePopup();
	SetZPos( -30 );

	SetHiddenBits( HIDEHUD_CHAT );
}
예제 #2
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : width - 
//			*text - 
//			textlen - 
// Output : int
//-----------------------------------------------------------------------------
int CBaseHudChat::ComputeBreakChar( int width, const char *text, int textlen )
{
#ifndef _XBOX
	CBaseHudChatLine *line = m_ChatLine;
	vgui::HFont font = line->GetFont();

	int currentlen = 0;
	int lastbreak = textlen;
	for (int i = 0; i < textlen ; i++)
	{
		char ch = text[i];

		if ( ch <= 32 )
		{
			lastbreak = i;
		}

		wchar_t wch[2];

		g_pVGuiLocalize->ConvertANSIToUnicode( &ch, wch, sizeof( wch ) );

		int a,b,c;

		vgui::surface()->GetCharABCwide(font, wch[0], a, b, c);
		currentlen += a + b + c;

		if ( currentlen >= width )
		{
			// If we haven't found a whitespace char to break on before getting
			//  to the end, but it's still too long, break on the character just before
			//  this one
			if ( lastbreak == textlen )
			{
				lastbreak = max( 0, i - 1 );
			}
			break;
		}
	}

	if ( currentlen >= width )
	{
		return lastbreak;
	}
	return textlen;
#else
	return 0;
#endif
}
예제 #3
0
//-----------------------------------------------------------------------------
// Purpose: 
// Output : CBaseHudChatLine
//-----------------------------------------------------------------------------
CBaseHudChatLine *CBaseHudChat::FindUnusedChatLine( void )
{
#ifndef _XBOX
	for ( int i = 0; i < CHAT_INTERFACE_LINES; i++ )
	{
		CBaseHudChatLine *line = m_ChatLines[ i ];
		if ( !line )
			continue;

		if ( line->IsVisible() )
			continue;

		return line;
	}
	return NULL;
#else
	return NULL;
#endif
}
예제 #4
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBaseHudChat::Clear( void )
{
#ifndef _XBOX
	// Kill input prompt
	StopMessageMode();

	// Expire all messages
	for ( int i = 0; i < CHAT_INTERFACE_LINES; i++ )
	{
		CBaseHudChatLine *line = m_ChatLines[ i ];
		if ( !line )
			continue;

		if ( !line->IsVisible() )
			continue;

		line->Expire();
	}
#endif
}
예제 #5
0
//-----------------------------------------------------------------------------
// Purpose: Do respositioning here to avoid latency due to repositioning of vgui
//  voice manager icon panel
//-----------------------------------------------------------------------------
void CBaseHudChat::OnTick( void )
{
#ifndef _XBOX
	m_nVisibleHeight = 0;

	CBaseHudChatLine *line = m_ChatLine;

	if ( line )
	{
		vgui::HFont font = line->GetFont();
		m_iFontHeight = vgui::surface()->GetFontTall( font ) + 2;

		// Put input area at bottom

		int iChatX, iChatY, iChatW, iChatH;
		int iInputX, iInputY, iInputW, iInputH;
		
		m_pChatInput->GetBounds( iInputX, iInputY, iInputW, iInputH );
		GetBounds( iChatX, iChatY, iChatW, iChatH );

		m_pChatInput->SetBounds( iInputX, iChatH - (m_iFontHeight * 1.75), iInputW, m_iFontHeight );

		//Resize the History Panel so it fits more lines depending on the screen resolution.
		int iChatHistoryX, iChatHistoryY, iChatHistoryW, iChatHistoryH;

		GetChatHistory()->GetBounds( iChatHistoryX, iChatHistoryY, iChatHistoryW, iChatHistoryH );

		iChatHistoryH = (iChatH - (m_iFontHeight * 2.25)) - iChatHistoryY;

		GetChatHistory()->SetBounds( iChatHistoryX, iChatHistoryY, iChatHistoryW, iChatHistoryH );
	}

	FadeChatHistory();

#endif
}
예제 #6
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBaseHudChat::ExpireOldest( void )
{
#ifndef _XBOX
	float oldestTime = 100000000.0f;
	CBaseHudChatLine *oldest = NULL;

	for ( int i = 0; i < CHAT_INTERFACE_LINES; i++ )
	{
		CBaseHudChatLine *line = m_ChatLines[ i ];
		if ( !line )
			continue;

		if ( !line->IsVisible() )
			continue;

		if ( !oldest )
		{
			oldest = line;
			oldestTime = line->GetStartTime();
			continue;
		}

		if ( line->GetStartTime() < oldestTime )
		{
			oldest = line;
			oldestTime = line->GetStartTime();
		}
	}

	if ( !oldest )
	{
		oldest = m_ChatLines[ 0  ];
	}

	oldest->Expire(); 
#endif
}
예제 #7
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *fmt - 
//			... - 
//-----------------------------------------------------------------------------
void CBaseHudChat::ChatPrintf( int iPlayerIndex, int iFilter, const char *fmt, ... )
{
	va_list marker;
	char msg[4096];

	va_start(marker, fmt);
	Q_vsnprintf(msg, sizeof( msg), fmt, marker);
	va_end(marker);

	// Strip any trailing '\n'
	if ( strlen( msg ) > 0 && msg[ strlen( msg )-1 ] == '\n' )
	{
		msg[ strlen( msg ) - 1 ] = 0;
	}

	// Strip leading \n characters ( or notify/color signifiers ) for empty string check
	char *pmsg = msg;
	while ( *pmsg && ( *pmsg == '\n' || ( *pmsg > 0 && *pmsg < COLOR_MAX ) ) )
	{
		pmsg++;
	}

	if ( !*pmsg )
		return;

	// Now strip just newlines, since we want the color info for printing
	pmsg = msg;
	while ( *pmsg && ( *pmsg == '\n' ) )
	{
		pmsg++;
	}

	if ( !*pmsg )
		return;

	CBaseHudChatLine *line = (CBaseHudChatLine *)FindUnusedChatLine();
	if ( !line )
	{
		line = (CBaseHudChatLine *)FindUnusedChatLine();
	}

	if ( !line )
	{
		return;
	}

	if ( iFilter != CHAT_FILTER_NONE )
	{
		if ( !(iFilter & m_iFilterFlags ) )
			return;
	}

	if ( *pmsg < 32 )
	{
		hudlcd->AddChatLine( pmsg + 1 );
	}
	else
	{
		hudlcd->AddChatLine( pmsg );
	}

	line->SetText( "" );

	int iNameStart = 0;
	int iNameLength = 0;

	player_info_t sPlayerInfo;
	if ( iPlayerIndex == 0 )
	{
		Q_memset( &sPlayerInfo, 0, sizeof(player_info_t) );
		Q_strncpy( sPlayerInfo.name, "Console", sizeof(sPlayerInfo.name)  );	
	}
	else
	{
		engine->GetPlayerInfo( iPlayerIndex, &sPlayerInfo );
	}	

	int bufSize = (strlen( pmsg ) + 1 ) * sizeof(wchar_t);
	wchar_t *wbuf = static_cast<wchar_t *>( _alloca( bufSize ) );
	if ( wbuf )
	{
		Color clrNameColor = GetClientColor( iPlayerIndex );

		line->SetExpireTime();

		g_pVGuiLocalize->ConvertANSIToUnicode( pmsg, wbuf, bufSize);

		// find the player's name in the unicode string, in case there is no color markup
		const char *pName = sPlayerInfo.name;

		if ( pName )
		{
			wchar_t wideName[MAX_PLAYER_NAME_LENGTH];
			g_pVGuiLocalize->ConvertANSIToUnicode( pName, wideName, sizeof( wideName ) );

			const wchar_t *nameInString = wcsstr( wbuf, wideName );

			if ( nameInString )
			{
				iNameStart = (nameInString - wbuf);
				iNameLength = wcslen( wideName );
			}
		}

		line->SetVisible( false );
		line->SetNameStart( iNameStart );
		line->SetNameLength( iNameLength );
		line->SetNameColor( clrNameColor );

		line->InsertAndColorizeText( wbuf, iPlayerIndex );
	}
}
예제 #8
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *fmt - 
//			... - 
//-----------------------------------------------------------------------------
void CBaseHudChat::Printf( const char *fmt, ... )
{
#ifndef _XBOX
	// No chat text in single player
	if ( gpGlobals->maxClients == 1 )
	{
		return;
	}

	va_list marker;
	char msg[4096];

	const char *pTranslatedFmt = hudtextmessage->LookupString(fmt);

	va_start(marker, fmt);
	Q_vsnprintf( msg, sizeof( msg ), pTranslatedFmt, marker );
	va_end(marker);

	// Strip any trailing '\n'
	if ( strlen( msg ) > 0 && msg[ strlen( msg )-1 ] == '\n' )
	{
		msg[ strlen( msg ) - 1 ] = 0;
	}

	// Strip leading \n characters ( or notify/color signifiers )
	char *pmsg = msg;
	while ( *pmsg && ( *pmsg == '\n' || *pmsg == 1 || *pmsg == 2 ) )
	{
		pmsg++;
	}
	
	if ( !*pmsg )
		return;

	// Search for return characters
	char *pos = strstr( pmsg, "\n" );
	if ( pos )
	{
		char msgcopy[ 8192 ];
		Q_strncpy( msgcopy, pmsg, sizeof( msgcopy ) );

		int offset = pos - pmsg;
		
		// Terminate first part
		msgcopy[ offset ] = 0;
		
		// Print first part
#if defined( CSTRIKE_DLL ) || defined( DOD_DLL ) // reltodo
		Printf( "%s", msgcopy );

		// Print remainder
		Printf( "%s", &msgcopy[ offset ] + 1 );
#else
		Printf( msgcopy );

		// Print remainder
		Printf( &msgcopy[ offset ] + 1 );
#endif
		return;
	}

	CBaseHudChatLine *firstline = m_ChatLines[ 0 ];

	int len = strlen( pmsg );

	// Check for string too long and split into multiple lines 
	// 
	int breakpos = ComputeBreakChar( firstline->GetWide() - 10, pmsg, len );
	if ( breakpos > 0 && breakpos < len )
	{
		char msgcopy[ 8192 ];
		Q_strncpy( msgcopy, pmsg, sizeof( msgcopy ) );

		int offset = breakpos;
		
		char savechar;

		savechar = msgcopy[ offset ];

		// Terminate first part
		msgcopy[ offset ] = 0;
		
		// Print first part
#if defined( CSTRIKE_DLL ) || defined( DOD_DLL ) // reltodo
		Printf( "%s", msgcopy );
#else
		Printf( msgcopy );
#endif

		// Was breakpos a printable char?
		if ( savechar > 32 )
		{
			msgcopy[ offset ] = savechar;

			// Print remainder
#if defined( CSTRIKE_DLL ) || defined( DOD_DLL ) // reltodo
			Printf( "%s", &msgcopy[ offset ] );
#else
			Printf( &msgcopy[ offset ] );
#endif
		}
		else
		{
#if defined( CSTRIKE_DLL ) || defined( DOD_DLL ) // reltodo
			Printf( "%s", &msgcopy[ offset ] + 1 );
#else
			Printf( &msgcopy[ offset ] + 1 );
#endif
		}
		return;
	}

	CBaseHudChatLine *line = FindUnusedChatLine();
	if ( !line )
	{
		ExpireOldest();
		line = FindUnusedChatLine();
	}

	if ( !line )
	{
		return;
	}

	line->SetText( "" );
	line->InsertColorChange( line->GetTextColor() );
	line->SetExpireTime();
	line->InsertString( pmsg );
	line->SetVisible( true );
	line->SetNameLength( 0 );
	
	CLocalPlayerFilter filter;
	C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "HudChat.Message" );
#endif
}
예제 #9
0
//-----------------------------------------------------------------------------
// Purpose: Do respositioning here to avoid latency due to repositioning of vgui
//  voice manager icon panel
//-----------------------------------------------------------------------------
void CBaseHudChat::OnTick( void )
{
#ifndef _XBOX
	int i;
	for ( i = 0; i < CHAT_INTERFACE_LINES; i++ )
	{
		CBaseHudChatLine *line = m_ChatLines[ i ];
		if ( !line )
			continue;

		if ( !line->IsVisible() )
			continue;

		if ( !line->IsReadyToExpire() )
			continue;

		line->Expire();
	}

	int w, h;

	GetSize( w, h );

	CBaseHudChatLine *line = m_ChatLines[ 0 ];

	if ( line )
	{
		vgui::HFont font = line->GetFont();

		if ( font )
		{
			m_iFontHeight = vgui::surface()->GetFontTall( font ) + 2;

			// Put input area at bottom
			int w, h;
			GetSize( w, h );
			m_pChatInput->SetBounds( 1, h - m_iFontHeight - 1, w-2, m_iFontHeight );
		}
	}

	// Sort chat lines 
	qsort( m_ChatLines, CHAT_INTERFACE_LINES, sizeof( CBaseHudChatLine * ), SortLines );

	// Step backward from bottom
	int currentY = h - m_iFontHeight - 1;
	int startY = currentY;
	int ystep = m_iFontHeight;

	currentY -= GetChatInputOffset();

	// Walk backward
	for ( i = CHAT_INTERFACE_LINES - 1; i >= 0 ; i-- )
	{
		CBaseHudChatLine *line = m_ChatLines[ i ];
		if ( !line )
			continue;

		if ( !line->IsVisible() )
		{
			line->SetSize( w, m_iFontHeight );
			continue;
		}

		line->PerformFadeout();
		line->SetSize( w, m_iFontHeight * line->GetNumLines() );
		line->SetPos( 0, ( currentY+m_iFontHeight) - m_iFontHeight * line->GetNumLines() );
		
		currentY -= ystep * line->GetNumLines();
	}

	if ( currentY != startY )
	{
		m_nVisibleHeight = startY - currentY + 2;
	}
	else
	{
		m_nVisibleHeight = 0;
	}

	vgui::surface()->MovePopupToBack( GetVPanel() );
#endif
}