diff options
Diffstat (limited to 'game/client/dod/dod_hud_deathstats.cpp')
| -rw-r--r-- | game/client/dod/dod_hud_deathstats.cpp | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/game/client/dod/dod_hud_deathstats.cpp b/game/client/dod/dod_hud_deathstats.cpp new file mode 100644 index 0000000..90fa064 --- /dev/null +++ b/game/client/dod/dod_hud_deathstats.cpp @@ -0,0 +1,383 @@ + +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "dod_hud_deathstats.h" +#include "vgui_controls/AnimationController.h" +#include "iclientmode.h" +#include <vgui_controls/Label.h> +#include <vgui/ILocalize.h> +#include <vgui/ISurface.h> +#include "hud_macros.h" +#include "c_dod_playerresource.h" +#include "c_dod_team.h" +#include "c_dod_player.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern ConVar cl_deathicon_width; +extern ConVar cl_deathicon_height; + +//DECLARE_HUDELEMENT( CDODDeathStatsPanel ); + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CDODDeathStatsPanel::CDODDeathStatsPanel( const char *pElementName ) +: EditablePanel( NULL, "DeathStats" ), CHudElement( pElementName ) +{ + vgui::Panel *pParent = g_pClientMode->GetViewport(); + SetParent( pParent ); + SetVisible( false ); + SetAlpha( 0 ); + SetScheme( "ClientScheme" ); + + m_pAttackerHistoryLabel = new vgui::Label( this, "AttackerDmgLabel", "..." ); + m_pSummaryLabel = new vgui::Label( this, "LifeSummaryLabel", "..." ); + + memset( &m_DeathRecord, 0, sizeof(m_DeathRecord) ); + + LoadControlSettings("Resource/UI/DeathStats.res"); +} + +void CDODDeathStatsPanel::OnScreenSizeChanged( int iOldWide, int iOldTall ) +{ + LoadControlSettings( "resource/UI/DeathStats.res" ); +} + +void CDODDeathStatsPanel::ApplySchemeSettings( vgui::IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); + + SetBgColor( GetSchemeColor("TransparentLightBlack", pScheme) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDODDeathStatsPanel::Reset() +{ + Hide(); +} + +void CDODDeathStatsPanel::Init() +{ + Hide(); + + ListenForGameEvent( "player_death" ); + + m_iMaterialTexture = vgui::surface()->CreateNewTextureID(); + + CHudElement::Init(); +} + +void CDODDeathStatsPanel::VidInit( void ) +{ + m_iconD_skull = gHUD.GetIcon( "d_skull_dod" ); + m_pIconKill = gHUD.GetIcon( "stats_kill" ); + m_pIconWounded = gHUD.GetIcon( "stats_wounded" ); + m_pIconCap = gHUD.GetIcon( "stats_cap" ); + m_pIconDefended = gHUD.GetIcon( "stats_defended" ); +} + +//----------------------------------------------------------------------------- +// Purpose: Handle player_death message +//----------------------------------------------------------------------------- +void CDODDeathStatsPanel::FireGameEvent( IGameEvent * event) +{ + if ( Q_strcmp( "player_death", event->GetName() ) == 0 ) + { + C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); + + if ( !pLocalPlayer ) + return; + + if ( !g_PR ) + return; + + int victim = engine->GetPlayerForUserID( event->GetInt("userid") ); + + // only deal with deathnotices where we die + if ( victim != pLocalPlayer->entindex() ) + { + return; + } + + int killer = engine->GetPlayerForUserID( event->GetInt("attacker") ); + + const char *killedwith = event->GetString( "weapon" ); + + char fullkilledwith[128]; + if ( killedwith && *killedwith ) + { + Q_snprintf( fullkilledwith, sizeof(fullkilledwith), "d_%s", killedwith ); + } + else + { + fullkilledwith[0] = 0; + } + + // Get the names of the players + const char *killer_name = g_PR->GetPlayerName( killer ); + const char *victim_name = g_PR->GetPlayerName( victim ); + + if ( !killer_name ) + killer_name = ""; + if ( !victim_name ) + victim_name = ""; + + m_DeathRecord.Killer.iEntIndex = killer; + m_DeathRecord.Victim.iEntIndex = victim; + Q_strncpy( m_DeathRecord.Killer.szName, killer_name, MAX_PLAYER_NAME_LENGTH ); + Q_strncpy( m_DeathRecord.Victim.szName, victim_name, MAX_PLAYER_NAME_LENGTH ); + m_DeathRecord.bSuicide = ( !killer || killer == victim ); + + // Try and find the death identifier in the icon list + m_DeathRecord.iconDeath = gHUD.GetIcon( fullkilledwith ); + + if ( !m_DeathRecord.iconDeath ) + { + // Can't find it, so use the default skull & crossbones icon + m_DeathRecord.iconDeath = m_iconD_skull; + } + + // Info we get from this message: + // - who killed us with what + + // Info that is networked to the local player + // - the hitgroups we hit the guy who killed us with + // - life kills + // - life woundings + // - life caps + // - life defenses + + Show(); + } +} + +const char *szHitgroupNames[] = +{ + "head", + "chest", + "arm", + "leg" +}; + +void CDODDeathStatsPanel::Paint( void ) +{ + int deathNoticeWidth = 0; + + if ( m_DeathRecord.Victim.iEntIndex > 0 ) + deathNoticeWidth = DrawDeathNoticeItem( m_iDeathNoticeX, m_iDeathNoticeY ); + + const int minWidth = XRES(160); + + int panelWidth = ( deathNoticeWidth < minWidth ? minWidth : deathNoticeWidth ); + + int wide, tall; + + // set width of summary label to death notice width + m_pSummaryLabel->GetSize( wide, tall ); + m_pSummaryLabel->SetSize( panelWidth, tall ); + + C_DODPlayer *pLocalPlayer = C_DODPlayer::GetLocalDODPlayer(); + + if ( !pLocalPlayer ) + return; + + char buf[512]; + buf[0] = '\0'; + + if ( !m_DeathRecord.bSuicide ) + { + bool bStart = true; + bool bHit = false; + + for ( int i=0;i<4;i++ ) + { + if ( pLocalPlayer->m_iHitsOnAttacker[i] > 0 ) + { + bHit = true; + if ( bStart ) + { + Q_snprintf( buf, sizeof(buf), "You hit %s %i %s in the %s\n", + m_DeathRecord.Killer.szName, + pLocalPlayer->m_iHitsOnAttacker[i], + pLocalPlayer->m_iHitsOnAttacker[i] == 1 ? "time" : "times", + szHitgroupNames[i] ); + + bStart = false; + } + else + { + Q_snprintf( buf, sizeof(buf), "%s and %i %s in the %s\n", + buf, + pLocalPlayer->m_iHitsOnAttacker[i], + pLocalPlayer->m_iHitsOnAttacker[i] == 1 ? "time" : "times", + szHitgroupNames[i] ); + } + } + } + } + + Q_strncat( buf, "\n", sizeof(buf), COPY_ALL_CHARACTERS ); + + if ( pLocalPlayer->m_iPerLifeKills ) + { + Q_snprintf( buf, sizeof(buf), "%sKills: %i\n\n", + buf, + pLocalPlayer->m_iPerLifeKills ); + } + + if ( pLocalPlayer->m_iPerLifeWounded ) + { + Q_snprintf( buf, sizeof(buf), "%sWounded: %i\n\n", + buf, + pLocalPlayer->m_iPerLifeWounded ); + } + + if ( pLocalPlayer->m_iPerLifeCaptures ) + { + Q_snprintf( buf, sizeof(buf), "%sFlag Captures: %i\n\n", + buf, + pLocalPlayer->m_iPerLifeCaptures ); + } + + if ( pLocalPlayer->m_iPerLifeDefenses ) + { + Q_snprintf( buf, sizeof(buf), "%sFlag Defenses: %i\n\n", + buf, + pLocalPlayer->m_iPerLifeDefenses ); + } + + m_pAttackerHistoryLabel->SetText( buf ); + m_pAttackerHistoryLabel->SizeToContents(); + + int panel_h = YRES(160); + + SetSize( panelWidth, panel_h ); +} + +float GetScale( int nIconWidth, int nIconHeight, int nWidth, int nHeight ); + +int CDODDeathStatsPanel::DrawDeathNoticeItem( int x, int y ) +{ + // Get the team numbers for the players involved + int iKillerTeam = TEAM_UNASSIGNED; + int iVictimTeam = TEAM_UNASSIGNED; + + if( g_PR ) + { + iKillerTeam = g_PR->GetTeam( m_DeathRecord.Killer.iEntIndex ); + iVictimTeam = g_PR->GetTeam( m_DeathRecord.Victim.iEntIndex ); + } + + wchar_t victim[ 256 ]; + wchar_t killer[ 256 ]; + + g_pVGuiLocalize->ConvertANSIToUnicode( m_DeathRecord.Victim.szName, victim, sizeof( victim ) ); + g_pVGuiLocalize->ConvertANSIToUnicode( m_DeathRecord.Killer.szName, killer, sizeof( killer ) ); + + // Get the local position for this notice + int len = UTIL_ComputeStringWidth( m_hTextFont, victim ); + + int iconWide; + int iconTall; + + CHudTexture *icon = m_DeathRecord.iconDeath; + + Assert( icon ); + + if ( !icon ) + return 0; + + if( icon->bRenderUsingFont ) + { + iconWide = surface()->GetCharacterWidth( icon->hFont, icon->cCharacterInFont ); + iconTall = surface()->GetFontTall( icon->hFont ); + } + else + { + float scale = GetScale( icon->Width(), icon->Height(), XRES(cl_deathicon_width.GetInt()), YRES(cl_deathicon_height.GetInt()) ); + iconWide = (int)( scale * (float)icon->Width() ); + iconTall = (int)( scale * (float)icon->Height() ); + } + + int spacerX = XRES(5); + + //int x = xRight - len - spacerX - iconWide - XRES(10); + + surface()->DrawSetTextFont( m_hTextFont ); + int iFontTall = vgui::surface()->GetFontTall( m_hTextFont ); + int yText = y + ( iconTall - iFontTall ) / 2; + + int boxWidth = len + iconWide + spacerX; + int boxHeight = MIN( iconTall, m_flLineHeight ); + int boxBorder = XRES(2); + + // Only draw killers name if it wasn't a suicide + if ( !m_DeathRecord.bSuicide ) + { + int nameWidth = UTIL_ComputeStringWidth( m_hTextFont, killer ) + spacerX; // gap + + //x -= nameWidth; + boxWidth += nameWidth; + + Panel::DrawBox( x-boxBorder, + y-boxBorder, + boxWidth+2*boxBorder, + boxHeight+2*boxBorder, + m_ActiveBackgroundColor, + 1.0 ); + + Color c = g_PR->GetTeamColor( iKillerTeam ); + surface()->DrawSetTextColor( c ); + + // Draw killer's name + surface()->DrawSetTextPos( x, yText ); + const wchar_t *p = killer; + while ( *p ) + { + surface()->DrawUnicodeChar( *p++ ); + } + surface()->DrawGetTextPos( x, yText ); + + x += spacerX; + } + else + { + Panel::DrawBox( x-boxBorder, + y-boxBorder, + boxWidth+2*boxBorder, + boxHeight+2*boxBorder, + m_ActiveBackgroundColor, + 1.0 ); + } + + Color iconColor( 255, 80, 0, 255 ); + + // Draw death weapon + //If we're using a font char, this will ignore iconTall and iconWide + icon->DrawSelf( x, y, iconWide, iconTall, iconColor ); + x += iconWide + spacerX; + + Color c = g_PR->GetTeamColor( iVictimTeam ); + surface()->DrawSetTextColor( c ); + + // Draw victims name + surface()->DrawSetTextFont( m_hTextFont ); //reset the font, draw icon can change it + surface()->DrawSetTextPos( x, yText ); + const wchar_t *p = victim; + while ( *p ) + { + surface()->DrawUnicodeChar( *p++ ); + } + + return boxWidth; +} |