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)
{
if(s.Sidedefs.Count < 3 || s.FlatVertices.Length < 3)
if(s.Sidedefs == null || s.Sidedefs.Count < 3 || s.FlatVertices.Length < 3)
{
// Collect changed lines
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
s.Dispose();
@ -2400,24 +2403,26 @@ namespace CodeImp.DoomBuilder.Geometry
}
//mxd
public static Sector FindPotentialSector(Linedef line, bool front)
public static Sector FindSectorContaining(Linedef line, bool front)
{
List<LinedefSide> sectorsides = FindPotentialSectorAt(line, front);
if(sectorsides == null) return 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)
{
Sidedef target = (sectorside.Front ? sectorside.Line.Front : sectorside.Line.Back);
if(target != null)
{
if(result == null) result = target.Sector;
else if(result != target.Sector) return null; // Fial...
}
if(target == null) return null; // Fial...
if(result == null) result = target.Sector;
else if(result != target.Sector) return null; // Fial...
if(sectorside.Line == line) foundstartline = true;
}
return result;
return (foundstartline ? result : null);
}
#endregion

View File

@ -2134,29 +2134,29 @@ namespace CodeImp.DoomBuilder.Map
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
if(mergemode != MergeGeometryMode.CLASSIC)
{
// Linedefs cache needs to be up to date...
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...
CorrectSectorReferences(changedlines, true);
CorrectOuterSides(new HashSet<Linedef>(changedlines));
@ -2166,6 +2166,10 @@ namespace CodeImp.DoomBuilder.Map
HashSet<Sector> changedsectors = GetSectorsFromLinedefs(changedlines);
foreach(Sector s in changedsectors) s.Marked = true;
}
else
{
FlipBackwardLinedefs(changedlines);
}
return true;
}
@ -2437,7 +2441,7 @@ namespace CodeImp.DoomBuilder.Map
foreach(Linedef line in linesmissingfront)
{
// 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!
if(nearest != null) linefrontsectorref[line] = nearest;
@ -2447,7 +2451,7 @@ namespace CodeImp.DoomBuilder.Map
foreach(Linedef line in linesmissingback)
{
// 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!
if(nearest != null) linebacksectorref[line] = nearest;

View File

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

View File

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