mirror of
https://git.do.srb2.org/STJr/ZoneBuilder.git
synced 2024-11-10 06:41:49 +00:00
Fixed: in some cases sidedefs were incorrectly reassigned when applying Edit Selection and Drag Geometry modes.
This commit is contained in:
parent
2e32b8839a
commit
8599e33b2f
3 changed files with 110 additions and 42 deletions
|
@ -2359,67 +2359,118 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
}
|
||||
}
|
||||
|
||||
// Check single-sided lines. Add new sidedefs if necessary
|
||||
// These steps must be done in 2 phases, otherwise we'll end up getting sidedefs modified in a previous adjustment loop step
|
||||
|
||||
// Find sidedefs to join singlesided lines
|
||||
Dictionary<Linedef, Sidedef> linenearestsideref = new Dictionary<Linedef, Sidedef>();
|
||||
foreach(Linedef line in singlesidedlines)
|
||||
{
|
||||
// Line is now inside a sector?
|
||||
Vector2D testpoint = line.GetSidePoint(line.Front == null);
|
||||
Linedef nl = General.Map.Map.NearestLinedef(testpoint, selectedlines);
|
||||
if(nl != null)
|
||||
Sector nearest = General.Map.Map.GetSectorByCoordinates(testpoint, selectedsectors);
|
||||
|
||||
if(nearest != null)
|
||||
{
|
||||
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
||||
if(ns != null)
|
||||
Linedef nl = null;
|
||||
float distance = float.MaxValue;
|
||||
|
||||
// Find nearest linedef
|
||||
foreach(Sidedef ns in nearest.Sidedefs)
|
||||
{
|
||||
// Create new sidedef
|
||||
Sidedef newside = General.Map.Map.CreateSidedef(line, line.Front == null, ns.Sector);
|
||||
|
||||
// Copy props from the other side
|
||||
Sidedef propssource = ((line.Front ?? line.Back) ?? ns);
|
||||
propssource.CopyPropertiesTo(newside);
|
||||
newside.RemoveUnneededTextures(true, true, true);
|
||||
newside.Other.RemoveUnneededTextures(true, true, true);
|
||||
|
||||
// Correct the linedef
|
||||
if((line.Front == null) && (line.Back != null))
|
||||
float d = ns.Line.SafeDistanceToSq(testpoint, true);
|
||||
if(d < distance)
|
||||
{
|
||||
line.FlipVertices();
|
||||
line.FlipSidedefs();
|
||||
// This one is closer
|
||||
nl = ns.Line;
|
||||
distance = d;
|
||||
}
|
||||
}
|
||||
|
||||
// Correct the sided flags
|
||||
line.ApplySidedFlags();
|
||||
// Find nearest sidedef
|
||||
if(nl != null)
|
||||
{
|
||||
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
||||
if(ns != null) linenearestsideref[line] = ns;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check outer sidedefs. Remove/change sector if necessary
|
||||
// Find sidedefs to join outer sides
|
||||
Dictionary<Sidedef, Sidedef> sidenearestsideref = new Dictionary<Sidedef, Sidedef>();
|
||||
foreach(Sidedef side in outersides)
|
||||
{
|
||||
// Side is inside a sector?
|
||||
Vector2D testpoint = side.Line.GetSidePoint(side.IsFront);
|
||||
Linedef nl = General.Map.Map.NearestLinedef(testpoint, selectedlines);
|
||||
bool lineisoutside = true;
|
||||
if(nl != null)
|
||||
Sector nearest = General.Map.Map.GetSectorByCoordinates(testpoint, selectedsectors);
|
||||
sidenearestsideref[side] = null; // This side will be removed in phase 2
|
||||
|
||||
if(nearest != null)
|
||||
{
|
||||
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
||||
if(ns != null)
|
||||
Linedef nl = null;
|
||||
float distance = float.MaxValue;
|
||||
|
||||
// Find nearest linedef
|
||||
foreach(Sidedef ns in nearest.Sidedefs)
|
||||
{
|
||||
lineisoutside = false;
|
||||
if(ns.Sector != null && side.Sector != ns.Sector)
|
||||
float d = ns.Line.SafeDistanceToSq(testpoint, true);
|
||||
if(d < distance)
|
||||
{
|
||||
// Reattach side
|
||||
side.SetSector(ns.Sector);
|
||||
side.RemoveUnneededTextures(true, true, true);
|
||||
// This one is closer
|
||||
nl = ns.Line;
|
||||
distance = d;
|
||||
}
|
||||
}
|
||||
|
||||
// Find nearest sidedef
|
||||
if(nl != null)
|
||||
{
|
||||
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
||||
if(ns != null && ns.Sector != null)
|
||||
{
|
||||
if(side.Sector != ns.Sector)
|
||||
sidenearestsideref[side] = ns; // This side will be reattached in phase 2
|
||||
else
|
||||
sidenearestsideref.Remove(side); // This side is already attached where it needs to be
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Side points nowhere. Remove it
|
||||
if(lineisoutside)
|
||||
// Check single-sided lines. Add new sidedefs if necessary
|
||||
// Key is dragged single-sided line, value is the nearset side of a sector dragged line ended up in.
|
||||
foreach(KeyValuePair<Linedef, Sidedef> group in linenearestsideref)
|
||||
{
|
||||
Linedef line = group.Key;
|
||||
|
||||
// Create new sidedef
|
||||
Sidedef newside = General.Map.Map.CreateSidedef(line, line.Front == null, group.Value.Sector);
|
||||
|
||||
// Copy props from the other side
|
||||
Sidedef propssource = ((line.Front ?? line.Back) ?? group.Value);
|
||||
propssource.CopyPropertiesTo(newside);
|
||||
newside.RemoveUnneededTextures(true, true, true);
|
||||
newside.Other.RemoveUnneededTextures(true, true, true);
|
||||
|
||||
// Correct the linedef
|
||||
if((line.Front == null) && (line.Back != null))
|
||||
{
|
||||
// Remove the sidedef
|
||||
Linedef l = side.Line;
|
||||
side.Dispose();
|
||||
line.FlipVertices();
|
||||
line.FlipSidedefs();
|
||||
}
|
||||
|
||||
// Correct the sided flags
|
||||
line.ApplySidedFlags();
|
||||
}
|
||||
|
||||
// Check outer sidedefs. Remove/change sector if necessary
|
||||
// Key is outer sidedef of dragged geometry, value is nearset side of a sector dragged side ended up in.
|
||||
foreach(KeyValuePair<Sidedef, Sidedef> group in sidenearestsideref)
|
||||
{
|
||||
if(group.Value == null)
|
||||
{
|
||||
// Side points nowhere. Remove it
|
||||
Linedef l = group.Key.Line;
|
||||
group.Key.Dispose();
|
||||
|
||||
// Correct the linedef
|
||||
if((l.Front == null) && (l.Back != null))
|
||||
|
@ -2431,6 +2482,12 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
// Correct the sided flags
|
||||
l.ApplySidedFlags();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reattach side
|
||||
group.Key.SetSector(group.Value.Sector);
|
||||
group.Key.RemoveUnneededTextures(true, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Update map geometry
|
||||
|
|
|
@ -3093,6 +3093,17 @@ namespace CodeImp.DoomBuilder.Map
|
|||
return null;
|
||||
}
|
||||
|
||||
//mxd
|
||||
/// <summary>This returns a sector if given coordinates are inside one.</summary>
|
||||
public Sector GetSectorByCoordinates(Vector2D pos, HashSet<Sector> sectorsToExclude)
|
||||
{
|
||||
foreach(Sector s in sectors)
|
||||
{
|
||||
if(!sectorsToExclude.Contains(s) && s.Intersect(pos)) return s;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//mxd
|
||||
/// <summary>This returns a sector if given coordinates are inside one.</summary>
|
||||
public Sector GetSectorByCoordinates(Vector2D pos, VisualBlockMap blockmap)
|
||||
|
|
|
@ -1482,6 +1482,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
General.Map.Map.RemoveVirtualSectors();
|
||||
}
|
||||
|
||||
// Stitch geometry
|
||||
if(snaptonearest) General.Map.Map.StitchGeometry();
|
||||
|
||||
// Make corrections for backward linedefs
|
||||
MapSet.FlipBackwardLinedefs(General.Map.Map.Linedefs);
|
||||
|
||||
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
|
||||
if(unstablelines.Count == 0)
|
||||
{
|
||||
|
@ -1490,12 +1496,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
affectedsectors.UnionWith(General.Map.Map.GetUnselectedSectorsFromLinedefs(selectedlines));
|
||||
Tools.AdjustOuterSidedefs(affectedsectors, new HashSet<Linedef>(selectedlines));
|
||||
}
|
||||
|
||||
// Stitch geometry
|
||||
if(snaptonearest) General.Map.Map.StitchGeometry();
|
||||
|
||||
// Make corrections for backward linedefs
|
||||
MapSet.FlipBackwardLinedefs(General.Map.Map.Linedefs);
|
||||
|
||||
// Snap to map format accuracy
|
||||
General.Map.Map.SnapAllToAccuracy(General.Map.UDMF && usepreciseposition);
|
||||
|
|
Loading…
Reference in a new issue