diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 8c0d3ff1960b86d58fbbedba3ac1848d5f0cf994..9eec5bc6e7dd0a561a770c9ad0ecc1ed7486a5b1 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -246,6 +246,7 @@ static boolean lib_pSearchBlockmap_Objects_aux(lua_State *L, INT32 x, INT32 y, m
 			if (lua_toboolean(gL, -1))
 				return false;
 		}
+		lua_pop(gL, 1);
 		if (P_MobjWasRemoved(thing) // func just popped our thing, cannot continue.
 		|| (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue.
 		{
@@ -314,6 +315,158 @@ static int lib_pSearchBlockmap_Objects(lua_State *L)
 	lua_pushboolean(L, retval);
 	return 1;
 }
+
+// auxillary function for lib_pSearchBlockmap_Objects
+static boolean lib_pSearchBlockmap_Lines_aux(lua_State *L, INT32 x, INT32 y, mobj_t *thing, int funcarg)
+{
+	INT32 offset;
+	const INT32 *list; // Big blockmap
+#ifdef POLYOBJECTS
+	polymaplink_t *plink; // haleyjd 02/22/06
+#endif
+	line_t *ld;
+
+	if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
+		return true;
+
+	offset = y*bmapwidth + x;
+
+#ifdef POLYOBJECTS
+	// haleyjd 02/22/06: consider polyobject lines
+	plink = polyblocklinks[offset];
+
+	while (plink)
+	{
+		polyobj_t *po = plink->po;
+
+		if (po->validcount != validcount) // if polyobj hasn't been checked
+		{
+			size_t i;
+			po->validcount = validcount;
+
+			for (i = 0; i < po->numLines; ++i)
+			{
+				if (po->lines[i]->validcount == validcount) // line has been checked
+					continue;
+				po->lines[i]->validcount = validcount;
+
+				lua_pushvalue(L, funcarg);
+				LUA_PushUserdata(L, thing, META_MOBJ);
+				LUA_PushUserdata(L, po->lines[i], META_LINE);
+				if (lua_pcall(gL, 2, 1, 0)) {
+					if (!blockfuncerror || cv_debug & DBG_LUA)
+						CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
+					lua_pop(gL, 1);
+					blockfuncerror = true;
+					return true;
+				}
+				if (!lua_isnil(gL, -1))
+				{ // if nil, continue
+					if (lua_toboolean(gL, -1))
+						return false;
+				}
+				lua_pop(gL, 1);
+				if (P_MobjWasRemoved(thing))
+					return true;
+			}
+		}
+		plink = (polymaplink_t *)(plink->link.next);
+	}
+#endif
+
+	offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x];
+
+	// First index is really empty, so +1 it.
+	for (list = blockmaplump + offset + 1; *list != -1; list++)
+	{
+		ld = &lines[*list];
+
+		if (ld->validcount == validcount)
+			continue; // Line has already been checked.
+
+		ld->validcount = validcount;
+
+		lua_pushvalue(L, funcarg);
+		LUA_PushUserdata(L, thing, META_MOBJ);
+		LUA_PushUserdata(L, ld, META_LINE);
+		if (lua_pcall(gL, 2, 1, 0)) {
+			if (!blockfuncerror || cv_debug & DBG_LUA)
+				CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
+			lua_pop(gL, 1);
+			blockfuncerror = true;
+			return true;
+		}
+		if (!lua_isnil(gL, -1))
+		{ // if nil, continue
+			if (lua_toboolean(gL, -1))
+				return false;
+		}
+		lua_pop(gL, 1);
+		if (P_MobjWasRemoved(thing))
+			return true;
+	}
+	return true; // Everything was checked.
+}
+
+// P_SearchBlockmap_Lines
+// same deal as the _Objects version
+static int lib_pSearchBlockmap_Lines(lua_State *L)
+{
+	int n = lua_gettop(L);
+	mobj_t *mobj;
+	INT32 xl, xh, yl, yh, bx, by;
+	fixed_t x1, x2, y1, y2;
+	int funcarg;
+	boolean retval = true;
+
+	// the mobj we are searching around
+	mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
+	if (!mobj)
+		return LUA_ErrInvalid(L, "mobj_t");
+
+	if (n > 2) // specific x/y ranges have been supplied
+	{
+		if (n < 6)
+			return luaL_error(L, "arguments 2 to 5 not all given (expected 4 fixed-point integers)");
+
+		x1 = luaL_checkfixed(L, 2);
+		x2 = luaL_checkfixed(L, 3);
+		y1 = luaL_checkfixed(L, 4);
+		y2 = luaL_checkfixed(L, 5);
+		funcarg = 6;
+	}
+	else // mobj and function only - search around mobj's radius by default
+	{
+		x1 = mobj->x - mobj->radius;
+		x2 = mobj->x + mobj->radius;
+		y1 = mobj->y - mobj->radius;
+		y2 = mobj->y + mobj->radius;
+		funcarg = 2;
+	}
+	luaL_checktype(L, funcarg, LUA_TFUNCTION);
+
+	xl = (unsigned)(x1 - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
+	xh = (unsigned)(x2 - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
+	yl = (unsigned)(y1 - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
+	yh = (unsigned)(y2 - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
+
+	BMBOUNDFIX(xl, xh, yl, yh);
+
+	blockfuncerror = false; // reset
+	validcount++;
+	for (bx = xl; bx <= xh; bx++)
+		for (by = yl; by <= yh; by++)
+		{
+			if (!lib_pSearchBlockmap_Lines_aux(L, bx, by, mobj, funcarg))
+				retval = false;
+			if (P_MobjWasRemoved(mobj)){
+				lua_pushboolean(L, false);
+				return 1;
+			}	
+		}
+	lua_pushboolean(L, retval);
+	return 1;
+}
 #endif
 
 // P_ENEMY
@@ -2105,6 +2258,7 @@ static luaL_Reg lib[] = {
 	{"P_PointOnLineSide",lib_pPointOnLineSide},
 #ifdef LUA_BLOCKMAP
 	{"P_SearchBlockmap_Objects",lib_pSearchBlockmap_Objects},
+	{"P_SearchBlockmap_Lines",lib_pSearchBlockmap_Lines},
 #endif
 
 	// p_enemy