From 0dce22ce85adb244aecf3c0de777e108b257730b Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Sun, 14 Feb 2016 21:02:18 +0100
Subject: [PATCH] - some portal considerations.

---
 src/g_heretic/a_hereticweaps.cpp | 13 +++++++++----
 src/r_defs.h                     |  3 +++
 src/r_utility.cpp                | 18 ++++++++++++------
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp
index 619fe7b5af..f51de13e1b 100644
--- a/src/g_heretic/a_hereticweaps.cpp
+++ b/src/g_heretic/a_hereticweaps.cpp
@@ -1077,12 +1077,17 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm)
 	mo = Spawn<ARainPillar> (pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE);
 	// We used bouncecount to store the 3D floor index in A_HideInCeiling
 	if (!mo) return 0;
+	if (mo->Sector->PortalGroup != self->Sector->PortalGroup)
+	{
+		// spawning this through a portal will never work right so abort right away.
+		mo->Destroy();
+		return 0;
+	}
 	fixed_t newz;
-	if (self->bouncecount >= 0 
-		&& (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size())
-		newz = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(pos.x, pos.y);// - 40 * FRACUNIT;
+	if (self->bouncecount >= 0 && (unsigned)self->bouncecount < self->Sector->e->XFloor.ffloors.Size())
+		newz = self->Sector->e->XFloor.ffloors[self->bouncecount]->bottom.plane->ZatPoint(mo);// - 40 * FRACUNIT;
 	else
-		newz = self->Sector->ceilingplane.ZatPoint(pos.x, pos.y);
+		newz = self->Sector->ceilingplane.ZatPoint(mo);
 	int moceiling = P_Find3DFloor(NULL, pos.x, pos.y, newz, false, false, newz);
 	if (moceiling >= 0)
 		mo->SetZ(newz - mo->height, false);
diff --git a/src/r_defs.h b/src/r_defs.h
index da122e14a4..d65b654c2c 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -741,16 +741,19 @@ struct sector_t
 
 	inline bool PortalBlocksView(int plane)
 	{
+		if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true;
 		return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
 	}
 
 	inline bool PortalBlocksMovement(int plane)
 	{
+		if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true;
 		return !!(planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
 	}
 
 	inline bool PortalBlocksSound(int plane)
 	{
+		if (SkyBoxes[plane] == NULL || SkyBoxes[plane]->special1 != SKYBOX_LINKEDPORTAL) return true;
 		return !!(planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
 	}
 
diff --git a/src/r_utility.cpp b/src/r_utility.cpp
index 540ab740a8..794c30d4ce 100644
--- a/src/r_utility.cpp
+++ b/src/r_utility.cpp
@@ -878,16 +878,22 @@ void R_SetupFrame (AActor *actor)
 	interpolator.DoInterpolations (r_TicFrac);
 
 	// Keep the view within the sector's floor and ceiling
-	fixed_t theZ = viewsector->ceilingplane.ZatPoint (viewx, viewy) - 4*FRACUNIT;
-	if (viewz > theZ)
+	if (viewsector->PortalBlocksMovement(sector_t::ceiling))
 	{
-		viewz = theZ;
+		fixed_t theZ = viewsector->ceilingplane.ZatPoint(viewx, viewy) - 4 * FRACUNIT;
+		if (viewz > theZ)
+		{
+			viewz = theZ;
+		}
 	}
 
-	theZ = viewsector->floorplane.ZatPoint (viewx, viewy) + 4*FRACUNIT;
-	if (viewz < theZ)
+	if (viewsector->PortalBlocksMovement(sector_t::floor))
 	{
-		viewz = theZ;
+		fixed_t theZ = viewsector->floorplane.ZatPoint(viewx, viewy) + 4 * FRACUNIT;
+		if (viewz < theZ)
+		{
+			viewz = theZ;
+		}
 	}
 
 	if (!paused)