Example #1
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
Color CBaseHudChat::GetTextColorForClient( TextColor colorNum, int clientIndex )
{
	Color c;
	switch ( colorNum )
	{
	case COLOR_PLAYERNAME:
		c = GetClientColor( clientIndex );
	break;

	case COLOR_LOCATION:
		c = g_ColorDarkGreen;
		break;

	case COLOR_ACHIEVEMENT:
		{
			vgui::IScheme *pSourceScheme = vgui::scheme()->GetIScheme( vgui::scheme()->GetScheme( "SourceScheme" ) ); 
			if ( pSourceScheme )
			{
				c = pSourceScheme->GetColor( "SteamLightGreen", GetBgColor() );
			}
			else
			{
				c = GetDefaultTextColor();
			}
		}
		break;

	default:
		c = GetDefaultTextColor();
	}

	return Color( c[0], c[1], c[2], 255 );
}
void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIndex )
{
	int i;

	// find an empty string slot
	for ( i = 0; i < MAX_LINES; i++ )
	{
		if ( ! *g_szLineBuffer[i] )
			break;
	}
	if ( i == MAX_LINES )
	{
		// force scroll buffer up
		ScrollTextUp();
		i = MAX_LINES - 1;
	}

	g_iNameLengths[i] = 0;
	g_pflNameColors[i] = NULL;

	// if it's a say message, search for the players name in the string
	if ( *pszBuf == 2 && clientIndex > 0 )
	{
		GetPlayerInfo( clientIndex, &g_PlayerInfoList[clientIndex] );
		const char *pName = g_PlayerInfoList[clientIndex].name;

		if ( pName )
		{
			const char *nameInString = strstr( pszBuf, pName );

			if ( nameInString )
			{
				g_iNameLengths[i] = strlen( pName ) + (nameInString - pszBuf);
				g_pflNameColors[i] = GetClientColor( clientIndex );
			}
		}
	}

	strncpy( g_szLineBuffer[i], pszBuf, max(iBufSize -1, MAX_CHARS_PER_LINE-1) );

	// make sure the text fits in one line
	EnsureTextFitsInOneLineAndWrapIfHaveTo( i );

	// Set scroll time
	if ( i == 0 )
	{
		flScrollTime = gHUD.m_flTime + m_HUD_saytext_time->value;
	}

	m_iFlags |= HUD_ACTIVE;
	PlaySound( "misc/talk.wav", 1 );

	if ( ScreenHeight >= 480 )
		Y_START = ScreenHeight - 60;
	else
		Y_START = ScreenHeight - 45;
	Y_START -= (line_height * (MAX_LINES+1));

}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
Color CHudChat::GetTextColorForClient( TextColor colorNum, int clientIndex )
{
	IScheme *pScheme = scheme()->GetIScheme( GetScheme() );

	if ( pScheme == NULL )
		return Color( 255, 255, 255, 255 );

	Color c;
	switch ( colorNum )
	{
	case COLOR_PLAYERNAME:
		c = GetClientColor( clientIndex );
		break;

	case COLOR_LOCATION:
		c = g_ColorDarkGreen;
		break;

	case COLOR_ACHIEVEMENT:
		{
			IScheme *pSourceScheme = scheme()->GetIScheme( scheme()->GetScheme( "SourceScheme" ) ); 
			if ( pSourceScheme )
			{
				c = pSourceScheme->GetColor( "SteamLightGreen", GetBgColor() );
			}
			else
			{
				c = pScheme->GetColor( "TFColors.ChatTextYellow", GetBgColor() );
			}
		}
		break;

	default:
		c = pScheme->GetColor( "TFColors.ChatTextYellow", GetBgColor() );
	}

	return Color( c[0], c[1], c[2], 255 );
}
Example #4
0
void CHudStatusBar :: ParseStatusString( int line_num )
{
	// localise string first
	char szBuffer[MAX_STATUSTEXT_LENGTH];
	memset( szBuffer, 0, sizeof szBuffer );
	gHUD.m_TextMessage.LocaliseTextString( m_szStatusText[line_num], szBuffer, MAX_STATUSTEXT_LENGTH );

	// parse m_szStatusText & m_iStatusValues into m_szStatusBar
	memset( m_szStatusBar[line_num], 0, MAX_STATUSTEXT_LENGTH );
	char *src = szBuffer;
	char *dst = m_szStatusBar[line_num];

	char *src_start = src, *dst_start = dst;

	while ( *src != 0 )
	{
		while ( *src == '\n' )
			src++;  // skip over any newlines

		if ( ((src - src_start) >= MAX_STATUSTEXT_LENGTH) || ((dst - dst_start) >= MAX_STATUSTEXT_LENGTH) )
			break;

		int index = atoi( src );
		// should we draw this line?
		if ( (index >= 0 && index < MAX_STATUSBAR_VALUES) && (m_iStatusValues[index] != -1))
		{  // parse this line and append result to the status bar
			while ( *src >= '0' && *src <= '9' )
				src++;

			if ( *src == '\n' || *src == 0 )
				continue; // no more left in this text line

			// copy the text, char by char, until we hit a % or a \n
			while ( *src != '\n' && *src != 0 )
			{
				if ( *src != '%' )
				{  // just copy the character
					*dst = *src;
					dst++, src++;
				}
				else
				{
					// get the descriptor
					char valtype = *(++src); // move over %

					// if it's a %, draw a % sign
					if ( valtype == '%' )
					{
						*dst = valtype;
						dst++, src++;
						continue;
					}

					// move over descriptor, then get and move over the index
					index = atoi( ++src ); 
					while ( *src >= '0' && *src <= '9' )
						src++;

					if ( index >= 0 && index < MAX_STATUSBAR_VALUES )
					{
						int indexval = m_iStatusValues[index];

						// get the string to substitute in place of the %XX
						char szRepString[MAX_PLAYER_NAME_LENGTH];
						switch ( valtype )
						{
						case 'p':  // player name
							GetPlayerInfo( indexval, &g_PlayerInfoList[indexval] );
							if ( g_PlayerInfoList[indexval].name != NULL )
							{
								strncpy( szRepString, g_PlayerInfoList[indexval].name, MAX_PLAYER_NAME_LENGTH );
								m_pflNameColors[line_num] = GetClientColor( indexval );
							}
							else
							{
								strcpy( szRepString, "******" );
							}

							break;
						case 'i':  // number
							sprintf( szRepString, "%d", indexval );
							break;
						default:
							szRepString[0] = 0;
						}

						for ( char *cp = szRepString; *cp != 0 && ((dst - dst_start) < MAX_STATUSTEXT_LENGTH); cp++, dst++ )
							*dst = *cp;
					}
				}
			}
		}
		else
		{
			// skip to next line of text
			while ( *src != 0 && *src != '\n' )
				src++;
		}
	}
}
Example #5
0
// This message handler may be better off elsewhere
int CHudDeathNotice :: MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbuf )
{
	int i;
	m_iFlags |= HUD_ACTIVE;

	BEGIN_READ( pbuf, iSize );

	int killer = READ_BYTE();
	int victim = READ_BYTE();

	char killedwith[32];
	strcpy( killedwith, "d_" );
	strncat( killedwith, READ_STRING(), 32 );

	gHUD.m_Scoreboard.DeathMsg( killer, victim );

	for ( i = 0; i < MAX_DEATHNOTICES; i++ )
	{
		if ( rgDeathNoticeList[i].iId == 0 )
			break;
	}
	if ( i == MAX_DEATHNOTICES )
	{ // move the rest of the list forward to make room for this item
		memmove( rgDeathNoticeList, rgDeathNoticeList+1, sizeof(DeathNoticeItem) * MAX_DEATHNOTICES );
		i = MAX_DEATHNOTICES - 1;
	}

	gHUD.m_Scoreboard.GetAllPlayersInfo();

	// Get the Killer's name
	char *killer_name = g_PlayerInfoList[ killer ].name;
	if ( !killer_name )
	{
		killer_name = "";
		rgDeathNoticeList[i].szKiller[0] = 0;
	}
	else
	{
		rgDeathNoticeList[i].KillerColor = GetClientColor( killer );
		strncpy( rgDeathNoticeList[i].szKiller, killer_name, MAX_PLAYER_NAME_LENGTH );
		rgDeathNoticeList[i].szKiller[MAX_PLAYER_NAME_LENGTH-1] = 0;
	}

	// Get the Victim's name
	char *victim_name = NULL;
	// If victim is -1, the killer killed a specific, non-player object (like a sentrygun)
	if ( ((char)victim) != -1 )
		victim_name = g_PlayerInfoList[ victim ].name;
	if ( !victim_name )
	{
		victim_name = "";
		rgDeathNoticeList[i].szVictim[0] = 0;
	}
	else
	{
		rgDeathNoticeList[i].VictimColor = GetClientColor( victim );
		strncpy( rgDeathNoticeList[i].szVictim, victim_name, MAX_PLAYER_NAME_LENGTH );
		rgDeathNoticeList[i].szVictim[MAX_PLAYER_NAME_LENGTH-1] = 0;
	}

	// Is it a non-player object kill?
	if ( ((char)victim) == -1 )
	{
		rgDeathNoticeList[i].iNonPlayerKill = TRUE;

		// Store the object's name in the Victim slot (skip the d_ bit)
		strcpy( rgDeathNoticeList[i].szVictim, killedwith+2 );
	}
	else
	{
		if ( killer == victim || killer == 0 )
			rgDeathNoticeList[i].iSuicide = TRUE;

		if ( !strcmp( killedwith, "d_teammate" ) )
			rgDeathNoticeList[i].iTeamKill = TRUE;
	}

	// Find the sprite in the list
	int spr = gHUD.GetSpriteIndex( killedwith );

	rgDeathNoticeList[i].iId = spr;

	DEATHNOTICE_DISPLAY_TIME = CVAR_GET_FLOAT( "hud_deathnotice_time" );
	rgDeathNoticeList[i].flDisplayTime = gHUD.m_flTime + DEATHNOTICE_DISPLAY_TIME;

	if (rgDeathNoticeList[i].iNonPlayerKill)
	{
		ConsolePrint( rgDeathNoticeList[i].szKiller );
		ConsolePrint( " killed a " );
		ConsolePrint( rgDeathNoticeList[i].szVictim );
		ConsolePrint( "\n" );
	}
	else
	{
		// record the death notice in the console
		if ( rgDeathNoticeList[i].iSuicide )
		{
			ConsolePrint( rgDeathNoticeList[i].szVictim );

			if ( !strcmp( killedwith, "d_world" ) )
			{
				ConsolePrint( " died" );
			}
			else
			{
				ConsolePrint( " killed self" );
			}
		}
		else if ( rgDeathNoticeList[i].iTeamKill )
		{
			ConsolePrint( rgDeathNoticeList[i].szKiller );
			ConsolePrint( " killed his teammate " );
			ConsolePrint( rgDeathNoticeList[i].szVictim );
		}
		else
		{
			ConsolePrint( rgDeathNoticeList[i].szKiller );
			ConsolePrint( " killed " );
			ConsolePrint( rgDeathNoticeList[i].szVictim );
		}

		if ( *killedwith && (*killedwith > 13 ) && strcmp( killedwith, "d_world" ) && !rgDeathNoticeList[i].iTeamKill )
		{
			ConsolePrint( " with " );

			// replace the code names with the 'real' names
			if ( !strcmp( killedwith+2, "egon" ) )
				strcpy( killedwith, "d_gluon gun" );
			if ( !strcmp( killedwith+2, "gauss" ) )
				strcpy( killedwith, "d_tau cannon" );

			ConsolePrint( killedwith+2 ); // skip over the "d_" part
		}

		ConsolePrint( "\n" );
	}

	return 1;
}
Example #6
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 );
	}
}
Example #7
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *fmt - 
//			... - 
//-----------------------------------------------------------------------------
void CHudChat::ChatPrintf( int iPlayerIndex, 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 )
	char *pmsg = msg;
	while ( *pmsg && ( *pmsg == '\n' || *pmsg == 1 || *pmsg == 2 ) )
	{
		pmsg++;
	}
	
	if ( !*pmsg )
		return;

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

	if ( !line )
	{
		return;
	}

	line->SetText( "" );
	
	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 );
	}	

	const char *pName = sPlayerInfo.name;

	if ( pName )
	{
		const char *nameInString = strstr( pmsg, pName );

		if ( nameInString )
		{
			iNameLength = strlen( pName ) + (nameInString - pmsg);
		}
	}
	else
		line->InsertColorChange( Color( g_ColorYellow[0], g_ColorYellow[1], g_ColorYellow[2], 255 ) );

	char *buf = static_cast<char *>( _alloca( strlen( pmsg ) + 1  ) );
	wchar_t *wbuf = static_cast<wchar_t *>( _alloca( (strlen( pmsg ) + 1 ) * sizeof(wchar_t) ) );
	if ( buf )
	{
		float *flColor = GetClientColor( iPlayerIndex );

		line->SetExpireTime();
	
		// draw the first x characters in the player color
		Q_strncpy( buf, pmsg, min( iNameLength + 1, MAX_PLAYER_NAME_LENGTH+32) );
		buf[ min( iNameLength, MAX_PLAYER_NAME_LENGTH+31) ] = 0;
		line->InsertColorChange( Color( flColor[0], flColor[1], flColor[2], 255 ) );
		line->InsertString( buf );
		Q_strncpy( buf, pmsg + iNameLength, strlen( pmsg ));
		buf[ strlen( pmsg + iNameLength ) ] = '\0';
		line->InsertColorChange( Color( g_ColorYellow[0], g_ColorYellow[1], g_ColorYellow[2], 255 ) );
		vgui::localize()->ConvertANSIToUnicode( buf, wbuf, strlen(pmsg)*sizeof(wchar_t));
		line->InsertString( wbuf );
		line->SetVisible( true );
		line->SetNameLength( iNameLength );
		line->SetNameColor( Color( flColor[0], flColor[1], flColor[2], 255 ) );
	}

	CLocalPlayerFilter filter;
	C_BaseEntity::EmitSound( filter, -1 /*SOUND_FROM_LOCAL_PLAYER*/, "HudChat.Message" );
}
Example #8
0
void CHudSayText :: SayTextPrint( const char *pszBuf, size_t uiBufSize, int clientIndex )
{
	if ( gViewPort && !gViewPort->AllowedToPrintText() )
	{
		// Print it straight to the console
		ConsolePrint( pszBuf );
		return;
	}

	int i;
	// find an empty string slot
	for ( i = 0; i < MAX_LINES; i++ )
	{
		if ( ! *m_szLineBuffer[i] )
			break;
	}
	if ( i == MAX_LINES )
	{
		// force scroll buffer up
		ScrollTextUp();
		i = MAX_LINES - 1;
	}

	m_iNameLengths[i] = 0;
	m_pvecNameColors[i] = nullptr;

	// if it's a say message, search for the players name in the string
	if ( *pszBuf == 2 && clientIndex > 0 )
	{
		gEngfuncs.pfnGetPlayerInfo( clientIndex, &g_PlayerInfoList[clientIndex] );
		const char *pName = g_PlayerInfoList[clientIndex].name;

		if ( pName )
		{
			const char *nameInString = strstr( pszBuf, pName );

			if ( nameInString )
			{
				m_iNameLengths[i] = strlen( pName ) + (nameInString - pszBuf);
				m_pvecNameColors[i] = &GetClientColor( clientIndex );
			}
		}
	}

	//Need to assign the constant to a local here because std::max takes it by reference, which won't work for this constant.
	//Static const integrals initialized in their declaration have no address, which causes segfaults on Linux.
	//See https://www.reddit.com/r/cpp_questions/comments/510sdc/strange_segfault_under_gcc_using_stdmax_and
	// - Solokiller
	const size_t uiMax = MAX_CHARS_PER_LINE;

	strncpy( m_szLineBuffer[i], pszBuf, max(uiBufSize , uiMax ) );

	// make sure the text fits in one line
	EnsureTextFitsInOneLineAndWrapIfHaveTo( i );

	// Set scroll time
	if ( i == 0 )
	{
		m_flScrollTime = gHUD.m_flTime + m_HUD_saytext_time->value;
	}

	m_iFlags |= HUD_ACTIVE;
	PlaySound( "misc/talk.wav", 1 );

	m_iYStart = ScreenHeight - 60 - ( m_iLineHeight * (MAX_LINES+2) );
}
Example #9
0
// returns the ypos where it finishes drawing
int CHudScoreboard :: DrawPlayers( float list_slot, int nameoffset, const char *team )
{
	// draw the players, in order,  and restricted to team if set
	while ( 1 )
	{
		// Find the top ranking player
		int highest_frags = -99999;	int lowest_deaths = 99999;
		int best_player = 0;

		for ( int i = 1; i < MAX_PLAYERS; i++ )
		{
			if ( g_PlayerInfoList[i].name && g_PlayerExtraInfo[i].frags >= highest_frags )
			{
				if ( !(team && stricmp(g_PlayerExtraInfo[i].teamname, team)) )  // make sure it is the specified team
				{
					extra_player_info_t *pl_info = &g_PlayerExtraInfo[i];
					if ( pl_info->frags > highest_frags || pl_info->deaths < lowest_deaths )
					{
						best_player = i;
						lowest_deaths = pl_info->deaths;
						highest_frags = pl_info->frags;
					}
				}
			}
		}

		if ( !best_player )
			break;

		// draw out the best player
		hud_player_info_t *pl_info = &g_PlayerInfoList[best_player];

		int ypos = ystart + (list_slot * ROW_GAP);

		// check we haven't drawn too far down
		if ( ypos > yend )  // don't draw to close to the lower border
			break;

		int r = 255, g = 255, b = 255;
		float *colors = GetClientColor( best_player );
		r *= colors[0];
		g *= colors[1];
		b *= colors[2];

		if(pl_info->thisplayer) // hey, it's me!
		{
			FillRGBABlend( xstart, ypos, xend - xstart, ROW_GAP, 255, 255, 255, 15 );
		}


		DrawUtils::DrawHudString( NAME_POS_START() + nameoffset, ypos, NAME_POS_END(), pl_info->name, r, g, b );

		// draw bomb( if player have the bomb )
		if( g_PlayerExtraInfo[best_player].dead )
			DrawUtils::DrawHudString( ATTRIB_POS_START(), ypos, ATTRIB_POS_END(), "Dead", r, g, b );
		else if( g_PlayerExtraInfo[best_player].has_c4 )
			DrawUtils::DrawHudString( ATTRIB_POS_START(), ypos, ATTRIB_POS_END(), "Bomb", r, g, b );
		else if( g_PlayerExtraInfo[best_player].vip )
			DrawUtils::DrawHudString( ATTRIB_POS_START(), ypos, ATTRIB_POS_END(), "VIP",  r, g, b );

		// draw kills (right to left)
		DrawUtils::DrawHudNumberString( KILLS_POS_END(), ypos, KILLS_POS_START(), g_PlayerExtraInfo[best_player].frags, r, g, b );

		// draw deaths
		DrawUtils::DrawHudNumberString( DEATHS_POS_END(), ypos, DEATHS_POS_START(), g_PlayerExtraInfo[best_player].deaths, r, g, b );

		// draw ping & packetloss
		static char buf[64];
		sprintf( buf, "%d", g_PlayerInfoList[best_player].ping );
		DrawUtils::DrawHudStringReverse( PING_POS_END(), ypos, PING_POS_START(), buf, r, g, b );
	
		pl_info->name = NULL;  // set the name to be NULL, so this client won't get drawn again
		list_slot++;
	}

	list_slot += 2.0f;

	return list_slot;
}
Example #10
0
// This message handler may be better off elsewhere
int CHudDeathNotice :: MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbuf )
{
	m_iFlags |= HUD_ACTIVE;

	BEGIN_READ( pbuf, iSize );

	int killer = READ_BYTE();
	int victim = READ_BYTE();

	char killedwith[32];
	strcpy( killedwith, "d_" );
	strncat( killedwith, READ_STRING(), 32 );

//	if (gViewPort)
//		gViewPort->DeathMsg( killer, victim );

	gHUD.m_Spectator.DeathMessage(victim);

	for ( int i = 0; i < MAX_DEATHNOTICES; i++ )
	{
		if ( rgDeathNoticeList[i].iId == 0 )
			break;
	}
	if ( i == MAX_DEATHNOTICES )
	{ // move the rest of the list forward to make room for this item
		memmove( rgDeathNoticeList, rgDeathNoticeList+1, sizeof(DeathNoticeItem) * MAX_DEATHNOTICES );
		i = MAX_DEATHNOTICES - 1;
	}

//	if (gViewPort)
//		gViewPort->GetAllPlayersInfo();

	// Get the Killer's name
	char *killer_name = g_PlayerInfoList[ killer ].name;
	if ( !killer_name )
	{
		killer_name = "";
		rgDeathNoticeList[i].szKiller[0] = 0;
	}
	else
	{
		rgDeathNoticeList[i].KillerColor = GetClientColor( killer );
		strncpy( rgDeathNoticeList[i].szKiller, killer_name, MAX_PLAYER_NAME_LENGTH );
		rgDeathNoticeList[i].szKiller[MAX_PLAYER_NAME_LENGTH-1] = 0;
	}

	// Get the Victim's name
	char *victim_name = NULL;
	// If victim is -1, the killer killed a specific, non-player object (like a sentrygun)
	if ( ((char)victim) != -1 )
		victim_name = g_PlayerInfoList[ victim ].name;
	if ( !victim_name )
	{
		victim_name = "";
		rgDeathNoticeList[i].szVictim[0] = 0;
	}
	else
	{
		rgDeathNoticeList[i].VictimColor = GetClientColor( victim );
		strncpy( rgDeathNoticeList[i].szVictim, victim_name, MAX_PLAYER_NAME_LENGTH );
		rgDeathNoticeList[i].szVictim[MAX_PLAYER_NAME_LENGTH-1] = 0;
	}

	// Is it a non-player object kill?
	if ( ((char)victim) == -1 )
	{
		rgDeathNoticeList[i].iNonPlayerKill = TRUE;

		// Store the object's name in the Victim slot (skip the d_ bit)
		strcpy( rgDeathNoticeList[i].szVictim, killedwith+2 );
	}
	else
	{
		if ( killer == victim || killer == 0 )
			rgDeathNoticeList[i].iSuicide = TRUE;

		if ( !strcmp( killedwith, "d_teammate" ) )
			rgDeathNoticeList[i].iTeamKill = TRUE;
	}

	// Find the sprite in the list
	int spr = gHUD.GetSpriteIndex( killedwith );

	rgDeathNoticeList[i].iId = spr;

	DEATHNOTICE_DISPLAY_TIME = CVAR_GET_FLOAT( "hud_deathnotice_time" );
	rgDeathNoticeList[i].flDisplayTime = gHUD.m_flTime + DEATHNOTICE_DISPLAY_TIME;

	if (rgDeathNoticeList[i].iNonPlayerKill)
	{
		ConsolePrint( rgDeathNoticeList[i].szKiller );
		ConsolePrint( " killed a " );
		ConsolePrint( rgDeathNoticeList[i].szVictim );
		ConsolePrint( "\n" );
	}
	else
	{
		// record the death notice in the console
		if ( rgDeathNoticeList[i].iSuicide )
		{
			ConsolePrint( rgDeathNoticeList[i].szVictim );

			if ( !strcmp( killedwith, "d_world" ) )
			{
				ConsolePrint( " died" );
			}
			else
			{
				ConsolePrint( " killed self" );
			}
		}
		else if ( rgDeathNoticeList[i].iTeamKill )
		{
			ConsolePrint( rgDeathNoticeList[i].szKiller );
			ConsolePrint( " killed his teammate " );
			ConsolePrint( rgDeathNoticeList[i].szVictim );
		}
		else
		{
			ConsolePrint( rgDeathNoticeList[i].szKiller );
			ConsolePrint( " killed " );
			ConsolePrint( rgDeathNoticeList[i].szVictim );
		}

		if ( killedwith && *killedwith && (*killedwith > 13 ) && strcmp( killedwith, "d_world" ) && !rgDeathNoticeList[i].iTeamKill )
		{
			ConsolePrint( " with " );

			// replace the code names with the 'real' names
			if ( !strcmp( killedwith+2, "blaster" ) )
				strcpy( killedwith, "d_E11 Blaster Rifle" );
			if ( !strcmp( killedwith+2, "wh" ) )
				strcpy( killedwith, "d_War Head Launcher" );
			if ( !strcmp( killedwith+2, "egon" ) )
				strcpy( killedwith, "d_Egon Gun" );
			if ( !strcmp( killedwith+2, "nuke" ) )
				strcpy( killedwith, "d_Redeemer" );
			if ( !strcmp( killedwith+2, "flame" ) )
				strcpy( killedwith, "d_Flamethrower" );
			if ( !strcmp( killedwith+2, "gauss" ) )
				strcpy( killedwith, "d_Gauss Gun" );
			if ( !strcmp( killedwith+2, "frostball" ) )
				strcpy( killedwith, "d_Froster" );
			if ( !strcmp( killedwith+2, "glock" ) )
				strcpy( killedwith, "d_Glock 18" );
			if ( !strcmp( killedwith+2, "30mmsg" ) )
				strcpy( killedwith, "d_30mm Assault Shotgun" );
			if ( !strcmp( killedwith+2, "sggren" ) )
				strcpy( killedwith, "d_30mm Assault Shotgun" );
			if ( !strcmp( killedwith+2, "glock_akimbo" ) )
				strcpy( killedwith, "d_Dual Glock 18" );
			if ( !strcmp( killedwith+2, "9mmAR" ) )
				strcpy( killedwith, "d_MP5" );
			if ( !strcmp( killedwith+2, "turretkit" ) )
				strcpy( killedwith, "d_Personal Defencive System" );
			if ( !strcmp( killedwith+2, "shieldgun" ) )
				strcpy( killedwith, "d_Chendler pistol" );
			if ( !strcmp( killedwith+2, "ak74grenade" ) )
				strcpy( killedwith, "d_AK74 grenade" );
			if ( !strcmp( killedwith+2, "mmissile" ) )
				strcpy( killedwith, "d_Devastator" );
			if ( !strcmp( killedwith+2, "pbolt" ) )
				strcpy( killedwith, "d_Energy Pistol" );
			if ( !strcmp( killedwith+2, "flak_shard" ) )
				strcpy( killedwith, "d_Flak Cannon" );
			if ( !strcmp( killedwith+2, "flak_bomb" ) )
				strcpy( killedwith, "d_Flak Cannon" );
			if ( !strcmp( killedwith+2, "clmomma" ) )
				strcpy( killedwith, "d_Cluster Grenade" );
			if ( !strcmp( killedwith+2, "clbaby" ) )
				strcpy( killedwith, "d_Cluster Baby" );
			if ( !strcmp( killedwith+2, "chronoclip" ) )
				strcpy( killedwith, "d_Chronosceptor Power Cell" );
			if ( !strcmp( killedwith+2, "black_hole" ) )
				strcpy( killedwith, "d_Chronosceptor" );
			if ( !strcmp( killedwith+2, "pshield_det" ) )
				strcpy( killedwith, "d_Power Shield Explosion" );
			if ( !strcmp( killedwith+2, "sunofgod" ) )
				strcpy( killedwith, "d_Charge Radiance Emitter" );
			if ( !strcmp( killedwith+2, "nggrenade" ) )
				strcpy( killedwith, "d_Nerve Gas Grenade" );
			if ( !strcmp( killedwith+2, "bolt" ) )
				strcpy( killedwith, "d_Crossbow" );
			if ( !strcmp( killedwith+2, "gluon" ) )
				strcpy( killedwith, "d_Gluon Gun" );
			if ( !strcmp( killedwith+2, "gluon2" ) )
				strcpy( killedwith, "d_Gluon Gun" );
			if ( !strcmp( killedwith+2, "rrp" ) )
				strcpy( killedwith, "d_RPG" );
			if ( !strcmp( killedwith+2, "tankproj" ) )
				strcpy( killedwith, "d_Tank Heavy Cannon" );
			if ( !strcmp( killedwith+2, "tank_model" ) )
				strcpy( killedwith, "d_Machine gun turret" );
			if ( !strcmp( killedwith+2, "mortar" ) )
				strcpy( killedwith, "d_Air Strike" );
			if ( !strcmp( killedwith+2, "tank_gauss" ) )
				strcpy( killedwith, "d_Energy Turret" );
			if ( !strcmp( killedwith+2, "turret_sentry" ) )
				strcpy( killedwith, "d_Sentry Turret" );
			if ( !strcmp( killedwith+2, "turret_ion" ) )
				strcpy( killedwith, "d_Ion Turret" );
			if ( !strcmp( killedwith+2, "dumbfire" ) )
				strcpy( killedwith, "d_Missile Turret" );
			if ( !strcmp( killedwith+2, "satchel" ) )
				strcpy( killedwith, "d_Satchel Charge" );
			if ( !strcmp( killedwith+2, "biomass" ) )
				strcpy( killedwith, "d_Bio Rifle" );
			if ( !strcmp( killedwith+2, "u2" ) )
				strcpy( killedwith, "d_U2 Assault Rifle" );
			if ( !strcmp( killedwith+2, "u2momma" ) )
				strcpy( killedwith, "d_U2 Grenade" );
			if ( !strcmp( killedwith+2, "u2baby" ) )
				strcpy( killedwith, "d_U2 Grenade" );
			if ( !strcmp( killedwith+2, "deagle" ) )
				strcpy( killedwith, "d_Desert Eagle" );
			if ( !strcmp( killedwith+2, "usp" ) )
				strcpy( killedwith, "d_Silenced USP Match" );
			if ( !strcmp( killedwith+2, "357" ) )
				strcpy( killedwith, "d_Python 357" );
			if ( !strcmp( killedwith+2, "shotgun" ) )
				strcpy( killedwith, "d_SPAS 14" );
			if ( !strcmp( killedwith+2, "autoshotgun" ) )
				strcpy( killedwith, "d_Combat SPAS-12" );
			if ( !strcmp( killedwith+2, "g11" ) )
				strcpy( killedwith, "d_H&K G11" );
			if ( !strcmp( killedwith+2, "plasma" ) )
				strcpy( killedwith, "d_Plasma Rifle" );
			if ( !strcmp( killedwith+2, "plasma2" ) )
				strcpy( killedwith, "d_Plasma Rifle" );
			if ( !strcmp( killedwith+2, "dispball" ) )
				strcpy( killedwith, "d_Displacer" );
			if ( !strcmp( killedwith+2, "teleenter" ) )
				strcpy( killedwith, "d_Displacer" );
			if ( !strcmp( killedwith+2, "pulserifle" ) )
				strcpy( killedwith, "d_Pulse Rifle" );
			if ( !strcmp( killedwith+2, "pulse" ) )
				strcpy( killedwith, "d_Pulse Rifle" );
			if ( !strcmp( killedwith+2, "teslagun" ) )
				strcpy( killedwith, "d_M41A Tesla Gun" );
			if ( !strcmp( killedwith+2, "teslagren" ) )
				strcpy( killedwith, "d_Shock Grenade" );
			if ( !strcmp( killedwith+2, "barett" ) )
				strcpy( killedwith, "d_M82 Barett" );
			if ( !strcmp( killedwith+2, "hellfire" ) )
				strcpy( killedwith, "d_Incendiary Cannon" );
			if ( !strcmp( killedwith+2, "nail" ) )
				strcpy( killedwith, "d_Nailgun" );
			if ( !strcmp( killedwith+2, "photongun" ) )
				strcpy( killedwith, "d_Photon Gun" );
			if ( !strcmp( killedwith+2, "taucannon" ) )
				strcpy( killedwith, "d_Tau Particle Weapon" );
			if ( !strcmp( killedwith+2, "shock" ) )
				strcpy( killedwith, "d_Smart Shock Pistol" );
			if ( !strcmp( killedwith+2, "detpack" ) )
				strcpy( killedwith, "d_C4 Explosive" );
			if ( !strcmp( killedwith+2, "sstrike" ) )
				strcpy( killedwith, "d_Satellite Dispersion Cannon" );
			if ( !strcmp( killedwith+2, "uzi" ) )
				strcpy( killedwith, "d_Mac 10" );
			if ( !strcmp( killedwith+2, "uzi_akimbo" ) )
				strcpy( killedwith, "d_Dual Mac 10" );
			if ( !strcmp( killedwith+2, "akimbogun" ) )
				strcpy( killedwith, "d_Steyr Aug + SG552" );
			if ( !strcmp( killedwith+2, "m72" ) )
				strcpy( killedwith, "d_M72 Gauss Rifle" );

			if ( !strcmp( killedwith+2, "x_flame" ) )
				strcpy( killedwith, "d_FIRE" );
			if ( !strcmp( killedwith+2, "x_radiation" ) )
				strcpy( killedwith, "d_RADIATION" );
			if ( !strcmp( killedwith+2, "x_nervegas" ) )
				strcpy( killedwith, "d_NERVEGAS" );
			if ( !strcmp( killedwith+2, "x_poison" ) )
				strcpy( killedwith, "d_POISON" );
			if ( !strcmp( killedwith+2, "x_acid" ) )
				strcpy( killedwith, "d_ACID" );
			if ( !strcmp( killedwith+2, "x_freeze" ) )
				strcpy( killedwith, "d_COLD" );
			if ( !strcmp( killedwith+2, "x_bleeding" ) )
				strcpy( killedwith, "d_BLOOD LOST" );

			ConsolePrint( killedwith+2 ); // skip over the "d_" part
		}

		ConsolePrint( "\n" );
	}

	return 1;
}