diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
index e8f0e94fed5d383ed682e4ea5690dcd4c0309fd6..d22c796ece0bb5d00a6cf72ee4c3970a427c4c8d 100644
--- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
@@ -28,6 +28,8 @@ using CodeImp.DoomBuilder.Editing;
 using CodeImp.DoomBuilder.Actions;
 using CodeImp.DoomBuilder.Types;
 using CodeImp.DoomBuilder.Config;
+using CodeImp.DoomBuilder.GZBuilder.Tools;
+using CodeImp.DoomBuilder.Data;
 
 #endregion
 
@@ -175,6 +177,68 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			else
 				General.Interface.HideInfo();
 		}
+
+		//mxd
+		private void alignTextureToLine(bool alignFloors, bool alignToFrontSide) {
+			ICollection<Linedef> lines = General.Map.Map.GetSelectedLinedefs(true);
+
+			if(lines.Count == 0) {
+				General.Interface.DisplayStatus(StatusType.Warning, "This action requires a selection");
+				return;
+			}
+
+			//Create Undo
+			string rest = (alignFloors ? "Floors" : "Ceilings") + " to " + (alignToFrontSide ? "Front" : "Back")+ " Side";
+			General.Map.UndoRedo.CreateUndo("Align " + rest);
+			int counter = 0;
+
+			foreach(Linedef l in lines){
+				Sector s = null;
+
+				if(alignToFrontSide) {
+					if(l.Front != null && l.Front.Sector != null) s = l.Front.Sector;
+				} else {
+					if(l.Back != null && l.Back.Sector != null)	s = l.Back.Sector;
+				}
+
+				if(s == null) continue;
+				counter++;
+
+				s.Fields.BeforeFieldsChange();
+
+				float sourceAngle = (float)Math.Round(General.ClampAngle(alignToFrontSide ? -Angle2D.RadToDeg(l.Angle) + 90 : -Angle2D.RadToDeg(l.Angle) - 90), 1);
+				if(!alignToFrontSide) sourceAngle = General.ClampAngle(sourceAngle + 180);
+
+				//update angle
+				UDMFTools.SetFloat(s.Fields, (alignFloors ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f, false);
+
+				//update offset
+				Vector2D offset = (alignToFrontSide ? l.Start.Position : l.End.Position).GetRotated(Angle2D.DegToRad(sourceAngle));
+				ImageData texture = General.Map.Data.GetFlatImage(s.LongFloorTexture);
+
+				if((texture == null) || (texture == General.Map.Data.WhiteTexture) ||
+				   (texture.Width <= 0) || (texture.Height <= 0) || !texture.IsImageLoaded) {
+				}else{
+					offset.x %= texture.Width / s.Fields.GetValue((alignFloors ? "xscalefloor" : "xscaleceiling"), 1.0f);
+					offset.y %= texture.Height / s.Fields.GetValue((alignFloors ? "yscalefloor" : "yscaleceiling"), 1.0f);
+				}
+
+				UDMFTools.SetFloat(s.Fields, (alignFloors ? "xpanningfloor" : "xpanningceiling"), (float)Math.Round(-offset.x), 0f, false);
+				UDMFTools.SetFloat(s.Fields, (alignFloors ? "ypanningfloor" : "ypanningceiling"), (float)Math.Round(offset.y), 0f, false);
+
+				//update
+				s.UpdateNeeded = true;
+				s.UpdateCache();
+			}
+
+			General.Interface.DisplayStatus(StatusType.Info, "Aligned " +counter + " " + rest);
+
+			//update
+			General.Map.Map.Update();
+			General.Interface.RedrawDisplay();
+			General.Interface.RefreshInfo();
+			General.Map.IsChanged = true;
+		}
 		
 		#endregion
 		
@@ -1131,6 +1195,34 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			General.Map.IsChanged = true;
 		}
 
+		//mxd
+		[BeginAction("alignfloortofront")]
+		public void AlignFloorToFront() {
+			if(!General.Map.UDMF) return;
+			alignTextureToLine(true, true);
+		}
+
+		//mxd
+		[BeginAction("alignfloortoback")]
+		public void AlignFloorToBack() {
+			if(!General.Map.UDMF) return;
+			alignTextureToLine(true, false);
+		}
+
+		//mxd
+		[BeginAction("alignceilingtofront")]
+		public void AlignCeilingToFront() {
+			if(!General.Map.UDMF) return;
+			alignTextureToLine(false, true);
+		}
+
+		//mxd
+		[BeginAction("alignceilingtoback")]
+		public void AlignCeilingToBack() {
+			if(!General.Map.UDMF) return;
+			alignTextureToLine(false, false);
+		}
+
 		#endregion
 	}
 }
diff --git a/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs b/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs
index ce20fce4b7f788007fdac8515f2bdd1d2961d7d7..46b82effddcf8d5dc6ae4a01efe261562272057e 100644
--- a/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs
+++ b/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs
@@ -46,6 +46,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.thingsmenu = new System.Windows.Forms.ToolStripMenuItem();
 			this.alignToWallItem = new System.Windows.Forms.ToolStripMenuItem();
 			this.pointAtCursorItem = new System.Windows.Forms.ToolStripMenuItem();
+			this.selectInSectorsItem = new System.Windows.Forms.ToolStripMenuItem();
 			this.globalstrip = new System.Windows.Forms.ToolStrip();
 			this.manualstrip = new System.Windows.Forms.ToolStrip();
 			this.buttoncopyproperties = new System.Windows.Forms.ToolStripButton();
@@ -63,7 +64,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.buttonMarqueSelectTouching = new System.Windows.Forms.ToolStripButton();
 			this.buttonAlignThingsToWall = new System.Windows.Forms.ToolStripButton();
 			this.buttonTextureOffsetLock = new System.Windows.Forms.ToolStripButton();
-			this.selectInSectorsItem = new System.Windows.Forms.ToolStripMenuItem();
+			this.alignLinedefsItem = new System.Windows.Forms.ToolStripMenuItem();
+			this.alignFloorToFrontItem = new System.Windows.Forms.ToolStripMenuItem();
+			this.alignFloorToBackItem = new System.Windows.Forms.ToolStripMenuItem();
+			this.alignCeilingToFrontItem = new System.Windows.Forms.ToolStripMenuItem();
+			this.alignCeilingToBackItem = new System.Windows.Forms.ToolStripMenuItem();
 			this.menustrip.SuspendLayout();
 			this.manualstrip.SuspendLayout();
 			this.SuspendLayout();
@@ -91,11 +96,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
             this.toolStripMenuItem1,
             this.curvelinedefsitem,
             this.toolStripMenuItem3,
-            this.splitlinedefsitem});
+            this.splitlinedefsitem,
+            this.alignLinedefsItem});
 			this.linedefsmenu.Name = "linedefsmenu";
 			this.linedefsmenu.Size = new System.Drawing.Size(63, 20);
 			this.linedefsmenu.Text = "&Linedefs";
 			this.linedefsmenu.Visible = false;
+			this.linedefsmenu.DropDownOpening += new System.EventHandler(this.linedefsmenu_DropDownOpening);
 			// 
 			// selectsinglesideditem
 			// 
@@ -190,7 +197,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			// toolStripMenuItem2
 			// 
 			this.toolStripMenuItem2.Name = "toolStripMenuItem2";
-			this.toolStripMenuItem2.Size = new System.Drawing.Size(149, 6);
+			this.toolStripMenuItem2.Size = new System.Drawing.Size(146, 6);
 			this.toolStripMenuItem2.Visible = false;
 			// 
 			// thingsmenu
@@ -222,6 +229,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			this.pointAtCursorItem.Text = "&Point at Cursor";
 			this.pointAtCursorItem.Click += new System.EventHandler(this.InvokeTaggedAction);
 			// 
+			// selectInSectorsItem
+			// 
+			this.selectInSectorsItem.Name = "selectInSectorsItem";
+			this.selectInSectorsItem.Size = new System.Drawing.Size(245, 22);
+			this.selectInSectorsItem.Tag = "thingsselectinsectors";
+			this.selectInSectorsItem.Text = "&Select Things in Selected Sectors";
+			this.selectInSectorsItem.Click += new System.EventHandler(this.InvokeTaggedAction);
+			// 
 			// globalstrip
 			// 
 			this.globalstrip.Location = new System.Drawing.Point(0, 24);
@@ -409,13 +424,48 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				"tant while sector is dragged\r\n";
 			this.buttonTextureOffsetLock.Click += new System.EventHandler(this.buttonTextureOffsetLock_Click);
 			// 
-			// selectInSectorsItem
+			// alignLinedefsItem
 			// 
-			this.selectInSectorsItem.Name = "selectInSectorsItem";
-			this.selectInSectorsItem.Size = new System.Drawing.Size(245, 22);
-			this.selectInSectorsItem.Tag = "thingsselectinsectors";
-			this.selectInSectorsItem.Text = "&Select Things in Selected Sectors";
-			this.selectInSectorsItem.Click += new System.EventHandler(this.InvokeTaggedAction);
+			this.alignLinedefsItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.alignFloorToFrontItem,
+            this.alignFloorToBackItem,
+            this.alignCeilingToFrontItem,
+            this.alignCeilingToBackItem});
+			this.alignLinedefsItem.Name = "alignLinedefsItem";
+			this.alignLinedefsItem.Size = new System.Drawing.Size(205, 22);
+			this.alignLinedefsItem.Text = "&Align Textures";
+			// 
+			// alignFloorToFrontItem
+			// 
+			this.alignFloorToFrontItem.Name = "alignFloorToFrontItem";
+			this.alignFloorToFrontItem.Size = new System.Drawing.Size(181, 22);
+			this.alignFloorToFrontItem.Tag = "alignfloortofront";
+			this.alignFloorToFrontItem.Text = "Floor to Front Side";
+			this.alignFloorToFrontItem.Click += new System.EventHandler(this.InvokeTaggedAction);
+			// 
+			// alignFloorToBackItem
+			// 
+			this.alignFloorToBackItem.Name = "alignFloorToBackItem";
+			this.alignFloorToBackItem.Size = new System.Drawing.Size(181, 22);
+			this.alignFloorToBackItem.Tag = "alignfloortoback";
+			this.alignFloorToBackItem.Text = "Floor to Back Side";
+			this.alignFloorToBackItem.Click += new System.EventHandler(this.InvokeTaggedAction);
+			// 
+			// alignCeilingToFrontItem
+			// 
+			this.alignCeilingToFrontItem.Name = "alignCeilingToFrontItem";
+			this.alignCeilingToFrontItem.Size = new System.Drawing.Size(181, 22);
+			this.alignCeilingToFrontItem.Tag = "alignceilingtofront";
+			this.alignCeilingToFrontItem.Text = "Ceiling to Front Side";
+			this.alignCeilingToFrontItem.Click += new System.EventHandler(this.InvokeTaggedAction);
+			// 
+			// alignCeilingToBackItem
+			// 
+			this.alignCeilingToBackItem.Name = "alignCeilingToBackItem";
+			this.alignCeilingToBackItem.Size = new System.Drawing.Size(181, 22);
+			this.alignCeilingToBackItem.Tag = "alignceilingtoback";
+			this.alignCeilingToBackItem.Text = "Ceiling to Back Side";
+			this.alignCeilingToBackItem.Click += new System.EventHandler(this.InvokeTaggedAction);
 			// 
 			// MenusForm
 			// 
@@ -481,5 +531,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		private System.Windows.Forms.ToolStripMenuItem pointAtCursorItem;
 		private System.Windows.Forms.ToolStripButton buttonTextureOffsetLock;
 		private System.Windows.Forms.ToolStripMenuItem selectInSectorsItem;
+		private System.Windows.Forms.ToolStripMenuItem alignLinedefsItem;
+		private System.Windows.Forms.ToolStripMenuItem alignFloorToFrontItem;
+		private System.Windows.Forms.ToolStripMenuItem alignFloorToBackItem;
+		private System.Windows.Forms.ToolStripMenuItem alignCeilingToFrontItem;
+		private System.Windows.Forms.ToolStripMenuItem alignCeilingToBackItem;
 	}
 }
\ No newline at end of file
diff --git a/Source/Plugins/BuilderModes/Interface/MenusForm.cs b/Source/Plugins/BuilderModes/Interface/MenusForm.cs
index cd09f153529ff1efda5cd022544683967f34fd08..e6ebd1af2aba9460710862200acfa98456aa6578 100644
--- a/Source/Plugins/BuilderModes/Interface/MenusForm.cs
+++ b/Source/Plugins/BuilderModes/Interface/MenusForm.cs
@@ -174,5 +174,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		}
 		
 		#endregion
+
+		#region Events
+
+		//mxd
+		private void linedefsmenu_DropDownOpening(object sender, EventArgs e) {
+			alignLinedefsItem.Enabled = General.Map.UDMF;
+		}
+
+		#endregion
 	}
 }
\ No newline at end of file
diff --git a/Source/Plugins/BuilderModes/Resources/Actions.cfg b/Source/Plugins/BuilderModes/Resources/Actions.cfg
index 10e6b0ed5307dcff2ac4e5bcf0e204a25cc6e200..b720e32b35356aa269dd33f3f9ab24f9742d5763 100644
--- a/Source/Plugins/BuilderModes/Resources/Actions.cfg
+++ b/Source/Plugins/BuilderModes/Resources/Actions.cfg
@@ -302,6 +302,50 @@ splitlinedefs
 	allowscroll = true;
 }
 
+//mxd
+alignfloortofront
+{
+	title = "Align Floor Texture to Front Side";
+	category = "linedefs";
+	description = "Aligns floor textures to front sides of selected linedefs.";
+	allowkeys = true;
+	allowmouse = false;
+	allowscroll = false;
+}
+
+//mxd
+alignfloortoback
+{
+	title = "Align Floor Texture to Back Side";
+	category = "linedefs";
+	description = "Aligns floor textures to back sides of selected linedefs.";
+	allowkeys = true;
+	allowmouse = false;
+	allowscroll = false;
+}
+
+//mxd
+alignceilingtofront
+{
+	title = "Align Ceiling Texture to Front Side";
+	category = "linedefs";
+	description = "Aligns ceiling textures to front sides of selected linedefs.";
+	allowkeys = true;
+	allowmouse = false;
+	allowscroll = false;
+}
+
+//mxd
+alignceilingtoback
+{
+	title = "Align Ceiling Texture to Back Side";
+	category = "linedefs";
+	description = "Aligns ceiling textures to back sides of selected linedefs.";
+	allowkeys = true;
+	allowmouse = false;
+	allowscroll = false;
+}
+
 joinsectors
 {
 	title = "Join Sectors";
diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs
index c1d4446e6640f9c6c8b7918240f1002716110f80..7740aeab9003d7e77402400ec777499b540764cb 100644
--- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs
@@ -234,18 +234,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			//find an angle to rotate texture
 			float sourceAngle = (float)Math.Round(General.ClampAngle(isFront ? -Angle2D.RadToDeg(targetLine.Angle) + 90 : -Angle2D.RadToDeg(targetLine.Angle) - 90), 1);
 			if(!isFront) sourceAngle = General.ClampAngle(sourceAngle + 180);
-			string rotationKey = (isFloor ? "rotationfloor" : "rotationceiling");
 
 			//update angle
-			UDMFTools.SetFloat(Sector.Sector.Fields, rotationKey, sourceAngle, 0f, false);
-
-			//update scale. Target should be either floor or ceiling at this point
-			string xScaleKey = (isFloor ? "xscalefloor" : "xscaleceiling");
-			string yScaleKey = (isFloor ? "yscalefloor" : "yscaleceiling");
+			UDMFTools.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f, false);
 
 			//set scale
-			UDMFTools.SetFloat(Sector.Sector.Fields, xScaleKey, scaleX, 1.0f, false);
-			UDMFTools.SetFloat(Sector.Sector.Fields, yScaleKey, scaleY, 1.0f, false);
+			UDMFTools.SetFloat(Sector.Sector.Fields, (isFloor ? "xscalefloor" : "xscaleceiling"), scaleX, 1.0f, false);
+			UDMFTools.SetFloat(Sector.Sector.Fields, (isFloor ? "yscalefloor" : "yscaleceiling"), scaleY, 1.0f, false);
 
 			//update offset
 			float distToStart = Vector2D.Distance(hitpos, targetLine.Start.Position);
@@ -288,15 +283,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			}
 
 			//update angle
-			string rotationKey = (isFloor ? "rotationfloor" : "rotationceiling");
-			UDMFTools.SetFloat(Sector.Sector.Fields, rotationKey, sourceAngle, 0f, false);
+			UDMFTools.SetFloat(Sector.Sector.Fields, (isFloor ? "rotationfloor" : "rotationceiling"), sourceAngle, 0f, false);
 
 			//update scaleY
 			string xScaleKey = (isFloor ? "xscalefloor" : "xscaleceiling");
 			string yScaleKey = (isFloor ? "yscalefloor" : "yscaleceiling");
 
 			float scaleX = Sector.Sector.Fields.GetValue(xScaleKey, 1.0f);
-			float scaleY;// = (float)Math.Round(scaleX * (1 / (float)Math.Cos(slopeAngle)), 2);
+			float scaleY;
 
 			//set scale
 			if(aligny) {