diff --git a/src/gl/dynlights/a_dynlight.cpp b/src/gl/dynlights/a_dynlight.cpp
index 45e8bfb14f..0ab8345053 100644
--- a/src/gl/dynlights/a_dynlight.cpp
+++ b/src/gl/dynlights/a_dynlight.cpp
@@ -582,81 +582,107 @@ double ADynamicLight::DistToSeg(const DVector3 &pos, seg_t *seg)
 // to sidedefs and sector parts.
 //
 //==========================================================================
+struct LightLinkEntry
+{
+	subsector_t *sub;
+	DVector3 pos;
+};
+static TArray<LightLinkEntry> collected_ss;
 
-void ADynamicLight::CollectWithinRadius(const DVector3 &pos, subsector_t *subSec, float radius)
+void ADynamicLight::CollectWithinRadius(const DVector3 &opos, subsector_t *subSec, float radius)
 {
 	if (!subSec) return;
-
+	collected_ss.Clear();
+	collected_ss.Push({ subSec, opos });
 	subSec->validcount = ::validcount;
 
-	touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors);
-	if (subSec->sector->validcount != ::validcount)
+	for (unsigned i = 0; i < collected_ss.Size(); i++)
 	{
-		touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector);
-		subSec->sector->validcount = ::validcount;
-	}
+		subSec = collected_ss[i].sub;
+		auto &pos = collected_ss[i].pos;
 
-	for (unsigned int i = 0; i < subSec->numlines; i++)
-	{
-		seg_t * seg = subSec->firstline + i;
-
-		// check distance from x/y to seg and if within radius add this seg and, if present the opposing subsector (lather/rinse/repeat)
-		// If out of range we do not need to bother with this seg.
-		if (DistToSeg(pos, seg) <= radius)
+		touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors);
+		if (subSec->sector->validcount != ::validcount)
 		{
-			if (seg->sidedef && seg->linedef && seg->linedef->validcount != ::validcount)
+			touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector);
+			subSec->sector->validcount = ::validcount;
+		}
+
+		for (unsigned int i = 0; i < subSec->numlines; i++)
+		{
+			seg_t * seg = subSec->firstline + i;
+
+			// check distance from x/y to seg and if within radius add this seg and, if present the opposing subsector (lather/rinse/repeat)
+			// If out of range we do not need to bother with this seg.
+			if (DistToSeg(pos, seg) <= radius)
 			{
-				// light is in front of the seg
-				if ((pos.Y - seg->v1->fY()) * (seg->v2->fX() - seg->v1->fX()) + (seg->v1->fX() - pos.X) * (seg->v2->fY() - seg->v1->fY()) <= 0)
+				if (seg->sidedef && seg->linedef && seg->linedef->validcount != ::validcount)
 				{
-					seg->linedef->validcount = validcount;
-					touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides);
-				}
-			}
-			if (seg->linedef)
-			{
-				FLinePortal *port = seg->linedef->getPortal();
-				if (port && port->mType == PORTT_LINKED)
-				{
-					line_t *other = port->mDestination;
-					if (other->validcount != ::validcount)
+					// light is in front of the seg
+					if ((pos.Y - seg->v1->fY()) * (seg->v2->fX() - seg->v1->fX()) + (seg->v1->fX() - pos.X) * (seg->v2->fY() - seg->v1->fY()) <= 0)
 					{
-						subsector_t *othersub = R_PointInSubsector(other->v1->fPos() + other->Delta() / 2);
-						if (othersub->validcount != ::validcount) CollectWithinRadius(PosRelative(other), othersub, radius);
+						seg->linedef->validcount = validcount;
+						touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides);
+					}
+				}
+				if (seg->linedef)
+				{
+					FLinePortal *port = seg->linedef->getPortal();
+					if (port && port->mType == PORTT_LINKED)
+					{
+						line_t *other = port->mDestination;
+						if (other->validcount != ::validcount)
+						{
+							subsector_t *othersub = R_PointInSubsector(other->v1->fPos() + other->Delta() / 2);
+							if (othersub->validcount != ::validcount)
+							{
+								othersub->validcount = ::validcount;
+								collected_ss.Push({ othersub, PosRelative(other) });
+							}
+						}
+					}
+				}
+
+				seg_t *partner = seg->PartnerSeg;
+				if (partner)
+				{
+					subsector_t *sub = partner->Subsector;
+					if (sub != NULL && sub->validcount != ::validcount)
+					{
+						sub->validcount = ::validcount;
+						collected_ss.Push({ sub, pos });
 					}
 				}
 			}
-
-			seg_t *partner = seg->PartnerSeg;
-			if (partner)
+		}
+		sector_t *sec = subSec->sector;
+		if (!sec->PortalBlocksSight(sector_t::ceiling))
+		{
+			line_t *other = subSec->firstline->linedef;
+			if (sec->GetPortalPlaneZ(sector_t::ceiling) < Z() + radius)
 			{
-				subsector_t *sub = partner->Subsector;
-				if (sub != NULL && sub->validcount != ::validcount)
+				DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::ceiling);
+				subsector_t *othersub = R_PointInSubsector(refpos);
+				if (othersub->validcount != ::validcount)
 				{
-					CollectWithinRadius(pos, sub, radius);
+					othersub->validcount = ::validcount;
+					collected_ss.Push({ othersub, PosRelative(othersub->sector) });
 				}
 			}
 		}
-	}
-	sector_t *sec = subSec->sector;
-	if (!sec->PortalBlocksSight(sector_t::ceiling))
-	{
-		line_t *other = subSec->firstline->linedef;
-		if (sec->GetPortalPlaneZ(sector_t::ceiling) < Z() + radius)
+		if (!sec->PortalBlocksSight(sector_t::floor))
 		{
-			DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::ceiling);
-			subsector_t *othersub = R_PointInSubsector(refpos);
-			if (othersub->validcount != ::validcount) CollectWithinRadius(PosRelative(othersub->sector), othersub, radius);
-		}
-	}
-	if (!sec->PortalBlocksSight(sector_t::floor))
-	{
-		line_t *other = subSec->firstline->linedef;
-		if (sec->GetPortalPlaneZ(sector_t::floor) > Z() - radius)
-		{
-			DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::floor);
-			subsector_t *othersub = R_PointInSubsector(refpos);
-			if (othersub->validcount != ::validcount) CollectWithinRadius(PosRelative(othersub->sector), othersub, radius);
+			line_t *other = subSec->firstline->linedef;
+			if (sec->GetPortalPlaneZ(sector_t::floor) > Z() - radius)
+			{
+				DVector2 refpos = other->v1->fPos() + other->Delta() / 2 + sec->GetPortalDisplacement(sector_t::floor);
+				subsector_t *othersub = R_PointInSubsector(refpos);
+				if (othersub->validcount != ::validcount)
+				{
+					othersub->validcount = ::validcount;
+					collected_ss.Push({ othersub, PosRelative(othersub->sector) });
+				}
+			}
 		}
 	}
 }
diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp
index 54f1dd75b9..81164e434a 100644
--- a/src/gl/scene/gl_walls_draw.cpp
+++ b/src/gl/scene/gl_walls_draw.cpp
@@ -102,9 +102,10 @@ void GLWall::SetupLights()
 
 			Vector fn, pos;
 
-			float x = node->lightsource->X();
-			float y = node->lightsource->Y();
-			float z = node->lightsource->Z();
+			DVector3 posrel = node->lightsource->PosRelative(seg->frontsector);
+			float x = posrel.X;
+			float y = posrel.Y;
+			float z = posrel.Z;
 			float dist = fabsf(p.DistToPoint(x, z, y));
 			float radius = node->lightsource->GetRadius();
 			float scale = 1.0f / ((2.f * radius) - dist);
diff --git a/src/p_map.cpp b/src/p_map.cpp
index 290b84b9ed..f889069f18 100644
--- a/src/p_map.cpp
+++ b/src/p_map.cpp
@@ -869,12 +869,6 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
 			if (tm.thing->Z() < portz && tm.thing->Z() + tm.thing->MaxStepHeight >= portz && tm.floorz < portz)
 			{
 				// Actor is stepping through a portal.
-				/*
-				tm.floorz = portz;
-				tm.floorsector = oppsec;
-				tm.floorpic = cres.line->sidedef[0]->GetTexture(side_t::mid);
-				tm.floorterrain = 0;
-				*/
 				tm.portalstep = true;
 				return true;
 			}
@@ -2150,7 +2144,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
 				goto pushline;
 			}
 			else if (BlockingMobj->Top() - thing->Z() > thing->MaxStepHeight
-				|| (BlockingMobj->Sector->ceilingplane.ZatPoint(pos) - (BlockingMobj->Top()) < thing->Height)
+				|| ((BlockingMobj->Sector->ceilingplane.ZatPoint(pos) - (BlockingMobj->Top()) < thing->Height) && BlockingMobj->Sector->PortalBlocksMovement(sector_t::ceiling))
 				|| (tm.ceilingz - (BlockingMobj->Top()) < thing->Height))
 			{
 				goto pushline;
diff --git a/src/p_sight.cpp b/src/p_sight.cpp
index 21aa1bbe3d..df02e2ebbd 100644
--- a/src/p_sight.cpp
+++ b/src/p_sight.cpp
@@ -716,6 +716,7 @@ bool SightCheck::P_SightPathTraverse ()
 // step through map blocks
 // Count is present to prevent a round off error from skipping the break
 
+	int itres;
 	for (count = 0 ; count < 1000 ; count++)
 	{
 		// end traversing when reaching the end of the blockmap
@@ -724,15 +725,15 @@ bool SightCheck::P_SightPathTraverse ()
 		{
 			break;
 		}
-		int res = P_SightBlockLinesIterator(mapx, mapy);
-		if (res == 0)
+		itres = P_SightBlockLinesIterator(mapx, mapy);
+		if (itres == 0)
 		{
 			sightcounts[1]++;
 			return false;	// early out
 		}
 
 		// either reached the end or had an early-out condition with portals left to check,
-		if (res == -1 || (mapxstep | mapystep) == 0)
+		if (itres == -1 || (mapxstep | mapystep) == 0)
 			break;
 
 		switch (((xs_FloorToInt(yintercept) == mapy) << 1) | (xs_FloorToInt(xintercept) == mapx))
@@ -787,7 +788,9 @@ sightcounts[1]++;
 //
 sightcounts[2]++;
 
-	return P_SightTraverseIntercepts ( );
+	bool traverseres = P_SightTraverseIntercepts ( );
+	if (itres == -1) return false;	// if the iterator had an early out there was no line of sight. The traverser was only called to collect more portals.
+	return traverseres;
 }
 
 /*
diff --git a/wadsrc/static/filter/hexen/sprofs.txt b/wadsrc/static/filter/hexen/sprofs.txt
index a8d614ca07..4408e3b95d 100644
--- a/wadsrc/static/filter/hexen/sprofs.txt
+++ b/wadsrc/static/filter/hexen/sprofs.txt
@@ -57,7 +57,7 @@ CLERW0, 37, 53, iwad
 CLERX0, 37, 43, iwad
 CLERY0, 38, 30, iwad
 CLERZ0, 38, 18, iwad
-CLER[0, 38, 12, iwad
+"CLER[0", 38, 12, iwad
 CPB1A0, 8, 7, iwad
 CPB2A0, 7, 6, iwad
 CPB3A0, 12, 4, iwad
diff --git a/wadsrc/static/filter/strife/sprofs.txt b/wadsrc/static/filter/strife/sprofs.txt
index d7118297bc..c6dafb581a 100644
--- a/wadsrc/static/filter/strife/sprofs.txt
+++ b/wadsrc/static/filter/strife/sprofs.txt
@@ -200,8 +200,8 @@ PGRDW0, 35, 28, iwad
 PGRDX0, 35, 28, iwad
 PGRDY0, 35, 28, iwad
 PGRDZ0, 35, 28, iwad
-PGRD[0, 35, 28, iwad
-PGRD\0, 35, 28, iwad
+"PGRD[0", 35, 28, iwad
+"PGRD\0", 35, 28, iwad
 PDEDE0, 22, 20, iwad
 PDEDF0, 23, 16, iwad
 PDEDG0, 23, 15, iwad