diff --git a/src/p_slopes.c b/src/p_slopes.c
index 7f070e2a1793b4d02a44fefa374f4a887a8da4a1..37244e021b2aaf7e34c14f6a3bc456963cc0792f 100644
--- a/src/p_slopes.c
+++ b/src/p_slopes.c
@@ -1046,15 +1046,37 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope)
 {
 	vector3_t slopemom, axis;
 	angle_t ang;
+	angle_t advanceAng = ANG15;
+	const boolean upwards = (slope->zangle < ANGLE_180);
 
 	if (slope->flags & SL_NOPHYSICS)
 		return 0;
 
 	// If there's physics, time for launching.
 	// Doesn't kill the vertical momentum as much as P_SlopeLaunch does.
-	ang = slope->zangle + ANG15*((slope->zangle > 0) ? 1 : -1);
-	if (ang > ANGLE_90 && ang < ANGLE_180)
-		ang = ((slope->zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards
+	ang = slope->zangle;
+
+	// for the time being, let's pretend the slope inclines upwards only
+	if (!upwards)
+	{
+		ang += ANGLE_180;
+	}
+
+	// angles past 90 degrees need to shrink to get closer to 90 degrees
+	if (ang > ANGLE_90)
+	{
+		advanceAng = InvAngle(advanceAng);
+	}
+
+	// now we set the actual final angle
+	if ((ang > ANGLE_90) != (ang + advanceAng > ANGLE_90))
+	{
+		ang = (upwards ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards
+	}
+	else
+	{
+		ang = slope->zangle + advanceAng;
+	}
 
 	slopemom.x = mo->momx;
 	slopemom.y = mo->momy;