diff --git a/Build/Compilers/ZDoom/zspecial.acs b/Build/Compilers/ZDoom/zspecial.acs
index 2e0f1fad06cd9a56b902728384938622327968a2..8f2fe1af5541e8c6ab359ce1496bf90c675c78f3 100644
--- a/Build/Compilers/ZDoom/zspecial.acs
+++ b/Build/Compilers/ZDoom/zspecial.acs
@@ -364,6 +364,7 @@ special
 	-94:SetSectorDamage(2,5),
 	-95:SetSectorTerrain(3),
 	-96:SpawnParticle(1,15),
+	-97:SetMusicVolume(1),
 	
 	// Zandronum's
 	-100:ResetMap(0),
diff --git a/Build/Scripting/ZDoom_ACS.cfg b/Build/Scripting/ZDoom_ACS.cfg
index 92b35aa0426e456c3c0eb0db47cf816b34dbf959..7d56990267f2db396e34d8882d3b69556604bfa4 100644
--- a/Build/Scripting/ZDoom_ACS.cfg
+++ b/Build/Scripting/ZDoom_ACS.cfg
@@ -373,6 +373,7 @@ keywords
 	SetMarineWeapon = "void SetMarineWeapon(int tid, int weapon)\nSets a Scripted Marine's weapon on the fly.\nweapon: one of MARINEWEAPON_ flags";
 	SetMugShotState = "void SetMugShotState(str state)\nSets the state of the mug shot in SBARINFO status bars.\nThe state you set will only be interrupted by damage or if the player\npicks up a weapon, provided the mugshot supports it.";
 	SetMusic = "void SetMusic(str song[, int order[, int unused]])";
+	SetMusicVolume = "void SetMusicVolume(float volume)";
 	SetPlayerProperty = "SetPlayerProperty(who, set, which)";
 	SetPointer = "bool SetPointer(int assign_slot, int tid[, int pointer_selector[, int flags]])\nSet the value of one of the caller's stored pointers.";
 	SetResultValue = "void SetResultValue(int value)";
diff --git a/Source/Core/Controls/ScriptEditorControl.cs b/Source/Core/Controls/ScriptEditorControl.cs
index c6c26e1611cf98178a8a0feb8ac50676893eeefc..8dbf2f0ad521fd189b904abb67fa4d9a113765f5 100644
--- a/Source/Core/Controls/ScriptEditorControl.cs
+++ b/Source/Core/Controls/ScriptEditorControl.cs
@@ -754,6 +754,7 @@ namespace CodeImp.DoomBuilder.Controls
 		//mxd. Find next result
 		public bool FindNext(FindReplaceOptions options, bool useselectionstart)
 		{
+			if(string.IsNullOrEmpty(options.FindText)) return false;
 			int startpos = (useselectionstart ? Math.Min(scriptedit.SelectionStart, scriptedit.SelectionEnd) : Math.Max(scriptedit.SelectionStart, scriptedit.SelectionEnd));
 
 			// Search the document
@@ -792,6 +793,7 @@ namespace CodeImp.DoomBuilder.Controls
 		//mxd. Find previous result
 		public bool FindPrevious(FindReplaceOptions options)
 		{
+			if(string.IsNullOrEmpty(options.FindText)) return false;
 			int endpos = Math.Max(0, Math.Min(scriptedit.SelectionStart, scriptedit.SelectionEnd) - 1);
 
 			// Search the document
diff --git a/Source/Core/Controls/ScriptEditorPanel.Designer.cs b/Source/Core/Controls/ScriptEditorPanel.Designer.cs
index d53cdc8aab90fe3233bb4cd70743f2e98da40e5d..7a5c69829540c9addd0dba0597edcf398577f858 100644
--- a/Source/Core/Controls/ScriptEditorPanel.Designer.cs
+++ b/Source/Core/Controls/ScriptEditorPanel.Designer.cs
@@ -385,6 +385,7 @@ namespace CodeImp.DoomBuilder.Controls
 			// searchprev
 			// 
 			this.searchprev.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+			this.searchprev.Enabled = false;
 			this.searchprev.Image = global::CodeImp.DoomBuilder.Properties.Resources.SearchPrev;
 			this.searchprev.ImageTransparentColor = System.Drawing.Color.Magenta;
 			this.searchprev.Name = "searchprev";
@@ -395,6 +396,7 @@ namespace CodeImp.DoomBuilder.Controls
 			// searchnext
 			// 
 			this.searchnext.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+			this.searchnext.Enabled = false;
 			this.searchnext.Image = global::CodeImp.DoomBuilder.Properties.Resources.SearchNext;
 			this.searchnext.ImageTransparentColor = System.Drawing.Color.Magenta;
 			this.searchnext.Name = "searchnext";
diff --git a/Source/Core/Controls/ScriptEditorPanel.cs b/Source/Core/Controls/ScriptEditorPanel.cs
index 6723a8df92533bcffeffcce7b109ee9505c8c272..23f13acc70caf5cb3e25b82bfc96819b304c69f8 100644
--- a/Source/Core/Controls/ScriptEditorPanel.cs
+++ b/Source/Core/Controls/ScriptEditorPanel.cs
@@ -33,6 +33,8 @@ namespace CodeImp.DoomBuilder.Controls
 	internal partial class ScriptEditorPanel : UserControl
 	{
 		#region ================== Constants
+
+		private static readonly Color QUICKSEARCH_FAIL_COLOR = Color.MistyRose; //mxd
 		
 		#endregion
 		
@@ -579,14 +581,34 @@ namespace CodeImp.DoomBuilder.Controls
 			buttonunindent.Enabled = (t != null && t.Scintilla.Lines[t.Scintilla.CurrentLine].Indentation > 0); //mxd
 			buttonwhitespace.Enabled = (t != null); //mxd
 			buttonwordwrap.Enabled = (t != null); //mxd
-			searchbox.Enabled = (t != null); //mxd
-			searchprev.Enabled = (t != null); //mxd
-			searchnext.Enabled = (t != null); //mxd
 			searchmatchcase.Enabled = (t != null); //mxd
 			searchwholeword.Enabled = (t != null); //mxd
 			
 			if(t != null)
 			{
+				//mxd. Update quick search controls
+				searchbox.Enabled = true;
+				if(searchbox.Text.Length > 0)
+				{
+					if(t.Scintilla.Text.IndexOf(searchbox.Text, searchmatchcase.Checked ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase) != -1)
+					{
+						searchprev.Enabled = true;
+						searchnext.Enabled = true;
+						searchbox.BackColor = SystemColors.Window;
+					}
+					else
+					{
+						searchprev.Enabled = false;
+						searchnext.Enabled = false;
+						searchbox.BackColor = QUICKSEARCH_FAIL_COLOR;
+					}
+				}
+				else
+				{
+					searchprev.Enabled = false;
+					searchnext.Enabled = false;
+				}
+
 				// Check the according script config in menu
 				foreach(ToolStripMenuItem item in buttonscriptconfig.DropDownItems)
 				{
@@ -604,6 +626,13 @@ namespace CodeImp.DoomBuilder.Controls
 				// Focus to script editor
 				if(focuseditor) ForceFocus();
 			}
+			else
+			{
+				//mxd. Disable quick search controls
+				searchbox.Enabled = false; 
+				searchprev.Enabled = false;
+				searchnext.Enabled = false;
+			}
 
 			//mxd. Update script type description
 			scripttype.Text = ((t != null && t.Config != null) ? t.Config.Description : "Plain Text");
@@ -1216,7 +1245,7 @@ namespace CodeImp.DoomBuilder.Controls
 		private void searchbox_TextChanged(object sender, EventArgs e)
 		{
 			bool success = (searchbox.Text.Length > 0 && ActiveTab.FindNext(GetQuickSearchOptions(), true));
-			searchbox.BackColor = ((success || searchbox.Text.Length == 0) ? SystemColors.Window : Color.MistyRose);
+			searchbox.BackColor = ((success || searchbox.Text.Length == 0) ? SystemColors.Window : QUICKSEARCH_FAIL_COLOR);
 			searchnext.Enabled = success;
 			searchprev.Enabled = success;
 		}
diff --git a/Source/Core/GZBuilder/Windows/TagStatisticsForm.cs b/Source/Core/GZBuilder/Windows/TagStatisticsForm.cs
index 63c2eee28bc22b1df4b24a7b7ad91a3dc29e9c46..7aebf389854fc70f6dbd71c1ea9a0f62a5ed7f85 100644
--- a/Source/Core/GZBuilder/Windows/TagStatisticsForm.cs
+++ b/Source/Core/GZBuilder/Windows/TagStatisticsForm.cs
@@ -203,13 +203,13 @@ namespace CodeImp.DoomBuilder.GZBuilder.Windows
 
 		private void apply_Click(object sender, EventArgs e) 
 		{
-			//refill TagLabels with table data
+			// Refill TagLabels with table data
 			dataGridView.Sort(TagColumn, ListSortDirection.Ascending);
 			General.Map.Options.TagLabels.Clear();
 
 			foreach(DataGridViewRow row in dataGridView.Rows) 
 			{
-				string label = row.Cells[1].Value.ToString();
+				string label = (string)row.Cells[1].Value;
 				if(!string.IsNullOrEmpty(label))
 					General.Map.Options.TagLabels.Add((int)row.Cells[0].Value, label);
 			}
diff --git a/Source/Core/Rendering/TextLabel.cs b/Source/Core/Rendering/TextLabel.cs
index 7f75619c8b2796b39e27638a4353cd41f8c99ce0..4f157dcf37ffa918847c0775f59b72028e8d2642 100644
--- a/Source/Core/Rendering/TextLabel.cs
+++ b/Source/Core/Rendering/TextLabel.cs
@@ -53,6 +53,7 @@ namespace CodeImp.DoomBuilder.Rendering
 		private TextAlignmentX alignx;
 		private TextAlignmentY aligny;
 		private SizeF textsize;
+		private Size texturesize;
 		private bool drawbg; //mxd
 		
 		// This keeps track if changes were made
@@ -199,8 +200,8 @@ namespace CodeImp.DoomBuilder.Rendering
 						}
 
 						// Create label image
-						Bitmap img = CreateLabelImage(text, font, alignx, aligny, color, backcolor, drawbg);
-						textsize = img.Size;
+						Bitmap img = CreateLabelImage(text, font, alignx, aligny, color, backcolor, drawbg, out textsize);
+						texturesize = img.Size;
 
 						// Create texture
 						MemoryStream memstream = new MemoryStream((img.Size.Width * img.Size.Height * 4) + 4096);
@@ -217,8 +218,8 @@ namespace CodeImp.DoomBuilder.Rendering
 					switch(alignx)
 					{
 						case TextAlignmentX.Left: beginx = absview.X; break;
-						case TextAlignmentX.Center: beginx = absview.X + (absview.Width - textsize.Width) * 0.5f; break;
-						case TextAlignmentX.Right: beginx = absview.X + absview.Width - textsize.Width; break;
+						case TextAlignmentX.Center: beginx = absview.X + (absview.Width - texturesize.Width) * 0.5f; break;
+						case TextAlignmentX.Right: beginx = absview.X + absview.Width - texturesize.Width; break;
 					}
 
 					// Align the text vertically
@@ -226,8 +227,8 @@ namespace CodeImp.DoomBuilder.Rendering
 					switch(aligny)
 					{
 						case TextAlignmentY.Top: beginy = absview.Y; break;
-						case TextAlignmentY.Middle: beginy = absview.Y + (absview.Height - textsize.Height) * 0.5f; break;
-						case TextAlignmentY.Bottom: beginy = absview.Y + absview.Height - textsize.Height; break;
+						case TextAlignmentY.Middle: beginy = absview.Y + (absview.Height - texturesize.Height) * 0.5f; break;
+						case TextAlignmentY.Bottom: beginy = absview.Y + absview.Height - texturesize.Height; break;
 					}
 
 					//mxd. Create the buffer
@@ -240,7 +241,7 @@ namespace CodeImp.DoomBuilder.Rendering
 					//mxd. Lock the buffer
 					using(DataStream stream = textbuffer.Lock(0, 4 * FlatVertex.Stride, LockFlags.Discard | LockFlags.NoSystemLock))
 					{
-						FlatQuad quad = new FlatQuad(PrimitiveType.TriangleStrip, beginx, beginy, beginx + textsize.Width, beginy + textsize.Height);
+						FlatQuad quad = new FlatQuad(PrimitiveType.TriangleStrip, beginx, beginy, beginx + texturesize.Width, beginy + texturesize.Height);
 						stream.WriteRange(quad.Vertices);
 					}
 
@@ -261,7 +262,7 @@ namespace CodeImp.DoomBuilder.Rendering
 		}
 
 		//mxd
-		private static Bitmap CreateLabelImage(string text, Font font, TextAlignmentX alignx, TextAlignmentY aligny, PixelColor color, PixelColor backcolor, bool drawbg)
+		private static Bitmap CreateLabelImage(string text, Font font, TextAlignmentX alignx, TextAlignmentY aligny, PixelColor color, PixelColor backcolor, bool drawbg, out SizeF textsize)
 		{
 			PointF textorigin = new PointF(4, 3);
 			RectangleF textrect = new RectangleF(textorigin, General.Interface.MeasureString(text, font));
@@ -269,6 +270,9 @@ namespace CodeImp.DoomBuilder.Rendering
 			textrect.Height = (float)Math.Round(textrect.Height);
 			RectangleF bgrect = new RectangleF(0, 0, textrect.Width + textorigin.X * 2, textrect.Height + textorigin.Y * 2);
 
+			// Store calculated text size...
+			textsize = new SizeF(bgrect.Width, bgrect.Height);
+
 			// Make PO2 image, for speed and giggles...
 			RectangleF po2rect = new RectangleF(0, 0, General.NextPowerOf2((int)bgrect.Width), General.NextPowerOf2((int)bgrect.Height));
 
diff --git a/Source/Plugins/BuilderModes/BuilderModes.csproj b/Source/Plugins/BuilderModes/BuilderModes.csproj
index 630393e03fa5d3108f36d0f9d823159ef861a3f0..2afdcfb6465a458e5110e638b487ac0dec2c7145 100644
--- a/Source/Plugins/BuilderModes/BuilderModes.csproj
+++ b/Source/Plugins/BuilderModes/BuilderModes.csproj
@@ -313,6 +313,7 @@
     <Compile Include="FindReplace\FindVertexNumber.cs" />
     <Compile Include="General\HintLabel.cs" />
     <Compile Include="General\BuilderModesTools.cs" />
+    <Compile Include="General\SelectionLabel.cs" />
     <Compile Include="General\UndoGroup.cs" />
     <Compile Include="Interface\BridgeModeForm.cs">
       <SubType>Form</SubType>
diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
index ec077bf02624beae3b8b81b9d6c8add4464c2431..5f9d23f5e0ad9a0f0386a0d327a0579c5d536b7d 100644
--- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs
@@ -62,7 +62,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		private Vector2D insertpreview = new Vector2D(float.NaN, float.NaN); //mxd
 
 		//mxd. Text labels
-		private Dictionary<Linedef, TextLabel> labels;
+		private Dictionary<Linedef, SelectionLabel> labels;
 		private Dictionary<Sector, TextLabel[]> sectorlabels;
 		private Dictionary<Sector, string[]> sectortexts;
 		
@@ -92,7 +92,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			if(!isdisposed)
 			{
 				// Dispose old labels
-				if(labels != null) foreach(TextLabel l in labels.Values) l.Dispose();
+				if(labels != null) foreach(SelectionLabel l in labels.Values) l.Dispose();
 				if(sectorlabels != null)
 				{
 					foreach(TextLabel[] lbl in sectorlabels.Values)
@@ -410,11 +410,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			base.UpdateSelectionInfo();
 			
 			// Dispose old labels
-			if(labels != null) foreach(TextLabel l in labels.Values) l.Dispose();
+			if(labels != null) foreach(SelectionLabel l in labels.Values) l.Dispose();
 
 			// Make text labels for selected linedefs
 			ICollection<Linedef> orderedselection = General.Map.Map.GetSelectedLinedefs(true);
-			labels = new Dictionary<Linedef, TextLabel>(orderedselection.Count);
+			labels = new Dictionary<Linedef, SelectionLabel>(orderedselection.Count);
 
 			// Otherwise significant delays will occure.
 			// Also we probably won't care about selection ordering when selecting this many anyway
@@ -423,15 +423,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			int index = 0;
 			foreach(Linedef linedef in orderedselection)
 			{
-				Vector2D v = linedef.GetCenterPoint();
-				TextLabel l = new TextLabel();
-				l.TransformCoords = true;
-				l.Rectangle = new RectangleF(v.x, v.y, 0.0f, 0.0f);
-				l.AlignX = TextAlignmentX.Center;
-				l.AlignY = TextAlignmentY.Middle;
+				SelectionLabel l = new SelectionLabel();
+				l.OffsetPosition = true;
 				l.Color = (linedef == highlighted ? General.Colors.Selection : General.Colors.Highlight);
 				l.BackColor = General.Colors.Background.WithAlpha(192);
-				l.Text = (++index).ToString();
+				l.TextLabel.Text = (++index).ToString();
 				labels.Add(linedef, l);
 			}
 		}
@@ -628,11 +624,15 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				if(BuilderPlug.Me.ViewSelectionNumbers)
 				{
 					List<TextLabel> torender = new List<TextLabel>(labels.Count);
-					foreach(KeyValuePair<Linedef, TextLabel> group in labels)
+					foreach(KeyValuePair<Linedef, SelectionLabel> group in labels)
 					{
 						// Render only when enough space for the label to see
+						group.Value.Move(group.Key.Start.Position, group.Key.End.Position);
 						float requiredsize = (group.Value.TextSize.Width) / renderer.Scale;
-						if(group.Key.Length > requiredsize) torender.Add(group.Value);
+						if(group.Key.Length > requiredsize)
+						{
+							torender.Add(group.Value.TextLabel);
+						}
 					}
 
 					renderer.RenderText(torender);
@@ -1271,7 +1271,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			General.Interface.DisplayStatus(StatusType.Selection, string.Empty);
 
 			//mxd. Clear selection labels
-			foreach(TextLabel l in labels.Values) l.Dispose();
+			foreach(SelectionLabel l in labels.Values) l.Dispose();
 			labels.Clear();
 
 			// Redraw
diff --git a/Source/Plugins/BuilderModes/General/LineLengthLabel.cs b/Source/Plugins/BuilderModes/General/LineLengthLabel.cs
index 0ae3dd16d053e4f0e46c28a48e5e536422ce0650..e499180e1dc7087ce614805e2f91c7cbfa85acee 100644
--- a/Source/Plugins/BuilderModes/General/LineLengthLabel.cs
+++ b/Source/Plugins/BuilderModes/General/LineLengthLabel.cs
@@ -52,7 +52,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		//mxd. Display options
 		public bool ShowAngle { get { return showangle; } set { showangle = value; UpdateText(); } }
 		public bool OffsetPosition { get { return offsetposition; } set { offsetposition = value; Move(start, end); } }
-		public PixelColor TextColor { get { return label.Color; } set { label.Color = value; } }
+		public PixelColor Color { get { return label.Color; } set { label.Color = value; } }
+		public PixelColor BackColor { get { return label.BackColor; } set { label.BackColor = value; } }
+		public SizeF TextSize { get { return label.TextSize; } }
 
 		#endregion
 
@@ -108,7 +110,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 						AlignX = TextAlignmentX.Center, 
 						AlignY = TextAlignmentY.Middle, 
 						Color = General.Colors.Highlight, 
-						BackColor = General.Colors.Background.WithAlpha(64), 
+						BackColor = General.Colors.Background.WithAlpha(128), 
 						TransformCoords = true,
 					};
 		}
diff --git a/Source/Plugins/BuilderModes/General/SelectionLabel.cs b/Source/Plugins/BuilderModes/General/SelectionLabel.cs
new file mode 100644
index 0000000000000000000000000000000000000000..cf6db44a5d83d0cac34e1a8e49e798c3a225d87d
--- /dev/null
+++ b/Source/Plugins/BuilderModes/General/SelectionLabel.cs
@@ -0,0 +1,11 @@
+namespace CodeImp.DoomBuilder.BuilderModes
+{
+	internal class SelectionLabel : LineLengthLabel
+	{
+		// Constructor
+		public SelectionLabel() : base(false, true) { }
+		
+		// We don't want any changes here
+		protected override void UpdateText() { }
+	}
+}