Skip to content

Commit

Permalink
Ghost - Refactor away from player to HUD/Gamerule
Browse files Browse the repository at this point in the history
* No longer handles states from player to HUD
* HUD handles some states itself, some given to gamerules to handle it
  instead especially for networked
* PVS over networked for smoother ghost visuals
* fixes #475
  • Loading branch information
nullsystem committed Jul 4, 2024
1 parent fb71036 commit 0bc917a
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 201 deletions.
39 changes: 0 additions & 39 deletions mp/src/game/client/neo/c_neo_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ IMPLEMENT_CLIENTCLASS_DT(C_NEO_Player, DT_NEO_Player, CNEO_Player)
RecvPropInt(RECVINFO(m_iNextSpawnClassChoice)),
RecvPropInt(RECVINFO(m_bInLean)),

RecvPropVector(RECVINFO(m_vecGhostMarkerPos)),
RecvPropBool(RECVINFO(m_bGhostExists)),
RecvPropBool(RECVINFO(m_bInThermOpticCamo)),
RecvPropBool(RECVINFO(m_bLastTickInThermOpticCamo)),
RecvPropBool(RECVINFO(m_bInVision)),
Expand All @@ -99,7 +97,6 @@ BEGIN_PREDICTION_DATA(C_NEO_Player)
DEFINE_PRED_FIELD(m_rvFriendlyPlayerPositions, FIELD_VECTOR, FTYPEDESC_INSENDTABLE),
DEFINE_PRED_ARRAY(m_rfAttackersScores, FIELD_FLOAT, MAX_PLAYERS + 1, FTYPEDESC_INSENDTABLE),
DEFINE_PRED_ARRAY(m_rfAttackersHits, FIELD_INTEGER, MAX_PLAYERS + 1, FTYPEDESC_INSENDTABLE),
DEFINE_PRED_FIELD(m_vecGhostMarkerPos, FIELD_VECTOR, FTYPEDESC_INSENDTABLE),

DEFINE_PRED_FIELD_TOL(m_flCamoAuxLastTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE),

Expand Down Expand Up @@ -420,8 +417,6 @@ C_NEO_Player::C_NEO_Player()
m_iNextSpawnClassChoice = -1;
m_iXP.GetForModify() = 0;

m_vecGhostMarkerPos = vec3_origin;
m_bGhostExists = false;
m_bShowClassMenu = m_bShowTeamMenu = m_bIsClassMenuOpen = m_bIsTeamMenuOpen = false;
m_bInThermOpticCamo = m_bInVision = false;
m_bHasBeenAirborneForTooLongToSuperJump = false;
Expand Down Expand Up @@ -898,40 +893,6 @@ void C_NEO_Player::PreThink( void )
engine->ClientCmd(teammenu.GetName());
}

if (auto *ghostMarker = GET_NAMED_HUDELEMENT(CNEOHud_GhostMarker, neo_ghost_marker))
{
if (!m_bGhostExists)
{
ghostMarker->SetVisible(false);
}
else
{
const float distance = METERS_PER_INCH *
GetAbsOrigin().DistTo(m_vecGhostMarkerPos);

if (!IsCarryingGhost())
{
ghostMarker->SetVisible(true);

int ghostMarkerX, ghostMarkerY;
GetVectorInScreenSpace(m_vecGhostMarkerPos, ghostMarkerX, ghostMarkerY);

ghostMarker->SetScreenPosition(ghostMarkerX, ghostMarkerY);
ghostMarker->SetGhostingTeam(NEORules()->ghosterTeam());
ghostMarker->SetClientCurrentTeam(GetTeamNumber());
ghostMarker->SetGhostDistance(distance);
}
else
{
ghostMarker->SetVisible(false);
}
}
}
else
{
Warning("Couldn't find ghostMarker\n");
}

if (auto *indicator = GET_HUDELEMENT(CNEOHud_GameEvent))
{
if (m_bShowTestMessage)
Expand Down
4 changes: 0 additions & 4 deletions mp/src/game/client/neo/c_neo_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,9 @@ class C_NEO_Player : public C_HL2MP_Player
bool m_bShowClassMenu, m_bShowTeamMenu;
CNetworkVar(bool, m_bHasBeenAirborneForTooLongToSuperJump);

CNetworkVar(bool, m_bGhostExists);

CNetworkVar(float, m_flCamoAuxLastTime);
CNetworkVar(int, m_nVisionLastTick);

CNetworkVector(m_vecGhostMarkerPos);

CNetworkVar(bool, m_bInThermOpticCamo);
CNetworkVar(bool, m_bLastTickInThermOpticCamo);
CNetworkVar(bool, m_bInVision);
Expand Down
6 changes: 3 additions & 3 deletions mp/src/game/client/neo/ui/neo_hud_compass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,17 +232,17 @@ void CNEOHud_Compass::DrawCompass() const
if (m_objectiveVisible && !player->IsCarryingGhost())
{
// Point the objective arrow to the ghost, if it exists
if (player->m_vecGhostMarkerPos != vec3_origin)
if (NEORules()->GhostExists())
{
int ghostMarkerX, ghostMarkerY;
const bool ghostIsInView = GetVectorInScreenSpace(player->m_vecGhostMarkerPos, ghostMarkerX, ghostMarkerY);
const bool ghostIsInView = GetVectorInScreenSpace(NEORules()->GetGhostPos(), ghostMarkerX, ghostMarkerY);
if (ghostIsInView) {
// Print a unicode arrow to signify compass needle
const wchar_t arrowUnicode[] = L"";

ghostMarkerX = clamp(ghostMarkerX, resXHalf - xBoxWidthHalf, resXHalf + xBoxWidthHalf);

const int ghosterTeam = NEORules()->ghosterTeam();
const int ghosterTeam = NEORules()->GetGhosterTeam();
const int ownTeam = player->GetTeam()->GetTeamNumber();

const auto teamClr32 = player->GetTeam()->GetRenderColor();
Expand Down
101 changes: 51 additions & 50 deletions mp/src/game/client/neo/ui/neo_hud_ghost_marker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "neo_gamerules.h"
#include "neo_player_shared.h"
#include "c_neo_player.h"

#include "iclientmode.h"
#include <vgui/ILocalize.h>
Expand Down Expand Up @@ -30,12 +31,6 @@ NEO_HUD_ELEMENT_DECLARE_FREQ_CVAR(GhostMarker, 0.01)
CNEOHud_GhostMarker::CNEOHud_GhostMarker(const char* pElemName, vgui::Panel* parent)
: CNEOHud_WorldPosMarker(pElemName, parent)
{
m_flDistMeters = 0;

m_iGhostingTeam = TEAM_UNASSIGNED;
m_iClientTeam = TEAM_UNASSIGNED;
m_iPosX = m_iPosY = 0;

{
int i;
for (i = 0; i < sizeof(m_szMarkerText) - 1; ++i)
Expand Down Expand Up @@ -66,12 +61,6 @@ CNEOHud_GhostMarker::CNEOHud_GhostMarker(const char* pElemName, vgui::Panel* par
surface()->GetScreenSize(wide, tall);
SetBounds(0, 0, wide, tall);

// NEO HACK (Rain): this is kind of awkward, we should get the handle on ApplySchemeSettings
vgui::IScheme *scheme = vgui::scheme()->GetIScheme(neoscheme);
Assert(scheme);

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

m_hTex = surface()->CreateNewTextureID();
Assert(m_hTex > 0);
surface()->DrawSetTextureFile(m_hTex, "vgui/hud/ctg/g_beacon_circle", 1, false);
Expand All @@ -84,9 +73,17 @@ CNEOHud_GhostMarker::CNEOHud_GhostMarker(const char* pElemName, vgui::Panel* par
SetBgColor(Color(0, 0, 0, 0));
}

void CNEOHud_GhostMarker::ApplySchemeSettings(vgui::IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);

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

void CNEOHud_GhostMarker::UpdateStateForNeoHudElementDraw()
{
V_snprintf(m_szMarkerText, sizeof(m_szMarkerText), "GHOST %.0f M", m_flDistMeters);
const float flDistMeters = METERS_PER_INCH * C_NEO_Player::GetLocalPlayer()->GetAbsOrigin().DistTo(NEORules()->GetGhostPos());
V_snprintf(m_szMarkerText, sizeof(m_szMarkerText), "GHOST DISTANCE: %.0fm", flDistMeters);
g_pVGuiLocalize->ConvertANSIToUnicode(m_szMarkerText, m_wszMarkerTextUnicode, sizeof(m_wszMarkerTextUnicode));
}

Expand All @@ -97,34 +94,59 @@ void CNEOHud_GhostMarker::DrawNeoHudElement()
return;
}

auto fadeMultiplier = GetFadeValueTowardsScreenCentre(m_iPosX, m_iPosY);

if(fadeMultiplier > 0.001)
const auto localPlayer = static_cast<C_NEO_Player *>(C_NEO_Player::GetLocalPlayer());
if (!NEORules()->GhostExists() || localPlayer->IsCarryingGhost())
{
auto adjustedGrey = Color(COLOR_GREY.r(), COLOR_GREY.b(), COLOR_GREY.g(), COLOR_GREY.a() * fadeMultiplier);

surface()->DrawSetTextColor(adjustedGrey);
surface()->DrawSetTextFont(m_hFont);
int textSizeX, textSizeY;
surface()->GetTextSize(m_hFont, m_wszMarkerTextUnicode, textSizeX, textSizeY);
surface()->DrawSetTextPos(m_iPosX - (textSizeX / 2), m_iPosY + textSizeY);
surface()->DrawPrintText(m_wszMarkerTextUnicode, sizeof(m_szMarkerText));
return;
}

bool hideText = false;
Color ghostColor = COLOR_GREY;
if (m_iGhostingTeam == TEAM_JINRAI || m_iGhostingTeam == TEAM_NSF)
const int iGhostingTeam = NEORules()->GetGhosterTeam();
const int iClientTeam = localPlayer->GetTeamNumber();
if (iGhostingTeam == TEAM_JINRAI || iGhostingTeam == TEAM_NSF)
{
if ((m_iClientTeam == TEAM_JINRAI || m_iClientTeam == TEAM_NSF) && (m_iClientTeam != m_iGhostingTeam))
if ((iClientTeam == TEAM_JINRAI || iClientTeam == TEAM_NSF) && (iClientTeam != iGhostingTeam))
{
// If viewing from playing player, but opposite of ghosting team, show red
ghostColor = COLOR_RED;
}
else
{
// Otherwise show ghosting team color (if friendly or spec)
ghostColor = (m_iGhostingTeam == TEAM_JINRAI) ? COLOR_JINRAI : COLOR_NSF;
ghostColor = (iGhostingTeam == TEAM_JINRAI) ? COLOR_JINRAI : COLOR_NSF;

// Use the friendly HUD text for distance display instead if spectator team or same team
hideText = (iClientTeam < FIRST_GAME_TEAM || iGhostingTeam == iClientTeam);
}
}

int iPosX, iPosY;
Vector ghostPos = NEORules()->GetGhostPos();
// Use PVS over networked-given position if possible as it'll give a smoother visual
if (const int ghosterPlayerIdx = NEORules()->GetGhosterPlayer();
ghosterPlayerIdx > 0)
{
if (auto ghosterPlayer = static_cast<CNEO_Player *>(UTIL_PlayerByIndex(ghosterPlayerIdx));
ghosterPlayer->IsVisible())
{
ghostPos = ghosterPlayer->EyePosition();
}
}
GetVectorInScreenSpace(ghostPos, iPosX, iPosY);

const float fadeMultiplier = GetFadeValueTowardsScreenCentre(iPosX, iPosY);
if (!hideText && fadeMultiplier > 0.001f)
{
auto adjustedGrey = Color(COLOR_GREY.r(), COLOR_GREY.b(), COLOR_GREY.g(), COLOR_GREY.a() * fadeMultiplier);

surface()->DrawSetTextColor(adjustedGrey);
surface()->DrawSetTextFont(m_hFont);
int textSizeX, textSizeY;
surface()->GetTextSize(m_hFont, m_wszMarkerTextUnicode, textSizeX, textSizeY);
surface()->DrawSetTextPos(iPosX - (textSizeX / 2), iPosY + (2 * textSizeY));
surface()->DrawPrintText(m_wszMarkerTextUnicode, sizeof(m_szMarkerText));
}

const float scale = neo_ghost_marker_hud_scale_factor.GetFloat();

Expand All @@ -140,8 +162,8 @@ void CNEOHud_GhostMarker::DrawNeoHudElement()
if (m_fMarkerScalesCurrent[i] > 1)
m_fMarkerScalesCurrent[i] -= 1;

const int offset_X = m_iPosX - ((m_iMarkerTexWidth * 0.5f * m_fMarkerScalesCurrent[i]) * scale);
const int offset_Y = m_iPosY - ((m_iMarkerTexHeight * 0.5f * m_fMarkerScalesCurrent[i]) * scale);
const int offset_X = iPosX - ((m_iMarkerTexWidth * 0.5f * m_fMarkerScalesCurrent[i]) * scale);
const int offset_Y = iPosY - ((m_iMarkerTexHeight * 0.5f * m_fMarkerScalesCurrent[i]) * scale);

int alpha = 64 + alpha6;
if (m_fMarkerScalesCurrent[i] > 0.5)
Expand All @@ -167,24 +189,3 @@ void CNEOHud_GhostMarker::Paint()
BaseClass::Paint();
PaintNeoElement();
}

void CNEOHud_GhostMarker::SetGhostingTeam(int team)
{
m_iGhostingTeam = team;
}

void CNEOHud_GhostMarker::SetClientCurrentTeam(int team)
{
m_iClientTeam = team;
}

void CNEOHud_GhostMarker::SetScreenPosition(int x, int y)
{
m_iPosX = x;
m_iPosY = y;
}

void CNEOHud_GhostMarker::SetGhostDistance(float distance)
{
m_flDistMeters = distance;
}
30 changes: 10 additions & 20 deletions mp/src/game/client/neo/ui/neo_hud_ghost_marker.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,24 @@ class CNEOHud_GhostMarker : public CNEOHud_WorldPosMarker
public:
CNEOHud_GhostMarker(const char *pElemName, vgui::Panel *parent = NULL);

virtual void Paint();

void SetGhostingTeam(int team);
void SetClientCurrentTeam(int team);
void SetScreenPosition(int x, int y);
void SetGhostDistance(float distance);
virtual void ApplySchemeSettings(vgui::IScheme *pScheme) override;
virtual void Paint() override;

protected:
virtual void UpdateStateForNeoHudElementDraw();
virtual void DrawNeoHudElement();
virtual ConVar* GetUpdateFrequencyConVar() const;
virtual void UpdateStateForNeoHudElementDraw() override;
virtual void DrawNeoHudElement() override;
virtual ConVar *GetUpdateFrequencyConVar() const override;

private:
float m_fMarkerScalesStart[4] = { 0.78f, 0.6f, 0.38f, 0.0f };
float m_fMarkerScalesCurrent[4] = { 0.78f, 0.6f, 0.38f, 0.0f };
int m_iMarkerTexWidth, m_iMarkerTexHeight;
int m_iPosX, m_iPosY;
int m_iGhostingTeam;
int m_iClientTeam;

char m_szMarkerText[12 + 1];
wchar_t m_wszMarkerTextUnicode[12 + 1];

float m_flDistMeters;

vgui::HTexture m_hTex;
char m_szMarkerText[32 + 1];
wchar_t m_wszMarkerTextUnicode[32 + 1];

vgui::HFont m_hFont;
vgui::HTexture m_hTex = 0UL;
vgui::HFont m_hFont = 0UL;
};

#endif // NEO_HUD_GHOST_MARKER_H
#endif // NEO_HUD_GHOST_MARKER_H
Loading

0 comments on commit 0bc917a

Please sign in to comment.