Skip to content

Commit

Permalink
add various fixes from main repo 2
Browse files Browse the repository at this point in the history
  • Loading branch information
Bitl committed Mar 31, 2022
1 parent b613544 commit 3b26616
Show file tree
Hide file tree
Showing 10 changed files with 416 additions and 324 deletions.
443 changes: 260 additions & 183 deletions sp/src/game/client/glow_outline_effect.cpp

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion sp/src/game/client/glow_outline_effect.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ class CGlowObjectManager

private:

void RenderGlowModels( const CViewSetup *pSetup, int nSplitScreenSlot, CMatRenderContextPtr &pRenderContext );
void ApplyEntityGlowEffects( const CViewSetup *pSetup, int nSplitScreenSlot, CMatRenderContextPtr &pRenderContext, float flBloomScale, int x, int y, int w, int h );

struct GlowObjectDefinition_t
Expand Down Expand Up @@ -150,6 +149,10 @@ class CGlowObjectManager
static const int ENTRY_IN_USE = -2;
};

void DrawGlowVisible(int nSplitScreenSlot, CMatRenderContextPtr& pRenderContext);
void DrawGlowOccluded(int nSplitScreenSlot, CMatRenderContextPtr& pRenderContext);
void DrawGlowAlways(int nSplitScreenSlot, CMatRenderContextPtr& pRenderContext);

CUtlVector< GlowObjectDefinition_t > m_GlowObjectDefinitions;
int m_nFirstFreeSlot;
};
Expand Down
286 changes: 149 additions & 137 deletions sp/src/game/shared/baseplayer_shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1069,205 +1069,218 @@ float IntervalDistance( float x, float x0, float x1 )
return 0;
}

CBaseEntity *CBasePlayer::FindUseEntity()
static float EstimatedDistanceSquared(const Vector &point, const CBaseEntity *pEntity)
{
Vector forward, up;
EyeVectors( &forward, NULL, &up );
Vector nearestPoint;
pEntity->CollisionProp()->CalcNearestPoint( point, &nearestPoint );
return (nearestPoint - point).LengthSqr();
}

trace_t tr;
// Search for objects in a sphere (tests for entities that are not solid, yet still useable)
CBaseEntity *CBasePlayer::FindUseEntity()
{
Vector forward;
EyeVectors( &forward, NULL, NULL );
Vector searchCenter = EyePosition();

// NOTE: Some debris objects are useable too, so hit those as well
// A button, etc. can be made out of clip brushes, make sure it's +useable via a traceline, too.
int useableContents = MASK_SOLID | CONTENTS_DEBRIS | CONTENTS_PLAYERCLIP;
// Some debris objects are +usable, and clip brushes can be made into
// +usable entities.
int usableContents = MASK_SOLID | CONTENTS_DEBRIS | CONTENTS_PLAYERCLIP;

// However, we occasionally need to ignore clip brushes so that objects
// inside of or beyond them can be +used.
const int usableContentsIgnoreClip = usableContents & ~CONTENTS_PLAYERCLIP;

#ifdef CSTRIKE_DLL
useableContents = MASK_NPCSOLID_BRUSHONLY | MASK_OPAQUE_AND_NPCS;
usableContents = MASK_NPCSOLID_BRUSHONLY | MASK_OPAQUE_AND_NPCS;
#endif

#ifdef HL1_DLL
useableContents = MASK_SOLID;
#endif
#ifndef CLIENT_DLL
CBaseEntity *pFoundByTrace = NULL;
usableContents = MASK_SOLID;
#endif

// UNDONE: Might be faster to just fold this range into the sphere query
CBaseEntity *pObject = NULL;
// First, try to hit an entity directly in front of the player.
trace_t directTrace;
UTIL_TraceLine( searchCenter, searchCenter + PLAYER_USE_RADIUS * forward, usableContents, this, COLLISION_GROUP_NONE, &directTrace );

float nearestDist = FLT_MAX;
// try the hit entity if there is one, or the ground entity if there isn't.
CBaseEntity *pNearest = NULL;
CBaseEntity *pObject = directTrace.m_pEnt;
bool bUsable = IsUseableEntity( pObject, 0 );

const int NUM_TANGENTS = 8;
// trace a box at successive angles down
// forward, 45 deg, 30 deg, 20 deg, 15 deg, 10 deg, -10, -15
const float tangents[NUM_TANGENTS] = { 0, 1, 0.57735026919f, 0.3639702342f, 0.267949192431f, 0.1763269807f, -0.1763269807f, -0.267949192431f };
for ( int i = 0; i < NUM_TANGENTS; i++ )
if ( !bUsable && (directTrace.contents & CONTENTS_PLAYERCLIP) )
{
if ( i == 0 )
{
UTIL_TraceLine( searchCenter, searchCenter + forward * 1024, useableContents, this, COLLISION_GROUP_NONE, &tr );
}
else
{
Vector down = forward - tangents[i]*up;
VectorNormalize(down);
UTIL_TraceHull( searchCenter, searchCenter + down * 72, -Vector(16,16,16), Vector(16,16,16), useableContents, this, COLLISION_GROUP_NONE, &tr );
}
pObject = tr.m_pEnt;

#ifndef CLIENT_DLL
pFoundByTrace = pObject;
#endif
bool bUsable = IsUseableEntity(pObject, 0);
while ( pObject && !bUsable && pObject->GetMoveParent() )
{
pObject = pObject->GetMoveParent();
bUsable = IsUseableEntity(pObject, 0);
}
// We hit a non-usable clip brush. Try tracing again, ignoring clip
// brushes, so that objects inside of or beyond them can be +used.

if ( bUsable )
{
Vector delta = tr.endpos - tr.startpos;
float centerZ = CollisionProp()->WorldSpaceCenter().z;
delta.z = IntervalDistance( tr.endpos.z, centerZ + CollisionProp()->OBBMins().z, centerZ + CollisionProp()->OBBMaxs().z );
float dist = delta.Length();
if ( dist < PLAYER_USE_RADIUS )
{
#ifndef CLIENT_DLL

if ( sv_debug_player_use.GetBool() )
{
NDebugOverlay::Line( searchCenter, tr.endpos, 0, 255, 0, true, 30 );
NDebugOverlay::Cross3D( tr.endpos, 16, 0, 255, 0, true, 30 );
}

if ( pObject->MyNPCPointer() && pObject->MyNPCPointer()->IsPlayerAlly( this ) )
{
// If about to select an NPC, do a more thorough check to ensure
// that we're selecting the right one from a group.
pObject = DoubleCheckUseNPC( pObject, searchCenter, forward );
}
#endif
if ( sv_debug_player_use.GetBool() )
{
Msg( "Trace using: %s\n", pObject ? pObject->GetDebugName() : "no usable entity found" );
}
// NOTE: If a usable clip brush is behind a non-usable clip brush,
// then we won't be able to +use it, unfortunately. This is difficult
// to workaround. For example, the non-usable clip brush cannot be added
// to a list of ignored entities, because it is part of the worldspawn,
// and we cannot ignore that.
UTIL_TraceLine( searchCenter, searchCenter + PLAYER_USE_RADIUS * forward, usableContentsIgnoreClip, this, COLLISION_GROUP_NONE, &directTrace );

pNearest = pObject;

// if this is directly under the cursor just return it now
if ( i == 0 )
return pObject;
}
}
pObject = directTrace.m_pEnt;
bUsable = IsUseableEntity( pObject, 0 );
}

// check ground entity first
// if you've got a useable ground entity, then shrink the cone of this search to 45 degrees
// otherwise, search out in a 90 degree cone (hemisphere)
if ( GetGroundEntity() && IsUseableEntity(GetGroundEntity(), FCAP_USE_ONGROUND) )
// If the object is not usable, determine if a move ancestor is.
while ( pObject && !bUsable && pObject->GetMoveParent() )
{
pNearest = GetGroundEntity();
pObject = pObject->GetMoveParent();
bUsable = IsUseableEntity( pObject, 0 );
}
if ( pNearest )

if ( bUsable )
{
// estimate nearest object by distance from the view vector
Vector point;
pNearest->CollisionProp()->CalcNearestPoint( searchCenter, &point );
nearestDist = CalcDistanceToLine( point, searchCenter, forward );
pNearest = pObject;

if ( sv_debug_player_use.GetBool() )
{
Msg("Trace found %s, dist %.2f\n", pNearest->GetClassname(), nearestDist );
const float distSquared = EstimatedDistanceSquared( searchCenter, pNearest );
Msg( "Line trace found usable entity: %s, distance: %.2f\n", pNearest->GetDebugName(), sqrt( distSquared ) );
}
}

for ( CEntitySphereQuery sphere( searchCenter, PLAYER_USE_RADIUS ); ( pObject = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() )
else
{
if ( !pObject )
continue;
// Any objects directly in front of us weren't usable and close enough.
// Next, determine if the ground entity is usable.
float nearestDistSquared = FLT_MAX;

if ( !IsUseableEntity( pObject, FCAP_USE_IN_RADIUS ) )
continue;
if ( GetGroundEntity() && IsUseableEntity( GetGroundEntity(), FCAP_USE_ONGROUND ) )
{
pNearest = GetGroundEntity();
nearestDistSquared = EstimatedDistanceSquared( searchCenter, pNearest );

// see if it's more roughly in front of the player than previous guess
Vector point;
pObject->CollisionProp()->CalcNearestPoint( searchCenter, &point );
if ( sv_debug_player_use.GetBool() )
{
Msg( "Ground query found usable entity: %s, distance: %.2f\n", pNearest->GetDebugName(), sqrt( nearestDistSquared ) );
}
}

Vector dir = point - searchCenter;
VectorNormalize(dir);
float dot = DotProduct( dir, forward );
// Next, determine which of the reachable and usable objects in the cone
// volume directly in front of player is closest, and whether or not any
// is closer than the ground entity.
for ( CEntitySphereQuery sphere( searchCenter, PLAYER_USE_RADIUS ); ( pObject = sphere.GetCurrentEntity() ) != NULL; sphere.NextEntity() )
{
if ( !IsUseableEntity( pObject, 0 ) )
continue;

// Need to be looking at the object more or less
if ( dot < 0.8 )
continue;
// Determine if the object is nearer than the previous nearest object.
Vector nearestPoint;
pObject->CollisionProp()->CalcNearestPoint( searchCenter, &nearestPoint );

float dist = CalcDistanceToLine( point, searchCenter, forward );
Vector dir = nearestPoint - searchCenter;
VectorNormalize(dir);

if ( sv_debug_player_use.GetBool() )
{
Msg("Radius found %s, dist %.2f\n", pObject->GetClassname(), dist );
}
// Need to be looking at the object more or less.
// NOTE: If the closest point on the object happens to be off to the
// side, even though the object is predominantly if front of the player,
// then it will be rejected, unfortunately.
if ( DotProduct( dir, forward ) < 0.8 )
continue;

if ( dist < nearestDist )
{
// Since this has purely been a radius search to this point, we now
// make sure the object isn't behind glass or a grate.
trace_t trCheckOccluded;
UTIL_TraceLine( searchCenter, point, useableContents, this, COLLISION_GROUP_NONE, &trCheckOccluded );
const float distSquared = (nearestPoint - searchCenter).LengthSqr();

if ( trCheckOccluded.fraction == 1.0 || trCheckOccluded.m_pEnt == pObject )
if ( sv_debug_player_use.GetBool() )
{
pNearest = pObject;
nearestDist = dist;
Msg( "Cone query found usable entity: %s, distance: %.2f\n", pObject->GetDebugName(), sqrt( distSquared ) );
}

if ( distSquared < nearestDistSquared )
{
// The object is inside the cone, but it may be blocked by another
// object. Verify that we can trace to the object directly.

// NOTE: this traces to a particular point on the object's collision
// prop. If the trace to that point happens to be blocked by another
// object, even though other nearby visible points aren't, then we
// won't be able to +use the object, unfortunately.

// We ignore clip brushes here so that objects in or behind clip
// brushes can be +used. If the current object itself is a usable
// clip brush, this trace will fail to hit it, but unless it is
// blocked, the trace fraction will typically be 1.0 anyway, and
// pNearest will be set to the usable clip brush object.
trace_t tr;
UTIL_TraceLine( searchCenter, nearestPoint, usableContentsIgnoreClip, this, COLLISION_GROUP_NONE, &tr );

if ( tr.fraction == 1.0 || tr.m_pEnt == pObject )
{
pNearest = pObject;
nearestDistSquared = distSquared;
}
}
}

}

#ifndef CLIENT_DLL
if ( !pNearest )
{
// Haven't found anything near the player to use, nor any NPC's at distance.
// Check to see if the player is trying to select an NPC through a rail, fence, or other 'see-though' volume.
trace_t trAllies;
UTIL_TraceLine( searchCenter, searchCenter + forward * PLAYER_USE_RADIUS, MASK_OPAQUE_AND_NPCS, this, COLLISION_GROUP_NONE, &trAllies );
// If we haven't found an object that the player can use yet,
// allow a player to use an NPC through 'see-through' volumes
// (rails, fenches, windows, grates, etc.).
UTIL_TraceLine( searchCenter, searchCenter + PLAYER_USE_RADIUS * forward, MASK_OPAQUE_AND_NPCS, this, COLLISION_GROUP_NONE, &directTrace );
pObject = directTrace.m_pEnt;

if ( trAllies.m_pEnt && IsUseableEntity( trAllies.m_pEnt, 0 ) && trAllies.m_pEnt->MyNPCPointer() && trAllies.m_pEnt->MyNPCPointer()->IsPlayerAlly( this ) )
if ( pObject && IsUseableEntity( pObject, 0 ) && pObject->MyNPCPointer() && pObject->MyNPCPointer()->IsPlayerAlly( this ) )
{
// This is an NPC, take it!
pNearest = trAllies.m_pEnt;
pNearest = pObject;

if ( sv_debug_player_use.GetBool() )
{
const float distSquared = EstimatedDistanceSquared( searchCenter, pNearest );
Msg( "Line trace found usable entity: %s, distance: %.2f\n", pNearest->GetDebugName(), sqrt( distSquared ) );
}
}
}

if ( pNearest && pNearest->MyNPCPointer() && pNearest->MyNPCPointer()->IsPlayerAlly( this ) )
if ( pNearest == directTrace.m_pEnt && pNearest && pNearest->MyNPCPointer() && pNearest->MyNPCPointer()->IsPlayerAlly( this ) )
{
pNearest = DoubleCheckUseNPC( pNearest, searchCenter, forward );
// If about to select an NPC with a line trace, do a more thorough
// check to ensure that we're selecting the right one from a group.
// Lengthen trace slightly to account for the fact that we're
// tracing for hitboxes, which are usually farther away than OBBs.
trace_t tr;
UTIL_TraceLine( searchCenter, searchCenter + 1.1 * PLAYER_USE_RADIUS * forward, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
pObject = tr.m_pEnt;

if ( pObject != pNearest && pObject && pObject->MyNPCPointer() && pObject->MyNPCPointer()->IsPlayerAlly( this ) )
{
// Player is selecting a different NPC through some negative space
// in the first NPC's hitboxes (between legs, over shoulder, etc).
pNearest = tr.m_pEnt;
directTrace = tr;

if ( sv_debug_player_use.GetBool() )
{
const float distSquared = EstimatedDistanceSquared( searchCenter, pNearest );
Msg( "Hitbox line trace found usable entity: %s, distance: %.2f\n", pNearest->GetDebugName(), sqrt( distSquared ) );
}
}
}
#endif

// Draw debug overlays and print debug messages.
if ( sv_debug_player_use.GetBool() )
{
#ifndef CLIENT_DLL
if ( !pNearest )
{
NDebugOverlay::Line( searchCenter, tr.endpos, 255, 0, 0, true, 30 );
NDebugOverlay::Cross3D( tr.endpos, 16, 255, 0, 0, true, 30 );
NDebugOverlay::Line( searchCenter, directTrace.endpos, 255, 0, 0, true, 30 );
NDebugOverlay::Cross3D( directTrace.endpos, 16, 255, 0, 0, true, 30 );
}
else if ( pNearest == pFoundByTrace )
else if ( pNearest == directTrace.m_pEnt )
{
NDebugOverlay::Line( searchCenter, tr.endpos, 0, 255, 0, true, 30 );
NDebugOverlay::Cross3D( tr.endpos, 16, 0, 255, 0, true, 30 );
NDebugOverlay::Line( searchCenter, directTrace.endpos, 0, 255, 0, true, 30 );
NDebugOverlay::Cross3D( directTrace.endpos, 16, 0, 255, 0, true, 30 );
}
else
{
NDebugOverlay::Box( pNearest->WorldSpaceCenter(), Vector(-8, -8, -8), Vector(8, 8, 8), 0, 255, 0, true, 30 );
}
}
#endif

if ( sv_debug_player_use.GetBool() )
{
Msg( "Radial using: %s\n", pNearest ? pNearest->GetDebugName() : "no usable entity found" );
Msg( "Using: %s\n", pNearest ? pNearest->GetDebugName() : "no usable entity found" );
}

return pNearest;
Expand Down Expand Up @@ -1302,7 +1315,7 @@ void CBasePlayer::PlayerUse ( void )
EyeVectors( &forward, NULL, &up );

trace_t tr;
// Search for objects in a sphere (tests for entities that are not solid, yet still useable)
// Search for objects in a sphere (tests for entities that are not solid, yet still usable)
Vector searchCenter = EyePosition();

CUsePushFilter filter;
Expand Down Expand Up @@ -2085,4 +2098,3 @@ bool fogparams_t::operator !=( const fogparams_t& other ) const

return false;
}

Binary file modified sp/src/lib/public/mathlib.lib
Binary file not shown.
Binary file modified sp/src/lib/public/raytrace.lib
Binary file not shown.
Binary file modified sp/src/lib/public/tier1.lib
Binary file not shown.
Binary file modified sp/src/lib/public/vgui_controls.lib
Binary file not shown.
2 changes: 1 addition & 1 deletion sp/src/public/mathlib/mathlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,7 @@ void BuildGammaTable( float gamma, float texGamma, float brightness, int overbri
// convert texture to linear 0..1 value
inline float TexLightToLinear( int c, int exponent )
{
extern float power2_n[256];
extern ALIGN128 float power2_n[256];
Assert( exponent >= -128 && exponent <= 127 );
return ( float )c * power2_n[exponent+128];
}
Expand Down
Loading

0 comments on commit 3b26616

Please sign in to comment.