diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 4af5066aeb8df5a75b6091c205e932c72f6f2349..741f44bb63ceaf4c3a3056da8354ee592ce37c64 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -1840,6 +1840,45 @@ static int lib_pMoveOrigin(lua_State *L)
 	return 2;
 }
 
+static int lib_pLineIsBlocking(lua_State *L)
+{
+	mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
+	line_t *line = *((line_t **)luaL_checkudata(L, 2, META_LINE));
+	NOHUD
+	INLEVEL
+	if (!mo)
+		return LUA_ErrInvalid(L, "mobj_t");
+	if (!line)
+		return LUA_ErrInvalid(L, "line_t");
+	
+	// P_LineOpening in P_LineIsBlocking sets these variables.
+	// We want to keep their old values after so that whatever
+	// map collision code uses them doesn't get messed up.
+	fixed_t oldopentop = opentop;
+	fixed_t oldopenbottom = openbottom;
+	fixed_t oldopenrange = openrange;
+	fixed_t oldlowfloor = lowfloor;
+	fixed_t oldhighceiling = highceiling;
+	pslope_t *oldopentopslope = opentopslope;
+	pslope_t *oldopenbottomslope = openbottomslope;
+	ffloor_t *oldopenfloorrover = openfloorrover;
+	ffloor_t *oldopenceilingrover = openceilingrover;
+	
+	lua_pushboolean(L, P_LineIsBlocking(mo, line));
+	
+	opentop = oldopentop;
+	openbottom = oldopenbottom;
+	openrange = oldopenrange;
+	lowfloor = oldlowfloor;
+	highceiling = oldhighceiling;
+	opentopslope = oldopentopslope;
+	openbottomslope = oldopenbottomslope;
+	openfloorrover = oldopenfloorrover;
+	openceilingrover = oldopenceilingrover;
+	
+	return 1;
+}
+
 static int lib_pSlideMove(lua_State *L)
 {
 	mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@@ -4147,6 +4186,7 @@ static luaL_Reg lib[] = {
 	{"P_TeleportMove",lib_pTeleportMove},
 	{"P_SetOrigin",lib_pSetOrigin},
 	{"P_MoveOrigin",lib_pMoveOrigin},
+	{"P_LineIsBlocking",lib_pLineIsBlocking},
 	{"P_SlideMove",lib_pSlideMove},
 	{"P_BounceMove",lib_pBounceMove},
 	{"P_CheckSight", lib_pCheckSight},
diff --git a/src/p_local.h b/src/p_local.h
index 4b330184bddd915ea155ca1741b6b03bf80f43d8..03663662667e05d3cc32f56d874e570146a48aea 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -418,6 +418,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);
 boolean P_Move(mobj_t *actor, fixed_t speed);
 boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
 boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z);
+boolean P_LineIsBlocking(mobj_t *mo, line_t *li);
 void P_SlideMove(mobj_t *mo);
 void P_BounceMove(mobj_t *mo);
 boolean P_CheckSight(mobj_t *t1, mobj_t *t2);
diff --git a/src/p_map.c b/src/p_map.c
index 80135db7471058b85f7aadda2fef0c37e4ddba57..a69fa06e265a2182fed958d1fe17932c5016adb8 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -3400,36 +3400,41 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
 	return false;
 }
 
-static boolean PTR_LineIsBlocking(line_t *li)
+//
+// P_LineIsBlocking
+//
+// Determines if line would block mo's movement
+//
+boolean P_LineIsBlocking(mobj_t *mo, line_t *li)
 {
 	// one-sided linedefs are always solid to sliding movement.
 	if (!li->backsector)
-		return !P_PointOnLineSide(slidemo->x, slidemo->y, li);
+		return !P_PointOnLineSide(mo->x, mo->y, li);
 
-	if (!(slidemo->flags & MF_MISSILE))
+	if (!(mo->flags & MF_MISSILE))
 	{
 		if (li->flags & ML_IMPASSIBLE)
 			return true;
 
-		if ((slidemo->flags & (MF_ENEMY|MF_BOSS)) && li->flags & ML_BLOCKMONSTERS)
+		if ((mo->flags & (MF_ENEMY|MF_BOSS)) && li->flags & ML_BLOCKMONSTERS)
 			return true;
 	}
 
 	// set openrange, opentop, openbottom
-	P_LineOpening(li, slidemo);
+	P_LineOpening(li, mo);
 
-	if (openrange < slidemo->height)
+	if (openrange < mo->height)
 		return true; // doesn't fit
 
-	if (opentop - slidemo->z < slidemo->height)
+	if (opentop - mo->z < mo->height)
 		return true; // mobj is too high
 
-	if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, slidemo->scale))
+	if (openbottom - mo->z > FixedMul(MAXSTEPMOVE, mo->scale))
 		return true; // too big a step up
 
-	if (slidemo->player
-		&& openrange < P_GetPlayerHeight(slidemo->player)
-		&& !P_PlayerCanEnterSpinGaps(slidemo->player))
+	if (mo->player
+		&& openrange < P_GetPlayerHeight(mo->player)
+		&& !P_PlayerCanEnterSpinGaps(mo->player))
 			return true; // nonspin character should not take this path
 
 	return false;
@@ -3533,7 +3538,7 @@ static boolean PTR_SlideTraverse(intercept_t *in)
 
 	li = in->d.line;
 
-	if (!PTR_LineIsBlocking(li))
+	if (!P_LineIsBlocking(slidemo, li))
 		return true;
 
 	// the line blocks movement,