Fix grenade corner clipping

► Fixed an issue where grenades could clip through walls when rolled into corners.
This commit is contained in:
speedvoltage 2025-03-10 21:28:46 +01:00
parent a62efecf62
commit c59b640085

View file

@ -74,7 +74,7 @@ private:
void RollGrenade( CBasePlayer *pPlayer );
void LobGrenade( CBasePlayer *pPlayer );
// check a throw from vecSrc. If not valid, move the position back along the line to vecEye
void CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc );
void CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc, const QAngle &angles = vec3_angle );
CNetworkVar( bool, m_bRedraw ); //Draw the weapon again after throwing a grenade
@ -392,13 +392,19 @@ void CWeaponFrag::ItemPostFrame( void )
}
// check a throw from vecSrc. If not valid, move the position back along the line to vecEye
void CWeaponFrag::CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc )
void CWeaponFrag::CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc, const QAngle &angles )
{
// Compute an extended AABB that takes into account the requested grenade rotation.
// This will prevent grenade from going through nearby solids when model initially intersects with any.
matrix3x4_t rotation;
AngleMatrix( angles, rotation );
Vector mins, maxs;
RotateAABB( rotation, -Vector( GRENADE_RADIUS + 2, GRENADE_RADIUS + 2, 2 ), Vector( GRENADE_RADIUS + 2, GRENADE_RADIUS + 2, GRENADE_RADIUS * 2 + 2 ), mins, maxs );
trace_t tr;
UTIL_TraceHull( vecEye, vecSrc, -Vector(GRENADE_RADIUS+2,GRENADE_RADIUS+2,GRENADE_RADIUS+2), Vector(GRENADE_RADIUS+2,GRENADE_RADIUS+2,GRENADE_RADIUS+2),
pPlayer->PhysicsSolidMaskForEntity(), pPlayer, pPlayer->GetCollisionGroup(), &tr );
UTIL_TraceHull( vecEye, vecSrc, mins, maxs, pPlayer->PhysicsSolidMaskForEntity(), pPlayer, pPlayer->GetCollisionGroup(), &tr );
if ( tr.DidHit() )
{
vecSrc = tr.endpos;
@ -527,7 +533,6 @@ void CWeaponFrag::RollGrenade( CBasePlayer *pPlayer )
CrossProduct( tr.plane.normal, tangent, vecFacing );
}
vecSrc += (vecFacing * 18.0);
CheckThrowPosition( pPlayer, pPlayer->WorldSpaceCenter(), vecSrc );
Vector vecThrow;
pPlayer->GetVelocity( &vecThrow, NULL );
@ -536,6 +541,7 @@ void CWeaponFrag::RollGrenade( CBasePlayer *pPlayer )
QAngle orientation(0,pPlayer->GetLocalAngles().y,-90);
// roll it
AngularImpulse rotSpeed(0,0,720);
CheckThrowPosition( pPlayer, pPlayer->WorldSpaceCenter(), vecSrc, orientation );
CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, orientation, vecThrow, rotSpeed, pPlayer, GRENADE_TIMER, false );
if ( pGrenade )
@ -553,4 +559,3 @@ void CWeaponFrag::RollGrenade( CBasePlayer *pPlayer )
m_bRedraw = true;
}