Skip to content
Merged
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
69 changes: 3 additions & 66 deletions src/game/client/neo/ui/neo_hud_ghost_marker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,6 @@ void CNEOHud_GhostMarker::UpdateStateForNeoHudElementDraw()
{
if (NEORules()->GetGameType() != NEO_GAME_TYPE_JGR)
{
if (m_ghostInPVS && (!NEORules()->GhostExists() || NEORules()->IsRoundOver()))
{
m_ghostInPVS = nullptr;
}

if (!NEORules()->GetGhosterPlayer())
{
const float flDistMeters = METERS_PER_INCH * C_NEO_Player::GetLocalPlayer()->GetAbsOrigin().DistTo(NEORules()->GetGhostPos());
Expand Down Expand Up @@ -127,7 +122,6 @@ void CNEOHud_GhostMarker::UpdateStateForNeoHudElementDraw()

void CNEOHud_GhostMarker::resetHUDState()
{
m_ghostInPVS = nullptr;
m_jgrInPVS = nullptr;
}

Expand All @@ -148,9 +142,8 @@ void CNEOHud_GhostMarker::DrawNeoHudElement()
return;
}

const bool ghostExists = NEORules()->GhostExists();
const auto localPlayer = static_cast<C_NEO_Player*>(C_NEO_Player::GetLocalPlayer());
bool hideGhostMarker = (!ghostExists || localPlayer->IsCarryingGhost());
const C_NEO_Player* localPlayer = C_NEO_Player::GetLocalNEOPlayer();
bool hideGhostMarker = (localPlayer->IsCarryingGhost());
if (!hideGhostMarker && (localPlayer->GetObserverMode() == OBS_MODE_IN_EYE))
{
// NEO NOTE (nullsystem): Skip this if we're observing a player in first person
Expand All @@ -162,29 +155,6 @@ void CNEOHud_GhostMarker::DrawNeoHudElement()
return;
}

// NEO NOTE (nullsystem): Fetch client-side ghost entity when possible, it should be always emitted and therefore
// be able to be given on each round start. This itself is an expensive operation but only done once per round
// start. The usage of PVS is preferred since it'll give a smoother visual to the player verses relying on server
// side positioning.
//
// (Rain): Could we instead use OnPVSStatusChanged to track this client side?
if (!m_ghostInPVS)
{
C_AllBaseEntityIterator itr;
C_BaseEntity* ent = nullptr;
while ((ent = itr.Next()) != nullptr)
{
if (auto* ghostEnt = dynamic_cast<C_WeaponGhost*>(ent))
{
m_ghostInPVS = ghostEnt;
break;
}
}
// It should be valid at this point since it passed hideGhostMarker. Otherwise something very wrong
// happened.
Assert(m_ghostInPVS);
}

hideText = NEORules()->GetGhosterPlayer();
const int iGhostingTeam = NEORules()->GetGhosterTeam();
const int iClientTeam = localPlayer->GetTeamNumber();
Expand All @@ -201,41 +171,8 @@ void CNEOHud_GhostMarker::DrawNeoHudElement()
ghostColor = (iGhostingTeam == TEAM_JINRAI) ? COLOR_JINRAI : COLOR_NSF;
}
}

// Use PVS over networked-given position if possible as it'll give a smoother visual
// NEO NOTE (Rain): this assignment was segfaulting on Linux, so I've split the logic
// and added extra guards, so we can catch it better if it still happens.
Vector ghostPos;
if (m_ghostInPVS && m_ghostInPVS->IsVisible())
{
ghostPos = m_ghostInPVS->GetAbsOrigin();
}
else
{
if (NEORules())
{
ghostPos = NEORules()->GetGhostPos();
}
else
{
Assert(false);
return;
}
}

if (const int ghosterPlayerIdx = NEORules()->GetGhosterPlayer();
ghosterPlayerIdx > 0)
{
if (auto ghosterPlayer = static_cast<CNEO_Player*>(UTIL_PlayerByIndex(ghosterPlayerIdx)))
{
if (ghosterPlayer->IsVisible())
{
ghostPos = ghosterPlayer->EyePosition();
}
}
}

GetVectorInScreenSpace(ghostPos, iPosX, iPosY);
GetVectorInScreenSpace(NEORules()->GetGhostMarkerPos(), iPosX, iPosY);
}
else
{
Expand Down
9 changes: 1 addition & 8 deletions src/game/client/neo/ui/neo_hud_ghost_marker.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
#ifndef NEO_HUD_GHOST_MARKER_H
#define NEO_HUD_GHOST_MARKER_H
#ifdef _WIN32
#pragma once
#endif

#include "neo_hud_childelement.h"
#include "hudelement.h"
Expand Down Expand Up @@ -31,7 +27,6 @@ class CNEOHud_GhostMarker : public CNEOHud_WorldPosMarker
virtual ConVar *GetUpdateFrequencyConVar() const override;

private:
C_WeaponGhost *m_ghostInPVS = nullptr;
CNEO_Juggernaut *m_jgrInPVS = nullptr;
float m_fMarkerScalesStart[4] = { 0.78f, 0.6f, 0.38f, 0.0f };
float m_fMarkerScalesCurrent[4] = { 0.78f, 0.6f, 0.38f, 0.0f };
Expand All @@ -40,6 +35,4 @@ class CNEOHud_GhostMarker : public CNEOHud_WorldPosMarker

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

#endif // NEO_HUD_GHOST_MARKER_H
};
47 changes: 43 additions & 4 deletions src/game/shared/neo/neo_gamerules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ BEGIN_NETWORK_TABLE_NOBASE( CNEORules, DT_NEORules )
RecvPropBool(RECVINFO(m_bGhostExists)),
RecvPropFloat(RECVINFO(m_flGhostLastHeld)),
RecvPropVector(RECVINFO(m_vecGhostMarkerPos)),
RecvPropEHandle(RECVINFO(m_hGhost)),
RecvPropInt(RECVINFO(m_iJuggernautPlayerIndex)),
RecvPropBool(RECVINFO(m_bJuggernautItemExists)),
RecvPropVector(RECVINFO(m_vecJuggernautMarkerPos)),
Expand All @@ -268,6 +269,7 @@ BEGIN_NETWORK_TABLE_NOBASE( CNEORules, DT_NEORules )
SendPropBool(SENDINFO(m_bGhostExists)),
SendPropFloat(SENDINFO(m_flGhostLastHeld)),
SendPropVector(SENDINFO(m_vecGhostMarkerPos), -1, SPROP_COORD_MP_LOWPRECISION | SPROP_CHANGES_OFTEN, MIN_COORD_FLOAT, MAX_COORD_FLOAT),
SendPropEHandle(SENDINFO(m_hGhost)),
SendPropInt(SENDINFO(m_iJuggernautPlayerIndex)),
SendPropBool(SENDINFO(m_bJuggernautItemExists)),
SendPropVector(SENDINFO(m_vecJuggernautMarkerPos), -1, SPROP_COORD_MP_LOWPRECISION | SPROP_CHANGES_OFTEN, MIN_COORD_FLOAT, MAX_COORD_FLOAT),
Expand Down Expand Up @@ -953,6 +955,7 @@ void CNEORules::Think(void)
if (dynamic_cast<CWeaponGhost*>(pEnt))
{
m_pGhost = static_cast<CWeaponGhost*>(pEnt);
m_hGhost = m_pGhost;
return;
}
pEnt = gEntList.NextEnt(pEnt);
Expand Down Expand Up @@ -1328,9 +1331,10 @@ void CNEORules::Think(void)

if (m_pGhost->GetAbsOrigin().IsValid())
{
// Someone's carrying it, center at their body
m_vecGhostMarkerPos = (pGhosterPlayer && (nextGhosterTeam == TEAM_JINRAI || nextGhosterTeam == TEAM_NSF)) ?
pGhosterPlayer->EyePosition() : m_pGhost->GetAbsOrigin();
// Someone's carrying it
m_vecGhostMarkerPos = (nextGhosterTeam == TEAM_JINRAI || nextGhosterTeam == TEAM_NSF) ?
// NEO NOTE (Adam) GetGhostMarkerPos() can return m_vecGhostMarkerPos if m_pGhost is invalid, but we've checked for m_pGhost above so should be fine?
GetGhostMarkerPos() : m_pGhost->GetAbsOrigin();
}
else
{
Expand Down Expand Up @@ -1845,8 +1849,9 @@ void CNEORules::SpawnTheGhost(const Vector *origin)
m_pGhost->NetworkStateChanged();
spawnedGhostNow = true;
}
m_hGhost = m_pGhost;
m_bGhostExists = true;

Assert(UTIL_IsValidEntity(m_pGhost));

if (origin)
Expand Down Expand Up @@ -4303,6 +4308,40 @@ float CNEORules::GetRemainingPreRoundFreezeTime(const bool clampToZero) const
}
}

Vector CNEORules::GetGhostPos() const
{
#ifdef GAME_DLL
return m_pGhost ? m_pGhost->GetAbsOrigin() : m_vecGhostMarkerPos;
#else
if (auto pGhost = static_cast<CWeaponGhost*>(m_hGhost.Get());
pGhost)
{
return pGhost->GetAbsOrigin();
}
return m_vecGhostMarkerPos;
#endif // GAME_DLL
}

Vector CNEORules::GetGhostMarkerPos() const
{
if (auto pGhosterPlayer = static_cast<CNEO_Player*>(UTIL_PlayerByIndex(GetGhosterPlayer()));
pGhosterPlayer
#ifdef CLIENT_DLL
&& pGhosterPlayer->IsVisible()
#endif // CLIENT_DLL
)
{
if (auto pWeapon = static_cast<CNEOBaseCombatWeapon*>(pGhosterPlayer->GetActiveWeapon());
pWeapon && pWeapon->GetNeoWepBits() & NEO_WEP_GHOST)
{
constexpr const int GHOST_MARKER_STANDING_PLAYER_OFFSET = 32;
constexpr const int GHOST_MARKER_CROUCHING_PLAYER_OFFSET = 24;
return pGhosterPlayer->GetAbsOrigin() + Vector(0, 0, pGhosterPlayer->GetFlags() & FL_DUCKING ? GHOST_MARKER_CROUCHING_PLAYER_OFFSET : GHOST_MARKER_STANDING_PLAYER_OFFSET);
}
}
return GetGhostPos();
}

const char *CNEORules::GetTeamClantag(const int iTeamNum) const
{
switch (iTeamNum)
Expand Down
5 changes: 4 additions & 1 deletion src/game/shared/neo/neo_gamerules.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "GameEventListener.h"
#include "neo_player_shared.h"
#include "neo_misc.h"
#include "weapon_ghost.h"
#ifdef GAME_DLL
#include "neo_juggernaut.h"
#endif
Expand Down Expand Up @@ -323,7 +324,8 @@ class CNEORules : public CHL2MPRules, public CGameEventListener
int GetGhosterTeam() const { return m_iGhosterTeam; }
int GetGhosterPlayer() const { return m_iGhosterPlayer; }
bool GhostExists() const { return m_bGhostExists; }
Vector GetGhostPos() const { return m_vecGhostMarkerPos; }
Vector GetGhostPos() const;
Vector GetGhostMarkerPos() const;

int GetJuggernautPlayer() const { return m_iJuggernautPlayerIndex; }
bool JuggernautItemExists() const { return m_bJuggernautItemExists; }
Expand Down Expand Up @@ -453,6 +455,7 @@ class CNEORules : public CHL2MPRules, public CGameEventListener
CNetworkVector(m_vecGhostMarkerPos);
CNetworkVar(bool, m_bGhostExists);
CNetworkVar(float, m_flGhostLastHeld);
CNetworkHandle( CWeaponGhost, m_hGhost );

// Juggernaut networked variables
CNetworkVar(int, m_iJuggernautPlayerIndex);
Expand Down