From 39ed87570bdb2f86969d4be821c94b722dc71179 Mon Sep 17 00:00:00 2001 From: Joe Ludwig Date: Wed, 26 Jun 2013 15:22:04 -0700 Subject: First version of the SOurce SDK 2013 --- mp/src/game/client/death.cpp | 300 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 mp/src/game/client/death.cpp (limited to 'mp/src/game/client/death.cpp') diff --git a/mp/src/game/client/death.cpp b/mp/src/game/client/death.cpp new file mode 100644 index 00000000..fa63ede8 --- /dev/null +++ b/mp/src/game/client/death.cpp @@ -0,0 +1,300 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Draws the death notices +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" +#include "hud_macros.h" +#include "hudelement.h" +#include "c_playerresource.h" +#include "iclientmode.h" +#include +#include +#include +#include +#include +#include +#include + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CHudDeathNotice : public CHudElement, public vgui::Panel +{ + DECLARE_CLASS_SIMPLE( CHudDeathNotice, vgui::Panel ); +public: + CHudDeathNotice( const char *pElementName ); + void Init( void ); + void VidInit( void ); + bool ShouldDraw( void ); + virtual void Paint(); + + virtual void ApplySchemeSettings( vgui::IScheme *scheme ); + + void FireGameEvent( KeyValues * event); + +private: + CHudTexture *m_iconD_skull; // sprite index of skull icon + + vgui::HFont m_hTextFont; + Color m_clrText; +}; + +using namespace vgui; + +// +//----------------------------------------------------- +// + +DECLARE_HUDELEMENT( CHudDeathNotice ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CHudDeathNotice::CHudDeathNotice( const char *pElementName ) : + CHudElement( pElementName ), BaseClass( NULL, "HudDeathNotice" ) +{ + vgui::Panel *pParent = g_pClientMode->GetViewport(); + SetParent( pParent ); + + SetHiddenBits( HIDEHUD_MISCSTATUS ); +} + +void CHudDeathNotice::ApplySchemeSettings( IScheme *scheme ) +{ + BaseClass::ApplySchemeSettings( scheme ); + + m_hTextFont = scheme->GetFont( "HudNumbersSmall" ); + m_clrText = scheme->GetColor( "FgColor", GetFgColor() ); + + SetPaintBackgroundEnabled( false ); +} + +//----------------------------------------------------- +struct DeathNoticeItem { + char szKiller[MAX_PLAYER_NAME_LENGTH]; + char szVictim[MAX_PLAYER_NAME_LENGTH]; + CHudTexture *iconDeath; // the index number of the associated sprite + int iSuicide; + int iTeamKill; + float flDisplayTime; +}; + +#define MAX_DEATHNOTICES 4 +static int DEATHNOTICE_DISPLAY_TIME = 6; + +// Robin HACKHACK: HL2 doesn't use deathmsgs, so I just forced these down below our minimap. +// It should be positioned by TF2/HL2 separately, and TF2 should position it according to the minimap position +#define DEATHNOTICE_TOP YRES( 140 ) // Was: 20 + +DeathNoticeItem rgDeathNoticeList[ MAX_DEATHNOTICES + 1 ]; + +static ConVar hud_deathnotice_time( "hud_deathnotice_time", "6", 0 ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudDeathNotice::Init( void ) +{ + memset( rgDeathNoticeList, 0, sizeof(rgDeathNoticeList) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudDeathNotice::VidInit( void ) +{ + m_iconD_skull = gHUD.GetIcon( "d_skull" ); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw if we've got at least one death notice in the queue +//----------------------------------------------------------------------------- +bool CHudDeathNotice::ShouldDraw( void ) +{ + return ( CHudElement::ShouldDraw() && ( rgDeathNoticeList[0].iconDeath ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudDeathNotice::Paint() +{ + int x, y; + + surface()->DrawSetTextFont( m_hTextFont ); + surface()->DrawSetTextColor( m_clrText ); + + for ( int i = 0; i < MAX_DEATHNOTICES; i++ ) + { + // we've gone through them all + if ( rgDeathNoticeList[i].iconDeath == NULL ) + break; + + // display time has expired + // remove the current item from the list + if ( rgDeathNoticeList[i].flDisplayTime < gpGlobals->curtime ) + { + Q_memmove( &rgDeathNoticeList[i], &rgDeathNoticeList[i+1], sizeof(DeathNoticeItem) * (MAX_DEATHNOTICES - i) ); + // continue on the next item; stop the counter getting incremented + i--; + continue; + } + + rgDeathNoticeList[i].flDisplayTime = MIN( rgDeathNoticeList[i].flDisplayTime, gpGlobals->curtime + DEATHNOTICE_DISPLAY_TIME ); + + // Draw the death notice + y = DEATHNOTICE_TOP + (20 * i) + 100; //!!! + + CHudTexture *icon = rgDeathNoticeList[i].iconDeath; + if ( !icon ) + continue; + + wchar_t victim[ 256 ]; + wchar_t killer[ 256 ]; + + g_pVGuiLocalize->ConvertANSIToUnicode( rgDeathNoticeList[i].szVictim, victim, sizeof( victim ) ); + g_pVGuiLocalize->ConvertANSIToUnicode( rgDeathNoticeList[i].szKiller, killer, sizeof( killer ) ); + + int len = UTIL_ComputeStringWidth( m_hTextFont, victim ); + + x = ScreenWidth() - len - icon->Width() - 5; + + if ( !rgDeathNoticeList[i].iSuicide ) + { + int lenkiller = UTIL_ComputeStringWidth( m_hTextFont, killer ); + + x -= (5 + lenkiller ); + + // Draw killer's name + surface()->DrawSetTextPos( x, y ); + surface()->DrawUnicodeString( killer ); + surface()->DrawGetTextPos( x, y ); + x += 5; + } + + Color iconColor( 255, 80, 0, 255 ); + + if ( rgDeathNoticeList[i].iTeamKill ) + { + // display it in sickly green + iconColor = Color( 10, 240, 10, 255 ); + } + + // Draw death weapon + icon->DrawSelf( x, y, iconColor ); + + x += icon->Width(); + + // Draw victims name + surface()->DrawSetTextPos( x, y ); + surface()->DrawUnicodeString( victim ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: This message handler may be better off elsewhere +//----------------------------------------------------------------------------- +void CHudDeathNotice::FireGameEvent( KeyValues * event) +{ + // Got message during connection + if ( !g_PR ) + return; + + int killer = engine->GetPlayerForUserID( event->GetInt("killer") ); + int victim = engine->GetPlayerForUserID( event->GetInt("victim") ); + + char killedwith[32]; + Q_snprintf( killedwith, sizeof( killedwith ), "d_%s", event->GetString("weapon") ); + + int i; + for ( i = 0; i < MAX_DEATHNOTICES; i++ ) + { + if ( rgDeathNoticeList[i].iconDeath == NULL ) + break; + } + if ( i == MAX_DEATHNOTICES ) + { // move the rest of the list forward to make room for this item + Q_memmove( rgDeathNoticeList, rgDeathNoticeList+1, sizeof(DeathNoticeItem) * MAX_DEATHNOTICES ); + i = MAX_DEATHNOTICES - 1; + } + + // 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 = ""; + + Q_strncpy( rgDeathNoticeList[i].szKiller, killer_name, MAX_PLAYER_NAME_LENGTH ); + Q_strncpy( rgDeathNoticeList[i].szVictim, victim_name, MAX_PLAYER_NAME_LENGTH ); + + if ( killer == victim || killer == 0 ) + rgDeathNoticeList[i].iSuicide = true; + + if ( !strcmp( killedwith, "d_teammate" ) ) + rgDeathNoticeList[i].iTeamKill = true; + + // try and find the death identifier in the icon list + rgDeathNoticeList[i].iconDeath = gHUD.GetIcon( killedwith ); + if ( !rgDeathNoticeList[i].iconDeath ) + { + // can't find it, so use the default skull & crossbones icon + rgDeathNoticeList[i].iconDeath = m_iconD_skull; + } + + DEATHNOTICE_DISPLAY_TIME = hud_deathnotice_time.GetFloat(); + + rgDeathNoticeList[i].flDisplayTime = gpGlobals->curtime + DEATHNOTICE_DISPLAY_TIME; + + // record the death notice in the console + if ( rgDeathNoticeList[i].iSuicide ) + { + Msg( "%s", rgDeathNoticeList[i].szVictim ); + + if ( !strcmp( killedwith, "d_world" ) ) + { + Msg( " died" ); + } + else + { + Msg( " killed self" ); + } + } + else if ( rgDeathNoticeList[i].iTeamKill ) + { + Msg( "%s", rgDeathNoticeList[i].szKiller ); + Msg( " killed his teammate " ); + Msg( "%s", rgDeathNoticeList[i].szVictim ); + } + else + { + Msg( "%s", rgDeathNoticeList[i].szKiller ); + Msg( " killed " ); + Msg( "%s", rgDeathNoticeList[i].szVictim ); + } + + if ( killedwith && *killedwith && (*killedwith > 13 ) && strcmp( killedwith, "d_world" ) && !rgDeathNoticeList[i].iTeamKill ) + { + Msg( " with " ); + + // replace the code names with the 'real' names + if ( !strcmp( killedwith+2, "egon" ) ) + Q_strncpy( killedwith, "d_gluon gun", sizeof( killedwith ) ); + if ( !strcmp( killedwith+2, "gauss" ) ) + Q_strncpy( killedwith, "d_tau cannon", sizeof( killedwith ) ); + + Msg( killedwith+2 ); // skip over the "d_" part + } + + Msg( "\n" ); +} + + + + -- cgit v1.2.3