diff --git a/Build/Scripting/ZDoom_DECORATE.cfg b/Build/Scripting/ZDoom_DECORATE.cfg index 909eaf5b738df00b10e323c266ce6bad0d147f12..a1f8a5e502edb7afa3c41d45091a61469b222d09 100644 --- a/Build/Scripting/ZDoom_DECORATE.cfg +++ b/Build/Scripting/ZDoom_DECORATE.cfg @@ -368,7 +368,7 @@ keywords A_BarrelDestroy = "A_BarrelDestroy"; //Miscellaneous functions not listed in the "Action functions" wiki article A_Bang4Cloud = "A_Bang4Cloud"; - A_Blast = "A_Blast[(int flags = 0[, int strength = 255[, int radius = 255[, float speed = 20.0[, str blasteffect = \"BlastEffect\"[, str blastsound = \"BlastRadius\"]]]]])]\nA_Blast[(int flags = 0[, int strength = 255[, float radius = 255.0[, float speed = 20.0[, str blasteffect = \"BlastEffect\"[, str blastsound = \"BlastRadius\"]]]]])]"; + A_Blast = "A_Blast[(int flags = 0[, float strength = 255.0[, float radius = 255.0[, float speed = 20.0[, str blasteffect = \"BlastEffect\"[, str blastsound = \"BlastRadius\"]]]]])]"; A_BishopMissileWeave = "A_BishopMissileWeave"; A_DropWeaponPieces = "A_DropWeaponPieces(str actorclass1, str actorclass2, str actorclass3)"; A_Feathers = "A_Feathers"; diff --git a/Help/gzdb/features/classic_modes/draw_grid_tri.jpg b/Help/gzdb/features/classic_modes/draw_grid_tri.jpg index 68817542e7ea8886f6e1ebe0d98f2b6b3847954c..6cd5d922c829ba816bf75b1c578aeaa2e3d3db5c 100644 Binary files a/Help/gzdb/features/classic_modes/draw_grid_tri.jpg and b/Help/gzdb/features/classic_modes/draw_grid_tri.jpg differ diff --git a/Help/gzdb/features/classic_modes/mode_drawcurve.html b/Help/gzdb/features/classic_modes/mode_drawcurve.html index 472288a2ecebeb4dfcee2aa0e9a210bce8c435fe..3db4b83a15a7f0752665fea3fe9974986be6c76e 100644 --- a/Help/gzdb/features/classic_modes/mode_drawcurve.html +++ b/Help/gzdb/features/classic_modes/mode_drawcurve.html @@ -25,7 +25,9 @@ This mode lets you draw various curve shapes. <br> <b>Default key:</b> Ctrl-Alt-D.<br> <b>Additional actions:</b> Increase Subdivision Level, Decrease Subdivision Level.<br><br> You can activate this mode by pressing <strong>Ctrl-Alt-D</strong> (default key).<br> -You can use the side panel or "<strong>Increase Subdivision Level</strong>" and "<strong>Decrease Subdivision Level</strong>" actions to control how detailed the curve is: +Press "<strong>Continuous drawing</strong>" button on the mode panel to disable automatic switching to previous editing mode after finishing drawing.<br> +Press "<strong>Auto-finish drawing</strong>" button on the mode panel to automatically finish drawing when currently drawn lines and already existing level geometry form a closed shape.<br> +You can use the mode panel or "<strong>Increase Subdivision Level</strong>" and "<strong>Decrease Subdivision Level</strong>" actions to control how detailed the curve is: <br> <img src="draw_curve.jpg" /></div> </body> diff --git a/Help/gzdb/features/classic_modes/mode_drawellipse.html b/Help/gzdb/features/classic_modes/mode_drawellipse.html index 1ed952a5575999c13294eba471fa75a36b8c36a1..772aa198d44c4cc150e133eb6fc6667ce73f17e8 100644 --- a/Help/gzdb/features/classic_modes/mode_drawellipse.html +++ b/Help/gzdb/features/classic_modes/mode_drawellipse.html @@ -21,14 +21,15 @@ This mode lets you draw various ellipsoid shapes.<br> <b>Menu path:</b> Mode -> Draw Ellipse.<br> <b>Action category:</b> Drawing.<br> <b>Default key:</b> Ctrl-Alt-D.<br> - <b>Additional actions:</b> Increase Subdivision Level, Decrease Subdivision Level, Increase Corners Bevel, Decrease Corners Bevel.<br> + <b>Additional actions:</b> Increase Subdivision Level, Decrease Subdivision Level, Increase Corners Bevel, Decrease Corners Bevel, Rotate Clockwise, Rotate Counterclockwise.<br> <br> You can activate this mode by pressing <strong>Alt-Shift-D</strong> (default key).<br> - You can use the side panel or "<strong>Increase Subdivision Level</strong>" and "<strong>Decrease Subdivision Level</strong>" actions to control the number of sides ellipse has: - <br> + Press "<strong>Continuous drawing</strong>" button on the mode panel to disable automatic switching to previous editing mode after finishing drawing.<br> + You can use the mode panel or "<strong>Rotate Clockwise</strong>" and "<strong>Rotate Counterclockwise</strong>" actions to rotate the shape.<br> + You can use the mode panel or "<strong>Increase Subdivision Level</strong>" and "<strong>Decrease Subdivision Level</strong>" actions to control the number of sides ellipse has.<br> <img src="draw_ellipse1.jpg" /> <br> - You can use side panel or "<strong>Increase Corners Bevel</strong>" and "<strong>Decrease Corners Bevel</strong>" actions to bevel the ellipse: <br> + You can use mode panel or "<strong>Increase Corners Bevel</strong>" and "<strong>Decrease Corners Bevel</strong>" actions to bevel the ellipse: <br> <img src="draw_ellipse2.jpg" /> <br> When using "<strong>Increase/Decrease Corners Bevel</strong>" actions, the bevel increment is based on the current grid size.</p> diff --git a/Help/gzdb/features/classic_modes/mode_drawgrid.html b/Help/gzdb/features/classic_modes/mode_drawgrid.html index 2512b7840fc659429ad0018466a740832d78e5dc..659e7dd8b477edeeb97872efc039ec53c2078e9b 100644 --- a/Help/gzdb/features/classic_modes/mode_drawgrid.html +++ b/Help/gzdb/features/classic_modes/mode_drawgrid.html @@ -24,8 +24,9 @@ <b>Default key:</b> none.<br /> <b>Additional actions:</b> Increase Subdivision Level, Decrease Subdivision Level, Increase Corners Bevel, Decrease Corners Bevel.</p> <p>You can use the side panel or "<strong>Increase/Decrease Subdivision Level</strong>" and "<strong>Increase/Decrease Corners Bevel</strong>" actions to change the number of horizontal and vertical slices.<br /> - Check "<strong>Lock slices to grid</strong>" to match slices number to current grid size.<br /> - Check "<strong>Triangulate</strong>" if you want to create triangles instead of quads:</p> + Change "<strong>Lock slices to grid</strong>" setting to match slices number to current grid size horizontally, vertically or in both directions.<br /> + Check "<strong>Triangulate</strong>" if you want to create triangles instead of quads.<br /> + Check "<strong>Continuous drawing</strong>" to disable automatic switching to previous editing mode after finishing drawing.</p> <p><img src="draw_grid_tri.jpg" alt="" /></p> </div> </body> diff --git a/Help/gzdb/features/classic_modes/mode_drawrect.html b/Help/gzdb/features/classic_modes/mode_drawrect.html index 29aaccf0f04160eb7a3320309ee6190465e21486..8328c48b7bb2c30164d4bd46c6ad0c1a36a34d93 100644 --- a/Help/gzdb/features/classic_modes/mode_drawrect.html +++ b/Help/gzdb/features/classic_modes/mode_drawrect.html @@ -21,9 +21,11 @@ This mode lets you draw various rectangle shapes.<br> <b>Menu path:</b> Mode -> Draw Rectangle.<br /> <b>Action category:</b> Drawing.<br> <b>Default key:</b> Ctrl-Shift-D.<br> -<b>Additional actions:</b> Increase Subdivision Level, Decrease Subdivision Level, Increase Corners Bevel, Decrease Corners Bevel.<br><br> +<b>Additional actions:</b> Increase Subdivision Level, Decrease Subdivision Level, Increase Corners Bevel, Decrease Corners Bevel.<br> +<br> You can activate this mode by pressing <strong>Ctrl-Shift-D</strong> (default key).<br> -You can use the side panel or "<strong>Increase/Decrease Subdivision Level</strong>" and "<strong>Increase/Decrease Corners Bevel</strong>" actions to change corner bevel amount and detail level: +Press "<strong>Continuous drawing</strong>" button on the mode panel to disable automatic switching to previous editing mode after finishing drawing.<br> +You can use the mode panel or "<strong>Increase/Decrease Subdivision Level</strong>" and "<strong>Increase/Decrease Corners Bevel</strong>" actions to change corner bevel amount and detail level: <br> <img src="draw_rectangle1.jpg" /> <br> diff --git a/Source/Core/Data/WADReader.cs b/Source/Core/Data/WADReader.cs index e29ae59d73c331c84f1795dee41df122d25dd6f0..dec6464a403a73753850cf219a1046028a6c13cc 100644 --- a/Source/Core/Data/WADReader.cs +++ b/Source/Core/Data/WADReader.cs @@ -83,7 +83,7 @@ namespace CodeImp.DoomBuilder.Data // Initialize file = new WAD(location.location, true); - is_iwad = (file.Type == WAD.TYPE_IWAD); + is_iwad = file.IsIWAD; strictpatches = dl.option1; patchranges = new List<LumpRange>(); spriteranges = new List<LumpRange>(); @@ -175,7 +175,7 @@ namespace CodeImp.DoomBuilder.Data public override void Resume() { file = new WAD(location.location, true); - is_iwad = (file.Type == WAD.TYPE_IWAD); + is_iwad = file.IsIWAD; base.Resume(); } @@ -219,23 +219,27 @@ namespace CodeImp.DoomBuilder.Data } } - //mxd. Display warnings for unclosed ranges - foreach(KeyValuePair<LumpRange, KeyValuePair<string, string>> group in failedranges) + // Don't check official IWADs + if(!file.IsOfficialIWAD) { - if(successfulrangestarts.ContainsKey(group.Key.start)) continue; - General.ErrorLogger.Add(ErrorType.Warning, "\"" + group.Value.Key + "\" range at index " + group.Key.start + " is not closed in resource \"" + location.location + "\" (\"" + group.Value.Value + "\" marker is missing)."); - } + //mxd. Display warnings for unclosed ranges + foreach(KeyValuePair<LumpRange, KeyValuePair<string, string>> group in failedranges) + { + if(successfulrangestarts.ContainsKey(group.Key.start)) continue; + General.ErrorLogger.Add(ErrorType.Warning, "\"" + group.Value.Key + "\" range at index " + group.Key.start + " is not closed in resource \"" + location.location + "\" (\"" + group.Value.Value + "\" marker is missing)."); + } - //mxd. Check duplicates - foreach(LumpRange range in ranges) - { - HashSet<string> names = new HashSet<string>(StringComparer.OrdinalIgnoreCase); - for(int i = range.start + 1; i < range.end; i++) + //mxd. Check duplicates + foreach(LumpRange range in ranges) { - if(names.Contains(file.Lumps[i].Name)) - General.ErrorLogger.Add(ErrorType.Warning, elementname + " \"" + file.Lumps[i].Name + "\", index " + i + " is double defined in resource \"" + location.location + "\"."); - else - names.Add(file.Lumps[i].Name); + HashSet<string> names = new HashSet<string>(StringComparer.OrdinalIgnoreCase); + for(int i = range.start + 1; i < range.end; i++) + { + if(names.Contains(file.Lumps[i].Name)) + General.ErrorLogger.Add(ErrorType.Warning, elementname + " \"" + file.Lumps[i].Name + "\", index " + i + " is double defined in resource \"" + location.location + "\"."); + else + names.Add(file.Lumps[i].Name); + } } } } diff --git a/Source/Core/Editing/ClassicMode.cs b/Source/Core/Editing/ClassicMode.cs index 8558a3e6410e55ed0a8c881527852b0723e996ad..9ff5be126a9e2c52d784733581764666281ef317 100644 --- a/Source/Core/Editing/ClassicMode.cs +++ b/Source/Core/Editing/ClassicMode.cs @@ -461,7 +461,6 @@ namespace CodeImp.DoomBuilder.Editing #region ================== Processing // Processing - public override void OnProcess(float deltatime) { OnProcess((long)deltatime); } //mxd. DB2 compatibility public override void OnProcess(long deltatime) { base.OnProcess(deltatime); diff --git a/Source/Core/Editing/EditMode.cs b/Source/Core/Editing/EditMode.cs index 3f4a5c9d6c214f6d1b972231f9bebe5633134338..4920e23c3e0a9d95c945400b0ac83078d6be409e 100644 --- a/Source/Core/Editing/EditMode.cs +++ b/Source/Core/Editing/EditMode.cs @@ -246,7 +246,6 @@ namespace CodeImp.DoomBuilder.Editing // Processing events public virtual void OnProcess(long deltatime) { } - public virtual void OnProcess(float deltatime) { OnProcess((long)deltatime); } //mxd. DB2 compatibility // Generic events public virtual void OnReloadResources() { } diff --git a/Source/Core/General/General.cs b/Source/Core/General/General.cs index d100cc2f10ddc50a3469164e9ce7cb4fc381991a..e9e9d308cf79867078651b2a72dc154bd3ebf65b 100644 --- a/Source/Core/General/General.cs +++ b/Source/Core/General/General.cs @@ -231,6 +231,7 @@ namespace CodeImp.DoomBuilder public static bool NoSettings { get { return nosettings; } } public static EditingManager Editing { get { return editing; } } public static ErrorLogger ErrorLogger { get { return errorlogger; } } + internal static int PendingUpdateRev; //mxd #endregion @@ -993,7 +994,7 @@ namespace CodeImp.DoomBuilder // Terminate properly? if(properexit) { - General.WriteLogLine("Termination requested"); + General.WriteLogLine(PendingUpdateRev != 0 ? "Program update requested" : "Termination requested"); // Unbind static methods from actions General.Actions.UnbindMethods(typeof(General)); @@ -1018,7 +1019,14 @@ namespace CodeImp.DoomBuilder if(mainwindow != null) { mainwindow.Dispose(); mainwindow = null; } if(actions != null) { actions.Dispose(); actions = null; } if(types != null) { types.Dispose(); types = null; } - try { D3DDevice.Terminate(); } catch(Exception) { } + try { D3DDevice.Terminate(); } catch { } + + //mxd. Launch the updater? + if(PendingUpdateRev != 0) + { + General.WriteLogLine("Initiating update to R" + PendingUpdateRev + "..."); + Process.Start(Path.Combine(apppath, "Updater.exe"), "-rev " + PendingUpdateRev); + } // Application ends here and now General.WriteLogLine("Termination done"); @@ -1181,7 +1189,10 @@ namespace CodeImp.DoomBuilder openfile.Filter = "Doom WAD Files (*.wad)|*.wad"; openfile.Title = "Open Map"; if(!string.IsNullOrEmpty(settings.LastUsedMapFolder) && Directory.Exists(settings.LastUsedMapFolder)) //mxd - openfile.InitialDirectory = settings.LastUsedMapFolder; //mxd + { + openfile.RestoreDirectory = true; + openfile.InitialDirectory = settings.LastUsedMapFolder; + } openfile.AddExtension = false; openfile.CheckFileExists = true; openfile.Multiselect = false; @@ -1468,6 +1479,12 @@ namespace CodeImp.DoomBuilder savefile.OverwritePrompt = true; savefile.ValidateNames = true; savefile.FileName = map.FileTitle; //mxd + if(map.FilePathName.Length > 0) //mxd + { + savefile.RestoreDirectory = true; + savefile.InitialDirectory = Path.GetDirectoryName(map.FilePathName); + } + if(savefile.ShowDialog(mainwindow) == DialogResult.OK) { // Check if we're saving to the same file as the original. diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs index c56e02697afc88d02b036a4bc598ad576151f916..7d21db5d4148d777b00887fcf8a5911aa4b0f831 100644 --- a/Source/Core/General/MapManager.cs +++ b/Source/Core/General/MapManager.cs @@ -664,7 +664,7 @@ namespace CodeImp.DoomBuilder General.MainWindow.DisplayStatus(StatusType.Busy, "Compressing sidedefs..."); outputset.CompressSidedefs(); - // Check if it still doesnt fit + // Check if it still doesnt if(outputset.Sidedefs.Count > io.MaxSidedefs) { // Problem! Can't save the map like this! @@ -727,6 +727,20 @@ namespace CodeImp.DoomBuilder General.WriteLogLine("Saving map to file: " + newfilepathname); + //mxd. Official IWAD check... + WAD hashtest = new WAD(newfilepathname, true); + if(hashtest.IsOfficialIWAD) + { + General.WriteLogLine("Map saving aborted: attempt to modify official IWAD"); + General.ShowErrorMessage("Official IWADs should not be modified.\nConsider making a PWAD instead", MessageBoxButtons.OK); + return false; + } + else + { + hashtest.Dispose(); + hashtest = null; + } + // Scripts changed? bool localscriptschanged = CheckScriptChanged(); @@ -907,7 +921,7 @@ namespace CodeImp.DoomBuilder WAD origwad = new WAD(origwadfile, true); // Create new target file - targetwad = new WAD(newfilepathname); + targetwad = new WAD(newfilepathname) { IsIWAD = origwad.IsIWAD }; //mxd. Let's preserve wad type // Copy all lumps, except the original map GameConfiguration origcfg; //mxd diff --git a/Source/Core/Geometry/Tools.cs b/Source/Core/Geometry/Tools.cs index afafdd009a3e6d7d257348ea9a97757fc28ce626..fd2e41b5dcceb03989c7282d4989a57f2324df9f 100644 --- a/Source/Core/Geometry/Tools.cs +++ b/Source/Core/Geometry/Tools.cs @@ -359,7 +359,6 @@ namespace CodeImp.DoomBuilder.Geometry { // Add line to path path.Add(new LinedefSide(nextline, nextfront)); - if(!tracecount.ContainsKey(nextline)) tracecount.Add(nextline, 1); else tracecount[nextline]++; // Determine next vertex to use Vertex v = nextfront ? nextline.End : nextline.Start; @@ -390,6 +389,21 @@ namespace CodeImp.DoomBuilder.Geometry Linedef prevline = nextline; nextline = (lines[0] == nextline ? lines[1] : lines[0]); + //mxd. Try to pick a line with lower tracecount... + // Otherwise we will just walk the same path trise + int curcount = (!tracecount.ContainsKey(nextline) ? 0 : tracecount[nextline]); + if(curcount > 0) + { + foreach(Linedef l in lines) + { + if(l != nextline && l != prevline && (!tracecount.ContainsKey(l) || tracecount[l] < curcount)) + { + nextline = l; + break; + } + } + } + // Are we allowed to trace this line again? if(!tracecount.ContainsKey(nextline) || (tracecount[nextline] < 3)) { @@ -403,6 +417,9 @@ namespace CodeImp.DoomBuilder.Geometry path = null; } } + + //mxd. Increase trace count + if(!tracecount.ContainsKey(nextline)) tracecount.Add(nextline, 1); else tracecount[nextline]++; } // Continue as long as we have not reached the start yet // or we have no next line to trace diff --git a/Source/Core/IO/WAD.cs b/Source/Core/IO/WAD.cs index ea4eefc872c0c88725e9468c737d816fe02ed260..4827fe9b0e3e23b7bd9dd8eb4b61a2237baeb003 100644 --- a/Source/Core/IO/WAD.cs +++ b/Source/Core/IO/WAD.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using System.Security.Cryptography; using System.Text; using System.IO; @@ -30,11 +31,58 @@ namespace CodeImp.DoomBuilder.IO #region ================== Constants // WAD types - public const string TYPE_IWAD = "IWAD"; - public const string TYPE_PWAD = "PWAD"; + private const string TYPE_IWAD = "IWAD"; + private const string TYPE_PWAD = "PWAD"; // Encoder public static readonly Encoding ENCODING = Encoding.ASCII; + + //mxd. Official IWAD MD5 hashes + private static readonly HashSet<string> IWAD_HASHES = new HashSet<string> + { + ////// DOOM IWADS ////// + "d9153ced9fd5b898b36cc5844e35b520", // DOOM2 1.666g MD5 + "30e3c2d0350b67bfbf47271970b74b2f", // DOOM2 1.666 MD5 + "ea74a47a791fdef2e9f2ea8b8a9da13b", // DOOM2 1.7 MD5 + "d7a07e5d3f4625074312bc299d7ed33f", // DOOM2 1.7a MD5 + "c236745bb01d89bbb866c8fed81b6f8c", // DOOM2 1.8 MD5 + "25e1459ca71d321525f84628f45ca8cd", // DOOM2 1.9 MD5 + "3cb02349b3df649c86290907eed64e7b", // DOOM2 French MD5 + "c3bea40570c23e511a7ed3ebcd9865f7", // BFG DOOM2 MD5 + + "981b03e6d1dc033301aa3095acc437ce", // DOOM 1.1 MD5 + "792fd1fea023d61210857089a7c1e351", // DOOM 1.2 MD5 + "464e3723a7e7f97039ac9fd057096adb", // DOOM 1.6b MD5 + "54978d12de87f162b9bcc011676cb3c0", // DOOM 1.666 MD5 + "11e1cd216801ea2657723abc86ecb01f", // DOOM 1.8 MD5 + "1cd63c5ddff1bf8ce844237f580e9cf3", // DOOM 1.9 MD5 + "fb35c4a5a9fd49ec29ab6e900572c524", // BFG DOOM MD5 + + "c4fe9fd920207691a9f493668e0a2083", // ULTIMATE DOOM MD5 + + "75c8cf89566741fa9d22447604053bd7", // PLUTONIA MD5 + "3493be7e1e2588bc9c8b31eab2587a04", // PLUTONIA RARE MD5 + + "4e158d9953c79ccf97bd0663244cc6b6", // TNT MD5 + "1d39e405bf6ee3df69a8d2646c8d5c49", // TNT Fixed MD5 + "be626c12b7c9d94b1dfb9c327566b4ff", // PSN TNT MD5 + + ////// HERETIC IWADS ////// + "3117e399cdb4298eaa3941625f4b2923", // HERETIC 1.0 MD5 + "1e4cb4ef075ad344dd63971637307e04", // HERETIC 1.2 MD5 + "66d686b1ed6d35ff103f15dbd30e0341", // HERETIC 1.3 MD5 + + ////// HEXEN IWADS ////// + "c88a2bb3d783e2ad7b599a8e301e099e", // HEXEN Beta MD5 + "b2543a03521365261d0a0f74d5dd90f0", // HEXEN 1.0 MD5 + "abb033caf81e26f12a2103e1fa25453f", // HEXEN 1.1 MD5 + "1077432e2690d390c256ac908b5f4efa", // HEXEN DK 1.0 MD5 + "78d5898e99e220e4de64edaa0e479593", // HEXEN DK 1.1 MD5 + + ////// STRIFE IWADS ////// + "8f2d3a6a289f5d2f2f9c1eec02b47299", // STRIFE 1.0 MD5 + "2fed2031a5b03892106e0f117f17901f", // STRIFE 1.2 MD5 + }; #endregion @@ -47,15 +95,16 @@ namespace CodeImp.DoomBuilder.IO private BinaryWriter writer; // Header - private string type; private int numlumps; private int lumpsoffset; + private bool isiwad; //mxd + private bool isofficialiwad; //mxd // Lumps private List<Lump> lumps; // Status - private readonly bool isreadonly; + private bool isreadonly; private bool isdisposed; #endregion @@ -63,10 +112,11 @@ namespace CodeImp.DoomBuilder.IO #region ================== Properties public string Filename { get { return filename; } } - public string Type { get { return type; } } public Encoding Encoding { get { return ENCODING; } } public bool IsReadOnly { get { return isreadonly; } } public bool IsDisposed { get { return isdisposed; } } + public bool IsIWAD { get { return isiwad; } set { isiwad = value; } } //mxd + public bool IsOfficialIWAD { get { return isofficialiwad; } } //mxd public List<Lump> Lumps { get { return lumps; } } #endregion @@ -131,6 +181,12 @@ namespace CodeImp.DoomBuilder.IO { FileAccess access; FileShare share; + + // Keep filename + filename = pathfilename; + + //mxd + CheckHash(); // Determine if opening for read only if(isreadonly) @@ -146,9 +202,6 @@ namespace CodeImp.DoomBuilder.IO share = FileShare.Read; } - // Keep filename - filename = pathfilename; - // Open the file stream file = File.Open(pathfilename, FileMode.OpenOrCreate, access, share); @@ -157,7 +210,7 @@ namespace CodeImp.DoomBuilder.IO if(!isreadonly) writer = new BinaryWriter(file, ENCODING); // Is the WAD file zero length? - if(file.Length == 0) + if(file.Length < 4) { // Create the headers in file CreateHeaders(); @@ -173,14 +226,15 @@ namespace CodeImp.DoomBuilder.IO private void CreateHeaders() { // Default settings - type = TYPE_PWAD; + isiwad = false; //mxd + isofficialiwad = false; //mxd lumpsoffset = 12; // New lumps array lumps = new List<Lump>(numlumps); // Write the headers - WriteHeaders(); + if(!isreadonly) WriteHeaders(); } // This reads the WAD header and lumps table @@ -193,7 +247,7 @@ namespace CodeImp.DoomBuilder.IO file.Seek(0, SeekOrigin.Begin); // Read WAD type - type = ENCODING.GetString(reader.ReadBytes(4)); + isiwad = (ENCODING.GetString(reader.ReadBytes(4)) == TYPE_IWAD); //mxd // Number of lumps numlumps = reader.ReadInt32(); @@ -223,14 +277,14 @@ namespace CodeImp.DoomBuilder.IO } } - // This reads the WAD header and lumps table + // This writes the WAD header and lumps table public void WriteHeaders() { // Seek to beginning file.Seek(0, SeekOrigin.Begin); // Write WAD type - writer.Write(ENCODING.GetBytes(type)); + writer.Write(ENCODING.GetBytes(isiwad ? TYPE_IWAD : TYPE_PWAD)); // Number of lumps writer.Write(numlumps); @@ -250,6 +304,48 @@ namespace CodeImp.DoomBuilder.IO writer.Write(lumps[i].FixedName); } } + + //mxd + private void CheckHash() + { + // Open the file stream + FileStream fs = File.Open(filename, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite); + + // Empty file can't be official iwad + if(fs.Length > 4) + { + BinaryReader r = new BinaryReader(fs, ENCODING); + + // Read WAD type + if(ENCODING.GetString(r.ReadBytes(4)) == TYPE_IWAD) + { + // Rewind + r.BaseStream.Position = 0; + + // Check hash + MD5 hasher = MD5.Create(); + byte[] data = hasher.ComputeHash(r.BaseStream); + + // Create a new Stringbuilder to collect the bytes and create a string. + StringBuilder hash = new StringBuilder(); + + // Loop through each byte of the hashed data and format each one as a hexadecimal string. + for(int i = 0; i < data.Length; i++) + { + hash.Append(data[i].ToString("x2")); + } + + isofficialiwad = IWAD_HASHES.Contains(hash.ToString()); + if(!isreadonly && isofficialiwad) isreadonly = true; + } + + // Close the reader + r.Close(); + } + + // Close the file + fs.Dispose(); + } // This flushes writing changes /*public void Flush() diff --git a/Source/Core/VisualModes/VisualMode.cs b/Source/Core/VisualModes/VisualMode.cs index d1425d1bf8898b841a9b549beda4e54c04bee8ca..7fc1aaf2502ef4b76990993711f533650ef7e7be 100644 --- a/Source/Core/VisualModes/VisualMode.cs +++ b/Source/Core/VisualModes/VisualMode.cs @@ -1099,7 +1099,6 @@ namespace CodeImp.DoomBuilder.VisualModes /// <summary> /// While this mode is active, this is called continuously to process whatever needs processing. /// </summary> - public override void OnProcess(float deltatime) { OnProcess((long)deltatime); } //mxd. DB2 compatibility public override void OnProcess(long deltatime) { base.OnProcess(deltatime); diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs index 4fa53e370b7350ff5f6d7daeeda2a61396a93543..c7f4204da741860b598235054a4f78ca93eb7e62 100644 --- a/Source/Core/Windows/MainForm.cs +++ b/Source/Core/Windows/MainForm.cs @@ -4182,12 +4182,13 @@ namespace CodeImp.DoomBuilder.Windows // Update ignored revision number General.Settings.IgnoredRemoteRevision = (form.IgnoreThisUpdate ? remoterev : 0); - if(result == DialogResult.OK && General.AskSaveMap()) + if(result == DialogResult.OK) { - // Launch the updater - Process.Start(Path.Combine(General.AppPath, "Updater.exe"), "-rev " + remoterev); + // Updater will be launched from General.Terminate + General.PendingUpdateRev = remoterev; // Close + General.WriteLogLine("Initiating shutdown due to update request..."); General.Exit(true); } } diff --git a/Source/Core/Windows/OpenMapOptionsForm.cs b/Source/Core/Windows/OpenMapOptionsForm.cs index 48139db147b3db8a2805b876d8465778600becca..8d90ed296b74e888ca74d8546708beadffcffa85 100644 --- a/Source/Core/Windows/OpenMapOptionsForm.cs +++ b/Source/Core/Windows/OpenMapOptionsForm.cs @@ -446,7 +446,7 @@ namespace CodeImp.DoomBuilder.Windows } // Check if we should warn the user for missing resources - if((wadfile.Type != WAD.TYPE_IWAD) && (locations.Count == 0) && (configinfo.Resources.Count == 0)) + if((!wadfile.IsIWAD) && (locations.Count == 0) && (configinfo.Resources.Count == 0)) { if(MessageBox.Show(this, "You are about to load a map without selecting any resources. Textures, flats and " + "sprites may not be shown correctly or may not show up at all. Do you want to continue?", Application.ProductName, diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawCurveMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawCurveMode.cs index 55dca5660f7f4fd3f9042932a8ee48102cfa9c97..330e1276ad83470140fedfc2ddb172545f8c4367 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawCurveMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawCurveMode.cs @@ -183,7 +183,7 @@ namespace CodeImp.DoomBuilder.BuilderModes General.Map.UndoRedo.CreateUndo("Curve draw"); // Make an analysis and show info - string[] adjectives = new[] + string[] adjectives = { "beautiful", "lovely", "romantic", "stylish", "cheerful", "comical", "awesome", "accurate", "adorable", "adventurous", "attractive", "cute", @@ -197,27 +197,23 @@ namespace CodeImp.DoomBuilder.BuilderModes List<DrawnVertex> verts = new List<DrawnVertex>(); - //if we have a curve... + // If we have a curve... if(points.Count > 2) { - //is it a closed curve? - int lastPoint; - if(points[0].pos == points[points.Count - 1].pos) - { - lastPoint = curve.Segments.Count; - } + // Is it an (auto)closed curve? + int lastpoint; + if(drawingautoclosed || points[0].pos == points[points.Count - 1].pos) + lastpoint = curve.Segments.Count; else - { - lastPoint = curve.Segments.Count - 1; - } + lastpoint = curve.Segments.Count - 1; - for(int i = 0; i < lastPoint; i++) + for(int i = 0; i < lastpoint; i++) { int next = (i == curve.Segments.Count - 1 ? 0 : i + 1); bool stitch = points[i].stitch && points[next].stitch; bool stitchline = points[i].stitchline && points[next].stitchline; - //add segment points except the last one + // Add segment points except the last one for(int c = 0; c < curve.Segments[i].Points.Length - 1; c++) { DrawnVertex dv = new DrawnVertex(); @@ -228,9 +224,9 @@ namespace CodeImp.DoomBuilder.BuilderModes } } - //add last point + // Add the last point DrawnVertex end = new DrawnVertex(); - end.pos = curve.Segments[lastPoint - 1].End; + end.pos = curve.Segments[lastpoint - 1].End; end.stitch = verts[verts.Count - 1].stitch; end.stitchline = verts[verts.Count - 1].stitchline; verts.Add(end); @@ -283,6 +279,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Reset settings points.Clear(); labels.Clear(); + drawingautoclosed = false; // Redraw display General.Interface.RedrawDisplay(); @@ -319,9 +316,11 @@ namespace CodeImp.DoomBuilder.BuilderModes panel.SegmentLength = segmentlength; panel.OnValueChanged += OptionsPanelOnValueChanged; panel.OnContinuousDrawingChanged += OnContinuousDrawingChanged; + panel.OnAutoCloseDrawingChanged += OnAutoCloseDrawingChanged; - // Needs to be set after adding the OnContinuousDrawingChanged event... + // Needs to be set after adding the events... panel.ContinuousDrawing = General.Settings.ReadPluginSetting("drawcurvemode.continuousdrawing", false); + panel.AutoCloseDrawing = General.Settings.ReadPluginSetting("drawlinesmode.autoclosedrawing", false); } protected override void AddInterface() @@ -334,6 +333,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Store settings General.Settings.WritePluginSetting("drawcurvemode.segmentlength", segmentlength); General.Settings.WritePluginSetting("drawcurvemode.continuousdrawing", panel.ContinuousDrawing); + General.Settings.WritePluginSetting("drawlinesmode.autoclosedrawing", panel.AutoCloseDrawing); // Remove the buttons panel.Unregister(); diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawEllipseMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawEllipseMode.cs index b704ab8269ef760d65f7d37b89b626addc836ca9..2e836bd9ac16f4e19d37efc49f5309adaec25adb 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawEllipseMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawEllipseMode.cs @@ -1,6 +1,8 @@ #region ================== Namespaces using System; +using System.Collections.Generic; +using CodeImp.DoomBuilder.Actions; using CodeImp.DoomBuilder.Editing; using CodeImp.DoomBuilder.Geometry; @@ -20,17 +22,22 @@ namespace CodeImp.DoomBuilder.BuilderModes public class DrawEllipseMode : DrawRectangleMode { #region ================== Variables - - // Drawing - private float angle; // in radians // Interface private DrawEllipseOptionsPanel panel; + // Drawing + private float angle; // in radians + #endregion #region ================== Constructor + public DrawEllipseMode() + { + autoclosedrawing = false; + } + #endregion #region ================== Settings panel @@ -135,9 +142,14 @@ namespace CodeImp.DoomBuilder.BuilderModes return shape; } - protected override string GetHintText() + protected override string GetHintText() { - return "BVL: " + bevelwidth + "; VERTS: " + subdivisions; + List<string> result = new List<string>(); + if(bevelwidth != 0) result.Add("BVL: " + bevelwidth); + if(subdivisions != 0) result.Add("VERTS: " + subdivisions); + if(panel.Angle != 0) result.Add("ANGLE: " + panel.Angle); + + return string.Join("; ", result.ToArray()); } #endregion @@ -229,6 +241,22 @@ namespace CodeImp.DoomBuilder.BuilderModes } } + [BeginAction("rotateclockwise")] + private void IncreaseAngle() + { + panel.Angle = General.ClampAngle(panel.Angle + 5); + angle = Angle2D.DegToRad(panel.Angle); + Update(); + } + + [BeginAction("rotatecounterclockwise")] + private void DecreaseAngle() + { + panel.Angle = General.ClampAngle(panel.Angle - 5); + angle = Angle2D.DegToRad(panel.Angle); + Update(); + } + #endregion } } diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs index fb3498bcc5eec5bebc1d981589bd9f9074ed4920..a4f81918ae2620fb2bb4b5ff4b891d0282e9a612 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs @@ -66,6 +66,8 @@ namespace CodeImp.DoomBuilder.BuilderModes protected bool snaptocardinaldirection; //mxd. ALT-SHIFT to enable protected static bool usefourcardinaldirections; protected bool continuousdrawing; //mxd. Restart after finishing drawing? + protected bool autoclosedrawing; //mxd. Finish drawing when new points and existing geometry form a closed shape + protected bool drawingautoclosed; //mxd //mxd. Labels display style protected bool labelshowangle = true; @@ -428,28 +430,125 @@ namespace CodeImp.DoomBuilder.BuilderModes labels.Add(new LineLengthLabel(labelshowangle, labeluseoffset)); Update(); - // Check if point stitches with the first - if((points.Count > 1) && points[points.Count - 1].stitch) + if(points.Count > 1) { - Vector2D p1 = points[0].pos; - Vector2D p2 = points[points.Count - 1].pos; - Vector2D delta = p1 - p2; - if((Math.Abs(delta.x) <= 0.001f) && (Math.Abs(delta.y) <= 0.001f)) + // Check if point stitches with the first + if(points[points.Count - 1].stitch) { - //mxd. Seems... logical? - if(points.Count == 2) + Vector2D p1 = points[0].pos; + Vector2D p2 = points[points.Count - 1].pos; + Vector2D delta = p1 - p2; + if((Math.Abs(delta.x) <= 0.001f) && (Math.Abs(delta.y) <= 0.001f)) { - OnCancel(); + //mxd. Seems... logical? + if(points.Count == 2) + { + OnCancel(); + return true; + } + + // Finish drawing + FinishDraw(); return true; } + } + + //mxd. Points and existing geometry form a closed shape? + if(continuousdrawing && autoclosedrawing) + { + // Determive center point + float minx = float.MaxValue; + float maxx = float.MinValue; + float miny = float.MaxValue; + float maxy = float.MinValue; + + foreach(DrawnVertex v in points) + { + if(v.pos.x < minx) minx = v.pos.x; + if(v.pos.x > maxx) maxx = v.pos.x; + if(v.pos.y < miny) miny = v.pos.y; + if(v.pos.y > maxy) maxy = v.pos.y; + } + + Vector2D shapecenter = new Vector2D(minx + (maxx - minx) / 2, miny + (maxy - miny) / 2); - // Finish drawing - FinishDraw(); + // Determine center point between start and end points + minx = Math.Min(points[0].pos.x, points[points.Count - 1].pos.x); + maxx = Math.Max(points[0].pos.x, points[points.Count - 1].pos.x); + miny = Math.Min(points[0].pos.y, points[points.Count - 1].pos.y); + maxy = Math.Max(points[0].pos.y, points[points.Count - 1].pos.y); + + Vector2D startendcenter = new Vector2D(minx + (maxx - minx) / 2, miny + (maxy - miny) / 2); + + // Offset the center perpendicular to the start -> end line direction... + if(shapecenter == startendcenter) + { + shapecenter -= new Line2D(points[0].pos, points[points.Count - 1].pos).GetPerpendicular().GetNormal(); + } + + // Do the check + if(CanFinishDrawing(points[0].pos, points[points.Count - 1].pos, shapecenter)) + { + drawingautoclosed = true; + FinishDraw(); + } } } return true; } + + //mxd + private static bool CanFinishDrawing(Vector2D start, Vector2D end, Vector2D center) + { + Linedef startline = FindPotentialLine(start, center); + if(startline == null) return false; + + Linedef endline = FindPotentialLine(end, center); + if(endline == null) return false; + + // Can finish drawing if a path between startline and endline exists + return Tools.FindClosestPath(startline, startline.SideOfLine(center) < 0.0f, endline, endline.SideOfLine(center) < 0.0f, true) != null; + } + + //mxd + private static Linedef FindPotentialLine(Vector2D target, Vector2D center) + { + // Target position on top of existing vertex? + Vertex v = General.Map.Map.NearestVertex(target); + if(v == null) return null; + + Linedef result = null; + if(v.Position == target) + { + float mindistance = float.MaxValue; + foreach(Linedef l in v.Linedefs) + { + if(result == null) + { + result = l; + mindistance = Vector2D.DistanceSq(l.GetCenterPoint(), center); + } + else + { + float curdistance = Vector2D.DistanceSq(l.GetCenterPoint(), center); + if(curdistance < mindistance) + { + mindistance = curdistance; + result = l; + } + } + } + } + else + { + // Result position will split a line? + result = General.Map.Map.NearestLinedef(target); + if(result.DistanceTo(target, true) > BuilderPlug.Me.StitchRange) return null; + } + + return result; + } #endregion @@ -460,9 +559,11 @@ namespace CodeImp.DoomBuilder.BuilderModes //Add options docker panel = new DrawLineOptionsPanel(); panel.OnContinuousDrawingChanged += OnContinuousDrawingChanged; + panel.OnAutoCloseDrawingChanged += OnAutoCloseDrawingChanged; - // Needs to be set after adding the OnContinuousDrawingChanged event... + // Needs to be set after adding the events... panel.ContinuousDrawing = General.Settings.ReadPluginSetting("drawlinesmode.continuousdrawing", false); + panel.AutoCloseDrawing = General.Settings.ReadPluginSetting("drawlinesmode.autoclosedrawing", false); } protected virtual void AddInterface() @@ -473,6 +574,7 @@ namespace CodeImp.DoomBuilder.BuilderModes protected virtual void RemoveInterface() { General.Settings.WritePluginSetting("drawlinesmode.continuousdrawing", panel.ContinuousDrawing); + General.Settings.WritePluginSetting("drawlinesmode.autoclosedrawing", panel.AutoCloseDrawing); panel.Unregister(); } @@ -509,7 +611,11 @@ namespace CodeImp.DoomBuilder.BuilderModes public override void OnCancel() { //mxd. Cannot leave this way when continuous drawing is enabled - if(continuousdrawing) return; + if(continuousdrawing) + { + drawingautoclosed = false; + return; + } // Cancel base class base.OnCancel(); @@ -584,6 +690,7 @@ namespace CodeImp.DoomBuilder.BuilderModes //mxd. Reset settings points.Clear(); labels.Clear(); + drawingautoclosed = false; //mxd. Redraw display General.Interface.RedrawDisplay(); @@ -650,6 +757,12 @@ namespace CodeImp.DoomBuilder.BuilderModes { continuousdrawing = (bool)value; } + + //mxd + protected void OnAutoCloseDrawingChanged(object value, EventArgs e) + { + autoclosedrawing = (bool)value; + } #endregion diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawGridMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawGridMode.cs index aef069b89c015282ba8d3705e2dc8192b5812d0b..c12b33cf1df13d8d298992a949baaffb8dbcf858 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawGridMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawGridMode.cs @@ -72,6 +72,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { snaptogrid = true; usefourcardinaldirections = true; + autoclosedrawing = false; gridpoints = new List<DrawnVertex[]>(); } @@ -144,6 +145,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Reset settings points.Clear(); labels.Clear(); + drawingautoclosed = false; // Redraw display General.Interface.RedrawDisplay(); diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawRectangleMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawRectangleMode.cs index df3a0125fc55a609623f62b502673c94d9543a85..9ac19f3868af64818bed4af7be8d196b72e5d013 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawRectangleMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawRectangleMode.cs @@ -58,6 +58,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { snaptogrid = true; usefourcardinaldirections = true; + autoclosedrawing = false; } public override void Dispose() @@ -263,9 +264,13 @@ namespace CodeImp.DoomBuilder.BuilderModes return points; } - protected virtual string GetHintText() + protected virtual string GetHintText() { - return "BVL: " + bevelwidth + "; SUB: " + subdivisions; + List<string> result = new List<string>(); + if(bevelwidth != 0) result.Add("BVL: " + bevelwidth); + if(subdivisions != 0) result.Add("SUB: " + subdivisions); + + return string.Join("; ", result.ToArray()); } // Update top-left and bottom-right points, which define drawing shape @@ -362,7 +367,7 @@ namespace CodeImp.DoomBuilder.BuilderModes General.Map.UndoRedo.CreateUndo(undoname); // Make an analysis and show info - string[] adjectives = new[] { "gloomy", "sad", "unhappy", "lonely", "troubled", "depressed", "heartsick", "glum", "pessimistic", "bitter", "downcast" }; // aaand my english vocabulary ends here :) + string[] adjectives = { "gloomy", "sad", "unhappy", "lonely", "troubled", "depressed", "heartsick", "glum", "pessimistic", "bitter", "downcast" }; // aaand my english vocabulary ends here :) string word = adjectives[new Random().Next(adjectives.Length - 1)]; string a = (word[0] == 'u' ? "an " : "a "); @@ -411,6 +416,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Reset settings points.Clear(); labels.Clear(); + drawingautoclosed = false; // Redraw display General.Interface.RedrawDisplay(); diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs index 2d3906423dac15249349310ed8b1413b59bff900..2f09d0437b7d6219ba2000a3ca2dc63683a66886 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs @@ -1290,63 +1290,122 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Any selected lines? - if(selected.Count > 0) + if(selected.Count == 0) { - // Make undo - if(selected.Count > 1) - { - General.Map.UndoRedo.CreateUndo("Flip " + selected.Count + " linedefs"); - General.Interface.DisplayStatus(StatusType.Action, "Flipped " + selected.Count + " linedefs."); - } - else - { - General.Map.UndoRedo.CreateUndo("Flip linedef"); - General.Interface.DisplayStatus(StatusType.Action, "Flipped a linedef."); - } + General.Interface.DisplayStatus(StatusType.Warning, "This action requires a selection!"); + return; + } - //mxd. Do it sector-wise - Dictionary<Sector, int> sectors = new Dictionary<Sector, int>(); + // Make undo + if(selected.Count > 1) + { + General.Map.UndoRedo.CreateUndo("Flip " + selected.Count + " linedefs"); + General.Interface.DisplayStatus(StatusType.Action, "Flipped " + selected.Count + " linedefs."); + } + else + { + General.Map.UndoRedo.CreateUndo("Flip linedef"); + General.Interface.DisplayStatus(StatusType.Action, "Flipped a linedef."); + } - foreach(Linedef l in selected) + // Flip all selected linedefs + foreach(Linedef l in selected) + { + l.FlipVertices(); + l.FlipSidedefs(); + } + + // Remove selection if only one linedef was selected + if(selected.Count == 1) + { + foreach(Linedef ld in selected) ld.Selected = false; + selected.Clear(); + } + + // Redraw + General.Map.Map.Update(); + General.Map.IsChanged = true; + General.Interface.RefreshInfo(); + General.Interface.RedrawDisplay(); + } + + [BeginAction("alignlinedefs")] + public void AlignLinedefs() //mxd + { + // No selected lines? + ICollection<Linedef> selected = General.Map.Map.GetSelectedLinedefs(true); + if(selected.Count == 0) + { + // Anything highlighted? + if(highlighted != null) { - if(l.Front != null && l.Front.Sector != null) - { - if(!sectors.ContainsKey(l.Front.Sector)) sectors.Add(l.Front.Sector, 0); - sectors[l.Front.Sector]++; - } - - if(l.Back != null && l.Back.Sector != null) - { - if(!sectors.ContainsKey(l.Back.Sector)) sectors.Add(l.Back.Sector, 0); - sectors[l.Back.Sector]++; - } + // Select the highlighted item + highlighted.Selected = true; + selected.Add(highlighted); } + } - //mxd. Sort the collection so sectors with the most selected linedefs go first - List<KeyValuePair<Sector, int>> sortedlist = sectors.ToList(); - sortedlist.Sort((firstPair, nextPair) => firstPair.Value.CompareTo(nextPair.Value)); - sortedlist.Reverse(); + // Any selected lines? + if(selected.Count == 0) + { + General.Interface.DisplayStatus(StatusType.Warning, "This action requires a selection!"); + return; + } - //mxd. Gather our ordered sectors - List<Sector> sectorslist = new List<Sector>(sortedlist.Count()); - sectorslist.AddRange(sortedlist.Select(pair => pair.Key)); + // Make undo + if(selected.Count > 1) + { + General.Map.UndoRedo.CreateUndo("Align " + selected.Count + " linedefs"); + General.Interface.DisplayStatus(StatusType.Action, "Aligned " + selected.Count + " linedefs."); + } + else + { + General.Map.UndoRedo.CreateUndo("Align linedef"); + General.Interface.DisplayStatus(StatusType.Action, "Aligned a linedef."); + } - //mxd. Flip the lines - Tools.FlipSectorLinedefs(sectorslist, true); + //mxd. Do it sector-wise + Dictionary<Sector, int> sectors = new Dictionary<Sector, int>(); - // Remove selection if only one linedef was selected - if(selected.Count == 1) + foreach(Linedef l in selected) + { + if(l.Front != null && l.Front.Sector != null) { - foreach(Linedef ld in selected) ld.Selected = false; - selected.Clear(); + if(!sectors.ContainsKey(l.Front.Sector)) sectors.Add(l.Front.Sector, 0); + sectors[l.Front.Sector]++; } + + if(l.Back != null && l.Back.Sector != null) + { + if(!sectors.ContainsKey(l.Back.Sector)) sectors.Add(l.Back.Sector, 0); + sectors[l.Back.Sector]++; + } + } - // Redraw - General.Map.Map.Update(); - General.Map.IsChanged = true; - General.Interface.RefreshInfo(); - General.Interface.RedrawDisplay(); + //mxd. Sort the collection so sectors with the most selected linedefs go first + List<KeyValuePair<Sector, int>> sortedlist = sectors.ToList(); + sortedlist.Sort((firstPair, nextPair) => firstPair.Value.CompareTo(nextPair.Value)); + sortedlist.Reverse(); + + //mxd. Gather our ordered sectors + List<Sector> sectorslist = new List<Sector>(sortedlist.Count()); + sectorslist.AddRange(sortedlist.Select(pair => pair.Key)); + + //mxd. Flip the lines + Tools.FlipSectorLinedefs(sectorslist, true); + + // Remove selection if only one linedef was selected + if(selected.Count == 1) + { + foreach(Linedef ld in selected) ld.Selected = false; + selected.Clear(); } + + // Redraw + General.Map.Map.Update(); + General.Map.IsChanged = true; + General.Interface.RefreshInfo(); + General.Interface.RedrawDisplay(); } [BeginAction("flipsidedefs")] @@ -1363,6 +1422,13 @@ namespace CodeImp.DoomBuilder.BuilderModes } } + //mxd. Any selected lines? + if(selected.Count == 0) + { + General.Interface.DisplayStatus(StatusType.Warning, "This action requires a selection!"); + return; + } + //mxd. Do this only with double-sided linedefs List<Linedef> validlines = new List<Linedef>(); foreach(Linedef l in selected) @@ -1370,39 +1436,38 @@ namespace CodeImp.DoomBuilder.BuilderModes if(l.Front != null && l.Back != null) validlines.Add(l); } - // Any selected lines? - if(validlines.Count > 0) + //mxd. Any double-sided lines selected? + if(validlines.Count == 0) { - // Make undo - if(validlines.Count > 1) - { - General.Map.UndoRedo.CreateUndo("Flip " + validlines.Count + " sidedefs"); - General.Interface.DisplayStatus(StatusType.Action, "Flipped " + validlines.Count + " sidedefs."); - } - else - { - General.Map.UndoRedo.CreateUndo("Flip sidedef"); - General.Interface.DisplayStatus(StatusType.Action, "Flipped a sidedef."); - } + General.Interface.DisplayStatus(StatusType.Warning, "No sidedefs to flip! Only 2-sided linedefs can be flipped."); + return; + } - // Flip sidedefs in all selected linedefs - foreach(Linedef l in validlines) - { - l.FlipSidedefs(); - l.Front.Sector.UpdateNeeded = true; - l.Back.Sector.UpdateNeeded = true; - } + // Make undo + if(validlines.Count > 1) + { + General.Map.UndoRedo.CreateUndo("Flip " + validlines.Count + " sidedefs"); + General.Interface.DisplayStatus(StatusType.Action, "Flipped " + validlines.Count + " sidedefs."); + } + else + { + General.Map.UndoRedo.CreateUndo("Flip sidedef"); + General.Interface.DisplayStatus(StatusType.Action, "Flipped a sidedef."); + } - // Redraw - General.Map.Map.Update(); - General.Map.IsChanged = true; - General.Interface.RefreshInfo(); - General.Interface.RedrawDisplay(); - } - else + // Flip sidedefs in all selected linedefs + foreach(Linedef l in validlines) { - General.Interface.DisplayStatus(StatusType.Warning, "No sidedefs to flip (only 2-sided linedefs can be flipped)!"); + l.FlipSidedefs(); + l.Front.Sector.UpdateNeeded = true; + l.Back.Sector.UpdateNeeded = true; } + + // Redraw + General.Map.Map.Update(); + General.Map.IsChanged = true; + General.Interface.RefreshInfo(); + General.Interface.RedrawDisplay(); } //mxd. Make gradient brightness diff --git a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs index 03e6a3ccc739a943ded664fbdc1e79f47c5be706..776cd1da81460a6c0ccec511cb10a6b8acf33d01 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs @@ -2411,6 +2411,57 @@ namespace CodeImp.DoomBuilder.BuilderModes //mxd [BeginAction("fliplinedefs")] public void FlipLinedefs() + { + // Get selection + ICollection<Sector> selected = General.Map.Map.GetSelectedSectors(true); + + if(selected.Count == 0 && highlighted != null && !highlighted.IsDisposed) + selected.Add(highlighted); + + if(selected.Count == 0) + { + General.Interface.DisplayStatus(StatusType.Warning, "This action requires a selection!"); + return; + } + + // Make undo + if(selected.Count > 1) + { + General.Map.UndoRedo.CreateUndo("Align linedefs of " + selected.Count + " sectors"); + General.Interface.DisplayStatus(StatusType.Action, "Aligned linedefs of " + selected.Count + "sectors."); + } + else + { + General.Map.UndoRedo.CreateUndo("Align sector linedefs"); + General.Interface.DisplayStatus(StatusType.Action, "Aligned sector linedefs."); + } + + HashSet<Linedef> selectedlines = new HashSet<Linedef>(); + foreach(Sector s in selected) + { + foreach(Sidedef side in s.Sidedefs) + { + if(!selectedlines.Contains(side.Line)) selectedlines.Add(side.Line); + } + } + + // Flip all selected linedefs + foreach(Linedef l in selectedlines) + { + l.FlipVertices(); + l.FlipSidedefs(); + } + + // Redraw + General.Map.Map.Update(); + General.Map.IsChanged = true; + General.Interface.RefreshInfo(); + General.Interface.RedrawDisplay(); + } + + //mxd + [BeginAction("alignlinedefs")] + public void AlignLinedefs() { // Get selection ICollection<Sector> selection = General.Map.Map.GetSelectedSectors(true); @@ -2427,13 +2478,13 @@ namespace CodeImp.DoomBuilder.BuilderModes // Make undo if(selection.Count > 1) { - General.Map.UndoRedo.CreateUndo("Flip linedefs of " + selection.Count + " sectors"); - General.Interface.DisplayStatus(StatusType.Action, "Flipped linedefs of " + selection.Count + "sectors."); + General.Map.UndoRedo.CreateUndo("Align linedefs of " + selection.Count + " sectors"); + General.Interface.DisplayStatus(StatusType.Action, "Aligned linedefs of " + selection.Count + "sectors."); } else { - General.Map.UndoRedo.CreateUndo("Flip sector linedefs"); - General.Interface.DisplayStatus(StatusType.Action, "Flipped sector linedefs."); + General.Map.UndoRedo.CreateUndo("Align sector linedefs"); + General.Interface.DisplayStatus(StatusType.Action, "Aligned sector linedefs."); } // Flip lines diff --git a/Source/Plugins/BuilderModes/Interface/DrawCurveOptionsPanel.Designer.cs b/Source/Plugins/BuilderModes/Interface/DrawCurveOptionsPanel.Designer.cs index 901edbb781f5a107c5286278cb19e261d2b47367..853cf270d22a1304350d3f9671b676e78f1ce685 100644 --- a/Source/Plugins/BuilderModes/Interface/DrawCurveOptionsPanel.Designer.cs +++ b/Source/Plugins/BuilderModes/Interface/DrawCurveOptionsPanel.Designer.cs @@ -29,11 +29,12 @@ private void InitializeComponent() { this.toolstrip = new System.Windows.Forms.ToolStrip(); + this.continuousdrawing = new System.Windows.Forms.ToolStripButton(); + this.autoclosedrawing = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.seglabel = new System.Windows.Forms.ToolStripLabel(); this.seglen = new CodeImp.DoomBuilder.Controls.ToolStripNumericUpDown(); this.reset = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.continuousdrawing = new System.Windows.Forms.ToolStripButton(); this.toolstrip.SuspendLayout(); this.SuspendLayout(); // @@ -41,16 +42,43 @@ // this.toolstrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.continuousdrawing, + this.autoclosedrawing, this.toolStripSeparator1, this.seglabel, this.seglen, this.reset}); this.toolstrip.Location = new System.Drawing.Point(0, 0); this.toolstrip.Name = "toolstrip"; - this.toolstrip.Size = new System.Drawing.Size(320, 25); + this.toolstrip.Size = new System.Drawing.Size(562, 25); this.toolstrip.TabIndex = 7; this.toolstrip.Text = "toolStrip1"; // + // continuousdrawing + // + this.continuousdrawing.CheckOnClick = true; + this.continuousdrawing.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Repeat; + this.continuousdrawing.ImageTransparentColor = System.Drawing.Color.Magenta; + this.continuousdrawing.Name = "continuousdrawing"; + this.continuousdrawing.Size = new System.Drawing.Size(135, 22); + this.continuousdrawing.Text = "Continuous drawing"; + this.continuousdrawing.CheckedChanged += new System.EventHandler(this.continuousdrawing_CheckedChanged); + // + // autoclosedrawing + // + this.autoclosedrawing.CheckOnClick = true; + this.autoclosedrawing.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.NewSector2; + this.autoclosedrawing.ImageTransparentColor = System.Drawing.Color.Magenta; + this.autoclosedrawing.Margin = new System.Windows.Forms.Padding(2, 1, 0, 2); + this.autoclosedrawing.Name = "autoclosedrawing"; + this.autoclosedrawing.Size = new System.Drawing.Size(131, 22); + this.autoclosedrawing.Text = "Auto-close drawing"; + this.autoclosedrawing.CheckedChanged += new System.EventHandler(this.autoclosedrawing_CheckedChanged); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // // seglabel // this.seglabel.Name = "seglabel"; @@ -87,32 +115,17 @@ this.reset.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Reset; this.reset.ImageTransparentColor = System.Drawing.Color.Magenta; this.reset.Name = "reset"; - this.reset.Size = new System.Drawing.Size(23, 20); + this.reset.Size = new System.Drawing.Size(23, 22); this.reset.Text = "Reset"; this.reset.Click += new System.EventHandler(this.reset_Click); // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); - // - // continuousdrawing - // - this.continuousdrawing.CheckOnClick = true; - this.continuousdrawing.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Repeat; - this.continuousdrawing.ImageTransparentColor = System.Drawing.Color.Magenta; - this.continuousdrawing.Name = "continuousdrawing"; - this.continuousdrawing.Size = new System.Drawing.Size(135, 22); - this.continuousdrawing.Text = "Continuous drawing"; - this.continuousdrawing.CheckedChanged += new System.EventHandler(this.continuousdrawing_CheckedChanged); - // // DrawCurveOptionsPanel // this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.Controls.Add(this.toolstrip); this.Name = "DrawCurveOptionsPanel"; - this.Size = new System.Drawing.Size(320, 60); + this.Size = new System.Drawing.Size(562, 60); this.toolstrip.ResumeLayout(false); this.toolstrip.PerformLayout(); this.ResumeLayout(false); @@ -128,6 +141,7 @@ private System.Windows.Forms.ToolStripButton reset; private System.Windows.Forms.ToolStripButton continuousdrawing; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripButton autoclosedrawing; } } diff --git a/Source/Plugins/BuilderModes/Interface/DrawCurveOptionsPanel.cs b/Source/Plugins/BuilderModes/Interface/DrawCurveOptionsPanel.cs index 4d751f231baac81a49dddab54ec6b5aa0fe04a1f..5dd68f10e8cb8c079fa18c9a2b6fcfd25992808f 100644 --- a/Source/Plugins/BuilderModes/Interface/DrawCurveOptionsPanel.cs +++ b/Source/Plugins/BuilderModes/Interface/DrawCurveOptionsPanel.cs @@ -7,10 +7,12 @@ namespace CodeImp.DoomBuilder.BuilderModes { public event EventHandler OnValueChanged; public event EventHandler OnContinuousDrawingChanged; + public event EventHandler OnAutoCloseDrawingChanged; private bool blockevents; public int SegmentLength { get { return (int)seglen.Value; } set { blockevents = true; seglen.Value = value; blockevents = false; } } public bool ContinuousDrawing { get { return continuousdrawing.Checked; } set { continuousdrawing.Checked = value; } } + public bool AutoCloseDrawing { get { return autoclosedrawing.Checked; } set { autoclosedrawing.Checked = value; } } public DrawCurveOptionsPanel(int minLength, int maxLength) { @@ -25,6 +27,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public void Register() { General.Interface.AddButton(continuousdrawing); + General.Interface.AddButton(autoclosedrawing); General.Interface.AddButton(toolStripSeparator1); General.Interface.AddButton(seglabel); General.Interface.AddButton(seglen); @@ -37,6 +40,7 @@ namespace CodeImp.DoomBuilder.BuilderModes General.Interface.RemoveButton(seglen); General.Interface.RemoveButton(seglabel); General.Interface.RemoveButton(toolStripSeparator1); + General.Interface.RemoveButton(autoclosedrawing); General.Interface.RemoveButton(continuousdrawing); } @@ -54,5 +58,10 @@ namespace CodeImp.DoomBuilder.BuilderModes { if(OnContinuousDrawingChanged != null) OnContinuousDrawingChanged(continuousdrawing.Checked, EventArgs.Empty); } + + private void autoclosedrawing_CheckedChanged(object sender, EventArgs e) + { + if(OnAutoCloseDrawingChanged != null) OnAutoCloseDrawingChanged(autoclosedrawing.Checked, EventArgs.Empty); + } } } diff --git a/Source/Plugins/BuilderModes/Interface/DrawLineOptionsPanel.Designer.cs b/Source/Plugins/BuilderModes/Interface/DrawLineOptionsPanel.Designer.cs index af61aca311e5b07ea8b810d3f9afb9df4a254465..88f1ada0ca54ac0da0ed232837d468eb28441ad4 100644 --- a/Source/Plugins/BuilderModes/Interface/DrawLineOptionsPanel.Designer.cs +++ b/Source/Plugins/BuilderModes/Interface/DrawLineOptionsPanel.Designer.cs @@ -30,16 +30,18 @@ { this.toolStrip1 = new System.Windows.Forms.ToolStrip(); this.continuousdrawing = new System.Windows.Forms.ToolStripButton(); + this.autoclosedrawing = new System.Windows.Forms.ToolStripButton(); this.toolStrip1.SuspendLayout(); this.SuspendLayout(); // // toolStrip1 // this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.continuousdrawing}); + this.continuousdrawing, + this.autoclosedrawing}); this.toolStrip1.Location = new System.Drawing.Point(0, 0); this.toolStrip1.Name = "toolStrip1"; - this.toolStrip1.Size = new System.Drawing.Size(200, 25); + this.toolStrip1.Size = new System.Drawing.Size(406, 25); this.toolStrip1.TabIndex = 8; this.toolStrip1.Text = "toolStrip1"; // @@ -53,13 +55,24 @@ this.continuousdrawing.Text = "Continuous drawing"; this.continuousdrawing.CheckedChanged += new System.EventHandler(this.continuousdrawing_CheckedChanged); // + // autoclosedrawing + // + this.autoclosedrawing.CheckOnClick = true; + this.autoclosedrawing.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.NewSector2; + this.autoclosedrawing.ImageTransparentColor = System.Drawing.Color.Magenta; + this.autoclosedrawing.Margin = new System.Windows.Forms.Padding(2, 1, 0, 2); + this.autoclosedrawing.Name = "autoclosedrawing"; + this.autoclosedrawing.Size = new System.Drawing.Size(133, 22); + this.autoclosedrawing.Text = "Auto-finish drawing"; + this.autoclosedrawing.CheckedChanged += new System.EventHandler(this.autoclosedrawing_CheckedChanged); + // // DrawLineOptionsPanel // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.toolStrip1); this.Name = "DrawLineOptionsPanel"; - this.Size = new System.Drawing.Size(200, 60); + this.Size = new System.Drawing.Size(406, 60); this.toolStrip1.ResumeLayout(false); this.toolStrip1.PerformLayout(); this.ResumeLayout(false); @@ -71,5 +84,6 @@ private System.Windows.Forms.ToolStrip toolStrip1; private System.Windows.Forms.ToolStripButton continuousdrawing; + private System.Windows.Forms.ToolStripButton autoclosedrawing; } } diff --git a/Source/Plugins/BuilderModes/Interface/DrawLineOptionsPanel.cs b/Source/Plugins/BuilderModes/Interface/DrawLineOptionsPanel.cs index fbc34259572874728f491ffcfb9bb3564282c11f..776e26e4cc22b2faea1d97216fd8d3341a1bb6cf 100644 --- a/Source/Plugins/BuilderModes/Interface/DrawLineOptionsPanel.cs +++ b/Source/Plugins/BuilderModes/Interface/DrawLineOptionsPanel.cs @@ -6,8 +6,10 @@ namespace CodeImp.DoomBuilder.BuilderModes internal partial class DrawLineOptionsPanel : UserControl { public event EventHandler OnContinuousDrawingChanged; + public event EventHandler OnAutoCloseDrawingChanged; public bool ContinuousDrawing { get { return continuousdrawing.Checked; } set { continuousdrawing.Checked = value; } } + public bool AutoCloseDrawing { get { return autoclosedrawing.Checked; } set { autoclosedrawing.Checked = value; } } public DrawLineOptionsPanel() { @@ -17,10 +19,12 @@ namespace CodeImp.DoomBuilder.BuilderModes public void Register() { General.Interface.AddButton(continuousdrawing); + General.Interface.AddButton(autoclosedrawing); } public void Unregister() { + General.Interface.RemoveButton(autoclosedrawing); General.Interface.RemoveButton(continuousdrawing); } @@ -28,5 +32,10 @@ namespace CodeImp.DoomBuilder.BuilderModes { if(OnContinuousDrawingChanged != null) OnContinuousDrawingChanged(continuousdrawing.Checked, EventArgs.Empty); } + + private void autoclosedrawing_CheckedChanged(object sender, EventArgs e) + { + if(OnAutoCloseDrawingChanged != null) OnAutoCloseDrawingChanged(autoclosedrawing.Checked, EventArgs.Empty); + } } } diff --git a/Source/Plugins/BuilderModes/Interface/DrawRectangleOptionsPanel.Designer.cs b/Source/Plugins/BuilderModes/Interface/DrawRectangleOptionsPanel.Designer.cs index aee62a101e19f37dfb73e2b69c4e62d20e5ce215..77d70a54eb0b537a538688b5fe1a16ecb4f9c12d 100644 --- a/Source/Plugins/BuilderModes/Interface/DrawRectangleOptionsPanel.Designer.cs +++ b/Source/Plugins/BuilderModes/Interface/DrawRectangleOptionsPanel.Designer.cs @@ -88,7 +88,6 @@ 0, 0, 0}); - this.radius.ValueChanged += new System.EventHandler(this.ValueChanged); // // subdivslabel // @@ -118,7 +117,6 @@ 0, 0, 0}); - this.subdivs.ValueChanged += new System.EventHandler(this.ValueChanged); // // continuousdrawing // diff --git a/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs b/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs index 9e99436971432969b1e27cc65efe477a23663650..07d52c057509cd41f1a361dd263d1dbda3619cb2 100644 --- a/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs +++ b/Source/Plugins/BuilderModes/Interface/MenusForm.Designer.cs @@ -107,6 +107,8 @@ namespace CodeImp.DoomBuilder.BuilderModes this.itemcopyprops = new System.Windows.Forms.ToolStripMenuItem(); this.itempasteprops = new System.Windows.Forms.ToolStripMenuItem(); this.itempastepropsoptions = new System.Windows.Forms.ToolStripMenuItem(); + this.alignsectorlinedefsitem = new System.Windows.Forms.ToolStripMenuItem(); + this.alignlinedefsitem = new System.Windows.Forms.ToolStripMenuItem(); this.menustrip.SuspendLayout(); this.manualstrip.SuspendLayout(); this.fileMenuStrip.SuspendLayout(); @@ -135,6 +137,7 @@ namespace CodeImp.DoomBuilder.BuilderModes this.selectdoublesideditem, this.toolStripMenuItem4, this.fliplinedefsitem, + this.alignlinedefsitem, this.flipsidedefsitem, this.toolStripMenuItem1, this.curvelinedefsitem, @@ -318,6 +321,7 @@ namespace CodeImp.DoomBuilder.BuilderModes this.mergesectorsitem, this.toolStripMenuItem2, this.flipsectorlinedefsitem, + this.alignsectorlinedefsitem, this.toolStripSeparator8, this.makedooritem, this.toolStripSeparator4, @@ -847,6 +851,23 @@ namespace CodeImp.DoomBuilder.BuilderModes this.itempastepropsoptions.Text = "Paste Properties Special..."; this.itempastepropsoptions.Click += new System.EventHandler(this.InvokeTaggedAction); // + // alignsectorlinedefsitem + // + this.alignsectorlinedefsitem.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Flip; + this.alignsectorlinedefsitem.Name = "alignsectorlinedefsitem"; + this.alignsectorlinedefsitem.Size = new System.Drawing.Size(224, 22); + this.alignsectorlinedefsitem.Tag = "alignlinedefs"; + this.alignsectorlinedefsitem.Text = "Align &Linedefs"; + this.alignsectorlinedefsitem.Click += new System.EventHandler(this.InvokeTaggedAction); + // + // alignlinedefsitem + // + this.alignlinedefsitem.Image = global::CodeImp.DoomBuilder.BuilderModes.Properties.Resources.Flip; + this.alignlinedefsitem.Name = "alignlinedefsitem"; + this.alignlinedefsitem.Size = new System.Drawing.Size(224, 22); + this.alignlinedefsitem.Tag = "alignlinedefs"; + this.alignlinedefsitem.Text = "Align &Linedefs"; + // // MenusForm // this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); @@ -955,5 +976,7 @@ namespace CodeImp.DoomBuilder.BuilderModes private System.Windows.Forms.ToolStripMenuItem itempasteprops; private System.Windows.Forms.ToolStripMenuItem itempastepropsoptions; private System.Windows.Forms.ToolStripSeparator separatorcopyprops; + private System.Windows.Forms.ToolStripMenuItem alignsectorlinedefsitem; + private System.Windows.Forms.ToolStripMenuItem alignlinedefsitem; } } \ No newline at end of file diff --git a/Source/Plugins/BuilderModes/Properties/Resources.Designer.cs b/Source/Plugins/BuilderModes/Properties/Resources.Designer.cs index a4739659012e9cf6f2ac1ab6e0b075884952de81..3a36fac33c6a60c8a577ca17dbb494271c6d020d 100644 --- a/Source/Plugins/BuilderModes/Properties/Resources.Designer.cs +++ b/Source/Plugins/BuilderModes/Properties/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. -// Runtime Version:2.0.50727.5485 +// Runtime Version:2.0.50727.5466 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -256,6 +256,13 @@ namespace CodeImp.DoomBuilder.BuilderModes.Properties { } } + internal static System.Drawing.Bitmap NewSector2 { + get { + object obj = ResourceManager.GetObject("NewSector2", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + internal static System.Drawing.Bitmap PasteProperties { get { object obj = ResourceManager.GetObject("PasteProperties", resourceCulture); diff --git a/Source/Plugins/BuilderModes/Properties/Resources.resx b/Source/Plugins/BuilderModes/Properties/Resources.resx index f6dd0729e20d388f55f5c65e7b6e860c3e88e302..6992badfbfe7eaaccd723f30cd93c0d12bf83c2a 100644 --- a/Source/Plugins/BuilderModes/Properties/Resources.resx +++ b/Source/Plugins/BuilderModes/Properties/Resources.resx @@ -118,6 +118,9 @@ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> + <data name="Join" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\Join.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> <data name="FloorAlign" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\FloorAlign.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> </data> @@ -136,6 +139,9 @@ <data name="ViewSelectionEffects" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\ViewSelectionEffects.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> </data> + <data name="Flip" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\Flip.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + </data> <data name="HideAll" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\HideAll.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> </data> @@ -193,9 +199,6 @@ <data name="Text" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\Text.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> </data> - <data name="Show" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\Show.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> - </data> <data name="BrightnessGradient" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\BrightnessGradient.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> </data> @@ -211,8 +214,8 @@ <data name="Reset" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\Reset.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> </data> - <data name="Join" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\Join.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + <data name="Show" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\Show.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> </data> <data name="ViewSelectionIndex" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\ViewSelectionIndex.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> @@ -229,8 +232,8 @@ <data name="ColorPick" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\ColorPick.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> </data> - <data name="Flip" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\Flip.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + <data name="Repeat" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\Repeat.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> </data> <data name="FlipSelectionH" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\FlipSelectionH.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> @@ -256,7 +259,7 @@ <data name="Show3" type="System.Resources.ResXFileRef, System.Windows.Forms"> <value>..\Resources\Show3.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> </data> - <data name="Repeat" type="System.Resources.ResXFileRef, System.Windows.Forms"> - <value>..\Resources\Repeat.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> + <data name="NewSector2" type="System.Resources.ResXFileRef, System.Windows.Forms"> + <value>..\Resources\NewSector2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> </data> </root> \ No newline at end of file diff --git a/Source/Plugins/BuilderModes/Resources/Actions.cfg b/Source/Plugins/BuilderModes/Resources/Actions.cfg index 444923fcd039f2e8397109122c0b1182e2c68c8a..04ca2188506a19e327ebf75627ff5174ebd3c162 100644 --- a/Source/Plugins/BuilderModes/Resources/Actions.cfg +++ b/Source/Plugins/BuilderModes/Resources/Actions.cfg @@ -298,6 +298,16 @@ fliplinedefs allowscroll = true; } +alignlinedefs //mxd +{ + title = "Align Linedefs"; + category = "linedefs"; + description = "This aligns the selected linedefs, so their front (or back) point towards (or away from) the same sector."; + allowkeys = true; + allowmouse = true; + allowscroll = true; +} + flipsidedefs { title = "Flip Sidedefs"; diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs index 096d6d0b473a6a90581c82cb98403963b66fd367..9eccf262f10ec063fdaf648b77367dd7fbc0544a 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs @@ -580,7 +580,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Processing - public virtual void OnProcess(float deltatime) + public virtual void OnProcess(long deltatime) { // If the texture was not loaded, but is loaded now, then re-setup geometry if(setuponloadedtexture != 0) diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs index d0623eeda069c612a939df40d2a70e361e7fbf62..8af4ca056e43dcdfc1d4ae07091f1413212a390f 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs @@ -795,7 +795,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } // Processing - public virtual void OnProcess(float deltatime) + public virtual void OnProcess(long deltatime) { // If the texture was not loaded, but is loaded now, then re-setup geometry if(setuponloadedtexture != 0) diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs index f8db38f344e423be26c2d4518fd36b6ef28f6afb..1a8434886ca8e41def7db20caa0c4da5728c638a 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs @@ -606,7 +606,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public void OnTextureAlign(bool alignx, bool aligny) { } public void OnToggleUpperUnpegged() { } public void OnToggleLowerUnpegged() { } - public void OnProcess(float deltatime) { } + public void OnProcess(long deltatime) { } public void OnTextureFloodfill() { } public void OnInsert() { } public void OnTextureFit(FitTextureOptions options) { } //mxd diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualVertex.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualVertex.cs index a0b9e5c5510cfa2cd1e1f08f16ada1bbfa38dcee..214dc9343bb5dc9522a281f00a8002d7006d108c 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualVertex.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualVertex.cs @@ -254,7 +254,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public void OnToggleLowerUnpegged() { } public void OnResetTextureOffset() { } public void OnResetLocalTextureOffset() { } //mxd - public void OnProcess(float deltatime) { } + public void OnProcess(long deltatime) { } public void OnTextureFloodfill() { } public void OnInsert() { } public void ApplyTexture(string texture) { } diff --git a/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs b/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs index c7e4467e6dd8a25c849964ac22d09803bc8e47a3..4582d5915910b1b5aa18a35258ae5c4a4ae64355 100644 --- a/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs +++ b/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs @@ -48,7 +48,7 @@ namespace CodeImp.DoomBuilder.BuilderModes void OnTextureFloodfill(); void OnToggleUpperUnpegged(); void OnToggleLowerUnpegged(); - void OnProcess(float deltatime); + void OnProcess(long deltatime); void OnInsert(); void OnDelete(); diff --git a/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs b/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs index 596d19d1fd1d81c86ef42865a83c1576f38c0302..32f8f54694c3c70ed2ed50a85f3e7d1763cf5c26 100644 --- a/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs +++ b/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs @@ -48,7 +48,7 @@ namespace CodeImp.DoomBuilder.BuilderModes public void OnTextureFloodfill() { } public void OnToggleUpperUnpegged() { } public void OnToggleLowerUnpegged() { } - public void OnProcess(float deltatime) { } + public void OnProcess(long deltatime) { } public void OnInsert() { } public void OnDelete() { } public void ApplyTexture(string texture) { }