From 2a404cf1fceb5df1f3b89790fb3426fbaec9c14b Mon Sep 17 00:00:00 2001
From: biwa <6475593+biwa@users.noreply.github.com>
Date: Sat, 11 May 2024 14:28:52 +0200
Subject: [PATCH] Linedefs Mode, Sectors Mode, Things Mode: fixed a problem
 where multi-selecting many spread out map elements could result in an
 exception. Fixes #1053

---
 Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs | 6 +++++-
 Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs  | 6 +++++-
 Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs   | 6 +++++-
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
index e7f1bb546..7520e7c3e 100755
--- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
@@ -362,7 +362,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				if(curdistance < closest2) closest2 = curdistance;
 
 				// Return closer one
-				return (int)(closest1 - closest2);
+				// biwa: the difference between closest1 and closest2 can exceed the capacity of int, and that
+				// sometimes seem to cause problems, resulting in the sorting to throw an ArgumentException
+				// because of inconsistent results. Making sure to only return -1, 0, or 1 seems to fix the issue
+				// See https://github.com/UltimateDoomBuilder/UltimateDoomBuilder/issues/1053
+				return (closest1 - closest2) < 0 ? -1 : ((closest1 - closest2) > 0 ? 1 : 0);
 			});
 
 			return result;
diff --git a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs
index e4c78d583..e936f5174 100755
--- a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs
@@ -722,7 +722,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				}
 
 				// Return closer one
-				return (int)(closest1 - closest2);
+				// biwa: the difference between closest1 and closest2 can exceed the capacity of int, and that
+				// sometimes seem to cause problems, resulting in the sorting to throw an ArgumentException
+				// because of inconsistent results. Making sure to only return -1, 0, or 1 seems to fix the issue
+				// See https://github.com/UltimateDoomBuilder/UltimateDoomBuilder/issues/1053
+				return (closest1 - closest2) < 0 ? -1 : ((closest1 - closest2) > 0 ? 1 : 0);
 			});
 
 			return result;
diff --git a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs
index 247ec2619..c6d39c6d6 100755
--- a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs
@@ -1011,7 +1011,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				double closest2 = Vector2D.DistanceSq(t2.Position, targetpoint);
 
 				// Return closer one
-				return (int)(closest1 - closest2);
+				// biwa: the difference between closest1 and closest2 can exceed the capacity of int, and that
+				// sometimes seem to cause problems, resulting in the sorting to throw an ArgumentException
+				// because of inconsistent results. Making sure to only return -1, 0, or 1 seems to fix the issue
+				// See https://github.com/UltimateDoomBuilder/UltimateDoomBuilder/issues/1053
+				return (closest1 - closest2) < 0 ? -1 : ((closest1 - closest2) > 0 ? 1 : 0);
 			});
 
 			return result;
-- 
GitLab