diff --git game/Player.h game/Player.h
index a51a589..b4f2fd5 100644
--- game/Player.h
+++ game/Player.h
@@ -825,6 +825,8 @@ public:
 
 	void					UpdateSkinSetup( bool restart );
 
+	bool					IsShoulderingBody( void ) { return m_bShoulderingBody; };
+
 	bool					OnLadder( void ) const;
 	// Virtal override of idActor::OnElevator()
 	virtual CMultiStateMover* OnElevator(bool mustBeMoving) const;
diff --git game/gamesys/SysCvar.cpp game/gamesys/SysCvar.cpp
index 0bc7994..0ce51c2 100644
--- game/gamesys/SysCvar.cpp
+++ game/gamesys/SysCvar.cpp
@@ -226,6 +226,7 @@ idCVar cv_pm_mantle_pushNonCrouched_msecs("pm_mantle_pushNonCrouched_msecs","550
 idCVar cv_pm_mantle_pushNonCrouched_playgrunt_speedthreshold("pm_mantle_pushNonCrouched_playgrunt_speedthreshold", "120.0", CVAR_GAME | CVAR_FLOAT, "If the player speed exceeds this threshold, a grund sound is played when performing the mantle.", 0.0f, 100000.0f);
 idCVar cv_pm_mantle_fastLowObstaces("pm_mantle_fastLowObstacles", "1", CVAR_GAME | CVAR_BOOL, "If true, a faster mantle will be performed for low obstacles.", 0, 1);
 idCVar cv_pm_mantle_maxLowObstacleHeight("pm_mantle_maxLowObstacleHeight", "36.0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "The maximum height of obstacles over which a fast mantle can be performed", 0.0f, 60.0f);
+idCVar cv_pm_mantle_maxShoulderingObstacleHeight("pm_mantle_maxShoulderingObstacleHeight", "41.0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "The maximum height of obstacles allowed for a shouldering body mantle", 0.0f, 60.0f);
 idCVar cv_pm_mantle_fastMediumObstaclesCrouched("pm_mantle_fastMediumObstaclesCrouched", "1", CVAR_GAME | CVAR_BOOL, "If true, a faster mantle will be performed for medium-high obstacles in crouched state", 0, 1);
 idCVar cv_pm_mantle_pullFast_msecs("pm_mantle_pullFast_msecs", "450.0", CVAR_GAME | CVAR_INTEGER |CVAR_ARCHIVE, "The duration it takes for a fast pull.", 0, 10000);
 idCVar cv_pm_mantle_fallingFast_speedthreshold("pm_mantle_fallingFast_speedthreshold", "360.0", CVAR_GAME | CVAR_FLOAT, "If falling faster than this threshold, no fast mantles will be performed.", 0.0f, 100000.0f);
diff --git game/gamesys/SysCvar.h game/gamesys/SysCvar.h
index 0d558ff..74b9b6c 100644
--- game/gamesys/SysCvar.h
+++ game/gamesys/SysCvar.h
@@ -181,6 +181,7 @@ extern idCVar cv_pm_mantle_push_msecs;
 extern idCVar cv_pm_mantle_pushNonCrouched_msecs;
 extern idCVar cv_pm_mantle_fastLowObstaces;
 extern idCVar cv_pm_mantle_maxLowObstacleHeight;
+extern idCVar cv_pm_mantle_maxShoulderingObstacleHeight;
 extern idCVar cv_pm_mantle_fastMediumObstaclesCrouched;
 extern idCVar cv_pm_mantle_pullFast_msecs;
 extern idCVar cv_pm_mantle_pushNonCrouched_playgrunt_speedthreshold;
diff --git game/physics/Physics_Player.cpp game/physics/Physics_Player.cpp
index e610f28..d1cfabf 100644
--- game/physics/Physics_Player.cpp
+++ game/physics/Physics_Player.cpp
@@ -5107,9 +5107,41 @@ void idPhysics_Player::PerformMantle()
 			}
 			const float eyeHeight = -eyePos * gravityNormal;
 
-			const bool bFallingFast = 
-				(current.velocity * gravityNormal) > 
-				cv_pm_mantle_fallingFast_speedthreshold.GetFloat();
+			const float fallingSpeed = current.velocity * gravityNormal;
+			const bool bFallingFast = fallingSpeed > cv_pm_mantle_fallingFast_speedthreshold.GetFloat();
+
+			const bool bIsCrouched = current.movementFlags & PMF_DUCKED;
+			const bool bIsShoulderingBody = static_cast<idPlayer*>(self)->IsShoulderingBody();
+
+			// #5892: While shouldering a body, allow mantling at roughly waist height.
+			if (bIsShoulderingBody)
+			{
+				const float obstacleHeight = mantleEndHeight - floorHeight;
+
+				// While crouched, the max allowed shouldering mantle
+				// height is a bit less than while standing.
+				// Two reasons: animation and challenge.
+				const float maxShoulderingMantleHeight = bIsCrouched ?
+					cv_pm_mantle_maxShoulderingObstacleHeight.GetFloat() - 5 :
+					cv_pm_mantle_maxShoulderingObstacleHeight.GetFloat();
+
+				// Must only be push or pushNonCrouched mantle phase.
+				// Note: Check to make sure that's the case in the mantle
+				// phase conditionals below, especially when editing them.
+
+				// Must mantle at roughly waist height.
+				if (obstacleHeight > maxShoulderingMantleHeight)
+					return;
+				// Must be standing on the ground (or not falling from a jump-mantle).
+				// In other words, don't be going downwards.
+				//   "groundPlane" only works with dedicated mantle key.
+				//   When the jump key is used to mantle, the player lifts
+				//   ever so slightly off the ground before a mantle is
+				//   detected. Using "fallingSpeed" here as an alternative
+				//   way to ensure the player is approximately grounded.
+				if (!groundPlane && fallingSpeed > 0)
+					return;
+			}
 
 			if (cv_pm_mantle_fastLowObstaces.GetBool()) // STiFU #4930
 			{
@@ -5127,9 +5159,8 @@ void idPhysics_Player::PerformMantle()
 			if (cv_pm_mantle_fastMediumObstaclesCrouched.GetBool()) // STiFU #4945
 			{
 				// Use floorHeight instead of feetHeight to allow this mantle also when jump-mantling medium sized obstacles
-				const bool bIsCrouched = current.movementFlags & PMF_DUCKED;
-
 				if (   bIsCrouched
+					&& !bIsShoulderingBody // #5892
 					&& !bFallingFast
 					&& eyeHeight < mantleEndHeight // When endheight lower than eyes, use the regular push mantle
 					&& mantleEndHeight < floorHeight + pm_normalviewheight.GetFloat())
@@ -5139,7 +5170,7 @@ void idPhysics_Player::PerformMantle()
 					return;
 				}
 			}
-			if (eyeHeight < mantleEndHeight)
+			if (eyeHeight < mantleEndHeight && !bIsShoulderingBody) // #5892
 			{
 				// Start with pull if on the ground, hang if not
 				if (groundPlane)
