Skip to content
Open
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
72 changes: 70 additions & 2 deletions src/game/shared/tf/tf_gamerules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5752,6 +5752,8 @@ void CTFRadiusDamageInfo::CalculateFalloff( void )
//-----------------------------------------------------------------------------
// Purpose: Attempt to apply the radius damage to the specified entity
//-----------------------------------------------------------------------------
ConVar tf_radiusdamage_los_simple( "tf_radiusdamage_los_simple", "0", FCVAR_NONE, "Use simpler line-of-sight checks for radius damage" );
ConVar tf_radiusdamage_los_debug( "tf_radiusdamage_los_debug", "0", FCVAR_CHEAT );
int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
{
if ( pEntity == pEntityIgnore || pEntity->m_takedamage == DAMAGE_NO )
Expand Down Expand Up @@ -5780,11 +5782,77 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
UTIL_TraceLine( vecSrc, vecSpot, MASK_RADIUS_DAMAGE, &filterSelf, &tr );
}

bool bDebugLoS = tf_radiusdamage_los_debug.GetBool() && ( pEntity->IsPlayer() || tf_radiusdamage_los_debug.GetInt() == 2 );

if ( bDebugLoS )
{
NDebugOverlay::Line( tr.startpos, tr.endpos, 255, 0, 0, true, 3 );
NDebugOverlay::Line( tr.endpos, vecSpot, 96, 0, 0, true, 3 );
}

// If we don't trace the whole way to the target, and we didn't hit the target entity, we're blocked
if ( tr.fraction != 1.f && tr.m_pEnt != pEntity )
{
// Don't let projectiles block damage
return 0;
if ( tf_radiusdamage_los_simple.GetBool() )
return 0;

if ( pEntity == dmgInfo->GetAttacker() )
return 0;

if ( tr.startsolid )
return 0;

// explosions can get blocked by bits of ground geometry such as stair steps, which is frustrating for players
// so when the initial LoS-check fails, let's try to find a raised position to perform a second LoS-check from

float flStepHeight = 18.f;

Vector vecStartPos = tr.endpos;
Vector vecTarget = vecStartPos;
vecTarget.z -= flStepHeight;

// trace down to find walkable ground
trace_t trStep;
UTIL_TraceLine( vecStartPos, vecTarget, MASK_RADIUS_DAMAGE, &filter, &trStep );

if ( bDebugLoS )
{
NDebugOverlay::Line( trStep.startpos, trStep.endpos, 0, 128, 255, true, 3 );
}

if ( trStep.fraction == 1.f || trStep.plane.normal.z < 0.7 )
// don't splash if we can't find walkable ground
// this stops Soldiers from splashing high-ground targets by shooting at the edge of the ledge from below
return 0;

if ( trStep.endpos.z > vecSpot.z )
// this is higher than the target's position
return 0;

vecStartPos = trStep.endpos;
vecTarget = vecStartPos;
vecTarget.z += flStepHeight;

// trace up from the floor to simulate step up
UTIL_TraceLine( vecStartPos, vecTarget, MASK_RADIUS_DAMAGE, &filter, &trStep );

if ( bDebugLoS )
{
NDebugOverlay::Line( trStep.startpos, trStep.endpos, 0, 255, 255, true, 3 );
}

// check if explosion can see target from this raised position
UTIL_TraceLine( trStep.endpos, vecSpot, MASK_RADIUS_DAMAGE, &filter, &trStep );

if ( bDebugLoS )
{
NDebugOverlay::Line( trStep.startpos, trStep.endpos, 0, 255, 0, true, 3 );
NDebugOverlay::Line( trStep.endpos, vecSpot, 0, 96, 0, true, 3 );
}

if ( trStep.startsolid || trStep.fraction != 1.f && trStep.m_pEnt != pEntity )
// target is still blocked
return 0;
}

// Adjust the damage - apply falloff.
Expand Down