From 05a05c640649ebe15382207db141424e89bed370 Mon Sep 17 00:00:00 2001
From: Mitchell Richters <mjr4077au@gmail.com>
Date: Fri, 7 Oct 2022 22:50:29 +1100
Subject: [PATCH] - Duke: Fix interpolation for `SE_20_STRETCH_BRIDGE`, such as
 curtains in E1L1/2/3.

* I'm not sure if there's a better way to handle this, but I had to do the nested `twoSided()` checks to ensure all walls of E1L3's curtains in the execution chair viewing room interpolated as expected.
---
 source/games/duke/src/spawn.cpp | 63 +++++++++++++++++++--------------
 1 file changed, 36 insertions(+), 27 deletions(-)

diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp
index baadb71c7..3f1c3c393 100644
--- a/source/games/duke/src/spawn.cpp
+++ b/source/games/duke/src/spawn.cpp
@@ -718,38 +718,47 @@ void spawneffector(DDukeActor* actor, TArray<DDukeActor*>* actors)
 
 		case SE_20_STRETCH_BRIDGE:
 		{
-			walltype* closewall = nullptr;
-
 			//find the two most clostest wall x's and y's
-			double maxdist = 0x7fffffff;
-
-			for (auto& wal : wallsofsector(sectp))
+			for (unsigned i = 0; i < 2; i++)
 			{
-				double dist = (actor->spr.pos.XY() - wal.pos).LengthSquared();
-				if (dist < maxdist)
+				walltype* closewall = nullptr;
+				double maxdist = 0x7fffffff;
+
+				for (auto& wal : wallsofsector(sectp))
 				{
-					maxdist = dist;
-					closewall = &wal;
+					double dist = (actor->spr.pos.XY() - wal.pos).LengthSquared();
+					if (dist < maxdist && &wal != actor->temp_walls[0])
+					{
+						maxdist = dist;
+						closewall = &wal;
+					}
+				}
+
+				actor->temp_walls[i] = closewall;
+
+				StartInterpolation(actor->temp_walls[i], Interp_Wall_X);
+				StartInterpolation(actor->temp_walls[i], Interp_Wall_Y);
+
+				if (actor->temp_walls[i]->twoSided())
+				{
+					auto nwal = actor->temp_walls[i]->nextWall();
+					StartInterpolation(nwal, Interp_Wall_X);
+					StartInterpolation(nwal, Interp_Wall_Y);
+					nwal = nwal->point2Wall();
+					StartInterpolation(nwal, Interp_Wall_X);
+					StartInterpolation(nwal, Interp_Wall_Y);
+
+					if (nwal->twoSided())
+					{
+						nwal = nwal->nextWall();
+						StartInterpolation(nwal, Interp_Wall_X);
+						StartInterpolation(nwal, Interp_Wall_Y);
+						nwal = nwal->point2Wall();
+						StartInterpolation(nwal, Interp_Wall_X);
+						StartInterpolation(nwal, Interp_Wall_Y);
+					}
 				}
 			}
-
-			actor->temp_walls[0] = closewall;
-
-			maxdist = 0x7fffffff;
-
-			for (auto& wal : wallsofsector(sectp))
-			{
-				double dist = (actor->spr.pos.XY() - wal.pos).LengthSquared();
-				if (dist < maxdist && &wal != actor->temp_walls[0])
-				{
-					maxdist = dist;
-					closewall = &wal;
-				}
-			}
-
-			actor->temp_walls[1] = closewall;
-			StartInterpolation(sectp, Interp_Sect_FloorPanX);
-			StartInterpolation(sectp, Interp_Sect_FloorPanY);
 			break;
 		}