diff --git a/Build/Configurations/Includes/ZDoom_misc.cfg b/Build/Configurations/Includes/ZDoom_misc.cfg
index 676295848bbef7362d5f4e4e716d0754b49361fb..7e8b65744506228ba0540789088f811991904243 100644
--- a/Build/Configurations/Includes/ZDoom_misc.cfg
+++ b/Build/Configurations/Includes/ZDoom_misc.cfg
@@ -175,6 +175,31 @@ thingflagscompare_udmf
 	}
 }
 
+//mxd. SectorAction flags renaming
+secact_flagsrename
+{
+	DoomMapSetIO
+	{
+		8 = "Monsters activate";
+	}
+	
+	HexenMapSetIO
+	{
+		8 = "Monsters activate";
+		16 = "Projectiles activate";
+		8192 = "Players can't activate";
+		16384 = "Activate once only";
+	}
+	
+	UniversalMapSetIO
+	{
+		ambush = "Monsters activate";
+		dormant = "Projectiles activate";
+		strifeally = "Players can't activate";
+		standing = "Activate once only";
+	}
+}
+
 // Default sector brightness levels
 sectorbrightness
 {
diff --git a/Build/Configurations/Includes/ZDoom_things.cfg b/Build/Configurations/Includes/ZDoom_things.cfg
index 13740cdc1f5094d2e1e54ac66544faaed9d8a498..cbf355d445bcf7d6d7efa9c058d986a3436855b5 100644
--- a/Build/Configurations/Includes/ZDoom_things.cfg
+++ b/Build/Configurations/Includes/ZDoom_things.cfg
@@ -757,30 +757,35 @@ zdoom
 		{
 			title = "Actor enters sector";
 			class = "SecActEnter";
+			flagsrename { include("ZDoom_misc.cfg", "secact_flagsrename") }
 		} 
 		
 		9989
 		{
 			title = "Actor hits fake floor";
 			class = "SecActHitFakeFloor";
+			flagsrename { include("ZDoom_misc.cfg", "secact_flagsrename") }
 		}
 		
 		9996
 		{
 			title = "Actor hits ceiling";
 			class = "SecActHitCeil";
+			flagsrename { include("ZDoom_misc.cfg", "secact_flagsrename") }
 		}
 		
 		9999
 		{
 			title = "Actor hits floor";
 			class = "SecActHitFloor";
+			flagsrename { include("ZDoom_misc.cfg", "secact_flagsrename") }
 		} 
 		
 		9997
 		{
 			title = "Actor leaves sector";
 			class = "SecActExit";
+			flagsrename { include("ZDoom_misc.cfg", "secact_flagsrename") }
 		}
 		
 		9982
diff --git a/Help/gc_thingsettings.html b/Help/gc_thingsettings.html
index 3df49c8198d39fa4d28bf7030580fd76c9b08e54..db75c8a26c9a07433930c293c095e15da11d961d 100644
--- a/Help/gc_thingsettings.html
+++ b/Help/gc_thingsettings.html
@@ -22,25 +22,23 @@
     This defines what the default flags should be first the first new thing when inserted. In map formats that use numeric thing flags, the settings in this structure should be the numeric flags to set. In map formats that use named flags, the settings must be the names of the flags to set. The value of the settings is optional and is ignored by Doom Builder.<br />
     <br />
     Example for numeric flags:
-  <pre>
-defaultthingflags
+  <pre>defaultthingflags
 {
-	1;
-	2;
-	4;
-	32;
+  1;
+  2;
+  4;
+  32;
 }
 </pre>
   <br />
   Example for named flags:
-  <pre>
-defaultthingflags
+  <pre>defaultthingflags
 {
-	skill1;
-	skill2;
-	skill3;
-	single;
-	coop;
+  skill1;
+  skill2;
+  skill3;
+  single;
+  coop;
 }
 </pre>
   <br />
@@ -51,16 +49,16 @@ defaultthingflags
   <pre>        
 thingrenderstyles
 {
-	normal = "Normal";
-	translucent = "Translucent";
-	soultrans = "Translucent (Lost Soul)";
-	translucentstencil = "Translucent (stencil)";
-	add = "Additive";
-	subtract = "Subtractive";
-	stencil = "Stencil";
-	fuzzy = "Fuzzy";
-	optfuzzy = "Fuzzy/Shadow (uses r_drawfuzz CVAR)";
-	none = "None";
+  normal = "Normal";
+  translucent = "Translucent";
+  soultrans = "Translucent (Lost Soul)";
+  translucentstencil = "Translucent (stencil)";
+  add = "Additive";
+  subtract = "Subtractive";
+  stencil = "Stencil";
+  fuzzy = "Fuzzy";
+  optfuzzy = "Fuzzy/Shadow (uses r_drawfuzz CVAR)";
+  none = "None";
 }
 </pre>
   <br />
@@ -166,13 +164,46 @@ thingrenderstyles
   When set to true, the sprite set in the Game Configuration will be used even if a DECORATE actor definition of this thing contains a different sprite.<br />
   <br />
   <b class="fat">class</b> (string) - <span class="red">GZDB only</span>.<br />
-  Sets  DECORATE class name, which corresponds to this thing. Used internally to attach models and dynamic lights to given thing and when looking for an actor class to inherit from in DECORATE parser.<br />
+  Sets DECORATE class name, which corresponds to this thing. Used internally to attach models and dynamic lights to given thing and when looking for an actor class to inherit from in DECORATE parser.<br />
   <strong>Example:</strong>
   <pre>3001
 {
-    title = "Imp";
-    sprite = "TROOA2A8";
-    <span class="blue">class = "DoomImp";</span>
+  title = "Imp";
+  sprite = "TROOA2A8";
+  <span class="blue">class = "DoomImp";</span>
+}</pre>
+<br />
+  <b class="fat">locksprite</b> (boolean) - <span class="red">GZDB only</span>.<br />
+  When set to true, the sprite set in the Game Configuration will be used even if a DECORATE actor definition of this thing contains a different sprite.<br />
+  <br />
+  <b class="fat">flagsrename</b> (structure) - <span class="red">GZDB only</span>.<br />
+  Allows to specify custom flag names for specific Things for every supported map format.<br />
+  <strong>Example:</strong>
+  <pre>9998
+{
+  title = "Actor enters sector";
+  class = "SecActEnter";
+  <span class="blue">flagsrename
+  {
+    DoomMapSetIO
+    {
+      8 = "Monsters activate";
+    }
+    HexenMapSetIO
+    {
+      8 = "Monsters activate";
+      16 = "Projectiles activate";
+      8192 = "Players can't activate";
+      16384 = "Activate once only";
+    }
+    UniversalMapSetIO
+    {
+      ambush = "Monsters activate";
+      dormant = "Projectiles activate";
+      strifeally = "Players can't activate";
+      standing = "Activate once only";
+    }
+  }</span>
 }</pre>
 <br />
 <span class="big">Thing argument definitions:</span><br />
diff --git a/Help/gzdb/text_lumps.html b/Help/gzdb/text_lumps.html
index 0d75e11f51f953a722c88356349565007e4c441e..8f8a50131bce8900293da7c4bcc464125ac58366 100644
--- a/Help/gzdb/text_lumps.html
+++ b/Help/gzdb/text_lumps.html
@@ -63,7 +63,8 @@
     Sound Sequence and Sound Sequence Group definitions are loaded and can be selected in the "Sound sequence" drop-down of the Edit Sector window (UDMF only). 
     
     <h2>LOCKDEFS:</h2>
-    Lock definitions are loaded. The values are used to  populate &quot;<strong>keys</strong>&quot; Game Configuration enum.
+    Lock definitions are loaded. The values are used to  populate &quot;<strong>keys</strong>&quot; Game Configuration enum.<br />
+    You can specify a lock title by adding &quot;<strong>//$Title</strong>&quot; special comment inside a lock's definition body.
     <h2>TERRAIN:</h2>
     Terrain names are loaded and used in the floor and ceiling "Terrain" drop-downs of the Edit Sector window (UDMF only).
     
@@ -91,12 +92,12 @@
     <p>If you are creating maps for Doom or Doom 2, you probably don't need to read this, since required information is already added for those games.<br />
       <br />
 	  <b>To load models or dynamic lights defined in GLDEFS for things defined in configuration files:</b><br />
-	  To display a model instead of a thing sprite, or to attach a light defined in GLDEFS, GZDB needs to know a thing's class name (because that's how overrides are defined in MODELDEF and GLDEFS). Things defined in Doom Builder configuration files don't have this value. So, if you aren't using configs, which came with GZDoom Builder, or you are creating maps for games other than Doom and Doom 2, you'll need to add a new value named "class" to thing definition in game configuration:<br />
+	  To display a model instead of a thing sprite, or to attach a light defined in GLDEFS, GZDB needs to know a thing's class name (because that's how overrides are defined in MODELDEF and GLDEFS). Things defined in Doom Builder configuration files don't have this value. So, if you aren't using configs, which came with GZDoom Builder, or you are creating maps for games other than Doom and Doom 2, you'll need to add a new value named "class" to thing definition in game configuration:
 <pre>3001
 {
-    title = "Imp";
-    sprite = "TROOA2A8";
-    <span class="blue">class = "DoomImp";</span> // <- you'll need to add this value
+  title = "Imp";
+  sprite = "TROOA2A8";
+  <span class="blue">class = "DoomImp";</span> // <- you'll need to add this value
 }</pre>
  <br>
  You can find all thing class names at <a href="http://www.zdoom.org/wiki/Classes">http://www.zdoom.org/wiki/Classes</a>.</p>
diff --git a/Source/Core/Config/ThingTypeInfo.cs b/Source/Core/Config/ThingTypeInfo.cs
index 23d8b8133941511f5734366f65c52fb1715b9ef8..4081155aa4b9014f002d74316999a68135270ff5 100644
--- a/Source/Core/Config/ThingTypeInfo.cs
+++ b/Source/Core/Config/ThingTypeInfo.cs
@@ -17,6 +17,7 @@
 #region ================== Namespaces
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Drawing;
 using System.Globalization;
@@ -85,6 +86,7 @@ namespace CodeImp.DoomBuilder.Config
 		private readonly bool locksprite; //mxd
 		private bool obsolete; //mxd
 		private string obsoletemessage; //mxd
+		private Dictionary<string, Dictionary<string, string>> flagsrename; //mxd. <MapSetIOName, <flag, title>>
 
 		//mxd. GZDoom rendering properties
 		private ThingRenderMode rendermode;
@@ -126,6 +128,7 @@ namespace CodeImp.DoomBuilder.Config
 		public SizeF SpriteScale { get { return spritescale; } }
 		public string ClassName { get { return classname; } } //mxd. Need this to add model overrides for things defined in configs
 		public string LightName { get { return lightname; } } //mxd
+		public Dictionary<string, string> FlagsRename { get { return flagsrename.ContainsKey(General.Map.Config.FormatInterface) ? flagsrename[General.Map.Config.FormatInterface] : null ; } } //mxd
 
 		//mxd. GZDoom rendering properties
 		public ThingRenderMode RenderMode { get { return rendermode; } }
@@ -168,6 +171,7 @@ namespace CodeImp.DoomBuilder.Config
 			this.absolutez = false;
 			this.xybillboard = false;
 			this.locksprite = false; //mxd
+			this.flagsrename = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); //mxd
 			
 			// We have no destructor
 			GC.SuppressFinalize(this);
@@ -207,6 +211,28 @@ namespace CodeImp.DoomBuilder.Config
 			this.spritescale = new SizeF(sscale, sscale);
 			this.locksprite = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".locksprite", false); //mxd
 			this.classname = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".class", String.Empty); //mxd
+
+			//mxd. Read flagsrename
+			this.flagsrename = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
+			IDictionary maindic = cfg.ReadSetting("thingtypes." + cat.Name + "." + key + ".flagsrename", new Hashtable());
+			foreach(DictionaryEntry de in maindic)
+			{
+				string ioname = de.Key.ToString().ToLowerInvariant();
+				switch(ioname)
+				{
+					case "doommapsetio":
+					case "hexenmapsetio":
+					case "universalmapsetio":
+						IDictionary flagdic = de.Value as IDictionary;
+						if(flagdic == null) continue;
+						flagsrename.Add(ioname, new Dictionary<string, string>());
+						foreach(DictionaryEntry fe in flagdic)
+							flagsrename[ioname].Add(fe.Key.ToString(), fe.Value.ToString());
+						break;
+
+					default: throw new NotImplementedException("Unsupported MapSetIO");
+				}
+			}
 			
 			// Read the args
 			for(int i = 0; i < Linedef.NUM_ARGS; i++)
@@ -254,7 +280,8 @@ namespace CodeImp.DoomBuilder.Config
 			this.fixedrotation = cat.FixedRotation; //mxd
 			this.absolutez = cat.AbsoluteZ;
 			this.spritescale = new SizeF(cat.SpriteScale, cat.SpriteScale);
-			this.locksprite = false;
+			this.locksprite = false; //mxd
+			this.flagsrename = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); //mxd
 
 			// Safety
 			if(this.radius < 4f || this.fixedsize) this.radius = THING_FIXED_SIZE;
@@ -298,6 +325,7 @@ namespace CodeImp.DoomBuilder.Config
 			this.fixedrotation = cat.FixedRotation; //mxd
 			this.absolutez = cat.AbsoluteZ;
 			this.spritescale = new SizeF(cat.SpriteScale, cat.SpriteScale);
+			this.flagsrename = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); //mxd
 
 			// Safety
 			if(this.hangs && this.absolutez) this.hangs = false; //mxd
@@ -344,6 +372,7 @@ namespace CodeImp.DoomBuilder.Config
 			this.fixedrotation = cat.FixedRotation; //mxd
 			this.absolutez = cat.AbsoluteZ;
 			this.spritescale = new SizeF(cat.SpriteScale, cat.SpriteScale);
+			this.flagsrename = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); //mxd
 
 			// Safety
 			if(this.hangs && this.absolutez) this.hangs = false; //mxd
@@ -393,6 +422,7 @@ namespace CodeImp.DoomBuilder.Config
 			this.absolutez = other.absolutez;
 			this.xybillboard = other.xybillboard; //mxd
 			this.spritescale = new SizeF(other.spritescale.Width, other.spritescale.Height);
+			this.flagsrename = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); //mxd
 
 			//mxd. Copy GZDoom rendering properties
 			this.rendermode = other.rendermode;
diff --git a/Source/Core/Controls/ThingInfoPanel.cs b/Source/Core/Controls/ThingInfoPanel.cs
index 3a5f993adcb0e3a1220179130922197094701cca..6d469d3e6a6c3aed5339f46605b92621850cbdac 100644
--- a/Source/Core/Controls/ThingInfoPanel.cs
+++ b/Source/Core/Controls/ThingInfoPanel.cs
@@ -153,8 +153,8 @@ namespace CodeImp.DoomBuilder.Controls
 			}
 
 			// Apply script args?
-			Label[] arglabels = new[] { arglbl1, arglbl2, arglbl3, arglbl4, arglbl5 };
-			Label[] args = new[] { arg1, arg2, arg3, arg4, arg5 };
+			Label[] arglabels = { arglbl1, arglbl2, arglbl3, arglbl4, arglbl5 };
+			Label[] args = { arg1, arg2, arg3, arg4, arg5 };
 
 			if(scriptitem != null)
 			{
@@ -195,10 +195,17 @@ namespace CodeImp.DoomBuilder.Controls
 
 			//mxd. Flags
 			flags.Items.Clear();
+			Dictionary<string, string> flagsrename = ti.FlagsRename;
 			foreach(KeyValuePair<string, string> group in General.Map.Config.ThingFlags)
 			{
 				if(t.Flags.ContainsKey(group.Key) && t.Flags[group.Key])
-					flags.Items.Add(new ListViewItem(group.Value) { Checked = true });
+				{
+					ListViewItem lvi = (flagsrename != null && flagsrename.ContainsKey(group.Key)) 
+						? new ListViewItem(flagsrename[group.Key]) { ForeColor = SystemColors.HotTrack } 
+						: new ListViewItem(group.Value);
+					lvi.Checked = true;
+					flags.Items.Add(lvi);
+				}
 			}
 
 			//mxd. Flags panel visibility and size
diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs
index 93fb5aab458effe5a48591d279dd6b78236e179d..6f26d71229745c2c4bd312fe5ae061230f9439e7 100644
--- a/Source/Core/Data/DataManager.cs
+++ b/Source/Core/Data/DataManager.cs
@@ -105,6 +105,8 @@ namespace CodeImp.DoomBuilder.Data
 		private string[] damagetypes;
 		private Dictionary<string, PixelColor> knowncolors; // Colors parsed from X11R6RGB lump. Color names are lowercase without spaces
 		private CvarsCollection cvars; // Variables parsed from CVARINFO
+		private Dictionary<int, PixelColor> lockcolors; // Lock colors defined in LOCKDEFS
+		private Dictionary<int, int> lockableactions; // <Action number, arg referenceing "keys" enum number>
 
 		//mxd. Text resources
 		private Dictionary<ScriptType, HashSet<TextResource>> textresources; 
@@ -168,6 +170,8 @@ namespace CodeImp.DoomBuilder.Data
 		public Dictionary<string, PixelColor> KnownColors { get { return knowncolors; } }
 		internal Dictionary<ScriptType, HashSet<TextResource>> TextResources { get { return textresources; } }
 		internal CvarsCollection CVars { get { return cvars; } }
+		public Dictionary<int, PixelColor> LockColors { get { return lockcolors; } }
+		public Dictionary<int, int> LockableActions { get { return lockableactions; } }
 
 		//mxd
 		internal IEnumerable<DataReader> Containers { get { return containers; } }
@@ -2798,6 +2802,7 @@ namespace CodeImp.DoomBuilder.Data
 
 			// Apply to the enums list?
 			EnumList keys = parser.GetLockDefs();
+			lockableactions = new Dictionary<int, int>();
 			if(keys.Count > 0)
 			{
 				keys.Insert(0, new EnumItem("0", "None"));
@@ -2812,9 +2817,22 @@ namespace CodeImp.DoomBuilder.Data
 
 				foreach(LinedefActionInfo info in General.Map.Config.LinedefActions.Values)
 				{
-					foreach(ArgumentInfo ai in info.Args)
-						if(ai.Enum.Name == "keys") ai.Enum = General.Map.Config.Enums["keys"];
+					for(int i = 0; i < info.Args.Length; i++)
+					{
+						if(info.Args[i].Enum.Name == "keys")
+						{
+							info.Args[i].Enum = General.Map.Config.Enums["keys"];
+							lockableactions[info.Index] = i;
+						}
+					}
 				}
+
+				// Also store lock colors
+				lockcolors = parser.MapColors;
+			}
+			else
+			{
+				lockcolors = new Dictionary<int, PixelColor>();
 			}
 		}
 
diff --git a/Source/Core/Windows/ThingEditForm.cs b/Source/Core/Windows/ThingEditForm.cs
index 76dc045fcf9737c245e27b826d203bc543da8c2b..5a18300cf128feda9b3bf34c07469d58256bf289 100644
--- a/Source/Core/Windows/ThingEditForm.cs
+++ b/Source/Core/Windows/ThingEditForm.cs
@@ -50,6 +50,7 @@ namespace CodeImp.DoomBuilder.Windows
 		private bool undocreated; //mxd
 		private static bool useabsoluteheight; //mxd
 		private List<ThingProperties> thingprops; //mxd
+		private Dictionary<string, string> flagsrename; //mxd
 
 		//mxd. Window setup stuff
 		private static Point location = Point.Empty;
@@ -186,6 +187,9 @@ namespace CodeImp.DoomBuilder.Windows
 			posY.ButtonStep = General.Map.Grid.GridSize;
 			posZ.ButtonStep = General.Map.Grid.GridSize;
 
+			//mxd
+			thinginfo = General.Map.Data.GetThingInfoEx(ft.Type);
+
 			// Action/tags
 			action.Value = ft.Action;
 			if(General.Map.FormatInterface.HasThingTag) //mxd
@@ -213,7 +217,10 @@ namespace CodeImp.DoomBuilder.Windows
 				ThingTypeInfo info = thingtype.GetSelectedInfo(); //mxd
 
 				if(info != null && info.Index != t.Type)
+				{
 					thingtype.ClearSelectedType();
+					thinginfo = null; //mxd
+				}
 				
 				// Flags
 				foreach(CheckBox c in flags.Checkboxes)
@@ -263,6 +270,7 @@ namespace CodeImp.DoomBuilder.Windows
 
 			argscontrol.UpdateScriptControls(); //mxd
 			actionhelp.UpdateAction(action.GetValue()); //mxd
+			UpdateFlagNames(); //mxd
 		}
 
 		//mxd
@@ -274,6 +282,51 @@ namespace CodeImp.DoomBuilder.Windows
 			//mxd. Make undo
 			General.Map.UndoRedo.CreateUndo("Edit " + (things.Count > 1 ? things.Count + " things" : "thing"));
 		}
+
+		//mxd
+		private void UpdateFlagNames()
+		{
+			Dictionary<string, string> newflagsrename = (thinginfo != null ? thinginfo.FlagsRename : null);
+
+			// Update flag names?
+			if(flagsrename != null || newflagsrename != null)
+			{
+				flags.SuspendLayout();
+
+				// Restore default flags?
+				if(flagsrename != null)
+				{
+					foreach(CheckBox cb in flags.Checkboxes)
+					{
+						string flag = cb.Tag.ToString();
+						if(flagsrename.ContainsKey(flag))
+						{
+							cb.Text = General.Map.Config.ThingFlags[flag];
+							cb.ForeColor = SystemColors.WindowText;
+						}
+					}
+				}
+
+				// Apply new renaming?
+				if(newflagsrename != null)
+				{
+					foreach(CheckBox cb in flags.Checkboxes)
+					{
+						string flag = cb.Tag.ToString();
+						if(newflagsrename.ContainsKey(flag))
+						{
+							cb.Text = newflagsrename[flag];
+							cb.ForeColor = SystemColors.HotTrack;
+						}
+					}
+				}
+
+				flags.ResumeLayout();
+			}
+
+			// Store current flag names
+			flagsrename = newflagsrename;
+		}
 		
 		#endregion
 
@@ -569,6 +622,8 @@ namespace CodeImp.DoomBuilder.Windows
 				t.UpdateConfiguration();
 			}
 
+			UpdateFlagNames(); //mxd
+
 			General.Map.IsChanged = true;
 			if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
 		}
diff --git a/Source/Core/Windows/ThingEditFormUDMF.cs b/Source/Core/Windows/ThingEditFormUDMF.cs
index 8f3350aa94e02049f77a77f2162a93df5b974f92..df08d4509d11c52d5d040b2ecf4cdcaeb416265a 100644
--- a/Source/Core/Windows/ThingEditFormUDMF.cs
+++ b/Source/Core/Windows/ThingEditFormUDMF.cs
@@ -51,6 +51,7 @@ namespace CodeImp.DoomBuilder.Windows
 		private static bool useabsoluteheight; //mxd
 		private List<ThingProperties> thingprops; //mxd
 		private readonly string[] renderstyles; //mxd
+		private Dictionary<string, string> flagsrename; //mxd
 
 		//mxd. Window setup stuff
 		private static Point location = Point.Empty;
@@ -207,6 +208,7 @@ namespace CodeImp.DoomBuilder.Windows
 			ThingTypeInfo fti = General.Map.Data.GetThingInfoEx(ft.Type);
 			if(fti != null && fti.Actor != null && fti.Actor.UserVars.Count > 0)
 				fieldslist.SetUserVars(fti.Actor.UserVars, ft.Fields, true);
+			thinginfo = fti; //mxd
 
 			// Custom fields
 			fieldslist.SetValues(ft.Fields, true);
@@ -245,7 +247,11 @@ namespace CodeImp.DoomBuilder.Windows
 
 				// Type does not match?
 				ThingTypeInfo info = thingtype.GetSelectedInfo(); //mxd
-				if(info != null && info.Index != t.Type) thingtype.ClearSelectedType();
+				if(info != null && info.Index != t.Type)
+				{
+					thingtype.ClearSelectedType();
+					thinginfo = null; //mxd
+				}
 
 				// Flags
 				foreach(CheckBox c in flags.Checkboxes) 
@@ -324,6 +330,7 @@ namespace CodeImp.DoomBuilder.Windows
 			actionhelp.UpdateAction(action.GetValue()); //mxd
 			labelScale.Enabled = scale.NonDefaultValue; //mxd
 			commenteditor.FinishSetup(); //mxd
+			UpdateFlagNames(); //mxd
 		}
 
 		//mxd
@@ -337,6 +344,51 @@ namespace CodeImp.DoomBuilder.Windows
 			foreach(Thing t in things) t.Fields.BeforeFieldsChange();
 		}
 
+		//mxd
+		private void UpdateFlagNames()
+		{
+			Dictionary<string, string> newflagsrename = (thinginfo != null ? thinginfo.FlagsRename : null);
+			
+			// Update flag names?
+			if(flagsrename != null || newflagsrename != null)
+			{
+				flags.SuspendLayout();
+
+				// Restore default flags?
+				if(flagsrename != null)
+				{
+					foreach(CheckBox cb in flags.Checkboxes)
+					{
+						string flag = cb.Tag.ToString();
+						if(flagsrename.ContainsKey(flag))
+						{
+							cb.Text = General.Map.Config.ThingFlags[flag];
+							cb.ForeColor = SystemColors.WindowText;
+						}
+					}
+				}
+
+				// Apply new renaming?
+				if(newflagsrename != null)
+				{
+					foreach(CheckBox cb in flags.Checkboxes)
+					{
+						string flag = cb.Tag.ToString();
+						if(newflagsrename.ContainsKey(flag))
+						{
+							cb.Text = newflagsrename[flag];
+							cb.ForeColor = SystemColors.HotTrack;
+						}
+					}
+				}
+
+				flags.ResumeLayout();
+			}
+
+			// Store current flag names
+			flagsrename = newflagsrename;
+		}
+
 		#endregion
 
 		#region ================== Events
@@ -710,6 +762,8 @@ namespace CodeImp.DoomBuilder.Windows
 				t.UpdateConfiguration();
 			}
 
+			UpdateFlagNames(); //mxd
+
 			General.Map.IsChanged = true;
 			if(OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty);
 		}
diff --git a/Source/Core/ZDoom/LockDefsParser.cs b/Source/Core/ZDoom/LockDefsParser.cs
index 4ff8cf603ed8648855a434734d8cd764c4b9b758..ef50e236029adb3abc41ab1598ce811bf163fed0 100644
--- a/Source/Core/ZDoom/LockDefsParser.cs
+++ b/Source/Core/ZDoom/LockDefsParser.cs
@@ -1,6 +1,7 @@
 using System.Collections.Generic;
 using CodeImp.DoomBuilder.Config;
 using CodeImp.DoomBuilder.Data;
+using CodeImp.DoomBuilder.Rendering;
 
 namespace CodeImp.DoomBuilder.ZDoom
 {
@@ -9,10 +10,14 @@ namespace CodeImp.DoomBuilder.ZDoom
 		internal override ScriptType ScriptType { get { return ScriptType.LOCKDEFS; } }
 
 		private Dictionary<int, string> locks;
+		private Dictionary<int, PixelColor> mapcolors;
+
+		public Dictionary<int, PixelColor> MapColors { get { return mapcolors; } }
 
 		public LockDefsParser()
 		{
 			locks = new Dictionary<int, string>();
+			mapcolors = new Dictionary<int, PixelColor>();
 		}
 
 		public override bool Parse(TextResourceData data, bool clearerrors)
@@ -32,6 +37,8 @@ namespace CodeImp.DoomBuilder.ZDoom
 			string locktitle = string.Empty;
 			string game = string.Empty;
 			int bracelevel = 0;
+			long lockstartpos = -1;
+			PixelColor mapcolor = new PixelColor();
 
 			while(SkipWhitespace(true))
 			{
@@ -64,10 +71,13 @@ namespace CodeImp.DoomBuilder.ZDoom
 						//wiki: The locknumber must be in the 1-to-255 range
 						if(locknum < 1 || locknum > 255)
 						{
-							ReportError("The locknumber must be in the 1-to-255 range, but is " + locknum);
+							ReportError("The locknumber must be in the [1 .. 255] range, but is " + locknum);
 							return false;
 						}
 
+						// Store position
+						lockstartpos = datastream.Position;
+
 						SkipWhitespace(true);
 						token = ReadToken().ToLowerInvariant();
 						if(!string.IsNullOrEmpty(token))
@@ -93,6 +103,51 @@ namespace CodeImp.DoomBuilder.ZDoom
 						locktitle = StripQuotes(ReadToken(false));
 						break;
 
+					// Mapcolor r g b
+					case "mapcolor":
+						int r = 0;
+						int g = 0;
+						int b = 0;
+
+						SkipWhitespace(false);
+						if(!ReadSignedInt(ref r))
+						{
+							ReportError("Expected Mapcolor Red value");
+							return false;
+						}
+						if(r < 0 || r > 255)
+						{
+							ReportError("Mapcolor Red value must be in [0 .. 255] range, but is " + r);
+							return false;
+						}
+
+						SkipWhitespace(false);
+						if(!ReadSignedInt(ref g))
+						{
+							ReportError("Expected Mapcolor Green value");
+							return false;
+						}
+						if(g < 0 || g > 255)
+						{
+							ReportError("Mapcolor Green value must be in [0 .. 255] range, but is " + g);
+							return false;
+						}
+
+						SkipWhitespace(false);
+						if(!ReadSignedInt(ref b))
+						{
+							ReportError("Expected Mapcolor Blue value");
+							return false;
+						}
+						if(b < 0 || b > 255)
+						{
+							ReportError("Mapcolor Blue value must be in [0 .. 255] range, but is " + b);
+							return false;
+						}
+
+						mapcolor = new PixelColor(255, (byte)r, (byte)g, (byte)b);
+						break;
+
 					case "{":
 						bracelevel++;
 						break;
@@ -104,18 +159,32 @@ namespace CodeImp.DoomBuilder.ZDoom
 						if(locknum > 0 && (string.IsNullOrEmpty(game) || General.Map.Config.BaseGame == game))
 						{
 							// No custom title given?
-							if(string.IsNullOrEmpty(locktitle)) locktitle = "Lock " + locknum;
+							if(string.IsNullOrEmpty(locktitle))
+							{
+								locktitle = "Lock " + locknum;
+							}
 
+							// Lock already defined?
 							if(locks.ContainsKey(locknum))
+							{
+								// Do some stream poition hacking to make the warning point to the correct line
+								long curpos = datastream.Position;
+								if(lockstartpos != -1) datastream.Position = lockstartpos;
 								LogWarning("Lock " + locknum + " is double-defined as \"" + locks[locknum] + "\" and \"" + locktitle + "\"");
+								datastream.Position = curpos;
+							}
 
+							// Add to collections
 							locks[locknum] = locktitle;
+							if(mapcolor.a == 255) mapcolors[locknum] = mapcolor;
 						}
 
 						// Reset values
 						locknum = -1;
 						locktitle = string.Empty;
 						game = string.Empty;
+						mapcolor = new PixelColor();
+						lockstartpos = -1;
 						break;
 				}
 			}
diff --git a/Source/Plugins/AutomapMode/AutomapMode.cs b/Source/Plugins/AutomapMode/AutomapMode.cs
index 69fe1f141b77d235ddc57130b628dc29cf5156ae..1077b856a5080ddb0aacd12e55a038ea7634c8c5 100644
--- a/Source/Plugins/AutomapMode/AutomapMode.cs
+++ b/Source/Plugins/AutomapMode/AutomapMode.cs
@@ -1,15 +1,15 @@
 
 #region ================== Copyright (c) 2016 Boris Iwanski
 
-/*
- * Copyright (c) 2016 Boris Iwanski https://github.com/biwa/automapmode
- * This program is released under GNU General Public License
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
+/*
+ * Copyright (c) 2016 Boris Iwanski https://github.com/biwa/automapmode
+ * This program is released under GNU General Public License
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
  */
 
 #endregion
@@ -21,21 +21,21 @@ using System.Collections.Generic;
 using System.Drawing;
 using System.Windows.Forms;
 using CodeImp.DoomBuilder.Config;
-using CodeImp.DoomBuilder.Map;
+using CodeImp.DoomBuilder.Map;
 using CodeImp.DoomBuilder.Rendering;
-using CodeImp.DoomBuilder.Editing;
-
-#endregion
-
-namespace CodeImp.DoomBuilder.AutomapMode
-{
-	[EditMode(DisplayName = "Automap Mode",
-			  SwitchAction = "automapmode",	// Action name used to switch to this mode
-			  ButtonImage = "automap.png",	// Image resource name for the button
-			  ButtonOrder = int.MinValue + 503,	// Position of the button (lower is more to the bottom)
-			  ButtonGroup = "000_editing",
-			  UseByDefault = true)]
-
+using CodeImp.DoomBuilder.Editing;
+
+#endregion
+
+namespace CodeImp.DoomBuilder.AutomapMode
+{
+	[EditMode(DisplayName = "Automap Mode",
+			  SwitchAction = "automapmode",	// Action name used to switch to this mode
+			  ButtonImage = "automap.png",	// Image resource name for the button
+			  ButtonOrder = int.MinValue + 503,	// Position of the button (lower is more to the bottom)
+			  ButtonGroup = "000_editing",
+			  UseByDefault = true)]
+
 	public class AutomapMode : ClassicMode
 	{
 		#region ================== Enums
@@ -51,22 +51,22 @@ namespace CodeImp.DoomBuilder.AutomapMode
 
 		#region ================== Constants
 
-		private const float LINE_LENGTH_SCALER = 0.001f; //mxd
-
-		#endregion
-
-		#region ================== Variables
-
-		private CustomPresentation automappresentation;
+		private const float LINE_LENGTH_SCALER = 0.001f; //mxd
+
+		#endregion
+
+		#region ================== Variables
+
+		private CustomPresentation automappresentation;
 		private List<Linedef> validlinedefs;
 		private HashSet<Sector> secretsectors; //mxd
-
-		// Highlighted item
+
+		// Highlighted item
 		private Linedef highlighted;
 
 		//mxd. UI
-		private MenusForm menusform;
-
+		private MenusForm menusform;
+
 		//mxd. Colors
 		private PixelColor ColorSingleSided;
 		private PixelColor ColorSecret;
@@ -75,25 +75,26 @@ namespace CodeImp.DoomBuilder.AutomapMode
 		private PixelColor ColorMatchingHeight;
 		private PixelColor ColorHiddenFlag;
 		private PixelColor ColorInvisible;
-		private PixelColor ColorBackground;
-		
-		#endregion
-
-		#region ================== Properties
-
-		public override object HighlightedObject { get { return highlighted; } }
-		
-		#endregion
-
-		#region ================== Constructor / Disposer
-
-		//mxd
+		private PixelColor ColorBackground;
+		
+		#endregion
+
+		#region ================== Properties
+
+		public override object HighlightedObject { get { return highlighted; } }
+		
+		#endregion
+
+		#region ================== Constructor / Disposer
+
+		//mxd
 		public AutomapMode()
 		{
 			// Create and setup menu
 			menusform = new MenusForm();
 			menusform.ShowHiddenLines = General.Settings.ReadPluginSetting("automapmode.showhiddenlines", false);
 			menusform.ShowSecretSectors = General.Settings.ReadPluginSetting("automapmode.showsecretsectors", false);
+			menusform.ShowLocks = General.Settings.ReadPluginSetting("automapmode.showlocks", true);
 			menusform.ColorPreset = (ColorPreset)General.Settings.ReadPluginSetting("automapmode.colorpreset", (int)ColorPreset.DOOM);
 
 			// Handle events
@@ -103,10 +104,8 @@ namespace CodeImp.DoomBuilder.AutomapMode
 				General.Interface.RedrawDisplay();
 			};
 
-			menusform.OnShowSecretSectorsChanged += delegate
-			{
-				General.Interface.RedrawDisplay();
-			};
+			menusform.OnShowSecretSectorsChanged += delegate { General.Interface.RedrawDisplay(); };
+			menusform.OnShowLocksChanged += delegate { General.Interface.RedrawDisplay(); };
 
 			menusform.OnColorPresetChanged += delegate
 			{
@@ -117,51 +116,51 @@ namespace CodeImp.DoomBuilder.AutomapMode
 			// Apply color preset
 			ApplyColorPreset(menusform.ColorPreset);
 		}
-
-		#endregion
-
-		#region ================== Methods
-
+
+		#endregion
+
+		#region ================== Methods
+
 		// This highlights a new item
 		private void Highlight(Linedef l)
 		{
-			// Update display
-			if(renderer.StartPlotter(false))
-			{
-				// Undraw previous highlight
-				if((highlighted != null) && !highlighted.IsDisposed)
+			// Update display
+			if(renderer.StartPlotter(false))
+			{
+				// Undraw previous highlight
+				if((highlighted != null) && !highlighted.IsDisposed)
 				{
-					PixelColor c = LinedefIsValid(highlighted) ? DetermineLinedefColor(highlighted) : PixelColor.Transparent;
-					renderer.PlotLine(highlighted.Start.Position, highlighted.End.Position, c, LINE_LENGTH_SCALER);
-				}
-
-				// Set new highlight
-				highlighted = l;
-
-				// Render highlighted item
-				if((highlighted != null) && !highlighted.IsDisposed && LinedefIsValid(highlighted))
+					PixelColor c = LinedefIsValid(highlighted) ? DetermineLinedefColor(highlighted) : PixelColor.Transparent;
+					renderer.PlotLine(highlighted.Start.Position, highlighted.End.Position, c, LINE_LENGTH_SCALER);
+				}
+
+				// Set new highlight
+				highlighted = l;
+
+				// Render highlighted item
+				if((highlighted != null) && !highlighted.IsDisposed && LinedefIsValid(highlighted))
 				{
-					renderer.PlotLine(highlighted.Start.Position, highlighted.End.Position, General.Colors.InfoLine, LINE_LENGTH_SCALER);
-				}
-
-				// Done
-				renderer.Finish();
-				renderer.Present();
-			}
-
-			// Show highlight info
-			if((highlighted != null) && !highlighted.IsDisposed)
-				General.Interface.ShowLinedefInfo(highlighted);
-			else
-				General.Interface.HideInfo();
-		}
-
-		//mxd
-		internal void UpdateValidLinedefs()
-		{
-			validlinedefs = new List<Linedef>();
+					renderer.PlotLine(highlighted.Start.Position, highlighted.End.Position, General.Colors.InfoLine, LINE_LENGTH_SCALER);
+				}
+
+				// Done
+				renderer.Finish();
+				renderer.Present();
+			}
+
+			// Show highlight info
+			if((highlighted != null) && !highlighted.IsDisposed)
+				General.Interface.ShowLinedefInfo(highlighted);
+			else
+				General.Interface.HideInfo();
+		}
+
+		//mxd
+		internal void UpdateValidLinedefs()
+		{
+			validlinedefs = new List<Linedef>();
 			foreach(Linedef ld in General.Map.Map.Linedefs)
-				if(LinedefIsValid(ld)) validlinedefs.Add(ld);
+				if(LinedefIsValid(ld)) validlinedefs.Add(ld);
 		}
 
 		//mxd
@@ -170,10 +169,17 @@ namespace CodeImp.DoomBuilder.AutomapMode
 			secretsectors = new HashSet<Sector>();
 			foreach(Sector s in General.Map.Map.Sectors)
 				if(SectorIsSecret(s)) secretsectors.Add(s);
-		}
-
-		private PixelColor DetermineLinedefColor(Linedef ld)
+		}
+
+		private PixelColor DetermineLinedefColor(Linedef ld)
 		{
+			//mxd
+			if(menusform.ShowLocks)
+			{
+				PixelColor lockcolor = new PixelColor();
+				if(GetLockColor(ld, ref lockcolor)) return lockcolor;
+			}
+			
 			//mxd
 			if(menusform.ShowSecretSectors &&
 			   (ld.Front != null && secretsectors.Contains(ld.Front.Sector) || ld.Back != null && secretsectors.Contains(ld.Back.Sector)))
@@ -187,22 +193,22 @@ namespace CodeImp.DoomBuilder.AutomapMode
 			if(ld.Front.Sector.CeilHeight == ld.Back.Sector.CeilHeight && ld.Front.Sector.FloorHeight == ld.Back.Sector.FloorHeight)
 				return ColorMatchingHeight;
 
-			if(menusform.ShowHiddenLines ^ General.Interface.CtrlState) return ColorInvisible; 
-
-			return new PixelColor(255, 255, 255, 255);
-		}
-
-		private bool LinedefIsValid(Linedef ld)
-		{
-			if(menusform.ShowHiddenLines ^ General.Interface.CtrlState) return true;
-			if(ld.IsFlagSet(BuilderPlug.Me.HiddenFlag)) return false;
-			if(ld.Back == null || ld.Front == null || ld.IsFlagSet(BuilderPlug.Me.SecretFlag)) return true;
-			if(ld.Back != null && ld.Front != null && (ld.Front.Sector.FloorHeight != ld.Back.Sector.FloorHeight || ld.Front.Sector.CeilHeight != ld.Back.Sector.CeilHeight)) return true;
-
-			return false;
-		}
-
-		//mxd
+			if(menusform.ShowHiddenLines ^ General.Interface.CtrlState) return ColorInvisible; 
+
+			return new PixelColor(255, 255, 255, 255);
+		}
+
+		private bool LinedefIsValid(Linedef ld)
+		{
+			if(menusform.ShowHiddenLines ^ General.Interface.CtrlState) return true;
+			if(ld.IsFlagSet(BuilderPlug.Me.HiddenFlag)) return false;
+			if(ld.Back == null || ld.Front == null || ld.IsFlagSet(BuilderPlug.Me.SecretFlag)) return true;
+			if(ld.Back != null && ld.Front != null && (ld.Front.Sector.FloorHeight != ld.Back.Sector.FloorHeight || ld.Front.Sector.CeilHeight != ld.Back.Sector.CeilHeight)) return true;
+
+			return false;
+		}
+
+		//mxd
 		private static bool SectorIsSecret(Sector s)
 		{
 			SectorEffectData data = General.Map.Config.GetSectorEffectData(s.Effect);
@@ -221,6 +227,33 @@ namespace CodeImp.DoomBuilder.AutomapMode
 			return false;
 		}
 
+		//mxd
+		private static bool GetLockColor(Linedef l, ref PixelColor lockcolor)
+		{
+			int locknum = 0;
+
+			// Check locknumber property
+			if(General.Map.UDMF)
+			{
+				locknum = UniFields.GetInteger(l.Fields, "locknumber");
+			}
+
+			// Check action
+			if(locknum == 0 && l.Action != 0 && General.Map.Data.LockableActions.ContainsKey(l.Action))
+			{
+				locknum = l.Args[General.Map.Data.LockableActions[l.Action]];
+			}
+
+			if(locknum != 0 && General.Map.Data.LockColors.ContainsKey(locknum))
+			{
+				lockcolor = General.Map.Data.LockColors[locknum];
+				return true;
+			}
+
+			// No dice
+			return false;
+		}
+
 		//mxd
 		private void ApplyColorPreset(ColorPreset preset)
 		{
@@ -259,63 +292,64 @@ namespace CodeImp.DoomBuilder.AutomapMode
 					ColorBackground = new PixelColor(255, 0, 0, 0);
 					break;
 			}
-		}
-
-		#endregion
-		
-		#region ================== Events
-
-		public override void OnHelp()
+		}
+
+		#endregion
+		
+		#region ================== Events
+
+		public override void OnHelp()
 		{
-			General.ShowHelp("/gzdb/features/classic_modes/mode_automap.html");
-		}
-
-		// Cancel mode
-		public override void OnCancel()
-		{
-			base.OnCancel();
-
-			// Return to this mode
-			General.Editing.ChangeMode(new AutomapMode());
-		}
-
-		// Mode engages
-		public override void OnEngage()
-		{
-			base.OnEngage();
+			General.ShowHelp("/gzdb/features/classic_modes/mode_automap.html");
+		}
+
+		// Cancel mode
+		public override void OnCancel()
+		{
+			base.OnCancel();
+
+			// Return to this mode
+			General.Editing.ChangeMode(new AutomapMode());
+		}
+
+		// Mode engages
+		public override void OnEngage()
+		{
+			base.OnEngage();
 			renderer.DrawMapCenter = false; //mxd
-
-			// Automap presentation without the surfaces
-			automappresentation = new CustomPresentation();
-			automappresentation.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Mask));
-			automappresentation.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
-			automappresentation.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
-			renderer.SetPresentation(automappresentation);
+
+			// Automap presentation without the surfaces
+			automappresentation = new CustomPresentation();
+			automappresentation.AddLayer(new PresentLayer(RendererLayer.Overlay, BlendingMode.Mask));
+			automappresentation.AddLayer(new PresentLayer(RendererLayer.Grid, BlendingMode.Mask));
+			automappresentation.AddLayer(new PresentLayer(RendererLayer.Geometry, BlendingMode.Alpha, 1f, true));
+			renderer.SetPresentation(automappresentation);
 
 			UpdateValidLinedefs();
 			UpdateSecretSectors(); //mxd
 
 			//mxd. Show UI
 			menusform.Register();
-		}
-		
-		// Mode disengages
-		public override void OnDisengage()
-		{
+		}
+		
+		// Mode disengages
+		public override void OnDisengage()
+		{
 			base.OnDisengage();
 
 			//mxd. Store settings
 			General.Settings.WritePluginSetting("automapmode.showhiddenlines", menusform.ShowHiddenLines);
 			General.Settings.WritePluginSetting("automapmode.showsecretsectors", menusform.ShowSecretSectors);
+			General.Settings.WritePluginSetting("automapmode.showlocks", menusform.ShowLocks);
 			General.Settings.WritePluginSetting("automapmode.colorpreset", (int)menusform.ColorPreset);
 
 			//mxd. Hide UI
 			menusform.Unregister();
-
-			// Hide highlight info
-			General.Interface.HideInfo();
-		}
-
+
+			// Hide highlight info
+			General.Interface.HideInfo();
+		}
+
 		//mxd
 		public override void OnUndoEnd()
 		{
@@ -323,8 +357,8 @@ namespace CodeImp.DoomBuilder.AutomapMode
 			UpdateSecretSectors();
 
 			base.OnUndoEnd();
-		}
-
+		}
+
 		//mxd
 		public override void OnRedoEnd()
 		{
@@ -332,119 +366,119 @@ namespace CodeImp.DoomBuilder.AutomapMode
 			UpdateSecretSectors();
 
 			base.OnRedoEnd();
-		}
-
-		// This redraws the display
-		public override void OnRedrawDisplay()
-		{
-			renderer.RedrawSurface();
-			
-			// Render lines
-			if(renderer.StartPlotter(true))
+		}
+
+		// This redraws the display
+		public override void OnRedrawDisplay()
+		{
+			renderer.RedrawSurface();
+			
+			// Render lines
+			if(renderer.StartPlotter(true))
 			{
-				foreach(Linedef ld in General.Map.Map.Linedefs)
-				{
-					if(LinedefIsValid(ld))
-						renderer.PlotLine(ld.Start.Position, ld.End.Position, DetermineLinedefColor(ld), LINE_LENGTH_SCALER);
-				}
-
-				if((highlighted != null) && !highlighted.IsDisposed && LinedefIsValid(highlighted))
+				foreach(Linedef ld in General.Map.Map.Linedefs)
 				{
-					renderer.PlotLine(highlighted.Start.Position, highlighted.End.Position, General.Colors.InfoLine, LINE_LENGTH_SCALER);
-				}
-
-				renderer.Finish();
-			}
-
-			//mxd. Render background
+					if(LinedefIsValid(ld))
+						renderer.PlotLine(ld.Start.Position, ld.End.Position, DetermineLinedefColor(ld), LINE_LENGTH_SCALER);
+				}
+
+				if((highlighted != null) && !highlighted.IsDisposed && LinedefIsValid(highlighted))
+				{
+					renderer.PlotLine(highlighted.Start.Position, highlighted.End.Position, General.Colors.InfoLine, LINE_LENGTH_SCALER);
+				}
+
+				renderer.Finish();
+			}
+
+			//mxd. Render background
 			if(renderer.StartOverlay(true))
 			{
 				RectangleF screenrect = new RectangleF(0, 0, General.Interface.Display.Width, General.Interface.Display.Height);
 				renderer.RenderRectangleFilled(screenrect, ColorBackground, false);
 				renderer.Finish();
-			}
-
-			renderer.Present();
-		}
-
-		protected override void OnSelectEnd()
-		{
-			// Item highlighted?
-			if((highlighted != null) && !highlighted.IsDisposed)
+			}
+
+			renderer.Present();
+		}
+
+		protected override void OnSelectEnd()
+		{
+			// Item highlighted?
+			if((highlighted != null) && !highlighted.IsDisposed)
 			{
-				General.Map.UndoRedo.CreateUndo("Toggle \"Shown as 1-sided on automap\" linedef flag");
-
-				// Toggle flag
+				General.Map.UndoRedo.CreateUndo("Toggle \"Shown as 1-sided on automap\" linedef flag");
+
+				// Toggle flag
 				highlighted.SetFlag(BuilderPlug.Me.SecretFlag, !highlighted.IsFlagSet(BuilderPlug.Me.SecretFlag));
-				UpdateValidLinedefs();
-			}
-
-			base.OnSelectEnd();
-		}
-		
-		protected override void OnEditEnd()
-		{
-			// Item highlighted?
-			if((highlighted != null) && !highlighted.IsDisposed)
+				UpdateValidLinedefs();
+			}
+
+			base.OnSelectEnd();
+		}
+		
+		protected override void OnEditEnd()
+		{
+			// Item highlighted?
+			if((highlighted != null) && !highlighted.IsDisposed)
 			{
-				General.Map.UndoRedo.CreateUndo("Toggle \"Not shown on automap\" linedef flag");
-
-				// Toggle flag
+				General.Map.UndoRedo.CreateUndo("Toggle \"Not shown on automap\" linedef flag");
+
+				// Toggle flag
 				highlighted.SetFlag(BuilderPlug.Me.HiddenFlag, !highlighted.IsFlagSet(BuilderPlug.Me.HiddenFlag));
-				UpdateValidLinedefs();
-				General.Interface.RedrawDisplay();
-			}
-
-			base.OnEditEnd();
-		}
-		
-		// Mouse moves
-		public override void OnMouseMove(MouseEventArgs e)
-		{
-			base.OnMouseMove(e);
-
-			// Not holding any buttons?
-			if(e.Button == MouseButtons.None)
-			{
-				// Find the nearest linedef within highlight range
-				Linedef l = MapSet.NearestLinedefRange(validlinedefs, mousemappos, BuilderPlug.Me.HighlightRange / renderer.Scale);
-
-				// Highlight if not the same
-				if(l != highlighted) Highlight(l);
-			}
-		}
-
-		// Mouse leaves
-		public override void OnMouseLeave(EventArgs e)
-		{
-			base.OnMouseLeave(e);
-
-			// Highlight nothing
-			Highlight(null);
-		}
-
-		public override void OnKeyDown(KeyEventArgs e)
-		{
-			base.OnKeyDown(e);
-
-			if(e.Control)
+				UpdateValidLinedefs();
+				General.Interface.RedrawDisplay();
+			}
+
+			base.OnEditEnd();
+		}
+		
+		// Mouse moves
+		public override void OnMouseMove(MouseEventArgs e)
+		{
+			base.OnMouseMove(e);
+
+			// Not holding any buttons?
+			if(e.Button == MouseButtons.None)
+			{
+				// Find the nearest linedef within highlight range
+				Linedef l = MapSet.NearestLinedefRange(validlinedefs, mousemappos, BuilderPlug.Me.HighlightRange / renderer.Scale);
+
+				// Highlight if not the same
+				if(l != highlighted) Highlight(l);
+			}
+		}
+
+		// Mouse leaves
+		public override void OnMouseLeave(EventArgs e)
+		{
+			base.OnMouseLeave(e);
+
+			// Highlight nothing
+			Highlight(null);
+		}
+
+		public override void OnKeyDown(KeyEventArgs e)
+		{
+			base.OnKeyDown(e);
+
+			if(e.Control)
 			{
-				UpdateValidLinedefs();
-				General.Interface.RedrawDisplay();
-			}
-		}
-
-		public override void OnKeyUp(KeyEventArgs e)
-		{
-			base.OnKeyUp(e);
-
-			if(!e.Control)
+				UpdateValidLinedefs();
+				General.Interface.RedrawDisplay();
+			}
+		}
+
+		public override void OnKeyUp(KeyEventArgs e)
+		{
+			base.OnKeyUp(e);
+
+			if(!e.Control)
 			{
-				UpdateValidLinedefs();
-				General.Interface.RedrawDisplay();
-			}
-		}
-
-		#endregion
-	}
-}
+				UpdateValidLinedefs();
+				General.Interface.RedrawDisplay();
+			}
+		}
+
+		#endregion
+	}
+}
diff --git a/Source/Plugins/AutomapMode/AutomapMode.csproj b/Source/Plugins/AutomapMode/AutomapMode.csproj
index 5b4bcf188e283519cdf73cf962ac33f29a8c2b72..ce64f2935af733d8cd4b2e97f649dc1c84e1a876 100644
--- a/Source/Plugins/AutomapMode/AutomapMode.csproj
+++ b/Source/Plugins/AutomapMode/AutomapMode.csproj
@@ -94,4 +94,7 @@
   <ItemGroup>
     <None Include="Resources\ShowSecrets.png" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\ShowLocks.png" />
+  </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/Source/Plugins/AutomapMode/Interface/MenusForm.Designer.cs b/Source/Plugins/AutomapMode/Interface/MenusForm.Designer.cs
index e4a3d5cc4fc74cb97ef4922f78130660b8d68aad..28bcf0947eb54adb1427f5ead51b17f607d66caa 100644
--- a/Source/Plugins/AutomapMode/Interface/MenusForm.Designer.cs
+++ b/Source/Plugins/AutomapMode/Interface/MenusForm.Designer.cs
@@ -29,11 +29,12 @@
 		private void InitializeComponent()
 		{
 			this.toolStrip1 = new System.Windows.Forms.ToolStrip();
-			this.showhiddenlines = new System.Windows.Forms.ToolStripButton();
-			this.showsecretsectors = new System.Windows.Forms.ToolStripButton();
 			this.colorpresetseparator = new System.Windows.Forms.ToolStripSeparator();
 			this.colorpresetlabel = new System.Windows.Forms.ToolStripLabel();
 			this.colorpreset = new System.Windows.Forms.ToolStripComboBox();
+			this.showhiddenlines = new System.Windows.Forms.ToolStripButton();
+			this.showsecretsectors = new System.Windows.Forms.ToolStripButton();
+			this.showlocks = new System.Windows.Forms.ToolStripButton();
 			this.toolStrip1.SuspendLayout();
 			this.SuspendLayout();
 			// 
@@ -42,6 +43,7 @@
 			this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
             this.showhiddenlines,
             this.showsecretsectors,
+            this.showlocks,
             this.colorpresetseparator,
             this.colorpresetlabel,
             this.colorpreset});
@@ -51,26 +53,6 @@
 			this.toolStrip1.TabIndex = 0;
 			this.toolStrip1.Text = "toolStrip1";
 			// 
-			// showhiddenlines
-			// 
-			this.showhiddenlines.CheckOnClick = true;
-			this.showhiddenlines.Image = global::CodeImp.DoomBuilder.AutomapMode.Properties.Resources.ShowHiddenLines;
-			this.showhiddenlines.ImageTransparentColor = System.Drawing.Color.Magenta;
-			this.showhiddenlines.Margin = new System.Windows.Forms.Padding(0, 1, 2, 2);
-			this.showhiddenlines.Name = "showhiddenlines";
-			this.showhiddenlines.Size = new System.Drawing.Size(123, 22);
-			this.showhiddenlines.Text = "Show hidden lines";
-			this.showhiddenlines.CheckedChanged += new System.EventHandler(this.showhiddenlines_CheckedChanged);
-			// 
-			// showsecretsectors
-			// 
-			this.showsecretsectors.CheckOnClick = true;
-			this.showsecretsectors.Image = global::CodeImp.DoomBuilder.AutomapMode.Properties.Resources.ShowSecrets;
-			this.showsecretsectors.Name = "showsecretsectors";
-			this.showsecretsectors.Size = new System.Drawing.Size(95, 22);
-			this.showsecretsectors.Text = "Show secrets";
-			this.showsecretsectors.CheckedChanged += new System.EventHandler(this.showsecretsectors_CheckedChanged);
-			// 
 			// colorpresetseparator
 			// 
 			this.colorpresetseparator.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
@@ -94,6 +76,37 @@
 			this.colorpreset.Size = new System.Drawing.Size(75, 25);
 			this.colorpreset.SelectedIndexChanged += new System.EventHandler(this.colorpreset_SelectedIndexChanged);
 			// 
+			// showhiddenlines
+			// 
+			this.showhiddenlines.CheckOnClick = true;
+			this.showhiddenlines.Image = global::CodeImp.DoomBuilder.AutomapMode.Properties.Resources.ShowHiddenLines;
+			this.showhiddenlines.ImageTransparentColor = System.Drawing.Color.Magenta;
+			this.showhiddenlines.Margin = new System.Windows.Forms.Padding(0, 1, 2, 2);
+			this.showhiddenlines.Name = "showhiddenlines";
+			this.showhiddenlines.Size = new System.Drawing.Size(123, 22);
+			this.showhiddenlines.Text = "Show hidden lines";
+			this.showhiddenlines.CheckedChanged += new System.EventHandler(this.showhiddenlines_CheckedChanged);
+			// 
+			// showsecretsectors
+			// 
+			this.showsecretsectors.CheckOnClick = true;
+			this.showsecretsectors.Image = global::CodeImp.DoomBuilder.AutomapMode.Properties.Resources.ShowSecrets;
+			this.showsecretsectors.Margin = new System.Windows.Forms.Padding(0, 1, 2, 2);
+			this.showsecretsectors.Name = "showsecretsectors";
+			this.showsecretsectors.Size = new System.Drawing.Size(95, 22);
+			this.showsecretsectors.Text = "Show secrets";
+			this.showsecretsectors.CheckedChanged += new System.EventHandler(this.showsecretsectors_CheckedChanged);
+			// 
+			// showlocks
+			// 
+			this.showlocks.CheckOnClick = true;
+			this.showlocks.Image = global::CodeImp.DoomBuilder.AutomapMode.Properties.Resources.ShowLocks;
+			this.showlocks.ImageTransparentColor = System.Drawing.Color.Magenta;
+			this.showlocks.Name = "showlocks";
+			this.showlocks.Size = new System.Drawing.Size(86, 22);
+			this.showlocks.Text = "Show locks";
+			this.showlocks.CheckedChanged += new System.EventHandler(this.showlocks_CheckedChanged);
+			// 
 			// MenusForm
 			// 
 			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -116,5 +129,6 @@
 		private System.Windows.Forms.ToolStripSeparator colorpresetseparator;
 		private System.Windows.Forms.ToolStripLabel colorpresetlabel;
 		private System.Windows.Forms.ToolStripComboBox colorpreset;
+		private System.Windows.Forms.ToolStripButton showlocks;
 	}
 }
diff --git a/Source/Plugins/AutomapMode/Interface/MenusForm.cs b/Source/Plugins/AutomapMode/Interface/MenusForm.cs
index 859f5290a28707d581d04b430bda59c5b30c6905..77d49da6cec4d6bff53ae3502cccea2e6a58c187 100644
--- a/Source/Plugins/AutomapMode/Interface/MenusForm.cs
+++ b/Source/Plugins/AutomapMode/Interface/MenusForm.cs
@@ -7,10 +7,12 @@ namespace CodeImp.DoomBuilder.AutomapMode
 	{
 		public event EventHandler OnShowHiddenLinesChanged;
 		public event EventHandler OnShowSecretSectorsChanged;
+		public event EventHandler OnShowLocksChanged;
 		internal event EventHandler OnColorPresetChanged;
 
 		public bool ShowHiddenLines { get { return showhiddenlines.Checked; } set { showhiddenlines.Checked = value; } }
 		public bool ShowSecretSectors { get { return showsecretsectors.Checked; } set { showsecretsectors.Checked = value; } }
+		public bool ShowLocks { get { return showlocks.Checked; } set { showlocks.Checked = value; } }
 		internal AutomapMode.ColorPreset ColorPreset { get { return (AutomapMode.ColorPreset)colorpreset.SelectedIndex; } set { colorpreset.SelectedIndex = (int)value; } }
 		
 		public MenusForm()
@@ -22,6 +24,7 @@ namespace CodeImp.DoomBuilder.AutomapMode
 		{
 			General.Interface.AddButton(showhiddenlines);
 			General.Interface.AddButton(showsecretsectors);
+			if(!General.Map.DOOM) General.Interface.AddButton(showlocks);
 			General.Interface.AddButton(colorpresetseparator);
 			General.Interface.AddButton(colorpresetlabel);
 			General.Interface.AddButton(colorpreset);
@@ -32,6 +35,7 @@ namespace CodeImp.DoomBuilder.AutomapMode
 			General.Interface.RemoveButton(colorpreset);
 			General.Interface.RemoveButton(colorpresetlabel);
 			General.Interface.RemoveButton(colorpresetseparator);
+			if(!General.Map.DOOM) General.Interface.RemoveButton(showlocks);
 			General.Interface.RemoveButton(showsecretsectors);
 			General.Interface.RemoveButton(showhiddenlines);
 		}
@@ -46,6 +50,11 @@ namespace CodeImp.DoomBuilder.AutomapMode
 			if(OnShowSecretSectorsChanged != null) OnShowSecretSectorsChanged(showsecretsectors.Checked, EventArgs.Empty);
 		}
 
+		private void showlocks_CheckedChanged(object sender, EventArgs e)
+		{
+			if(OnShowLocksChanged != null) OnShowLocksChanged(showlocks.Checked, EventArgs.Empty);
+		}
+
 		private void colorpreset_SelectedIndexChanged(object sender, EventArgs e)
 		{
 			if(OnColorPresetChanged != null) OnColorPresetChanged(colorpreset.SelectedIndex, EventArgs.Empty);
diff --git a/Source/Plugins/AutomapMode/Properties/Resources.Designer.cs b/Source/Plugins/AutomapMode/Properties/Resources.Designer.cs
index 493c26216b9b9e24d00db82dc79972921252122e..b58d6834384588aaf0fe7e62aabc4b5547c32822 100644
--- a/Source/Plugins/AutomapMode/Properties/Resources.Designer.cs
+++ b/Source/Plugins/AutomapMode/Properties/Resources.Designer.cs
@@ -1,7 +1,7 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:2.0.50727.5485
+//     Runtime Version:2.0.50727.5466
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
 //     the code is regenerated.
@@ -67,6 +67,13 @@ namespace CodeImp.DoomBuilder.AutomapMode.Properties {
             }
         }
         
+        internal static System.Drawing.Bitmap ShowLocks {
+            get {
+                object obj = ResourceManager.GetObject("ShowLocks", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
         internal static System.Drawing.Bitmap ShowSecrets {
             get {
                 object obj = ResourceManager.GetObject("ShowSecrets", resourceCulture);
diff --git a/Source/Plugins/AutomapMode/Properties/Resources.resx b/Source/Plugins/AutomapMode/Properties/Resources.resx
index 4fa11f4c726876704a0a587fda264c744f1393de..80e0c05ebbf54dfaa2b133f59cc192ed4cf7850a 100644
--- a/Source/Plugins/AutomapMode/Properties/Resources.resx
+++ b/Source/Plugins/AutomapMode/Properties/Resources.resx
@@ -118,10 +118,13 @@
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="ShowSecrets" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\ShowSecrets.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
   <data name="ShowHiddenLines" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Resources\ShowHiddenLines.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
-  <data name="ShowSecrets" type="System.Resources.ResXFileRef, System.Windows.Forms">
-    <value>..\Resources\ShowSecrets.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  <data name="ShowLocks" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\ShowLocks.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
 </root>
\ No newline at end of file
diff --git a/Source/Plugins/AutomapMode/Resources/ShowLocks.png b/Source/Plugins/AutomapMode/Resources/ShowLocks.png
new file mode 100644
index 0000000000000000000000000000000000000000..3df4ffc3fb29609f2b2332d98c88e71a36fd255d
Binary files /dev/null and b/Source/Plugins/AutomapMode/Resources/ShowLocks.png differ