diff --git a/src/p_mobj.c b/src/p_mobj.c
index 38e88da90a187ccb1e8d05ed3f95855eb19847f3..a819883ada1d3ece957b50f1baa0a47706296298 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -2121,16 +2121,6 @@ void P_XYMovement(mobj_t *mo)
 
 	if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG))
 	{
-#ifdef ESLOPE
-		pslope_t *transferslope = NULL;
-		fixed_t transfermomz = 0;
-		if (oldslope && (P_MobjFlip(mo)*(predictedz - mo->z) > 0)) // Only for moving up (relative to gravity), otherwise there's a failed launch when going down slopes and hitting walls
-		{
-			transferslope = ((mo->standingslope) ? mo->standingslope : oldslope);
-			transfermomz = P_PrepareSlopeToWallTransfer(mo, transferslope); // This isn't the end of it; momz will be scaled based upon the angle of movement after collision, and then it'll be applied.
-		}
-#endif
-
 		// blocked move
 		moved = false;
 
@@ -2188,18 +2178,35 @@ void P_XYMovement(mobj_t *mo)
 		}
 		else if (player || mo->flags & (MF_SLIDEME|MF_PUSHABLE))
 		{ // try to slide along it
+#ifdef ESLOPE
+			// Wall transfer part 1.
+			pslope_t *transferslope = NULL;
+			fixed_t transfermomz = 0;
+			if (oldslope && (P_MobjFlip(mo)*(predictedz - mo->z) > 0)) // Only for moving up (relative to gravity), otherwise there's a failed launch when going down slopes and hitting walls
+			{
+				transferslope = ((mo->standingslope) ? mo->standingslope : oldslope);
+				transfermomz = P_GetWallTransferMomZ(mo, transferslope);
+			}
+#endif
+
 			P_SlideMove(mo);
 			xmove = ymove = 0;
+
 #ifdef ESLOPE
-			if (transfermomz && transferslope) // Scale transfer momentum based on how head-on it is to the slope.
-			{
-				angle_t relation = (transferslope->xydirection - R_PointToAngle2(0, 0, mo->momx, mo->momy));
-				fixed_t scalefactor = abs(FINESINE((relation >> ANGLETOFINESHIFT) & FINEMASK));
-				transfermomz = FixedMul(transfermomz, scalefactor);
-				if ((P_MobjFlip(mo)*(transfermomz - mo->momz)) > 2*FRACUNIT) // Do the actual launch!
+			// Wall transfer part 2.
+			if (transfermomz && transferslope) // Are we "transferring onto the wall" (really just a disguised vertical launch)?
+			{
+				angle_t relation; // Scale transfer momentum based on how head-on it is to the slope.
+				if (mo->momx || mo->momy) // "Guess" the angle of the wall you hit using new momentum
+					relation = transferslope->xydirection - R_PointToAngle2(0, 0, mo->momx, mo->momy);
+				else // Give it for free, I guess.
+					relation = ANGLE_90;
+				transfermomz = FixedMul(transfermomz,
+					abs(FINESINE((relation >> ANGLETOFINESHIFT) & FINEMASK)));
+				if (P_MobjFlip(mo)*(transfermomz - mo->momz) > 2*FRACUNIT) // Do the actual launch!
 				{
-					mo->standingslope = NULL;
 					mo->momz = transfermomz;
+					mo->standingslope = NULL;
 				}
 			}
 #endif
diff --git a/src/p_slopes.c b/src/p_slopes.c
index 3afd51cba1dd864d9a602fdb7f2fc07488eaa33c..f480b6e4f9d234e95e451ae5b9a503794c624f03 100644
--- a/src/p_slopes.c
+++ b/src/p_slopes.c
@@ -805,10 +805,12 @@ void P_SlopeLaunch(mobj_t *mo)
 }
 
 //
-// P_SlopeToWallTransfer
+// P_GetWallTransferMomZ
 //
-// Handles slope-to-wall transfer for objects.
-fixed_t P_PrepareSlopeToWallTransfer(mobj_t *mo, pslope_t *slope)
+// It would be nice to have a single function that does everything necessary for slope-to-wall transfer.
+// However, it needs to be seperated out in P_XYMovement to take into account momentum before and after hitting the wall.
+// This just performs the necessary calculations for getting the base vertical momentum; the horizontal is already reasonably calculated by P_SlideMove.
+fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope)
 {
 	vector3_t slopemom, axis;
 	angle_t ang;
diff --git a/src/p_slopes.h b/src/p_slopes.h
index ab102fcc0eb835e1e7d513eab893659b2c282b31..f59c5b767b4dac1762a0a458c899efce590f8531 100644
--- a/src/p_slopes.h
+++ b/src/p_slopes.h
@@ -37,7 +37,7 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y);
 void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
 void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
 void P_SlopeLaunch(mobj_t *mo);
-fixed_t P_PrepareSlopeToWallTransfer(mobj_t *mo, pslope_t *slope);
+fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope);
 void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope);
 void P_ButteredSlope(mobj_t *mo);