@@ -5721,14 +5721,19 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
57215721 CBaseEntity *pInflictor = dmgInfo->GetInflictor();
57225722
57235723 // Check that the explosion can 'see' this entity.
5724- Vector vecSpot = pEntity->BodyTarget( vecSrc, false );
5724+ std::vector<Vector> vecSpots{ pEntity->EyePosition() };
5725+ static const float flInnerRadiusPct = 0.05f;
57255726 CTraceFilterIgnorePlayers filterPlayers( pInflictor, COLLISION_GROUP_PROJECTILE );
57265727 CTraceFilterIgnoreProjectiles filterProjectiles( pInflictor, COLLISION_GROUP_PROJECTILE );
57275728 CTraceFilterIgnoreFriendlyCombatItems filterCombatItems( pInflictor, COLLISION_GROUP_PROJECTILE, pInflictor->GetTeamNumber() );
57285729 CTraceFilterChain filterPlayersAndProjectiles( &filterPlayers, &filterProjectiles );
57295730 CTraceFilterChain filter( &filterPlayersAndProjectiles, &filterCombatItems );
5731+ Vector vecOffset;
5732+ int totalChecks = 1;
5733+ int passedChecks = 0;
5734+ Vector vecMainSpot = pEntity->BodyTarget(vecSrc, false);
5735+ UTIL_TraceLine(vecSrc, vecMainSpot, MASK_RADIUS_DAMAGE, &filter, &tr);
57305736
5731- UTIL_TraceLine( vecSrc, vecSpot, MASK_RADIUS_DAMAGE, &filter, &tr );
57325737 if ( tr.startsolid && tr.m_pEnt )
57335738 {
57345739 // Return when inside an enemy combat shield and tracing against a player of that team ("absorbed")
@@ -5737,14 +5742,48 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
57375742
57385743 filterPlayers.SetPassEntity( tr.m_pEnt );
57395744 CTraceFilterChain filterSelf( &filterPlayers, &filterCombatItems );
5740- UTIL_TraceLine( vecSrc, vecSpot , MASK_RADIUS_DAMAGE, &filterSelf, &tr );
5745+ UTIL_TraceLine( vecSrc, vecMainSpot , MASK_RADIUS_DAMAGE, &filterSelf, &tr );
57415746 }
57425747
5743- // If we don't trace the whole way to the target, and we didn't hit the target entity, we're blocked
5748+ // If we don't trace the whole way to the target, and we didn't hit the target entity, we're blocked, so do a more robust check
57445749 if ( tr.fraction != 1.f && tr.m_pEnt != pEntity )
57455750 {
5746- // Don't let projectiles block damage
5747- return 0;
5751+ for (int x = -1; x <= 1; x += 2)
5752+ {
5753+ vecOffset.x = x * flInnerRadiusPct;
5754+ for (int y = -1; y <= 1; y += 2)
5755+ {
5756+ vecOffset.y = y * flInnerRadiusPct;
5757+ for (int z = -1; z <= 1; z += 2)
5758+ {
5759+ vecOffset.z = z * flInnerRadiusPct;
5760+ for (auto& vecSpot : vecSpots)
5761+ {
5762+ UTIL_TraceLine(vecSrc + vecOffset, vecSpot, MASK_RADIUS_DAMAGE, &filter, &tr);
5763+ if (tr.startsolid && tr.m_pEnt)
5764+ {
5765+ // Return when inside an enemy combat shield and tracing against a player of that team ("absorbed")
5766+ if (tr.m_pEnt->IsCombatItem() && pEntity->InSameTeam(tr.m_pEnt) && (pEntity != tr.m_pEnt))
5767+ return 0;
5768+
5769+ filterPlayers.SetPassEntity(tr.m_pEnt);
5770+ CTraceFilterChain filterSelf(&filterPlayers, &filterCombatItems);
5771+ UTIL_TraceLine(vecSrc + vecOffset, vecSpot, MASK_RADIUS_DAMAGE, &filterSelf, &tr);
5772+ }
5773+
5774+ totalChecks++;
5775+ // If we don't trace the whole way to the target, and we didn't hit the target entity, we're blocked
5776+ if (tr.fraction != 1.0 && tr.m_pEnt != pEntity)
5777+ return 0;
5778+ passedChecks++;
5779+ }
5780+ }
5781+ }
5782+ }
5783+ }
5784+ else
5785+ {
5786+ passedChecks++;
57485787 }
57495788
57505789 // Adjust the damage - apply falloff.
@@ -5788,6 +5827,9 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
57885827 }
57895828 }
57905829
5830+ // As a compromise, reduce the damage if we only did it on a robust check
5831+ flAdjustedDamage *= passedChecks / (float)totalChecks;
5832+
57915833 // If we end up doing 0 damage, exit now.
57925834 if ( flAdjustedDamage <= 0.f )
57935835 return 0;
@@ -5803,7 +5845,7 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
58035845 CTakeDamageInfo adjustedInfo = *dmgInfo;
58045846 adjustedInfo.SetDamage( flAdjustedDamage );
58055847
5806- Vector dir = vecSpot - vecSrc;
5848+ Vector dir = vecMainSpot - vecSrc;
58075849 VectorNormalize( dir );
58085850
58095851 // If we don't have a damage force, manufacture one
0 commit comments