From 849f340b93c720914d286e3abe2ffc13c542b93c Mon Sep 17 00:00:00 2001 From: Jakub Mach Date: Wed, 14 Apr 2021 01:57:46 +0200 Subject: [PATCH 1/5] PoC of ingame nametags, initial commit --- cl_dll/hud.cpp | 1 + cl_dll/hud.h | 3 +- cl_dll/hud_nametags.cpp | 231 ++++++++++++++++++++++++++++++++++++++++ cl_dll/hud_nametags.h | 67 ++++++++++++ 4 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 cl_dll/hud_nametags.cpp create mode 100644 cl_dll/hud_nametags.h diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 6d7d92fb..e35375cc 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -578,6 +578,7 @@ void CHud :: Init( void ) m_Vote.Init(); m_Watermark.Init(); m_OldScoreBoard.Init(); + m_NameTags.Init(); GetClientVoiceMgr()->Init(&g_VoiceStatusHelper, (vgui::Panel**)&gViewPort); m_Menu.Init(); diff --git a/cl_dll/hud.h b/cl_dll/hud.h index cb14c970..29e013d2 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -110,7 +110,7 @@ struct HUDLIST { #include "hud_vote.h" #include "hud_watermark.h" #include "rainbow.h" - +#include "hud_nametags.h" // //----------------------------------------------------- @@ -690,6 +690,7 @@ class CHud CHudOldScoreboard m_OldScoreBoard; CRainbow m_Rainbow; + CHudNameTags m_NameTags; void Init( void ); void VidInit( void ); diff --git a/cl_dll/hud_nametags.cpp b/cl_dll/hud_nametags.cpp new file mode 100644 index 00000000..c6923fd3 --- /dev/null +++ b/cl_dll/hud_nametags.cpp @@ -0,0 +1,231 @@ +//========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#include "hud.h" +#include "cl_util.h" +#include "cl_entity.h" +#include "triangleapi.h" +#include "vgui_TeamFortressViewport.h" +#include "vgui_SpectatorPanel.h" +#include "hltv.h" + +#include "pm_shared.h" +#include "pm_defs.h" +#include "pmtrace.h" +#include "parsemsg.h" +#include "entity_types.h" + +// these are included for the math functions +#include "com_model.h" +#include "demo_api.h" +#include "event_api.h" +#include "studio_util.h" +#include "screenfade.h" + + +#ifdef _MSC_VER +#pragma warning(disable: 4244) +#endif + +extern "C" float Distance(const float * v1, const float * v2); +extern float * GetClientColor( int clientIndex ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CHudNameTags::Init() +{ + gHUD.AddHudElem(this); + + m_iFlags |= HUD_ACTIVE; + + m_hud_nametags = gEngfuncs.pfnRegisterVariable("hud_nametags","1",0); + m_hud_nametags_type = gEngfuncs.pfnRegisterVariable("hud_nametags_type","1",0); + m_hud_nametags_team_always = gEngfuncs.pfnRegisterVariable("m_hud_nametags_team_always","1",0); + + return 1; +} + + +//----------------------------------------------------------------------------- +// Purpose: Loads new icons +//----------------------------------------------------------------------------- +int CHudNameTags::VidInit() +{ + m_iFlags &= ~HUD_ACTIVE; + + return 1; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : flTime - +// intermission - +//----------------------------------------------------------------------------- +int CHudNameTags::Draw(float flTime) +{ + // Only draw if client wants us to + if(m_hud_nametags->value != 1) return 1; + + int lx; + + char string[256]; + float * color; + + // make sure we have player info + gViewPort->GetAllPlayersInfo(); + + vec3_t origin, angles, point, forward, right, left, up, world, screen, offset; + float x,y,z; + int r,g,b; + cl_entity_t * ent; + float rmatrix[3][4]; // transformation matrix + //float zScale = (90.0f - v_angles[0] ) / 90.0f; + + // get yellow/brown HUD color + UnpackRGB(r, g, b, gHUD.m_iDefaultHUDColor); + + cl_entity_t *localPlayer = gEngfuncs.GetLocalPlayer(); + + // loop through all the players and draw additional infos to their sprites on the map + for (int i = 0; i < MAX_PLAYERS; i++) + { + //ent = m_OverviewEntities[i].entity; + cl_entity_s *ent = gEngfuncs.GetEntityByIndex(i+1); + + if(!ent || ent->curstate.messagenum < localPlayer->curstate.messagenum) + continue; + + if (!ent->player) + continue; + + // Don't draw nickname for ourselves + if(ent == localPlayer) + continue; + + if (g_PlayerInfoList[i + 1].name == nullptr) + continue; + + // Don't show an icon for dead or spectating players (ie: invisible entities). + if(ent->curstate.effects & EF_NODRAW) + continue; + + VectorCopy(ent->origin, origin); + origin[2] += 45.0f; // Kinda above the head TODO: Fix somewhat? + + // calculate screen position for name and infromation in hud::draw() + if ( gEngfuncs.pTriAPI->WorldToScreen(origin, screen) ) + continue; // object is behind viewer + + /*char mrdka[512]; + _snprintf( mrdka, sizeof( mrdka ), "HUD_SPEC ORIGIN x = %f, ORIGIN y = %f \n", origin[0], origin[1]); + gEngfuncs.pfnConsolePrint( mrdka ); + _snprintf( mrdka, sizeof( mrdka ), "HUD_SPEC BEFORE screen x = %f, screen y = %f \n", screen[0], screen[1]); + gEngfuncs.pfnConsolePrint( mrdka );*/ + + screen[0] = XPROJECT(screen[0]); + screen[1] = YPROJECT(screen[1]); + screen[2] = 0.0f; + + //_snprintf( mrdka, sizeof( mrdka ), "HUD_SPEC AFTER screen x = %f, screen y = %f \n", screen[0], screen[1]); + //gEngfuncs.pfnConsolePrint( mrdka ); + + x = screen[0]; + y = screen[1]; //+ Length(offset); + + color = GetClientColor( i+1 ); + + // draw the players name and health underneath + char colorless_name[256]; + color_tags::strip_color_tags(colorless_name, g_PlayerInfoList[i + 1].name, ARRAYSIZE(colorless_name)); + + //sprintf(string, "%s", g_PlayerInfoList[i+1].name ); + sprintf(string, "%s", colorless_name); + + lx = strlen(string)*3; // 3 is avg. character length :) + + // TODO: Fix, this can't trace origin to origin, it's not accurate + // TODO: e.g. when we are under the player and there are walls in the way + // TODO: etc. + pmtrace_t * trace = gEngfuncs.PM_TraceLine( localPlayer->origin, ent->origin, PM_TRACELINE_PHYSENTSONLY, 2, -1 ); + + if ( trace->fraction != 1.0 ) + { + // We didn't hit + //gEngfuncs.pfnServerCmd(string); + } + else + { + // If the player is 600 units away from the local player, show the nametag + // Or if we are playing a demo, show the nametag however far away he is + // Or if client wants teammates to always appear, regardless of their distance (obv only when in our PVS and traceable) + // TODO: Really distance? & really 600? + if(Distance(trace->endpos, localPlayer->origin) < 600.0f + || gEngfuncs.pDemoAPI->IsPlayingback() + || (g_PlayerExtraInfo[i + 1].teamname == g_PlayerExtraInfo[localPlayer->index].teamname && m_hud_nametags_team_always->value == 1) + ) + { + char mrdka[512]; + sprintf(mrdka, "X=%.2f Y=%.2f Z=%.2f\n", trace->endpos[0], trace->endpos[1], trace->endpos[2]); + gEngfuncs.pfnConsolePrint( mrdka ); + sprintf(mrdka, "PL X=%.2f Y=%.2f Z=%.2f\n", localPlayer->origin[0], localPlayer->origin[1], localPlayer->origin[2]); + gEngfuncs.pfnConsolePrint( mrdka ); + //gEngfuncs.pfnServerCmd(string); + + if(m_hud_nametags_type->value == 1) // Looks like "amxx_csay" HUD font + { + gHUD.DrawConsoleStringWithColorTags( + //m_vPlayerPos[i][0] - lx, + //m_vPlayerPos[i][1], + x - lx, + y, // - 50, + string, + true, + color[0], + color[1], + color[2] + ); + } + else // Looks like chat HUD font + { + //gEngfuncs.pfnDrawString(x - lx, y, string, r, g, b ); + gHUD.DrawHudStringCentered(x, y, string, r, g, b); + } + } + else + { + char mrdka[512]; + sprintf(mrdka, "HE TOO FAR AWAY"); + gEngfuncs.pfnConsolePrint( mrdka ); + } + } + } + + return 1; +} +bool CHudNameTags::IsActivePlayer(cl_entity_t * ent) +{ + return ( ent && + ent->player && + ent->curstate.solid != SOLID_NOT && + ent != gEngfuncs.GetLocalPlayer() && + g_PlayerInfoList[ent->index].name != NULL + ); +} + +void CHudNameTags::Reset() +{ + +} + +void CHudNameTags::InitHUDData() +{ + Reset(); + + // reset HUD FOV + gHUD.m_iFOV = CVAR_GET_FLOAT("default_fov"); +} diff --git a/cl_dll/hud_nametags.h b/cl_dll/hud_nametags.h new file mode 100644 index 00000000..144b45b3 --- /dev/null +++ b/cl_dll/hud_nametags.h @@ -0,0 +1,67 @@ +//========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef NAMETAGS_H +#define NAMETAGS_H +#pragma once + +#include +#include + +#include "cl_entity.h" +#include "interpolation.h" + +extern void VectorAngles( const float *forward, float *angles ); +extern "C" void NormalizeAngles( float *angles ); + +#define MAX_OVERVIEW_ENTITIES 128 +#define MAX_CAM_WAYPOINTS 32 + +class CHudNameTags : public CHudBase +{ + +public: + void Reset(); + void InitHUDData( void ); + bool AddOverviewEntityToList( HSPRITE sprite, cl_entity_t * ent, double killTime); + void DeathMessage(int victim); + bool AddOverviewEntity( int type, struct cl_entity_s *ent, const char *modelname ); + void CheckOverviewEntities(); + bool IsActivePlayer(cl_entity_t * ent); + void DirectorMessage( int iSize, void *pbuf ); + int Init(); + int VidInit(); + + int Draw(float flTime); + + void AddWaypoint( float time, vec3_t pos, vec3_t angle, float fov, int flags ); + void SetCameraView( vec3_t pos, vec3_t angle, float fov); + float GetFOV(); + bool GetDirectorCamera(vec3_t &position, vec3_t &angle); + + int m_iDrawCycle; + client_textmessage_t m_HUDMessages[MAX_SPEC_HUD_MESSAGES]; + char m_HUDMessageText[MAX_SPEC_HUD_MESSAGES][128]; + + cvar_t * m_hud_nametags; + cvar_t * m_hud_nametags_type; + cvar_t * m_hud_nametags_team_always; + +private: + vec3_t m_vPlayerPos[MAX_PLAYERS]; + + float m_flNextObserverInput; + float m_FOV; + float m_zoomDelta; + float m_moveDelta; + int m_lastPrimaryObject; + int m_lastSecondaryObject; + + cameraWayPoint_t m_CamPath[MAX_CAM_WAYPOINTS]; +}; + +#endif // SPECTATOR_H From af61dd4fc05fba519dad28947588d9c59dcf7ebc Mon Sep 17 00:00:00 2001 From: Jakub Mach Date: Thu, 15 Apr 2021 17:19:05 +0200 Subject: [PATCH 2/5] Offset trace by eye height & other stuff --- cl_dll/CMakeLists.txt | 2 + cl_dll/hud.cpp | 2 + cl_dll/hud_nametags.cpp | 174 ++++++++++++++++++++++------------------ cl_dll/hud_nametags.h | 32 +++----- 4 files changed, 108 insertions(+), 102 deletions(-) diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index 2f6396d7..b8c3a1bc 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -36,6 +36,8 @@ add_sources( health.h hud.cpp hud.h + hud_nametags.h + hud_nametags.cpp hud_bench.cpp hud_benchtrace.cpp hud_countdown.cpp diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index e35375cc..4aedb273 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -736,6 +736,7 @@ void CHud :: VidInit( void ) m_Location.VidInit(); m_NextMap.VidInit(); m_PlayerId.VidInit(); + m_NameTags.VidInit(); m_Scores.VidInit(); m_Settings.VidInit(); m_Speedometer.VidInit(); @@ -745,6 +746,7 @@ void CHud :: VidInit( void ) m_Vote.VidInit(); m_Watermark.VidInit(); m_OldScoreBoard.VidInit(); + //m_NameTagsVGUI.VidInit(); GetClientVoiceMgr()->VidInit(); } diff --git a/cl_dll/hud_nametags.cpp b/cl_dll/hud_nametags.cpp index c6923fd3..f853c465 100644 --- a/cl_dll/hud_nametags.cpp +++ b/cl_dll/hud_nametags.cpp @@ -25,7 +25,9 @@ #include "event_api.h" #include "studio_util.h" #include "screenfade.h" - +#include "vgui_TeamFortressViewport.h" +#include "vgui_helpers.h" +#include "vgui_loadtga.h" #ifdef _MSC_VER #pragma warning(disable: 4244) @@ -33,31 +35,34 @@ extern "C" float Distance(const float * v1, const float * v2); extern float * GetClientColor( int clientIndex ); +extern void V_GetInEyePos(int entity, float * origin, float * angles ); + +//DECLARE_MESSAGE(m_NameTags, PlayerId); //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- int CHudNameTags::Init() { + //HOOK_MESSAGE(PlayerId); gHUD.AddHudElem(this); m_iFlags |= HUD_ACTIVE; - m_hud_nametags = gEngfuncs.pfnRegisterVariable("hud_nametags","1",0); - m_hud_nametags_type = gEngfuncs.pfnRegisterVariable("hud_nametags_type","1",0); - m_hud_nametags_team_always = gEngfuncs.pfnRegisterVariable("m_hud_nametags_team_always","1",0); + m_hud_nametags = gEngfuncs.pfnRegisterVariable("hud_nametags","1", FCVAR_ARCHIVE); + m_hud_nametags_type = gEngfuncs.pfnRegisterVariable("hud_nametags_type","1", FCVAR_ARCHIVE); + m_hud_nametags_team_always = gEngfuncs.pfnRegisterVariable("hud_nametags_team_always","1", FCVAR_ARCHIVE); return 1; } - //----------------------------------------------------------------------------- // Purpose: Loads new icons //----------------------------------------------------------------------------- int CHudNameTags::VidInit() { - m_iFlags &= ~HUD_ACTIVE; - + //m_iFlags &= ~HUD_ACTIVE; + //m_hsprPlayer = SPR_Load("sprites/ascii_table_test.spr"); return 1; } @@ -69,34 +74,48 @@ int CHudNameTags::VidInit() int CHudNameTags::Draw(float flTime) { // Only draw if client wants us to - if(m_hud_nametags->value != 1) return 1; - + if(m_hud_nametags->value != 1) + return 1; + int lx; - - char string[256]; + char string[512]; float * color; + vec3_t origin_above_target_head, world, screen; + vec3_t origin_pl; + vec3_t vecSrc; + vec3_t vecTargetPlayer; + vec3_t view_ofs; + float x,y,z; + int r,g,b; + // make sure we have player info gViewPort->GetAllPlayersInfo(); - - vec3_t origin, angles, point, forward, right, left, up, world, screen, offset; - float x,y,z; - int r,g,b; - cl_entity_t * ent; - float rmatrix[3][4]; // transformation matrix - //float zScale = (90.0f - v_angles[0] ) / 90.0f; - + // get server's gamemode + auto gamemode = gHUD.m_Settings.GetGamemode(); // get yellow/brown HUD color UnpackRGB(r, g, b, gHUD.m_iDefaultHUDColor); - + + // get local player and get his eye level cl_entity_t *localPlayer = gEngfuncs.GetLocalPlayer(); - - // loop through all the players and draw additional infos to their sprites on the map + VectorCopy( localPlayer->origin, origin_pl ); + + VectorClear(view_ofs); + + if (localPlayer->curstate.usehull == 1) // if we're ducking + view_ofs[2] = VEC_DUCK_VIEW; + else + view_ofs[2] = DEFAULT_VIEWHEIGHT; + + VectorAdd( origin_pl, view_ofs, vecSrc ); + + //AngleVectors( angles_pl, forward, NULL, NULL ); // For get user aim + for (int i = 0; i < MAX_PLAYERS; i++) { - //ent = m_OverviewEntities[i].entity; cl_entity_s *ent = gEngfuncs.GetEntityByIndex(i+1); + // Target player not here, or not in our PVS if(!ent || ent->curstate.messagenum < localPlayer->curstate.messagenum) continue; @@ -107,101 +126,85 @@ int CHudNameTags::Draw(float flTime) if(ent == localPlayer) continue; + // Don't draw for player without a name (TODO: ?) if (g_PlayerInfoList[i + 1].name == nullptr) continue; - // Don't show an icon for dead or spectating players (ie: invisible entities). + // Don't show a nametag for dead or spectating players (ie: invisible entities). if(ent->curstate.effects & EF_NODRAW) continue; - VectorCopy(ent->origin, origin); - origin[2] += 45.0f; // Kinda above the head TODO: Fix somewhat? + VectorCopy(ent->origin, origin_above_target_head); + origin_above_target_head[2] += 45.0f; // Kinda above the head + // ^ TODO: change based on distance? // calculate screen position for name and infromation in hud::draw() - if ( gEngfuncs.pTriAPI->WorldToScreen(origin, screen) ) + if ( gEngfuncs.pTriAPI->WorldToScreen(origin_above_target_head, screen) ) continue; // object is behind viewer - /*char mrdka[512]; - _snprintf( mrdka, sizeof( mrdka ), "HUD_SPEC ORIGIN x = %f, ORIGIN y = %f \n", origin[0], origin[1]); - gEngfuncs.pfnConsolePrint( mrdka ); - _snprintf( mrdka, sizeof( mrdka ), "HUD_SPEC BEFORE screen x = %f, screen y = %f \n", screen[0], screen[1]); - gEngfuncs.pfnConsolePrint( mrdka );*/ - - screen[0] = XPROJECT(screen[0]); - screen[1] = YPROJECT(screen[1]); - screen[2] = 0.0f; - - //_snprintf( mrdka, sizeof( mrdka ), "HUD_SPEC AFTER screen x = %f, screen y = %f \n", screen[0], screen[1]); - //gEngfuncs.pfnConsolePrint( mrdka ); - - x = screen[0]; - y = screen[1]; //+ Length(offset); + x = XPROJECT(screen[0]); + y = YPROJECT(screen[1]); - color = GetClientColor( i+1 ); + color = GetClientColor( i+1 ); // team color // draw the players name and health underneath char colorless_name[256]; color_tags::strip_color_tags(colorless_name, g_PlayerInfoList[i + 1].name, ARRAYSIZE(colorless_name)); - //sprintf(string, "%s", g_PlayerInfoList[i+1].name ); - sprintf(string, "%s", colorless_name); + /*if(!strcmp(g_PlayerExtraInfo[localPlayer->index].teamname, g_PlayerExtraInfo[i + 1].teamname) && gHUD.m_Teamplay) + sprintf(string, "%s", colorless_name, health, armor, teammate); + else */ // For playerid msg + sprintf(string, "%s", colorless_name); + + lx = strlen(string)*4; // 3 is avg. character length :) + + VectorCopy(ent->origin, vecTargetPlayer); - lx = strlen(string)*3; // 3 is avg. character length :) + // Since the nametag is above the player's head, let's somewhat try to see if we can see his head + if (ent->curstate.usehull == 1) + vecTargetPlayer[2] += VEC_DUCK_VIEW; + else + vecTargetPlayer[2] += DEFAULT_VIEWHEIGHT; - // TODO: Fix, this can't trace origin to origin, it's not accurate - // TODO: e.g. when we are under the player and there are walls in the way - // TODO: etc. - pmtrace_t * trace = gEngfuncs.PM_TraceLine( localPlayer->origin, ent->origin, PM_TRACELINE_PHYSENTSONLY, 2, -1 ); + pmtrace_t * trace = gEngfuncs.PM_TraceLine( vecSrc, vecTargetPlayer, PM_TRACELINE_PHYSENTSONLY, 2, -1 ); - if ( trace->fraction != 1.0 ) + if ( trace->fraction == 1.0 ) { - // We didn't hit - //gEngfuncs.pfnServerCmd(string); - } - else - { - // If the player is 600 units away from the local player, show the nametag + // If the player is 600 units(?) away from the local player, show the nametag // Or if we are playing a demo, show the nametag however far away he is // Or if client wants teammates to always appear, regardless of their distance (obv only when in our PVS and traceable) + // Or if the gamemode is Kreedz + // Or if the localplayer is spectating // TODO: Really distance? & really 600? + // TODO: V_GetInEyePos( g_iUser2, origin, angles ); + if(Distance(trace->endpos, localPlayer->origin) < 600.0f || gEngfuncs.pDemoAPI->IsPlayingback() - || (g_PlayerExtraInfo[i + 1].teamname == g_PlayerExtraInfo[localPlayer->index].teamname && m_hud_nametags_team_always->value == 1) - ) + || (!strcmp(g_PlayerExtraInfo[localPlayer->index].teamname, g_PlayerExtraInfo[i + 1].teamname) + && m_hud_nametags_team_always->value == 1 + && gHUD.m_Teamplay) + || !strcmp(gamemode, "Kreedz") + || g_iUser1 + ) { - char mrdka[512]; - sprintf(mrdka, "X=%.2f Y=%.2f Z=%.2f\n", trace->endpos[0], trace->endpos[1], trace->endpos[2]); - gEngfuncs.pfnConsolePrint( mrdka ); - sprintf(mrdka, "PL X=%.2f Y=%.2f Z=%.2f\n", localPlayer->origin[0], localPlayer->origin[1], localPlayer->origin[2]); - gEngfuncs.pfnConsolePrint( mrdka ); - //gEngfuncs.pfnServerCmd(string); - - if(m_hud_nametags_type->value == 1) // Looks like "amxx_csay" HUD font + if(m_hud_nametags_type->value == 1) // Looks like chat HUD font { gHUD.DrawConsoleStringWithColorTags( - //m_vPlayerPos[i][0] - lx, - //m_vPlayerPos[i][1], x - lx, - y, // - 50, + y, string, true, color[0], color[1], color[2] ); + } - else // Looks like chat HUD font + else // Looks like HUD font { - //gEngfuncs.pfnDrawString(x - lx, y, string, r, g, b ); gHUD.DrawHudStringCentered(x, y, string, r, g, b); } } - else - { - char mrdka[512]; - sprintf(mrdka, "HE TOO FAR AWAY"); - gEngfuncs.pfnConsolePrint( mrdka ); - } } } @@ -225,7 +228,18 @@ void CHudNameTags::Reset() void CHudNameTags::InitHUDData() { Reset(); +} + +int CHudNameTags::MsgFunc_PlayerId(const char* name, int size, void* buf) +{ + BEGIN_READ(buf, size); - // reset HUD FOV - gHUD.m_iFOV = CVAR_GET_FLOAT("default_fov"); + player_id = READ_BYTE(); + teammate = (READ_BYTE() == 1); + health = READ_SHORT(); + armor = READ_SHORT(); + + m_iFlags |= HUD_ACTIVE; + + return 1; } diff --git a/cl_dll/hud_nametags.h b/cl_dll/hud_nametags.h index 144b45b3..8ab00e8c 100644 --- a/cl_dll/hud_nametags.h +++ b/cl_dll/hud_nametags.h @@ -9,6 +9,9 @@ #define NAMETAGS_H #pragma once +#define DEFAULT_VIEWHEIGHT 28 +#define VEC_DUCK_VIEW 12 + #include #include @@ -27,25 +30,19 @@ class CHudNameTags : public CHudBase public: void Reset(); void InitHUDData( void ); - bool AddOverviewEntityToList( HSPRITE sprite, cl_entity_t * ent, double killTime); - void DeathMessage(int victim); - bool AddOverviewEntity( int type, struct cl_entity_s *ent, const char *modelname ); - void CheckOverviewEntities(); bool IsActivePlayer(cl_entity_t * ent); - void DirectorMessage( int iSize, void *pbuf ); + + int MsgFunc_PlayerId(const char* name, int size, void* buf); + //void EV_GetGunPosition(cl_entity_s *args, float *pos, float *origin); int Init(); int VidInit(); int Draw(float flTime); - void AddWaypoint( float time, vec3_t pos, vec3_t angle, float fov, int flags ); - void SetCameraView( vec3_t pos, vec3_t angle, float fov); - float GetFOV(); - bool GetDirectorCamera(vec3_t &position, vec3_t &angle); - - int m_iDrawCycle; - client_textmessage_t m_HUDMessages[MAX_SPEC_HUD_MESSAGES]; - char m_HUDMessageText[MAX_SPEC_HUD_MESSAGES][128]; + int player_id; + bool teammate; + int health; + int armor; cvar_t * m_hud_nametags; cvar_t * m_hud_nametags_type; @@ -53,15 +50,6 @@ class CHudNameTags : public CHudBase private: vec3_t m_vPlayerPos[MAX_PLAYERS]; - - float m_flNextObserverInput; - float m_FOV; - float m_zoomDelta; - float m_moveDelta; - int m_lastPrimaryObject; - int m_lastSecondaryObject; - - cameraWayPoint_t m_CamPath[MAX_CAM_WAYPOINTS]; }; #endif // SPECTATOR_H From ed8b5cf517be6197cdf03519b194cb743c6025e1 Mon Sep 17 00:00:00 2001 From: Jakub Mach Date: Fri, 16 Apr 2021 00:02:48 +0200 Subject: [PATCH 3/5] Disable nametags for enemies, cleanup --- cl_dll/hud_nametags.cpp | 46 ++++++++++++++++++++--------------------- cl_dll/hud_nametags.h | 6 ++++-- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/cl_dll/hud_nametags.cpp b/cl_dll/hud_nametags.cpp index f853c465..924b4cd3 100644 --- a/cl_dll/hud_nametags.cpp +++ b/cl_dll/hud_nametags.cpp @@ -11,19 +11,16 @@ #include "triangleapi.h" #include "vgui_TeamFortressViewport.h" #include "vgui_SpectatorPanel.h" -#include "hltv.h" #include "pm_shared.h" #include "pm_defs.h" #include "pmtrace.h" #include "parsemsg.h" -#include "entity_types.h" // these are included for the math functions #include "com_model.h" #include "demo_api.h" #include "event_api.h" -#include "studio_util.h" #include "screenfade.h" #include "vgui_TeamFortressViewport.h" #include "vgui_helpers.h" @@ -49,9 +46,9 @@ int CHudNameTags::Init() m_iFlags |= HUD_ACTIVE; - m_hud_nametags = gEngfuncs.pfnRegisterVariable("hud_nametags","1", FCVAR_ARCHIVE); - m_hud_nametags_type = gEngfuncs.pfnRegisterVariable("hud_nametags_type","1", FCVAR_ARCHIVE); - m_hud_nametags_team_always = gEngfuncs.pfnRegisterVariable("hud_nametags_team_always","1", FCVAR_ARCHIVE); + m_hud_nametags = gEngfuncs.pfnRegisterVariable("hud_nametags", "1", FCVAR_ARCHIVE); + m_hud_nametags_type = gEngfuncs.pfnRegisterVariable("hud_nametags_type", "1", FCVAR_ARCHIVE); + m_hud_nametags_team_max_distance = gEngfuncs.pfnRegisterVariable("hud_nametags_team_max_distance", "1", FCVAR_ARCHIVE); return 1; } @@ -66,6 +63,13 @@ int CHudNameTags::VidInit() return 1; } +bool CHudNameTags::IsTeamMate(cl_entity_t *localPlayer, int playerId) +{ + return !strcmp(g_PlayerExtraInfo[localPlayer->index].teamname, + g_PlayerExtraInfo[playerId + 1].teamname) + && gHUD.m_Teamplay; +} + //----------------------------------------------------------------------------- // Purpose: // Input : flTime - @@ -73,8 +77,8 @@ int CHudNameTags::VidInit() //----------------------------------------------------------------------------- int CHudNameTags::Draw(float flTime) { - // Only draw if client wants us to - if(m_hud_nametags->value != 1) + // Only draw if client wants us to + if(m_hud_nametags->value != 1) return 1; int lx; @@ -172,33 +176,27 @@ int CHudNameTags::Draw(float flTime) { // If the player is 600 units(?) away from the local player, show the nametag // Or if we are playing a demo, show the nametag however far away he is - // Or if client wants teammates to always appear, regardless of their distance (obv only when in our PVS and traceable) + // Or if client wants teammates to always appear, regardless of their distance (obv only when in our PVS and traceable) // Or if the gamemode is Kreedz // Or if the localplayer is spectating - // TODO: Really distance? & really 600? - // TODO: V_GetInEyePos( g_iUser2, origin, angles ); - - if(Distance(trace->endpos, localPlayer->origin) < 600.0f - || gEngfuncs.pDemoAPI->IsPlayingback() - || (!strcmp(g_PlayerExtraInfo[localPlayer->index].teamname, g_PlayerExtraInfo[i + 1].teamname) - && m_hud_nametags_team_always->value == 1 - && gHUD.m_Teamplay) - || !strcmp(gamemode, "Kreedz") - || g_iUser1 - ) + // TODO: V_GetInEyePos( g_iUser2, origin, angles ); + + if (Distance(trace->endpos, localPlayer->origin) < m_hud_nametags_team_max_distance->value && IsTeamMate(localPlayer, i) || + gEngfuncs.pDemoAPI->IsPlayingback() || + !strcmp(gamemode, "Kreedz") || + g_iUser1) { - if(m_hud_nametags_type->value == 1) // Looks like chat HUD font + if(m_hud_nametags_type->value == 1) // Looks like chat HUD font { gHUD.DrawConsoleStringWithColorTags( - x - lx, - y, + x - lx, + y, string, true, color[0], color[1], color[2] ); - } else // Looks like HUD font { diff --git a/cl_dll/hud_nametags.h b/cl_dll/hud_nametags.h index 8ab00e8c..1c46d2d5 100644 --- a/cl_dll/hud_nametags.h +++ b/cl_dll/hud_nametags.h @@ -45,11 +45,13 @@ class CHudNameTags : public CHudBase int armor; cvar_t * m_hud_nametags; - cvar_t * m_hud_nametags_type; - cvar_t * m_hud_nametags_team_always; + cvar_t * m_hud_nametags_type; + cvar_t * m_hud_nametags_team_max_distance; private: vec3_t m_vPlayerPos[MAX_PLAYERS]; + + bool IsTeamMate(cl_entity_t *localPlayer, int playerId); }; #endif // SPECTATOR_H From 663b81f430fb6bc24214eccd09efc16f513261ae Mon Sep 17 00:00:00 2001 From: Jakub Mach Date: Mon, 22 Nov 2021 02:55:39 +0100 Subject: [PATCH 4/5] wip --- cl_dll/hud_nametags.cpp | 161 ++++++++++++++++++++++++++++++++------- cl_dll/hud_nametags.h | 4 + cl_dll/hud_spectator.cpp | 3 +- 3 files changed, 141 insertions(+), 27 deletions(-) diff --git a/cl_dll/hud_nametags.cpp b/cl_dll/hud_nametags.cpp index 924b4cd3..eff11626 100644 --- a/cl_dll/hud_nametags.cpp +++ b/cl_dll/hud_nametags.cpp @@ -26,6 +26,9 @@ #include "vgui_helpers.h" #include "vgui_loadtga.h" + +#include // TOOD: REMOVE ME + #ifdef _MSC_VER #pragma warning(disable: 4244) #endif @@ -50,6 +53,7 @@ int CHudNameTags::Init() m_hud_nametags_type = gEngfuncs.pfnRegisterVariable("hud_nametags_type", "1", FCVAR_ARCHIVE); m_hud_nametags_team_max_distance = gEngfuncs.pfnRegisterVariable("hud_nametags_team_max_distance", "1", FCVAR_ARCHIVE); + //struct model_s *hSpriteModel; return 1; } @@ -60,6 +64,8 @@ int CHudNameTags::VidInit() { //m_iFlags &= ~HUD_ACTIVE; //m_hsprPlayer = SPR_Load("sprites/ascii_table_test.spr"); + m_VoiceHeadModel = SPR_Load("sprites/alphabet_single.spr"); //gEngfuncs.pfnSPR_Load("sprites/alphabet_test.spr"); //SPR_Load + //m_VoiceHeadModel = SPR_Load("sprites/320hud1.spr"); //gEngfuncs.pfnSPR_Load("sprites/alphabet_test.spr"); //SPR_Load return 1; } @@ -135,7 +141,7 @@ int CHudNameTags::Draw(float flTime) continue; // Don't show a nametag for dead or spectating players (ie: invisible entities). - if(ent->curstate.effects & EF_NODRAW) + if (ent->curstate.effects & EF_NODRAW) continue; VectorCopy(ent->origin, origin_above_target_head); @@ -149,20 +155,18 @@ int CHudNameTags::Draw(float flTime) x = XPROJECT(screen[0]); y = YPROJECT(screen[1]); - color = GetClientColor( i+1 ); // team color + color = GetClientColor(i + 1); // team color // draw the players name and health underneath char colorless_name[256]; color_tags::strip_color_tags(colorless_name, g_PlayerInfoList[i + 1].name, ARRAYSIZE(colorless_name)); - /*if(!strcmp(g_PlayerExtraInfo[localPlayer->index].teamname, g_PlayerExtraInfo[i + 1].teamname) && gHUD.m_Teamplay) - sprintf(string, "%s", colorless_name, health, armor, teammate); - else */ // For playerid msg - sprintf(string, "%s", colorless_name); + sprintf(string, "%s", colorless_name); lx = strlen(string)*4; // 3 is avg. character length :) VectorCopy(ent->origin, vecTargetPlayer); + vec3_t point, up, right; // Since the nametag is above the player's head, let's somewhat try to see if we can see his head if (ent->curstate.usehull == 1) @@ -180,28 +184,111 @@ int CHudNameTags::Draw(float flTime) // Or if the gamemode is Kreedz // Or if the localplayer is spectating // TODO: V_GetInEyePos( g_iUser2, origin, angles ); + float distanceToPlayer = Distance(trace->endpos, localPlayer->origin); - if (Distance(trace->endpos, localPlayer->origin) < m_hud_nametags_team_max_distance->value && IsTeamMate(localPlayer, i) || - gEngfuncs.pDemoAPI->IsPlayingback() || - !strcmp(gamemode, "Kreedz") || - g_iUser1) + if (distanceToPlayer < m_hud_nametags_team_max_distance->value && IsTeamMate(localPlayer, i) || + gEngfuncs.pDemoAPI->IsPlayingback() || !strcmp(gamemode, "Kreedz") || g_iUser1) { - if(m_hud_nametags_type->value == 1) // Looks like chat HUD font - { - gHUD.DrawConsoleStringWithColorTags( - x - lx, - y, - string, - true, - color[0], - color[1], - color[2] - ); - } - else // Looks like HUD font - { - gHUD.DrawHudStringCentered(x, y, string, r, g, b); - } + float screenPoints[3]; + gEngfuncs.pTriAPI->WorldToScreen(origin_above_target_head, screenPoints); + + screenPoints[0] = XPROJECT(screenPoints[0]); + screenPoints[1] = YPROJECT(screenPoints[1]); + screenPoints[2] = 0.0f; + + gEngfuncs.Con_Printf("AHOJ\n"); + // see R_DrawSpriteModel + + // draws players sprite + auto origin = vecTargetPlayer; + + Vector screen_point; + gEngfuncs.pTriAPI->WorldToScreen(origin, screen_point); + + /*const Vector2D half_size(0.01875, 0.03333); + + this->DrawScreenRectangle( + gEngfuncs.pTriAPI, + screen_point.Make2D() - half_size, + screen_point.Make2D() + half_size + );*/ + + //AngleVectors(ent->angles, right, up, NULL ); + + auto hSpriteModel = (struct model_s *)gEngfuncs.GetSpritePointer( m_VoiceHeadModel ); + + gEngfuncs.pTriAPI->SpriteTexture( hSpriteModel, 0 ); + //gEngfuncs.pTriAPI->RenderMode( kRenderTransTexture ); + gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); + gEngfuncs.pTriAPI->CullFace( TRI_NONE ); + //glEnable(GL_TEXTURE_2D); + auto base = 100.0f; + auto scale = base / distanceToPlayer; + auto final_scale = base * scale ; + //VectorScale() +// auto x1 = 32.0f; +// auto x2 = 16.0f * 3.0f; +// auto a1 = (x1 - 1.0f) / (448 - 0); // 448 = width of the image +// auto a2 = (x2 - 1.0f) / (448 - 0); + + gEngfuncs.pTriAPI->Begin ( TRI_QUADS ); + for(int i = 0; i < sizeof(colorless_name) && colorless_name[i] != '\0'; i++) + { + char singleChar = colorless_name[i]; + int letterAlphabetNumber = (int)singleChar - 97; + + if ((int)singleChar < 97 && (int)singleChar > 122) + { + gEngfuncs.Con_Printf("Skipping character %c %i", singleChar, singleChar); + continue; + } + + auto x1 = 16.0f * letterAlphabetNumber; + auto x2 = 16.0f * (letterAlphabetNumber + 1); + auto a1 = (x1 - 0.0f) / (448 - 0); // 448 = width of the image // left corner of rectangle + auto a2 = (x2 - 0.0f) / (448 - 0); // right corner of rectangle + + gEngfuncs.Con_Printf("%f %f | distance = %f | final_scale = %f | a1 = %f | a2 = %f | char = %c | letter = %i | x1 = %f | x2 = %f\n", + screenPoints[0], screenPoints[1], distanceToPlayer, final_scale, a1, a2, singleChar, letterAlphabetNumber, x1, x2); + + gEngfuncs.pTriAPI->TexCoord2f(a2, 0); + gEngfuncs.pTriAPI->Vertex3f(screenPoints[0], screenPoints[1], 0); + gEngfuncs.pTriAPI->TexCoord2f(a1, 0); + gEngfuncs.pTriAPI->Vertex3f(screenPoints[0] + 20, screenPoints[1], 0); + gEngfuncs.pTriAPI->TexCoord2f(a1, 1); + gEngfuncs.pTriAPI->Vertex3f(screenPoints[0] + 20, screenPoints[1] + 32, 0); + gEngfuncs.pTriAPI->TexCoord2f(a2, 1); + gEngfuncs.pTriAPI->Vertex3f(screenPoints[0], screenPoints[1] + 32, 0); + + } + gEngfuncs.pTriAPI->End (); + gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); + /* + * gEngfuncs.Con_Printf("%f %f | distance = %f | final_scale = %f | a1 = %f | a2 = %f\n", + screenPoints[0], screenPoints[1], distanceToPlayer, final_scale, a1, a2); + gEngfuncs.pTriAPI->TexCoord2f(a2, 0); + gEngfuncs.pTriAPI->Vertex3f(screenPoints[0], screenPoints[1], 0); + gEngfuncs.pTriAPI->TexCoord2f(a1, 0); + gEngfuncs.pTriAPI->Vertex3f(screenPoints[0] + 20, screenPoints[1], 0); + gEngfuncs.pTriAPI->TexCoord2f(a1, 1); + gEngfuncs.pTriAPI->Vertex3f(screenPoints[0] + 20, screenPoints[1] + 32, 0); + gEngfuncs.pTriAPI->TexCoord2f(a2, 1); + gEngfuncs.pTriAPI->Vertex3f(screenPoints[0], screenPoints[1] + 32, 0); + * + * / gEngfuncs.pTriAPI->TexCoord2f (1, 0); +// gEngfuncs.pTriAPI->Vertex3f (screenPoints[0]+40, screenPoints[1]+40, 0); +// gEngfuncs.pTriAPI->TexCoord2f (0, 0); +// gEngfuncs.pTriAPI->Vertex3f (screenPoints[0]-40, screenPoints[1]-40, 0); +// gEngfuncs.pTriAPI->TexCoord2f (0, 1); +// gEngfuncs.pTriAPI->Vertex3f (screenPoints[0]-40, screenPoints[1]-40, 0); +// gEngfuncs.pTriAPI->TexCoord2f (1, 1); +// gEngfuncs.pTriAPI->Vertex3f (screenPoints[0]+40, screenPoints[1]+40, 0); + + * + * + * + * */ + } } } @@ -218,6 +305,27 @@ bool CHudNameTags::IsActivePlayer(cl_entity_t * ent) ); } +void CHudNameTags::DrawScreenRectangle(triangleapi_s *pTriAPI, Vector2D corner1, Vector2D corner2) +{ + Vector screen_points[4], world_points[4]; + screen_points[0] = Vector(corner1.x, corner1.y, 0.0f); + screen_points[1] = Vector(corner1.x, corner2.y, 0.0f); + screen_points[2] = Vector(corner2.x, corner2.y, 0.0f); + screen_points[3] = Vector(corner2.x, corner1.y, 0.0f); + + for (int i = 0; i < 4; ++i) + pTriAPI->ScreenToWorld(screen_points[i], world_points[i]); + + pTriAPI->Begin(TRI_QUADS); + + pTriAPI->Vertex3fv(world_points[0]); + pTriAPI->Vertex3fv(world_points[1]); + pTriAPI->Vertex3fv(world_points[2]); + pTriAPI->Vertex3fv(world_points[3]); + + pTriAPI->End(); +} + void CHudNameTags::Reset() { @@ -228,6 +336,7 @@ void CHudNameTags::InitHUDData() Reset(); } +// dont use rn int CHudNameTags::MsgFunc_PlayerId(const char* name, int size, void* buf) { BEGIN_READ(buf, size); diff --git a/cl_dll/hud_nametags.h b/cl_dll/hud_nametags.h index 1c46d2d5..77ce5260 100644 --- a/cl_dll/hud_nametags.h +++ b/cl_dll/hud_nametags.h @@ -51,7 +51,11 @@ class CHudNameTags : public CHudBase private: vec3_t m_vPlayerPos[MAX_PLAYERS]; + HSPRITE m_VoiceHeadModel; + bool IsTeamMate(cl_entity_t *localPlayer, int playerId); + + void DrawScreenRectangle(triangleapi_s *pTriAPI, Vector2D corner1, Vector2D corner2); }; #endif // SPECTATOR_H diff --git a/cl_dll/hud_spectator.cpp b/cl_dll/hud_spectator.cpp index 9477946e..6437ac5b 100644 --- a/cl_dll/hud_spectator.cpp +++ b/cl_dll/hud_spectator.cpp @@ -590,7 +590,8 @@ bool CHudSpectator::GetDirectorCamera(vec3_t &position, vec3_t &angle) //----------------------------------------------------------------------------- int CHudSpectator::VidInit() { - m_hsprPlayer = SPR_Load("sprites/iplayer.spr"); + //m_hsprPlayer = SPR_Load("sprites/iplayer.spr"); + m_hsprPlayer = SPR_Load("sprites/alphabet_single.spr"); // TODO: SOUP m_hsprPlayerBlue = SPR_Load("sprites/iplayerblue.spr"); m_hsprPlayerRed = SPR_Load("sprites/iplayerred.spr"); m_hsprPlayerDead = SPR_Load("sprites/iplayerdead.spr"); From ad8442e0711413cc82b7a01d10b94b4231f0f1ce Mon Sep 17 00:00:00 2001 From: Jakub Mach Date: Wed, 24 Nov 2021 19:20:50 +0100 Subject: [PATCH 5/5] wip --- cl_dll/hud_nametags.cpp | 191 +++++++++++++--------------------------- cl_dll/hud_nametags.h | 15 +--- 2 files changed, 65 insertions(+), 141 deletions(-) diff --git a/cl_dll/hud_nametags.cpp b/cl_dll/hud_nametags.cpp index eff11626..4b13afd0 100644 --- a/cl_dll/hud_nametags.cpp +++ b/cl_dll/hud_nametags.cpp @@ -1,10 +1,3 @@ -//========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - #include "hud.h" #include "cl_util.h" #include "cl_entity.h" @@ -26,9 +19,6 @@ #include "vgui_helpers.h" #include "vgui_loadtga.h" - -#include // TOOD: REMOVE ME - #ifdef _MSC_VER #pragma warning(disable: 4244) #endif @@ -50,22 +40,18 @@ int CHudNameTags::Init() m_iFlags |= HUD_ACTIVE; m_hud_nametags = gEngfuncs.pfnRegisterVariable("hud_nametags", "1", FCVAR_ARCHIVE); - m_hud_nametags_type = gEngfuncs.pfnRegisterVariable("hud_nametags_type", "1", FCVAR_ARCHIVE); m_hud_nametags_team_max_distance = gEngfuncs.pfnRegisterVariable("hud_nametags_team_max_distance", "1", FCVAR_ARCHIVE); - //struct model_s *hSpriteModel; return 1; } //----------------------------------------------------------------------------- -// Purpose: Loads new icons +// Purpose: Loads the ASCII table sprite //----------------------------------------------------------------------------- int CHudNameTags::VidInit() { //m_iFlags &= ~HUD_ACTIVE; - //m_hsprPlayer = SPR_Load("sprites/ascii_table_test.spr"); - m_VoiceHeadModel = SPR_Load("sprites/alphabet_single.spr"); //gEngfuncs.pfnSPR_Load("sprites/alphabet_test.spr"); //SPR_Load - //m_VoiceHeadModel = SPR_Load("sprites/320hud1.spr"); //gEngfuncs.pfnSPR_Load("sprites/alphabet_test.spr"); //SPR_Load + m_nameTagSprite = SPR_Load("sprites/ascii_table.spr"); //gEngfuncs.pfnSPR_Load("sprites/alphabet_test.spr"); //SPR_Load return 1; } @@ -86,10 +72,9 @@ int CHudNameTags::Draw(float flTime) // Only draw if client wants us to if(m_hud_nametags->value != 1) return 1; - - int lx; + char string[512]; - float * color; + float *color; vec3_t origin_above_target_head, world, screen; vec3_t origin_pl; @@ -99,10 +84,12 @@ int CHudNameTags::Draw(float flTime) float x,y,z; int r,g,b; + // Get the sprite pointer + auto hSpriteModel = (struct model_s *)gEngfuncs.GetSpritePointer(m_nameTagSprite); + // make sure we have player info gViewPort->GetAllPlayersInfo(); - // get server's gamemode - auto gamemode = gHUD.m_Settings.GetGamemode(); + // get yellow/brown HUD color UnpackRGB(r, g, b, gHUD.m_iDefaultHUDColor); @@ -120,15 +107,16 @@ int CHudNameTags::Draw(float flTime) VectorAdd( origin_pl, view_ofs, vecSrc ); //AngleVectors( angles_pl, forward, NULL, NULL ); // For get user aim - + for (int i = 0; i < MAX_PLAYERS; i++) { cl_entity_s *ent = gEngfuncs.GetEntityByIndex(i+1); - // Target player not here, or not in our PVS + // Target player not present on the server, or not in our PVS if(!ent || ent->curstate.messagenum < localPlayer->curstate.messagenum) continue; + // Target entity isn't a player entity if (!ent->player) continue; @@ -140,45 +128,42 @@ int CHudNameTags::Draw(float flTime) if (g_PlayerInfoList[i + 1].name == nullptr) continue; - // Don't show a nametag for dead or spectating players (ie: invisible entities). + // Don't show a nametag for dead or players that are only spectating (ie: invisible entities). if (ent->curstate.effects & EF_NODRAW) continue; + // Don't draw a nametag for player we are spectating in first person (incl. in PoV demos) + if (g_iUser1 && ent->index == g_iUser2) + continue; + VectorCopy(ent->origin, origin_above_target_head); origin_above_target_head[2] += 45.0f; // Kinda above the head // ^ TODO: change based on distance? - // calculate screen position for name and infromation in hud::draw() + // Calculate screen position for name and infromation in hud::draw() if ( gEngfuncs.pTriAPI->WorldToScreen(origin_above_target_head, screen) ) continue; // object is behind viewer - x = XPROJECT(screen[0]); - y = YPROJECT(screen[1]); - color = GetClientColor(i + 1); // team color // draw the players name and health underneath char colorless_name[256]; color_tags::strip_color_tags(colorless_name, g_PlayerInfoList[i + 1].name, ARRAYSIZE(colorless_name)); - sprintf(string, "%s", colorless_name); - lx = strlen(string)*4; // 3 is avg. character length :) - VectorCopy(ent->origin, vecTargetPlayer); - vec3_t point, up, right; + vec3_t point, up, right; // Since the nametag is above the player's head, let's somewhat try to see if we can see his head if (ent->curstate.usehull == 1) - vecTargetPlayer[2] += VEC_DUCK_VIEW; + vecTargetPlayer[2] += VEC_DUCK_VIEW; // he's crouched, draw it lower else - vecTargetPlayer[2] += DEFAULT_VIEWHEIGHT; + vecTargetPlayer[2] += DEFAULT_VIEWHEIGHT; // he's standing up (or dead, well, can't tell) pmtrace_t * trace = gEngfuncs.PM_TraceLine( vecSrc, vecTargetPlayer, PM_TRACELINE_PHYSENTSONLY, 2, -1 ); if ( trace->fraction == 1.0 ) { - // If the player is 600 units(?) away from the local player, show the nametag // Or if we are playing a demo, show the nametag however far away he is // Or if client wants teammates to always appear, regardless of their distance (obv only when in our PVS and traceable) // Or if the gamemode is Kreedz @@ -186,8 +171,8 @@ int CHudNameTags::Draw(float flTime) // TODO: V_GetInEyePos( g_iUser2, origin, angles ); float distanceToPlayer = Distance(trace->endpos, localPlayer->origin); - if (distanceToPlayer < m_hud_nametags_team_max_distance->value && IsTeamMate(localPlayer, i) || - gEngfuncs.pDemoAPI->IsPlayingback() || !strcmp(gamemode, "Kreedz") || g_iUser1) + //if (ShouldDrawEvenIfPlayerIsNotTeamMate() || (distanceToPlayer < m_hud_nametags_team_max_distance->value && IsTeamMate(localPlayer, i))) + if (true) { float screenPoints[3]; gEngfuncs.pTriAPI->WorldToScreen(origin_above_target_head, screenPoints); @@ -196,99 +181,60 @@ int CHudNameTags::Draw(float flTime) screenPoints[1] = YPROJECT(screenPoints[1]); screenPoints[2] = 0.0f; - gEngfuncs.Con_Printf("AHOJ\n"); // see R_DrawSpriteModel - // draws players sprite - auto origin = vecTargetPlayer; - - Vector screen_point; - gEngfuncs.pTriAPI->WorldToScreen(origin, screen_point); - - /*const Vector2D half_size(0.01875, 0.03333); - - this->DrawScreenRectangle( - gEngfuncs.pTriAPI, - screen_point.Make2D() - half_size, - screen_point.Make2D() + half_size - );*/ - - //AngleVectors(ent->angles, right, up, NULL ); - - auto hSpriteModel = (struct model_s *)gEngfuncs.GetSpritePointer( m_VoiceHeadModel ); - gEngfuncs.pTriAPI->SpriteTexture( hSpriteModel, 0 ); //gEngfuncs.pTriAPI->RenderMode( kRenderTransTexture ); gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); gEngfuncs.pTriAPI->CullFace( TRI_NONE ); //glEnable(GL_TEXTURE_2D); - auto base = 100.0f; - auto scale = base / distanceToPlayer; - auto final_scale = base * scale ; - //VectorScale() -// auto x1 = 32.0f; -// auto x2 = 16.0f * 3.0f; -// auto a1 = (x1 - 1.0f) / (448 - 0); // 448 = width of the image -// auto a2 = (x2 - 1.0f) / (448 - 0); + auto scale = (800 - 8) / (distanceToPlayer - 8); // TODO: + scale = std::fmin(scale, 1.25f); // TODO: + auto length = strlen(colorless_name); gEngfuncs.pTriAPI->Begin ( TRI_QUADS ); - for(int i = 0; i < sizeof(colorless_name) && colorless_name[i] != '\0'; i++) + for (int i = 0; i < sizeof(colorless_name) && colorless_name[i] != '\0'; i++) { char singleChar = colorless_name[i]; - int letterAlphabetNumber = (int)singleChar - 97; + int singleCharInt = (int)singleChar; + + int singleCharIntInSpriteTable = singleCharInt - ' '; - if ((int)singleChar < 97 && (int)singleChar > 122) + int letterAlphabetNumber = singleCharIntInSpriteTable % 19; + int line = singleCharIntInSpriteTable / 19; + + if (singleCharInt < 32 || singleCharInt > 126) { - gEngfuncs.Con_Printf("Skipping character %c %i", singleChar, singleChar); + gEngfuncs.Con_Printf("Skipping character %c %i\n", singleChar, singleChar); continue; } - - auto x1 = 16.0f * letterAlphabetNumber; - auto x2 = 16.0f * (letterAlphabetNumber + 1); - auto a1 = (x1 - 0.0f) / (448 - 0); // 448 = width of the image // left corner of rectangle - auto a2 = (x2 - 0.0f) / (448 - 0); // right corner of rectangle - - gEngfuncs.Con_Printf("%f %f | distance = %f | final_scale = %f | a1 = %f | a2 = %f | char = %c | letter = %i | x1 = %f | x2 = %f\n", - screenPoints[0], screenPoints[1], distanceToPlayer, final_scale, a1, a2, singleChar, letterAlphabetNumber, x1, x2); - - gEngfuncs.pTriAPI->TexCoord2f(a2, 0); - gEngfuncs.pTriAPI->Vertex3f(screenPoints[0], screenPoints[1], 0); - gEngfuncs.pTriAPI->TexCoord2f(a1, 0); - gEngfuncs.pTriAPI->Vertex3f(screenPoints[0] + 20, screenPoints[1], 0); - gEngfuncs.pTriAPI->TexCoord2f(a1, 1); - gEngfuncs.pTriAPI->Vertex3f(screenPoints[0] + 20, screenPoints[1] + 32, 0); - gEngfuncs.pTriAPI->TexCoord2f(a2, 1); - gEngfuncs.pTriAPI->Vertex3f(screenPoints[0], screenPoints[1] + 32, 0); + auto x1 = 16.0f * letterAlphabetNumber; // for the left corner of the rectangle + auto x2 = 16.0f * (letterAlphabetNumber + 1); // for the right corner of the rectangle + auto a1 = (x1 - 0.0f) / (384 - 0); // 448 = width of the image // left corner of the texture selection rectangle + auto a2 = (x2 - 0.0f) / (384 - 0); // right corner of the texture selection rectangle + + auto y1 = 32.0f * line; // for the top corner of the rectangle + auto y2 = 32.0f * (line + 1); // for the bottom corner of the rectangle + auto b1 = (y1 - 0.0f) / (160 - 0); // 160 = height of the sprite image + auto b2 = (y2 - 0.0f) / (160 - 0); + + auto xpos = screenPoints[0] - (8 * scale * length / 2) + (i * 8 * scale); + auto ypos = screenPoints[1]; // + scale; + gEngfuncs.Con_Printf("%f %f | distance = %f | scale = %f | a1 = %f | a2 = %f | char = %c | letter = %i | x1 = %f | x2 = %f | xpos = %f | i = %d\n", + screenPoints[0], screenPoints[1], distanceToPlayer, scale, a1, a2, singleChar, letterAlphabetNumber, x1, x2, xpos, i); + gEngfuncs.Con_Printf("y1 = %f | y2 = %f | b1 = %f | b2 = %f", y1, y2, b1, b2); + gEngfuncs.pTriAPI->TexCoord2f(a1, b1); + gEngfuncs.pTriAPI->Vertex3f(xpos, ypos, 0); + gEngfuncs.pTriAPI->TexCoord2f(a2, b1); + gEngfuncs.pTriAPI->Vertex3f(xpos + 8*scale, ypos, 0); + gEngfuncs.pTriAPI->TexCoord2f(a2, b2); + gEngfuncs.pTriAPI->Vertex3f(xpos + 8*scale, ypos + 16*scale, 0); + gEngfuncs.pTriAPI->TexCoord2f(a1, b2); + gEngfuncs.pTriAPI->Vertex3f(xpos, ypos + 16*scale, 0); } gEngfuncs.pTriAPI->End (); gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); - /* - * gEngfuncs.Con_Printf("%f %f | distance = %f | final_scale = %f | a1 = %f | a2 = %f\n", - screenPoints[0], screenPoints[1], distanceToPlayer, final_scale, a1, a2); - gEngfuncs.pTriAPI->TexCoord2f(a2, 0); - gEngfuncs.pTriAPI->Vertex3f(screenPoints[0], screenPoints[1], 0); - gEngfuncs.pTriAPI->TexCoord2f(a1, 0); - gEngfuncs.pTriAPI->Vertex3f(screenPoints[0] + 20, screenPoints[1], 0); - gEngfuncs.pTriAPI->TexCoord2f(a1, 1); - gEngfuncs.pTriAPI->Vertex3f(screenPoints[0] + 20, screenPoints[1] + 32, 0); - gEngfuncs.pTriAPI->TexCoord2f(a2, 1); - gEngfuncs.pTriAPI->Vertex3f(screenPoints[0], screenPoints[1] + 32, 0); - * - * / gEngfuncs.pTriAPI->TexCoord2f (1, 0); -// gEngfuncs.pTriAPI->Vertex3f (screenPoints[0]+40, screenPoints[1]+40, 0); -// gEngfuncs.pTriAPI->TexCoord2f (0, 0); -// gEngfuncs.pTriAPI->Vertex3f (screenPoints[0]-40, screenPoints[1]-40, 0); -// gEngfuncs.pTriAPI->TexCoord2f (0, 1); -// gEngfuncs.pTriAPI->Vertex3f (screenPoints[0]-40, screenPoints[1]-40, 0); -// gEngfuncs.pTriAPI->TexCoord2f (1, 1); -// gEngfuncs.pTriAPI->Vertex3f (screenPoints[0]+40, screenPoints[1]+40, 0); - - * - * - * - * */ - } } } @@ -305,25 +251,12 @@ bool CHudNameTags::IsActivePlayer(cl_entity_t * ent) ); } -void CHudNameTags::DrawScreenRectangle(triangleapi_s *pTriAPI, Vector2D corner1, Vector2D corner2) +bool CHudNameTags::ShouldDrawEvenIfPlayerIsNotTeamMate() { - Vector screen_points[4], world_points[4]; - screen_points[0] = Vector(corner1.x, corner1.y, 0.0f); - screen_points[1] = Vector(corner1.x, corner2.y, 0.0f); - screen_points[2] = Vector(corner2.x, corner2.y, 0.0f); - screen_points[3] = Vector(corner2.x, corner1.y, 0.0f); - - for (int i = 0; i < 4; ++i) - pTriAPI->ScreenToWorld(screen_points[i], world_points[i]); - - pTriAPI->Begin(TRI_QUADS); - - pTriAPI->Vertex3fv(world_points[0]); - pTriAPI->Vertex3fv(world_points[1]); - pTriAPI->Vertex3fv(world_points[2]); - pTriAPI->Vertex3fv(world_points[3]); - - pTriAPI->End(); + // get server's gamemode + auto gamemode = gHUD.m_Settings.GetGamemode(); + gEngfuncs.Con_Printf("RETURNING %i\n", (gEngfuncs.pDemoAPI->IsPlayingback() || !strcmp(gamemode, "Kreedz") || g_iUser1 || gEngfuncs.IsSpectateOnly())); + return (gEngfuncs.pDemoAPI->IsPlayingback() || !strcmp(gamemode, "Kreedz") || g_iUser1 || gEngfuncs.IsSpectateOnly()); } void CHudNameTags::Reset() diff --git a/cl_dll/hud_nametags.h b/cl_dll/hud_nametags.h index 77ce5260..c0fa1b03 100644 --- a/cl_dll/hud_nametags.h +++ b/cl_dll/hud_nametags.h @@ -1,10 +1,3 @@ -//========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - #ifndef NAMETAGS_H #define NAMETAGS_H #pragma once @@ -45,17 +38,15 @@ class CHudNameTags : public CHudBase int armor; cvar_t * m_hud_nametags; - cvar_t * m_hud_nametags_type; cvar_t * m_hud_nametags_team_max_distance; private: vec3_t m_vPlayerPos[MAX_PLAYERS]; - HSPRITE m_VoiceHeadModel; - - bool IsTeamMate(cl_entity_t *localPlayer, int playerId); + HSPRITE m_nameTagSprite; - void DrawScreenRectangle(triangleapi_s *pTriAPI, Vector2D corner1, Vector2D corner2); + bool IsTeamMate(cl_entity_t *localPlayer, int playerId); + bool ShouldDrawEvenIfPlayerIsNotTeamMate(); }; #endif // SPECTATOR_H