diff --git a/Source/Core/Editing/ClassicMode.cs b/Source/Core/Editing/ClassicMode.cs index 805e3455..88feca7e 100644 --- a/Source/Core/Editing/ClassicMode.cs +++ b/Source/Core/Editing/ClassicMode.cs @@ -722,7 +722,7 @@ namespace CodeImp.DoomBuilder.Editing if(s == null) { - General.MainWindow.DisplayStatus(StatusType.Warning, "Can't test from current position: cursor is not inside sector!"); + General.MainWindow.DisplayStatus(StatusType.Warning, "Can't test from current position: mouse cursor must be inside a sector!"); return false; } diff --git a/Source/Core/GZBuilder/Data/EngineInfo.cs b/Source/Core/GZBuilder/Data/EngineInfo.cs index 1fe74f44..fe333438 100644 --- a/Source/Core/GZBuilder/Data/EngineInfo.cs +++ b/Source/Core/GZBuilder/Data/EngineInfo.cs @@ -96,7 +96,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data if(File.Exists(testprogram)) { Icon i = Icon.ExtractAssociatedIcon(testprogram); - icon = (i != null ? i.ToBitmap() : new Bitmap(Properties.Resources.Question)); + icon = new Bitmap(i != null ? i.ToBitmap() : Properties.Resources.Question); } else { diff --git a/Source/Core/General/Launcher.cs b/Source/Core/General/Launcher.cs index 43e2d1e9..38744650 100644 --- a/Source/Core/General/Launcher.cs +++ b/Source/Core/General/Launcher.cs @@ -17,6 +17,7 @@ #region ================== Namespaces using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Windows.Forms; @@ -39,10 +40,10 @@ namespace CodeImp.DoomBuilder #region ================== Variables private string tempwad; - private Process process; //mxd + private Dictionary processes; //mxd private bool isdisposed; - delegate void EngineExitedCallback(); //mxd + delegate void EngineExitedCallback(Process p); //mxd #endregion @@ -59,6 +60,7 @@ namespace CodeImp.DoomBuilder { // Initialize CleanTempFile(manager); + processes = new Dictionary(); //mxd // Bind actions General.Actions.BindMethods(this); @@ -73,16 +75,30 @@ namespace CodeImp.DoomBuilder // Unbind actions General.Actions.UnbindMethods(this); - //mxd. Terminate process? - if(process != null) + //mxd. Terminate running processes? + if(processes != null) { - process.CloseMainWindow(); - process.Close(); + foreach(KeyValuePair group in processes) + { + // Close engine + group.Key.CloseMainWindow(); + group.Key.Close(); + + // Remove temporary file + if(File.Exists(group.Value)) + { + try { File.Delete(group.Value); } + catch { } + } + } } // Remove temporary file - try { File.Delete(tempwad); } - catch(Exception) { } + if(File.Exists(tempwad)) + { + try { File.Delete(tempwad); } + catch { } + } // Done isdisposed = true; @@ -232,18 +248,6 @@ namespace CodeImp.DoomBuilder return outp; } - //mxd - private bool AlreadyTesting() - { - if(process != null) - { - General.ShowWarningMessage("Game engine is already running." + Environment.NewLine + "Please close \"" + process.MainModule.FileName + "\" first.", MessageBoxButtons.OK); - return true; - } - - return false; - } - #endregion #region ================== Test @@ -252,23 +256,22 @@ namespace CodeImp.DoomBuilder [BeginAction("testmap")] public void Test() { - if(AlreadyTesting() || !General.Editing.Mode.OnMapTestBegin(false)) return; //mxd - TestAtSkill(General.Map.ConfigSettings.TestSkill); - General.Editing.Mode.OnMapTestEnd(false); //mxd + TestAtSkill(General.Map.ConfigSettings.TestSkill, false); } //mxd [BeginAction("testmapfromview")] public void TestFromView() { - if(AlreadyTesting() || !General.Editing.Mode.OnMapTestBegin(true)) return; - TestAtSkill(General.Map.ConfigSettings.TestSkill); - General.Editing.Mode.OnMapTestEnd(true); + TestAtSkill(General.Map.ConfigSettings.TestSkill, true); } // This saves the map to a temporary file and launches a test with the given skill - public void TestAtSkill(int skill) + public void TestAtSkill(int skill) { TestAtSkill(skill, false); } + public void TestAtSkill(int skill, bool testfromcurrentposition) { + if(!General.Editing.Mode.OnMapTestBegin(testfromcurrentposition)) return; //mxd + Cursor oldcursor = Cursor.Current; // Check if configuration is OK @@ -301,8 +304,11 @@ namespace CodeImp.DoomBuilder } // Remove temporary file - try { File.Delete(tempwad); } - catch(Exception) { } + if(File.Exists(tempwad) && !processes.ContainsValue(tempwad)) + { + try { File.Delete(tempwad); } + catch { } + } // Save map to temporary file Cursor.Current = Cursors.WaitCursor; @@ -334,9 +340,10 @@ namespace CodeImp.DoomBuilder try { // Start the program - process = Process.Start(processinfo); + Process process = Process.Start(processinfo); process.EnableRaisingEvents = true; //mxd process.Exited += ProcessOnExited; //mxd + processes.Add(process, tempwad); //mxd Cursor.Current = oldcursor; //mxd } catch(Exception e) @@ -351,16 +358,33 @@ namespace CodeImp.DoomBuilder } } General.Plugins.OnMapSaveEnd(SavePurpose.Testing); + General.Editing.Mode.OnMapTestEnd(testfromcurrentposition); //mxd } //mxd - private void TestingFinished() + private void TestingFinished(Process process) { // Done TimeSpan deltatime = TimeSpan.FromTicks(process.ExitTime.Ticks - process.StartTime.Ticks); - process = null; - General.WriteLogLine("Test program has finished."); + General.WriteLogLine("Testing with \"" + process.StartInfo.FileName + "\" has finished."); General.WriteLogLine("Run time: " + deltatime.TotalSeconds.ToString("###########0.00") + " seconds"); + + //mxd. Remove from active processes list + string closedtempfile = processes[process]; + processes.Remove(process); + + //mxd. Still have running engines?.. + if(processes.Count > 0) + { + // Remove temp file + if(File.Exists(closedtempfile)) + { + try { File.Delete(closedtempfile); } + catch { } + } + return; + } + General.MainWindow.DisplayReady(); // Clean up temp file @@ -374,20 +398,15 @@ namespace CodeImp.DoomBuilder General.Map.Graphics.Reset(); General.MainWindow.RedrawDisplay(); } - /*else if(General.Editing.Mode is VisualMode) - { - General.MainWindow.StopExclusiveMouseInput(); - General.MainWindow.StartExclusiveMouseInput(); - }*/ } General.MainWindow.FocusDisplay(); } //mxd - private void ProcessOnExited(object sender, EventArgs eventArgs) + private void ProcessOnExited(object sender, EventArgs e) { - General.MainWindow.Invoke(new EngineExitedCallback(TestingFinished)); + General.MainWindow.Invoke(new EngineExitedCallback(TestingFinished), new[] { sender }); } // This deletes the previous temp file and creates a new, empty temp file @@ -395,7 +414,7 @@ namespace CodeImp.DoomBuilder { // Remove temporary file try { File.Delete(tempwad); } - catch(Exception) { } + catch { } // Make new empty temp file tempwad = General.MakeTempFilename(manager.TempPath, "wad"); diff --git a/Source/Core/Geometry/Tools.cs b/Source/Core/Geometry/Tools.cs index 02775481..80cfbc28 100644 --- a/Source/Core/Geometry/Tools.cs +++ b/Source/Core/Geometry/Tools.cs @@ -937,7 +937,6 @@ namespace CodeImp.DoomBuilder.Geometry if(points[0].stitch) mergeverts.Add(v1); else nonmergeverts.Add(v1); // Go for all other points - int roundprecision = (General.Map.FormatInterface.VertexDecimals > 0 ? General.Map.FormatInterface.VertexDecimals - 1 : 0); //mxd for(int i = 1; i < points.Count; i++) { // Create vertex for point @@ -963,7 +962,7 @@ namespace CodeImp.DoomBuilder.Geometry // Check if any other lines intersect this line List intersections = new List(); Line2D measureline = ld.Line; - Dictionary processed = new Dictionary(); //mxd + HashSet processed = new HashSet(); //mxd //mxd foreach(Sector s in map.Sectors) @@ -973,7 +972,7 @@ namespace CodeImp.DoomBuilder.Geometry { foreach(Sidedef side in s.Sidedefs) { - if(processed.ContainsKey(side.Line)) continue; + if(processed.Contains(side.Line)) continue; if(side.Line == ld) continue; float u; @@ -983,7 +982,7 @@ namespace CodeImp.DoomBuilder.Geometry intersections.Add(u); } - processed.Add(side.Line, false); + processed.Add(side.Line); } } } @@ -1000,10 +999,6 @@ namespace CodeImp.DoomBuilder.Geometry // may already have changed in length due to a previous split Vector2D splitpoint = measureline.GetCoordinatesAt(u); - //mxd. Work around some imprecisions when splitting very long lines (like 19000 mu long) - splitpoint.x = (float)Math.Round(splitpoint.x, roundprecision); - splitpoint.y = (float)Math.Round(splitpoint.y, roundprecision); - // Make the vertex Vertex splitvertex = map.CreateVertex(splitpoint); if(splitvertex == null) return false; diff --git a/Source/Core/Map/MapSet.cs b/Source/Core/Map/MapSet.cs index c2f1bc2d..b1b8eb25 100644 --- a/Source/Core/Map/MapSet.cs +++ b/Source/Core/Map/MapSet.cs @@ -46,7 +46,7 @@ namespace CodeImp.DoomBuilder.Map /// Stiching distance. This is only to get around inaccuracies. Basically, /// geometry only stitches when exactly on top of each other. - public const float STITCH_DISTANCE = 0.001f; + public const float STITCH_DISTANCE = 0.005f; //mxd. 0.001f is not enough when drawing very long lines... // Virtual sector identification // This contains a character that is invalid in the UDMF standard, but valid diff --git a/Source/Plugins/AutomapMode/Interface/MenusForm.Designer.cs b/Source/Plugins/AutomapMode/Interface/MenusForm.Designer.cs index 5e7e03dd..e4a3d5cc 100644 --- a/Source/Plugins/AutomapMode/Interface/MenusForm.Designer.cs +++ b/Source/Plugins/AutomapMode/Interface/MenusForm.Designer.cs @@ -91,7 +91,7 @@ "Hexen", "Strife"}); this.colorpreset.Name = "colorpreset"; - this.colorpreset.Size = new System.Drawing.Size(121, 25); + this.colorpreset.Size = new System.Drawing.Size(75, 25); this.colorpreset.SelectedIndexChanged += new System.EventHandler(this.colorpreset_SelectedIndexChanged); // // MenusForm diff --git a/Source/Plugins/BuilderModes/ErrorChecks/ResultShortLinedef.cs b/Source/Plugins/BuilderModes/ErrorChecks/ResultShortLinedef.cs index 7b2db8aa..03f54ee9 100644 --- a/Source/Plugins/BuilderModes/ErrorChecks/ResultShortLinedef.cs +++ b/Source/Plugins/BuilderModes/ErrorChecks/ResultShortLinedef.cs @@ -1,6 +1,7 @@ #region ================== Namespaces using System; +using System.Drawing; using CodeImp.DoomBuilder.Map; using CodeImp.DoomBuilder.Rendering; @@ -50,7 +51,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // This must return the string that is displayed in the listbox public override string ToString() { - return "Linedef " + line.Index + " is shorter than 1 m.u."; + return "Linedef " + line.Index + " is shorter than 1 mu."; } // Rendering @@ -60,6 +61,19 @@ namespace CodeImp.DoomBuilder.BuilderModes renderer.PlotVertex(line.Start, ColorCollection.VERTICES); renderer.PlotVertex(line.End, ColorCollection.VERTICES); } + + // We must zoom in way more than usual... + public override RectangleF GetZoomArea() + { + // Get Area + RectangleF area = base.GetZoomArea(); + + // Remove padding + area.Inflate(-97f, -97f); + + // Return area + return area; + } #endregion } diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs index 9512836a..862403e3 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs @@ -2702,7 +2702,9 @@ namespace CodeImp.DoomBuilder.BuilderModes public void TextureCopy() { PreActionNoChange(); - GetTargetEventReceiver(true).OnCopyTexture(); //mxd + IVisualEventReceiver i = GetTargetEventReceiver(true); + i.OnCopyTexture(); //mxd + if(!(i is VisualThing)) copybuffer.Clear(); //mxd. Not copying things any more... PostAction(); } @@ -3119,7 +3121,9 @@ namespace CodeImp.DoomBuilder.BuilderModes VisualThing vt = (VisualThing)i; if(vt != null) copybuffer.Add(new ThingCopyData(vt.Thing)); } - General.Interface.DisplayStatus(StatusType.Info, "Copied " + copybuffer.Count + " Things"); + + string rest = copybuffer.Count + (copybuffer.Count > 1 ? " things." : " thing."); + General.Interface.DisplayStatus(StatusType.Info, "Copied " + rest); } //mxd @@ -3129,7 +3133,7 @@ namespace CodeImp.DoomBuilder.BuilderModes CopySelection(); //Create undo - string rest = copybuffer.Count + " thing" + (copybuffer.Count > 1 ? "s." : "."); + string rest = copybuffer.Count + (copybuffer.Count > 1 ? " things." : " thing."); CreateUndo("Cut " + rest); General.Interface.DisplayStatus(StatusType.Info, "Cut " + rest); @@ -3155,7 +3159,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { if(copybuffer.Count == 0) { - General.Interface.DisplayStatus(StatusType.Warning, "Nothing to paste, cut or copy some Things first!"); + TexturePaste(); // I guess we may paste a texture or two instead return; } @@ -3167,7 +3171,7 @@ namespace CodeImp.DoomBuilder.BuilderModes return; } - string rest = copybuffer.Count + " thing" + (copybuffer.Count > 1 ? "s" : ""); + string rest = copybuffer.Count + (copybuffer.Count > 1 ? " things." : " thing."); General.Map.UndoRedo.CreateUndo("Paste " + rest); General.Interface.DisplayStatus(StatusType.Info, "Pasted " + rest);