mirror of
https://git.do.srb2.org/STJr/ZoneBuilder.git
synced 2025-02-12 07:05:29 +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,22 +2359,94 @@ 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)
|
foreach(Linedef line in singlesidedlines)
|
||||||
{
|
{
|
||||||
// Line is now inside a sector?
|
// Line is now inside a sector?
|
||||||
Vector2D testpoint = line.GetSidePoint(line.Front == null);
|
Vector2D testpoint = line.GetSidePoint(line.Front == null);
|
||||||
Linedef nl = General.Map.Map.NearestLinedef(testpoint, selectedlines);
|
Sector nearest = General.Map.Map.GetSectorByCoordinates(testpoint, selectedsectors);
|
||||||
|
|
||||||
|
if(nearest != null)
|
||||||
|
{
|
||||||
|
Linedef nl = null;
|
||||||
|
float distance = float.MaxValue;
|
||||||
|
|
||||||
|
// Find nearest linedef
|
||||||
|
foreach(Sidedef ns in nearest.Sidedefs)
|
||||||
|
{
|
||||||
|
float d = ns.Line.SafeDistanceToSq(testpoint, true);
|
||||||
|
if(d < distance)
|
||||||
|
{
|
||||||
|
// This one is closer
|
||||||
|
nl = ns.Line;
|
||||||
|
distance = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find nearest sidedef
|
||||||
if(nl != null)
|
if(nl != null)
|
||||||
{
|
{
|
||||||
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
||||||
if(ns != null)
|
if(ns != null) linenearestsideref[line] = ns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
Sector nearest = General.Map.Map.GetSectorByCoordinates(testpoint, selectedsectors);
|
||||||
|
sidenearestsideref[side] = null; // This side will be removed in phase 2
|
||||||
|
|
||||||
|
if(nearest != null)
|
||||||
|
{
|
||||||
|
Linedef nl = null;
|
||||||
|
float distance = float.MaxValue;
|
||||||
|
|
||||||
|
// Find nearest linedef
|
||||||
|
foreach(Sidedef ns in nearest.Sidedefs)
|
||||||
|
{
|
||||||
|
float d = ns.Line.SafeDistanceToSq(testpoint, true);
|
||||||
|
if(d < distance)
|
||||||
|
{
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
// Create new sidedef
|
||||||
Sidedef newside = General.Map.Map.CreateSidedef(line, line.Front == null, ns.Sector);
|
Sidedef newside = General.Map.Map.CreateSidedef(line, line.Front == null, group.Value.Sector);
|
||||||
|
|
||||||
// Copy props from the other side
|
// Copy props from the other side
|
||||||
Sidedef propssource = ((line.Front ?? line.Back) ?? ns);
|
Sidedef propssource = ((line.Front ?? line.Back) ?? group.Value);
|
||||||
propssource.CopyPropertiesTo(newside);
|
propssource.CopyPropertiesTo(newside);
|
||||||
newside.RemoveUnneededTextures(true, true, true);
|
newside.RemoveUnneededTextures(true, true, true);
|
||||||
newside.Other.RemoveUnneededTextures(true, true, true);
|
newside.Other.RemoveUnneededTextures(true, true, true);
|
||||||
|
@ -2389,37 +2461,16 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
// Correct the sided flags
|
// Correct the sided flags
|
||||||
line.ApplySidedFlags();
|
line.ApplySidedFlags();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check outer sidedefs. Remove/change sector if necessary
|
// Check outer sidedefs. Remove/change sector if necessary
|
||||||
foreach(Sidedef side in outersides)
|
// 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)
|
||||||
{
|
{
|
||||||
// Side is inside a sector?
|
if(group.Value == null)
|
||||||
Vector2D testpoint = side.Line.GetSidePoint(side.IsFront);
|
|
||||||
Linedef nl = General.Map.Map.NearestLinedef(testpoint, selectedlines);
|
|
||||||
bool lineisoutside = true;
|
|
||||||
if(nl != null)
|
|
||||||
{
|
{
|
||||||
Sidedef ns = (nl.SideOfLine(testpoint) <= 0 ? nl.Front : nl.Back);
|
|
||||||
if(ns != null)
|
|
||||||
{
|
|
||||||
lineisoutside = false;
|
|
||||||
if(ns.Sector != null && side.Sector != ns.Sector)
|
|
||||||
{
|
|
||||||
// Reattach side
|
|
||||||
side.SetSector(ns.Sector);
|
|
||||||
side.RemoveUnneededTextures(true, true, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Side points nowhere. Remove it
|
// Side points nowhere. Remove it
|
||||||
if(lineisoutside)
|
Linedef l = group.Key.Line;
|
||||||
{
|
group.Key.Dispose();
|
||||||
// Remove the sidedef
|
|
||||||
Linedef l = side.Line;
|
|
||||||
side.Dispose();
|
|
||||||
|
|
||||||
// Correct the linedef
|
// Correct the linedef
|
||||||
if((l.Front == null) && (l.Back != null))
|
if((l.Front == null) && (l.Back != null))
|
||||||
|
@ -2431,6 +2482,12 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
// Correct the sided flags
|
// Correct the sided flags
|
||||||
l.ApplySidedFlags();
|
l.ApplySidedFlags();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Reattach side
|
||||||
|
group.Key.SetSector(group.Value.Sector);
|
||||||
|
group.Key.RemoveUnneededTextures(true, true, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update map geometry
|
// Update map geometry
|
||||||
|
|
|
@ -3093,6 +3093,17 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
return null;
|
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
|
//mxd
|
||||||
/// <summary>This returns a sector if given coordinates are inside one.</summary>
|
/// <summary>This returns a sector if given coordinates are inside one.</summary>
|
||||||
public Sector GetSectorByCoordinates(Vector2D pos, VisualBlockMap blockmap)
|
public Sector GetSectorByCoordinates(Vector2D pos, VisualBlockMap blockmap)
|
||||||
|
|
|
@ -1482,6 +1482,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
General.Map.Map.RemoveVirtualSectors();
|
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
|
//mxd. Reattach/add/remove sidedefs only when there are no unstable lines in selection
|
||||||
if(unstablelines.Count == 0)
|
if(unstablelines.Count == 0)
|
||||||
{
|
{
|
||||||
|
@ -1491,12 +1497,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
Tools.AdjustOuterSidedefs(affectedsectors, new HashSet<Linedef>(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
|
// Snap to map format accuracy
|
||||||
General.Map.Map.SnapAllToAccuracy(General.Map.UDMF && usepreciseposition);
|
General.Map.Map.SnapAllToAccuracy(General.Map.UDMF && usepreciseposition);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue