From 82f019b8bdce759b80369a9be045aa7d426801f0 Mon Sep 17 00:00:00 2001
From: biwa <6475593+biwa@users.noreply.github.com>
Date: Sat, 30 May 2020 16:41:05 +0200
Subject: [PATCH] Fixed a potential crash when undoing while having slope
 handle picking enabled

---
 .../VisualModes/BaseVisualMode.cs             | 40 ++++++++++++++++++-
 .../VisualModes/VisualSidedefSlope.cs         |  3 ++
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs
index 60702b08c..f97c07291 100755
--- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs
@@ -1187,14 +1187,27 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			}
 			allslopehandles.Clear();
 
-			if (General.Map.UDMF /* && General.Settings.ShowVisualSlopeHandles */)
+			BuildSlopeHandles(General.Map.Map.Sectors.ToList());
+		}
+
+		private void BuildSlopeHandles(List<Sector> sectors)
+		{
+			if (General.Map.UDMF)
 			{
-				foreach (Sector s in General.Map.Map.Sectors)
+				foreach (Sector s in sectors)
 				{
+					if (s.IsDisposed)
+					{
+						continue;
+					}
+
 					SectorData sectordata = GetSectorData(s);
 
 					sectordata.Update();
 
+					if (allslopehandles.ContainsKey(s))
+						allslopehandles.Remove(s);
+
 					foreach (Sidedef sidedef in s.Sidedefs)
 					{
 						VisualSlope handle = CreateVisualSlopeHandle(sectordata.Floor, sidedef, true);
@@ -1489,6 +1502,29 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			{
 				// Let the core do this (it will just dispose the sectors that were changed)
 				base.ResourcesReloadedPartial();
+
+				// The base doesn't know anything about slobe handles, so we have to clear them up ourself
+				if (General.Map.UDMF)
+				{
+					List<Sector> removedsectors = new List<Sector>();
+
+					// Get the sectors that were disposed...
+					foreach(Sector s in allslopehandles.Keys)
+					{
+						if (s.IsDisposed)
+							removedsectors.Add(s);
+					}
+
+					// ... so that we can remove their slope handles
+					foreach(Sector s in removedsectors)
+					{
+						allslopehandles[s].Clear();
+						allslopehandles.Remove(s);
+					}
+
+					// Rebuild slope handles for the changed sectors
+					BuildSlopeHandles(General.Map.Map.GetMarkedSectors(true));
+				}
 			}
 			else
 			{
diff --git a/Source/Plugins/BuilderModes/VisualModes/VisualSidedefSlope.cs b/Source/Plugins/BuilderModes/VisualModes/VisualSidedefSlope.cs
index 237a586b0..6346c9145 100644
--- a/Source/Plugins/BuilderModes/VisualModes/VisualSidedefSlope.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/VisualSidedefSlope.cs
@@ -84,6 +84,9 @@ namespace CodeImp.DoomBuilder.VisualModes
 		/// </summary>
 		public override bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir)
 		{
+			if (sidedef.IsDisposed || sidedef.Sector.IsDisposed)
+				return false;
+
 			RectangleF bbox = sidedef.Sector.BBox;
 
 			if ((up && plane.Distance(from) > 0.0f) || (!up && plane.Distance(from) < 0.0f))
-- 
GitLab