mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-24 12:51:30 +00:00
977adb47f2
Fixed severe lock-up after finishing dragging many vertices/linedefs/sectors in Classic modes. Updated documentation ("Synchronizing camera position").
153 lines
4.6 KiB
C#
153 lines
4.6 KiB
C#
#region ================== Namespaces
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using CodeImp.DoomBuilder.Geometry;
|
|
using CodeImp.DoomBuilder.Map;
|
|
using CodeImp.DoomBuilder.Rendering;
|
|
|
|
#endregion
|
|
|
|
namespace CodeImp.DoomBuilder.BuilderModes
|
|
{
|
|
public class ResultSectorInvalid : ErrorResult
|
|
{
|
|
#region ================== Variables
|
|
|
|
private readonly Sector sector;
|
|
|
|
#endregion
|
|
|
|
#region ================== Properties
|
|
|
|
public override int Buttons { get { return 1; } }
|
|
public override string Button1Text { get { return "Dissolve"; } }
|
|
|
|
#endregion
|
|
|
|
#region ================== Constructor / Destructor
|
|
|
|
// Constructor
|
|
public ResultSectorInvalid(Sector s)
|
|
{
|
|
// Initialize
|
|
sector = s;
|
|
viewobjects.Add(s);
|
|
hidden = s.IgnoredErrorChecks.Contains(this.GetType()); //mxd
|
|
description = "This sector has invalid geometry (it has less than 3 sidedefs or linedefs, or it's area is 0). This could cause problems with clipping and rendering in the game.";
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Methods
|
|
|
|
// This sets if this result is displayed in ErrorCheckForm (mxd)
|
|
internal override void Hide(bool hide)
|
|
{
|
|
hidden = hide;
|
|
Type t = this.GetType();
|
|
if(hide) sector.IgnoredErrorChecks.Add(t);
|
|
else if(sector.IgnoredErrorChecks.Contains(t)) sector.IgnoredErrorChecks.Remove(t);
|
|
}
|
|
|
|
// This must return the string that is displayed in the listbox
|
|
public override string ToString()
|
|
{
|
|
if(sector.Sidedefs != null && sector.Sidedefs.Count > 2)
|
|
return "Area of sector " + sector.Index + " is 0";
|
|
return "Sector " + sector.Index + " has " + (sector.Sidedefs == null ? "no" : sector.Sidedefs.Count.ToString()) + " sidedefs";
|
|
}
|
|
|
|
// Rendering
|
|
public override void PlotSelection(IRenderer2D renderer)
|
|
{
|
|
renderer.PlotSector(sector, General.Colors.Selection);
|
|
}
|
|
|
|
// Fix by merging with surrounding geometry/removing
|
|
public override bool Button1Click(bool batchMode)
|
|
{
|
|
if(!batchMode) General.Map.UndoRedo.CreateUndo("Invalid sector correction");
|
|
|
|
//collect the lines
|
|
List<Linedef> lines = new List<Linedef>();
|
|
foreach(Sidedef side in sector.Sidedefs)
|
|
{
|
|
if(!lines.Contains(side.Line) && !side.Line.IsDisposed)
|
|
lines.Add(side.Line);
|
|
}
|
|
|
|
//get rid of lines with zero length
|
|
foreach(Linedef line in lines)
|
|
if(line.Length == 0) line.Dispose();
|
|
|
|
if(lines.Count == 0)
|
|
{
|
|
sector.Dispose();
|
|
}
|
|
else if(lines.Count < 3) //merge with surrounding geometry
|
|
{
|
|
bool merged = false;
|
|
foreach(Sidedef side in sector.Sidedefs)
|
|
{
|
|
if(side.Other != null && side.Other.Sector != null && sector.Index != side.Other.Sector.Index)
|
|
{
|
|
sector.Join(side.Other.Sector);
|
|
merged = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!merged)
|
|
{
|
|
HashSet<Linedef> sectorlines = new HashSet<Linedef>();
|
|
foreach(Sidedef side in sector.Sidedefs) sectorlines.Add(side.Line);
|
|
|
|
if(sectorlines.Count > 0)
|
|
{
|
|
List<LinedefSide> newlines = new List<LinedefSide>(sectorlines.Count);
|
|
foreach(Linedef line in sectorlines)
|
|
{
|
|
if(line.Front != null) newlines.Add(new LinedefSide(line, true));
|
|
if(line.Back != null) newlines.Add(new LinedefSide(line, false));
|
|
}
|
|
|
|
if(newlines.Count > 0)
|
|
{
|
|
// If invalid sector is inside another one, join them
|
|
Vector2D center = new Vector2D(sector.BBox.X + sector.BBox.Width / 2, sector.BBox.Y + sector.BBox.Height / 2);
|
|
Linedef otherline = General.Map.Map.NearestLinedef(center, sectorlines);
|
|
Sidedef targetside = (otherline.Front ?? otherline.Back);
|
|
|
|
if(targetside != null &&
|
|
((otherline.Front != null && otherline.Front.Sector != null && otherline.Front.Sector.BBox.Contains(center.x, center.y)) ||
|
|
otherline.Back != null && otherline.Back.Sector != null && otherline.Back.Sector.BBox.Contains(center.x, center.y)))
|
|
{
|
|
Tools.JoinSector(newlines, targetside);
|
|
merged = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
//oh well, I don't know what else I can do here...
|
|
if(!merged) sector.Dispose();
|
|
}
|
|
}
|
|
else //redraw the lines
|
|
{
|
|
foreach(Linedef line in lines)
|
|
{
|
|
if(line.IsDisposed) continue;
|
|
DrawnVertex start = new DrawnVertex { pos = line.Start.Position, stitch = true, stitchline = true };
|
|
DrawnVertex end = new DrawnVertex { pos = line.End.Position, stitch = true, stitchline = true };
|
|
Tools.DrawLines(new List<DrawnVertex> { start, end }, false, false);
|
|
}
|
|
}
|
|
|
|
General.Map.Map.Update();
|
|
return true;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|