From b83a53bfdc5e58394852559509ca5a23ecca9abc Mon Sep 17 00:00:00 2001 From: HyperionCoding Date: Sun, 21 Sep 2025 20:14:53 +0300 Subject: [PATCH] Allow weapons with penetrate attribute to penetrate Medigun shield --- src/game/shared/tf/tf_player_shared.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/game/shared/tf/tf_player_shared.cpp b/src/game/shared/tf/tf_player_shared.cpp index abe67cf9c09..2f4597ba259 100644 --- a/src/game/shared/tf/tf_player_shared.cpp +++ b/src/game/shared/tf/tf_player_shared.cpp @@ -9937,7 +9937,8 @@ class CBulletPenetrateEnum : public IEntityEnumerator if ( pEnt == m_pShooter ) return true; - if ( pEnt->IsCombatCharacter() || pEnt->IsBaseObject() ) + CTFMedigunShield *pMedigunShield = dynamic_cast( pEnt ); + if ( pEnt->IsCombatCharacter() || pEnt->IsBaseObject() || pMedigunShield ) { if ( m_bIgnoreTeammates && pEnt->GetTeam() == m_pShooter->GetTeam() ) return true; @@ -10203,7 +10204,8 @@ void CTFPlayer::FireBullet( CTFWeaponBase *pWpn, const FireBulletsInfo_t &info, bool bPenetratingShot = ( (ePenetrateType == TF_DMG_CUSTOM_PENETRATE_ALL_PLAYERS) || (ePenetrateType == TF_DMG_CUSTOM_PENETRATE_MY_TEAM) || (ePenetrateType == TF_DMG_CUSTOM_PENETRATE_NONBURNING_TEAMMATE) ); if ( bPenetratingShot && trace.m_pEnt ) { - if ( trace.m_pEnt->IsCombatCharacter() || trace.m_pEnt->IsBaseObject() ) + CTFMedigunShield *pMedigunShield = dynamic_cast( trace.m_pEnt ); + if ( trace.m_pEnt->IsCombatCharacter() || trace.m_pEnt->IsBaseObject() || pMedigunShield ) { const float penetrationHullExtension = 40.0f; // Josh: EnumerateEntities only collides with bboxes, extend the ray to a larger hull, then we clip to it. @@ -10319,6 +10321,7 @@ void CTFPlayer::FireBullet( CTFWeaponBase *pWpn, const FireBulletsInfo_t &info, dmgInfo.SetPlayerPenetrationCount( iPenetratedPlayerCount ); pTarget->DispatchTraceAttack( dmgInfo, info.m_vecDirShooting, pTraceToUse, GetActiveWeapon() ? GetActiveWeapon()->GetDmgAccumulator() : NULL ); + CTFMedigunShield* pMedigunShield = dynamic_cast( pTarget ); const bool bIsPenetratingPlayer = pTargetPlayer != NULL; if ( bIsPenetratingPlayer ) { @@ -10327,9 +10330,23 @@ void CTFPlayer::FireBullet( CTFWeaponBase *pWpn, const FireBulletsInfo_t &info, CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pWpn, flPenetrationPenalty, penetration_damage_penalty ); dmgInfo.SetDamage( dmgInfo.GetDamage() * flPenetrationPenalty ); } + else if ( pMedigunShield ) + { + CBaseEntity *pTFOwner = pMedigunShield->GetOwnerEntity(); + if ( pTFOwner ) + { + int nShieldLevel = 0; + CALL_ATTRIB_HOOK_INT_ON_OTHER( pTFOwner, nShieldLevel, generate_rage_on_heal ); + iPenetratedPlayerCount += nShieldLevel; + + // Treat shield level 4 and higher inpenetrable, even by Sniper rifles + if ( nShieldLevel >= 4 ) + break; + } + } - // If we're only supposed to penetrate players and this thing isn't a player, stop here. - if ( !bIsPenetratingPlayer && (ePenetrateType == TF_DMG_CUSTOM_PENETRATE_ALL_PLAYERS) ) + // If we're only supposed to penetrate players and this thing isn't a player or medigun shield, stop here. + if ( !bIsPenetratingPlayer && (ePenetrateType == TF_DMG_CUSTOM_PENETRATE_ALL_PLAYERS) && !pMedigunShield ) break; } else