Skip to content
Draft
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
2 changes: 2 additions & 0 deletions src/game/client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ target_sources_grouped(
c_baseflex.cpp
c_baseplayer.cpp
c_baseviewmodel.cpp
c_buttons.cpp
c_breakableprop.cpp
c_colorcorrection.cpp
c_colorcorrectionvolume.cpp
Expand Down Expand Up @@ -856,6 +857,7 @@ target_sources_grouped(
c_baseplayer.h
c_basetempentity.h
c_baseviewmodel.h
c_buttons.h
c_breakableprop.h
c_effects.h
c_entitydissolve.h
Expand Down
4 changes: 4 additions & 0 deletions src/game/client/c_baseentity.h
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,11 @@ class C_BaseEntity : public IClientEntity
// These methods encapsulate MOVETYPE_FOLLOW, which became obsolete
void FollowEntity( CBaseEntity *pBaseEntity, bool bBoneMerge = true );
void StopFollowingEntity( ); // will also change to MOVETYPE_NONE
#ifdef NEO
virtual bool IsFollowingEntity();
#else
bool IsFollowingEntity();
#endif // NEO
CBaseEntity *GetFollowedEntity();

// For shadows rendering the correct body + sequence...
Expand Down
13 changes: 13 additions & 0 deletions src/game/client/c_baseplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2660,6 +2660,19 @@ void C_BasePlayer::SetSwimSoundTime( float flSwimSoundTime )
//-----------------------------------------------------------------------------
bool C_BasePlayer::IsUseableEntity( CBaseEntity *pEntity, unsigned int requiredCaps )
{
#ifdef NEO
if ( pEntity )
{
int caps = pEntity->ObjectCaps();
if ( caps & (FCAP_IMPULSE_USE|FCAP_CONTINUOUS_USE|FCAP_ONOFF_USE|FCAP_DIRECTIONAL_USE) )
{
if ( (caps & requiredCaps) == requiredCaps )
{
return true;
}
}
}
#endif // NEO
return false;
}

Expand Down
4 changes: 4 additions & 0 deletions src/game/client/c_baseplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener
virtual void AvoidPhysicsProps( CUserCmd *pCmd );

virtual void PlayerUse( void );
#ifdef NEO
virtual CBaseEntity *FindUseEntity( void );
#else
CBaseEntity *FindUseEntity( void );
#endif // NEO
virtual bool IsUseableEntity( CBaseEntity *pEntity, unsigned int requiredCaps );

// Data handlers
Expand Down
15 changes: 15 additions & 0 deletions src/game/client/c_buttons.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "c_buttons.h"

#include "tier0/memdbgon.h"

#define SF_BUTTON_USE_ACTIVATES 1024 // Button fires when used.

LINK_ENTITY_TO_CLASS(func_button, C_BaseButton);

IMPLEMENT_CLIENTCLASS_DT( C_BaseButton, DT_BaseButton, CBaseButton )
RecvPropInt( RECVINFO(m_spawnflags) ),
END_RECV_TABLE()

int C_BaseButton::ObjectCaps(void) {
return BaseClass::ObjectCaps() | ((m_spawnflags & SF_BUTTON_USE_ACTIVATES) ? (FCAP_IMPULSE_USE | FCAP_USE_IN_RADIUS) : 0);
};
14 changes: 14 additions & 0 deletions src/game/client/c_buttons.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include "c_baseentity.h"

class C_BaseButton : public C_BaseEntity
{
public:
DECLARE_CLASS(C_BaseButton, C_BaseEntity);
DECLARE_CLIENTCLASS();

int m_spawnflags;

virtual int ObjectCaps(void) override;
};
11 changes: 11 additions & 0 deletions src/game/client/c_playerresource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ IMPLEMENT_CLIENTCLASS_DT_NOBASE(C_PlayerResource, DT_PlayerResource, CPlayerReso
RecvPropArray3(RECVINFO_ARRAY(m_iStar), RecvPropInt(RECVINFO(m_iStar[0]))),
RecvPropArray3(RECVINFO_ARRAY(m_szNeoClantag), RecvPropString(RECVINFO(m_szNeoClantag[0]))),
RecvPropArray3(RECVINFO_ARRAY(m_iMaxHealth), RecvPropInt(RECVINFO(m_iMaxHealth[0]))),
RecvPropArray3(RECVINFO_ARRAY(m_bAfk), RecvPropInt(RECVINFO(m_bAfk[0]))),
#endif
RecvPropArray3( RECVINFO_ARRAY(m_iScore), RecvPropInt( RECVINFO(m_iScore[0]))),
RecvPropArray3( RECVINFO_ARRAY(m_iDeaths), RecvPropInt( RECVINFO(m_iDeaths[0]))),
Expand All @@ -57,6 +58,7 @@ BEGIN_PREDICTION_DATA( C_PlayerResource )
DEFINE_PRED_ARRAY(m_iStar, FIELD_INTEGER, MAX_PLAYERS_ARRAY_SAFE, FTYPEDESC_PRIVATE),
DEFINE_PRED_ARRAY(m_szNeoClantag, FIELD_STRING, MAX_PLAYERS_ARRAY_SAFE, FTYPEDESC_PRIVATE),
DEFINE_PRED_ARRAY(m_iMaxHealth, FIELD_INTEGER, MAX_PLAYERS_ARRAY_SAFE, FTYPEDESC_PRIVATE),
DEFINE_PRED_ARRAY(m_bAfk, FIELD_BOOLEAN, MAX_PLAYERS_ARRAY_SAFE, FTYPEDESC_PRIVATE),
#endif
DEFINE_PRED_ARRAY( m_iScore, FIELD_INTEGER, MAX_PLAYERS_ARRAY_SAFE, FTYPEDESC_PRIVATE ),
DEFINE_PRED_ARRAY( m_iDeaths, FIELD_INTEGER, MAX_PLAYERS_ARRAY_SAFE, FTYPEDESC_PRIVATE ),
Expand Down Expand Up @@ -94,6 +96,7 @@ C_PlayerResource::C_PlayerResource()
memset(m_iStar, 0, sizeof(m_iStar));
memset(m_szNeoClantag, 0, sizeof(m_szNeoClantag));
memset(m_iMaxHealth, 1, sizeof(m_iMaxHealth));
memset(m_bAfk, 0, sizeof(m_bAfk));
#endif
memset( m_iScore, 0, sizeof( m_iScore ) );
memset( m_iDeaths, 0, sizeof( m_iDeaths ) );
Expand Down Expand Up @@ -470,6 +473,14 @@ int C_PlayerResource::GetDisplayedHealth(int iIndex, int mode)
return GetHealth(iIndex);
}
}

bool C_PlayerResource::IsAfk(int iIndex)
{
if ( !IsConnected( iIndex ) && !IsValid( iIndex ) )
return false;

return m_bAfk[iIndex];
}
#endif

const Color &C_PlayerResource::GetTeamColor(int index_ )
Expand Down
2 changes: 2 additions & 0 deletions src/game/client/c_playerresource.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public : // IGameResources interface
const char *GetClanTag(int index);
virtual int GetMaxHealth(int index);
virtual int GetDisplayedHealth(int index, int mode);
virtual bool IsAfk(int index);
#endif
virtual int GetFrags( int index );
virtual int GetHealth( int index );
Expand Down Expand Up @@ -89,6 +90,7 @@ public : // IGameResources interface
int m_iStar[MAX_PLAYERS_ARRAY_SAFE];
char m_szNeoClantag[MAX_PLAYERS_ARRAY_SAFE][NEO_MAX_CLANTAG_LENGTH];
int m_iMaxHealth[MAX_PLAYERS_ARRAY_SAFE];
bool m_bAfk[MAX_PLAYERS_ARRAY_SAFE];
#endif
int m_iScore[MAX_PLAYERS_ARRAY_SAFE];
int m_iDeaths[MAX_PLAYERS_ARRAY_SAFE];
Expand Down
53 changes: 53 additions & 0 deletions src/game/client/glow_outline_effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ ConVar glow_outline_effect_width( "glow_outline_effect_width", "1.f", FCVAR_ARCH
ConVar glow_outline_effect_alpha( "glow_outline_effect_alpha", "0.5f", FCVAR_ARCHIVE, "Alpha of glow outline effect.", true, 0.f, true, 1.f);
ConVar glow_outline_effect_center_alpha("glow_outline_effect_center_alpha", "0.1f", FCVAR_ARCHIVE, "Opacity of the part of the glow effect drawn on top of the player model when obstructed", true, 0.f, true, 1.f);
ConVar glow_outline_effect_textured_center_alpha("glow_outline_effect_textured_center_alpha", "0.2f", FCVAR_ARCHIVE, "Opacity of the part of the glow effect drawn on top of the player model when cloaked", true, 0.f, true, 1.f);
ConVar cl_neo_hud_context_hint_highlight_object("cl_neo_hud_context_hint_highlight_object", "1", FCVAR_ARCHIVE, "Highlight interactible object", true, 0.f, true, 1.f,
[](IConVar* var, const char* pOldValue, float flOldValue)->void{
if (!cl_neo_hud_context_hint_highlight_object.GetBool())
g_GlowObjectManager.ClearUseItemObject();
return;
});
ConVar cl_neo_hud_context_hint_highlight_player("cl_neo_hud_context_hint_highlight_player", "1", FCVAR_ARCHIVE, "Highlight interactible players", true, 0.f, true, 1.f,
[](IConVar* var, const char* pOldValue, float flOldValue)->void{
if (!cl_neo_hud_context_hint_highlight_player.GetBool())
g_GlowObjectManager.ClearUseItemPlayer();
return;
});
#else
ConVar glow_outline_effect_enable( "glow_outline_effect_enable", "0", 0, "Enable entity outline glow effects.");
ConVar glow_outline_effect_width( "glow_outline_width", "10.0f", FCVAR_CHEAT, "Width of glow outline effect in screen space." );
Expand Down Expand Up @@ -81,7 +93,11 @@ void CGlowObjectManager::RenderGlowEffects( const CViewSetup *pSetup, int nSplit
{
if ( g_pMaterialSystemHardwareConfig->SupportsPixelShaders_2_0() )
{
#ifdef NEO
if ( glow_outline_effect_enable.GetBool() || cl_neo_hud_context_hint_highlight_object.GetBool() || cl_neo_hud_context_hint_highlight_player.GetBool() )
#else
if ( glow_outline_effect_enable.GetBool() )
#endif // NEO
{
CMatRenderContextPtr pRenderContext( materials );

Expand Down Expand Up @@ -156,6 +172,9 @@ void CGlowObjectManager::RenderGlowModels( const CViewSetup *pSetup, int nSplitS
continue;

#ifdef NEO
if ( i != m_GlowObjectDefinitions.Count() - 1 && useItem.m_hEntity.IsValid() && useItem.m_hEntity == m_GlowObjectDefinitions[i].m_hEntity)
continue;

// DrawModel can call ForcedMaterialOverride also
g_pStudioRender->ForcedMaterialOverride(pMatGlowColor);
#endif
Expand Down Expand Up @@ -201,11 +220,24 @@ void CGlowObjectManager::ApplyEntityGlowEffects( const CViewSetup *pSetup, int n

int iNumGlowObjects = 0;

#ifdef NEO
constexpr int INVALID_USEELEMENT_INDEX = -1;
int useElementIndex = INVALID_USEELEMENT_INDEX;
if (useItem.m_hEntity.IsValid())
{
useElementIndex = m_GlowObjectDefinitions.AddToTail(useItem);
}
#endif // NEO
for ( int i = 0; i < m_GlowObjectDefinitions.Count(); ++ i )
{
if ( m_GlowObjectDefinitions[i].IsUnused() || !m_GlowObjectDefinitions[i].ShouldDraw( nSplitScreenSlot ) )
continue;

#ifdef NEO
if (i != useElementIndex && useItem.m_hEntity == m_GlowObjectDefinitions[i].m_hEntity)
continue;
#endif // NEO

if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded || m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
{
if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded && m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
Expand Down Expand Up @@ -280,6 +312,11 @@ void CGlowObjectManager::ApplyEntityGlowEffects( const CViewSetup *pSetup, int n
{
if ( m_GlowObjectDefinitions[i].IsUnused() || !m_GlowObjectDefinitions[i].ShouldDraw( nSplitScreenSlot ) )
continue;

#ifdef NEO
if (i != useElementIndex && useItem.m_hEntity == m_GlowObjectDefinitions[i].m_hEntity)
continue;
#endif // NEO

if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded && !m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
{
Expand Down Expand Up @@ -316,7 +353,17 @@ void CGlowObjectManager::ApplyEntityGlowEffects( const CViewSetup *pSetup, int n
// this fixes a bug where if there are glow objects in the list, but none of them are glowing,
// the whole screen blooms.
if ( iNumGlowObjects <= 0 )
#ifdef NEO
{
if (useElementIndex != INVALID_USEELEMENT_INDEX)
{
m_GlowObjectDefinitions.Remove(useElementIndex);
}
return;
}
#else
return;
#endif // NEO

//=============================================
// Render the glow colors to _rt_FullFrameFB
Expand All @@ -325,6 +372,12 @@ void CGlowObjectManager::ApplyEntityGlowEffects( const CViewSetup *pSetup, int n
PIXEvent pixEvent( pRenderContext, "RenderGlowModels" );
RenderGlowModels( pSetup, nSplitScreenSlot, pRenderContext );
}
#ifdef NEO
if (useElementIndex != INVALID_USEELEMENT_INDEX)
{
m_GlowObjectDefinitions.Remove(useElementIndex);
}
#endif // NEO

// Get viewport
#ifndef NEO
Expand Down
42 changes: 42 additions & 0 deletions src/game/client/glow_outline_effect.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ class CMatRenderContextPtr;

static const int GLOW_FOR_ALL_SPLIT_SCREEN_SLOTS = -1;

#ifdef NEO
extern ConVar cl_neo_hud_context_hint_highlight_object;
extern ConVar cl_neo_hud_context_hint_highlight_player;
#endif // NEO

class CGlowObjectManager
{
public:
Expand Down Expand Up @@ -121,6 +126,39 @@ class CGlowObjectManager
Assert( !m_GlowObjectDefinitions[nGlowObjectHandle].IsUnused() );
m_GlowObjectDefinitions[nGlowObjectHandle].m_bUseTexturedHighlight = useTexturedHighlight;
}

void SetUseItem( C_BaseEntity *pEntity, const Vector &vGlowColor = Vector( 1.0f, 1.0f, 1.0f ), float flGlowAlpha = 1.0f, bool bRenderWhenOccluded = false, bool bRenderWhenUnoccluded = false, int nSplitScreenSlot = GLOW_FOR_ALL_SPLIT_SCREEN_SLOTS )
{
if (pEntity->IsPlayer() && !cl_neo_hud_context_hint_highlight_player.GetBool())
return;
else if (!pEntity->IsPlayer() && !cl_neo_hud_context_hint_highlight_object.GetBool())
return;

useItem.m_hEntity = pEntity;
useItem.m_vGlowColor = vGlowColor;
useItem.m_flGlowAlpha = flGlowAlpha;
useItem.m_bRenderWhenOccluded = bRenderWhenOccluded;
useItem.m_bRenderWhenUnoccluded = bRenderWhenUnoccluded;
useItem.m_nSplitScreenSlot = nSplitScreenSlot;
useItem.m_nNextFreeSlot = GlowObjectDefinition_t::ENTRY_IN_USE;
}

void ClearUseItem()
{
useItem.m_hEntity = INVALID_EHANDLE;
}
void ClearUseItemObject()
{
C_BaseEntity* pEntity = useItem.m_hEntity.Get();
if (pEntity && !pEntity->IsPlayer())
useItem.m_hEntity = INVALID_EHANDLE;
}
void ClearUseItemPlayer()
{
C_BaseEntity* pEntity = useItem.m_hEntity.Get();
if (pEntity && pEntity->IsPlayer())
useItem.m_hEntity = INVALID_EHANDLE;
}
#endif // NEO
private:

Expand Down Expand Up @@ -162,6 +200,10 @@ class CGlowObjectManager

CUtlVector< GlowObjectDefinition_t > m_GlowObjectDefinitions;
int m_nFirstFreeSlot;

#ifdef NEO
GlowObjectDefinition_t useItem;
#endif // NEO
};

extern CGlowObjectManager g_GlowObjectManager;
Expand Down
47 changes: 40 additions & 7 deletions src/game/client/neo/c_neo_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1461,11 +1461,6 @@ void C_NEO_Player::TeamChange(int iNewTeam)
#ifdef GLOWS_ENABLE
void C_NEO_Player::UpdateGlowEffects(int iNewTeam)
{
if (!glow_outline_effect_enable.GetBool() || NEORules()->GetHiddenHudElements() & NEO_HUD_ELEMENT_FRIENDLY_MARKER)
{
return;
}

auto updateGlowColour = [](C_BasePlayer* pPlayer, int iTeam = 0) {
float r, g, b;
NEORules()->GetTeamGlowColor(iTeam ? iTeam : pPlayer->GetTeamNumber(), r, g, b);
Expand All @@ -1479,7 +1474,7 @@ void C_NEO_Player::UpdateGlowEffects(int iNewTeam)
continue;
}

if (pPlayer->GetTeamNumber() == TEAM_SPECTATOR || pPlayer->GetTeamNumber() == TEAM_UNASSIGNED)
if (pPlayer->GetTeamNumber() == TEAM_SPECTATOR || pPlayer->GetTeamNumber() == TEAM_UNASSIGNED || !glow_outline_effect_enable.GetBool() || NEORules()->GetHiddenHudElements() & NEO_HUD_ELEMENT_FRIENDLY_MARKER)
{
pPlayer->SetClientSideGlowEnabled(false);
continue;
Expand All @@ -1495,7 +1490,7 @@ void C_NEO_Player::UpdateGlowEffects(int iNewTeam)
}
}
else {
if (iNewTeam == TEAM_SPECTATOR || iNewTeam == TEAM_UNASSIGNED)
if (iNewTeam == TEAM_SPECTATOR || iNewTeam == TEAM_UNASSIGNED || !glow_outline_effect_enable.GetBool() || NEORules()->GetHiddenHudElements() & NEO_HUD_ELEMENT_FRIENDLY_MARKER)
{
SetClientSideGlowEnabled(false);
return;
Expand Down Expand Up @@ -2104,3 +2099,41 @@ const char* C_NEO_Player::GetPlayerNameWithTakeoverContext(int player_index)
return base_name;
}

C_NEO_Player* C_NEO_Player::PlayerUseTraceLine()
{
// Select player under cursor
Vector eyePos = EyePosition();
Vector forward;
EyeVectors( &forward );
Vector traceEnd = eyePos + forward * MAX_COORD_RANGE;

// MASK_SHOT_HULL to match friendly fire warning trace
trace_t tr;
UTIL_TraceLine( eyePos, traceEnd, MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, &tr );

if (tr.DidHit() && tr.m_pEnt)
{
return ToNEOPlayer(tr.m_pEnt);
}
return nullptr;
}

void C_NEO_Player::PlayerUse()
{
BaseClass::PlayerUse();

// Was use pressed or released?
if ( ! ((m_nButtons | m_afButtonPressed | m_afButtonReleased) & IN_USE) )
return;

if ( (m_afButtonPressed & IN_USE) && prediction->IsFirstTimePredicted() && !GetUseEntity())
{
if (C_NEO_Player* pTargetPlayer = PlayerUseTraceLine();
pTargetPlayer )
{
m_Local.m_nOldButtons |= IN_USE;
m_afButtonPressed &= ~IN_USE;
engine->ExecuteClientCmd(VarArgs("useplayer %i", pTargetPlayer->entindex()));
}
}
}
Loading