diff --git a/src/game/shared/hl2mp/weapon_frag.cpp b/src/game/shared/hl2mp/weapon_frag.cpp index 8f4b7b001..022d9ca10 100644 --- a/src/game/shared/hl2mp/weapon_frag.cpp +++ b/src/game/shared/hl2mp/weapon_frag.cpp @@ -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; } -