Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions game/neo/scripts/HudLayout.res
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,10 @@
"ypos" "0"
"wide" "640"
"tall" "480"

"color" "255 20 20 150"
"font" "NHudOCRSmall"
"texture" "vgui/hud/ctg/g_beacon_enemy"
}

CNEOHud_GameEvent
Expand Down
1 change: 1 addition & 0 deletions src/game/client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,7 @@ target_sources_grouped(
TARGET client
NAME "Source Files\\NEO\\Material Proxies"
FILES
neo/material_proxies/neo_matproxy_ghost_beacon_rotation.cpp
neo/material_proxies/neo_matproxy_thermoptic.cpp
neo/material_proxies/neo_matproxy_thermoptic.h
neo/material_proxies/neo_matproxy_teamnum.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "materialsystem/imaterialproxy.h"
#include "materialsystem/imaterial.h"
#include "materialsystem/imaterialvar.h"
#include <KeyValues.h>
#include "neo/ui/neo_hud_ghost_beacons.h"
#include "toolframework_client.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

// forward declarations
void ToolFramework_RecordMaterialParams( IMaterial *pMaterial );

class CGhostBeaconRotationMaterialProxy : public IMaterialProxy
{
public:
CGhostBeaconRotationMaterialProxy();
virtual ~CGhostBeaconRotationMaterialProxy();
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
virtual void OnBind( void *pC_BaseEntity );
virtual void Release( void ) { delete this; }
virtual IMaterial *GetMaterial();

private:
IMaterialVar *m_pGhostBeaconRotationVar;
};

CGhostBeaconRotationMaterialProxy::CGhostBeaconRotationMaterialProxy()
{
m_pGhostBeaconRotationVar = NULL;
}

CGhostBeaconRotationMaterialProxy::~CGhostBeaconRotationMaterialProxy()
{
}

bool CGhostBeaconRotationMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
char const* pScrollVarName = pKeyValues->GetString( "ghostBeaconRotationVar" );
if( !pScrollVarName )
return false;

bool foundVar;
m_pGhostBeaconRotationVar = pMaterial->FindVar( pScrollVarName, &foundVar, false );
if( !foundVar )
return false;

return true;
}

extern CNEOHud_GhostBeacons* gHudGhostBeacons;
void CGhostBeaconRotationMaterialProxy::OnBind( void *pC_BaseEntity )
{
if( !m_pGhostBeaconRotationVar || !gHudGhostBeacons )
{
return;
}

m_pGhostBeaconRotationVar->SetFloatValue( gHudGhostBeacons->GetRotation() );

if ( ToolsEnabled() )
{
ToolFramework_RecordMaterialParams( GetMaterial() );
}
}

IMaterial *CGhostBeaconRotationMaterialProxy::GetMaterial()
{
return m_pGhostBeaconRotationVar->GetOwningMaterial();
}

EXPOSE_INTERFACE( CGhostBeaconRotationMaterialProxy, IMaterialProxy, "GhostBeaconRotation" IMATERIAL_PROXY_INTERFACE_VERSION );
140 changes: 85 additions & 55 deletions src/game/client/neo/ui/neo_hud_ghost_beacons.cpp
Original file line number Diff line number Diff line change
@@ -1,36 +1,30 @@
#include "neo_hud_ghost_beacons.h"

#include "cbase.h"

#include "iclientmode.h"
#include "ienginevgui.h"
#include <vgui/ILocalize.h>
#include <vgui/ISurface.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/ImagePanel.h>

#include "c_neo_npc_dummy.h"
#include "c_neo_player.h"
#include "neo_player_shared.h"
#include "c_team.h"
#include "neo_gamerules.h"
#include "weapon_ghost.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

using vgui::surface;

ConVar cl_neo_ghost_beacon_scale("cl_neo_ghost_beacon_scale", "1", FCVAR_ARCHIVE,
ConVar cl_neo_hud_ghost_beacon_scale("cl_neo_hud_ghost_beacon_scale", "1", FCVAR_ARCHIVE,
"Ghost beacons scale.", true, 0.01, false, 0);

ConVar cl_neo_ghost_beacon_scale_with_distance("cl_neo_ghost_beacon_scale_with_distance", "0", FCVAR_ARCHIVE,
"Toggles the scaling of ghost beacons with distance.", true, 0, true, 1);

ConVar cl_neo_ghost_beacon_alpha("cl_neo_ghost_beacon_alpha", "150", FCVAR_ARCHIVE,
"Alpha channel transparency of HUD ghost beacons.", true, 0, true, 255);
static float ghostBeaconRotation = 0.f;
ConVar cl_neo_hud_ghost_beacon_scale_with_distance("cl_neo_hud_ghost_beacon_scale_with_distance", "0", FCVAR_ARCHIVE,
"Toggles the scaling of ghost beacons with distance.", true, 0, true, 1, [](IConVar* var, const char* pOldValue, float flOldValue)->void{
if (!cl_neo_hud_ghost_beacon_scale_with_distance.GetBool())
ghostBeaconRotation = 0.f;
});

ConVar cl_neo_hud_ghost_beacon_draw_distance("cl_neo_hud_ghost_beacon_draw_distance", "1", FCVAR_ARCHIVE,
"Draw the distance to the ghost beacons.", true, 0, true, 1);

CNEOHud_GhostBeacons* gHudGhostBeacons;

DECLARE_NAMED_HUDELEMENT(CNEOHud_GhostBeacons, neo_ghost_beacons);

Expand All @@ -39,6 +33,8 @@ NEO_HUD_ELEMENT_DECLARE_FREQ_CVAR(GhostBeacons, 0.01)
CNEOHud_GhostBeacons::CNEOHud_GhostBeacons(const char *pElementName, vgui::Panel *parent)
: CHudElement(pElementName), EditablePanel(parent, pElementName)
{
gHudGhostBeacons = this;

SetAutoDelete(true);
m_iHideHudElementNumber = NEO_HUD_ELEMENT_GHOST_BEACONS;

Expand All @@ -51,17 +47,14 @@ CNEOHud_GhostBeacons::CNEOHud_GhostBeacons(const char *pElementName, vgui::Panel
SetParent(g_pClientMode->GetViewport());
}

int screenWidth, screenHeight;
surface()->GetScreenSize(screenWidth, screenHeight);
SetBounds(0, 0, screenWidth, screenHeight);

m_hTex = surface()->CreateNewTextureID();
Assert(m_hTex > 0);
surface()->DrawSetTextureFile(m_hTex, "vgui/hud/ctg/g_beacon_enemy", 1, false);

SetVisible(true);
}

CNEOHud_GhostBeacons::~CNEOHud_GhostBeacons()
{
gHudGhostBeacons = nullptr;
}

void CNEOHud_GhostBeacons::UpdateStateForNeoHudElementDraw()
{
}
Expand All @@ -70,11 +63,11 @@ void CNEOHud_GhostBeacons::ApplySchemeSettings(vgui::IScheme* pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);

m_hFont = pScheme->GetFont("NHudOCRSmall", true);

int screenWidth, screenHeight;
surface()->GetScreenSize(screenWidth, screenHeight);
vgui::surface()->GetScreenSize(screenWidth, screenHeight);
SetBounds(0, 0, screenWidth, screenHeight);
doubleScreenWidth = 2 * screenWidth;
doubleScreenHeight = 2 * screenHeight;

SetFgColor(COLOR_TRANSPARENT);
SetBgColor(COLOR_TRANSPARENT);
}
Expand Down Expand Up @@ -160,42 +153,79 @@ void CNEOHud_GhostBeacons::Paint()

void CNEOHud_GhostBeacons::DrawPlayer(float distance, const Vector& playerPos) const
{
const auto distInMeters = distance * METERS_PER_INCH;
const float scale = cl_neo_ghost_beacon_scale.GetFloat();
constexpr float HALF_BASE_TEX_LENGTH = 32;
const float distInMeters = distance * METERS_PER_INCH;
constexpr float BASE_TEX_LENGTH = 64;
float halfBeaconLength = BASE_TEX_LENGTH * 0.5f * cl_neo_hud_ghost_beacon_scale.GetFloat();

float halfBeaconLength = HALF_BASE_TEX_LENGTH * scale;
int posX, posY;
Vector ghostBeaconOffset = Vector(0, 0, cl_neo_ghost_beacon_scale_with_distance.GetBool() ? 32 : 48); // The center of the player, or raise slightly if not scaling
GetVectorInScreenSpace(playerPos, posX, posY, &ghostBeaconOffset);
if (cl_neo_ghost_beacon_scale_with_distance.GetBool())
Vector ghostBeaconOffset = Vector(0, 0, cl_neo_hud_ghost_beacon_scale_with_distance.GetBool() ? 0 : 48);
if (!GetVectorInScreenSpace(playerPos, posX, posY, &ghostBeaconOffset))
{
return;
}
bool centerXClamped = clamp(&posX, -screenWidth, doubleScreenWidth);
bool centerYClamped = clamp(&posY, -screenHeight, doubleScreenHeight);

if (cl_neo_hud_ghost_beacon_scale_with_distance.GetBool())
{
if (centerXClamped && centerYClamped)
{
return;
}

int pos2X, pos2Y;
Vector ghostBeaconOffset2 = Vector(0, 0, 64); // The top of the player
GetVectorInScreenSpace(playerPos, pos2X, pos2Y, &ghostBeaconOffset2);
halfBeaconLength = (posY - pos2Y) * 0.5 * scale;
Vector ghostBeaconEyeOffset = Vector(0, 0, 64);
if (!GetVectorInScreenSpace(playerPos, pos2X, pos2Y, &ghostBeaconEyeOffset))
{
return;
}

if (clamp(&pos2X, -screenWidth, doubleScreenWidth) && clamp(&pos2Y, -screenHeight, doubleScreenHeight))
{
return;
}

Vector2D playerUpDirectionOnScreen = Vector2D(pos2X - posX, pos2Y - posY);
const Vector2D screenUpDirection = Vector2D(0, 1);
float rotation = acos((playerUpDirectionOnScreen.Dot(screenUpDirection)) / playerUpDirectionOnScreen.Length()) + M_PI;
if (pos2X < posX)
{
rotation *= -1;
}
ghostBeaconRotation = RAD2DEG(rotation);

halfBeaconLength = (posY - pos2Y) * 0.5f * cl_neo_hud_ghost_beacon_scale.GetFloat();
posX = (posX + pos2X) / 2;
posY = (posY + pos2Y) / 2;
}

wchar_t m_wszBeaconTextUnicode[4 + 1];
V_snwprintf(m_wszBeaconTextUnicode, ARRAYSIZE(m_wszBeaconTextUnicode), L"%02d m", FastFloatToSmallInt(distInMeters));

const auto ghostViewDist = sv_neo_ghost_view_distance.GetFloat();
const float alphaMultiplier = (distInMeters < ghostViewDist * 35.f / 45) ? 1.0 : ((ghostViewDist - distInMeters) / 10);
const int alpha = cl_neo_ghost_beacon_alpha.GetInt() * alphaMultiplier;
surface()->DrawSetTextColor(255, 255, 255, alpha);
surface()->DrawSetTextFont(m_hFont);
int textWidth, textHeight;
surface()->GetTextSize(m_hFont, m_wszBeaconTextUnicode, textWidth, textHeight);
surface()->DrawSetTextPos(posX - (textWidth / 2), posY + halfBeaconLength);
surface()->DrawPrintText(m_wszBeaconTextUnicode, V_wcslen(m_wszBeaconTextUnicode));

surface()->DrawSetColor(255, 20, 20, alpha);
surface()->DrawSetTexture(m_hTex);

// End coordinates according to art size (and our distance scaling)
surface()->DrawTexturedRect(
const float alphaMultiplier = distInMeters < (ghostViewDist * 35.f / 45) ? 1.0f : (ghostViewDist - distInMeters) / 10;
const int alpha = beaconColor.a() * alphaMultiplier;

if (cl_neo_hud_ghost_beacon_draw_distance.GetBool())
{
wchar_t m_wszBeaconTextUnicode[4 + 1];
V_snwprintf(m_wszBeaconTextUnicode, ARRAYSIZE(m_wszBeaconTextUnicode), L"%02d m", FastFloatToSmallInt(distInMeters));

vgui::surface()->DrawSetTextColor(255, 255, 255, alpha);
vgui::surface()->DrawSetTextFont(m_hFont);
int textWidth, textHeight;
vgui::surface()->GetTextSize(m_hFont, m_wszBeaconTextUnicode, textWidth, textHeight);
vgui::surface()->DrawSetTextPos(posX - (textWidth / 2), posY + halfBeaconLength);
vgui::surface()->DrawPrintText(m_wszBeaconTextUnicode, V_wcslen(m_wszBeaconTextUnicode));
}

vgui::surface()->DrawSetColor(beaconColor.r(), beaconColor.g(), beaconColor.b(), alpha);
vgui::surface()->DrawSetTexture(m_hTex);
vgui::surface()->DrawTexturedRect(
posX - halfBeaconLength,
posY - halfBeaconLength,
posX + halfBeaconLength,
posY + halfBeaconLength);
}

float CNEOHud_GhostBeacons::GetRotation()
{
return ghostBeaconRotation;
}
11 changes: 7 additions & 4 deletions src/game/client/neo/ui/neo_hud_ghost_beacons.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
#include "hudelement.h"
#include <vgui_controls/EditablePanel.h>

#include "weapon_ghost.h"

class CNEOHud_GhostBeacons : public CNEOHud_ChildElement, public CHudElement, public vgui::EditablePanel
{
DECLARE_CLASS_SIMPLE(CNEOHud_GhostBeacons, EditablePanel);

public:
CNEOHud_GhostBeacons(const char *pElementName, vgui::Panel *parent = NULL);
~CNEOHud_GhostBeacons();
virtual void ApplySchemeSettings(vgui::IScheme* pScheme) override;
virtual void Paint() override;
float GetRotation();

private:
void DrawPlayer(float distance, const Vector& playerPos) const;
Expand All @@ -28,8 +28,11 @@ class CNEOHud_GhostBeacons : public CNEOHud_ChildElement, public CHudElement, pu
virtual ConVar* GetUpdateFrequencyConVar() const override;

private:
vgui::HFont m_hFont;
vgui::HTexture m_hTex;
int screenWidth = 0, screenHeight = 0, doubleScreenWidth = 0, doubleScreenHeight = 0;

CPanelAnimationVar(Color, beaconColor, "color", "255, 20, 20, 150");
CPanelAnimationVar(vgui::HFont, m_hFont, "font", "NHudOCRSmall");
CPanelAnimationVarAliasType(int, m_hTex, "texture", "vgui/hud/ctg/g_beacon_enemy", "textureid");

private:
CNEOHud_GhostBeacons(const CNEOHud_GhostBeacons &other);
Expand Down
29 changes: 29 additions & 0 deletions src/public/mathlib/mathlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,35 @@ inline T clamp( T const &val, T const &minVal, T const &maxVal )
return val;
}

#ifdef NEO
//
// Clamps a value in the range [min, max]. Returns true if the value was clamped
//
template< class T >
inline bool clamp( T *val, T const &minVal, T const &maxVal )
{
if (maxVal < minVal)
{
*val = maxVal;
return true;
}
else if (*val < minVal)
{
*val = minVal;
return true;
}
else if (*val > maxVal)
{
*val = maxVal;
return true;
}
else
{
return false;
}
}
#endif // NEO


// plane_t structure
// !!! if this is changed, it must be changed in asm code too !!!
Expand Down