From 7b54c0141db6434ac75faf38ee9279c818124aed Mon Sep 17 00:00:00 2001
From: MaxED <j.maxed@gmail.com>
Date: Sun, 26 Jun 2016 22:42:24 +0000
Subject: [PATCH] Changed: single-sided linedefs with only back sidedef present
 are now automatically flipped when loading a map. Changed, "Flip Linedefs"
 action: the action will no longer flip single-sided linedefs with only front
 side. Fixed a crash when trying to determine sprite angles when images with
 non-sprite names, starting with expected characters, were present in the
 Sprites namespace.

---
 Source/Core/Config/ThingTypeInfo.cs           |  8 ++------
 Source/Core/Data/DataManager.cs               |  2 +-
 Source/Core/Data/PK3StructuredReader.cs       |  4 +++-
 Source/Core/Data/WADReader.cs                 | 14 ++++++++++++--
 Source/Core/General/MapManager.cs             |  4 ++++
 Source/Core/IO/UniversalStreamReader.cs       |  2 +-
 .../BuilderModes/ClassicModes/LinedefsMode.cs | 19 ++++++++++++++++++-
 7 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/Source/Core/Config/ThingTypeInfo.cs b/Source/Core/Config/ThingTypeInfo.cs
index d1db85238..dfcaaa4e6 100644
--- a/Source/Core/Config/ThingTypeInfo.cs
+++ b/Source/Core/Config/ThingTypeInfo.cs
@@ -546,11 +546,7 @@ namespace CodeImp.DoomBuilder.Config
 			if(string.IsNullOrEmpty(sprite) || sprite.StartsWith(DataManager.INTERNAL_PREFIX)) return;
 
 			// Skip sprites with strange names
-			if(sprite.Length != 6 && sprite.Length != 8)
-			{
-				General.ErrorLogger.Add(ErrorType.Error, "Error in actor \"" + title + "\":" + index + ". Missing sprite or unsupported sprite name format :\"" + sprite.ToUpperInvariant() + "\"");
-				return;
-			}
+			if(sprite.Length != 6 && sprite.Length != 8) return;
 
 			// Get sprite angle
 			string anglestr = sprite.Substring(5, 1);
@@ -581,7 +577,7 @@ namespace CodeImp.DoomBuilder.Config
 			char sourceframe = sprite[4];
 			foreach(string s in spritenames)
 			{
-				//Check first frame block
+				// Check first frame block
 				char targetframe = s[4];
 				if(targetframe == sourceframe)
 				{
diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs
index 29794eeee..c42c5d3d4 100644
--- a/Source/Core/Data/DataManager.cs
+++ b/Source/Core/Data/DataManager.cs
@@ -1541,7 +1541,7 @@ namespace CodeImp.DoomBuilder.Data
 						}
 						else
 						{
-							General.ErrorLogger.Add(ErrorType.Error, "Missing sprite lump \"" + info.Sprite + "\". Forgot to include required resources?");
+							General.ErrorLogger.Add(ErrorType.Error, "Unable to find sprite lump \"" + info.Sprite + "\" used by actor \"" + ti.Title + "\":" + ti.Index + ". Forgot to include required resources?");
 						}
 					}
 					else
diff --git a/Source/Core/Data/PK3StructuredReader.cs b/Source/Core/Data/PK3StructuredReader.cs
index c2c4328d5..b4d4efb99 100644
--- a/Source/Core/Data/PK3StructuredReader.cs
+++ b/Source/Core/Data/PK3StructuredReader.cs
@@ -441,7 +441,9 @@ namespace CodeImp.DoomBuilder.Data
 			string[] files = GetAllFilesWhichTitleStartsWith(SPRITES_DIR, startswith, true);
 			foreach(string file in files)
 			{
-				result.Add(Path.GetFileNameWithoutExtension(file).ToUpperInvariant());
+				// Some users tend to place all manner of graphics into the "Sprites" folder...
+				string spritename = Path.GetFileNameWithoutExtension(file).ToUpperInvariant();
+				if(WADReader.IsValidSpriteName(spritename)) result.Add(spritename); 
 			}
 
 			return result;
diff --git a/Source/Core/Data/WADReader.cs b/Source/Core/Data/WADReader.cs
index f7569bada..7e1d85512 100644
--- a/Source/Core/Data/WADReader.cs
+++ b/Source/Core/Data/WADReader.cs
@@ -38,6 +38,10 @@ namespace CodeImp.DoomBuilder.Data
 		//mxd. TEXTUREx flags
 		private const int TX_WORLDPANNING = 0x8000;
 
+		//mxd. Sprite recognition. Also http://regexr.com/ is a nice site ^.^
+		private static readonly Regex sprite6 = new Regex(@"(\S{4}[A-Za-z\[\]\\]{1}[0-8]{1})");
+		private static readonly Regex sprite8 = new Regex(@"(\S{4}[A-Za-z\[\]\\]{1}[0-8]{1}[A-Za-z\[\]\\]{1}[0-8]{1})");
+
 		#endregion
 
 		#region ================== Structures
@@ -817,7 +821,7 @@ namespace CodeImp.DoomBuilder.Data
 		
 		#endregion
 
-		#region ================== Sprite
+		#region ================== Sprites
 
 		// This loads the textures
 		public override IEnumerable<ImageData> LoadSprites(Dictionary<string, TexturesParser> cachedparsers)
@@ -929,7 +933,7 @@ namespace CodeImp.DoomBuilder.Data
 			{
 				for(int i = range.start; i < range.end + 1; i++)
 				{
-					if(file.Lumps[i].Name.StartsWith(startswith))
+					if(file.Lumps[i].Name.StartsWith(startswith) && IsValidSpriteName(file.Lumps[i].Name))
 						result.Add(file.Lumps[i].Name);
 				}
 			}
@@ -937,6 +941,12 @@ namespace CodeImp.DoomBuilder.Data
 			return result;
 		}
 
+		//mxd
+		internal static bool IsValidSpriteName(string name)
+		{
+			return (name.Length == 6 && sprite6.IsMatch(name)) || (name.Length == 8 && sprite8.IsMatch(name));
+		}
+
 		#endregion
 
 		#region ================== Voxels (mxd)
diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs
index a0baba22b..efeadcd70 100644
--- a/Source/Core/General/MapManager.cs
+++ b/Source/Core/General/MapManager.cs
@@ -429,6 +429,10 @@ namespace CodeImp.DoomBuilder
 			// Remove unused sectors
 			map.RemoveUnusedSectors(true);
 
+			//mxd. Flip linedefs with only back side
+			int flipsdone = MapSet.FlipBackwardLinedefs(map.Linedefs);
+			if(flipsdone > 0) General.WriteLogLine(flipsdone + " single-sided linedefs were flipped.");
+
 			// Update structures
 			options.ApplyGridSettings();
 			map.UpdateConfiguration();
diff --git a/Source/Core/IO/UniversalStreamReader.cs b/Source/Core/IO/UniversalStreamReader.cs
index cbe5f342c..1474bc76f 100644
--- a/Source/Core/IO/UniversalStreamReader.cs
+++ b/Source/Core/IO/UniversalStreamReader.cs
@@ -248,7 +248,7 @@ namespace CodeImp.DoomBuilder.IO
 				args[2] = GetCollectionEntry(lc, "arg2", false, 0, where);
 				args[3] = GetCollectionEntry(lc, "arg3", false, 0, where);
 				args[4] = GetCollectionEntry(lc, "arg4", false, 0, where);
-				int s1 = GetCollectionEntry(lc, "sidefront", true, -1, where);
+				int s1 = GetCollectionEntry(lc, "sidefront", false, -1, where);
 				int s2 = GetCollectionEntry(lc, "sideback", false, -1, where);
 
 				//mxd. MoreIDs
diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
index a096d1d21..fdd57ae53 100644
--- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
@@ -1579,6 +1579,23 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				return;
 			}
 
+			//mxd. Remove single-sided lines with only front side
+			int selectedcount = selected.Count; // Store initial selection size...
+			List<Linedef> filtered = new List<Linedef>(selectedcount);
+			foreach(Linedef l in selected)
+			{
+				if(l.Back != null || l.Front == null) filtered.Add(l);
+			}
+			selected = filtered;
+
+			//mxd. Any valid lines?
+			if(selected.Count == 0)
+			{
+				General.Interface.DisplayStatus(StatusType.Warning, (selectedcount > 1 ? "Selected linedefs already point in the right direction!" 
+																					   : "Selected linedef already points in the right direction!"));
+				return;
+			}
+
 			// Make undo
 			if(selected.Count > 1)
 			{
@@ -1599,7 +1616,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			}
 
 			// Remove selection if only one linedef was selected
-			if(selected.Count == 1)
+			if(selectedcount == 1)
 			{
 				foreach(Linedef ld in selected) ld.Selected = false;
 				selected.Clear();
-- 
GitLab