diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 35798e688ae8802f85842ea95f4454daa189f07f..fb33e9025006d5414421e29710898b8be10d1c9f 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -2023,6 +2023,28 @@ static int lib_pCeilingzAtPos(lua_State *L)
 	return 1;
 }
 
+static int lib_pGetSectorLightLevelAt(lua_State *L)
+{
+	boolean has_sector = false;
+	sector_t *sector = NULL;
+	if (!lua_isnoneornil(L, 1))
+	{
+		has_sector = true;
+		sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
+	}
+	fixed_t x = luaL_checkfixed(L, 2);
+	fixed_t y = luaL_checkfixed(L, 3);
+	fixed_t z = luaL_checkfixed(L, 4);
+	INLEVEL
+	if (has_sector && !sector)
+		return LUA_ErrInvalid(L, "sector_t");
+	if (sector)
+		lua_pushinteger(L, P_GetLightLevelFromSectorAt(sector, x, y, z));
+	else
+		lua_pushinteger(L, P_GetSectorLightLevelAt(x, y, z));
+	return 1;
+}
+
 static int lib_pGetSectorColormapAt(lua_State *L)
 {
 	boolean has_sector = false;
@@ -4329,6 +4351,7 @@ static luaL_Reg lib[] = {
 	{"P_RadiusAttack",lib_pRadiusAttack},
 	{"P_FloorzAtPos",lib_pFloorzAtPos},
 	{"P_CeilingzAtPos",lib_pCeilingzAtPos},
+	{"P_GetSectorLightLevelAt",lib_pGetSectorLightLevelAt},
 	{"P_GetSectorColormapAt",lib_pGetSectorColormapAt},
 	{"P_DoSpring",lib_pDoSpring},
 	{"P_TouchSpecialThing",lib_pTouchSpecialThing},
diff --git a/src/p_local.h b/src/p_local.h
index ba033dc06fda53ac1dda5db3a1fb3e2192fc4bc8..5055e3252d4f645bd5567027514709a362ae62e5 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -445,7 +445,9 @@ boolean PIT_PushableMoved(mobj_t *thing);
 
 boolean P_DoSpring(mobj_t *spring, mobj_t *object);
 
-INT32 P_GetSectorLightAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z);
+INT32 P_GetSectorLightNumAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z);
+INT32 P_GetLightLevelFromSectorAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z);
+INT32 P_GetSectorLightLevelAt(fixed_t x, fixed_t y, fixed_t z);
 extracolormap_t *P_GetColormapFromSectorAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z);
 extracolormap_t *P_GetSectorColormapAt(fixed_t x, fixed_t y, fixed_t z);
 
diff --git a/src/p_map.c b/src/p_map.c
index 6a152c563de0636c160f25103a82566d85e19b08..32b4e4367d32dacf0710a6170b8921718f0f1948 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -5072,7 +5072,7 @@ fixed_t P_CeilingzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
 	return ceilingz;
 }
 
-INT32 P_GetSectorLightAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z)
+INT32 P_GetSectorLightNumAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z)
 {
 	if (!sector->numlights)
 		return -1;
@@ -5091,10 +5091,23 @@ INT32 P_GetSectorLightAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z)
 	return light;
 }
 
+INT32 P_GetLightLevelFromSectorAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z)
+{
+	if (sector->numlights)
+		return *sector->lightlist[P_GetSectorLightNumAt(sector, x, y, z)].lightlevel;
+	else
+		return sector->lightlevel;
+}
+
+INT32 P_GetSectorLightLevelAt(fixed_t x, fixed_t y, fixed_t z)
+{
+	return P_GetLightLevelFromSectorAt(R_PointInSubsector(x, y)->sector, x, y, z);
+}
+
 extracolormap_t *P_GetColormapFromSectorAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z)
 {
 	if (sector->numlights)
-		return *sector->lightlist[P_GetSectorLightAt(sector, x, y, z)].extra_colormap;
+		return *sector->lightlist[P_GetSectorLightNumAt(sector, x, y, z)].extra_colormap;
 	else
 		return sector->extra_colormap;
 }
diff --git a/src/r_things.c b/src/r_things.c
index 557e1681439cd13d6bd871f7c33a789a0d2ba2be..f2e095bd6172f503ce794152a71095536f4dc9f6 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -2134,7 +2134,7 @@ static void R_ProjectSprite(mobj_t *thing)
 
 	if (thing->subsector->sector->numlights)
 	{
-		light = P_GetSectorLightAt(thing->subsector->sector, interp.x, interp.y, splat ? gz : gzt);
+		light = P_GetSectorLightNumAt(thing->subsector->sector, interp.x, interp.y, splat ? gz : gzt);
 
 		INT32 lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT);
 		if (lightnum < 0)