diff --git a/Source/Plugins/3DFloorMode/ThreeDFloorMode.cs b/Source/Plugins/3DFloorMode/ThreeDFloorMode.cs
index e8f99fcff5254b9739f0052d30a9ae9dc49d6f35..cf7cd4add0e38fb3172904ceb848b956cd561c52 100644
--- a/Source/Plugins/3DFloorMode/ThreeDFloorMode.cs
+++ b/Source/Plugins/3DFloorMode/ThreeDFloorMode.cs
@@ -70,7 +70,7 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
 		// Highlighted item
 		protected Sector highlighted;
 		protected ThreeDFloor highlighted3dfloor;
-		private Association highlightasso = new Association();
+		private Association highlightasso;
 		private FlatVertex[] overlayGeometry;
 		private FlatVertex[] overlaygeometry3dfloors;
 		private FlatVertex[] overlaygeometry3dfloors_highlighted;
@@ -110,6 +110,7 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
 		public ThreeDFloorHelperMode()
 		{
 			threedfloors = BuilderPlug.GetThreeDFloors(General.Map.Map.Sectors.ToList());
+			highlightasso = new Association(renderer);
 
 			withdrawduplicateundo = false;
 
@@ -123,7 +124,6 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
 			{
 				withdrawduplicateundo = true;
 			}
-				
 		}
 
 		// Disposer
@@ -437,10 +437,10 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
 			if (s != null)
 			{
 				Vector2D center = (s.Labels.Count > 0 ? s.Labels[0].position : new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
-				highlightasso.Set(center, s.Tag, UniversalType.SectorTag);
+				highlightasso.Set(s);
 			}
 			else
-				highlightasso.Set(new Vector2D(), 0, 0);
+				highlightasso.Clear();
 
 			// New association highlights something?
 			if((s != null) && (s.Tag > 0)) completeredraw = true;
diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
index 44b8a5b5a541c2f5bf275e3cb1f7d646043b78b9..2737b60405c69e17d8a8e1af912a2961376de127 100755
--- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
@@ -56,8 +56,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 
 		// Highlighted item
 		private Linedef highlighted;
-		private readonly Association[] association = new Association[Linedef.NUM_ARGS];
-		private readonly Association highlightasso = new Association();
+		private readonly Association highlightasso;
 		private Vector2D insertpreview = new Vector2D(float.NaN, float.NaN); //mxd
 
 		//mxd. Text labels
@@ -82,7 +81,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		public LinedefsMode()
 		{
 			//mxd. Associations now requre initializing...
-			for(int i = 0; i < association.Length; i++) association[i] = new Association();
+			highlightasso = new Association(renderer);
 		}
 
 		//mxd
@@ -125,9 +124,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
 					labels[highlighted].Color = General.Colors.Highlight;
 					completeredraw = true;
 				}
-				
+
 				// Previous association highlights something?
-				if(highlighted.Tag != 0) completeredraw = true;
+				if (!highlightasso.IsEmpty) completeredraw = true;
 			}
 			
 			// Set highlight association
@@ -141,57 +140,18 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				}
 
 				// New association highlights something?
-				if(l.Tag != 0)
-				{
-					highlightasso.Set(new Vector2D((l.Start.Position + l.End.Position) / 2), l.Tags, UniversalType.LinedefTag);
-					completeredraw = true; 
-				}
-			}
-			else
-			{
-				highlightasso.Set(new Vector2D(), 0, 0);
-			}
+				highlightasso.Set(l);
 
-			// Use the line tag to highlight sectors (Doom style)
-			if(General.Map.Config.LineTagIndicatesSectors)
-			{
-				if(l != null)
-					association[0].Set(new Vector2D((l.Start.Position  + l.End.Position)/2), l.Tags, UniversalType.SectorTag);
-				else
-					association[0].Set(new Vector2D(), 0, 0);
+				// Only need a complete redraw if the association contains elements
+				if (!highlightasso.IsEmpty) completeredraw = true;
 			}
 			else
 			{
-				LinedefActionInfo action = null;
-
-				if(l != null)
-				{
-					// Check if we can find the linedefs action
-					if((l.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(l.Action))
-						action = General.Map.Config.LinedefActions[l.Action];
-				}
-				
-				// Determine linedef associations
-				for(int i = 0; i < Linedef.NUM_ARGS; i++)
-				{
-					// Previous association highlights something?
-					if((association[i].Type == UniversalType.SectorTag) ||
-					   (association[i].Type == UniversalType.LinedefTag) ||
-					   (association[i].Type == UniversalType.ThingTag)) completeredraw = true;
-
-					// Make new association
-					if(action != null)
-						association[i].Set(new Vector2D((l.Start.Position  + l.End.Position)/2), l.Args[i], action.Args[i].Type);
-					else
-						association[i].Set(new Vector2D(), 0, 0);
-
-					// New association highlights something?
-					if((association[i].Type == UniversalType.SectorTag) ||
-					   (association[i].Type == UniversalType.LinedefTag) ||
-					   (association[i].Type == UniversalType.ThingTag)) completeredraw = true;
-				}
+				// Only need a complete redraw if the old association wasn't empty
+				if (!highlightasso.IsEmpty) completeredraw = true;
+				highlightasso.Clear();
 			}
-			
+
 			// If we're changing associations, then we
 			// need to redraw the entire display
 			if(completeredraw)
@@ -599,11 +559,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			if(renderer.StartPlotter(true))
 			{
 				renderer.PlotLinedefSet(General.Map.Map.Linedefs);
-				for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.PlotAssociations(renderer, association[i], eventlines);
 				
 				if((highlighted != null) && !highlighted.IsDisposed)
 				{
-					BuilderPlug.PlotReverseAssociations(renderer, highlightasso, eventlines);
+					//BuilderPlug.PlotReverseAssociations(renderer, highlightasso, eventlines);
+					highlightasso.Plot();
 					renderer.PlotLinedef(highlighted, General.Colors.Highlight);
 				}
 				renderer.PlotVerticesSet(General.Map.Map.Vertices);
@@ -623,8 +583,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			{
 				if(!selecting) //mxd
 				{ 
-					for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.RenderAssociations(renderer, association[i], eventlines);
-					if((highlighted != null) && !highlighted.IsDisposed) BuilderPlug.RenderReverseAssociations(renderer, highlightasso, eventlines); //mxd
+					if ((highlighted != null) && !highlighted.IsDisposed) highlightasso.Render(); //mxd
 				}
 				else
 				{
@@ -640,8 +599,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
 					renderer.RenderRectangleFilled(new RectangleF((float)(insertpreview.x - vsize), (float)(insertpreview.y - vsize), vsize * 2.0f, vsize * 2.0f), General.Colors.InfoLine.WithAlpha(alpha), true);
 				}
 
-				renderer.RenderArrows(eventlines); //mxd
-
 				//mxd. Render sector tag labels
 				if(BuilderPlug.Me.ViewSelectionEffects)
 				{
diff --git a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs
index 2d6f93ac3f5b0250090640d507479967bf745eba..884bba277f877ebef7edfa14a049829734f36b53 100755
--- a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs
@@ -54,7 +54,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 
 		// Highlighted item
 		private Sector highlighted;
-		private readonly Association highlightasso = new Association();
+		private readonly Association highlightasso;
 
 		// Interface
 		new private bool editpressed;
@@ -87,6 +87,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		// Constructor
 		public SectorsMode()
 		{
+			highlightasso = new Association(renderer);
+
 			//mxd
 			effects = new Dictionary<int, string[]>();
 			foreach(SectorEffectInfo info in General.Map.Config.SortedSectorEffects) 
@@ -413,12 +415,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			// Set highlight association
 			if(s != null && s.Tag != 0) 
 			{
-				Vector2D center = (s.Labels.Count > 0 ? s.Labels[0].position : new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
-				highlightasso.Set(center, s.Tags, UniversalType.SectorTag);
+				highlightasso.Set(s);
 			} 
 			else 
 			{
-				highlightasso.Set(new Vector2D(), 0, 0);
+				highlightasso.Clear();
 			}
 
 			// New association highlights something?
@@ -843,7 +844,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				if((highlighted != null) && !highlighted.IsDisposed)
 				{
 					renderer.PlotSector(highlighted, General.Colors.Highlight);
-					BuilderPlug.PlotReverseAssociations(renderer, highlightasso, eventlines);
+					highlightasso.Plot();
 				}
 				renderer.Finish();
 			}
@@ -862,9 +863,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			// Render selection
 			if(renderer.StartOverlay(false)) 
 			{
-				if(highlighted != null && !highlighted.IsDisposed) BuilderPlug.RenderReverseAssociations(renderer, highlightasso, eventlines); //mxd
-				if(selecting) RenderMultiSelection();
-				renderer.RenderArrows(eventlines); //mxd
+				if (highlighted != null && !highlighted.IsDisposed) highlightasso.Render();
+				if (selecting) RenderMultiSelection();
+
 				renderer.Finish();
 			}
 			
diff --git a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs
index 8735d38fc2614b6c08c1ac563fe54fad1fcd1ef5..dba140bc6c0199d2a751428169d204e05b17f8d8 100755
--- a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs
@@ -56,9 +56,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 
 		// Highlighted item
 		private Thing highlighted;
-		private readonly Association[] association = new Association[Thing.NUM_ARGS];
-		private readonly Association directasso = new Association();
-		private readonly Association highlightasso = new Association();
+		private readonly Association highlightasso;
 
 		// Interface
 		new private bool editpressed;
@@ -89,8 +87,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		public ThingsMode()
 		{
 			//mxd. Associations now requre initializing...
-			for(int i = 0; i < association.Length; i++) association[i] = new Association();
-			directasso = new Association();
+			highlightasso = new Association(renderer);
 		}
 
 		//mxd
@@ -234,8 +231,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				renderer.PlotLinedefSet(General.Map.Map.Linedefs);
 				renderer.PlotVerticesSet(General.Map.Map.Vertices);
 
-				for(int i = 0; i < Thing.NUM_ARGS; i++) BuilderPlug.PlotAssociations(renderer, association[i], eventlines);
-				if(highlighted != null && !highlighted.IsDisposed) BuilderPlug.PlotReverseAssociations(renderer, highlightasso, eventlines);
+				if (highlighted != null && !highlighted.IsDisposed) highlightasso.Plot();
 				
 				renderer.Finish();
 			}
@@ -246,13 +242,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				float alpha = (General.Settings.FixedThingsScale ? Presentation.THINGS_ALPHA : General.Settings.ActiveThingsAlpha); //mxd
 				renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, General.Settings.HiddenThingsAlpha);
 				renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, alpha);
-				for(int i = 0; i < Thing.NUM_ARGS; i++) BuilderPlug.RenderAssociations(renderer, association[i], eventlines);
-				BuilderPlug.RenderAssociations(renderer, directasso, eventlines);
 				
 				if(highlighted != null && !highlighted.IsDisposed)
 				{
 					renderer.RenderThing(highlighted, General.Colors.Highlight, alpha);
-					BuilderPlug.RenderReverseAssociations(renderer, highlightasso, eventlines); //mxd
+					highlightasso.Render();
 				}
 
 				//mxd. Event lines
@@ -364,11 +358,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 					linktype = ti.ThingLink;
 
 				// New association highlights something?
-				if(t.Tag != 0) highlightasso.Set(t.Position, t.Tag, UniversalType.ThingTag, linktype);
+				highlightasso.Set(t);
 			}
 			else
 			{
-				highlightasso.Set(new Vector2D(), 0, 0);
+				highlightasso.Clear();
 			}
 
 			if(highlighted != null) //mxd
@@ -379,46 +373,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				highlighted.Highlighted = false;
 			}
 
-			//mxd. Determine thing associations
-			bool clearassociations = true; //mxd
-			if(t != null)
-			{
-				t.Highlighted = true; //mxd
-				
-				// Check if we can find the linedefs action
-				if((t.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(t.Action))
-				{
-					clearassociations = false;
-					LinedefActionInfo action = General.Map.Config.LinedefActions[t.Action];
-					for(int i = 0; i < Thing.NUM_ARGS; i++)
-						association[i].Set(t.Position, t.Args[i], action.Args[i].Type);
-
-					//Some things, such as Patrol and Interpolation specials, are associated via a shared tag rather than an argument
-					ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
-					if (ti != null && ti.ThingLink < 0) 
-						directasso.Set(t.Position, t.Tag, (int)UniversalType.ThingTag);
-				}
-				//mxd. Check if we can use thing arguments
-				else if(t.Action == 0)
-				{
-					ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
-					if(ti != null)
-					{
-						clearassociations = false;
-						for(int i = 0; i < Thing.NUM_ARGS; i++)
-							association[i].Set(t.Position, t.Args[i], ti.Args[i].Type);
-					}
-				}
-			}
-
-			// mxd. Clear associations?
-			if(clearassociations)
-			{
-				for (int i = 0; i < Thing.NUM_ARGS; i++)
-					association[i].Set(new Vector2D(), 0, 0);
-				directasso.Set(new Vector2D(), 0, 0);
-			}
-			
 			// Set new highlight and redraw display
 			highlighted = t;
 			General.Interface.RedrawDisplay();
diff --git a/Source/Plugins/BuilderModes/General/Association.cs b/Source/Plugins/BuilderModes/General/Association.cs
index 7b6e48093f4c159442f5f665688f1625cbdf1c00..432e034fae4a235ec6106fe6d29d7cf1f9d893fa 100755
--- a/Source/Plugins/BuilderModes/General/Association.cs
+++ b/Source/Plugins/BuilderModes/General/Association.cs
@@ -16,9 +16,16 @@
 
 #region ================== Namespaces
 
+using System;
 using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using CodeImp.DoomBuilder.Config;
 using CodeImp.DoomBuilder.Geometry;
+using CodeImp.DoomBuilder.Map;
+using CodeImp.DoomBuilder.Rendering;
 using CodeImp.DoomBuilder.Types;
+using CodeImp.DoomBuilder.Windows;
 
 #endregion
 
@@ -30,97 +37,747 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		private Vector2D center;
 		private UniversalType type;
 		private int directlinktype;
+		private Dictionary<string, List<Line3D>> eventlines;
+		private IRenderer2D renderer;
+		private SelectableElement element;
+		private List<PixelColor> distinctcolors;
+		private Font font;
+		private Dictionary<string, Vector2D> textwidths;
+		private Dictionary<string, List<TextLabel>> textlabels;
+
+		// Map elements that are associated
+		private List<Thing> things;
+		private List<Sector> sectors;
+		private List<Linedef> linedefs;
 
 		public HashSet<int> Tags { get { return tags; } }
 		public Vector2D Center { get { return center; } }
 		public UniversalType Type { get { return type; } }
 		public int DirectLinkType { get { return directlinktype; } }
+		public List<Thing> Things { get { return things; } }
+		public List<Sector> Sectors { get { return sectors; } }
+		public List<Linedef> Linedefs { get { return linedefs; } }
+		public bool IsEmpty { get { return things.Count == 0 && sectors.Count == 0 && linedefs.Count == 0; } }
 
 		//mxd. This sets up the association
-		public Association()
+		public Association(IRenderer2D renderer)
 		{
 			this.tags = new HashSet<int> { 0 };
+			this.renderer = renderer;
+
+			things = new List<Thing>();
+			sectors = new List<Sector>();
+			linedefs = new List<Linedef>();
+			eventlines = new Dictionary<string, List<Line3D>>();
+
+			font = new Font(new FontFamily(General.Settings.TextLabelFontName), General.Settings.TextLabelFontSize, (General.Settings.TextLabelFontBold ? FontStyle.Bold : FontStyle.Regular));
+
+			distinctcolors = new List<PixelColor>
+			{
+				General.Colors.InfoLine,
+				PixelColor.FromInt(0x84d5a4).WithAlpha(255),
+				PixelColor.FromInt(0xc059cb).WithAlpha(255),
+				PixelColor.FromInt(0xd0533d).WithAlpha(255),
+				// PixelColor.FromInt(0x415354).WithAlpha(255), // too dark
+				PixelColor.FromInt(0xcea953).WithAlpha(255),
+				PixelColor.FromInt(0x91d44b).WithAlpha(255),
+				PixelColor.FromInt(0xcd5b89).WithAlpha(255),
+				PixelColor.FromInt(0xa8b6c0).WithAlpha(255),
+				PixelColor.FromInt(0x797ecb).WithAlpha(255),
+				// PixelColor.FromInt(0x567539).WithAlpha(255), // too dark
+				// PixelColor.FromInt(0x72422f).WithAlpha(255), // too dark
+				// PixelColor.FromInt(0x5d3762).WithAlpha(255), // too dark
+				PixelColor.FromInt(0xffed6f).WithAlpha(255),
+				PixelColor.FromInt(0xccebc5).WithAlpha(255),
+				PixelColor.FromInt(0xbc80bd).WithAlpha(255),
+				// PixelColor.FromInt(0xd9d9d9).WithAlpha(255), // too gray
+				PixelColor.FromInt(0xfccde5).WithAlpha(255),
+				PixelColor.FromInt(0x80b1d3).WithAlpha(255),
+				PixelColor.FromInt(0xfdb462).WithAlpha(255),
+				PixelColor.FromInt(0xb3de69).WithAlpha(255),
+				PixelColor.FromInt(0xfb8072).WithAlpha(255),
+				PixelColor.FromInt(0xbebada).WithAlpha(255), // too blue/gray?
+				PixelColor.FromInt(0xffffb3).WithAlpha(255),
+				PixelColor.FromInt(0x8dd3c7).WithAlpha(255),
+			};
+		}
+
+		/// <summary>
+		/// Sets the association to a map element. Only works with an instance of Thing, Sector, or Linedef.
+		/// Also gets the forward and reverse associations
+		/// </summary>
+		/// <param name="element">An instance of Thing, Sector, or Linedef</param>
+		public void Set(SelectableElement element)
+		{
+			this.element = element;
+			things = new List<Thing>();
+			sectors = new List<Sector>();
+			linedefs = new List<Linedef>();
+			eventlines = new Dictionary<string, List<Line3D>>();
+
+			if (element is Sector)
+			{
+				Sector s = element as Sector;
+				center = (s.Labels.Count > 0 ? s.Labels[0].position : new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
+
+				type = UniversalType.SectorTag;
+				tags = new HashSet<int>(s.Tags);
+			}
+			else if(element is Linedef)
+			{
+				Linedef ld = element as Linedef;
+				center = ld.GetCenterPoint();
+
+				type = UniversalType.LinedefTag;
+				tags = new HashSet<int>(ld.Tags);
+			}
+			else if(element is Thing)
+			{
+				Thing t = element as Thing;
+				center = t.Position;
+
+				ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
+				directlinktype = ti.ThingLink;
+
+				type = UniversalType.ThingTag;
+				tags = new HashSet<int>(new int[] { t.Tag });
+			}
+
+			// Remove the tag 0, because nothing sensible will come from it
+			tags.Remove(0);
+
+			// Get forward and reverse associations
+			GetAssociations();
+
+			// Cache width of label text and generate the labels
+			textwidths = new Dictionary<string, Vector2D>(eventlines.Count);
+			textlabels = new Dictionary<string, List<TextLabel>>(eventlines.Count);
+
+			foreach(KeyValuePair<string, List<Line3D>> kvp in eventlines)
+			{
+				SizeF size = General.Interface.MeasureString(kvp.Key, font);
+				textwidths[kvp.Key] = new Vector2D(size.Width, size.Height);
+
+				// Create one label for each line. We might not need them all, but better
+				// to have them all at the beginning than to generate them later
+				textlabels[kvp.Key] = new List<TextLabel>(kvp.Value.Count);
+
+				for (int i = 0; i < kvp.Value.Count; i++)
+				{
+					// We don't need to set the position here, since it'll be done on the fly later
+					TextLabel l = new TextLabel();
+					l.AlignX = TextAlignmentX.Center;
+					l.AlignY = TextAlignmentY.Middle;
+					l.TransformCoords = true;
+					l.Text = kvp.Key;
+
+					textlabels[kvp.Key].Add(l);
+				}
+
+				textwidths[kvp.Key] = new Vector2D(textlabels[kvp.Key][0].TextSize.Width, textlabels[kvp.Key][0].TextSize.Height);
+			}
+
+			SetEventLineColors();
 		}
 
-		// This sets up the association
-		public Association(Vector2D center, int tag, int type)
+		/// <summary>
+		/// Clears out all lists so that the association appears empty
+		/// </summary>
+		public void Clear()
 		{
-			this.tags = new HashSet<int> { tag }; //mxd
-			this.type = (UniversalType)type;
-			this.center = center;
+			tags = new HashSet<int>();
+			things = new List<Thing>();
+			sectors = new List<Sector>();
+			linedefs = new List<Linedef>();
+			eventlines = new Dictionary<string, List<Line3D>>();
 		}
 
-		// This sets up the association
-		public Association(Vector2D center, int tag, UniversalType type)
+		/// <summary>
+		/// Get the forward and reverse associations between the element and other map elements
+		/// </summary>
+		private void GetAssociations()
 		{
-			this.tags = new HashSet<int> { tag }; //mxd
-			this.type = type;
-			this.center = center;
+			Dictionary<int, HashSet<int>> actiontags = new Dictionary<int, HashSet<int>>();
+			bool showforwardlabel = BuilderPlug.Me.EventLineLabelVisibility == 1 || BuilderPlug.Me.EventLineLabelVisibility == 3;
+			bool showreverselabel = BuilderPlug.Me.EventLineLabelVisibility == 2 || BuilderPlug.Me.EventLineLabelVisibility == 3;
+
+			// Special handling for Doom format maps where there the linedef's tag references sectors
+			if (General.Map.Config.LineTagIndicatesSectors)
+			{
+				if (tags.Count == 0)
+					return;
+
+				// Forward association from linedef to sector
+				if (element is Linedef)
+				{
+					foreach (Sector s in General.Map.Map.Sectors)
+					{
+						if (tags.Contains(s.Tag))
+						{
+							Vector2D sectorcenter = (s.Labels.Count > 0 ? s.Labels[0].position : new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
+
+							sectors.Add(s);
+
+							AddLineToAction(showforwardlabel ? GetActionDescription(element) : string.Empty, center, sectorcenter);
+						}
+					}
+				}
+				else if(element is Sector)
+				{
+					foreach(Linedef ld in General.Map.Map.Linedefs)
+					{
+						if(tags.Contains(ld.Tag))
+						{
+							linedefs.Add(ld);
+
+							AddLineToAction(showreverselabel ? GetActionDescription(ld) : string.Empty, ld.GetCenterPoint(), center);
+						}
+					}
+				}
+
+				return;
+			}
+
+			// Get tags of map elements the element is referencing. This is used for the forward associations
+			if (element is Linedef || element is Thing)
+				actiontags = GetTagsByType();
+
+			// Store presence of different types once, so that we don't have to do a lookup for each map element
+			bool hassectortags = actiontags.ContainsKey((int)UniversalType.SectorTag);
+			bool haslinedeftags = actiontags.ContainsKey((int)UniversalType.LinedefTag);
+			bool hasthingtag = actiontags.ContainsKey((int)UniversalType.ThingTag);
+
+			// Process all sectors in the map
+			foreach (Sector s in General.Map.Map.Sectors)
+			{
+				bool addforward = false;
+				bool addreverse = false;
+
+				// Check for forward association (from the element to the sector)
+				if (hassectortags && actiontags[(int)UniversalType.SectorTag].Overlaps(s.Tags))
+					addforward = true;
+
+				// Check the reverse association (from the sector to the element)
+				// Nothing here yet
+
+				if (addforward || addreverse)
+				{
+					Vector2D sectorcenter = (s.Labels.Count > 0 ? s.Labels[0].position : new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
+
+					sectors.Add(s);
+
+					if (addforward)
+						AddLineToAction(showforwardlabel ? GetActionDescription(element) : string.Empty, center, sectorcenter);
+
+					if (addreverse)
+						AddLineToAction(showreverselabel ? GetActionDescription(element) : string.Empty, sectorcenter, center);
+				}
+			}
+
+			// Process all linedefs in the map
+			foreach(Linedef ld in General.Map.Map.Linedefs)
+			{
+				bool addforward = false;
+				bool addreverse = false;
+
+				// Check the forward association (from the element to the linedef)
+				if (haslinedeftags && actiontags[(int)UniversalType.LinedefTag].Overlaps(ld.Tags))
+					addforward = true;
+
+				// Check the reverse association (from the linedef to the element)
+				if (IsAssociatedToLinedef(ld))
+					addreverse = true;
+
+				if (addforward || addreverse)
+				{
+					linedefs.Add(ld);
+
+					if (addforward)
+						AddLineToAction(showforwardlabel ? GetActionDescription(element) : string.Empty, center, ld.GetCenterPoint());
+
+					if (addreverse)
+						AddLineToAction(showreverselabel ? GetActionDescription(ld) : string.Empty, ld.GetCenterPoint(), center);
+				}
+			}
+
+			// Doom format only knows associations between linedefs and sectors, but not thing, so stop here
+			if (General.Map.DOOM)
+				return;
+
+			// Process all things in the map
+			foreach(Thing t in General.Map.Map.Things)
+			{
+				bool addforward = false;
+				bool addreverse = false;
+
+				// Check the forward association (from the element to the thing)
+				if (hasthingtag && actiontags[(int)UniversalType.ThingTag].Contains(t.Tag))
+					addforward = true;
+
+				// Check the reverse association (from the thing to the element). Only works for Hexen and UDMF,
+				// as Doom format doesn't have any way to reference other map elements
+				if (IsAssociatedToThing(t))
+					addreverse = true;
+
+				if (addforward || addreverse)
+				{
+					things.Add(t);
+
+					if (addforward)
+						AddLineToAction(showforwardlabel ? GetActionDescription(element) : string.Empty, center, t.Position);
+
+					if (addreverse)
+						AddLineToAction(showreverselabel ? GetActionDescription(t) : string.Empty, t.Position, center);
+				}
+			}
+		}
+
+		/// <summary>
+		/// Gets a dictionary of sector tags, linedef tags, and thing tags, grouped by their type, that the map element is referencing
+		/// </summary>
+		/// <returns>Dictionary of sector tags, linedef tags, and thing tags that the map element is referencing</returns>
+		private Dictionary<int, HashSet<int>> GetTagsByType()
+		{
+			LinedefActionInfo action = null;
+			int[] actionargs = new int[5];
+			Dictionary<int, HashSet<int>> actiontags = new Dictionary<int, HashSet<int>>();
+
+			// Get the action and its arguments from a linedef or a thing, if they have them
+			if (element is Linedef)
+			{
+				Linedef ld = element as Linedef;
+
+				if (ld.Action > 0 && General.Map.Config.LinedefActions.ContainsKey(ld.Action))
+					action = General.Map.Config.LinedefActions[ld.Action];
+
+				actionargs = ld.Args;
+			}
+			else if (element is Thing)
+			{
+				Thing t = element as Thing;
+
+				if (t.Action > 0 && General.Map.Config.LinedefActions.ContainsKey(t.Action))
+					action = General.Map.Config.LinedefActions[t.Action];
+
+				actionargs = t.Args;
+			}
+			else // element is a Sector
+			{
+				return actiontags;
+			}
+
+			if (action != null)
+			{
+				// Collect what map element the action arguments are referencing. Ignore the argument if it's 0, so that they
+				// are not associated to everything untagged
+				for (int i = 0; i < Linedef.NUM_ARGS; i++)
+				{
+					if ((action.Args[i].Type == (int)UniversalType.SectorTag ||
+						action.Args[i].Type == (int)UniversalType.LinedefTag ||
+						action.Args[i].Type == (int)UniversalType.ThingTag) &&
+						actionargs[i] > 0)
+					{
+						if (!actiontags.ContainsKey(action.Args[i].Type))
+							actiontags[action.Args[i].Type] = new HashSet<int>();
+
+						actiontags[action.Args[i].Type].Add(actionargs[i]);
+					}
+				}
+			}
+			else if (element is Thing && directlinktype >= 0 && Math.Abs(directlinktype) != ((Thing)element).Type)
+			{
+				// The direct link shenanigans if the thing doesn't have an action, but still reference something through
+				// the action parameters
+				Thing t = element as Thing;
+				ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
+
+				if (ti != null && directlinktype >= 0 && Math.Abs(directlinktype) != t.Type)
+				{
+					for (int i = 0; i < Linedef.NUM_ARGS; i++)
+					{
+						if ((ti.Args[i].Type == (int)UniversalType.SectorTag ||
+							ti.Args[i].Type == (int)UniversalType.LinedefTag ||
+							ti.Args[i].Type == (int)UniversalType.ThingTag))
+						{
+							if (!actiontags.ContainsKey(ti.Args[i].Type))
+								actiontags[ti.Args[i].Type] = new HashSet<int>();
+
+							actiontags[ti.Args[i].Type].Add(actionargs[i]);
+						}
+
+					}
+				}
+			}
+
+			return actiontags;
 		}
 
-		//mxd. This also sets up the association
-		public Association(Vector2D center, IEnumerable<int> tags, int type)
+		/// <summary>
+		/// Checks if there's an association between the element and a Linedef
+		/// </summary>
+		/// <param name="linedef">Linedef to check the association against</param>
+		/// <returns>true if the Linedef and the element are associated, false if not</returns>
+		private bool IsAssociatedToLinedef(Linedef linedef)
 		{
-			this.tags = new HashSet<int>(tags); //mxd
-			this.type = (UniversalType)type;
-			this.center = center;
+			// Doom style reference from linedef to sector?
+			if (General.Map.Config.LineTagIndicatesSectors && element is Sector)
+			{
+				if (linedef.Action > 0 && tags.Overlaps(linedef.Tags))
+					return true;
+			}
+
+			// Known action on this line?
+			if ((linedef.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(linedef.Action))
+			{
+				LinedefActionInfo action = General.Map.Config.LinedefActions[linedef.Action];
+				if (((action.Args[0].Type == (int)type) && (linedef.Args[0] != 0) && (tags.Contains(linedef.Args[0]))) ||
+					((action.Args[1].Type == (int)type) && (linedef.Args[1] != 0) && (tags.Contains(linedef.Args[1]))) ||
+					((action.Args[2].Type == (int)type) && (linedef.Args[2] != 0) && (tags.Contains(linedef.Args[2]))) ||
+					((action.Args[3].Type == (int)type) && (linedef.Args[3] != 0) && (tags.Contains(linedef.Args[3]))) ||
+					((action.Args[4].Type == (int)type) && (linedef.Args[4] != 0) && (tags.Contains(linedef.Args[4]))))
+				{
+					return true;
+				}
+			}
+
+			return false;
 		}
 
-		//mxd. This also sets up the association
-		public Association(Vector2D center, IEnumerable<int> tags, UniversalType type)
+		/// <summary>
+		/// Checks if there's an association between the element and a Thing
+		/// </summary>
+		/// <param name="thing">Thing to check the association against</param>
+		/// <returns>true if the Thing and the element are associated, false if not</returns>
+		private bool IsAssociatedToThing(Thing thing)
 		{
-			this.tags = new HashSet<int>(tags); //mxd
-			this.type = type;
-			this.center = center;
+			// Get the thing type info
+			ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(thing.Type);
+
+			// Known action on this thing?
+			if ((thing.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(thing.Action))
+			{
+				//Do not draw the association if this is a child link.
+				//  This prevents a reverse link to a thing via an argument, when it should be a direct tag-to-tag link instead.
+				if (ti != null && directlinktype < 0 && directlinktype != -thing.Type)
+					return false;
+
+				LinedefActionInfo action = General.Map.Config.LinedefActions[thing.Action];
+				if (((action.Args[0].Type == (int)type) && (tags.Contains(thing.Args[0]))) ||
+					 ((action.Args[1].Type == (int)type) && (tags.Contains(thing.Args[1]))) ||
+					 ((action.Args[2].Type == (int)type) && (tags.Contains(thing.Args[2]))) ||
+					 ((action.Args[3].Type == (int)type) && (tags.Contains(thing.Args[3]))) ||
+					 ((action.Args[4].Type == (int)type) && (tags.Contains(thing.Args[4]))))
+				{
+					return true;
+				}
+
+				//If there is a link setup on this thing, and it matches the association, then draw a direct link to any matching tag
+				if (ti != null && directlinktype == thing.Type && tags.Contains(thing.Tag))
+				{
+					return true;
+				}
+			}
+			//mxd. Thing action on this thing?
+			else if (thing.Action == 0)
+			{
+				// Gets the association, unless it is a child link.
+				// This prevents a reverse link to a thing via an argument, when it should be a direct tag-to-tag link instead.
+				if (ti != null && directlinktype >= 0 && Math.Abs(directlinktype) != thing.Type)
+				{
+					if (((ti.Args[0].Type == (int)type) && (tags.Contains(thing.Args[0]))) ||
+						 ((ti.Args[1].Type == (int)type) && (tags.Contains(thing.Args[1]))) ||
+						 ((ti.Args[2].Type == (int)type) && (tags.Contains(thing.Args[2]))) ||
+						 ((ti.Args[3].Type == (int)type) && (tags.Contains(thing.Args[3]))) ||
+						 ((ti.Args[4].Type == (int)type) && (tags.Contains(thing.Args[4]))))
+					{
+						return true;
+					}
+				}
+			}
+
+			return false;
 		}
 
-		// This sets up the association
-		public void Set(Vector2D center, int tag, int type)
+		/// <summary>
+		/// Returns a string that contains the description of the action and its arguments, based on the given Linedef or Thing
+		/// </summary>
+		/// <param name="se">An instance of Thing or Linedef</param>
+		/// <returns>String that contains the description of the action and its arguments for a given Linedef or Thing</returns>
+		private string GetActionDescription(SelectableElement se)
 		{
-			this.Set(center, tag, type, 0);
+			int action = 0;
+			int[] actionargs = new int[5];
+
+			if (se is Thing)
+			{
+				action = ((Thing)se).Action;
+				actionargs = ((Thing)se).Args;
+			}
+			else if(se is Linedef)
+			{
+				action = ((Linedef)se).Action;
+				actionargs = ((Linedef)se).Args;
+			}
+
+			if (action > 0)
+			{
+				LinedefActionInfo lai = General.Map.Config.GetLinedefActionInfo(action);
+				List<string> argdescription = new List<string>();
+
+				string description = lai.Index + ": " + lai.Title;
+
+				// Label style: only action, or if the element can't have any parameters
+				if (BuilderPlug.Me.EventLineLabelStyle == 0 || General.Map.Config.LineTagIndicatesSectors)
+					return description;
+
+				for (int i=0; i < 5; i++)
+				{
+					if(lai.Args[i].Used)
+					{
+						string argstring = "";
+
+						if(BuilderPlug.Me.EventLineLabelStyle == 2) // Label style: full arguments
+							argstring = lai.Args[i].Title + ": ";
+
+						EnumItem ei = lai.Args[i].Enum.GetByEnumIndex(actionargs[i].ToString());
+
+						if (ei != null && BuilderPlug.Me.EventLineLabelStyle == 2) // Label style: full arguments
+							argstring += ei.ToString();
+						else // Argument has no EnumItem or label style: short arguments
+							argstring += actionargs[i].ToString();
+
+						argdescription.Add(argstring);
+					}
+				}
+
+				description += " (" + string.Join(", ", argdescription) + ")";
+
+				return description;
+			}
+
+			return null;
 		}
 
-		public void Set(Vector2D center, int tag, int type, int directlinktype)
+		/// <summary>
+		/// Sets a different color for each event
+		/// </summary>
+		private void SetEventLineColors()
 		{
-			this.tags = new HashSet<int> { tag }; //mxd
-			this.type = (UniversalType)type;
-			this.center = center;
-			this.directlinktype = directlinktype;
+			int colorindex = 0;
+
+			foreach(KeyValuePair<string, List<TextLabel>> kvp in textlabels)
+			{
+				foreach (Line3D l in eventlines[kvp.Key])
+					l.Color = distinctcolors[colorindex];
+
+				foreach (TextLabel l in kvp.Value)
+					l.Color = distinctcolors[colorindex];
+
+				if(BuilderPlug.Me.EventLineDistinctColors)
+					if (++colorindex >= distinctcolors.Count)
+						colorindex = 0;
+			}
 		}
 
-		// This sets up the association
-		public void Set(Vector2D center, int tag, UniversalType type)
+		/// <summary>
+		/// Adds a line to an action
+		/// </summary>
+		/// <param name="action">Name of the action</param>
+		/// <param name="start">Start of the line</param>
+		/// <param name="end">End of the line</param>
+		private void AddLineToAction(string action, Vector2D start, Vector2D end)
 		{
-			this.Set(center, tag, type, 0);
+			if (action == null)
+				return;
+
+			if (!eventlines.ContainsKey(action))
+				eventlines[action] = new List<Line3D>();
+
+			eventlines[action].Add(new Line3D(start, end, true));
 		}
 
-		public void Set(Vector2D center, int tag, UniversalType type, int directlinktype)
+		/// <summary>
+		/// Generates a label position given a start and end point of a line. Taken (with modifications) from LineLengthLabel.Move()
+		/// </summary>
+		/// <param name="start">Start of the line</param>
+		/// <param name="end">End of the line</param>
+		/// <returns></returns>
+		private Vector2D GetLabelPosition(Vector2D start, Vector2D end)
 		{
-			this.tags = new HashSet<int> { tag }; //mxd
-			this.type = type;
-			this.center = center;
-			this.directlinktype = directlinktype;
+			// Check if start/end point is on screen...
+			Vector2D lt = General.Map.Renderer2D.DisplayToMap(new Vector2D(0.0, General.Interface.Display.Size.Height));
+			Vector2D rb = General.Map.Renderer2D.DisplayToMap(new Vector2D(General.Interface.Display.Size.Width, 0.0));
+			RectangleF viewport = new RectangleF((float)lt.x, (float)lt.y, (float)(rb.x - lt.x), (float)(rb.y - lt.y));
+			bool startvisible = viewport.Contains((float)start.x, (float)start.y);
+			bool endvisible = viewport.Contains((float)end.x, (float)end.y);
+
+			// Do this only when one point is visible, an the other isn't 
+			if ((!startvisible && endvisible) || (startvisible && !endvisible))
+			{
+				Line2D drawnline = new Line2D(start, end);
+				Line2D[] viewportsides = new[] {
+					new Line2D(lt, rb.x, lt.y), // top
+					new Line2D(lt.x, rb.y, rb.x, rb.y), // bottom
+					new Line2D(lt, lt.x, rb.y), // left
+					new Line2D(rb.x, lt.y, rb.x, rb.y), // right
+				};
+
+				foreach (Line2D side in viewportsides)
+				{
+					// Modify the start point so it stays on screen
+					double u;
+					if (!startvisible && side.GetIntersection(drawnline, out u))
+					{
+						start = drawnline.GetCoordinatesAt(u);
+						break;
+					}
+
+					// Modify the end point so it stays on screen
+					if (!endvisible && side.GetIntersection(drawnline, out u))
+					{
+						end = drawnline.GetCoordinatesAt(u);
+						break;
+					}
+				}
+			}
+
+			// Create position
+			Vector2D delta = end - start;
+			return new Vector2D(start.x + delta.x * 0.5, start.y + delta.y * 0.5);
 		}
 
-		//mxd. This also sets up the association
-		public void Set(Vector2D center, IEnumerable<int> tags, int type)
+		/// <summary>
+		/// Merges label positions based on a merge distance
+		/// </summary>
+		/// <param name="positions">Positions to merge</param>
+		/// <param name="distance">Distance to merge positions at</param>
+		/// <returns>List of new positions</returns>
+		List<Vector2D> MergePositions(List<Vector2D> positions, Vector2D distance)
 		{
-			this.Set(center, tags, (UniversalType)type, 0);
+			List<Vector2D> allpositions = positions.OrderBy(o => o.x).ToList();
+			List<Vector2D> newpositions = new List<Vector2D>(positions.Count);
+			Vector2D mergedistance = distance / renderer.Scale * 1.5;
+
+			// Keep going while we have positions me might want to merge
+			while (allpositions.Count > 0)
+			{
+				Vector2D curposition = allpositions[0];
+				allpositions.RemoveAt(0);
+
+				bool hasclosepositions = true;
+
+				// Keep merging as long as there are close positions nearby
+				while(hasclosepositions)
+				{
+					// Get all positions that are close to the current position
+					List<Vector2D> closepositions = allpositions.Where(o => Math.Abs(curposition.x - o.x) < mergedistance.x && Math.Abs(curposition.y - o.y) < mergedistance.y).ToList();
+
+					if (closepositions.Count > 0)
+					{
+						Vector2D tl = curposition;
+						Vector2D br = curposition;
+
+						// Get the max dimensions of the positions...
+						foreach (Vector2D v in closepositions)
+						{
+							if (v.x < tl.x) tl.x = v.x;
+							if (v.x > br.x) br.x = v.x;
+							if (v.y > tl.y) tl.y = v.y;
+							if (v.y < br.y) br.y = v.y;
+
+							// Remove the position from the list so that it doesn't get checked again
+							allpositions.Remove(v);
+						}
+
+						// ... and set the current position to the center of that
+						curposition.x = tl.x + (br.x - tl.x) / 2.0;
+						curposition.y = tl.y + (br.y - tl.y) / 2.0;
+					}
+					else
+					{
+						// The current position is a new final position
+						newpositions.Add(curposition);
+						hasclosepositions = false;
+						allpositions.Reverse();
+					}
+				}
+			}
+
+			return newpositions;
 		}
 
-		//mxd. This also sets up the association
-		public void Set(Vector2D center, IEnumerable<int> tags, UniversalType type)
+
+		/// <summary>
+		/// Renders associated things and sectors in the indication color.
+		/// Also renders event lines, if that option is enabled
+		/// </summary>
+		public void Render()
 		{
-			this.Set(center, tags, type, 0);
+			bool showlabels = BuilderPlug.Me.EventLineLabelVisibility > 0; // Show labels at all?
+
+			foreach (Thing t in things)
+				renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
+
+			// There must be a better way to do this
+			foreach(Sector s in sectors)
+			{
+				int highlightedColor = General.Colors.Highlight.WithAlpha(128).ToInt();
+				FlatVertex[] verts = new FlatVertex[s.FlatVertices.Length];
+				s.FlatVertices.CopyTo(verts, 0);
+				for (int i = 0; i < verts.Length; i++) verts[i].c = highlightedColor;
+				renderer.RenderGeometry(verts, null, true);
+			}
+
+			if (General.Settings.GZShowEventLines)
+			{
+				List<Line3D> lines = new List<Line3D>(eventlines.Count);
+				List<ITextLabel> labels = new List<ITextLabel>(eventlines.Count);
+
+				foreach(KeyValuePair<string, List<Line3D>> kvp in eventlines)
+				{
+					bool emptylabel = string.IsNullOrEmpty(kvp.Key); // Can be true if only either forward or reverse labels are shown
+					List<Vector2D> allpositions = new List<Vector2D>(kvp.Value.Count);
+
+					foreach (Line3D line in kvp.Value)
+					{
+						if (showlabels && !emptylabel)
+							allpositions.Add(GetLabelPosition(line.Start, line.End));
+
+						lines.Add(line);
+					}
+
+					if (showlabels && !emptylabel)
+					{
+						List<Vector2D> positions = MergePositions(allpositions, textwidths[kvp.Key]);
+						int labelcounter = 0;
+
+						// Set the position of the pre-generated labels. Only add the labels that are needed
+						foreach (Vector2D pos in positions)
+						{
+							textlabels[kvp.Key][labelcounter].Location = pos;
+							labels.Add(textlabels[kvp.Key][labelcounter]);
+							labelcounter++;
+						}
+					}
+				}
+
+				renderer.RenderArrows(lines);
+
+				if (showlabels)
+					renderer.RenderText(labels);
+			}
 		}
 
-		//mxd. This also sets up the association
-		public void Set(Vector2D center, IEnumerable<int> tags, UniversalType type, int directlinktype)
+		/// <summary>
+		/// Plots associated linedefs and sectors
+		/// </summary>
+		public void Plot()
 		{
-			this.tags = new HashSet<int>(tags); //mxd
-			this.type = type;
-			this.center = center;
-			this.directlinktype = directlinktype;
+			foreach(Linedef ld in linedefs)
+				renderer.PlotLinedef(ld, General.Colors.Indication);
+
+			foreach (Sector s in sectors)
+				renderer.PlotSector(s, General.Colors.Indication);
 		}
 
 		// This compares an association
diff --git a/Source/Plugins/BuilderModes/General/BuilderPlug.cs b/Source/Plugins/BuilderModes/General/BuilderPlug.cs
index ec9d59aae21317f2822515f0b5921540272204b5..7713cf2debe2f948674dfe1049bbce2751af8ed2 100755
--- a/Source/Plugins/BuilderModes/General/BuilderPlug.cs
+++ b/Source/Plugins/BuilderModes/General/BuilderPlug.cs
@@ -138,11 +138,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		private bool showlightradii; //mxd
 		private bool showsoundradii; //mxd
 		private int scaletexturesonslopes; // 0 = base scale of 1, 1 = use current scale as base, 2 = don't scale
-		
+		private int eventlinelabelvisibility; // 0 = never show, 1 = forward only, 2 = reverse only, 3 = forward + reverse
+		private int eventlinelabelstyle; // 0 = Action only, 1 = Action + short arguments, 2 = action + full arguments
+		private bool eventlinedistinctcolors;
+
 		#endregion
 
 		#region ================== Properties
-		
+
 		public override string Name { get { return "Ultimate Doom Builder"; } } //mxd
 		public static BuilderPlug Me { get { return me; } }
 
@@ -193,6 +196,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		public bool ShowLightRadii { get { return showlightradii; } internal set { showlightradii = value; } } //mxd
 		public bool ShowSoundRadii { get { return showsoundradii; } internal set { showsoundradii = value; } } //mxd
 		public int ScaleTexturesOnSlopes { get { return scaletexturesonslopes; } internal set { scaletexturesonslopes = value; } }
+		public int EventLineLabelVisibility { get { return eventlinelabelvisibility; } internal set { eventlinelabelvisibility = value; } }
+		public int EventLineLabelStyle { get { return eventlinelabelstyle; } internal set { eventlinelabelstyle = value; } }
+		public bool EventLineDistinctColors { get { return eventlinedistinctcolors; } internal set { eventlinedistinctcolors = value; } }
 
 		//mxd. "Make Door" action persistent settings
 		internal MakeDoorSettings MakeDoor;
@@ -297,6 +303,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			dontMoveGeometryOutsideMapBoundary = General.Settings.ReadPluginSetting("dontmovegeometryoutsidemapboundary", false); //mxd
 			syncSelection = General.Settings.ReadPluginSetting("syncselection", false); //mxd
 			scaletexturesonslopes = General.Settings.ReadPluginSetting("scaletexturesonslopes", 0);
+			eventlinelabelvisibility = General.Settings.ReadPluginSetting("eventlinelabelvisibility", 3);
+			eventlinelabelstyle = General.Settings.ReadPluginSetting("eventlinelabelstyle", 2);
+			eventlinedistinctcolors = General.Settings.ReadPluginSetting("eventlinedistinctcolors", true);
 		}
 
 		//mxd. Load settings, which can be changed via UI
@@ -619,176 +628,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			// Return list
 			return found.ToArray();
 		}
-		
-		// This renders the associated sectors/linedefs with the indication color
-		public static void PlotAssociations(IRenderer2D renderer, Association asso, List<Line3D> eventlines) 
-		{
-			// Tag must be above zero
-			if(General.GetByIndex(asso.Tags, 0) < 1) return;
-			
-			// Sectors?
-			switch(asso.Type)
-			{
-				case UniversalType.SectorTag: {
-					foreach(Sector s in General.Map.Map.Sectors)
-					{
-						if(!asso.Tags.Overlaps(s.Tags))continue;
-						renderer.PlotSector(s, General.Colors.Indication);
-						
-						if(!General.Settings.GZShowEventLines) continue;
-						Vector2D end = (s.Labels.Count > 0 ? s.Labels[0].position : new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
-						eventlines.Add(new Line3D(asso.Center, end)); //mxd
-					}
-					break;
-				}
-
-				case UniversalType.LinedefTag: {
-					foreach(Linedef l in General.Map.Map.Linedefs) 
-					{
-						if(!asso.Tags.Overlaps(l.Tags)) continue;
-						renderer.PlotLinedef(l, General.Colors.Indication);
-						if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(asso.Center, l.GetCenterPoint())); //mxd
-					}
-					break;
-				}
-			}
-		}
-
-		// This renders the associated things with the indication color
-		public static void RenderAssociations(IRenderer2D renderer, Association asso, List<Line3D> eventlines)
-		{
-			// Tag must be above zero
-			if(General.GetByIndex(asso.Tags, 0) < 1) return;
-
-			// Things?
-			switch(asso.Type)
-			{
-				case UniversalType.ThingTag:
-					foreach(Thing t in General.Map.Map.Things)
-					{
-						if(!asso.Tags.Contains(t.Tag)) continue;
-
-						//Do not draw the association if the user is hovering over a child link
-						ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
-						if (ti != null && ti.ThingLink < 0)
-							continue;
-
-						renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
-						if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(asso.Center, t.Position)); //mxd
-					}
-					break;
-
-				case UniversalType.SectorTag:
-					foreach(Sector s in General.Map.Map.Sectors) 
-					{
-						if(!asso.Tags.Overlaps(s.Tags)) continue;
-						int highlightedColor = General.Colors.Highlight.WithAlpha(128).ToInt();
-						FlatVertex[] verts = new FlatVertex[s.FlatVertices.Length];
-						s.FlatVertices.CopyTo(verts, 0);
-						for(int i = 0; i < verts.Length; i++) verts[i].c = highlightedColor;
-						renderer.RenderGeometry(verts, null, true);
-					}
-					break;
-			}
-		}
-
-		// This renders the associated sectors/linedefs with the indication color
-		public static void PlotReverseAssociations(IRenderer2D renderer, Association asso, List<Line3D> eventlines)
-		{
-			// Tag must be above zero
-			if(General.GetByIndex(asso.Tags, 0) < 1) return;
-			
-			// Doom style referencing to sectors?
-			if(General.Map.Config.LineTagIndicatesSectors && (asso.Type == UniversalType.SectorTag))
-			{
-				// Linedefs
-				foreach(Linedef l in General.Map.Map.Linedefs)
-				{
-					// Any action on this line?
-					if(l.Action <= 0 || !asso.Tags.Overlaps(l.Tags)) continue;
-					renderer.PlotLinedef(l, General.Colors.Indication);
-					if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(l.GetCenterPoint(), asso.Center)); //mxd
-				}
-			}
-
-			// Linedefs
-			foreach(Linedef l in General.Map.Map.Linedefs)
-			{
-				// Known action on this line?
-				if((l.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(l.Action))
-				{
-					LinedefActionInfo action = General.Map.Config.LinedefActions[l.Action];
-					if( ((action.Args[0].Type == (int)asso.Type) && (asso.Tags.Contains(l.Args[0]))) ||
-						((action.Args[1].Type == (int)asso.Type) && (asso.Tags.Contains(l.Args[1]))) ||
-						((action.Args[2].Type == (int)asso.Type) && (asso.Tags.Contains(l.Args[2]))) ||
-						((action.Args[3].Type == (int)asso.Type) && (asso.Tags.Contains(l.Args[3]))) ||
-						((action.Args[4].Type == (int)asso.Type) && (asso.Tags.Contains(l.Args[4]))))
-					{
-						renderer.PlotLinedef(l, General.Colors.Indication);
-						if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(l.GetCenterPoint(), asso.Center)); //mxd
-					}
-				}
-			}
-		}
-
-		// This renders the associated things with the indication color
-		public static void RenderReverseAssociations(IRenderer2D renderer, Association asso, List<Line3D> eventlines)
-		{
-			// Tag must be above zero
-			if(General.GetByIndex(asso.Tags, 0) < 1) return;
-
-			// Things
-			foreach(Thing t in General.Map.Map.Things)
-			{
-				// Get the thing type info
-				ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
-
-				// Known action on this thing?
-				if((t.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(t.Action))
-				{
-					//Do not draw the association if this is a child link.
-					//  This prevents a reverse link to a thing via an argument, when it should be a direct tag-to-tag link instead.
-					if(ti != null && asso.DirectLinkType < 0 && asso.DirectLinkType != -t.Type)
-						continue;
-
-					LinedefActionInfo action = General.Map.Config.LinedefActions[t.Action];
-					if(  ((action.Args[0].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[0]))) ||
-						 ((action.Args[1].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[1]))) ||
-						 ((action.Args[2].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[2]))) ||
-						 ((action.Args[3].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[3]))) ||
-						 ((action.Args[4].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[4]))))
-					{
-						renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
-						if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(t.Position, asso.Center)); //mxd
-					}
-
-					//If there is a link setup on this thing, and it matches the association, then draw a direct link to any matching tag
-					if(ti != null && asso.DirectLinkType == t.Type && asso.Tags.Contains(t.Tag))
-					{
-						renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
-						if (General.Settings.GZShowEventLines) eventlines.Add(new Line3D(t.Position, asso.Center));
-					}
-				}
-				//mxd. Thing action on this thing?
-				else if(t.Action == 0)
-				{
-					//Draw the association, unless it is a child link.
-					//  This prevents a reverse link to a thing via an argument, when it should be a direct tag-to-tag link instead.
-					if(ti != null && asso.DirectLinkType >= 0 && Math.Abs(asso.DirectLinkType) != t.Type)
-					{
-						if(  ((ti.Args[0].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[0]))) ||
-							 ((ti.Args[1].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[1]))) ||
-							 ((ti.Args[2].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[2]))) ||
-							 ((ti.Args[3].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[3]))) ||
-							 ((ti.Args[4].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[4]))))
-						{
-							renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
-							if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(t.Position, asso.Center));
-						}
-					}
-				}
-			}
-		}
 
 		#endregion
 
diff --git a/Source/Plugins/BuilderModes/Interface/PreferencesForm.Designer.cs b/Source/Plugins/BuilderModes/Interface/PreferencesForm.Designer.cs
index 1db5dac638fe2be90fac4b11d4d52fa45d5309be..92deef964db4c56004f7be75d91299e549eb5295 100755
--- a/Source/Plugins/BuilderModes/Interface/PreferencesForm.Designer.cs
+++ b/Source/Plugins/BuilderModes/Interface/PreferencesForm.Designer.cs
@@ -69,18 +69,22 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.label4 = new System.Windows.Forms.Label();
 			this.label7 = new System.Windows.Forms.Label();
 			this.groupBox1 = new System.Windows.Forms.GroupBox();
+			this.scaletexturesonslopes = new System.Windows.Forms.ComboBox();
+			this.label18 = new System.Windows.Forms.Label();
 			this.splitbehavior = new System.Windows.Forms.ComboBox();
 			this.label10 = new System.Windows.Forms.Label();
 			this.label1 = new System.Windows.Forms.Label();
 			this.heightbysidedef = new System.Windows.Forms.ComboBox();
-			this.label18 = new System.Windows.Forms.Label();
-			this.scaletexturesonslopes = new System.Windows.Forms.ComboBox();
+			this.groupBox5 = new System.Windows.Forms.GroupBox();
+			this.eventlinelabelvisibility = new System.Windows.Forms.ComboBox();
+			this.eventlinelabelstyle = new System.Windows.Forms.ComboBox();
 			this.tabs.SuspendLayout();
 			this.taboptions.SuspendLayout();
 			this.groupBox4.SuspendLayout();
 			this.groupBox3.SuspendLayout();
 			this.groupBox2.SuspendLayout();
 			this.groupBox1.SuspendLayout();
+			this.groupBox5.SuspendLayout();
 			this.SuspendLayout();
 			// 
 			// tabs
@@ -99,6 +103,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			// 
 			// taboptions
 			// 
+			this.taboptions.Controls.Add(this.groupBox5);
 			this.taboptions.Controls.Add(this.groupBox4);
 			this.taboptions.Controls.Add(this.groupBox3);
 			this.taboptions.Controls.Add(this.groupBox2);
@@ -122,9 +127,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.groupBox4.Controls.Add(this.label12);
 			this.groupBox4.Controls.Add(this.defaultbrightness);
 			this.groupBox4.Controls.Add(this.label11);
-			this.groupBox4.Location = new System.Drawing.Point(6, 335);
+			this.groupBox4.Location = new System.Drawing.Point(6, 320);
 			this.groupBox4.Name = "groupBox4";
-			this.groupBox4.Size = new System.Drawing.Size(272, 136);
+			this.groupBox4.Size = new System.Drawing.Size(272, 119);
 			this.groupBox4.TabIndex = 2;
 			this.groupBox4.TabStop = false;
 			this.groupBox4.Text = " Default sector settings";
@@ -132,7 +137,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			// label15
 			// 
 			this.label15.AutoSize = true;
-			this.label15.Location = new System.Drawing.Point(218, 37);
+			this.label15.Location = new System.Drawing.Point(218, 27);
 			this.label15.Name = "label15";
 			this.label15.Size = new System.Drawing.Size(27, 13);
 			this.label15.TabIndex = 26;
@@ -141,7 +146,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			// label14
 			// 
 			this.label14.AutoSize = true;
-			this.label14.Location = new System.Drawing.Point(218, 67);
+			this.label14.Location = new System.Drawing.Point(218, 57);
 			this.label14.Name = "label14";
 			this.label14.Size = new System.Drawing.Size(27, 13);
 			this.label14.TabIndex = 20;
@@ -159,7 +164,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.defaultfloorheight.ButtonStepSmall = 0.1F;
 			this.defaultfloorheight.ButtonStepsUseModifierKeys = false;
 			this.defaultfloorheight.ButtonStepsWrapAround = false;
-			this.defaultfloorheight.Location = new System.Drawing.Point(153, 32);
+			this.defaultfloorheight.Location = new System.Drawing.Point(153, 22);
 			this.defaultfloorheight.Name = "defaultfloorheight";
 			this.defaultfloorheight.Size = new System.Drawing.Size(59, 24);
 			this.defaultfloorheight.StepValues = null;
@@ -167,7 +172,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			// 
 			// label13
 			// 
-			this.label13.Location = new System.Drawing.Point(38, 37);
+			this.label13.Location = new System.Drawing.Point(38, 27);
 			this.label13.Name = "label13";
 			this.label13.Size = new System.Drawing.Size(110, 14);
 			this.label13.TabIndex = 24;
@@ -186,7 +191,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.defaultceilheight.ButtonStepSmall = 0.1F;
 			this.defaultceilheight.ButtonStepsUseModifierKeys = false;
 			this.defaultceilheight.ButtonStepsWrapAround = false;
-			this.defaultceilheight.Location = new System.Drawing.Point(153, 62);
+			this.defaultceilheight.Location = new System.Drawing.Point(153, 52);
 			this.defaultceilheight.Name = "defaultceilheight";
 			this.defaultceilheight.Size = new System.Drawing.Size(59, 24);
 			this.defaultceilheight.StepValues = null;
@@ -194,7 +199,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			// 
 			// label12
 			// 
-			this.label12.Location = new System.Drawing.Point(38, 67);
+			this.label12.Location = new System.Drawing.Point(38, 57);
 			this.label12.Name = "label12";
 			this.label12.Size = new System.Drawing.Size(110, 14);
 			this.label12.TabIndex = 22;
@@ -213,7 +218,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.defaultbrightness.ButtonStepSmall = 0.1F;
 			this.defaultbrightness.ButtonStepsUseModifierKeys = false;
 			this.defaultbrightness.ButtonStepsWrapAround = false;
-			this.defaultbrightness.Location = new System.Drawing.Point(153, 92);
+			this.defaultbrightness.Location = new System.Drawing.Point(153, 82);
 			this.defaultbrightness.Name = "defaultbrightness";
 			this.defaultbrightness.Size = new System.Drawing.Size(59, 24);
 			this.defaultbrightness.StepValues = null;
@@ -221,7 +226,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			// 
 			// label11
 			// 
-			this.label11.Location = new System.Drawing.Point(38, 97);
+			this.label11.Location = new System.Drawing.Point(38, 87);
 			this.label11.Name = "label11";
 			this.label11.Size = new System.Drawing.Size(110, 14);
 			this.label11.TabIndex = 20;
@@ -244,7 +249,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.groupBox3.Controls.Add(this.additiveselect);
 			this.groupBox3.Location = new System.Drawing.Point(284, 139);
 			this.groupBox3.Name = "groupBox3";
-			this.groupBox3.Size = new System.Drawing.Size(379, 332);
+			this.groupBox3.Size = new System.Drawing.Size(379, 360);
 			this.groupBox3.TabIndex = 3;
 			this.groupBox3.TabStop = false;
 			this.groupBox3.Text = " Options ";
@@ -389,7 +394,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.groupBox2.Controls.Add(this.label7);
 			this.groupBox2.Location = new System.Drawing.Point(6, 139);
 			this.groupBox2.Name = "groupBox2";
-			this.groupBox2.Size = new System.Drawing.Size(272, 190);
+			this.groupBox2.Size = new System.Drawing.Size(272, 175);
 			this.groupBox2.TabIndex = 1;
 			this.groupBox2.TabStop = false;
 			this.groupBox2.Text = " Ranges ";
@@ -594,6 +599,29 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.groupBox1.TabStop = false;
 			this.groupBox1.Text = " Behavior ";
 			// 
+			// scaletexturesonslopes
+			// 
+			this.scaletexturesonslopes.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+			this.scaletexturesonslopes.FormattingEnabled = true;
+			this.scaletexturesonslopes.Items.AddRange(new object[] {
+            "Use a scale of 1 as base",
+            "Use current scale as base",
+            "Don\'t scale"});
+			this.scaletexturesonslopes.Location = new System.Drawing.Point(342, 91);
+			this.scaletexturesonslopes.Name = "scaletexturesonslopes";
+			this.scaletexturesonslopes.Size = new System.Drawing.Size(309, 21);
+			this.scaletexturesonslopes.TabIndex = 3;
+			// 
+			// label18
+			// 
+			this.label18.AutoSize = true;
+			this.label18.Location = new System.Drawing.Point(133, 94);
+			this.label18.Name = "label18";
+			this.label18.Size = new System.Drawing.Size(190, 13);
+			this.label18.TabIndex = 2;
+			this.label18.Text = "When auto-aligning textures on slopes:";
+			this.label18.TextAlign = System.Drawing.ContentAlignment.TopRight;
+			// 
 			// splitbehavior
 			// 
 			this.splitbehavior.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
@@ -642,28 +670,43 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.heightbysidedef.Size = new System.Drawing.Size(309, 21);
 			this.heightbysidedef.TabIndex = 0;
 			// 
-			// label18
-			// 
-			this.label18.AutoSize = true;
-			this.label18.Location = new System.Drawing.Point(133, 94);
-			this.label18.Name = "label18";
-			this.label18.Size = new System.Drawing.Size(190, 13);
-			this.label18.TabIndex = 2;
-			this.label18.Text = "When auto-aligning textures on slopes:";
-			this.label18.TextAlign = System.Drawing.ContentAlignment.TopRight;
-			// 
-			// scaletexturesonslopes
-			// 
-			this.scaletexturesonslopes.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-			this.scaletexturesonslopes.FormattingEnabled = true;
-			this.scaletexturesonslopes.Items.AddRange(new object[] {
-            "Use a scale of 1 as base",
-            "Use current scale as base",
-            "Don\'t scale"});
-			this.scaletexturesonslopes.Location = new System.Drawing.Point(342, 91);
-			this.scaletexturesonslopes.Name = "scaletexturesonslopes";
-			this.scaletexturesonslopes.Size = new System.Drawing.Size(309, 21);
-			this.scaletexturesonslopes.TabIndex = 3;
+			// groupBox5
+			// 
+			this.groupBox5.Controls.Add(this.eventlinelabelstyle);
+			this.groupBox5.Controls.Add(this.eventlinelabelvisibility);
+			this.groupBox5.Location = new System.Drawing.Point(6, 445);
+			this.groupBox5.Name = "groupBox5";
+			this.groupBox5.Size = new System.Drawing.Size(272, 54);
+			this.groupBox5.TabIndex = 4;
+			this.groupBox5.TabStop = false;
+			this.groupBox5.Text = "Event line labels";
+			// 
+			// eventlinelabelvisibility
+			// 
+			this.eventlinelabelvisibility.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+			this.eventlinelabelvisibility.FormattingEnabled = true;
+			this.eventlinelabelvisibility.Items.AddRange(new object[] {
+            "Never show",
+            "Forward only",
+            "Reverse only",
+            "Forward + Reverse"});
+			this.eventlinelabelvisibility.Location = new System.Drawing.Point(6, 19);
+			this.eventlinelabelvisibility.Name = "eventlinelabelvisibility";
+			this.eventlinelabelvisibility.Size = new System.Drawing.Size(121, 21);
+			this.eventlinelabelvisibility.TabIndex = 0;
+			// 
+			// eventlinelabelstyle
+			// 
+			this.eventlinelabelstyle.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+			this.eventlinelabelstyle.FormattingEnabled = true;
+			this.eventlinelabelstyle.Items.AddRange(new object[] {
+            "Action only",
+            "Action + short arguments",
+            "Action + full arguments"});
+			this.eventlinelabelstyle.Location = new System.Drawing.Point(133, 19);
+			this.eventlinelabelstyle.Name = "eventlinelabelstyle";
+			this.eventlinelabelstyle.Size = new System.Drawing.Size(133, 21);
+			this.eventlinelabelstyle.TabIndex = 1;
 			// 
 			// PreferencesForm
 			// 
@@ -686,6 +729,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.groupBox2.PerformLayout();
 			this.groupBox1.ResumeLayout(false);
 			this.groupBox1.PerformLayout();
+			this.groupBox5.ResumeLayout(false);
 			this.ResumeLayout(false);
 
 		}
@@ -739,5 +783,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		private System.Windows.Forms.CheckBox additivepaintselect;
 		private System.Windows.Forms.ComboBox scaletexturesonslopes;
 		private System.Windows.Forms.Label label18;
+		private System.Windows.Forms.GroupBox groupBox5;
+		private System.Windows.Forms.ComboBox eventlinelabelvisibility;
+		private System.Windows.Forms.ComboBox eventlinelabelstyle;
 	}
 }
\ No newline at end of file
diff --git a/Source/Plugins/BuilderModes/Interface/PreferencesForm.cs b/Source/Plugins/BuilderModes/Interface/PreferencesForm.cs
index 38ff83de032c583be1682da86196788bbb2badd3..42cea092276d734b6d1cc8cce21635e927ac745c 100755
--- a/Source/Plugins/BuilderModes/Interface/PreferencesForm.cs
+++ b/Source/Plugins/BuilderModes/Interface/PreferencesForm.cs
@@ -65,6 +65,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			defaultceilheight.Text = General.Settings.DefaultCeilingHeight.ToString();//mxd
 			defaultfloorheight.Text = General.Settings.DefaultFloorHeight.ToString(); //mxd
 			scaletexturesonslopes.SelectedIndex = General.Settings.ReadPluginSetting("scaletexturesonslopes", 0);
+			eventlinelabelvisibility.SelectedIndex = General.Settings.ReadPluginSetting("eventlinelabelvisibility", 3);
+			eventlinelabelstyle.SelectedIndex = General.Settings.ReadPluginSetting("eventlinelabelstyle", 2);
 		}
 
 		#endregion
@@ -93,6 +95,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			General.Settings.WritePluginSetting("dontmovegeometryoutsidemapboundary", dontMoveGeometryOutsideBounds.Checked);//mxd
 			General.Settings.WritePluginSetting("syncselection", syncSelection.Checked);//mxd
 			General.Settings.WritePluginSetting("scaletexturesonslopes", scaletexturesonslopes.SelectedIndex);
+			General.Settings.WritePluginSetting("eventlinelabelvisibility", eventlinelabelvisibility.SelectedIndex);
+			General.Settings.WritePluginSetting("eventlinelabelstyle", eventlinelabelstyle.SelectedIndex);
 			General.Settings.SwitchViewModes = switchviewmodes.Checked; //mxd
 			General.Settings.SplitLineBehavior = (SplitLineBehavior)splitbehavior.SelectedIndex;//mxd