Fixed: in some cases lines with only back side were created after dragging map elements when using "Merge Dragger Vertices Only" drag mode.

Fixed: in some cases invalid sectors were created after dragging map elements when using "Merge Dragged Geometry" and "Replace with Dragged Geometry" drag modes, when at least one of dragged linedef was facing into an enclosed void area.
Fixed a crash after drawing lines over a sector with unclosed/invalid boundaries.
Fixed(?): probably fixed a crash when closing Script Editor with an unsaved file during program termination.
This commit is contained in:
MaxED 2016-09-10 20:45:41 +00:00 committed by spherallic
parent 246f947cba
commit c919c250f7
4 changed files with 50 additions and 41 deletions

View File

@ -2269,11 +2269,14 @@ namespace CodeImp.DoomBuilder.Geometry
private static bool SectorWasInvalid(Sector s) private static bool SectorWasInvalid(Sector s)
{ {
if(s.Sidedefs.Count < 3 || s.FlatVertices.Length < 3) if(s.Sidedefs == null || s.Sidedefs.Count < 3 || s.FlatVertices.Length < 3)
{ {
// Collect changed lines // Collect changed lines
HashSet<Linedef> changedlines = new HashSet<Linedef>(); HashSet<Linedef> changedlines = new HashSet<Linedef>();
foreach(Sidedef side in s.Sidedefs) changedlines.Add(side.Line); if(s.Sidedefs != null)
{
foreach(Sidedef side in s.Sidedefs) changedlines.Add(side.Line);
}
// Delete sector // Delete sector
s.Dispose(); s.Dispose();
@ -2400,24 +2403,26 @@ namespace CodeImp.DoomBuilder.Geometry
} }
//mxd //mxd
public static Sector FindPotentialSector(Linedef line, bool front) public static Sector FindSectorContaining(Linedef line, bool front)
{ {
List<LinedefSide> sectorsides = FindPotentialSectorAt(line, front); List<LinedefSide> sectorsides = FindPotentialSectorAt(line, front);
if(sectorsides == null) return null; if(sectorsides == null) return null;
Sector result = null; Sector result = null;
bool foundstartline = false;
// Proceed only if all sectorsides reference the same sector // Proceed only if all sectorsides reference the same sector and the start line is among them
foreach(LinedefSide sectorside in sectorsides) foreach(LinedefSide sectorside in sectorsides)
{ {
Sidedef target = (sectorside.Front ? sectorside.Line.Front : sectorside.Line.Back); Sidedef target = (sectorside.Front ? sectorside.Line.Front : sectorside.Line.Back);
if(target != null) if(target == null) return null; // Fial...
{
if(result == null) result = target.Sector; if(result == null) result = target.Sector;
else if(result != target.Sector) return null; // Fial... else if(result != target.Sector) return null; // Fial...
}
if(sectorside.Line == line) foundstartline = true;
} }
return result; return (foundstartline ? result : null);
} }
#endregion #endregion

View File

@ -2134,29 +2134,29 @@ namespace CodeImp.DoomBuilder.Map
EndAddRemove(); EndAddRemove();
// Collect changed lines... We need those in by-vertex-index order
// (otherwise SectorBuilder logic in some cases will incorrectly assign sector propertes)
List<Vertex> markedverts = GetMarkedVertices(true);
List<Linedef> changedlines = new List<Linedef>(markedverts.Count / 2);
HashSet<Linedef> changedlineshash = new HashSet<Linedef>();
foreach(Vertex v in markedverts)
{
foreach(Linedef l in v.Linedefs)
{
if(!changedlineshash.Contains(l))
{
changedlines.Add(l);
changedlineshash.Add(l);
}
}
}
//mxd. Correct sector references //mxd. Correct sector references
if(mergemode != MergeGeometryMode.CLASSIC) if(mergemode != MergeGeometryMode.CLASSIC)
{ {
// Linedefs cache needs to be up to date... // Linedefs cache needs to be up to date...
Update(true, false); Update(true, false);
// Collect changed lines... We need those in by-vertex-index order
// (otherwise SectorBuilder logic in some cases will incorrectly assign sector propertes)
List<Vertex> markedverts = GetMarkedVertices(true);
List<Linedef> changedlines = new List<Linedef>(markedverts.Count / 2);
HashSet<Linedef> changedlineshash = new HashSet<Linedef>();
foreach(Vertex v in markedverts)
{
foreach(Linedef l in v.Linedefs)
{
if(!changedlineshash.Contains(l))
{
changedlines.Add(l);
changedlineshash.Add(l);
}
}
}
// Fix stuff... // Fix stuff...
CorrectSectorReferences(changedlines, true); CorrectSectorReferences(changedlines, true);
CorrectOuterSides(new HashSet<Linedef>(changedlines)); CorrectOuterSides(new HashSet<Linedef>(changedlines));
@ -2166,6 +2166,10 @@ namespace CodeImp.DoomBuilder.Map
HashSet<Sector> changedsectors = GetSectorsFromLinedefs(changedlines); HashSet<Sector> changedsectors = GetSectorsFromLinedefs(changedlines);
foreach(Sector s in changedsectors) s.Marked = true; foreach(Sector s in changedsectors) s.Marked = true;
} }
else
{
FlipBackwardLinedefs(changedlines);
}
return true; return true;
} }
@ -2437,7 +2441,7 @@ namespace CodeImp.DoomBuilder.Map
foreach(Linedef line in linesmissingfront) foreach(Linedef line in linesmissingfront)
{ {
// Line is now inside a sector? (check from the missing side!) // Line is now inside a sector? (check from the missing side!)
Sector nearest = Tools.FindPotentialSector(line, true); Sector nearest = Tools.FindSectorContaining(line, true);
// We can reattach our line! // We can reattach our line!
if(nearest != null) linefrontsectorref[line] = nearest; if(nearest != null) linefrontsectorref[line] = nearest;
@ -2447,7 +2451,7 @@ namespace CodeImp.DoomBuilder.Map
foreach(Linedef line in linesmissingback) foreach(Linedef line in linesmissingback)
{ {
// Line is now inside a sector? (check from the missing side!) // Line is now inside a sector? (check from the missing side!)
Sector nearest = Tools.FindPotentialSector(line, false); Sector nearest = Tools.FindSectorContaining(line, false);
// We can reattach our line! // We can reattach our line!
if(nearest != null) linebacksectorref[line] = nearest; if(nearest != null) linebacksectorref[line] = nearest;

View File

@ -515,7 +515,7 @@ namespace CodeImp.DoomBuilder.VisualModes
// This preforms visibility culling // This preforms visibility culling
protected void DoCulling() protected void DoCulling()
{ {
Dictionary<Linedef, Linedef> visiblelines = new Dictionary<Linedef, Linedef>(200); HashSet<Linedef> visiblelines = new HashSet<Linedef>();
Vector2D campos2d = General.Map.VisualCamera.Position; Vector2D campos2d = General.Map.VisualCamera.Position;
// Make collections // Make collections
@ -535,10 +535,10 @@ namespace CodeImp.DoomBuilder.VisualModes
foreach(Linedef ld in block.Lines) foreach(Linedef ld in block.Lines)
{ {
// Line not already processed? // Line not already processed?
if(!visiblelines.ContainsKey(ld)) if(!visiblelines.Contains(ld))
{ {
// Add line if not added yet // Add line if not added yet
visiblelines.Add(ld, ld); visiblelines.Add(ld);
// Which side of the line is the camera on? // Which side of the line is the camera on?
if(ld.SideOfLine(campos2d) < 0) if(ld.SideOfLine(campos2d) < 0)
@ -572,21 +572,21 @@ namespace CodeImp.DoomBuilder.VisualModes
{ {
// Create new visual thing // Create new visual thing
vt = CreateVisualThing(t); vt = CreateVisualThing(t);
allthings.Add(t, vt); allthings[t] = vt;
} }
if (vt != null && !visiblethings.ContainsKey(vt.Thing)) if(vt != null && !visiblethings.ContainsKey(vt.Thing))
{ {
visiblethings.Add(vt.Thing, vt); visiblethings[vt.Thing] = vt;
} }
} }
} }
} }
if(processgeometry) if(processgeometry)
{ {
// Find camera sector // Find camera sector
Linedef nld = MapSet.NearestLinedef(visiblelines.Values, campos2d); Linedef nld = MapSet.NearestLinedef(visiblelines, campos2d);
if(nld != null) if(nld != null)
{ {
General.Map.VisualCamera.Sector = GetCameraSectorFromLinedef(nld); General.Map.VisualCamera.Sector = GetCameraSectorFromLinedef(nld);

View File

@ -96,7 +96,7 @@ namespace CodeImp.DoomBuilder.Windows
editor.SaveSettings(); editor.SaveSettings();
// Only when closed by the user // Only when closed by the user
if(!appclose) if(!appclose && (e.CloseReason == CloseReason.UserClosing || e.CloseReason == CloseReason.FormOwnerClosing))
{ {
// Remember if scipts are changed // Remember if scipts are changed
General.Map.ApplyScriptChanged(); General.Map.ApplyScriptChanged();