diff --git a/src/p_map.c b/src/p_map.c
index 95ad0258813acc587555ded086c4d7b6d58aadd6..6540a99b2d35fc925ca949eb6a484bc426db9958 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -3345,6 +3345,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
 boolean P_CheckSector(sector_t *sector, boolean crunch)
 {
 	msecnode_t *n;
+	size_t i;
 
 	nofit = false;
 	crushchange = crunch;
@@ -3359,9 +3360,57 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
 
 
 	// First, let's see if anything will keep it from crushing.
+
+	// Sal: This stupid function chain is required to fix polyobjects not being able to crush.
+	// Monster Iestyn: don't use P_CheckSector actually just look for objects in the blockmap instead
+	validcount++;
+
+	for (i = 0; i < sector->linecount; i++)
+	{
+		if (sector->lines[i]->polyobj)
+		{
+			polyobj_t *po = sector->lines[i]->polyobj;
+			if (po->validcount == validcount)
+				continue; // skip if already checked
+			if (!(po->flags & POF_SOLID))
+				continue;
+			if (po->lines[0]->backsector == sector) // Make sure you're currently checking the control sector
+			{
+				INT32 x, y;
+				po->validcount = validcount;
+
+				for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y)
+				{
+					for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x)
+					{
+						mobj_t *mo;
+
+						if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
+							continue;
+
+						mo = blocklinks[y * bmapwidth + x];
+
+						for (; mo; mo = mo->bnext)
+						{
+							// Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect
+
+							if (!P_MobjTouchingPolyobj(po, mo))
+								continue;
+
+							if (!PIT_ChangeSector(mo, false))
+							{
+								nofit = true;
+								return nofit;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
 	if (sector->numattached)
 	{
-		size_t i;
 		sector_t *sec;
 		for (i = 0; i < sector->numattached; i++)
 		{
@@ -3421,9 +3470,53 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
 	} while (n); // repeat from scratch until all things left are marked valid
 
 	// Nothing blocked us, so lets crush for real!
+
+	// Sal: This stupid function chain is required to fix polyobjects not being able to crush.
+	// Monster Iestyn: don't use P_CheckSector actually just look for objects in the blockmap instead
+	validcount++;
+
+	for (i = 0; i < sector->linecount; i++)
+	{
+		if (sector->lines[i]->polyobj)
+		{
+			polyobj_t *po = sector->lines[i]->polyobj;
+			if (po->validcount == validcount)
+				continue; // skip if already checked
+			if (!(po->flags & POF_SOLID))
+				continue;
+			if (po->lines[0]->backsector == sector) // Make sure you're currently checking the control sector
+			{
+				INT32 x, y;
+				po->validcount = validcount;
+
+				for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y)
+				{
+					for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x)
+					{
+						mobj_t *mo;
+
+						if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
+							continue;
+
+						mo = blocklinks[y * bmapwidth + x];
+
+						for (; mo; mo = mo->bnext)
+						{
+							// Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect
+
+							if (!P_MobjTouchingPolyobj(po, mo))
+								continue;
+
+							PIT_ChangeSector(mo, true);
+							return nofit;
+						}
+					}
+				}
+			}
+		}
+	}
 	if (sector->numattached)
 	{
-		size_t i;
 		sector_t *sec;
 		for (i = 0; i < sector->numattached; i++)
 		{
diff --git a/src/p_maputl.c b/src/p_maputl.c
index 1be57399cba4ab3e7e12595adc8988975e08651a..5368c137e68abe120abb945c410e8979819caffd 100644
--- a/src/p_maputl.c
+++ b/src/p_maputl.c
@@ -418,10 +418,6 @@ void P_CameraLineOpening(line_t *linedef)
 		if (front->ffloors || back->ffloors)
 		{
 			ffloor_t *rover;
-			fixed_t highestceiling = highceiling;
-			fixed_t lowestceiling = opentop;
-			fixed_t highestfloor = openbottom;
-			fixed_t lowestfloor = lowfloor;
 			fixed_t delta1, delta2;
 
 			// Check for frontsector's fake floors
@@ -437,15 +433,15 @@ void P_CameraLineOpening(line_t *linedef)
 
 					delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
 					delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
-					if (bottomheight < lowestceiling && delta1 >= delta2)
-						lowestceiling = bottomheight;
-					else if (bottomheight < highestceiling && delta1 >= delta2)
-						highestceiling = bottomheight;
-
-					if (topheight > highestfloor && delta1 < delta2)
-						highestfloor = topheight;
-					else if (topheight > lowestfloor && delta1 < delta2)
-						lowestfloor = topheight;
+					if (bottomheight < opentop && delta1 >= delta2)
+						opentop = bottomheight;
+					else if (bottomheight < highceiling && delta1 >= delta2)
+						highceiling = bottomheight;
+
+					if (topheight > openbottom && delta1 < delta2)
+						openbottom = topheight;
+					else if (topheight > lowfloor && delta1 < delta2)
+						lowfloor = topheight;
 				}
 
 			// Check for backsectors fake floors
@@ -461,28 +457,16 @@ void P_CameraLineOpening(line_t *linedef)
 
 					delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
 					delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
-					if (bottomheight < lowestceiling && delta1 >= delta2)
-						lowestceiling = bottomheight;
-					else if (bottomheight < highestceiling && delta1 >= delta2)
-						highestceiling = bottomheight;
-
-					if (topheight > highestfloor && delta1 < delta2)
-						highestfloor = topheight;
-					else if (topheight > lowestfloor && delta1 < delta2)
-						lowestfloor = topheight;
+					if (bottomheight < opentop && delta1 >= delta2)
+						opentop = bottomheight;
+					else if (bottomheight < highceiling && delta1 >= delta2)
+						highceiling = bottomheight;
+
+					if (topheight > openbottom && delta1 < delta2)
+						openbottom = topheight;
+					else if (topheight > lowfloor && delta1 < delta2)
+						lowfloor = topheight;
 				}
-
-			if (highestceiling < highceiling)
-				highceiling = highestceiling;
-
-			if (highestfloor > openbottom)
-				openbottom = highestfloor;
-
-			if (lowestceiling < opentop)
-				opentop = lowestceiling;
-
-			if (lowestfloor > lowfloor)
-				lowfloor = lowestfloor;
 		}
 		openrange = opentop - openbottom;
 		return;
@@ -500,23 +484,26 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
 		return;
 	}
 
-	// Treat polyobjects kind of like 3D Floors
+	front = linedef->frontsector;
+	back = linedef->backsector;
+
+	I_Assert(front != NULL);
+	I_Assert(back != NULL);
+
 #ifdef POLYOBJECTS
-	if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT))
+	if (linedef->polyobj)
 	{
-		front = linedef->frontsector;
-		back = linedef->frontsector;
+		// set these defaults so that polyobjects don't interfere with collision above or below them
+		opentop = INT32_MAX;
+		openbottom = INT32_MIN;
+		highceiling = INT32_MIN;
+		lowfloor = INT32_MAX;
+#ifdef ESLOPE
+		opentopslope = openbottomslope = NULL;
+#endif
 	}
 	else
 #endif
-	{
-		front = linedef->frontsector;
-		back = linedef->backsector;
-	}
-
-	I_Assert(front != NULL);
-	I_Assert(back != NULL);
-
 	{ // Set open and high/low values here
 		fixed_t frontheight, backheight;
 
@@ -622,25 +609,49 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
 				}
 			}
 		}
-
-		// Check for fake floors in the sector.
-		if (front->ffloors || back->ffloors
 #ifdef POLYOBJECTS
-		    || linedef->polyobj
+		if (linedef->polyobj)
+		{
+			// Treat polyobj's backsector like a 3D Floor
+			if (linedef->polyobj->flags & POF_TESTHEIGHT)
+			{
+				const sector_t *polysec = linedef->backsector;
+				fixed_t polytop, polybottom;
+				fixed_t delta1, delta2;
+
+				if (linedef->polyobj->flags & POF_CLIPPLANES)
+				{
+					polytop = polysec->ceilingheight;
+					polybottom = polysec->floorheight;
+				}
+				else
+				{
+					polytop = INT32_MAX;
+					polybottom = INT32_MIN;
+				}
+
+				delta1 = abs(mobj->z - (polybottom + ((polytop - polybottom)/2)));
+				delta2 = abs(thingtop - (polybottom + ((polytop - polybottom)/2)));
+
+				if (polybottom < opentop && delta1 >= delta2)
+					opentop = polybottom;
+				else if (polybottom < highceiling && delta1 >= delta2)
+					highceiling = polybottom;
+
+				if (polytop > openbottom && delta1 < delta2)
+					openbottom = polytop;
+				else if (polytop > lowfloor && delta1 < delta2)
+					lowfloor = polytop;
+			}
+			// otherwise don't do anything special, pretend there's nothing else there
+		}
+		else
 #endif
-		   )
+		// Check for fake floors in the sector.
+		if (front->ffloors || back->ffloors)
 		{
 			ffloor_t *rover;
-
-			fixed_t highestceiling = highceiling;
-			fixed_t lowestceiling = opentop;
-			fixed_t highestfloor = openbottom;
-			fixed_t lowestfloor = lowfloor;
 			fixed_t delta1, delta2;
-#ifdef ESLOPE
-			pslope_t *ceilingslope = opentopslope;
-			pslope_t *floorslope = openbottomslope;
-#endif
 
 			// Check for frontsector's fake floors
 			for (rover = front->ffloors; rover; rover = rover->next)
@@ -663,26 +674,26 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
 
 				if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
 				{
-					if (bottomheight < lowestceiling) {
-						lowestceiling = bottomheight;
+					if (bottomheight < opentop) {
+						opentop = bottomheight;
 #ifdef ESLOPE
-						ceilingslope = *rover->b_slope;
+						opentopslope = *rover->b_slope;
 #endif
 					}
-					else if (bottomheight < highestceiling)
-						highestceiling = bottomheight;
+					else if (bottomheight < highceiling)
+						highceiling = bottomheight;
 				}
 
 				if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
 				{
-					if (topheight > highestfloor) {
-						highestfloor = topheight;
+					if (topheight > openbottom) {
+						openbottom = topheight;
 #ifdef ESLOPE
-						floorslope = *rover->t_slope;
+						openbottomslope = *rover->t_slope;
 #endif
 					}
-					else if (topheight > lowestfloor)
-						lowestfloor = topheight;
+					else if (topheight > lowfloor)
+						lowfloor = topheight;
 				}
 			}
 
@@ -707,75 +718,28 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
 
 				if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
 				{
-					if (bottomheight < lowestceiling) {
-						lowestceiling = bottomheight;
+					if (bottomheight < opentop) {
+						opentop = bottomheight;
 #ifdef ESLOPE
-						ceilingslope = *rover->b_slope;
+						opentopslope = *rover->b_slope;
 #endif
 					}
-					else if (bottomheight < highestceiling)
-						highestceiling = bottomheight;
+					else if (bottomheight < highceiling)
+						highceiling = bottomheight;
 				}
 
 				if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
 				{
-					if (topheight > highestfloor) {
-						highestfloor = topheight;
+					if (topheight > openbottom) {
+						openbottom = topheight;
 #ifdef ESLOPE
-						floorslope = *rover->t_slope;
+						openbottomslope = *rover->t_slope;
 #endif
 					}
-					else if (topheight > lowestfloor)
-						lowestfloor = topheight;
-				}
-			}
-
-#ifdef POLYOBJECTS
-			// Treat polyobj's backsector like a 3D Floor
-			if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT))
-			{
-				const sector_t *polysec = linedef->backsector;
-
-				delta1 = abs(mobj->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
-				delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
-				if (polysec->floorheight < lowestceiling && delta1 >= delta2) {
-					lowestceiling = polysec->floorheight;
-#ifdef ESLOPE
-					ceilingslope = NULL;
-#endif
-				}
-				else if (polysec->floorheight < highestceiling && delta1 >= delta2)
-					highestceiling = polysec->floorheight;
-
-				if (polysec->ceilingheight > highestfloor && delta1 < delta2) {
-					highestfloor = polysec->ceilingheight;
-#ifdef ESLOPE
-					floorslope = NULL;
-#endif
+					else if (topheight > lowfloor)
+						lowfloor = topheight;
 				}
-				else if (polysec->ceilingheight > lowestfloor && delta1 < delta2)
-					lowestfloor = polysec->ceilingheight;
-			}
-#endif
-			if (highestceiling < highceiling)
-				highceiling = highestceiling;
-
-			if (highestfloor > openbottom) {
-				openbottom = highestfloor;
-#ifdef ESLOPE
-				openbottomslope = floorslope;
-#endif
-			}
-
-			if (lowestceiling < opentop) {
-				opentop = lowestceiling;
-#ifdef ESLOPE
-				opentopslope = ceilingslope;
-#endif
 			}
-
-			if (lowestfloor > lowfloor)
-				lowfloor = lowestfloor;
 		}
 	}
 
diff --git a/src/p_polyobj.c b/src/p_polyobj.c
index 82c57c85bdbaf2fa5f1ef0daa17ddfc60f4d3986..ba01ee44258e128ea3291197cd449256eba42af7 100644
--- a/src/p_polyobj.c
+++ b/src/p_polyobj.c
@@ -1860,7 +1860,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
 		po->lines[0]->backsector->floorheight = target->z - amtz;
 		po->lines[0]->backsector->ceilingheight = target->z + amtz;
 		// Sal: Remember to check your sectors!
-		P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage));
+		// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
+		//  updating objects in the front one too just added teleporting to ground bugs
 		P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
 		// Apply action to mirroring polyobjects as well
 		start = 0;
@@ -1874,7 +1875,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
 			po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did
 			po->lines[0]->backsector->ceilingheight += diffz;
 			// Sal: Remember to check your sectors!
-			P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage));
+			// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
+			//  updating objects in the front one too just added teleporting to ground bugs
 			P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
 		}
 
@@ -2037,8 +2039,9 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
 	po->lines[0]->backsector->floorheight += momz;
 	po->lines[0]->backsector->ceilingheight += momz;
 	// Sal: Remember to check your sectors!
-	P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage)); // frontsector is NEEDED for crushing
-	P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); // backsector may not be necessary, but just in case
+	// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
+	//  updating objects in the front one too just added teleporting to ground bugs
+	P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
 
 	// Apply action to mirroring polyobjects as well
 	start = 0;
@@ -2052,7 +2055,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
 		po->lines[0]->backsector->floorheight += momz;
 		po->lines[0]->backsector->ceilingheight += momz;
 		// Sal: Remember to check your sectors!
-		P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage));
+		// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
+		//  updating objects in the front one too just added teleporting to ground bugs
 		P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
 	}
 }