From 47a9dab56d74fe021f454bccec91e57715f6db94 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <coelckers@zdoom.fake>
Date: Wed, 14 May 2014 12:16:33 +0200
Subject: [PATCH] - allow setting sector planes' plane equations directly from
 UDMF.

---
 specs/udmf_zdoom.txt | 14 +++++++++-
 src/namedef.h        |  9 ++++++
 src/p_udmf.cpp       | 65 ++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt
index d7face672..1128b2e55 100644
--- a/specs/udmf_zdoom.txt
+++ b/specs/udmf_zdoom.txt
@@ -37,7 +37,7 @@ In addition to the base specification ZDoom recognizes the following lumps
 between the TEXTMAP and ENDMAP lumps:
 
     BEHAVIOR = contains compiled ACS code
-    DIALOGUE = contains compiled Strife conversation scripts.
+    DIALOGUE = contains compiled Strife or USDF conversation scripts.
     ZNODES = Nodes (must be stored as extended GL nodes. Compression is allowed
                     but deprecated for portability reasons.)
     BLOCKMAP = blockmap. It is recommended not to include this lump in UDMF maps.
@@ -166,6 +166,14 @@ Note: All <bool> fields default to false unless mentioned otherwise.
       yscaleceiling = <float>;        // Y texture scale of ceiling texture, Default = 1.0.
       rotationfloor = <float>;        // Rotation of floor texture in degrees, Default = 0.0.
       rotationceiling = <float>;      // Rotation of ceiling texture in degrees, Default = 0.0.
+	  ceilingplane_a = <float>;       // Define the plane equation for the sector's ceiling. Default is a horizontal plane at 'heightceiling'.
+	  ceilingplane_b = <float>;       // 'heightceiling' will still be used to calculate texture alignment.
+	  ceilingplane_c = <float>;       // The plane equation will only be used if all 4 values are given.
+	  ceilingplane_d = <float>;
+	  floorplane_a = <float>;         // Define the plane equation for the sector's floor. Default is a horizontal plane at 'heightfloor'.
+	  floorplane_b = <float>;         // 'heightfloor' will still be used to calculate texture alignment.
+	  floorplane_c = <float>;         // The plane equation will only be used if all 4 values are given.
+	  floorplane_d = <float>;
       lightfloor = <integer>;         // The floor's light level. Default is 0.
       lightceiling = <integer>;       // The ceiling's light level. Default is 0.
       lightfloorabsolute = <bool>;    // true = 'lightfloor' is an absolute value. Default is 
@@ -355,6 +363,10 @@ Added waterzone sector property.
 1.22 12.04.2014
 Added transparent line property (to be folded back to core UDMF standard), and health, score, renderstyle, fillcolor, alpha, scale, scalex, scaley, pitch and roll thing properties.
 
+1.24 14.05.2014
+Added plane equations for sector slopes. (Please read carefully to ensure proper use!)
+Changed language describing the DIALOGUE lump to mention USDF as an option.
+
 ===============================================================================
 EOF
 ===============================================================================
diff --git a/src/namedef.h b/src/namedef.h
index ba6de104d..a4c8da638 100644
--- a/src/namedef.h
+++ b/src/namedef.h
@@ -488,6 +488,15 @@ xx(blockhitscan)
 
 xx(Renderstyle)
 
+xx(ceilingplane_a)
+xx(ceilingplane_b)
+xx(ceilingplane_c)
+xx(ceilingplane_d)
+xx(floorplane_a)
+xx(floorplane_b)
+xx(floorplane_c)
+xx(floorplane_d)
+
 // USDF keywords
 xx(Amount)
 xx(Text)
diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp
index 2fa968502..0c380160d 100644
--- a/src/p_udmf.cpp
+++ b/src/p_udmf.cpp
@@ -1245,6 +1245,7 @@ public:
 		int lightcolor = -1;
 		int fadecolor = -1;
 		int desaturation = -1;
+		int fplaneflags = 0, cplaneflags = 0;
 
 		memset(sec, 0, sizeof(*sec));
 		sec->lightlevel = 160;
@@ -1446,6 +1447,48 @@ public:
 					Flag(sec->MoreFlags, SECF_UNDERWATER, key);
 					break;
 
+				case NAME_floorplane_a:
+					fplaneflags |= 1;
+					sec->floorplane.a = CheckFixed(key);
+					break;
+
+				case NAME_floorplane_b:
+					fplaneflags |= 2;
+					sec->floorplane.b = CheckFixed(key);
+					break;
+
+				case NAME_floorplane_c:
+					fplaneflags |= 4;
+					sec->floorplane.c = CheckFixed(key);
+					sec->floorplane.ic = FixedDiv(FRACUNIT, sec->floorplane.c);
+					break;
+
+				case NAME_floorplane_d:
+					fplaneflags |= 8;
+					sec->floorplane.d = CheckFixed(key);
+					break;
+
+				case NAME_ceilingplane_a:
+					cplaneflags |= 1;
+					sec->ceilingplane.a = CheckFixed(key);
+					break;
+
+				case NAME_ceilingplane_b:
+					cplaneflags |= 2;
+					sec->ceilingplane.b = CheckFixed(key);
+					break;
+
+				case NAME_ceilingplane_c:
+					cplaneflags |= 4;
+					sec->ceilingplane.c = CheckFixed(key);
+					sec->ceilingplane.ic = FixedDiv(FRACUNIT, sec->ceilingplane.c);
+					break;
+
+				case NAME_ceilingplane_d:
+					cplaneflags |= 8;
+					sec->ceilingplane.d = CheckFixed(key);
+					break;
+
 				default:
 					break;
 			}
@@ -1457,12 +1500,22 @@ public:
 		}
 
 		sec->secretsector = !!(sec->special&SECRET_MASK);
-		sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor);
-		sec->floorplane.c = FRACUNIT;
-		sec->floorplane.ic = FRACUNIT;
-		sec->ceilingplane.d = sec->GetPlaneTexZ(sector_t::ceiling);
-		sec->ceilingplane.c = -FRACUNIT;
-		sec->ceilingplane.ic = -FRACUNIT;
+		
+		// Reset the planes to their defaults if not all of the plane equation's parameters were found.
+		if (fplaneflags != 15)
+		{
+			sec->floorplane.a = sec->floorplane.b = 0;
+			sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor);
+			sec->floorplane.c = FRACUNIT;
+			sec->floorplane.ic = FRACUNIT;
+		}
+		if (cplaneflags != 15)
+		{
+			sec->ceilingplane.a = sec->ceilingplane.b = 0;
+			sec->ceilingplane.d = sec->GetPlaneTexZ(sector_t::ceiling);
+			sec->ceilingplane.c = -FRACUNIT;
+			sec->ceilingplane.ic = -FRACUNIT;
+		}
 
 		if (lightcolor == -1 && fadecolor == -1 && desaturation == -1)
 		{