mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-02-07 08:21:59 +00:00
More fixes in Vertex and Linedef deleting process and also Visual Vertex handles.
This commit is contained in:
parent
4abcca3cf8
commit
6462ff5edb
4 changed files with 167 additions and 34 deletions
|
@ -148,6 +148,14 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
// Already set isdisposed so that changes can be prohibited
|
// Already set isdisposed so that changes can be prohibited
|
||||||
isdisposed = true;
|
isdisposed = true;
|
||||||
|
|
||||||
|
//mxd. If there are sectors on both sides, join them
|
||||||
|
if(front != null && front.Sector != null && back != null && back.Sector != null && front.Sector.Index != back.Sector.Index) {
|
||||||
|
if(front.Sector.BBox.Width * front.Sector.BBox.Height > back.Sector.BBox.Width * back.Sector.BBox.Height)
|
||||||
|
back.Sector.Join(front.Sector);
|
||||||
|
else
|
||||||
|
front.Sector.Join(back.Sector);
|
||||||
|
}
|
||||||
|
|
||||||
// Dispose sidedefs
|
// Dispose sidedefs
|
||||||
if((front != null) && map.AutoRemove) front.Dispose(); else AttachFrontP(null);
|
if((front != null) && map.AutoRemove) front.Dispose(); else AttachFrontP(null);
|
||||||
if((back != null) && map.AutoRemove) back.Dispose(); else AttachBackP(null);
|
if((back != null) && map.AutoRemove) back.Dispose(); else AttachBackP(null);
|
||||||
|
|
|
@ -730,7 +730,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
}
|
}
|
||||||
|
|
||||||
[BeginAction("deleteitem", BaseAction = true)]
|
[BeginAction("deleteitem", BaseAction = true)]
|
||||||
public void DeleteItem()
|
public void DeleteItem() {
|
||||||
|
deleteItem(true); //mxd
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteItem(bool createUndo)
|
||||||
{
|
{
|
||||||
// Make list of selected vertices
|
// Make list of selected vertices
|
||||||
ICollection<Vertex> selected = General.Map.Map.GetSelectedVertices(true);
|
ICollection<Vertex> selected = General.Map.Map.GetSelectedVertices(true);
|
||||||
|
@ -740,27 +744,49 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
if(selected.Count > 0)
|
if(selected.Count > 0)
|
||||||
{
|
{
|
||||||
// Make undo
|
// Make undo
|
||||||
if(selected.Count > 1)
|
if(createUndo) { //mxd
|
||||||
{
|
if(selected.Count > 1) {
|
||||||
General.Map.UndoRedo.CreateUndo("Delete " + selected.Count + " vertices");
|
General.Map.UndoRedo.CreateUndo("Delete " + selected.Count + " vertices");
|
||||||
General.Interface.DisplayStatus(StatusType.Action, "Deleted " + selected.Count + " vertices.");
|
General.Interface.DisplayStatus(StatusType.Action, "Deleted " + selected.Count + " vertices.");
|
||||||
}
|
} else {
|
||||||
else
|
General.Map.UndoRedo.CreateUndo("Delete vertex");
|
||||||
{
|
General.Interface.DisplayStatus(StatusType.Action, "Deleted a vertex.");
|
||||||
General.Map.UndoRedo.CreateUndo("Delete vertex");
|
}
|
||||||
General.Interface.DisplayStatus(StatusType.Action, "Deleted a vertex.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. Find sectors, which will become invalid after vertex removal.
|
//mxd. Find sectors, affected by vertex removal.
|
||||||
Dictionary<Sector, Vector2D> toMerge = new Dictionary<Sector, Vector2D>();
|
Dictionary<Sector, Vector2D> toMerge = new Dictionary<Sector, Vector2D>();
|
||||||
|
List<Sector> possiblyInvalidSectors = new List<Sector>();
|
||||||
|
List<Sector> affectedSectors = new List<Sector>();
|
||||||
|
|
||||||
|
//mxd
|
||||||
foreach(Vertex v in selected) {
|
foreach(Vertex v in selected) {
|
||||||
foreach(Linedef l in v.Linedefs) {
|
foreach(Linedef l in v.Linedefs) {
|
||||||
if(l.Front != null && l.Front.Sector.Sidedefs.Count < 4 && !toMerge.ContainsKey(l.Front.Sector))
|
if(l.Front != null && l.Front.Sector != null){
|
||||||
toMerge.Add(l.Front.Sector, new Vector2D(l.Front.Sector.BBox.Location.X + l.Front.Sector.BBox.Width/2, l.Front.Sector.BBox.Location.Y + l.Front.Sector.BBox.Height/2));
|
if(!affectedSectors.Contains(l.Front.Sector))
|
||||||
|
affectedSectors.Add(l.Front.Sector);
|
||||||
|
|
||||||
if(l.Back != null && l.Back.Sector.Sidedefs.Count < 4 && !toMerge.ContainsKey(l.Back.Sector))
|
foreach(Sidedef side in l.Front.Sector.Sidedefs) {
|
||||||
toMerge.Add(l.Back.Sector, new Vector2D(l.Back.Sector.BBox.Location.X + l.Back.Sector.BBox.Width / 2, l.Back.Sector.BBox.Location.Y + l.Back.Sector.BBox.Height / 2));
|
if(side.Other != null && side.Other.Sector != null && !affectedSectors.Contains(side.Other.Sector))
|
||||||
|
affectedSectors.Add(side.Other.Sector);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l.Front.Sector.Sidedefs.Count < 4 && !toMerge.ContainsKey(l.Front.Sector))
|
||||||
|
toMerge.Add(l.Front.Sector, new Vector2D(l.Front.Sector.BBox.Location.X + l.Front.Sector.BBox.Width/2, l.Front.Sector.BBox.Location.Y + l.Front.Sector.BBox.Height/2));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l.Back != null && l.Back.Sector != null) {
|
||||||
|
if(!affectedSectors.Contains(l.Back.Sector))
|
||||||
|
affectedSectors.Add(l.Back.Sector);
|
||||||
|
|
||||||
|
foreach(Sidedef side in l.Back.Sector.Sidedefs) {
|
||||||
|
if(side.Other != null && side.Other.Sector != null && !affectedSectors.Contains(side.Other.Sector))
|
||||||
|
affectedSectors.Add(side.Other.Sector);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l.Back.Sector.Sidedefs.Count < 4 && !toMerge.ContainsKey(l.Back.Sector))
|
||||||
|
toMerge.Add(l.Back.Sector, new Vector2D(l.Back.Sector.BBox.Location.X + l.Back.Sector.BBox.Width / 2, l.Back.Sector.BBox.Location.Y + l.Back.Sector.BBox.Height / 2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,26 +809,85 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
Vertex v1 = (ld1.Start == v) ? ld1.End : ld1.Start;
|
Vertex v1 = (ld1.Start == v) ? ld1.End : ld1.Start;
|
||||||
Vertex v2 = (ld2.Start == v) ? ld2.End : ld2.Start;
|
Vertex v2 = (ld2.Start == v) ? ld2.End : ld2.Start;
|
||||||
|
|
||||||
//mxd
|
//mxd. Check if removing a vertex will collapse a sector with 3 "outer" sides
|
||||||
DrawnVertex dv1 = new DrawnVertex();
|
bool skip = false;
|
||||||
DrawnVertex dv2 = new DrawnVertex();
|
|
||||||
dv1.stitchline = true;
|
|
||||||
dv2.stitchline = true;
|
|
||||||
|
|
||||||
if(ld1.Start == v) {
|
if(ld1.Front != null) {
|
||||||
ld1.SetStartVertex(v2);
|
foreach(Sidedef side in ld1.Front.Sector.Sidedefs) {
|
||||||
dv1.pos = v2.Position;
|
if(!possiblyInvalidSectors.Contains(ld1.Front.Sector) && (side.Line.Start == v1 && side.Line.End == v2) || side.Line.Start == v2 && side.Line.End == v1) {
|
||||||
dv2.pos = v1.Position;
|
possiblyInvalidSectors.Add(ld1.Front.Sector);
|
||||||
} else {
|
skip = true;
|
||||||
ld1.SetEndVertex(v2);
|
}
|
||||||
dv1.pos = v1.Position;
|
}
|
||||||
dv2.pos = v2.Position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ld2.Dispose();
|
if(ld2.Front != null) {
|
||||||
|
foreach(Sidedef side in ld2.Front.Sector.Sidedefs) {
|
||||||
|
if(!possiblyInvalidSectors.Contains(ld2.Front.Sector) && (side.Line.Start == v1 && side.Line.End == v2) || side.Line.Start == v2 && side.Line.End == v1) {
|
||||||
|
possiblyInvalidSectors.Add(ld2.Front.Sector);
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ld1.Back != null) {
|
||||||
|
foreach(Sidedef side in ld1.Back.Sector.Sidedefs) {
|
||||||
|
if(!possiblyInvalidSectors.Contains(ld1.Back.Sector) && (side.Line.Start == v1 && side.Line.End == v2) || side.Line.Start == v2 && side.Line.End == v1) {
|
||||||
|
possiblyInvalidSectors.Add(ld1.Back.Sector);
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ld2.Back != null) {
|
||||||
|
foreach(Sidedef side in ld2.Back.Sector.Sidedefs) {
|
||||||
|
if(!possiblyInvalidSectors.Contains(ld2.Back.Sector) && (side.Line.Start == v1 && side.Line.End == v2) || side.Line.Start == v2 && side.Line.End == v1) {
|
||||||
|
possiblyInvalidSectors.Add(ld2.Back.Sector);
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
Tools.DrawLines(new List<DrawnVertex>() { dv1, dv2 });
|
if(!skip) {
|
||||||
|
DrawnVertex dv1 = new DrawnVertex();
|
||||||
|
DrawnVertex dv2 = new DrawnVertex();
|
||||||
|
dv1.stitchline = true;
|
||||||
|
dv2.stitchline = true;
|
||||||
|
dv1.stitch = true;
|
||||||
|
dv2.stitch = true;
|
||||||
|
|
||||||
|
if(ld1.Start == v) {
|
||||||
|
dv1.pos = v2.Position;
|
||||||
|
dv2.pos = v1.Position;
|
||||||
|
} else {
|
||||||
|
dv1.pos = v1.Position;
|
||||||
|
dv2.pos = v2.Position;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tools.DrawLines(new List<DrawnVertex>() { dv1, dv2 });
|
||||||
|
|
||||||
|
General.Map.IsChanged = true;
|
||||||
|
General.Map.Map.Update();
|
||||||
|
|
||||||
|
//if both of the lines are single sided, remove newly created sector
|
||||||
|
if((ld1.Front == null || ld1.Back == null) && (ld2.Front == null || ld2.Back == null)) {
|
||||||
|
List<Linedef> newLines = General.Map.Map.GetMarkedLinedefs(true);
|
||||||
|
|
||||||
|
int index = ld1.Front != null ? ld1.Front.Sector.Index : ld1.Back.Sector.Index;
|
||||||
|
General.Map.Map.GetSectorByIndex(index).Dispose();
|
||||||
|
|
||||||
|
foreach(Linedef l in newLines) {
|
||||||
|
if(l.Front != null && l.Front.Sector != null && !affectedSectors.Contains(l.Front.Sector))
|
||||||
|
affectedSectors.Add(l.Front.Sector);
|
||||||
|
if(l.Back != null && l.Back.Sector != null && !affectedSectors.Contains(l.Back.Sector))
|
||||||
|
affectedSectors.Add(l.Back.Sector);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ld1.Dispose();
|
||||||
|
ld2.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,10 +899,36 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
//mxd
|
//mxd
|
||||||
Tools.MergeInvalidSectors(toMerge);
|
Tools.MergeInvalidSectors(toMerge);
|
||||||
|
|
||||||
|
foreach(Sector s in possiblyInvalidSectors) {
|
||||||
|
//still invalid?
|
||||||
|
if(!s.IsDisposed && s.Sidedefs.Count < 3) s.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(Sector s in affectedSectors) {
|
||||||
|
if(s.IsDisposed) continue;
|
||||||
|
|
||||||
|
foreach(Sidedef side in s.Sidedefs){
|
||||||
|
if((side.Line.Front == null && side.Line.Back != null) || (side.Line.Front != null && side.Line.Back == null)){
|
||||||
|
side.Line.ApplySidedFlags();
|
||||||
|
}else if(side.Line.Front == null && side.Line.Back != null && side.Line.Back.Sector != null) {
|
||||||
|
// Flip linedef
|
||||||
|
side.Line.FlipVertices();
|
||||||
|
side.Line.FlipSidedefs();
|
||||||
|
side.Line.ApplySidedFlags();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update cache values
|
// Update cache values
|
||||||
General.Map.IsChanged = true;
|
General.Map.IsChanged = true;
|
||||||
General.Map.Map.Update();
|
General.Map.Map.Update();
|
||||||
|
|
||||||
|
//mxd. Because... well... some new vertices might have been created during vertex removal process...
|
||||||
|
if(General.Map.Map.GetSelectedVertices(true).Count > 0) {
|
||||||
|
deleteItem(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Invoke a new mousemove so that the highlighted item updates
|
// Invoke a new mousemove so that the highlighted item updates
|
||||||
MouseEventArgs e = new MouseEventArgs(MouseButtons.None, 0, (int)mousepos.x, (int)mousepos.y, 0);
|
MouseEventArgs e = new MouseEventArgs(MouseButtons.None, 0, (int)mousepos.x, (int)mousepos.y, 0);
|
||||||
OnMouseMove(e);
|
OnMouseMove(e);
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
private float cageradius2;
|
private float cageradius2;
|
||||||
private Vector3D boxp1;
|
private Vector3D boxp1;
|
||||||
private Vector3D boxp2;
|
private Vector3D boxp2;
|
||||||
|
private int storedHeight = int.MinValue;
|
||||||
|
|
||||||
// Undo/redo
|
// Undo/redo
|
||||||
private int undoticket;
|
private int undoticket;
|
||||||
|
@ -46,8 +47,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
if(vertex.Fields.ContainsKey(key)) {
|
if(vertex.Fields.ContainsKey(key)) {
|
||||||
z = vertex.Fields.GetValue(key, 0f);
|
z = vertex.Fields.GetValue(key, 0f);
|
||||||
|
|
||||||
if(z == height) //don't create garbage data!
|
if(z == height) { //don't create garbage data!
|
||||||
vertex.Fields.Remove(key);
|
vertex.Fields.Remove(key);
|
||||||
|
storedHeight = height;
|
||||||
|
}
|
||||||
|
} else if(storedHeight != int.MinValue) {
|
||||||
|
z = storedHeight;
|
||||||
|
vertex.Fields.Add(key, new UniValue(UniversalType.Float, z));
|
||||||
|
storedHeight = int.MinValue;
|
||||||
} else {
|
} else {
|
||||||
z = height;
|
z = height;
|
||||||
}
|
}
|
||||||
|
@ -83,13 +90,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
if(ceilingVertex) {
|
if(ceilingVertex) {
|
||||||
height = sectors[0].CeilHeight;
|
height = sectors[0].CeilHeight;
|
||||||
for(int i = 1; i < sectors.Length; i++) {
|
for(int i = 1; i < sectors.Length; i++) {
|
||||||
if(sectors[i].CeilHeight < height)
|
if(sectors[i].Sidedefs.Count == 3 && sectors[i].CeilHeight < height)
|
||||||
height = sectors[i].CeilHeight;
|
height = sectors[i].CeilHeight;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
height = sectors[0].FloorHeight;
|
height = sectors[0].FloorHeight;
|
||||||
for(int i = 1; i < sectors.Length; i++) {
|
for(int i = 1; i < sectors.Length; i++) {
|
||||||
if(sectors[i].FloorHeight > height)
|
if(sectors[i].Sidedefs.Count == 3 && sectors[i].FloorHeight > height)
|
||||||
height = sectors[i].FloorHeight;
|
height = sectors[i].FloorHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexData vd = data.Mode.GetVertexData(v);
|
VertexData vd = data.Mode.GetVertexData(v);
|
||||||
vd.AddUpdateSector(data.Sector, true);
|
|
||||||
|
foreach(Linedef line in v.Linedefs) {
|
||||||
|
if(line.Front != null && line.Front.Sector != null)
|
||||||
|
vd.AddUpdateSector(line.Front.Sector, false);
|
||||||
|
if(line.Back != null && line.Back.Sector != null)
|
||||||
|
vd.AddUpdateSector(line.Back.Sector, false);
|
||||||
|
}
|
||||||
|
|
||||||
data.Mode.UpdateVertexHandle(v);
|
data.Mode.UpdateVertexHandle(v);
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
|
|
Loading…
Reference in a new issue