diff --git a/Build/Configurations/Includes/ZDoom_things.cfg b/Build/Configurations/Includes/ZDoom_things.cfg
index c851f1f87045b911ecb6cfb49577148528b8a9a8..99a8cea38bb4ee21fbe06fab67a18b4a2f738a88 100644
--- a/Build/Configurations/Includes/ZDoom_things.cfg
+++ b/Build/Configurations/Includes/ZDoom_things.cfg
@@ -429,7 +429,7 @@ zdoom
 					128 = "Nonsolid";
 				}
 			}
-			arg4
+			arg3
 			{
 				title = "Thing";
 				type = 14;
@@ -445,11 +445,11 @@ zdoom
 			}
 			arg1
 			{
-				title = "Travel Time";
+				title = "Travel Time (otics)";
 			}
 			arg2
 			{
-				title = "Hold Time";
+				title = "Hold Time (otics)";
 			}
 			arg3
 			{
diff --git a/Build/Scripting/ZDoom_ACS.cfg b/Build/Scripting/ZDoom_ACS.cfg
index bb4d7a846b2794aad40540a64a9d4c7f5769c5d0..6624b667d706c27873586bd1e7847d4ac919c826 100644
--- a/Build/Scripting/ZDoom_ACS.cfg
+++ b/Build/Scripting/ZDoom_ACS.cfg
@@ -357,7 +357,7 @@ keywords
 	Teleport_EndGame = "Teleport_EndGame()";
 	Teleport_Line = "Teleport_Line(thisid, destid, flip)";
 	Teleport_NewMap = "Teleport_NewMap(map, pos)";
-	Teleport_NoFog = "Teleport_NoFog(tid)";
+	Teleport_NoFog = "Teleport_NoFog(tid, useangle, tag)";
 	Teleport_NoStop = "Teleport_NoStop(tid, tag, nofog)";
 	Teleport_ZombieChanger = "Teleport_ZombieChanger(tid, tag)";
 	TeleportGroup = "TeleportGroup(groupid, sourceid, destinationid, movesource, fog)";
diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj
index 382c009303d71790e3e37463e1a63b43d6e0f6fb..46c02f088123a511252ac0d1b2f7715a628dc8de 100644
--- a/Source/Core/Builder.csproj
+++ b/Source/Core/Builder.csproj
@@ -705,7 +705,7 @@
     <Compile Include="GZBuilder\Data\BoundingBox.cs" />
     <Compile Include="GZBuilder\Data\GameType.cs" />
     <Compile Include="GZBuilder\Data\GZDoomLight.cs" />
-    <Compile Include="GZBuilder\Data\LinkHelper.cs" />
+    <Compile Include="GZBuilder\Data\LinksCollector.cs" />
     <Compile Include="GZBuilder\Data\MapInfo.cs" />
     <Compile Include="GZBuilder\Data\ModeldefEntry.cs" />
     <Compile Include="GZBuilder\Data\ScriptItem.cs" />
diff --git a/Source/Core/GZBuilder/Data/LinkHelper.cs b/Source/Core/GZBuilder/Data/LinkHelper.cs
deleted file mode 100644
index 2bea3c3b6d2570e2409f437e6318db4222284b59..0000000000000000000000000000000000000000
--- a/Source/Core/GZBuilder/Data/LinkHelper.cs
+++ /dev/null
@@ -1,164 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-//using CodeImp.DoomBuilder.Geometry;
-using CodeImp.DoomBuilder.Map;
-using CodeImp.DoomBuilder.VisualModes;
-using CodeImp.DoomBuilder.GZBuilder.Geometry;
-using CodeImp.DoomBuilder.Geometry;
-using CodeImp.DoomBuilder.Rendering;
-using CodeImp.DoomBuilder.Config;
-
-namespace CodeImp.DoomBuilder.GZBuilder.Data {
-    
-    public static class LinksCollector {
-        private struct ThingsCheckResult {
-            public bool ProcessPathNodes;
-            public bool ProcessInterpolationPoints;
-            public bool ProcessThingsWithGoal;
-            public bool ProcessCameras;
-        }
-        
-        public static List<Line3D> GetThingLinks(ICollection<VisualThing> visualThings) {
-            List<Thing> things = new List<Thing>();
-            foreach (VisualThing vt in visualThings) things.Add(vt.Thing);
-
-            ThingsCheckResult result = checkThings(things);
-            if (result.ProcessPathNodes || result.ProcessInterpolationPoints || result.ProcessThingsWithGoal || result.ProcessCameras)
-                return getThingLinks(result, true);
-            return new List<Line3D>();
-        }
-        
-        public static List<Line3D> GetThingLinks(ICollection<Thing> things) {
-            ThingsCheckResult result = checkThings(things);
-            if (result.ProcessPathNodes || result.ProcessInterpolationPoints || result.ProcessThingsWithGoal || result.ProcessCameras)
-                return getThingLinks(result, false);
-            return new List<Line3D>();
-        }
-
-        private static ThingsCheckResult checkThings(ICollection<Thing> things) {
-            ThingsCheckResult result = new ThingsCheckResult();
-
-            foreach (Thing t in things) {
-                if (t.Type == 9024) //zdoom path node
-                    result.ProcessPathNodes = true;
-                else if (t.Type == 9070) //zdoom camera interpolation point
-                    result.ProcessInterpolationPoints = true;
-                else if (t.Action == 229 && t.Args[1] != 0) //Thing_SetGoal
-                    result.ProcessThingsWithGoal = true;
-                else if (t.Type == 9072 && (t.Args[0] != 0 || t.Args[1] != 0)) //camera with a path
-                    result.ProcessCameras = true;
-            }
-
-            return result;
-        }
-
-        private static List<Line3D> getThingLinks(ThingsCheckResult result, bool correctHeight) {
-            List<Line3D> lines = new List<Line3D>();
-            Dictionary<int, Thing> pathNodes = new Dictionary<int, Thing>();
-            Dictionary<int, Thing> interpolationPoints = new Dictionary<int, Thing>();
-            List<Thing> thingsWithGoal = new List<Thing>();
-            List<Thing> cameras = new List<Thing>();
-
-            bool getPathNodes = result.ProcessPathNodes || result.ProcessThingsWithGoal;
-            bool getInterpolationPoints = result.ProcessInterpolationPoints || result.ProcessCameras;
-
-            //collect relevant things
-            foreach (Thing t in General.Map.Map.Things) {
-                if (getPathNodes && t.Type == 9024) {
-                    pathNodes[t.Tag] = t;
-                }
-                if (getInterpolationPoints && t.Type == 9070) {
-                    interpolationPoints[t.Tag] = t;
-                }
-                if (result.ProcessThingsWithGoal && t.Action == 229 && t.Args[1] != 0) {
-                    thingsWithGoal.Add(t);
-                }
-                if (result.ProcessCameras && t.Type == 9072 && (t.Args[0] != 0 || t.Args[1] != 0)) {
-                    cameras.Add(t);
-                }
-            }
-
-            Vector3D start = new Vector3D();
-            Vector3D end = new Vector3D();
-
-            //process path nodes
-            if (result.ProcessPathNodes) {
-                foreach (KeyValuePair<int, Thing> group in pathNodes) {
-                    if (group.Value.Args[0] == 0) continue; //no goal
-                    if (pathNodes.ContainsKey(group.Value.Args[0])) {
-                        start = group.Value.Position;
-                        if (correctHeight) start.z += getCorrectHeight(group.Value);
-
-                        end = pathNodes[group.Value.Args[0]].Position;
-                        if (correctHeight) end.z += getCorrectHeight(pathNodes[group.Value.Args[0]]);
-
-                        lines.Add(new Line3D(start, end));
-                    }
-                }
-            }
-
-            //process things with Thing_SetGoal
-            if (result.ProcessThingsWithGoal) {
-                foreach (Thing t in thingsWithGoal) {
-                    if (pathNodes.ContainsKey(t.Args[1])) {
-                        if (t.Args[0] == 0 || t.Args[0] == t.Tag) {
-                            start = t.Position;
-                            if (correctHeight) start.z += getCorrectHeight(t);
-
-                            end = pathNodes[t.Args[1]].Position;
-                            if (correctHeight) end.z += getCorrectHeight(pathNodes[t.Args[1]]);
-
-                            lines.Add(new Line3D(start, end));
-                        }
-                    }
-                }
-            }
-
-            //process interpolation points
-            if (result.ProcessInterpolationPoints) {
-                foreach (KeyValuePair<int, Thing> group in interpolationPoints) {
-                    int targetTag = group.Value.Args[3] + group.Value.Args[4] * 256;
-                    if (targetTag == 0) continue; //no goal
-
-                    if (interpolationPoints.ContainsKey(targetTag)) {
-                        start = group.Value.Position;
-                        if (correctHeight) start.z += getCorrectHeight(group.Value);
-
-                        end = interpolationPoints[targetTag].Position;
-                        if (correctHeight) end.z += getCorrectHeight(interpolationPoints[targetTag]);
-
-                        lines.Add(new Line3D(start, end));
-                    }
-                }
-            }
-
-            //process cameras
-            if (result.ProcessCameras) {
-                foreach (Thing t in cameras) {
-                    int targetTag = t.Args[0] + t.Args[1] * 256;
-                    if (targetTag == 0) continue; //no goal
-
-                    if (interpolationPoints.ContainsKey(targetTag)) {
-                            start = t.Position;
-                            if (correctHeight) start.z += getCorrectHeight(t);
-
-                            end = interpolationPoints[targetTag].Position;
-                            if (correctHeight) end.z += getCorrectHeight(interpolationPoints[targetTag]);
-
-                        lines.Add(new Line3D(start, end));
-                    }
-                }
-            }
-
-            return lines;
-        }
-
-        private static float getCorrectHeight(Thing thing) {
-            ThingTypeInfo tti = General.Map.Data.GetThingInfo(thing.Type);
-            float height = tti.Height / 2f;
-            if (thing.Sector != null) height += thing.Sector.FloorHeight;
-            return height;
-        }
-    }
-}
diff --git a/Source/Core/GZBuilder/Data/LinksCollector.cs b/Source/Core/GZBuilder/Data/LinksCollector.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9351c2ed86f650878aa809ffa3eb47b78b8221c2
--- /dev/null
+++ b/Source/Core/GZBuilder/Data/LinksCollector.cs
@@ -0,0 +1,237 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+//using CodeImp.DoomBuilder.Geometry;
+using CodeImp.DoomBuilder.Map;
+using CodeImp.DoomBuilder.VisualModes;
+using CodeImp.DoomBuilder.GZBuilder.Geometry;
+using CodeImp.DoomBuilder.Geometry;
+using CodeImp.DoomBuilder.Rendering;
+using CodeImp.DoomBuilder.Config;
+
+namespace CodeImp.DoomBuilder.GZBuilder.Data {
+    
+    public static class LinksCollector {
+        private struct ThingsCheckResult {
+            public bool ProcessPathNodes;
+            public bool ProcessInterpolationPoints;
+            public bool ProcessThingsWithGoal;
+            public bool ProcessCameras;
+			public bool ProcessActorMovers;
+        }
+        
+        public static List<Line3D> GetThingLinks(ICollection<VisualThing> visualThings) {
+            List<Thing> things = new List<Thing>();
+            foreach (VisualThing vt in visualThings) things.Add(vt.Thing);
+
+            ThingsCheckResult result = checkThings(things);
+            if (result.ProcessPathNodes || result.ProcessInterpolationPoints || result.ProcessThingsWithGoal || result.ProcessCameras)
+                return getThingLinks(result, true);
+            return new List<Line3D>();
+        }
+        
+        public static List<Line3D> GetThingLinks(ICollection<Thing> things) {
+            ThingsCheckResult result = checkThings(things);
+            if (result.ProcessPathNodes || result.ProcessInterpolationPoints || result.ProcessThingsWithGoal || result.ProcessCameras)
+                return getThingLinks(result, false);
+            return new List<Line3D>();
+        }
+
+        private static ThingsCheckResult checkThings(ICollection<Thing> things) {
+            ThingsCheckResult result = new ThingsCheckResult();
+
+            foreach (Thing t in things) {
+				if(t.Type == 9024) //zdoom path node
+					result.ProcessPathNodes = true;
+				else if(t.Type == 9070) //zdoom camera interpolation point
+					result.ProcessInterpolationPoints = true;
+				else if(t.Action == 229 && t.Args[1] != 0) //Thing_SetGoal
+					result.ProcessThingsWithGoal = true;
+				else if(t.Type == 9072 && (t.Args[0] != 0 || t.Args[1] != 0)) //camera with a path
+					result.ProcessCameras = true;
+				else if(t.Type == 9074 && (t.Args[0] != 0 || t.Args[1] != 0) && t.Args[3] != 0) //actor mover
+					result.ProcessActorMovers = true;
+            }
+
+			if(result.ProcessActorMovers || result.ProcessCameras)
+				result.ProcessInterpolationPoints = true;
+
+			if(result.ProcessThingsWithGoal)
+				result.ProcessPathNodes = true;
+
+            return result;
+        }
+
+        private static List<Line3D> getThingLinks(ThingsCheckResult result, bool correctHeight) {
+            List<Line3D> lines = new List<Line3D>();
+			Dictionary<int, List<Thing>> pathNodes = new Dictionary<int, List<Thing>>();
+			Dictionary<int, List<Thing>> interpolationPoints = new Dictionary<int, List<Thing>>();
+            List<Thing> thingsWithGoal = new List<Thing>();
+            List<Thing> cameras = new List<Thing>();
+			List<Thing> actorMovers = new List<Thing>();
+			Dictionary<int, List<Thing>> actorMoverTargets = new Dictionary<int, List<Thing>>();
+
+            //collect relevant things
+            foreach (Thing t in General.Map.Map.Things) {
+				if(result.ProcessPathNodes && t.Type == 9024) {
+					if(!pathNodes.ContainsKey(t.Tag))
+						pathNodes[t.Tag] = new List<Thing>();
+					pathNodes[t.Tag].Add(t);
+                }
+				if(result.ProcessInterpolationPoints && t.Type == 9070) {
+					if(!interpolationPoints.ContainsKey(t.Tag))
+						interpolationPoints[t.Tag] = new List<Thing>();
+					interpolationPoints[t.Tag].Add(t);
+                }
+                if (result.ProcessThingsWithGoal && t.Action == 229 && t.Args[1] != 0) {
+                    thingsWithGoal.Add(t);
+                }
+                if (result.ProcessCameras && t.Type == 9072 && (t.Args[0] != 0 || t.Args[1] != 0)) {
+                    cameras.Add(t);
+                }
+				if(result.ProcessActorMovers && t.Type == 9074 && (t.Args[0] != 0 || t.Args[1] != 0) && t.Args[3] != 0) {
+					actorMovers.Add(t);
+				}
+            }
+
+			if(actorMovers.Count > 0) {
+				List<int> targetedTags = new List<int>();
+
+				foreach(Thing t in actorMovers) {
+					targetedTags.Add(t.Args[3]);
+				}
+
+				foreach(Thing t in General.Map.Map.Things) {
+					if(targetedTags.Contains(t.Tag)) {
+						if(!actorMoverTargets.ContainsKey(t.Tag))
+							actorMoverTargets[t.Tag] = new List<Thing>();
+						actorMoverTargets[t.Tag].Add(t);
+					}
+				}
+			}
+
+            Vector3D start = new Vector3D();
+            Vector3D end = new Vector3D();
+
+            //process path nodes
+            if (result.ProcessPathNodes) {
+                foreach (KeyValuePair<int, List<Thing>> group in pathNodes) {
+					foreach(Thing t in group.Value) {
+						if(t.Args[0] == 0) continue; //no goal
+						
+						if(pathNodes.ContainsKey(t.Args[0])) {
+							start = t.Position;
+							if(correctHeight) start.z += getCorrectHeight(t);
+
+							foreach(Thing tt in pathNodes[t.Args[0]]) {
+								end = tt.Position;
+								if(correctHeight) end.z += getCorrectHeight(tt);
+								lines.Add(new Line3D(start, end));
+							}
+						}
+					}
+                }
+            }
+
+            //process things with Thing_SetGoal
+            if (result.ProcessThingsWithGoal) {
+                foreach (Thing t in thingsWithGoal) {
+                    if (pathNodes.ContainsKey(t.Args[1])) {
+                        if (t.Args[0] == 0 || t.Args[0] == t.Tag) {
+                            start = t.Position;
+                            if (correctHeight) start.z += getCorrectHeight(t);
+
+							foreach(Thing tt in pathNodes[t.Args[1]]) {
+								end = tt.Position;
+								if(correctHeight) end.z += getCorrectHeight(tt);
+
+								lines.Add(new Line3D(start, end, Line3DType.ACTIVATOR));
+							}
+                        }
+                    }
+                }
+            }
+
+            //process interpolation points
+            if (result.ProcessInterpolationPoints) {
+                foreach (KeyValuePair<int, List<Thing>> group in interpolationPoints) {
+					foreach(Thing t in group.Value) {
+						int targetTag = t.Args[3] + t.Args[4] * 256;
+						if(targetTag == 0) continue; //no goal
+
+						if(interpolationPoints.ContainsKey(targetTag)) {
+							start = t.Position;
+							if(correctHeight) start.z += getCorrectHeight(t);
+
+							foreach(Thing tt in interpolationPoints[targetTag]) {
+								end = tt.Position;
+								if(correctHeight) end.z += getCorrectHeight(tt);
+								lines.Add(new Line3D(start, end));
+							}
+						}
+					}
+                }
+            }
+
+            //process cameras
+            if (result.ProcessCameras) {
+                foreach (Thing t in cameras) {
+                    int targetTag = t.Args[0] + t.Args[1] * 256;
+                    if (targetTag == 0) continue; //no goal
+
+					if(interpolationPoints.ContainsKey(targetTag)) {
+						start = t.Position;
+						if(correctHeight) start.z += getCorrectHeight(t);
+
+						foreach(Thing tt in interpolationPoints[targetTag]) {
+							end = tt.Position;
+							if(correctHeight) end.z += getCorrectHeight(tt);
+							lines.Add(new Line3D(start, end, Line3DType.ACTIVATOR));
+						}
+					}
+                }
+            }
+
+			//process actor movers
+			if(result.ProcessActorMovers) {
+				foreach(Thing t in actorMovers) {
+					int targetTag = t.Args[0] + t.Args[1] * 256;
+					if(targetTag == 0) continue; //no goal
+
+					//add interpolation point target
+					if(interpolationPoints.ContainsKey(targetTag)) {
+						start = t.Position;
+						if(correctHeight) start.z += getCorrectHeight(t);
+
+						foreach(Thing tt in interpolationPoints[targetTag]) {
+							end = tt.Position;
+							if(correctHeight) end.z += getCorrectHeight(tt);
+							lines.Add(new Line3D(start, end, Line3DType.ACTIVATOR));
+						}
+					}
+
+					//add thing-to-move target
+					if(actorMoverTargets.ContainsKey(t.Args[3])) {
+						start = t.Position;
+						if(correctHeight) start.z += getCorrectHeight(t);
+
+						foreach(Thing tt in actorMoverTargets[t.Args[3]]) {
+							end = tt.Position;
+							if(correctHeight) end.z += getCorrectHeight(tt);
+							lines.Add(new Line3D(start, end, Line3DType.ACTIVATOR));
+						}
+					}
+				}
+			}
+
+            return lines;
+        }
+
+        private static float getCorrectHeight(Thing thing) {
+            ThingTypeInfo tti = General.Map.Data.GetThingInfo(thing.Type);
+            float height = tti.Height / 2f;
+            if (thing.Sector != null) height += thing.Sector.FloorHeight;
+            return height;
+        }
+    }
+}
diff --git a/Source/Core/GZBuilder/Data/ThingCopyData.cs b/Source/Core/GZBuilder/Data/ThingCopyData.cs
index 58e49e3e31f6010e52b675baffbd3f63bd84583f..f84b7d2237af8f8761b10406afd77847f822ac85 100644
--- a/Source/Core/GZBuilder/Data/ThingCopyData.cs
+++ b/Source/Core/GZBuilder/Data/ThingCopyData.cs
@@ -41,7 +41,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data {
             t.Tag = tag;
             t.Action = action;
 
-            foreach(int i in args) 
+            for(int i = 0; i < args.Length; i++) 
                 t.Args[i] = args[i];
 
             foreach (KeyValuePair<string, UniValue> group in fields) {
diff --git a/Source/Core/GZBuilder/Geometry/Line3D.cs b/Source/Core/GZBuilder/Geometry/Line3D.cs
index b7f595b61b07bdf2829d2a5f85e6b7adb0e45d3e..a6e2cb7e46e2e6e2fa2f096b5c5b2deafd905520 100644
--- a/Source/Core/GZBuilder/Geometry/Line3D.cs
+++ b/Source/Core/GZBuilder/Geometry/Line3D.cs
@@ -4,16 +4,30 @@ using System.Text;
 using CodeImp.DoomBuilder.Geometry;
 
 namespace CodeImp.DoomBuilder.GZBuilder.Geometry {
-    public class Line3D {
-        
+	public enum Line3DType
+	{
+		DEFAULT,
+		ACTIVATOR,
+	}
+	
+	public class Line3D {
         // Coordinates
         public Vector3D v1;
         public Vector3D v2;
+		public Line3DType LineType { get { return lineType; } }
+		private Line3DType lineType;
 
-        // Constructor
-		public Line3D(Vector3D v1, Vector3D v2)	{
+        // Constructors
+		public Line3D(Vector3D v1, Vector3D v2) {
 			this.v1 = v1;
 			this.v2 = v2;
+			this.lineType = Line3DType.DEFAULT;
+		}
+
+		public Line3D(Vector3D v1, Vector3D v2, Line3DType lineType) {
+			this.v1 = v1;
+			this.v2 = v2;
+			this.lineType = lineType;
 		}
 
         public Vector3D GetDelta() { return v2 - v1; }
diff --git a/Source/Core/IO/Configuration.cs b/Source/Core/IO/Configuration.cs
index 41a2a7fa4ed574956602580465b01950a94c185d..3d032aa15f38643bf4387cc04e80814ae8468fd2 100644
--- a/Source/Core/IO/Configuration.cs
+++ b/Source/Core/IO/Configuration.cs
@@ -801,7 +801,7 @@ namespace CodeImp.DoomBuilder.IO
 							case "true": return (bool)true;
 							case "false": return (bool)false;
 							case "null": return null;
-							default: RaiseError(file, line, ERROR_KEYWORDUNKNOWN); return null;
+							default: RaiseError(file, line, ERROR_KEYWORDUNKNOWN + "\nUnrecognized token: '" + val.Trim().ToLowerInvariant() + "'"); return null;
 						}
 					}
 				}
diff --git a/Source/Core/IO/UniversalParser.cs b/Source/Core/IO/UniversalParser.cs
index 4980ac3226a082fd870801b68788caffeaf56de6..feaa205b7748785796af70ad03e8695273e9f1a9 100644
--- a/Source/Core/IO/UniversalParser.cs
+++ b/Source/Core/IO/UniversalParser.cs
@@ -609,7 +609,7 @@ namespace CodeImp.DoomBuilder.IO
 							default:
 								
 								// Unknown keyword
-								RaiseError(line, ERROR_KEYWORDUNKNOWN);
+								RaiseError(line, ERROR_KEYWORDUNKNOWN + "\nUnrecognized token: '" + val.Trim().ToLowerInvariant() + "'");
 								break;
 						}
 						
diff --git a/Source/Core/Rendering/IRenderer2D.cs b/Source/Core/Rendering/IRenderer2D.cs
index 1881d5c0dd5645ca37ccaa4407aaddc46c26f8e5..5772cc78b892ea3b3d39dd4a88d6bf57c0ddf50d 100644
--- a/Source/Core/Rendering/IRenderer2D.cs
+++ b/Source/Core/Rendering/IRenderer2D.cs
@@ -69,8 +69,8 @@ namespace CodeImp.DoomBuilder.Rendering
 		void Present();
 
 		// Drawing methods
-		void RenderArrows(List<Line3D> lines, PixelColor c); //mxd
-		void PlotArrows(List<Line3D> lines, PixelColor c); //mxd
+		void RenderArrow(Line3D line, PixelColor c); //mxd
+		void PlotArrow(Line3D line, PixelColor c); //mxd
 		void PlotLine(Vector2D start, Vector2D end, PixelColor c);
 		void PlotLinedef(Linedef l, PixelColor c);
 		void PlotLinedefSet(ICollection<Linedef> linedefs);
diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs
index d8b5a169a7ac5b451acc5ac6974fd82baff43e7b..d533604c2f695c6afaac12bf9abc7b4843a11392 100644
--- a/Source/Core/Rendering/Renderer2D.cs
+++ b/Source/Core/Rendering/Renderer2D.cs
@@ -1446,27 +1446,27 @@ namespace CodeImp.DoomBuilder.Rendering
 		}
 
 		//mxd
-		public void RenderArrows(List<Line3D> lines, PixelColor c) {
+		public void RenderArrow(Line3D line, PixelColor c) {
 			float scaler = 20f / scale;
-			foreach(Line3D l in lines) {
-				RenderLine(l.v1, l.v2, 0.8f, c, true);
-				float angle = l.GetAngle();
-				//arrowhead
-				RenderLine(l.v2, new Vector2D(l.v2.x - scaler * (float)Math.Sin(angle - 0.46f), l.v2.y + scaler * (float)Math.Cos(angle - 0.46f)), 0.8f, c, true);
-				RenderLine(l.v2, new Vector2D(l.v2.x - scaler * (float)Math.Sin(angle + 0.46f), l.v2.y + scaler * (float)Math.Cos(angle + 0.46f)), 0.8f, c, true);
-			}
+			//foreach(Line3D l in lines) {
+			RenderLine(line.v1, line.v2, 0.8f, c, true);
+			float angle = line.GetAngle();
+			//arrowhead
+			RenderLine(line.v2, new Vector2D(line.v2.x - scaler * (float)Math.Sin(angle - 0.46f), line.v2.y + scaler * (float)Math.Cos(angle - 0.46f)), 0.8f, c, true);
+			RenderLine(line.v2, new Vector2D(line.v2.x - scaler * (float)Math.Sin(angle + 0.46f), line.v2.y + scaler * (float)Math.Cos(angle + 0.46f)), 0.8f, c, true);
+			//}
 		}
 
 		//mxd
-		public void PlotArrows(List<Line3D> lines, PixelColor c) {
+		public void PlotArrow(Line3D line, PixelColor c) {
 			float scaler = 16f / scale;
-			foreach(Line3D l in lines) {
-				PlotLine(l.v1, l.v2, c);
-				float angle = l.GetAngle();
-				//arrowhead
-				PlotLine(l.v2, new Vector2D(l.v2.x - scaler * (float)Math.Sin(angle - 0.46f), l.v2.y + scaler * (float)Math.Cos(angle - 0.46f)), c);
-				PlotLine(l.v2, new Vector2D(l.v2.x - scaler * (float)Math.Sin(angle + 0.46f), l.v2.y + scaler * (float)Math.Cos(angle + 0.46f)), c);
-			}
+			//foreach(Line3D l in lines) {
+			PlotLine(line.v1, line.v2, c);
+			float angle = line.GetAngle();
+			//arrowhead
+			PlotLine(line.v2, new Vector2D(line.v2.x - scaler * (float)Math.Sin(angle - 0.46f), line.v2.y + scaler * (float)Math.Cos(angle - 0.46f)), c);
+			PlotLine(line.v2, new Vector2D(line.v2.x - scaler * (float)Math.Sin(angle + 0.46f), line.v2.y + scaler * (float)Math.Cos(angle + 0.46f)), c);
+			//}
 		}
 
 		// This renders a line with given color
diff --git a/Source/Core/Rendering/Renderer3D.cs b/Source/Core/Rendering/Renderer3D.cs
index 3e641cf144e7a4bfe9f2d454a957d8f90c458e3d..219b9c50cc25ce31fb4c738b952f5db8919bafe7 100644
--- a/Source/Core/Rendering/Renderer3D.cs
+++ b/Source/Core/Rendering/Renderer3D.cs
@@ -560,8 +560,22 @@ namespace CodeImp.DoomBuilder.Rendering
             if (General.Settings.GZShowEventLines) {
                 //mxd. gather links
                 List<Line3D> lines = GZBuilder.Data.LinksCollector.GetThingLinks(thingsbydistance);
-                if (lines.Count > 0)
-                    renderLinks(lines);
+				if(lines.Count > 0) {
+					List<Line3D> normalLines = new List<Line3D>();
+					List<Line3D> activatorLines = new List<Line3D>();
+					
+					foreach(Line3D l in lines){
+						if(l.LineType == Line3DType.DEFAULT)
+							normalLines.Add(l);
+						else
+							activatorLines.Add(l);
+					}
+
+					if(normalLines.Count > 0)
+						renderArrows(normalLines, General.Colors.InfoLine.ToColorValue());
+					if(activatorLines.Count > 0)
+						renderArrows(activatorLines, General.Colors.Selection3D.ToColorValue());
+				}
             }
 
 			// ADDITIVE PASS
@@ -671,7 +685,7 @@ namespace CodeImp.DoomBuilder.Rendering
         }
 
         //mxd
-        private void renderLinks(List<Line3D> lines) {
+        private void renderArrows(List<Line3D> lines, Color4 color) {
             //create vertices
             WorldVertex[] verts = new WorldVertex[lines.Count * 6];
 			float scaler = 20f;
@@ -707,7 +721,7 @@ namespace CodeImp.DoomBuilder.Rendering
             ApplyMatrices3D();
 
             // Setup color
-            graphics.Shaders.World3D.VertexColor = General.Colors.InfoLine.ToColorValue();
+			graphics.Shaders.World3D.VertexColor = color;
 
             //render
             graphics.Shaders.World3D.ApplySettings();
diff --git a/Source/Core/Windows/ResourceOptionsForm.cs b/Source/Core/Windows/ResourceOptionsForm.cs
index b0cafac568e8387d2296bddbb023ea3766c2d83d..e3e6b11650d74d2cb2a844ee7228ed4a2c8912ea 100644
--- a/Source/Core/Windows/ResourceOptionsForm.cs
+++ b/Source/Core/Windows/ResourceOptionsForm.cs
@@ -77,6 +77,10 @@ namespace CodeImp.DoomBuilder.Windows
 			
 			// Checkbox
 			notfortesting.Checked = res.notfortesting;
+
+			//mxd
+			if(General.Map != null && General.Map.FilePathName != "")
+				dirdialog.SelectedPath = Path.GetDirectoryName(General.Map.FilePathName);
 		}
 		
 		// OK clicked
diff --git a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs
index b1c1e571dd8b1bf9578afd0248ca96608c56ce11..305ab979995b2432ffbe15c52637f002b006eab4 100644
--- a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs
@@ -164,8 +164,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				}
 
                 //mxd
-                if(General.Settings.GZShowEventLines)
-                    renderer.RenderArrows(GZBuilder.Data.LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings), General.Colors.InfoLine);
+				if(General.Settings.GZShowEventLines) {
+					List<Line3D> lines = GZBuilder.Data.LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings);
+
+					foreach(Line3D l in lines) {
+						renderer.RenderArrow(l, l.LineType == Line3DType.ACTIVATOR ? General.Colors.Selection : General.Colors.InfoLine);
+					}
+				}
  
 				renderer.Finish();
 			}
diff --git a/Source/Plugins/BuilderModes/General/BuilderPlug.cs b/Source/Plugins/BuilderModes/General/BuilderPlug.cs
index 6d849a215d7ef24049f823b35433dace7d9befc5..c21c68b63d8525297a457423d9c9faf03d1e2f14 100644
--- a/Source/Plugins/BuilderModes/General/BuilderPlug.cs
+++ b/Source/Plugins/BuilderModes/General/BuilderPlug.cs
@@ -497,8 +497,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
 					}
 				}
 
-				if(General.Settings.GZShowEventLines)
-					renderer.PlotArrows(lines, General.Colors.InfoLine);//mxd
+				if(General.Settings.GZShowEventLines) { //mxd
+					//renderer.PlotArrows(lines, General.Colors.InfoLine);//mxd
+					foreach(Line3D l in lines){
+						renderer.PlotArrow(l, l.LineType == Line3DType.ACTIVATOR ? General.Colors.Selection : General.Colors.InfoLine);
+					}
+				}
 			}
 			// Linedefs?
 			else if(asso.type == UniversalType.LinedefTag)
@@ -512,8 +516,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
 					}
 				}
 
-				if(General.Settings.GZShowEventLines)
-					renderer.PlotArrows(lines, General.Colors.InfoLine);//mxd
+				if(General.Settings.GZShowEventLines) { //mxd
+					//renderer.PlotArrows(lines, General.Colors.InfoLine);//mxd
+					foreach(Line3D l in lines) {
+						renderer.PlotArrow(l, l.LineType == Line3DType.ACTIVATOR ? General.Colors.Selection : General.Colors.InfoLine);
+					}
+				}
 			}
 		}
 		
@@ -535,8 +543,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
 							lines.Add(new Line3D(asso.Center, t.Position));//mxd
 					}
 				}
-				if(General.Settings.GZShowEventLines)
-					renderer.RenderArrows(lines, General.Colors.InfoLine);//mxd
+				if(General.Settings.GZShowEventLines) { //mxd
+					//renderer.RenderArrows(lines, General.Colors.InfoLine);//mxd
+					foreach(Line3D l in lines) {
+						renderer.RenderArrow(l, l.LineType == Line3DType.ACTIVATOR ? General.Colors.Selection : General.Colors.InfoLine);
+					}
+				}
 			}
 		}
 		
@@ -566,8 +578,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
 						}
 					}
 				}
-				if(General.Settings.GZShowEventLines)
-					renderer.PlotArrows(lines, General.Colors.InfoLine); //mxd
+				if(General.Settings.GZShowEventLines) { //mxd
+					//renderer.PlotArrows(lines, General.Colors.InfoLine); //mxd
+					foreach(Line3D l in lines) {
+						renderer.PlotArrow(l, l.LineType == Line3DType.ACTIVATOR ? General.Colors.Selection : General.Colors.InfoLine);
+					}
+				}
 			}
 			else
 			{
@@ -592,8 +608,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
 					}
 				}
 
-				if(General.Settings.GZShowEventLines) //mxd
-					renderer.PlotArrows(lines, General.Colors.InfoLine);
+				if(General.Settings.GZShowEventLines) { //mxd
+					//renderer.PlotArrows(lines, General.Colors.InfoLine);
+					foreach(Line3D l in lines) {
+						renderer.PlotArrow(l, l.LineType == Line3DType.ACTIVATOR ? General.Colors.Selection : General.Colors.InfoLine);
+					}
+				}
 			}
 		}
 		
@@ -625,8 +645,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				}
 			}
 
-			if(General.Settings.GZShowEventLines)//mxd
-				renderer.RenderArrows(lines, General.Colors.InfoLine); 
+			if(General.Settings.GZShowEventLines) {//mxd
+				//renderer.RenderArrows(lines, General.Colors.InfoLine);
+				foreach(Line3D l in lines) {
+					renderer.RenderArrow(l, l.LineType == Line3DType.ACTIVATOR ? General.Colors.Selection : General.Colors.InfoLine);
+				}
+			}
 		}
 
 		#endregion