mirror of
https://github.com/unknownworlds/NS.git
synced 2024-12-22 18:31:11 +00:00
323 lines
8.9 KiB
C++
323 lines
8.9 KiB
C++
|
/***
|
||
|
*
|
||
|
* Copyright (c) 1999, Valve LLC. All rights reserved.
|
||
|
*
|
||
|
* This product contains software technology licensed from Id
|
||
|
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||
|
* All Rights Reserved.
|
||
|
*
|
||
|
* Use, distribution, and modification of this source code and/or resulting
|
||
|
* object code is restricted to non-commercial enhancements to products from
|
||
|
* Valve LLC. All other use, distribution, or modification is prohibited
|
||
|
* without written permission from Valve LLC.
|
||
|
*
|
||
|
****/
|
||
|
//
|
||
|
// death notice
|
||
|
//
|
||
|
#include "hud.h"
|
||
|
#include "cl_util.h"
|
||
|
|
||
|
#include <string.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#include "vgui_TeamFortressViewport.h"
|
||
|
#include "mod/AvHHudConstants.h"
|
||
|
#include "pm_shared/pm_shared.h"
|
||
|
#include "mod/AvHNetworkMessages.h"
|
||
|
|
||
|
DECLARE_MESSAGE( m_DeathNotice, DeathMsg );
|
||
|
|
||
|
struct DeathNoticeItem {
|
||
|
char szKiller[MAX_PLAYER_NAME_LENGTH*2];
|
||
|
char szVictim[MAX_PLAYER_NAME_LENGTH*2];
|
||
|
int iId; // the index number of the associated sprite
|
||
|
int iSuicide;
|
||
|
int iTeamKill;
|
||
|
int iNonPlayerKill;
|
||
|
float flDisplayTime;
|
||
|
float *KillerColor;
|
||
|
float *VictimColor;
|
||
|
};
|
||
|
|
||
|
#define MAX_DEATHNOTICES 4
|
||
|
static int DEATHNOTICE_DISPLAY_TIME = 6;
|
||
|
|
||
|
#define DEATHNOTICE_TOP 20
|
||
|
|
||
|
DeathNoticeItem rgDeathNoticeList[ MAX_DEATHNOTICES + 1 ];
|
||
|
|
||
|
// Changing these? Change them in vgui_TeamFortressViewport::iTeamColors as well
|
||
|
float g_ColorWhite[3] = { 1.0, 1.0f, 1.0 };
|
||
|
float g_ColorBlue[3] = { .49, .65, .82 };
|
||
|
float g_ColorOrange[3] = { 1.0, .66, 0.0 };
|
||
|
float g_ColorGreen[3] = { .56, .84, .55 };
|
||
|
float g_ColorRed[3] = { .78, .35, .27 };
|
||
|
|
||
|
float g_ColorYellow[3] = { 1.0, .96, .39 };
|
||
|
|
||
|
float* GetClientColor(int clientIndex)
|
||
|
{
|
||
|
int theTeamNumber = g_PlayerExtraInfo[clientIndex].teamnumber;
|
||
|
return kFTeamColors[theTeamNumber];
|
||
|
}
|
||
|
|
||
|
int CHudDeathNotice :: Init( void )
|
||
|
{
|
||
|
gHUD.AddHudElem( this );
|
||
|
|
||
|
HOOK_MESSAGE( DeathMsg );
|
||
|
|
||
|
CVAR_CREATE( "hud_deathnotice_time", "6", 0 );
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CHudDeathNotice :: InitHUDData( void )
|
||
|
{
|
||
|
memset( rgDeathNoticeList, 0, sizeof(rgDeathNoticeList) );
|
||
|
}
|
||
|
|
||
|
|
||
|
int CHudDeathNotice :: VidInit( void )
|
||
|
{
|
||
|
m_HUD_d_skull = gHUD.GetSpriteIndex( "d_skull" );
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int CHudDeathNotice :: Draw( float flTime )
|
||
|
{
|
||
|
int x, y, r, g, b;
|
||
|
|
||
|
for ( int i = 0; i < MAX_DEATHNOTICES; i++ )
|
||
|
{
|
||
|
if ( rgDeathNoticeList[i].iId == 0 )
|
||
|
break; // we've gone through them all
|
||
|
|
||
|
if ( rgDeathNoticeList[i].flDisplayTime < flTime )
|
||
|
{
|
||
|
// display time has expired, remove the current item from the list
|
||
|
memmove( &rgDeathNoticeList[i], &rgDeathNoticeList[i+1], sizeof(DeathNoticeItem) * (MAX_DEATHNOTICES - i) );
|
||
|
i--; // continue on the next item; stop the counter getting incremented
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
rgDeathNoticeList[i].flDisplayTime = min( rgDeathNoticeList[i].flDisplayTime, gHUD.m_flTime + DEATHNOTICE_DISPLAY_TIME );
|
||
|
|
||
|
// Only draw if the viewport will let me
|
||
|
if ( gViewPort && gViewPort->AllowedToPrintText() )
|
||
|
{
|
||
|
// Draw the death notice
|
||
|
//y = DEATHNOTICE_TOP + (20 * i); //!!!
|
||
|
int theBaseY = DEATHNOTICE_TOP;
|
||
|
|
||
|
// Bring down death messages when in top down or when we're drawing letter box
|
||
|
if(gHUD.m_Spectator.IsInOverviewMode())
|
||
|
{
|
||
|
// No HUD elements to compensate for
|
||
|
}
|
||
|
else if(gHUD.GetInTopDownMode())
|
||
|
{
|
||
|
theBaseY = .10*ScreenHeight();
|
||
|
}
|
||
|
else if(gHUD.GetIsMarine())
|
||
|
{
|
||
|
theBaseY = .26*ScreenHeight();
|
||
|
}
|
||
|
else if(gHUD.GetIsAlien())
|
||
|
{
|
||
|
theBaseY = kHiveNormScreenY*ScreenHeight() + (kMaxHives-1)*((kHiveNormScreenHeight + kHiveNormScreenVerticalSpacing)*ScreenHeight());
|
||
|
}
|
||
|
|
||
|
// Lower death messages more when spectating so they don't overlap (due to letterbox)
|
||
|
if(g_iUser1 != OBS_NONE)
|
||
|
{
|
||
|
theBaseY += .06*ScreenHeight();
|
||
|
}
|
||
|
|
||
|
y = theBaseY + (20 * i); //!!!
|
||
|
|
||
|
int id = (rgDeathNoticeList[i].iId == -1) ? m_HUD_d_skull : rgDeathNoticeList[i].iId;
|
||
|
x = ScreenWidth() - ConsoleStringLen(rgDeathNoticeList[i].szVictim) - (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left);
|
||
|
|
||
|
if ( !rgDeathNoticeList[i].iSuicide )
|
||
|
{
|
||
|
x -= (5 + ConsoleStringLen( rgDeathNoticeList[i].szKiller ) );
|
||
|
|
||
|
// Draw killers name
|
||
|
if ( rgDeathNoticeList[i].KillerColor )
|
||
|
DrawSetTextColor( rgDeathNoticeList[i].KillerColor[0], rgDeathNoticeList[i].KillerColor[1], rgDeathNoticeList[i].KillerColor[2] );
|
||
|
x = 5 + DrawConsoleString( x, y, rgDeathNoticeList[i].szKiller );
|
||
|
}
|
||
|
|
||
|
r = 255; g = 80; b = 0;
|
||
|
if ( rgDeathNoticeList[i].iTeamKill )
|
||
|
{
|
||
|
r = 10; g = 240; b = 10; // display it in sickly green
|
||
|
}
|
||
|
|
||
|
// Draw death weapon
|
||
|
SPR_Set( gHUD.GetSprite(id), r, g, b );
|
||
|
SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect(id) );
|
||
|
|
||
|
x += (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left);
|
||
|
|
||
|
// Draw victims name (if it was a player that was killed)
|
||
|
if (rgDeathNoticeList[i].iNonPlayerKill == FALSE)
|
||
|
{
|
||
|
if ( rgDeathNoticeList[i].VictimColor )
|
||
|
DrawSetTextColor( rgDeathNoticeList[i].VictimColor[0], rgDeathNoticeList[i].VictimColor[1], rgDeathNoticeList[i].VictimColor[2] );
|
||
|
x = DrawConsoleString( x, y, rgDeathNoticeList[i].szVictim );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
// This message handler may be better off elsewhere
|
||
|
int CHudDeathNotice :: MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbuf )
|
||
|
{
|
||
|
m_iFlags |= HUD_ACTIVE;
|
||
|
|
||
|
int killer, victim;
|
||
|
string killed_with;
|
||
|
NetMsg_DeathMsg( pbuf, iSize, killer, victim, killed_with );
|
||
|
|
||
|
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, killed_with.c_str()+2 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( killer == victim || killer == 0 )
|
||
|
rgDeathNoticeList[i].iSuicide = TRUE;
|
||
|
|
||
|
if ( !strcmp( killed_with.c_str(), "d_teammate" ) )
|
||
|
rgDeathNoticeList[i].iTeamKill = TRUE;
|
||
|
}
|
||
|
|
||
|
// Find the sprite in the list
|
||
|
char killed_with_spritename[32];
|
||
|
sprintf(killed_with_spritename, "d_%s", killed_with.c_str());
|
||
|
int spr = gHUD.GetSpriteIndex( killed_with_spritename );
|
||
|
|
||
|
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( killed_with.c_str(), "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 ( !killed_with.empty() && killed_with != "world" && !rgDeathNoticeList[i].iTeamKill )
|
||
|
{
|
||
|
ConsolePrint( " with " );
|
||
|
|
||
|
// replace the code names with the 'real' names
|
||
|
if ( killed_with == "d_egon" )
|
||
|
killed_with = "d_gluon gun";
|
||
|
if ( killed_with == "gauss" )
|
||
|
killed_with = "d_tau cannon";
|
||
|
ConsolePrint( killed_with.c_str()); // skip over the "d_" part
|
||
|
}
|
||
|
|
||
|
ConsolePrint( "\n" );
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|