From 7f685b4c77997074ead0c738c17640df4d5174af Mon Sep 17 00:00:00 2001 From: codeimp Date: Sun, 15 Aug 2010 19:43:00 +0000 Subject: [PATCH] Added maximum number of map element checks (now you can't corrupt your map when exceeding the format's limits) --- Source/Core/Editing/CopyPasteManager.cs | 20 +++- Source/Core/Editing/UndoManager.cs | 2 +- Source/Core/General/MapManager.cs | 28 +++++ Source/Core/Geometry/Tools.cs | 40 +++++-- Source/Core/IO/UniversalStreamReader.cs | 86 ++++++++------ Source/Core/Map/Linedef.cs | 43 ++++--- Source/Core/Map/MapSet.cs | 108 ++++++++++++++---- Source/Core/Windows/LinedefEditForm.cs | 72 +++++++----- .../ClassicModes/BaseClassicMode.cs | 30 +++-- .../ClassicModes/CurveLinedefsMode.cs | 12 +- .../ClassicModes/DrawGeometryMode.cs | 9 +- .../ClassicModes/EditSelectionMode.cs | 2 +- .../BuilderModes/ClassicModes/LinedefsMode.cs | 15 ++- .../ClassicModes/MakeSectorMode.cs | 95 ++++++++------- .../BuilderModes/ClassicModes/ThingsMode.cs | 41 ++++--- .../BuilderModes/ClassicModes/VerticesMode.cs | 25 +++- .../ErrorChecks/ResultLineMissingFront.cs | 1 + .../ErrorChecks/ResultLineMissingSides.cs | 4 + .../ErrorChecks/ResultLineNotDoubleSided.cs | 1 + 19 files changed, 433 insertions(+), 201 deletions(-) diff --git a/Source/Core/Editing/CopyPasteManager.cs b/Source/Core/Editing/CopyPasteManager.cs index 5270f8d8..e57003e4 100644 --- a/Source/Core/Editing/CopyPasteManager.cs +++ b/Source/Core/Editing/CopyPasteManager.cs @@ -289,12 +289,22 @@ namespace CodeImp.DoomBuilder.Editing if(options.ChangeTags == PasteOptions.TAGS_RENUMBER) Tools.RenumberMarkedTags(); if(options.RemoveActions) Tools.RemoveMarkedActions(); - // Done + // Clean up memstream.Dispose(); - General.Map.Map.UpdateConfiguration(); - General.Map.ThingsFilter.Update(); - General.Editing.Mode.OnPasteEnd(options.Copy()); - General.Plugins.OnPasteEnd(options); + + // Check if anything was pasted + int totalpasted = General.Map.Map.GetMarkedThings(true).Count; + totalpasted += General.Map.Map.GetMarkedVertices(true).Count; + totalpasted += General.Map.Map.GetMarkedLinedefs(true).Count; + totalpasted += General.Map.Map.GetMarkedSidedefs(true).Count; + totalpasted += General.Map.Map.GetMarkedSectors(true).Count; + if(totalpasted > 0) + { + General.Map.Map.UpdateConfiguration(); + General.Map.ThingsFilter.Update(); + General.Editing.Mode.OnPasteEnd(options.Copy()); + General.Plugins.OnPasteEnd(options); + } return true; } } diff --git a/Source/Core/Editing/UndoManager.cs b/Source/Core/Editing/UndoManager.cs index b2deb370..35498d72 100644 --- a/Source/Core/Editing/UndoManager.cs +++ b/Source/Core/Editing/UndoManager.cs @@ -571,7 +571,7 @@ namespace CodeImp.DoomBuilder.Editing General.Plugins.OnUndoWithdrawn(); } - + // This performs an undo [BeginAction("undo")] public void PerformUndo() diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs index ba8a4320..540599fa 100644 --- a/Source/Core/General/MapManager.cs +++ b/Source/Core/General/MapManager.cs @@ -501,6 +501,34 @@ namespace CodeImp.DoomBuilder return false; } } + + // Check things + if(map.Things.Count > io.MaxThings) + { + General.ShowErrorMessage("Unable to save the map: There are too many things!", MessageBoxButtons.OK); + return false; + } + + // Check sectors + if(map.Sectors.Count > io.MaxSectors) + { + General.ShowErrorMessage("Unable to save the map: There are too many sectors!", MessageBoxButtons.OK); + return false; + } + + // Check linedefs + if(map.Linedefs.Count > io.MaxLinedefs) + { + General.ShowErrorMessage("Unable to save the map: There are too many linedefs!", MessageBoxButtons.OK); + return false; + } + + // Check vertices + if(map.Vertices.Count > io.MaxVertices) + { + General.ShowErrorMessage("Unable to save the map: There are too many vertices!", MessageBoxButtons.OK); + return false; + } // TODO: Check for more limitations diff --git a/Source/Core/Geometry/Tools.cs b/Source/Core/Geometry/Tools.cs index 09f971e7..f991ed48 100644 --- a/Source/Core/Geometry/Tools.cs +++ b/Source/Core/Geometry/Tools.cs @@ -23,6 +23,7 @@ using System.Globalization; using System.Text; using CodeImp.DoomBuilder.Geometry; using CodeImp.DoomBuilder.Rendering; +using CodeImp.DoomBuilder.Windows; using SlimDX; using SlimDX.Direct3D9; using System.Drawing; @@ -453,12 +454,18 @@ namespace CodeImp.DoomBuilder.Geometry // If nearbylines is not null, then this method will find the default // properties from the nearest line in this collection when the // default properties can't be found in the alllines collection. + // Return null when no new sector could be made. public static Sector MakeSector(List alllines, List nearbylines) { - Sector newsector = General.Map.Map.CreateSector(); Sector sourcesector = null; SidedefSettings sourceside = new SidedefSettings(); bool foundsidedefaults = false; + + if(General.Map.Map.Sectors.Count >= General.Map.FormatInterface.MaxSectors) + return null; + + Sector newsector = General.Map.Map.CreateSector(); + if(newsector == null) return null; // Check if any of the sides already has a sidedef // Then we use information from that sidedef to make the others @@ -565,6 +572,7 @@ namespace CodeImp.DoomBuilder.Geometry { // Create sidedef is needed and ensure it points to the new sector if(ls.Line.Front == null) General.Map.Map.CreateSidedef(ls.Line, true, newsector); + if(ls.Line.Front == null) return null; if(ls.Line.Front.Sector != newsector) ls.Line.Front.SetSector(newsector); ApplyDefaultsToSidedef(ls.Line.Front, sourceside); } @@ -572,6 +580,7 @@ namespace CodeImp.DoomBuilder.Geometry { // Create sidedef is needed and ensure it points to the new sector if(ls.Line.Back == null) General.Map.Map.CreateSidedef(ls.Line, false, newsector); + if(ls.Line.Back == null) return null; if(ls.Line.Back.Sector != newsector) ls.Line.Back.SetSector(newsector); ApplyDefaultsToSidedef(ls.Line.Back, sourceside); } @@ -591,7 +600,7 @@ namespace CodeImp.DoomBuilder.Geometry } - // This joins a sector with the given lines and sides + // This joins a sector with the given lines and sides. Returns null when operation could not be completed. public static Sector JoinSector(List alllines, Sidedef original) { SidedefSettings sourceside = new SidedefSettings(); @@ -610,7 +619,8 @@ namespace CodeImp.DoomBuilder.Geometry // Create sidedef if needed if(ls.Line.Front == null) { - General.Map.Map.CreateSidedef(ls.Line, true, original.Sector); + Sidedef sd = General.Map.Map.CreateSidedef(ls.Line, true, original.Sector); + if(sd == null) return null; ApplyDefaultsToSidedef(ls.Line.Front, sourceside); ls.Line.ApplySidedFlags(); @@ -629,7 +639,8 @@ namespace CodeImp.DoomBuilder.Geometry // Create sidedef if needed if(ls.Line.Back == null) { - General.Map.Map.CreateSidedef(ls.Line, false, original.Sector); + Sidedef sd = General.Map.Map.CreateSidedef(ls.Line, false, original.Sector); + if(sd == null) return null; ApplyDefaultsToSidedef(ls.Line.Back, sourceside); ls.Line.ApplySidedFlags(); @@ -821,8 +832,9 @@ namespace CodeImp.DoomBuilder.Geometry /// /// This draws lines with the given points. Note that this tool removes any existing geometry /// marks and marks the new lines and vertices when done. Also marks the sectors that were added. + /// Returns false when the drawing failed. /// - public static void DrawLines(IList points) + public static bool DrawLines(IList points) { List newverts = new List(); List intersectverts = new List(); @@ -845,6 +857,7 @@ namespace CodeImp.DoomBuilder.Geometry // Make first vertex Vertex v1 = map.CreateVertex(points[0].pos); + if(v1 == null) return false; v1.Marked = true; // Keep references @@ -856,6 +869,7 @@ namespace CodeImp.DoomBuilder.Geometry { // Create vertex for point Vertex v2 = map.CreateVertex(points[i].pos); + if(v2 == null) return false; v2.Marked = true; // Keep references @@ -864,6 +878,7 @@ namespace CodeImp.DoomBuilder.Geometry // Create line between point and previous Linedef ld = map.CreateLinedef(v1, v2); + if(ld == null) return false; ld.Marked = true; ld.ApplySidedFlags(); ld.UpdateCache(); @@ -902,16 +917,18 @@ namespace CodeImp.DoomBuilder.Geometry // Make the vertex Vertex splitvertex = map.CreateVertex(splitpoint); + if(splitvertex == null) return false; splitvertex.Marked = true; newverts.Add(splitvertex); mergeverts.Add(splitvertex); // <-- add to merge? intersectverts.Add(splitvertex); - + // The Split method ties the end of the original line to the given // vertex and starts a new line at the given vertex, so continue // splitting with the new line, because the intersections are sorted // from low to high (beginning at the original line start) splitline = splitline.Split(splitvertex); + if(splitline == null) return false; splitline.ApplySidedFlags(); newlines.Add(splitline); } @@ -1116,11 +1133,13 @@ namespace CodeImp.DoomBuilder.Geometry // Make the new vertex Vertex v2 = map.CreateVertex(v2pos); + if(v2 == null) return false; v2.Marked = true; mergeverts.Add(v2); // Make the line Linedef ld = map.CreateLinedef(v1, v2); + if(ld == null) return false; ld.Marked = true; ld.ApplySidedFlags(); ld.UpdateCache(); @@ -1137,6 +1156,8 @@ namespace CodeImp.DoomBuilder.Geometry else lld = map.CreateLinedef(v1, firstline.Start); + if(lld == null) return false; + // Setup line lld.Marked = true; lld.ApplySidedFlags(); @@ -1282,6 +1303,8 @@ namespace CodeImp.DoomBuilder.Geometry { // Make the new sector Sector newsector = Tools.MakeSector(sectorlines, oldlines); + if(newsector == null) return false; + if(istruenewsector) newsector.Marked = true; // Go for all sidedefs in this new sector @@ -1354,7 +1377,8 @@ namespace CodeImp.DoomBuilder.Geometry } // Have our new lines join the existing sector - Tools.JoinSector(newsectorlines, joinsidedef); + if(Tools.JoinSector(newsectorlines, joinsidedef) == null) + return false; } } } @@ -1384,6 +1408,8 @@ namespace CodeImp.DoomBuilder.Geometry foreach(Vertex v in newverts) v.Marked = true; foreach(Linedef l in newlines) l.Marked = true; } + + return true; } #endregion diff --git a/Source/Core/IO/UniversalStreamReader.cs b/Source/Core/IO/UniversalStreamReader.cs index bd867a62..2e54b53c 100644 --- a/Source/Core/IO/UniversalStreamReader.cs +++ b/Source/Core/IO/UniversalStreamReader.cs @@ -196,10 +196,13 @@ namespace CodeImp.DoomBuilder.IO // Create new item Thing t = map.CreateThing(); - t.Update(type, x, y, height, Angle2D.DoomToReal(angledeg), stringflags, tag, special, args); + if(t != null) + { + t.Update(type, x, y, height, Angle2D.DoomToReal(angledeg), stringflags, tag, special, args); - // Custom fields - ReadCustomFields(c, t, "thing"); + // Custom fields + ReadCustomFields(c, t, "thing"); + } } } @@ -252,27 +255,30 @@ namespace CodeImp.DoomBuilder.IO if(Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f) { Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); - l.Update(stringflags, 0, tag, special, args); - l.UpdateCache(); - - // Custom fields - ReadCustomFields(lc, l, "linedef"); - - // Read sidedefs and connect them to the line - if(s1 > -1) + if(l != null) { - if(s1 < sidescolls.Count) - ReadSidedef(map, sidescolls[s1], l, true, sectorlink, s1); - else - General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid front sidedef " + s1 + ". Sidedef has been removed."); - } - - if(s2 > -1) - { - if(s2 < sidescolls.Count) - ReadSidedef(map, sidescolls[s2], l, false, sectorlink, s2); - else - General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid back sidedef " + s1 + ". Sidedef has been removed."); + l.Update(stringflags, 0, tag, special, args); + l.UpdateCache(); + + // Custom fields + ReadCustomFields(lc, l, "linedef"); + + // Read sidedefs and connect them to the line + if(s1 > -1) + { + if(s1 < sidescolls.Count) + ReadSidedef(map, sidescolls[s1], l, true, sectorlink, s1); + else + General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid front sidedef " + s1 + ". Sidedef has been removed."); + } + + if(s2 > -1) + { + if(s2 < sidescolls.Count) + ReadSidedef(map, sidescolls[s2], l, false, sectorlink, s2); + else + General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid back sidedef " + s1 + ". Sidedef has been removed."); + } } } else @@ -304,10 +310,13 @@ namespace CodeImp.DoomBuilder.IO if(sectorlink.ContainsKey(sector)) { Sidedef s = map.CreateSidedef(ld, front, sectorlink[sector]); - s.Update(offsetx, offsety, thigh, tmid, tlow); + if(s != null) + { + s.Update(offsetx, offsety, thigh, tmid, tlow); - // Custom fields - ReadCustomFields(sc, s, "sidedef"); + // Custom fields + ReadCustomFields(sc, s, "sidedef"); + } } else { @@ -343,13 +352,16 @@ namespace CodeImp.DoomBuilder.IO // Create new item Sector s = map.CreateSector(); - s.Update(hfloor, hceil, tfloor, tceil, special, tag, bright); + if(s != null) + { + s.Update(hfloor, hceil, tfloor, tceil, special, tag, bright); - // Custom fields - ReadCustomFields(c, s, "sector"); + // Custom fields + ReadCustomFields(c, s, "sector"); - // Add it to the lookup table - link.Add(i, s); + // Add it to the lookup table + link.Add(i, s); + } } // Return lookup table @@ -379,12 +391,14 @@ namespace CodeImp.DoomBuilder.IO // Create new item Vertex v = map.CreateVertex(new Vector2D(x, y)); + if(v != null) + { + // Custom fields + ReadCustomFields(c, v, "vertex"); - // Custom fields - ReadCustomFields(c, v, "vertex"); - - // Add it to the lookup table - link.Add(i, v); + // Add it to the lookup table + link.Add(i, v); + } } // Return lookup table diff --git a/Source/Core/Map/Linedef.cs b/Source/Core/Map/Linedef.cs index dde69756..b1c2259a 100644 --- a/Source/Core/Map/Linedef.cs +++ b/Source/Core/Map/Linedef.cs @@ -774,7 +774,7 @@ namespace CodeImp.DoomBuilder.Map } // This splits this line by vertex v - // Returns the new line resulting from the split + // Returns the new line resulting from the split, or null when it failed public Linedef Split(Vertex v) { Linedef nl; @@ -782,6 +782,7 @@ namespace CodeImp.DoomBuilder.Map // Copy linedef and change vertices nl = map.CreateLinedef(v, end); + if(nl == null) return null; CopyPropertiesTo(nl); SetEndVertex(v); nl.Selected = this.Selected; @@ -791,6 +792,7 @@ namespace CodeImp.DoomBuilder.Map if(front != null) { nsd = map.CreateSidedef(nl, true, front.Sector); + if(nsd == null) return null; front.CopyPropertiesTo(nsd); nsd.Marked = front.Marked; @@ -802,6 +804,7 @@ namespace CodeImp.DoomBuilder.Map if(back != null) { nsd = map.CreateSidedef(nl, false, back.Sector); + if(nsd == null) return null; back.CopyPropertiesTo(nsd); nsd.Marked = back.Marked; @@ -816,7 +819,8 @@ namespace CodeImp.DoomBuilder.Map // This joins the line with another line // This line will be disposed - public void Join(Linedef other) + // Returns false when the operation could not be completed + public bool Join(Linedef other) { Sector l1fs, l1bs, l2fs, l2bs; bool l1was2s, l2was2s; @@ -844,13 +848,13 @@ namespace CodeImp.DoomBuilder.Map // Copy my sidedefs to the other if(this.Start == other.Start) { - JoinChangeSidedefs(other, true, front); - JoinChangeSidedefs(other, false, back); + if(!JoinChangeSidedefs(other, true, front)) return false; + if(!JoinChangeSidedefs(other, false, back)) return false; } else { - JoinChangeSidedefs(other, false, front); - JoinChangeSidedefs(other, true, back); + if(!JoinChangeSidedefs(other, false, front)) return false; + if(!JoinChangeSidedefs(other, true, back)) return false; } // Copy my properties to the other @@ -866,7 +870,7 @@ namespace CodeImp.DoomBuilder.Map if(this.front != null) this.front.AddTexturesTo(other.back); // Change sidedefs - JoinChangeSidedefs(other, true, back); + if(!JoinChangeSidedefs(other, true, back)) return false; } // Compare back sectors else if((l1bs != null) && (l1bs == l2bs)) @@ -876,7 +880,7 @@ namespace CodeImp.DoomBuilder.Map if(this.back != null) this.back.AddTexturesTo(other.front); // Change sidedefs - JoinChangeSidedefs(other, false, front); + if(!JoinChangeSidedefs(other, false, front)) return false; } // Compare front and back else if((l1fs != null) && (l1fs == l2bs)) @@ -886,7 +890,7 @@ namespace CodeImp.DoomBuilder.Map if(this.back != null) this.back.AddTexturesTo(other.back); // Change sidedefs - JoinChangeSidedefs(other, true, front); + if(!JoinChangeSidedefs(other, true, front)) return false; } // Compare back and front else if((l1bs != null) && (l1bs == l2fs)) @@ -896,7 +900,7 @@ namespace CodeImp.DoomBuilder.Map if(this.front != null) this.front.AddTexturesTo(other.front); // Change sidedefs - JoinChangeSidedefs(other, false, back); + if(!JoinChangeSidedefs(other, false, back)) return false; } else { @@ -911,7 +915,7 @@ namespace CodeImp.DoomBuilder.Map if(this.back != null) this.back.AddTexturesTo(other.front); // Change sidedefs - JoinChangeSidedefs(other, false, front); + if(!JoinChangeSidedefs(other, false, front)) return false; } else { @@ -920,7 +924,7 @@ namespace CodeImp.DoomBuilder.Map if(this.front != null) this.front.AddTexturesTo(other.front); // Change sidedefs - JoinChangeSidedefs(other, false, back); + if(!JoinChangeSidedefs(other, false, back)) return false; } } // This line single sided? @@ -934,7 +938,7 @@ namespace CodeImp.DoomBuilder.Map if(this.back != null) this.back.AddTexturesTo(other.front); // Change sidedefs - JoinChangeSidedefs(other, false, front); + if(!JoinChangeSidedefs(other, false, front)) return false; } else { @@ -943,7 +947,7 @@ namespace CodeImp.DoomBuilder.Map if(this.back != null) this.back.AddTexturesTo(other.back); // Change sidedefs - JoinChangeSidedefs(other, true, front); + if(!JoinChangeSidedefs(other, true, front)) return false; } } else @@ -956,7 +960,7 @@ namespace CodeImp.DoomBuilder.Map if(this.back != null) this.back.AddTexturesTo(other.front); // Change sidedefs - JoinChangeSidedefs(other, false, front); + if(!JoinChangeSidedefs(other, false, front)) return false; } else { @@ -965,7 +969,7 @@ namespace CodeImp.DoomBuilder.Map if(this.front != null) this.front.AddTexturesTo(other.front); // Change sidedefs - JoinChangeSidedefs(other, false, back); + if(!JoinChangeSidedefs(other, false, back)) return false; } } } @@ -987,6 +991,7 @@ namespace CodeImp.DoomBuilder.Map // I got killed by the other. this.Dispose(); General.Map.IsChanged = true; + return true; } // This changes sidedefs (used for joining lines) @@ -994,7 +999,8 @@ namespace CodeImp.DoomBuilder.Map // front: Side on which to remove or create the sidedef (true for front side) // newside: The side from which to copy the properties to the new sidedef. // If this is null, no sidedef will be created (only removed) - private void JoinChangeSidedefs(Linedef target, bool front, Sidedef newside) + // Returns false when the operation could not be completed. + private bool JoinChangeSidedefs(Linedef target, bool front, Sidedef newside) { Sidedef sd; @@ -1011,9 +1017,12 @@ namespace CodeImp.DoomBuilder.Map if(newside != null) { sd = map.CreateSidedef(target, front, newside.Sector); + if(sd == null) return false; newside.CopyPropertiesTo(sd); sd.Marked = newside.Marked; } + + return true; } // String representation diff --git a/Source/Core/Map/MapSet.cs b/Source/Core/Map/MapSet.cs index 7cee2a80..920ecb74 100644 --- a/Source/Core/Map/MapSet.cs +++ b/Source/Core/Map/MapSet.cs @@ -22,6 +22,7 @@ using System.Collections.Generic; using System.Globalization; using System.Text; using CodeImp.DoomBuilder.Geometry; +using CodeImp.DoomBuilder.Windows; using SlimDX.Direct3D9; using CodeImp.DoomBuilder.Rendering; using SlimDX; @@ -513,6 +514,12 @@ namespace CodeImp.DoomBuilder.Map /// This creates a new vertex and returns it. public Vertex CreateVertex(Vector2D pos) { + if(numvertices == General.Map.FormatInterface.MaxVertices) + { + General.Interface.DisplayStatus(StatusType.Warning, "Failed to complete operation: maximum number of vertices reached."); + return null; + } + // Make the vertex Vertex v = new Vertex(this, numvertices, pos); AddItem(v, ref vertices, numvertices, ref numvertices); @@ -522,6 +529,12 @@ namespace CodeImp.DoomBuilder.Map /// This creates a new vertex and returns it. public Vertex CreateVertex(int index, Vector2D pos) { + if(numvertices == General.Map.FormatInterface.MaxVertices) + { + General.Interface.DisplayStatus(StatusType.Warning, "Failed to complete operation: maximum number of vertices reached."); + return null; + } + // Make the vertex Vertex v = new Vertex(this, index, pos); AddItem(v, ref vertices, index, ref numvertices); @@ -531,6 +544,12 @@ namespace CodeImp.DoomBuilder.Map /// This creates a new linedef and returns it. public Linedef CreateLinedef(Vertex start, Vertex end) { + if(numlinedefs == General.Map.FormatInterface.MaxLinedefs) + { + General.Interface.DisplayStatus(StatusType.Warning, "Failed to complete operation: maximum number of linedefs reached."); + return null; + } + // Make the linedef Linedef l = new Linedef(this, numlinedefs, start, end); AddItem(l, ref linedefs, numlinedefs, ref numlinedefs); @@ -540,6 +559,12 @@ namespace CodeImp.DoomBuilder.Map /// This creates a new linedef and returns it. public Linedef CreateLinedef(int index, Vertex start, Vertex end) { + if(numlinedefs == General.Map.FormatInterface.MaxLinedefs) + { + General.Interface.DisplayStatus(StatusType.Warning, "Failed to complete operation: maximum number of linedefs reached."); + return null; + } + // Make the linedef Linedef l = new Linedef(this, index, start, end); AddItem(l, ref linedefs, index, ref numlinedefs); @@ -549,6 +574,12 @@ namespace CodeImp.DoomBuilder.Map /// This creates a new sidedef and returns it. public Sidedef CreateSidedef(Linedef l, bool front, Sector s) { + if(numsidedefs == int.MaxValue) + { + General.Interface.DisplayStatus(StatusType.Warning, "Failed to complete operation: maximum number of sidedefs reached."); + return null; + } + // Make the sidedef Sidedef sd = new Sidedef(this, numsidedefs, l, front, s); AddItem(sd, ref sidedefs, numsidedefs, ref numsidedefs); @@ -558,6 +589,12 @@ namespace CodeImp.DoomBuilder.Map /// This creates a new sidedef and returns it. public Sidedef CreateSidedef(int index, Linedef l, bool front, Sector s) { + if(numsidedefs == int.MaxValue) + { + General.Interface.DisplayStatus(StatusType.Warning, "Failed to complete operation: maximum number of sidedefs reached."); + return null; + } + // Make the sidedef Sidedef sd = new Sidedef(this, index, l, front, s); AddItem(sd, ref sidedefs, index, ref numsidedefs); @@ -575,7 +612,13 @@ namespace CodeImp.DoomBuilder.Map public Sector CreateSector(int index) { int fixedindex; - + + if(numsectors == General.Map.FormatInterface.MaxSectors) + { + General.Interface.DisplayStatus(StatusType.Warning, "Failed to complete operation: maximum number of sectors reached."); + return null; + } + // Do we have any index holes we can use? if(indexholes.Count > 0) { @@ -596,6 +639,12 @@ namespace CodeImp.DoomBuilder.Map // This creates a new sector with a specific fixed index private Sector CreateSectorEx(int fixedindex, int index) { + if(numsectors == General.Map.FormatInterface.MaxSectors) + { + General.Interface.DisplayStatus(StatusType.Warning, "Failed to complete operation: maximum number of sectors reached."); + return null; + } + // Make the sector Sector s = new Sector(this, index, fixedindex); AddItem(s, ref sectors, index, ref numsectors); @@ -605,6 +654,12 @@ namespace CodeImp.DoomBuilder.Map /// This creates a new thing and returns it. public Thing CreateThing() { + if(numthings == General.Map.FormatInterface.MaxThings) + { + General.Interface.DisplayStatus(StatusType.Warning, "Failed to complete operation: maximum number of things reached."); + return null; + } + // Make the thing Thing t = new Thing(this, numthings); AddItem(t, ref things, numthings, ref numthings); @@ -614,6 +669,12 @@ namespace CodeImp.DoomBuilder.Map /// This creates a new thing and returns it. public Thing CreateThing(int index) { + if(numthings == General.Map.FormatInterface.MaxThings) + { + General.Interface.DisplayStatus(StatusType.Warning, "Failed to complete operation: maximum number of things reached."); + return null; + } + // Make the thing Thing t = new Thing(this, index); AddItem(t, ref things, index, ref numthings); @@ -1841,9 +1902,9 @@ namespace CodeImp.DoomBuilder.Map #region ================== Stitching /// - /// Stitches marked geometry with non-marked geometry. Returns the number of stitches made. + /// Stitches marked geometry with non-marked geometry. Returns false when the operation failed. /// - public int StitchGeometry() + public bool StitchGeometry() { ICollection movinglines; ICollection fixedlines; @@ -1851,7 +1912,6 @@ namespace CodeImp.DoomBuilder.Map ICollection movingverts; ICollection fixedverts; RectangleF editarea; - int stitches = 0; int stitchundo; // Find vertices @@ -1871,7 +1931,7 @@ namespace CodeImp.DoomBuilder.Map // Join nearby vertices BeginAddRemove(); - stitches += MapSet.JoinVertices(fixedverts, movingverts, true, MapSet.STITCH_DISTANCE); + MapSet.JoinVertices(fixedverts, movingverts, true, MapSet.STITCH_DISTANCE); EndAddRemove(); // Update cached values of lines because we need their length/angle @@ -1881,21 +1941,24 @@ namespace CodeImp.DoomBuilder.Map // Split moving lines with unselected vertices nearbyfixedverts = MapSet.FilterByArea(fixedverts, ref editarea); - stitches += MapSet.SplitLinesByVertices(movinglines, nearbyfixedverts, MapSet.STITCH_DISTANCE, movinglines); + if(!MapSet.SplitLinesByVertices(movinglines, nearbyfixedverts, MapSet.STITCH_DISTANCE, movinglines)) + return false; // Split non-moving lines with selected vertices fixedlines = MapSet.FilterByArea(fixedlines, ref editarea); - stitches += MapSet.SplitLinesByVertices(fixedlines, movingverts, MapSet.STITCH_DISTANCE, movinglines); + if(!MapSet.SplitLinesByVertices(fixedlines, movingverts, MapSet.STITCH_DISTANCE, movinglines)) + return false; // Remove looped linedefs - stitches += MapSet.RemoveLoopedLinedefs(movinglines); + MapSet.RemoveLoopedLinedefs(movinglines); // Join overlapping lines - stitches += MapSet.JoinOverlappingLines(movinglines); + if(!MapSet.JoinOverlappingLines(movinglines)) + return false; EndAddRemove(); - return stitches; + return true; } #endregion @@ -1951,10 +2014,9 @@ namespace CodeImp.DoomBuilder.Map return count; } - /// This joins overlapping lines together and returns the number of joins made. - public static int JoinOverlappingLines(ICollection lines) + /// This joins overlapping lines together. Returns false when the operation failed. + public static bool JoinOverlappingLines(ICollection lines) { - int joinsdone = 0; bool joined; do @@ -1980,7 +2042,7 @@ namespace CodeImp.DoomBuilder.Map // Merge these two linedefs while(lines.Remove(l2)) ; - l2.Join(l1); + if(!l2.Join(l1)) return false; // If l2 was marked as new geometry, we have to make sure // that l1's FrontInterior is correct for the drawing procedure @@ -1999,7 +2061,6 @@ namespace CodeImp.DoomBuilder.Map } } - joinsdone++; joined = true; break; } @@ -2024,7 +2085,7 @@ namespace CodeImp.DoomBuilder.Map // Merge these two linedefs while(lines.Remove(l2)) ; - l2.Join(l1); + if(!l2.Join(l1)) return false; // If l2 was marked as new geometry, we have to make sure // that l1's FrontInterior is correct for the drawing procedure @@ -2043,7 +2104,6 @@ namespace CodeImp.DoomBuilder.Map } } - joinsdone++; joined = true; break; } @@ -2057,7 +2117,7 @@ namespace CodeImp.DoomBuilder.Map while(joined); // Return result - return joinsdone; + return true; } /// This removes looped linedefs (linedefs which reference the same vertex for @@ -2184,11 +2244,10 @@ namespace CodeImp.DoomBuilder.Map } /// This splits the given lines with the given vertices. All affected lines - /// will be added to changedlines. Returns the number of splits made - public static int SplitLinesByVertices(ICollection lines, ICollection verts, float splitdist, ICollection changedlines) + /// will be added to changedlines. Returns false when the operation failed. + public static bool SplitLinesByVertices(ICollection lines, ICollection verts, float splitdist, ICollection changedlines) { float splitdist2 = splitdist * splitdist; - int splitsdone = 0; bool splitted; do @@ -2215,6 +2274,7 @@ namespace CodeImp.DoomBuilder.Map { // Split line l with vertex v Linedef nl = l.Split(v); + if(nl == null) return false; // Add the new line to the list lines.Add(nl); @@ -2232,7 +2292,6 @@ namespace CodeImp.DoomBuilder.Map } // Count the split - splitsdone++; splitted = true; break; } @@ -2246,9 +2305,8 @@ namespace CodeImp.DoomBuilder.Map } } while(splitted); - - // Return result - return splitsdone; + + return true; } /// This finds the side closest to the specified position. diff --git a/Source/Core/Windows/LinedefEditForm.cs b/Source/Core/Windows/LinedefEditForm.cs index 4cc1e043..6b4ad206 100644 --- a/Source/Core/Windows/LinedefEditForm.cs +++ b/Source/Core/Windows/LinedefEditForm.cs @@ -397,21 +397,29 @@ namespace CodeImp.DoomBuilder.Windows { // Make sure we have a valid sector (make a new one if needed) if(l.Front != null) index = l.Front.Sector.Index; else index = -1; - s = General.Map.Map.GetSectorByIndex(frontsector.GetResult(index)); - if(s == null) s = General.Map.Map.CreateSector(); - - // Create new sidedef? - if(l.Front == null) General.Map.Map.CreateSidedef(l, true, s); + index = frontsector.GetResult(index); + if((index > -1) && (index < General.Map.Map.Sectors.Count)) + { + s = General.Map.Map.GetSectorByIndex(index); + if(s == null) s = General.Map.Map.CreateSector(); + if(s != null) + { + // Create new sidedef? + if(l.Front == null) General.Map.Map.CreateSidedef(l, true, s); + if(l.Front != null) + { + // Change sector? + if(l.Front.Sector != s) l.Front.SetSector(s); - // Change sector? - if(l.Front.Sector != s) l.Front.SetSector(s); - - // Apply settings - l.Front.OffsetX = General.Clamp(frontoffsetx.GetResult(l.Front.OffsetX), General.Map.FormatInterface.MinTextureOffset, General.Map.FormatInterface.MaxTextureOffset); - l.Front.OffsetY = General.Clamp(frontoffsety.GetResult(l.Front.OffsetY), General.Map.FormatInterface.MinTextureOffset, General.Map.FormatInterface.MaxTextureOffset); - l.Front.SetTextureHigh(fronthigh.GetResult(l.Front.HighTexture)); - l.Front.SetTextureMid(frontmid.GetResult(l.Front.MiddleTexture)); - l.Front.SetTextureLow(frontlow.GetResult(l.Front.LowTexture)); + // Apply settings + l.Front.OffsetX = General.Clamp(frontoffsetx.GetResult(l.Front.OffsetX), General.Map.FormatInterface.MinTextureOffset, General.Map.FormatInterface.MaxTextureOffset); + l.Front.OffsetY = General.Clamp(frontoffsety.GetResult(l.Front.OffsetY), General.Map.FormatInterface.MinTextureOffset, General.Map.FormatInterface.MaxTextureOffset); + l.Front.SetTextureHigh(fronthigh.GetResult(l.Front.HighTexture)); + l.Front.SetTextureMid(frontmid.GetResult(l.Front.MiddleTexture)); + l.Front.SetTextureLow(frontlow.GetResult(l.Front.LowTexture)); + } + } + } } // Remove back side? @@ -424,21 +432,29 @@ namespace CodeImp.DoomBuilder.Windows { // Make sure we have a valid sector (make a new one if needed) if(l.Back != null) index = l.Back.Sector.Index; else index = -1; - s = General.Map.Map.GetSectorByIndex(backsector.GetResult(index)); - if(s == null) s = General.Map.Map.CreateSector(); + index = backsector.GetResult(index); + if((index > -1) && (index < General.Map.Map.Sectors.Count)) + { + s = General.Map.Map.GetSectorByIndex(index); + if(s == null) s = General.Map.Map.CreateSector(); + if(s != null) + { + // Create new sidedef? + if(l.Back == null) General.Map.Map.CreateSidedef(l, false, s); + if(l.Back != null) + { + // Change sector? + if(l.Back.Sector != s) l.Back.SetSector(s); - // Create new sidedef? - if(l.Back == null) General.Map.Map.CreateSidedef(l, false, s); - - // Change sector? - if(l.Back.Sector != s) l.Back.SetSector(s); - - // Apply settings - l.Back.OffsetX = General.Clamp(backoffsetx.GetResult(l.Back.OffsetX), General.Map.FormatInterface.MinTextureOffset, General.Map.FormatInterface.MaxTextureOffset); - l.Back.OffsetY = General.Clamp(backoffsety.GetResult(l.Back.OffsetY), General.Map.FormatInterface.MinTextureOffset, General.Map.FormatInterface.MaxTextureOffset); - l.Back.SetTextureHigh(backhigh.GetResult(l.Back.HighTexture)); - l.Back.SetTextureMid(backmid.GetResult(l.Back.MiddleTexture)); - l.Back.SetTextureLow(backlow.GetResult(l.Back.LowTexture)); + // Apply settings + l.Back.OffsetX = General.Clamp(backoffsetx.GetResult(l.Back.OffsetX), General.Map.FormatInterface.MinTextureOffset, General.Map.FormatInterface.MaxTextureOffset); + l.Back.OffsetY = General.Clamp(backoffsety.GetResult(l.Back.OffsetY), General.Map.FormatInterface.MinTextureOffset, General.Map.FormatInterface.MaxTextureOffset); + l.Back.SetTextureHigh(backhigh.GetResult(l.Back.HighTexture)); + l.Back.SetTextureMid(backmid.GetResult(l.Back.MiddleTexture)); + l.Back.SetTextureLow(backlow.GetResult(l.Back.LowTexture)); + } + } + } } // Custom fields diff --git a/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs b/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs index 4e6467c3..bb0c690e 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/BaseClassicMode.cs @@ -174,21 +174,27 @@ namespace CodeImp.DoomBuilder.BuilderModes { // Make a new one Thing t = General.Map.Map.CreateThing(); - t.Type = General.Map.Config.Start3DModeThingType; - t.Move(mousemappos); - t.UpdateConfiguration(); - General.Map.ThingsFilter.Update(); - thingfound = t; + if(t != null) + { + t.Type = General.Map.Config.Start3DModeThingType; + t.Move(mousemappos); + t.UpdateConfiguration(); + General.Map.ThingsFilter.Update(); + thingfound = t; + } } - // Make sure that the found thing is between ceiling and floor - thingfound.DetermineSector(); - if(thingfound.Position.z < 0.0f) thingfound.Move(thingfound.Position.x, thingfound.Position.y, 0.0f); - if(thingfound.Sector != null) + if(thingfound != null) { - if((thingfound.Position.z + 50.0f) > (thingfound.Sector.CeilHeight - thingfound.Sector.FloorHeight)) - thingfound.Move(thingfound.Position.x, thingfound.Position.y, - thingfound.Sector.CeilHeight - thingfound.Sector.FloorHeight - 50.0f); + // Make sure that the found thing is between ceiling and floor + thingfound.DetermineSector(); + if(thingfound.Position.z < 0.0f) thingfound.Move(thingfound.Position.x, thingfound.Position.y, 0.0f); + if(thingfound.Sector != null) + { + if((thingfound.Position.z + 50.0f) > (thingfound.Sector.CeilHeight - thingfound.Sector.FloorHeight)) + thingfound.Move(thingfound.Position.x, thingfound.Position.y, + thingfound.Sector.CeilHeight - thingfound.Sector.FloorHeight - 50.0f); + } } // Update Visual Mode camera diff --git a/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs index b3588c1b..1bdde18f 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs @@ -211,9 +211,19 @@ namespace CodeImp.DoomBuilder.BuilderModes { // Make vertex Vertex v = General.Map.Map.CreateVertex(points[i]); - + if(v == null) + { + General.Map.UndoRedo.WithdrawUndo(); + return; + } + // Split the line and move on with this line splitline = splitline.Split(v); + if(splitline == null) + { + General.Map.UndoRedo.WithdrawUndo(); + return; + } } } } diff --git a/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs b/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs index 0ba819b4..e81cd199 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/DrawGeometryMode.cs @@ -460,7 +460,14 @@ namespace CodeImp.DoomBuilder.BuilderModes General.Interface.DisplayStatus(StatusType.Action, "Created " + a + word + " drawing."); // Make the drawing - Tools.DrawLines(points); + if(!Tools.DrawLines(points)) + { + // Drawing failed + // NOTE: I have to call this twice, because the first time only cancels this volatile mode + General.Map.UndoRedo.WithdrawUndo(); + General.Map.UndoRedo.WithdrawUndo(); + return; + } // Snap to map format accuracy General.Map.Map.SnapAllToAccuracy(); diff --git a/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs b/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs index ec8bb34f..9121f1d4 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/EditSelectionMode.cs @@ -894,7 +894,7 @@ namespace CodeImp.DoomBuilder.BuilderModes } else { - General.Interface.DisplayStatus(StatusType.Warning, "Please make a selection first!"); + General.Interface.MessageBeep(MessageBeepType.Default); // Cancel now General.Editing.CancelMode(); diff --git a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs index 7004e571..66a29718 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/LinedefsMode.cs @@ -743,12 +743,23 @@ namespace CodeImp.DoomBuilder.BuilderModes // Split in middle of line splitvertex = General.Map.Map.CreateVertex(ld.GetCenterPoint()); } + + if(splitvertex == null) + { + General.Map.UndoRedo.WithdrawUndo(); + break; + } // Snap to map format accuracy splitvertex.SnapToAccuracy(); - + // Split the line - ld.Split(splitvertex); + Linedef sld = ld.Split(splitvertex); + if(sld == null) + { + General.Map.UndoRedo.WithdrawUndo(); + break; + } } // Update cache values diff --git a/Source/Plugins/BuilderModes/ClassicModes/MakeSectorMode.cs b/Source/Plugins/BuilderModes/ClassicModes/MakeSectorMode.cs index 9e844476..aa766efa 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/MakeSectorMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/MakeSectorMode.cs @@ -242,23 +242,30 @@ namespace CodeImp.DoomBuilder.BuilderModes // Make the sector Sector s = Tools.MakeSector(allsides, oldlines); - - // Now we go for all the lines along the sector to - // see if they only have a back side. In that case we want - // to flip the linedef to that it only has a front side. - foreach(Sidedef sd in s.Sidedefs) + if(s != null) { - if((sd.Line.Front == null) && (sd.Line.Back != null)) + // Now we go for all the lines along the sector to + // see if they only have a back side. In that case we want + // to flip the linedef to that it only has a front side. + foreach(Sidedef sd in s.Sidedefs) { - // Flip linedef - sd.Line.FlipVertices(); - sd.Line.FlipSidedefs(); + if((sd.Line.Front == null) && (sd.Line.Back != null)) + { + // Flip linedef + sd.Line.FlipVertices(); + sd.Line.FlipSidedefs(); + } } + + General.Map.Data.UpdateUsedTextures(); + General.Interface.SetCursor(Cursors.Default); + return s; + } + else + { + General.Map.UndoRedo.WithdrawUndo(); + return null; } - - General.Map.Data.UpdateUsedTextures(); - General.Interface.SetCursor(Cursors.Default); - return s; } #endregion @@ -376,17 +383,19 @@ namespace CodeImp.DoomBuilder.BuilderModes { // Make the sector Sector s = MakeSector(); + if(s != null) + { + // Quickly flash this sector to indicate it was created + General.Map.IsChanged = true; + General.Map.Map.Update(); + General.Interface.RedrawDisplay(); + flashpolygon = new FlatVertex[s.FlatVertices.Length]; + s.FlatVertices.CopyTo(flashpolygon, 0); + flashintensity = 1.0f; + flashstarttime = (double)General.Clock.GetCurrentTime(); + General.Interface.EnableProcessing(); + } - // Quickly flash this sector to indicate it was created - General.Map.IsChanged = true; - General.Map.Map.Update(); - General.Interface.RedrawDisplay(); - flashpolygon = new FlatVertex[s.FlatVertices.Length]; - s.FlatVertices.CopyTo(flashpolygon, 0); - flashintensity = 1.0f; - flashstarttime = (double)General.Clock.GetCurrentTime(); - General.Interface.EnableProcessing(); - // Redraw overlay DrawGeometry(); DrawOverlay(); @@ -418,28 +427,30 @@ namespace CodeImp.DoomBuilder.BuilderModes { // Make the sector Sector s = MakeSector(); - General.Map.Map.Update(); - - // Edit the sector - List secs = new List(); secs.Add(s); - if(General.Interface.ShowEditSectors(secs) == DialogResult.OK) + if(s != null) { - // Quickly flash this sector to indicate it was created - General.Map.IsChanged = true; General.Map.Map.Update(); - flashpolygon = new FlatVertex[s.FlatVertices.Length]; - s.FlatVertices.CopyTo(flashpolygon, 0); - flashintensity = 1.0f; - flashstarttime = (double)General.Clock.GetCurrentTime(); - General.Interface.EnableProcessing(); - } - else - { - // Undo - General.Map.UndoRedo.PerformUndo(); - General.Map.UndoRedo.ClearAllRedos(); - } + // Edit the sector + List secs = new List(); secs.Add(s); + if(General.Interface.ShowEditSectors(secs) == DialogResult.OK) + { + // Quickly flash this sector to indicate it was created + General.Map.IsChanged = true; + General.Map.Map.Update(); + flashpolygon = new FlatVertex[s.FlatVertices.Length]; + s.FlatVertices.CopyTo(flashpolygon, 0); + flashintensity = 1.0f; + flashstarttime = (double)General.Clock.GetCurrentTime(); + General.Interface.EnableProcessing(); + } + else + { + // Undo + General.Map.UndoRedo.WithdrawUndo(); + } + } + // Redraw overlay DrawGeometry(); DrawOverlay(); diff --git a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs index 3cab1656..4b2a0d33 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/ThingsMode.cs @@ -649,27 +649,32 @@ namespace CodeImp.DoomBuilder.BuilderModes return null; } - // Create things at mouse position + // Create thing Thing t = General.Map.Map.CreateThing(); - General.Settings.ApplyDefaultThingSettings(t); - t.Move(pos); - t.UpdateConfiguration(); - - // Update things filter so that it includes this thing - General.Map.ThingsFilter.Update(); - - // Snap to grid enabled? - if(General.Interface.SnapToGrid) + if(t != null) { - // Snap to grid - t.SnapToGrid(); - } - else - { - // Snap to map format accuracy - t.SnapToAccuracy(); - } + General.Settings.ApplyDefaultThingSettings(t); + + t.Move(pos); + + t.UpdateConfiguration(); + // Update things filter so that it includes this thing + General.Map.ThingsFilter.Update(); + + // Snap to grid enabled? + if(General.Interface.SnapToGrid) + { + // Snap to grid + t.SnapToGrid(); + } + else + { + // Snap to map format accuracy + t.SnapToAccuracy(); + } + } + return t; } diff --git a/Source/Plugins/BuilderModes/ClassicModes/VerticesMode.cs b/Source/Plugins/BuilderModes/ClassicModes/VerticesMode.cs index 45b98bbe..cb10aae0 100644 --- a/Source/Plugins/BuilderModes/ClassicModes/VerticesMode.cs +++ b/Source/Plugins/BuilderModes/ClassicModes/VerticesMode.cs @@ -309,16 +309,26 @@ namespace CodeImp.DoomBuilder.BuilderModes // Make the vertex Vertex v = General.Map.Map.CreateVertex(insertpos); - + if(v == null) + { + General.Map.UndoRedo.WithdrawUndo(); + return; + } + // Snap to map format accuracy v.SnapToAccuracy(); // Split the line with this vertex - l.Split(v); + Linedef sld = l.Split(v); + if(sld == null) + { + General.Map.UndoRedo.WithdrawUndo(); + return; + } // Update General.Map.Map.Update(); - + // Highlight it Highlight(v); @@ -616,9 +626,14 @@ namespace CodeImp.DoomBuilder.BuilderModes // Just insert here, don't snap to anything insertpos = mousemappos; } - + // Make the vertex Vertex v = General.Map.Map.CreateVertex(insertpos); + if(v == null) + { + General.Map.UndoRedo.WithdrawUndo(); + return; + } // Snap to map format accuracy v.SnapToAccuracy(); @@ -636,7 +651,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Update General.Map.Map.Update(); - + // Redraw screen General.Interface.RedrawDisplay(); } diff --git a/Source/Plugins/BuilderModes/ErrorChecks/ResultLineMissingFront.cs b/Source/Plugins/BuilderModes/ErrorChecks/ResultLineMissingFront.cs index fbe27d66..50535e98 100644 --- a/Source/Plugins/BuilderModes/ErrorChecks/ResultLineMissingFront.cs +++ b/Source/Plugins/BuilderModes/ErrorChecks/ResultLineMissingFront.cs @@ -134,6 +134,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { General.Map.UndoRedo.CreateUndo("Create front sidedef"); Sidedef newside = General.Map.Map.CreateSidedef(line, true, copysidedef.Sector); + if(newside == null) return false; copysidedef.CopyPropertiesTo(newside); line.ApplySidedFlags(); General.Map.Map.Update(); diff --git a/Source/Plugins/BuilderModes/ErrorChecks/ResultLineMissingSides.cs b/Source/Plugins/BuilderModes/ErrorChecks/ResultLineMissingSides.cs index 8b356ec9..8499cc55 100644 --- a/Source/Plugins/BuilderModes/ErrorChecks/ResultLineMissingSides.cs +++ b/Source/Plugins/BuilderModes/ErrorChecks/ResultLineMissingSides.cs @@ -163,6 +163,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Front General.Map.UndoRedo.CreateUndo("Create front sidedef"); Sidedef newside = General.Map.Map.CreateSidedef(line, true, copysidedeffront.Sector); + if(newside == null) return false; copysidedeffront.CopyPropertiesTo(newside); } else if(copysidedefback != null) @@ -172,6 +173,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // We will then flip it to make sure to ends up in the right position. General.Map.UndoRedo.CreateUndo("Create front sidedef"); Sidedef newside = General.Map.Map.CreateSidedef(line, true, copysidedefback.Sector); + if(newside == null) return false; copysidedefback.CopyPropertiesTo(newside); line.FlipVertices(); } @@ -189,10 +191,12 @@ namespace CodeImp.DoomBuilder.BuilderModes // Front newside = General.Map.Map.CreateSidedef(line, true, copysidedeffront.Sector); + if(newside == null) return false; copysidedeffront.CopyPropertiesTo(newside); // Back newside = General.Map.Map.CreateSidedef(line, false, copysidedefback.Sector); + if(newside == null) return false; copysidedefback.CopyPropertiesTo(newside); line.ApplySidedFlags(); diff --git a/Source/Plugins/BuilderModes/ErrorChecks/ResultLineNotDoubleSided.cs b/Source/Plugins/BuilderModes/ErrorChecks/ResultLineNotDoubleSided.cs index 910dfb58..3f719a57 100644 --- a/Source/Plugins/BuilderModes/ErrorChecks/ResultLineNotDoubleSided.cs +++ b/Source/Plugins/BuilderModes/ErrorChecks/ResultLineNotDoubleSided.cs @@ -133,6 +133,7 @@ namespace CodeImp.DoomBuilder.BuilderModes { General.Map.UndoRedo.CreateUndo("Create back sidedef"); Sidedef newside = General.Map.Map.CreateSidedef(line, false, copysidedef.Sector); + if(newside == null) return false; copysidedef.CopyPropertiesTo(newside); line.ApplySidedFlags(); General.Map.Map.Update();