diff --git a/src/doomdef.h b/src/doomdef.h
index 9a1e5af9ee5a6e5ce5c1bc7063a918354a4b17ab..e645c0848e4d44eccac78e01788e2d351a6f9721 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -431,6 +431,12 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
 /// Kalaron/Eternity Engine slope code (SRB2CB ported)
 #define ESLOPE
 
+#if defined(ESLOPE)
+/// Backwards compatibility with SRB2CB's slope linedef types.
+///	\note	A simple shim that prints a warning.
+#define ESLOPE_TYPESHIM
+#endif
+
 ///	Delete file while the game is running.
 ///	\note	EXTREMELY buggy, tends to crash game.
 //#define DELFILE
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 68fb1696f5076fda20577a8f6035808bf96ad3ab..775cd9d6d18b943e9d035ab26df92a46ed9c75e7 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -1252,13 +1252,12 @@ static void P_PlayerFlip(mobj_t *mo)
 }
 
 //
-// P_CheckGravity
+// P_GetMobjGravity
 //
-// Checks the current gravity state
-// of the object. If affect is true,
-// a gravity force will be applied.
+// Returns the current gravity
+// value of the object.
 //
-void P_CheckGravity(mobj_t *mo, boolean affect)
+fixed_t P_GetMobjGravity(mobj_t *mo)
 {
 	fixed_t gravityadd = 0;
 	boolean no3dfloorgrav = true; // Custom gravity
@@ -1400,11 +1399,25 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
 	if (goopgravity)
 		gravityadd = -gravityadd/5;
 
-	if (affect)
-		mo->momz += FixedMul(gravityadd, mo->scale);
-
 	if (mo->player && !!(mo->eflags & MFE_VERTICALFLIP) != wasflip)
 		P_PlayerFlip(mo);
+	
+	return gravityadd;
+}
+
+//
+// P_CheckGravity
+//
+// Checks the current gravity state
+// of the object. If affect is true,
+// a gravity force will be applied.
+//
+void P_CheckGravity(mobj_t *mo, boolean affect)
+{
+	fixed_t gravityadd = P_GetMobjGravity(mo);
+
+	if (affect)
+		mo->momz += FixedMul(gravityadd, mo->scale);
 
 	if (mo->type == MT_SKIM && mo->z + mo->momz <= mo->watertop && mo->z >= mo->watertop)
 	{
@@ -1480,7 +1493,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy)
 		    && abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale)
 		    && (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING))
 #ifdef ESLOPE
-			&& !(player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
+			&& !(player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && (abs(player->mo->standingslope->zdelta) >= FRACUNIT/2))
 #endif
 				)
 		{
diff --git a/src/p_mobj.h b/src/p_mobj.h
index 9542ce8ba1e26fc3bad29d3970f165c88dc1aa9b..de7f0c8d537c3cebb02829a6b3dc0751aacf0eae 100644
--- a/src/p_mobj.h
+++ b/src/p_mobj.h
@@ -425,6 +425,9 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
 // check mobj against water content, before movement code
 void P_MobjCheckWater(mobj_t *mobj);
 
+// get mobj gravity
+fixed_t P_GetMobjGravity(mobj_t *mo);
+
 // Player spawn points
 void P_SpawnPlayer(INT32 playernum);
 void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing);
diff --git a/src/p_slopes.c b/src/p_slopes.c
index 6393ca4b558514e0616dc0423f60d899e29342c9..f4ef4dcc27d9d6c187e2b4e951488201d113e4f4 100644
--- a/src/p_slopes.c
+++ b/src/p_slopes.c
@@ -16,6 +16,7 @@
 #include "m_bbox.h"
 #include "z_zone.h"
 #include "p_local.h"
+#include "p_mobj.h"
 #include "p_spec.h"
 #include "p_slopes.h"
 #include "p_setup.h"
@@ -881,7 +882,7 @@ void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum)
 // Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes
 void P_ResetDynamicSlopes(void) {
 	size_t i;
-#if 1 // Rewrite old specials to new ones, and give a console warning
+#ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning
 	boolean warned = false;
 #endif
 
@@ -894,7 +895,7 @@ void P_ResetDynamicSlopes(void) {
 	{
 		switch (lines[i].special)
 		{
-#if 1 // Rewrite old specials to new ones, and give a console warning
+#ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning
 #define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");}
 			case 386:
 			case 387:
@@ -1018,6 +1019,9 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y)
 // When given a vector, rotates it and aligns it to a slope
 void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
 {
+	if (slope->flags & SL_NOPHYSICS)
+		return; // No physics, no quantizing.
+	
 	vector3_t axis;
 	axis.x = -slope->d.y;
 	axis.y = slope->d.x;
@@ -1032,26 +1036,37 @@ void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
 // Handles slope ejection for objects
 void P_SlopeLaunch(mobj_t *mo)
 {
-	// Double the pre-rotation Z, then halve the post-rotation Z. This reduces the
-	// vertical launch given from slopes while increasing the horizontal launch
-	// given. Good for SRB2's gravity and horizontal speeds.
-	vector3_t slopemom;
-	slopemom.x = mo->momx;
-	slopemom.y = mo->momy;
-	slopemom.z = mo->momz*2;
-	P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
-
-	mo->momx = slopemom.x;
-	mo->momy = slopemom.y;
-	mo->momz = slopemom.z/2;
-
+	if (!(mo->standingslope->flags & SL_NOPHYSICS)) // If there's physics, time for launching.
+	{
+		// Double the pre-rotation Z, then halve the post-rotation Z. This reduces the
+		// vertical launch given from slopes while increasing the horizontal launch
+		// given. Good for SRB2's gravity and horizontal speeds.
+		vector3_t slopemom;
+		slopemom.x = mo->momx;
+		slopemom.y = mo->momy;
+		slopemom.z = mo->momz*2;
+		P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
+
+		mo->momx = slopemom.x;
+		mo->momy = slopemom.y;
+		mo->momz = slopemom.z/2;
+	}
+	
 	//CONS_Printf("Launched off of slope.\n");
 	mo->standingslope = NULL;
 }
 
 // Function to help handle landing on slopes
 void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
-{
+{	
+	if (slope->flags & SL_NOPHYSICS) { // No physics, no need to make anything complicated.
+		if (P_MobjFlip(thing)*(thing->momz) < 0) { // falling, land on slope
+			thing->momz = -P_MobjFlip(thing);
+			thing->standingslope = slope;
+		}
+		return;
+	}
+
 	vector3_t mom;
 	mom.x = thing->momx;
 	mom.y = thing->momy;
@@ -1081,6 +1096,9 @@ void P_ButteredSlope(mobj_t *mo)
 
 	if (!mo->standingslope)
 		return;
+	
+	if (mo->standingslope->flags & SL_NOPHYSICS)
+		return; // No physics, no butter.
 
 	if (mo->flags & (MF_NOCLIPHEIGHT|MF_NOGRAVITY))
 		return; // don't slide down slopes if you can't touch them or you're not affected by gravity
@@ -1116,7 +1134,7 @@ void P_ButteredSlope(mobj_t *mo)
 	// This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down
 
 	// Multiply by gravity
-	thrust = FixedMul(thrust, gravity); // TODO account for per-sector gravity etc
+	thrust = FixedMul(thrust, FixedMul(gravity, abs(P_GetMobjGravity(mo)))); // Now uses the absolute of mobj gravity. You're welcome.
 	// Multiply by scale (gravity strength depends on mobj scale)
 	thrust = FixedMul(thrust, mo->scale);
 
diff --git a/src/p_user.c b/src/p_user.c
index 4117cfc4c44755a2c8c87dbdbb1245836468cfd6..461497bcbffa34a8a6257adbc6c50d54a55b70f4 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -3741,7 +3741,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
 	{
 		if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<<FRACBITS, player->mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)
 #ifdef ESLOPE
-			&& (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
+			&& (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
 #endif
 			)
 		{
@@ -3774,7 +3774,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
 		else if ((cmd->buttons & BT_USE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20))
 			&& !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<<FRACBITS, player->mo->scale)
 #ifdef ESLOPE
-			|| (player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
+			|| (player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2)
 #endif
 			) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING))
 		{
@@ -3790,7 +3790,7 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
 	if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH)
 		&& player->speed < FixedMul(5*FRACUNIT,player->mo->scale)
 #ifdef ESLOPE
-			&& (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
+			&& (!player->mo->standingslope || (player->mo->standingslope->flags & SL_NOPHYSICS) || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
 #endif
 			)
 	{
@@ -4776,7 +4776,7 @@ static void P_3dMovement(player_t *player)
 
 #ifdef ESLOPE
 	if ((totalthrust.x || totalthrust.y)
-		&& player->mo->standingslope && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
+		&& player->mo->standingslope && (!(player->mo->standingslope->flags & SL_NOPHYSICS)) && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
 		// Factor thrust to slope, but only for the part pushing up it!
 		// The rest is unaffected.
 		angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection;