@@ -5476,12 +5476,17 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
54765476 CBaseEntity *pInflictor = dmgInfo->GetInflictor();
54775477
54785478 // Check that the explosion can 'see' this entity.
5479- Vector vecSpot = pEntity->BodyTarget( vecSrc, false );
5479+ //std::vector<Vector> vecSpots{pEntity->EyePosition(), pEntity->WorldSpaceCenter(), pEntity->GetAbsOrigin()};
5480+ std::vector<Vector> vecSpots{pEntity->EyePosition()};
5481+ static const float flInnerRadiusPct = 0.05f;
54805482 CTraceFilterIgnorePlayers filterPlayers( pInflictor, COLLISION_GROUP_PROJECTILE );
54815483 CTraceFilterIgnoreFriendlyCombatItems filterCombatItems( pInflictor, COLLISION_GROUP_PROJECTILE, pInflictor->GetTeamNumber() );
54825484 CTraceFilterChain filter( &filterPlayers, &filterCombatItems );
5483-
5484- UTIL_TraceLine( vecSrc, vecSpot, MASK_RADIUS_DAMAGE, &filter, &tr );
5485+ Vector vecOffset;
5486+ int totalChecks = 1;
5487+ int passedChecks = 0;
5488+ Vector vecMainSpot = pEntity->BodyTarget(vecSrc, false);
5489+ UTIL_TraceLine( vecSrc, vecMainSpot, MASK_RADIUS_DAMAGE, &filter, &tr );
54855490 if ( tr.startsolid && tr.m_pEnt )
54865491 {
54875492 // Return when inside an enemy combat shield and tracing against a player of that team ("absorbed")
@@ -5490,12 +5495,48 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
54905495
54915496 filterPlayers.SetPassEntity( tr.m_pEnt );
54925497 CTraceFilterChain filterSelf( &filterPlayers, &filterCombatItems );
5493- UTIL_TraceLine( vecSrc, vecSpot , MASK_RADIUS_DAMAGE, &filterSelf, &tr );
5498+ UTIL_TraceLine( vecSrc, vecMainSpot , MASK_RADIUS_DAMAGE, &filterSelf, &tr );
54945499 }
5495-
5496- // If we don't trace the whole way to the target, and we didn't hit the target entity, we're blocked
5500+ // 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
54975501 if ( tr.fraction != 1.0 && tr.m_pEnt != pEntity )
5498- return 0;
5502+ {
5503+ for (int x = -1; x <= 1; x += 2)
5504+ {
5505+ vecOffset.x = x * flInnerRadiusPct;
5506+ for (int y = -1; y <= 1; y += 2)
5507+ {
5508+ vecOffset.y = y * flInnerRadiusPct;
5509+ for (int z = -1; z <= 1; z += 2)
5510+ {
5511+ vecOffset.z = z * flInnerRadiusPct;
5512+ for ( auto& vecSpot : vecSpots )
5513+ {
5514+ UTIL_TraceLine( vecSrc + vecOffset, vecSpot, MASK_RADIUS_DAMAGE, &filter, &tr );
5515+ if ( tr.startsolid && tr.m_pEnt )
5516+ {
5517+ // Return when inside an enemy combat shield and tracing against a player of that team ("absorbed")
5518+ if ( tr.m_pEnt->IsCombatItem() && pEntity->InSameTeam( tr.m_pEnt ) && ( pEntity != tr.m_pEnt ) )
5519+ return 0;
5520+
5521+ filterPlayers.SetPassEntity( tr.m_pEnt );
5522+ CTraceFilterChain filterSelf( &filterPlayers, &filterCombatItems );
5523+ UTIL_TraceLine( vecSrc + vecOffset, vecSpot, MASK_RADIUS_DAMAGE, &filterSelf, &tr );
5524+ }
5525+
5526+ totalChecks++;
5527+ // If we don't trace the whole way to the target, and we didn't hit the target entity, we're blocked
5528+ if ( tr.fraction != 1.0 && tr.m_pEnt != pEntity )
5529+ return 0;
5530+ passedChecks++;
5531+ }
5532+ }
5533+ }
5534+ }
5535+ }
5536+ else
5537+ {
5538+ passedChecks++;
5539+ }
54995540
55005541 // Adjust the damage - apply falloff.
55015542 float flAdjustedDamage = 0.0f;
@@ -5538,6 +5579,9 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
55385579 }
55395580 }
55405581
5582+ // As a compromise, reduce the damage if we only did it on a robust check
5583+ flAdjustedDamage *= passedChecks / (float) totalChecks;
5584+
55415585 // If we end up doing 0 damage, exit now.
55425586 if ( flAdjustedDamage <= 0 )
55435587 return 0;
@@ -5553,7 +5597,7 @@ int CTFRadiusDamageInfo::ApplyToEntity( CBaseEntity *pEntity )
55535597 CTakeDamageInfo adjustedInfo = *dmgInfo;
55545598 adjustedInfo.SetDamage( flAdjustedDamage );
55555599
5556- Vector dir = vecSpot - vecSrc;
5600+ Vector dir = vecMainSpot - vecSrc;
55575601 VectorNormalize( dir );
55585602
55595603 // If we don't have a damage force, manufacture one
@@ -6147,7 +6191,7 @@ bool CTFGameRules::ApplyOnDamageModifyRules( CTakeDamageInfo &info, CBaseEntity
61476191 // Use defense buffs if it's not a backstab or direct crush damage (telefrage, etc.)
61486192 if ( pVictim && info.GetDamageCustom() != TF_DMG_CUSTOM_BACKSTAB && ( info.GetDamageType() & DMG_CRUSH ) == 0 )
61496193 {
6150- if ( pVictim->m_Shared.InCond( TF_COND_DEFENSEBUFF ) )
6194+ if ( !iPierceResists && pVictim->m_Shared.InCond( TF_COND_DEFENSEBUFF ) )
61516195 {
61526196 // We take no crits of any kind...
61536197 if( eBonusEffect == kBonusEffect_MiniCrit || eBonusEffect == kBonusEffect_Crit )
@@ -16437,7 +16481,7 @@ bool CTFGameRules::PlayerMayBlockPoint( CBasePlayer *pPlayer, int iPointIndex, c
1643716481#endif
1643816482
1643916483 // Invuln players can block points
16440- if ( pTFPlayer->m_Shared.IsInvulnerable() )
16484+ if ( pTFPlayer->m_Shared.IsInvulnerable() || pTFPlayer->m_Shared.InCond( TF_COND_MEGAHEAL ) )
1644116485 {
1644216486 if ( pszReason )
1644316487 {
0 commit comments